ios - AVAudioPlayer 丢失 "Playing"状态

标签 ios avaudioplayer

我有一个 AVAudioPlayer 需要在后台继续运行。

音频在 plist 中设置为背景模式,并且在启动时运行:

[[UIApplication sharedApplication] beginReceivingRemoteControlEvents];
[[RootController shared].view becomeFirstResponder];

AVAudioSession* session = [AVAudioSession sharedInstance];
[session setDelegate: self];
[session setActive:YES error:nil];
[session setCategory: AVAudioSessionCategoryPlayback error:nil];

- (BOOL)canBecomeFirstResponder { return YES; }

问题

有时 AVAudioPlayer 会进入这种奇怪的状态:

  • 正在播放,但是状态栏的播放图标消失了
  • 如果我暂停然后播放,图标可能会显示一秒钟,然后消失
  • 关键是 - 如果我在播放时调用 setCurrentTime,播放图标会显示并保持不变

我已经为此投入了大约 20 个小时,希望有任何想法。

最佳答案

漏洞描述

如果您正在播放 AVAudioPlayer 然后您创建 AVPlayer,播放图标将消失。显然 AVPlayer 立即获得优先权,因为它尚未播放,播放图标从状态栏中消失。

这会导致一些严重的问题:

  1. 如果应用程序在后台,iOS 将在 5 秒内关闭您的 AVAudioPlayer(因为它没有意识到您正在播放音频)
  2. 即使正在播放音频,iOS Remote 也会显示播放按钮
  3. 状态栏中没有显示播放图标

解决方法

首先,如果您不必使用 AVPlayer,那就别用。我使用它是因为我需要在不先下载的情况下播放远程 MP3。我以前用这个AudioStreamer类但放弃了,因为当流断开连接时它会弹出警报以及我无法修复的其他一些错误。

因此,如果您受困于 AVPlayer,只有一种方法可以重新连接您的 AVAudioPlayer 的播放状态。 如果您在 AVAudioPlayer 上调用 setCurrentTime,那么它会神奇地将自己重新关联为应用程序的当前播放器。因此,您需要在初始化任何 AVPlayer 之后以及在 AVAudioPlayer 上恢复播放时调用它。

我决定将 AVAudioPlayer 子类化,这样我就可以在全局列表中注册它(当它被初始化时)并在它被释放时注销它。我还覆盖了 play 方法,以便任何恢复播放的调用也将调用 setCurrentTime。然后我将 AVPlayer 子类化,以便在任何时候初始化一个,所有事件的 AVAudioPlayer 都会自己调用 setCurrentTime。最后一件事 - 您必须在短时间(可能是 1 秒)延迟后调用 setCurrentTime,否则它将无效。

不是开玩笑,这是将近 40 小时的故障排除的结果。

关于ios - AVAudioPlayer 丢失 "Playing"状态,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11894600/

相关文章:

ios - 具有约束的 Swift 协议(protocol)扩展不会使类符合该协议(protocol)

ios - Swift UnsafeMutablePointer<Unmanaged<CFString>?> 分配和打印

iphone - 如何在iPhone App中添加音频播放器

objective-c - 为不同的声音重用 AVAudioPlayer

ios - 播放简单的声音

objective-c - UIView setNeedsDisplay 调用CALayer 的setNeedsDisplay?

ios - 当超出 UITableViewCell 边界时, subview 会被修剪

swift - 8000 PCM格式的AVAudioEngine如何录音播放?

ios - 以椭圆形剪辑 UIImage 的顶部

ios4 - 如何在按下按钮后每秒必须播放简短声音的情况下释放AVAudioPlayer对象