应用程序从后台返回前台时,暂停的音频会自动播放:

9

applicationDidEnterBackground: 被触发时,我使用 AVAudioPlayer 暂停正在播放的音频:

[self.avPlayer pause];

现在,当applicationWillEnterForeground:被触发时,音频会自动开始播放!由于我没有开始播放音频,用户界面没有更新,仍然显示音频处于暂停状态。
发生了什么?这是在iPad 2上的iOS 6.x中发生的,这个问题在运行iOS 5.x的老一些的iPad上不会出现。
这是我设置AVAudioSession的方法:
// Setup the audio session
BOOL succeeded = NO;
NSError *sessionError = nil;
AVAudioSession *session = [AVAudioSession sharedInstance];
[session setDelegate:self];

if ([session respondsToSelector:@selector(setPreferredSampleRate:error:)]) {
    succeeded = [session setPreferredSampleRate:128000.0f error:&sessionError];

} else {
    succeeded = [session setPreferredHardwareSampleRate:128000.0f error:&sessionError];
}

succeeded = [session setCategory:AVAudioSessionCategorySoloAmbient error:&sessionError];
succeeded = [session setActive:YES error:&sessionError];

为什么你不在applicationWillEnterForeground:方法中再次执行[self.avPlayer pause];呢? - soryngod
你在哪里使用这段代码? - user2435304
这种方法有点靠试错(在我看来)。话虽如此,:) 我确实尝试过了,但它并没有起作用!我不知道这里是使用了什么样的魔法。 - Mustafa
AVAudioSession在应用程序启动时设置。 - Mustafa
5个回答

3

2020年还没有解决方案吗?

关于这个荒谬的问题。它似乎真的是iOS系统中的一个普通bug。

我们唯一真正找到的解决方案是:

在所有三个代理调用中...

func applicationWillResignActive(_ application: UIApplication) {
    yourPlayer.handleAppResign()
}

func applicationDidEnterBackground(_ application: UIApplication) {
    yourPlayer.handleAppResign()
}

func applicationWillTerminate(_ application: UIApplication) {
    yourPlayer.handleAppResign()
}

当你处理特定情况时,你会有:

func ...handleThat() {
    yourAVPlayer?.rate = 0
}

实际上,只需添加以下内容:
func ...handleThat() {
    yourAVPlayer?.rate = 0
    yourAVPlayer = nil
}

通常情况下你不会这样做,因为你通常只是暂停。

但事实上,这似乎是解决疯狂的“苹果自动取消暂停”的唯一方法。

看起来没有其他办法。


1
我发现一些奇怪的用户体验问题,当从后台返回应用时会出现问题。根据一些帖子,我计划进行一些小的调整。我做了一些相对简单的事情——在应用进入前台时检查是否正在播放其他音乐:
    func applicationWillEnterForeground(application: UIApplication) {
         if AVAudioSession.sharedInstance().otherAudioPlaying{                 
NSNotificationCenter.defaultCenter().postNotificationName(Notifications.ForegroundEnteredWithOtherAudioPlaying, object: nil)
         }
    }

如果是这样,当接收到那个通知时,您可以暂停播放器。您提到这没有起作用,但是没有看到您的其余代码,很难知道原因。
我还需要做的另一件事是从播放器项目中删除对状态标志的观察者,因为我监听ReadyToPlay值以告诉AvPlayer实际播放。当应用程序进入前台并且存在活动音频会话时,就会触发该值。因此,在暂停时删除该观察者,并在每次播放时设置它(这并不疯狂,因为我认为只有在开始播放后才关心观察),我能够控制很多奇怪的事情。
我还编写了一堆测试用例,我将在此分享,以确保您的体验非常好。它不是全面的,但也相当详尽。
    // 1. Play, leave app, don't open anything else, come back
    // 2. Play, leave app, open an app that plays music, come back
    // 3. Play, leave app, open an app that plays music, play music, come back
    // 4. Play, let audio go for 5 seconds, pause, open an app that plays music, come back
    // 5. Play, let audio go for 5 seconds, pause, open an app that plays music, play music, come back
    // 6. Press play, leave app before playback starts, open an app that plays music, come back
    // 7. Crazy s$*t like play, leave app, open an app that plays music, play music, come back, tap a different song 

1
在我最近的一个应用程序中,我发现了一个类似的问题,即音频播放会自动暂停,并在您接到电话并且GUI未刷新时恢复。我通过使用以下方法解决了这个问题:
在处理播放器代码的类中注册此内容。
[[UIApplication sharedApplication] beginReceivingRemoteControlEvents];

使用 AVAudioSessionaudioPlayerEndInterruption 委托方法,在应用程序恢复后获得控制。在此函数中,您可以恢复播放并相应地更新UI。

- (void)audioPlayerEndInterruption:(AVAudioPlayer *)player withOptions:(NSUInteger)flags

希望这有所帮助。

0

我也遇到了同样的问题。所以我注册了我的类来监听UIApplicationWillResignActive事件,并在接收到通知时暂停音频。


0

HRM的解决方案对我没用。唯一让它避免自动恢复播放的方法是使用stop:[self.avPlayer stop]


AVPlayer中没有"stop"这样的调用。 - Fattie

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接