Youtube的HTML5video播放器如何控制缓冲?
我正在观看YouTubevideo,并决定调查其video播放器的某些部分。 我注意到,与大多数HTML5video不同,Youtube的video播放器不会执行正常的video源,而是使用bloburl作为源。
以前我testing过HTML5video,我发现服务器从一开始就开始stream式传输整个video,并在后台缓冲整个video的其余部分。 这意味着如果你的video是300兆,所有300兆将被下载。 如果你寻求中间的话,它将开始从寻找位置一路下载到最后。
Youtube不能这样工作(至less在铬)。 相反,它设法控制缓冲,所以它只在暂停时缓冲一定量。 它也似乎只缓冲相关的部分,所以如果你跳过它将确保不缓冲不可能被观看的部分。
在我试图研究这是如何工作的,我注意到videosrc标签有一个blob:http%3A//www.youtube.com/ee625eee-2802-49b2-a13f-eb374d551d54
的值blob:http%3A//www.youtube.com/ee625eee-2802-49b2-a13f-eb374d551d54
,它指向我的blob ,然后导致我键入数组 。 使用这两种资源,我可以将mp4video加载到blob中,并将其显示在HTML5video标签中。
但是,我现在所坚持的是YouTube如何处理这些作品。 看着networkingstream量,它似乎发送请求到http://r6---sn-p5q7ynee.c.youtube.com/videoplayback
它返回二进制video数据回1.1M块。 同样值得注意的是,由于HTML5video请求的大部分正常请求似乎在stream式传输过程中收到了206个响应代码,而YouTube的播放video呼叫又回到了200。
我试图尝试只加载一个字节范围(通过设置Range
http头),不幸的是失败(我假设,因为没有与video来的video的元数据)。
在这一点上,我坚持搞清楚Youtube是如何完成这个的。 我想出了几个想法,尽pipe我没有完全卖出这些想法:
1)Youtube发送每个/videoplayback
调用自我包含的video和audio块。 这似乎是上传方面的一个相当沉重的负担,似乎将它们拼接在一起,使它看起来像是一个无聊的video很难。 此外,video标签似乎认为这是一个完整的video,从调用$('video').duration
和$('video').currentTime
,这使我相信video标签认为这是一个单一的video文件。 最后,vidoe src标签永远不会改变,这让我相信它是用一个单一的blob工作,而不是交换blob。
2)Youtube构build一个空的blob预先大小到完整的videoarrays,并下载它的块更新blob。 然后确保用户没有太接近最后下载的部分(以防止用户进入blob的未下载部分)。 我看到这个问题,我没有看到任何方式dynamic更新blob通过JavaScript(虽然也许我只是麻烦search它)
3)Youtube下载元数据,然后通过附加下载的video片段开始构buildblob。 我用这种方法看到的问题是我不明白它将如何处理后缓冲领域的寻求。
也许我只是在我面前丢失了一个明显的答案,任何人有什么想法?
编辑:我只是想到了第四个选项。 另一个想法是,他们可能会使用文件API将二进制块写入文件并使用该文件进行stream式处理。 文件API似乎有能力寻求特定的位置,因此可以让你填写一个空字节的video,并填写他们收到。 这绝对适用于videosearch。
当您查看GoogleChrome的AppData时,您将看到它在缓冲区中分段的文件。 上传到YouTube的video是分段的,这就是为什么如果该时间段在当前分段之外,则无法在第一次点击该栏时精确定位时间范围。
段的数量取决于video的长度以及开始和停止播放video的时间。
当您链接到video的时间范围时,它将简单地跳过在该时间范围之前的片段的缓冲。
不幸的是,我对video播放的编码知之甚less,但我希望这能指出您正确的方向。
Youtube仅在支持Media Source Extensions的浏览器中使用此function,因此由浏览器决定所有其他function。
页面中有一个canvas元素,也许这将帮助http://html5doctor.com/video-canvas-magic/
我们知道video被分割了,问题是如何将它们拼接在一起。我认为真正的video元素不会做播放工作,它支持数据源,并将每一帧的细节绘制到canvas元素上。
var v = document.getElementById('v'); var canvas = document.getElementById('c'); v.addEventListener('play', function(){ if(v.paused || v.ended) return false; c.drawImage(v,0,0,w,h); setTimeout(draw,20,v,c,w,h); },false);
好的,您需要知道的很less的事情是YouTube基于这个伟大的开源项目 。 它对每个浏览器都有不同的performance,如果你的浏览器支持像WEBM这样的更encryption集的解码,它将使用它来保存Google的带宽。 另外,如果你看这个演示,那么你会发现一个部分,将整个video下载到一个名为“离线存储”的东西。 我知道铬有它,其他浏览器并不是每一个在某些情况下,他们必须使用整个video源,而不是一个blob。 所以这个blob取决于用户与video的交互。 是的,video只是一个文件,他们有一个像video的数据库,该video的元数据,可以分成块的点。
您可以通过阅读项目文档来了解更多信息。 我真的build议你看看演示。