最近我一直在研究将 MP4 流式传输到浏览器的不同方法。Flash Media Server 是一个明显的选择(使用 Cloudfront),我见过的大多数解决方案都使用 RTMP 协议。
然而,我花了一些时间在 YouTube 上使用 Firebug 和 Chrome 调试器来弄清楚他们的流媒体是如何工作的,我发现他们的一些视频和质量率之间存在一些有趣的差异。
我的两个示例视频是 A 和B。A 最高可达 480p,B 最高可达 1080p。对于这两个视频,所有高达 480p 的速率都通过 HTTP 在带有 H.264 视频和 AAC 音频的 FLV 容器中提供。这里有趣的是,如果您还没有下载(缓存)整个视频,并且您尝试向前跳到视频的未缓存部分,则会使用等于目标偏移量的 'begin' 参数发出新请求毫秒。来自视频 A 的 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
此 URL 返回的文件是完全有效的 FLV,仅包含请求的偏移量之后的视频部分。
我对视频 B 的更高分辨率版本进行了同样的测试。在 720p 和 1080p 时,YouTube 将返回一个 MP4 容器中的视频,还包含 H.264 视频和 AAC 音频。令我印象深刻的是,他们的服务器为 MP4 视频采用相同类型的偏移量(通过 'begin' 参数)并返回一个有效的、可流式传输的 MP4(具有正确偏移量的文件前面的 moov atom),它也只包括视频的请求部分。
那么,YouTube 是如何做到这一点的呢?他们如何使用正确的标头和仅请求视频的所需片段即时生成 FLV 或 MP4 容器?我知道这可以使用 FFMPEG 来寻找所需的起点并使用 qt-faststart 脚本将 moov 原子重新定位到流的前面来完成,但这似乎太慢而无法按需处理数百万YouTube 观众。
想法?
提前致谢!
脚注:此时我不允许包含超过 1 个链接,所以这里是视频 A 的 URL:http://www.youtube.com/watch?v=hWjrMTWXH28“视频最高可达 480p”