88

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

这篇文章是我在搜索时找到的最接近的东西......我尝试了手刹和数据转圈,但似乎都没有任何区别:

关于如何做到这一点或是否有可能的任何想法?

这是我正在使用的代码:

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

2 回答 2

161
  1. 确保moov(metadata) 在mdat(audio/video data)之前。这也称为“快速启动”或“网络优化”。例如,Handbrake 有一个“Web Optimized”复选框ffmpegavconv有输出选项-movflags faststart
  2. 确保您的 Web 服务器报告正确的内容类型 (video/mp4)。
  3. 确保您的 Web 服务器配置为处理字节范围请求
  4. 确保您的 Web 服务器没有在 mp4 文件的压缩之上应用 gzip 或 deflate 压缩。

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

于 2012-04-26T09:16:50.510 回答
7

这是我用来在 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;
}
于 2016-08-31T10:24:15.543 回答