- From: Brian Birtles <bbirtles@mozilla.com>
- Date: Wed, 16 Oct 2013 14:28:50 +0900
- To: public-fx@w3.org
Dear all,
Following is a summary of changes I intend to make to the operation of
players in Web Animations.
Background reading:
* What are players?:
http://brian.sol1.net/svg/2013/07/25/players-wanted-the-pause-and-seek-game/
* Initial proposal to make players stop:
http://lists.w3.org/Archives/Public/public-fx/2013JulSep/0009.html, point 6
* Follow-up discussion:
http://lists.w3.org/Archives/Public/public-fx/2013JulSep/0043.html, point 2
Objective: Make players "stop" when they reach the end of their source
content.
Motivation:
* Analogous to how video "players" etc. work
* Allows defining onend events for players or making them then-able
* Allows defining a reverse() method which, if called twice, is a no-op
(maybe)
* Closer to how HTML media elements work
Current model:
* Players are content-agnostic. It's like a stubborn record player where
the needle just keeps moving out indefinitely even past the end of the
record.
Proposed alternatives:
Option A: Clamp the current time
================================
* We calculate the current time as usual but before reporting it back by
the API, we clamp it to the range:
[0, content end time]
(I'm calling this the "content range" from here on.)
* In effect, you end up with an "actual current time" and a "reported
current time".
+ The primary benefit of this model is that it's not stative. You can
make all the changes you like to the source content and regardless of
the order or timing of the operations the result is going to be the same.
For example, if you play 5s of source content through to the end,
wait 1s, then add some more content, it picks up playback from the 6s
mark--the same as if you made that change earlier.
- The primary drawback is the distinction between actual current time vs
reported current time. Either we confuse the API by exposing both, or we
hide the actual current time which could lead to surprising results.
- It also differs from what happens with video players etc.
Option B: The DVD player - times outside the content range are
disallowed
===============================================================
* With a DVD player, you can't possibly seek to a point outside the
source content so in this model we do the same. Attempts to set times
outside this range simply get silently adjusted to fall within the range.
For example, if you play 5s of source content through to the end, then
adjust the source content so it is *shorter*, say 3s long, the current
time is updated to 3s. Note that unlike Option A, this is the *actual*
current time. If we then extend the source content to say, 7s, playback
starts from the 3s mark.
+ The primary advantage of this is it easy to reason about to the extent
that it mimicks a DVD player. However, you can't change the length of
the content of a DVD while it is in play--and when you replace the DVD
in a DVD player it either resets its position or bases it on a cached
position for the new DVD; so it's actually not a great parallel.
- On the other hand there are some disadvantages including:
* You can't set the current time to 5s *then* add source content and
start playing. (That *may* be problematic when we introduce media
reference items, I'm not sure.)
* You can't swap the source content of two players since here's what
will happen:
// Swap
var tmp = playerA.source;
playerA.source = playerB.source;
playerB.source = tmp;
// playerA maintains its current time (although possibly truncated if
playerB's source is shorter)
// playerB's current time is reset to 0 since after the second line it
has no source content
Option C: The record player
===========================
* This model is similar to option B except you *can* set the position to
somewhere outside the content range but it won't move when outside that
range. It's like the needle on a record player--you can position it off
the record but it won't move if you do that.
In effect, we add another kind of auto-pausing that is orthogonal to the
existing pause state of a player. We enter this "auto-paused" state if:
* we get a sample that would give us a current time outside the content
range and we're not already in the auto-paused state
* we are seeked to a current time outside the content range
We exit the "auto-paused" state if:
* sampling with the current timeline time would give us a current time
inside the content range
So if you were to play 5s of content to end and *then* update the source
content to 3s the current time would continue to be 5s and would not
change. Then if you were to update the source content to 7s, it would
begin playing from 5s.
+ This means you can:
* Set the current time to 5s *then* add source content and it picks up
playing from the 5s mark
* Swap the content of two players and have them keep their positions
- The primary disadvantage is you're making the behaviour of the player
more dependant on current state and hence the timing of operations matters.
For example, if you start a player whose source content is an empty
group, but don't add anything to the group for a while--perhaps you're
waiting on some async resource to load--and *then* you add it, you will
be out of sync with any other players started at the same time (since
you will have accumulated time lag while waiting for content to be
added). On the up-side, you *will* start playback from the beginning of
the content.
Remedies for this particular situation:
a) Add a catchUp() method to reset the timeLag of a player.
b) Don't create the player until you're ready to play, then give it the
appropriate start time.
c) Create the player with source content of infinite length initially
and then add the content in when ready.
But this is just one example. In general you will observe differences in
behaviour between making a change to source content *before* the player
reaches the end (and hence no time lag is accumulated) and making the
same change *after* the player has reached the end. What's more the
difference comes down to timing and might only manifest when you start
running the content on a different kind of device.
So they are the three models. We've previously said we'll do option C
but I don't know if we quite appreciated how dependent it is on timing.
I still lean towards C, but what do you think? If nothing else, I wanted
to document some of the thinking behind this design.
It's worthwhile considering how media reference items would behave in
these cases too.
I'll follow up this post with a rough sketch of how I think the API
might look for option C.
Thanks,
Brian
Received on Wednesday, 16 October 2013 05:29:23 UTC