YouTube HTML5 API - 在轮询播放器当前时间时是不是可以获得更好的时间分辨率?
Posted
技术标签:
【中文标题】YouTube HTML5 API - 在轮询播放器当前时间时是不是可以获得更好的时间分辨率?【英文标题】:YouTube HTML5 API - Is it possible to get better time resolution when polling the player for current time?YouTube HTML5 API - 在轮询播放器当前时间时是否可以获得更好的时间分辨率? 【发布时间】:2014-08-03 03:28:08 【问题描述】:我一直在寻找解决这个问题的方法,但我仍然没有找到。我们的应用需要使用player.getCurrentTime()
轮询YouTube 视频对象来驱动一些屏幕动画。使用 flash API 这很棒,因为我们可以以40ms
间隔(25 FPS)轮询播放器并获得非常准确的当前播放器时间值。我们现在已经开始使用 iFrame API,遗憾的是它不允许任何接近该精度水平的东西。我做了一些研究,似乎因为它是一个 iFrame,所以 postMessage
用于将玩家状态暴露给 player.getCurrentTime()
调用。不幸的是,这个 post message 事件很少被触发 - 有时低至每秒 4 次。更糟糕的是,消息触发的实际速率似乎取决于浏览器的渲染引擎。
有谁知道是否可以强制渲染引擎更频繁地触发这些消息,以便在轮询玩家时获得更大的时间分辨率?我试过requestAnimationFrame
并没有解决问题。有没有人成功地让 iFrame 播放器报告更准确和更频繁的时间?
【问题讨论】:
postMessage 的频率不是特别高的原因是它每次都必须发送一些相当大的 json 数据包,并且性能开始受到影响(这也是它不一致的原因;正如您所建议的,它使用基于渲染可用性的内部间隔来触发事件——可能是 iframe 内的 requestAnimationFrame 。他们还没有公开任何改变帖子频率或访问底层视频文件的方法(例如,使用原生 html5 媒体 API 来获取时间)。令人沮丧,但我现在不知道有什么办法解决它 感谢您提供更多信息。确实非常令人沮丧。我什至尝试在玩家轮询间隔之间使用我自己的高分辨率计时器来补间我的动画。这甚至不起作用,因为玩家返回的当前时间不一致。例如,它仅返回上一个 postMessage 事件的时间,该事件可能发生在 150 毫秒前。使用补间,动画看起来很流畅,直到您需要使用播放器的实际时间更新它,此时您将获得时间校正和生涩的动画校正。确实非常令人沮丧。 【参考方案1】:我已经为我原来的问题想出了一个解决方法。我编写了一个简单的补间函数,它将以我想要的频率轮询 iFrame 播放器并在其间插入时间瞬间。播放器本身仅每 250 毫秒左右更新一次当前时间,具体取决于渲染引擎和平台。如果您比这更频繁地轮询它,它将在多个连续轮询中返回相同的当前时间值。但是,如果您应用一些逻辑,您可以检测播放器何时返回新的当前时间并相应地更新您自己的计时器。我在一个间隔为 25 毫秒的计时器上运行下面的函数。在每次迭代中,我都会在当前时间上增加 25 毫秒,除非我检测到玩家报告的当前时间发生了变化。在这种情况下,我用新的“实际”当前时间更新我自己的计时器。当您执行此操作时,可能会有一个小的跳跃或非线性,但如果您以足够高的速率轮询玩家,这应该是难以察觉的。
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;
【讨论】:
很棒的技巧。拯救了我的一天!【参考方案2】:在 HTML5 中,Youtube API 中的 getCurrentTime() 函数和 postMessage 事件很可能与 HTML5 媒体元素规范的 currentTime 属性和 timeupdate 事件相关联。
timeupdate 事件的触发速率因浏览器而异,并且截至今天无法根据您正在寻找的精度水平进行调整(Flash 在这方面仍然领先一些)。根据specification:
如果在正常播放期间通过当前播放位置的通常单调增加达到时间,并且如果用户代理在过去 15 到 250 毫秒内没有在元素上触发 timeupdate 事件并且仍然没有运行事件处理程序这样的事件,那么用户代理必须排队一个任务,以在元素上触发一个名为 timeupdate 的简单事件。 (在其他情况下,例如显式搜索,相关事件会作为更改当前播放位置的整个过程的一部分而被触发。)
因此,事件的触发速度不会超过大约 66Hz 或低于 4Hz(假设事件处理程序的运行时间不超过 250 毫秒)。鼓励用户代理根据系统负载和每次处理事件的平均成本来改变事件的频率,这样 UI 更新的频率不会超过用户代理在解码视频时可以轻松处理的频率。
对于 currentTime 属性,精度以seconds 表示。任何低于秒的精度都是特定于浏览器的实现,不应被视为理所当然(实际上,在 Chrome 等现代浏览器中,您将获得亚秒精度,但效率会波动)。
最重要的是,Youtube API 可能会限制所有这些事情,以达到 250 毫秒精度的更大共同点,并使所有浏览器都满意(因此每秒 4 个事件以及您在测试中注意到的情况)。对于您的情况,您最好尝试将动画缩放到这个 250 毫秒的精度概念,并允许一些误差范围以获得更好的用户体验。未来浏览器和 HTML5 媒体会变得更好,希望我们能获得真正的毫秒精度。
【讨论】:
感谢您的信息。我希望他们解决这个问题。有很多很棒的网络应用程序需要视频播放器提供更准确的时间信息。这似乎比 Flash 播放器在这方面的灵活性退了一步。以上是关于YouTube HTML5 API - 在轮询播放器当前时间时是不是可以获得更好的时间分辨率?的主要内容,如果未能解决你的问题,请参考以下文章