首页 文章

Youtube的HTML5视频播放器如何控制缓冲?

提问于
浏览
48

我正在观看youtube视频,我决定调查其视频播放器的某些部分 . 我注意到,与我见过的大多数HTML5视频不同,Youtube的视频播放器不会使用普通视频源,而是使用blob网址作为源 .

以前我测试了HTML5视频,我发现服务器从一开始就开始流式传输整个视频,并在后台缓冲整个视频的剩余部分 . 这意味着如果您的视频为300兆,则将下载所有300兆 . 如果你寻求中间,它将从搜索位置开始一直下载到最后 .

Youtube不会这样工作(至少在chrome中) . 相反,它设法控制缓冲,因此它只在暂停时缓冲一定量 . 它似乎只缓冲相关的部分,所以如果你跳过它将确保不缓冲不太可能被观看的部分 .

在我试图调查这是如何工作的时候,我注意到视频src标签的值为 blob:http%3A//www.youtube.com/ee625eee-2802-49b2-a13f-eb374d551d54 ,它将我指向blobs,然后将其引导至typed arrays . 使用这两个资源,我可以将mp4视频加载到blob中并将其显示在HTML5视频标记中 .

然而,我现在坚持的是Youtube如何处理这些碎片 . 查看网络流量,它似乎将请求发送到 http://r6---sn-p5q7ynee.c.youtube.com/videoplayback ,它以2.1mb的块返回二进制视频数据 . 值得注意的是,由于HTML5视频请求导致的大多数正常请求似乎在流式传输时收到了206响应代码,但是youtube的playvideo调用获得了200响应 .

我试图只尝试加载一个字节范围(通过设置 Range http标头),但遗憾的是失败了(我假设因为视频中没有视频的元数据) .

在这一点上,我一直在想弄清楚Youtube如何实现这一目标 . 我提出了几个想法,但我没有完全卖掉:

1)Youtube正在发送每个 /videoplayback 呼叫的自包含视频和音频块 . 这似乎是上传方面相当沉重的负担,似乎很难将这些拼接在一起,使它看起来像是一个完整的视频,从调用 $('video').duration$('video').currentTime 判断,这让我相信视频标签认为它是一个单一的视频文件 . 最后,vidoe src标签永远不会改变,这让我相信它正在使用单个blob而不是切换blob .

2)Youtube构造一个预先调整为完整视频数组的空blob,并在下载时更新blob . 然后它将确保用户没有太接近最后下载的片段(以防止用户进入blob的未下载部分) . 我看到的问题是,我没有看到通过javascript动态更新blob的任何方法(尽管我可能只是在谷歌上搜索它)

3)Youtube下载元数据,然后通过在下载视频片段时附加视频片段来开始按顺序构建blob . 我用这种方法看到的问题是我不明白它将如何处理后缓冲区域中的搜索 .

也许我只是错过了一个在我面前的明显答案 . 任何人都有任何想法?


编辑:我刚想到了第四个选项 . 另一个想法是他们可能使用文件API将二进制块写入文件并使用该文件流出 . 文件API似乎能够搜索特定位置,因此允许您使用空字节填充视频并在接收时填充它们 . 这肯定也适合视频搜索 .

4 回答

  • 4

    好的,你需要知道的很少的事情是YouTube基于这个伟大的开源Project . 它对于每个浏览器都表现不同,如果您的浏览器支持像WEBM这样的更密集的解码,它将使用它来节省Google的带宽 . 另外,如果你看这个Demo然后你会发现一个部分将整个视频下载到一个名为"offline storage"的东西中 . 我知道chrome有它和其他一些浏览器并不是每个浏览器都需要使用整个视频源而不是blob . 因此blob是流式传输,具体取决于用户与视频的交互 . 是的,视频只是一个文件,他们有该视频的元数据,就像一个小数据库,告诉视频的时间和可以分割块的点 .

    您可以通过阅读项目文档了解更多信息 . 我真的建议你看一下这个演示 .

  • 6

    当您查看GoogleChrome的AppData时,在播放YouTube视频时,您会看到它在分段文件中缓冲 . 上传到youtube的视频是细分的,这就是为什么如果该时间范围超出当前细分,则无法在第一次单击条形图时完美确定时间范围 .

    段的数量取决于视频的长度,以及开始和停止播放的时间视频 .

    当您链接到视频的时间范围时,它将简单地跳过在该时间范围之前的段的缓冲 .

    不幸的是,我对视频播放的编码知之甚少,但我希望这能指出你正确的方向 .

  • 4

    Youtube仅在支持Media Source Extensions的浏览器中使用此功能,因此由浏览器决定所有其他功能,因为此功能 .

  • 3

    页面中有一个canvas元素,也许这会帮助http://html5doctor.com/video-canvas-magic/

    我们知道视频是分段的,问题是如何将它们拼接在一起 . 我认为真正的视频元素不做播放工作,它支持数据源,并将每个帧的画面绘制到画布元素 .

    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);
    

相关问题