如何从 S3 流式传输 MP4 视频,而无需 AVPlayer 在播放前下载文件?

Joa*_*ona 8 amazon-s3 amazon-web-services ios avplayer swift

我在公共 S3 存储桶中有很多长(45 分钟 - 90 分钟)MP4 视频,我想使用AVPlayer.

我经常AVPlayerViewController播放它们,但我需要等待几分钟才能开始播放,因为它会下载整个视频而不是流式传输。

我在本地缓存它,所以这只是第一次发生,但我很想流式传输视频,这样用户就不必等待整个视频下载。

有些人指出我需要 Cloudfront 来流式传输视频,但在文档中,我读到只有当很多人流式传输同一个文件时才需要这样做。我正在构建 MVP,所以我只需要一个简单的解决方案。

有没有办法从 S3 存储桶流式传输 MP4 视频,而AVPlayerViewController无需在向用户播放之前完全下载文件?

Erm*_*ary 16

总长DR

AVPlayer不支持您定义的“流”(HTTP 范围请求),因此要么使用支持的替代视频播放器,要么使用真正的媒体流协议(如 HLS),该协议受AVPlayer& 支持,会在下载全部内容之前启动视频。

CloudFront 非常适合一般交付,但并不是真正需要的 - 您可能已经看到它因 CloudFront RTMP发行版而被提及,但它们现在已停止使用


详细解答

S3 支持使用HTTP 范围请求进行字节范围提取的概念- 您可以通过对视频文件执行 HEAD 请求并查看标头是否存在且值设置为字节(或不是“无”)来验证这一点。Accept-Ranges

在浏览器中加载您的 MP4 文件并注意,一旦您单击“播放”,它就会开始播放。您还可以移至视频文件的末尾,但您尚未真正下载整个视频文件。HTTP 范围请求使该机制得以发挥作用。当用户到达视频的该部分时,可以下载视频的小块。这节省了文件服务器和用户带宽,同时提供比客户端下载整个文件更好的用户体验。

服务器需要首先支持字节范围提取,然后客户端才能决定发出范围请求(或不发出)。关键是,一旦服务器支持,HTTP 客户端就可以决定是分块获取数据还是一次性获取数据。

正如您所知道的那样,这并不是真正的“流媒体”,而是使用 HTTP 206 部分内容响应“从服务器分块下载视频并播放它”。

在视频中搜索时,您可以在浏览器的“网络”选项卡中将其视为一系列多个 206 响应。不会下载整个视频,但视频会从您跳到的任意位置进行流式传输。

该图显示了在浏览器中加载视频并移动到视频中的随机点时 Google Chrome 网络选项卡中的多个 HTTP 206 部分内容响应; 突出显示 HTTP 范围请求


问题在于AVPlayer

不幸的是,AVPlayer不支持使用 HTTP 范围请求和 HTTP 206 部分内容响应的“流式传输”。我已通过在 Xcode 中创建演示 iOS 应用程序来手动验证这一点。

这与 S3 无关- 如果您将这些文件存储在任何其他云提供商或文件服务器上,您会看到该文件在播放前仍然已完全加载。


可能的解决方案

现在问题已经明确了,解决办法有2种。

使用替代视频播放器

最简单的解决方案是使用支持字节范围提取的替代视频播放器。我不是 iOS 开发方面的专家,所以遗憾的是我无法推荐一个替代方案,但我确信将会有一个业界更喜欢的流行库,而不是内置的AVPlayer. 这将为您提供“流媒体”的(极其常见的)定义。

使用视频流协议

但是,如果您必须使用AVPlayer,解决方案是使用视频流协议实现真正的媒体流 - 真正的流还允许您利用自适应比特率切换、实时音频切换、许可等功能。

有很多可用的协议,例如DASH(基于 HTTP 的动态自适应流媒体)、SRT(安全可靠传输)以及最后但并非最不重要的HLS(HTTP 实时流媒体)。

如今,互联网上使用最广泛的流媒体协议是 HLS,由 Apple 自己创建(嘿,也许不支持范围请求的原因是强迫您使用该协议)。如果您有兴趣, Apple 自己的文档非常适合您深入研究。

在无需过多了解协议细节的情况下,HLS 将允许播放通常更快地开始,快进可以更快,并在观看视频时提供真正的流媒体体验。

要继续使用 HLS:

  1. 使用AWS Elemental MediaConvert将 MP4 文件转换为 HLS 格式 -.M3U8.ts媒体片段文件外,生成的输出还将是 1 个(或更多)清单文件

  2. 将结果输出上传到 S3

  3. 指向AVPlayer文件.M3U8

let asset = AVURLAsset(url: "https://ermiya.s3.eu-west-1.amazonaws.com/videos/video1playlist.m3u8")
let item = AVPlayerItem(asset: asset)
...
Run Code Online (Sandbox Code Playgroud)
  1. 享受视频近乎即时的加载

云锋

至于Amazon CloudFront,它本身并不是必需的,在这种情况下 S3 就足够了,但快速的 Google 搜索会提到它提供的大量好处,特别是缓存,它可以帮助您节省以后的 S3 成本。


结论

如果可以的话,我会选择转换为 HLS,因为它会产生更多的可能性,并且总体上是更好的真正流媒体体验,但由于 iOS 的限制,使用替代视频播放器也能正常工作AVPlayer

是否使用 CloudFront,将取决于您的用户群、S3 的使用情况和其他因素。

当您创建 MVP 时,我建议您将 MP4 文件批量转换为 HLS 格式,而不是使用 CloudFront,否则会增加云配置的复杂性。