Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

YouTube HTML5 API - Is it possible to get better time resolution when polling the player for current time?

I've been looking for a solution for this for a while now and I still haven't found it. Our app needs to poll a YouTube video object using player.getCurrentTime() to drive some screen animations. Using the flash API this was great because we could poll the player at 40ms intervals (25 FPS) and get very accurate current player time values. We have now started to use the iFrame API which unfortunately does not allow anything near that level of accuracy. I did some research and it seems that because it's an iFrame, a postMessage is used to expose the players state to the player.getCurrentTime() call. Unfortunately this post message event is fired very infrequently - sometimes as low as 4 times a second. Worse, the actual rate the message fires seems to be dependent on the render engine for the browser.

Does anybody know if it is possible to force the render engine to fire those messages more frequently so that greater time resolution can be achieved polling the player? I tried requestAnimationFrame and it doesn't solve the problem. Has anybody successfully managed to get the iFrame player to report more accurate times and more frequently?

like image 429
Dan Barry Avatar asked Jun 12 '14 17:06

Dan Barry


2 Answers

I've come up with a workaround for my original problem. I wrote a simple tween function that will poll the iFrame player at the frequency I desire and interpolate the time instants in between. The player itself only updates the current time every 250 ms or so depending on the render engine and platform. If you poll it more frequently than that, it will return the same current time value on several consecutive polls. However, if you apply some logic, you can detect when the player returns a new current time and update your own timer accordingly. I run the function below on a timer with a 25 ms interval. On each iteration, I add 25 ms to the current time except in the case where I detect a change in the current time reported by the player. In that case I update my own timer with the new "actual" current time. There maybe a small jump or non linearity in the time when you do this but if you poll the player at a high enough rate, this should be imperceptible.

 window.setInterval(tween_time, 25);

    function tween_time() {

        time_update = (ytplayer.getCurrentTime()*1000)

        playing=ytplayer.getPlayerState();

            if (playing==1){

                if (last_time_update == time_update)
                {
                    current_time_msec += 25;
                }

                if (last_time_update != time_update)
                {
                    current_time_msec = time_update;
                }       

            }


            do_my_animations();


        last_time_update = time_update;

    }
like image 153
Dan Barry Avatar answered Sep 22 '22 14:09

Dan Barry


In HTML5 it is likely that the getCurrentTime() function and postMessage event in Youtube API are linked to the currentTime property and timeupdate event of the HTML5 media element specification.

The rate at which the timeupdate event fires varies between browsers and as of today cannot be tuned for the level of precision you are looking for (Flash is still a bit ahead on this one). According to the specification:

If the time was reached through the usual monotonic increase of the current playback position during normal playback, and if the user agent has not fired a timeupdate event at the element in the past 15 to 250ms and is not still running event handlers for such an event, then the user agent must queue a task to fire a simple event named timeupdate at the element. (In the other cases, such as explicit seeks, relevant events get fired as part of the overall process of changing the current playback position.)

The event thus is not to be fired faster than about 66Hz or slower than 4Hz (assuming the event handlers don't take longer than 250ms to run). User agents are encouraged to vary the frequency of the event based on the system load and the average cost of processing the event each time, so that the UI updates are not any more frequent than the user agent can comfortably handle while decoding the video.

For the currentTime property the precision is expressed in seconds. Any precision below of the second is browser specific implementation and should not be taken for granted (in reality you will get sub second precision in modern browsers like Chrome but with fluctuating efficiency).

On top of that the Youtube API could be throttling all of those things up to get to the larger common ground of 250ms precision and make all browsers happy (hence 4 events per second and what you did notice in your tests). For your case scenario you better off trying to scale your animations to this 250 ms precision notion and allow for some margin of error for a better user experience. In the future browsers and HTML5 media will get better and hopefully we will get true milliseconds precision.

like image 20
Arnaud Leyder Avatar answered Sep 25 '22 14:09

Arnaud Leyder