|Reliable way to know when video is seeking (iframe API)||Adrian Holovaty||8/21/12 10:01 PM|
I'm developing an app with the YouTube iframe API in which I need to
know exactly when the video is playing vs. not playing. The clear
solution here is to use onStateChange to check for
PLAYING/PAUSED/BUFFERING events, but I've found this data is
inconsistent while the video is being seeked.
Specifically, if the video is being played and I call seekTo(),
there's usually a period of several hundred milliseconds where the
video *isn't* playing but onStateChange hasn't fired anything. Here's
what it looks like in order of events (this is written as if it were
an interactive JS interpreter):
// onStateChange=PLAYING event fires reliably
// Now, the video STOPS playing, while it locates the part
// of the video to seek to. Several hundred milliseconds
// pass, depending on how much of the video has been loaded,
// the speed of my network connection, etc., and my app has
// no reliable way of knowing that it's currently not playing.
// onStateChange=PLAYING event eventually fires when the video
// starts again (BUT NOT ALWAYS!)
One hacky way to get around this would be to change my app to assume
the video pauses when player.seekTo() is called. But then the question
is, how do I know when the video starts again? I could look for the
onStateChange=PLAYING event, but that does NOT reliably fire again
after the seekTo() call. So I actually consider there to be *two*
problems here -- the fact that there's no onStateChange event for
seeks, and the fact that onStateChange does not reliably fire after a
seek is finished.
I've created a demo of this, and you'll be able to see both problems in action:
Just load the page -- no need to click anything. When the page loads,
it loads a video, plays it, waits 1.5 seconds, then does a seekTo(),
then does several more seeks every 1.5 seconds. It prints out every
onStateChange event, regardless of type, and calculates how many
milliseconds pass between the seekTo() and the subsequent
onStateChange.PLAYING event -- this is time during which we cannot
reliably tell whether it's playing. And sometimes (usually after the
third seekTo(1) in the example) the player does *not* trigger
onStateChange after a seekTo(). (In that case, this demo prints out
the message "Didn't get an onStateChange after the last seekTo!")
I tested this (and got the same results) in Chrome 21.0.1180.79 and
Firefox 4.0, both on OS X Lion. Here are the results I get:
I hope this makes sense. FWIW, to be crystal clear, here's what I
would like to see changed in the API:
* When seekTo() is called, trigger onStateChange immediately with
PlayerState.BUFFERING to specify it's seeking.
* After the seek is done, guarantee that onStateChange=PLAYING is always fired.
Both of these changes seem to be backwards-compatible.
Let me know if I can provide any more info, and thanks for reading --
|Re: Reliable way to know when video is seeking (iframe API)||Jeffrey Posnick||8/22/12 2:02 PM|
The delay you're seeing is attributable to the amount of time it takes the native player (Flash or HTML5 <video>) to figure out exactly where in the byte stream it needs to start reading and to resume playing. In the case of Flash playback, finding the nearest key frame might is needed, and that might also apply to HTML5 <video> depending on the implementation details. The playback isn't paused, and as soon as all the bytes have been loaded, there's no buffering going on, so neither PAUSED nor BUFFERING are appropriate states. The API also doesn't fire onStateChange() events unless the state is actually different from the previous state, so you should never see two PLAYING states in a row.
I understand that this doesn't meet your specific requirements, but it's the model the API uses for state events. I guess what you're asking for is something like a SEEKING state, but I don't even know if the YouTube Player API has any insight into what's going on under the hood in the Flash/HTML5 <video> playback engine when this sort of thing is taking place, and therefore might not even have any way to detect SEEKING events even if we wanted to add that as a state.
|Re: [YouTube-API] Re: Reliable way to know when video is seeking (iframe API)||Adrian Holovaty||8/22/12 2:09 PM|
Thanks for the quick response! I understand your point about
potentially not having visibility into Flash/HTML5 implementation of
But regarding your point that "you should never see two PLAYING states
in a row" -- that indeed is happening in my demo. Each time it calls
seekTo(), onStateChange is fired with PLAYING, and there are no other
onStateChange events in between. Take a look at
http://red-bean.com/~adrian/timing_demo.png -- it has 13 PLAYING
events in a row! :-/
> You received this message because you are subscribed to the Google Groups
> "YouTube APIs Developer Forum" group.
> To view this discussion on the web visit
> To post to this group, send email to youtube-...@googlegroups.com.
> To unsubscribe from this group, send email to
> For more options, visit this group at
|Re: [YouTube-API] Re: Reliable way to know when video is seeking (iframe API)||Jeffrey Posnick||8/22/12 2:20 PM|
Hmm, I didn't see the same thing when I tried your demo, but I tried using HTML5 <video> playback. After trying your demo in an Incognito window and getting Flash playback, I do see the multiple PLAYING events. And yeah, that shouldn't happen—we should be consistent between the HTML5 <video> and Flash scenario, and firing multiple identical state change events in a row isn't expected.
I'll open a bug with the Players API team about that.
|Re: [YouTube-API] Re: Reliable way to know when video is seeking (iframe API)||Adrian Holovaty||8/22/12 2:26 PM|
Ah, cool, glad it wasn't me overlooking something totally obvious!
Thanks for the response. I can imagine it's a huge pain having to
maintain these two separate-yet-identical APIs. Your work is