11

我们正在开发一个需要通过AVPlayer播放视频文件的应用程序。文件需要存储在用户的设备上,还必须在下载的同时播放。

目前我们已经构建了一个下载模块,它使用ASIHTTPRequest库通过 PHP 获取视频文件(我们不希望媒体可以通过公共 URL 链接)并将它们异步写入磁盘。

然后,我们根据AV Foundation Programming Guide设置了一个 AVPlayer ,使用 AVURLAsset 获取文件,使用资产创建 AVPlayerItem,使用项目构建 AVPlayer,然后将播放器设置为 AVPlayerLayer。播放器在完全下载的视频文件下运行良好,并且在模拟器中也能很好地运行逐步下载的文件。

不幸的是,在实际设备上,播放器的行为发生了变化,相反,它似乎只加载了一次视频,并没有尝试从磁盘中获取新的数据包。结果是播放器将播放视频和音频,直到视频中标记资源加载时下载进度的位置(例如,如果缓冲 2MB 的数据然后创建播放器,播放器将只播放高达 2MB 的数据)。因为它有视频的标题,播放器会很高兴地继续认为它正在播放整个视频,但没有其他视频被渲染到屏幕上。

最后一个问题是,如果将视频插入 AVComposition 并使用它创建 AVPlayer,则渐进式视频将可以正常播放。这将是一个很好的解决方案(有时对于我们的应用程序来说是必需的),除了我们应用程序的客户端要求视频可以通过 AirPlay 在 Apple TV 上播放,而 AVCompositions 无法做到这一点。

有谁知道是否有一种方法可以使用从 AVURLAssets 构建的 AVPlayer 逐步下载视频文件?有没有办法强制 player/playerItem 使用 AVURLAsset 从磁盘读取它似乎与 AVComposition 一样,而不是看似将视频缓存在内存中?

谢谢!

4

1 回答 1

6

我没有一个解决方案来让它与 AVURLAssets 一起工作,但我使用了一种稍微不同的方法。我们将我们的应用程序与CocoaHTTPServer捆绑在一起,并通过对本地服务器的 HTTP 请求播放未完全下载的视频文件。

服务器知道文件的总长度,然后可以通过查看 HTTP-Headers 来决定文件的哪一部分是请求的,然后从磁盘或远程源加载它。

在那里开发时,总是有 3 个初始请求,一个用于文件的前两个字节,一个来自文件开头的较大块,一个直接来自文件末尾的块。这就是为什么总是需要直接从远程服务器加载至少最后一部分,因为玩家从一开始就需要它。我猜本地文件也会发生同样的情况,因此播放器从文件中加载最后一个字节(不是正确的最后一个字节)并且不会播放该长度。

您必须通过查看提供的“HTTPAsyncFileResponse”来继承 HTTPConnection 并创建自己的 HTTPResponse 类。

我希望这能让您了解如何使用不同的方法来完成此任务。

于 2013-02-13T12:46:30.490 回答