HTML5-如何流式传输大的.mp4文件?


77

我正在尝试设置一个非常基本的html5页面,该页面会加载20MB的.mp4视频。看来,浏览器需要下载整个内容,而不仅仅是播放视频的第一部分并在其余部分进行流传输。

这篇文章是我在搜索时发现的最接近的内容...我尝试了“手刹”和“数据转弯”,但两者均未发挥作用:

关于如何执行此操作或是否可行的任何想法?

这是我正在使用的代码:

<video controls="controls">
    <source src="/video.mp4" type="video/mp4" />
    Your browser does not support the video tag.
</video>

Answers:


145
  1. 确保moov(元数据)在mdat(音频/视频数据)之前。这也称为“快速启动”或“网络优化”。例如,Handbrake具有“ Web优化”复选框,而ffmpegavconv具有输出选项-movflags faststart
  2. 确保您的Web服务器报告的内容类型正确(视频/ mp4)。
  3. 确保将您的Web服务器配置为服务字节范围请求
  4. 确保您的Web服务器未在mp4文件中的压缩之上应用gzip或放气压缩。

您可以使用curl -I http://yoursite/video.mp4或使用浏览器中的开发人员工具(ChromeFirefox)检查Web服务器发送的标头(如果已缓存页面,请重新加载页面)。的HTTP响应头应包括内容-类型:视频/ MP4接受-范围:字节,并且没有内容编码:


我在网上找不到好的答案...是否有应用程序或简便的方法来检查moov元数据及其在文件中的位置?
longda

2
@longda:可以显示mp4文件结构的命令行实用程序包括L-SMASH boxdumper,Atomic Parsley-T和mp4v2 mp4file --dump
mark4o 2014年

3
为了记录(主要是因为我是个白痴),您可以通过命令行调用,如下所示:(atomicparsley <filename> -T选项位于最后)。再次感谢@ mark4o的所有帮助!
隆达2014年

1
@Matheretter:“快速启动”或“网络优化”仅表示moov开头而不是结尾,这允许在下载整个文件之前使用字节范围请求。如果这导致搜索不起作用,请检查正在处理字节范围请求的代码中的错误,如果moov末尾将不使用该错误(到知道所需的字节时,该错误便已经下载了)。整个文件)。我在另一个问题中看到,您已经为此编写了自定义php代码。
mark4o

1
您对此有参考吗?
0xcaff '16

6

这是我用来在C#(MVC)中创建Web API控制器的解决方案,该控制器将为具有字节范围(部分请求)的视频文件提供服务。部分请求允许浏览器仅下载所需播放的视频,而不下载整个视频。这使其效率更高。

请注意,这仅适用于最新版本。

var stream = new FileStream(videoFilename, FileMode.Open, FileAccess.Read , FileShare.Read);

var mediaType = MediaTypeHeaderValue.Parse($"video/{videoFormat}");

if (Request.Headers.Range != null)
{
    try
    {
        var partialResponse = Request.CreateResponse(HttpStatusCode.PartialContent);
        partialResponse.Content = new ByteRangeStreamContent(stream, Request.Headers.Range, mediaType);

        return partialResponse;
    }
    catch (InvalidByteRangeException invalidByteRangeException)
    {
        return Request.CreateErrorResponse(invalidByteRangeException);
    }
}
else
{
    // If it is not a range request we just send the whole thing as normal
    var fullResponse = Request.CreateResponse(HttpStatusCode.OK);

    fullResponse.Content = new StreamContent(stream);
    fullResponse.Content.Headers.ContentType = mediaType;

    return fullResponse;
}

2
这个答案很简单,并且处理非常简单的流式传输。完美工作
James Woodall 2016年
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.