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

Posted

技术标签:

【中文标题】HTML5 - 如何流式传输大型 .mp4 文件?【英文标题】:HTML5 - How to stream large .mp4 files? 【发布时间】:2012-05-06 21:20:53 【问题描述】:

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

This post 是我在搜索时发现的最接近的东西...我尝试了 Hand Brake 和 Data Go Round,但似乎都没有任何区别:

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

这是我正在使用的代码:

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

【问题讨论】:

【参考方案1】:
    Ensure that the moov (metadata) is before the mdat (audio/video data)。这也称为“快速启动”或“网络优化”。例如,Handbrake has a "Web Optimized" checkbox、ffmpeg 和 avconv 具有输出选项 -movflags faststart。 确保您的网络服务器报告正确的内容类型 (video/mp4)。 Ensure that your web server is configured to serve byte range requests。 确保您的网络服务器没有在 mp4 文件的压缩之上应用 gzip 或 deflate 压缩。

您可以使用 curl -I http://yoursite/video.mp4 或使用浏览器中的开发人员工具(Chrome、Firefox)检查 Web 服务器发送的标头(如果页面被缓存,请重新加载)。 HTTP Response Header 应包含 Content-Type: video/mp4Accept-Ranges: bytes,并且没有 Content-Encoding:。 p>

【讨论】:

我在网上没有找到好的答案...有没有应用程序或简单的方法来检查 moov 元数据及其在文件中的位置? @longda:可以显示 mp4 文件结构的命令行实用程序包括 L-SMASH boxdumper、Atomic Parsley -T 和 mp4v2 mp4file --dump 为了记录(主要是因为我是个白痴),您可以通过命令行调用如下:atomicparsley &lt;filename&gt; -T(选项在最后)。再次感谢@mark4o 的所有帮助! @Matheretter:“快速启动”或“网络优化”只是意味着moov 位于开头而不是结尾,这允许在下载整个文件之前使用字节范围请求进行搜索。如果这导致寻求不起作用,请检查处理字节范围请求的代码中的错误,如果 moov 位于末尾(当它知道它需要哪些字节时)将不会使用它已经下载了整个文件)。我在您的其他问题中看到您为此编写了自定义 php 代码。 你有这个参考吗?【参考方案2】:

这是我用来在 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;

【讨论】:

这个答案很简单,可以处理非常简单的流式传输。完美运行

以上是关于HTML5 - 如何流式传输大型 .mp4 文件?的主要内容,如果未能解决你的问题,请参考以下文章

HTML5 视频 - 从 SQL 文件流中流式传输

如何下载(或以 blob 形式获取)用于流式传输 HTML5 视频的 MediaSource?

如何将 .MP4 文件等本地文件流式传输到 Chrome Cast?

伪流式传输 MP4 文件

如何使用 MPEG DASH 流式传输和捕获 MP4 文件?

如何使用 Node.js 通过 ffmpeg 流式传输 MP4 文件?