YouTube 的高清视频流服务器技术?

发布于 2024-09-10 12:15:59 字数 1821 浏览 9 评论 0原文

最近我一直在研究将 MP4 流式传输到浏览器的不同方法。 Flash Media Server 是一个明显的选择(使用 Cloudfront),而且我见过的大多数解决方案都使用 RTMP 协议。

然而,我花了一些时间在 YouTube 上使用 Firebug 和 Chrome 调试器弄清楚他们的流媒体是如何工作的,并且我发现了他们的一些视频和质量率之间的一些有趣的差异。

我的两个示例视频是 A 和 B。 A 的分辨率最高可达 480p,B 的分辨率最高可达 1080p。对于这两个视频,所有高达 480p 的速率均通过 HTTP 在包含 H.264 视频和 AAC 音频的 FLV 容器中提供。这里有趣的是,如果您尚未下载(缓存)整个视频,并且尝试跳到视频的未缓存部分,则会发出一个新请求,其“begin”参数等于中的目标偏移量毫秒。 480p 视频 A 的示例:

http://v11.lscache8.c.youtube.com/videoplayback?ip=0.0.0.0&sparams=id%2Cexpire%2Cip%2Cipbits%2Citag%2Calgorithm%2Cburst%2Cfactor%2Coc%3AU0dWTldQVF9FSkNNNl9PSlhJ&fexp=904806%2C902906%2C903711&algorithm=throttle-factor&itag=35&ipbits=0&burst=40&sver=3&expire=1279756800&key=yt1&signature=D2D704D63C242CF187CAA5B5D5BAFB8DFACAC5FF.39180C01559C976717B651A7EB1D0C6249231EB7&factor=1.25&id=8568eb3135971f6f&begin=111863

Response Headers:
Cache-Control:public,max-age=23472
Connection:close
Content-Length:14320637
Content-Type:video/x-flv
Date:Wed, 21 Jul 2010 17:23:48 GMT
Expires:Wed, 21 Jul 2010 23:55:00 GMT
Last-Modified:Wed, 19 May 2010 12:31:41 GMT
Server:gvs 1.0
X-Content-Type-Options:nosniff

此 URL 返回的文件是完全有效的 FLV,仅包含请求的偏移量之后的视频部分。

我对视频 B 的更高分辨率版本进行了同样的测试。在 720p 和 1080p 下,YouTube 将返回 MP4 容器中的视频,还包含 H.264 视频和 AAC 音频。令我印象深刻的是,他们的服务器对 MP4 视频采用相同类型的偏移量(通过“begin”参数)并返回一个有效的、可流式传输的 MP4(具有正确偏移量的文件前面的 moov 原子),该偏移量也只包括视频的请求部分。

那么,YouTube 是如何做到这一点的呢?他们如何即时生成具有正确标头且仅包含所请求视频的所需片段的 FLV 或 MP4 容器?我知道这可以使用 FFMPEG 来寻找所需的起始点并使用 qt-faststart 脚本将 moov 原子重新定位到流的前面来完成,但这似乎太慢了,无法处理数百万个的点播YouTube 观众。

有想法吗?

提前致谢!

脚注:此时我不允许包含超过 1 个链接,因此这里是视频 A 的 URL:http://www.youtube.com/watch?v=hWjrMTWXH28“视频最高可达 480p”

Lately I've been researching different methods for streaming MP4s to the browser. Flash Media Server is an obvious choice here (using Cloudfront), and most solutions I've seen use the RTMP protocol.

However, I spent some time on YouTube with Firebug and Chrome debugger figuring out how their streaming worked and I discovered some interesting differences between some of their videos and quality rates.

My two sample videos are A and B. A is available up to 480p and B is available up to 1080p. For both videos, all rates up to 480p are served in an FLV container with H.264 video and AAC audio, over HTTP. What's interesting here is that if you have not yet downloaded (cached) the entire video, and you try to skip forward to an uncached part of the video, a new request will be made with a 'begin' parameter equal to the target offset in milliseconds. Example from Video A at 480p:

http://v11.lscache8.c.youtube.com/videoplayback?ip=0.0.0.0&sparams=id%2Cexpire%2Cip%2Cipbits%2Citag%2Calgorithm%2Cburst%2Cfactor%2Coc%3AU0dWTldQVF9FSkNNNl9PSlhJ&fexp=904806%2C902906%2C903711&algorithm=throttle-factor&itag=35&ipbits=0&burst=40&sver=3&expire=1279756800&key=yt1&signature=D2D704D63C242CF187CAA5B5D5BAFB8DFACAC5FF.39180C01559C976717B651A7EB1D0C6249231EB7&factor=1.25&id=8568eb3135971f6f&begin=111863

Response Headers:
Cache-Control:public,max-age=23472
Connection:close
Content-Length:14320637
Content-Type:video/x-flv
Date:Wed, 21 Jul 2010 17:23:48 GMT
Expires:Wed, 21 Jul 2010 23:55:00 GMT
Last-Modified:Wed, 19 May 2010 12:31:41 GMT
Server:gvs 1.0
X-Content-Type-Options:nosniff

The file returned by this URL is a fully valid FLV containing only the portion of the video after the requested offset.

I did the same kind of test on the higher resolution versions of Video B. At 720p and 1080p, YouTube will return a video in an MP4 container, also with H.264 video and AAC audio. What's impressive to me is that their server takes the same type of offset for an MP4 video (via the 'begin' parameter) and returns a valid, streamable MP4 (moov atom at the front of the file with correct offsets) that also only includes the requested portion of the video.

So, how does YouTube do this? How do they generate the FLV or MP4 container on the fly with the correct headers and only the desired segment of the requested video? I know this can be accomplished using FFMPEG to seek to the desired start point and the qt-faststart script to reposition the moov atom to the front of the stream, but it seems like this would be too slow to handle on-demand for millions of YouTube viewers.

Ideas?

Thanks in advance!

Footnote: I am not allowed to include more than 1 link at this point, so here is Video A's URL: http:// www.youtube .com/watch?v=hWjrMTWXH28 "Video available up to 480p"

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

浅沫记忆 2024-09-17 12:15:59

在这个论坛上也有人提出了类似的问题。
http://www.flashforum.de/forum /video/flv-ab-beliebiger-position-streamen-248483.html

有两种可用的解决方案:

  1. 使用流媒体服务器
  2. 使用以您选择的编程语言编写的文件包装器(示例是用 php 编写的) )

在这两种解决方案中,您都需要使用 flvmid 修改所有视频,以将关键帧信息添加到 flv 视频中。

在第二个解决方案中,您的 php 脚本接收上面发布的请求并解析 flv-video,直到它到达参数 begin 指定的位置。之后,它开始将视频内容推送给页面访问者。
阅读该主题以获取更多信息和 php 代码示例。

原始帖子是用德语编写的,但您可以使用 http://translate.google.com 来获得糟糕的英语:)

您发布的 HTTP 响应包含以下行:

Server:gvs

也许gvs 意味着类似“Google 视频服务器”的内容。我搜索了gvs,但找不到任何有价值的东西。

A simular question has been asked at this forum.
http://www.flashforum.de/forum/video/flv-ab-beliebiger-position-streamen-248483.html

There are two solutions avaiable:

  1. Use a streaming server
  2. Use a file-wrapper written in a programming-language of your choice (example is written in php)

In both solutions you need to modify all your videos f.e. using flvmid to add the key-frame-informations to the flv-video.

In the second solution you php-script recives the request you've posted above and parses the flv-video until it reaches the position given by the parameter begin. After that it starts to push the video-content to the page-visitor.
Read the thread to get more informations and a php-code-examples.

The original thread is written in german but you can use http://translate.google.com to get a bad english :)

The HTTP-Response you've posted contains the following line:

Server:gvs

Maybe gvs means something like "Google Video Server". I've searched for gvs but I could not find anything of value.

零時差 2024-09-17 12:15:59

查看 NGINX 服务器,它有专门执行此操作的模块。作者对 FLV 和 MP4 容器进行了所有解析和重写,以按照所需的确切偏移量进行输出。流媒体部分不需要 ffmpeg,因为它太过分了。

Have a look in to the NGINX server, it has modules to do exactly this. The author did all the parsing and rewriting of the FLV and MP4 containers to output on the exact required offset. No need for ffmpeg at the streaming part as it would be overkill.

慕巷 2024-09-17 12:15:59

Youtube 使用lighttpd 服务器进行流媒体播放。它实际上使用伪流而不是流。这种机制允许观看者寻找视频中尚未下载的部分

Youtube uses lighttpd server for streaming. It actually uses pseudo streaming not streaming. This mechanism allows viewers to seek to not-yet downloaded parts of a video

冰魂雪魄 2024-09-17 12:15:59

我不认为 YouTube 使用 FFMPEG 进行流媒体播放。容器格式,无论是 flv 还是 mp4,都很简单,并且计算量不大。重要的是找到距指定 begin 时间戳最近的关键帧并从它开始。

I don't think YouTube use FFMPEG for its streaming. Container format, either flv or mp4, is simple enough and is not computation intensive. It's important only to find the nearest key-frame to specified begin timestamp and to start from it.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文