5

我有一个应用程序,该应用程序当前附带了它可以播放的所有视频。这不能很好地扩展,除非您想播放所有电影,否则会浪费磁盘空间。由于您必须重新下载所有电影,因此升级应用程序也不太理想。

我想做的是即时下载电影,在下载时播放,然后如果下载成功,将其保存到文件系统,以便下次他们想观看时,它会从本地文件流式传输。

我可以对视频做任何需要的事情,但目前我将它作为来自 Amazon S3 的 .mp4 文件提供,具有视频/mp4 的 mimetype,所以我的问题的前半部分工作正常:电影下载,一旦 MPMovieViewController 认为下载“足够”,它就会开始播放它。

有没有办法利用该视频文件的缓存,以便我可以保存它并控制它在文件系统上的驻留时间?这似乎是最简单的方法。

我的目标是 iOS 5+6,但如果唯一可用的解决方案需要 iOS 6,我也会考虑。谢谢!

更新:使用 AFNetworking,我想我现在已经完成了一半。我正在从服务器下载视频文件,并监听下载进度。一旦我看到 25% 的视频已下载,我开始使用 MPMoviePlayerController 播放本地文件。

我现在遇到的主要问题是播放似乎搞砸了。一切正常,下载了 25%,开始播放……下载继续正常……然后文件完全下载完毕,不久后视频冻结。屏幕播放计时器仍指示播放正在进行,我没有看到任何“播放完成”类型的通知,但视频被冻结。我基于这种行为的猜测是,视频播放的初始缓冲区可能已用完,并且现在没有检测到磁盘上有更多视频可用?

有什么方法可以与 MPMoviePlayerController 交互,让它知道定期刷新它正在播放的缓冲区吗?或者其他方式来处理这种情况?

4

2 回答 2

8

更新:确保从@TomHamming 看到更新的答案。

我还没有找到一个确凿的答案,但目前我相信答案是:你不能可靠地做到这一点。至少不是没有很多看起来太像黑客的工作。我向 Apple 提交了功能请求,因为通过对 MPMoviePlayerController 进行一些调整,这似乎是可能的。

我将回顾我尝试或考虑的各种事情,以及我遇到的结果。

  • 将 MPMoviePlayerController 传递给您的电影文件的 URL,它允许它流式传输,然后将文件从保存到的缓存中拉出到您的本地 Documents 文件夹中。从 iOS 6 起将无法正常工作。我向 Apple 提交了功能请求,但就目前而言,您无法获得他们正在下载的文件 AFAIK。

  • 开始使用 NSURLConnection(或类似 AFNetwork)下载电影文件,然后当“相当数量”下载到设备时,将文件 URL 传递给 MPMoviePlayerController 并让它从磁盘流式传输。有点作品,但不是很好。三个问题:

    • 真的很难知道什么时候开始播放文件。我还没有弄清楚Apple使用的算法,所以我总是谨慎行事,等待25%下载后再玩。

    • MPMoviePlayerController 接口不提供电影正在流式传输的感觉,就像 Apple 通过网络进行计算时一样。在用户看来,文件已完全下载,但实际上并非如此。

    • 最重要的是,MPMoviePlayerController 似乎无法很好地播放未完全下载的文件。一旦文件完成下载,或者播放器赶上了下载量,我就遇到了播放问题,并且从未找到处理这些情况的优雅方法。

  • 与上面相同的过程,但使用 AVFoundation 类来更精细地控制播放过程,并避免上述关于播放停止等问题。可能有效,但我想要 MPMoviePlayerController 的所有功能。自己重新实现 MPMoviePlayerController 只是为了获得这一功能似乎是在浪费时间。

  • 与上面 #1 相同的过程,但在您的应用程序中运行一个小型 Web 服务器来处理将视频从磁盘流式传输到 MPMoviePlayerController,希望流式传输能够像直接从外部网络流式传输文件时那样正常工作服务器。工作,但结果仍然是零星的,性能似乎受到影响。我用CocoaHTTP做了我的测试。我决定反对这种方法,因为它感觉就像一个可怕的黑客攻击。

  • 运行轻量级 HTTP 代理,从而在下载的电影文件数据从 Internet 流式传输到您的 MPMoviePlayerController 时对其进行拦截。不确定这是否有效。我还不能对此进行测试,因为我还没有找到一个用 Objective-C 编写的轻量级 HTTP 代理,并且此时不想实现一个只是为了尝试这个实验。这似乎是所有这些黑客中最容易实现的——如果您不必编写代理!

在这一点上,我决定采用不那么骇人听闻但也不那么用户友好的路线,即完全下载文件,然后将其传递给 MPMoviePlayerController,直到出现更好的解决方案。

于 2012-09-29T02:45:21.573 回答
2

从 iOS 10 开始,您可以使用AVAssetDownloadTask. 请参阅此 WWDC 2016 会议此文档

或者,如果您的电影没有经过 DRM 处理,您可以使用AVAssetResourceLoaderDelegate来执行此操作,这可以有效地让您提供AVPlayer任意字节流。请参阅此演练

于 2018-04-04T17:00:49.760 回答