53

我正在观看一个 youtube 视频,我决定研究其视频播放器的某些部分。我注意到,与我见过的大多数 HTML5 视频不同,Youtube 的视频播放器不做普通的视频源,而是使用 blob url 作为源。

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

Youtube 不能以这种方式工作(至少在 chrome 中)。相反,它设法控制缓冲,因此它仅在暂停时缓冲一定量。它似乎也只缓冲相关的片段,所以如果你跳过它会确保不会缓冲不太可能被观看的片段。

在我尝试调查它是如何工作的过程中,我注意到 video 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/videoplayback1.1mb 的块返回二进制视频数据。似乎还值得注意的是,由于 HTML5 视频请求导致的大多数正常请求似乎在流式传输时收到了 206 响应代码,但 youtube 的 playvideo 调用得到了 200 响应。

我试图尝试仅加载一系列字节(通过设置Rangehttp 标头),但不幸的是失败了(我假设是因为视频附带的视频没有元数据)。

在这一点上,我一直在弄清楚 Youtube 是如何做到这一点的。我提出了几个想法,但没有一个完全被我所接受:

/videoplayback1) Youtube 每次通话都会发送自包含的视频和音频块。这在上传方面似乎是一个相当沉重的负担,而且似乎很难将它们拼接在一起以使其看起来像是一个无缝的视频。$('video').duration此外,从调用and判断,视频标签似乎认为它是一个完整的视频,$('video').currentTime这让我相信视频标签认为它是一个单独的视频文件。最后,vidoe src 标签永远不会改变,这让我相信它正在处理单个 blob 而不是切换 blob。

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

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

也许我只是错过了一个明显的答案,就在我面前。有人有什么想法吗?


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

4

4 回答 4

5

当您查看 GoogleChrome 的 AppData 时,在播放 youtube 视频时,您会看到它缓冲在分段文件中。上传到 youtube 的视频是分段的,这就是为什么如果时间范围在当前分段之外,您无法在第一次点击栏时完美地确定时间范围。

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

当您链接到视频的时间范围时,它只会跳过该时间范围之前的片段的缓冲。

不幸的是,我对视频播放的编码知之甚少,但我希望这能为您指明正确的方向。

于 2013-10-09T08:58:09.927 回答
4

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

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

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

于 2014-10-28T03:21:23.567 回答
4

好的,您只需要知道 YouTube 就是基于这个伟大的开源项目。每个浏览器的行为都不同,如果您的浏览器支持更密集的解码(如 WEBM),它将使用它来节省 Google 的带宽。另外,如果您查看此演示 ,您会发现一个部分将整个视频下载到一个称为“离线存储”的东西中。我知道 chrome 拥有它,而其他一些浏览器并非在某些情况下都必须使用整个视频源而不是 blob。因此,该 blob 正在流式传输,具体取决于用户与视频的交互。是的,视频只是 1 个文件,他们有该视频的元数据,就像一个小数据库,告诉视频的时间和可以划分块的点。

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

于 2016-12-20T12:45:19.453 回答
3

Youtube 仅在支持媒体源扩展的浏览器中使用此功能,因此由浏览器决定是否使用此功能。

于 2014-04-02T22:47:51.610 回答