【问题标题】:AVQueuePlayer unable to play local MP3 filesAVQueuePlayer 无法播放本地 MP3 文件
【发布时间】:2014-11-01 05:18:54
【问题描述】:

我目前正在编写一个允许用户从 soundcloud 流式传输音乐的 iOS 应用程序。目前,我可以在展台前沿和后台应用程序状态从 Soundcloud 进行流式传输。当我下载 MP3 文件并尝试播放它并在应用程序在后台持续播放时遇到问题,更具体地说是在锁定屏幕或屏幕关闭时。

当我播放下载的文件并锁定屏幕时,音频会继续播放一段时间。通常它会播放 2 -3 分钟。之后播放将停止,并且播放列表中任何其他下载的 mp3 文件将不会播放,直到用户返回应用程序。如果用户有互联网连接,播放列表中未下载的项目将完美播放,无论之前下载的项目是否无法播放。

有时我会收到以下错误:

AVPlayerItemStatusFailed: Error Domain=AVFoundationErrorDomain Code=-11800 "操作无法完成" UserInfo=0x170270500 {NSUnderlyingError=0x170059380 "操作无法完成。操作不允许", NSLocalizedFailureReason=发生未知错误 (1) , NSLocalizedDescription=操作无法完成}

我还会从 AVPlayerItem 收到以下通知

通知:NSConcreteNotification 0x1700538c0 {name = AVPlayerItemDidPlayToEndTimeNotification;对象 = AVPlayerItem:0x178009300,资产 = AVURLAsset:0x17822aaa0,URL = file:///var/mobile/Applications/51118E74-3334-4EFC-B148-B485DE675F9E/Documents/Downloads/SC_165903784.mp3}

当正在播放的第一个项目停止播放时会收到此通知。当它没有完成播放到其持续时间结束时,我收到此通知是没有意义的。

我的猜测是,因为应用程序处于后台模式,读取文件的时间设置有限,但我对此表示怀疑。

我正在使用以下内容从本地文件创建 AVPlayerItem。

NSURL* url = [NSURL fileURLWithPath:song.downloadFilePath]; [AVPlayerItem playerItemWithURL:url];

我尝试构建自己的 AVQueuePlayer 并使用 iOS Hysteria Player,但是这两个实例都给我带来了离线下载播放的相同错误。

非常感谢任何见解或解决方案。

谢谢!

【问题讨论】:

  • 我也有同样的问题……这不好。 ://
  • @jacob-pritchett 看起来我们可能不得不使用 AVAudioPlayer 来播放本地内容。现在我决定从我的应用程序中移除本地播放功能并继续使用 AVQueuePlayer。

标签: ios audio avplayer avqueueplayer avurlasset


【解决方案1】:

您是在播放 Documents 目录中的文件吗? (或者除了 app bundle 之外的任何地方?)

如果是这样,请务必使用以下命令将文件保存到目录中 [fileToSave writeToFile:filePath options:NSDataWritingFileProtectionNone error:nil];.

NSDataWritingFileProtectionNone 是关键位!至少在我的情况下,发生了什么是这样的:iOS 正在努力确保安全,因此默认情况下对您添加到 Documents 目录(以及其他非应用程序捆绑目录)的文件启用文件保护, 我相信)。通过添加 NSDataWritingFileProtectionNone,您请求系统不再对您的文件启用此保护。

来自Apple's iOS Documentation

如果您保护文件,您的应用必须准备好失去对 那个文件。启用完整文件保护后,您的应用会丢失 用户锁定时读取和写入文件内容的能力 设备。

现在,当我读到这句话时,我几乎可以肯定这是我的应用在设备锁定后无法继续播放的原因。为了安全起见,iOS 似乎默认自动将文件置于保护之下……但这会阻止包括您的应用程序在内的所有内容在设备锁定时访问它。我的错误是,一旦设备被锁定,它就只播放部分歌曲,这是有道理的……因为它对实际歌曲文件的访问被撤销,它只能播放已经播放的歌曲部分缓冲到 RAM 中!

这是我为解决长达一个月的问题而努力解决的问题。我真诚地希望它也能为您解决问题。

【讨论】:

    【解决方案2】:

    我认为这个问题是由 AVQueuePlayer 的限制引起的,HysteriaPlayer 使用 AVQueuePlayer 作为核心播放器,所以这就是原因。

    我看到 AVQueuePlayer 文档提到(很遗憾我找不到)它无法处理与本地和远程音频混合的队列。

    有一些解决方法:

    使用 AVPlayer

    不要使用AVQueuePlayer,自己处理队列,然后喂给AVPlayer。

    分离两个AVQueuePlayer

    一个用于本地媒体,一个用于远程媒体。正确插入和使用 PlayerItem 和 Player。

    我会在一个月后给 HysteriaPlayer 打补丁来满足这个要求,到时候你可以回来。

    【讨论】:

    • 感谢@olajuwon,我用 AVQueuePlayer 进行了一些测试。我从 soundcloud 下载了内容并创建了一个仅包含本地内容的队列,但我仍然遇到问题。从我的测试来看,AVQueuePlayer 似乎无法正确处理本地内容的播放。就好像文件系统在应用程序进入后台后从读取其余文件中启动了 AVQueuePlayer,而不管后台模式设置如何。我认为更好的方法是将 AVQueuePlayer 用于远程内容,将 AVAudioPlayer 用于本地。
    • 你是对的,关键是 AVQueuePlayer 无法处理混合在一起的远程和本地音频,我认为这可能与 AVQueuePlayer 的预缓冲功能有关,我不确定这一点。我正在用两个 AVPlayer 修补 HysteriaPlayer,因为很多人都有关于 AVQueuePlayer 的问题。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-04-23
    相关资源
    最近更新 更多