【问题标题】:HTML5 - How to stream large .mp4 files?HTML5 - 如何流式传输大型 .mp4 文件?
【发布时间】: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>

【问题讨论】:

    标签: html video streaming large-files


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

    您可以使用 curl -I http://yoursite/video.mp4 或使用浏览器中的开发人员工具(ChromeFirefox)检查 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;
    }
    

    【讨论】:

    • 这个答案很简单,可以处理非常简单的流式传输。完美运行
    猜你喜欢
    • 1970-01-01
    • 2014-10-29
    • 1970-01-01
    • 2011-08-01
    • 1970-01-01
    • 1970-01-01
    • 2016-02-16
    • 2013-05-27
    • 2015-06-29
    相关资源
    最近更新 更多