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/mp4 和 Accept-Ranges: bytes,并且没有 Content-Encoding:。 p>
【讨论】:
我在网上没有找到好的答案...有没有应用程序或简单的方法来检查 moov 元数据及其在文件中的位置? @longda:可以显示 mp4 文件结构的命令行实用程序包括 L-SMASHboxdumper
、Atomic Parsley -T
和 mp4v2 mp4file --dump
。
为了记录(主要是因为我是个白痴),您可以通过命令行调用如下:atomicparsley <filename> -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 文件?的主要内容,如果未能解决你的问题,请参考以下文章
如何下载(或以 blob 形式获取)用于流式传输 HTML5 视频的 MediaSource?
如何将 .MP4 文件等本地文件流式传输到 Chrome Cast?