从 AVAudioSession Ambient 模式切换到播放模式会停止其他应用程序的音频

问题描述 投票:0回答:2

如果我使用以下选项将应用程序的音频会话模式设置为 AVAudioSessionCategoryPlayback:

AVAudioSessionCategoryOptionInterruptSpokenAudioAndMixWithOthers |
AVAudioSessionCategoryOptionDuckOthers

一切运行良好,我的应用程序在后台播放 Apple 音乐时播放音频。

但是,如果我的应用程序的音频会话类别在更改为 AVAudioSessionCategoryPlayback 之前为 AVAudioSessionCategoryAmbient,Apple music(和其他音乐应用程序)将停止播放。

这是我的代码(我检查错误和返回值,但为了清楚起见,我删除了代码片段中的这些部分:

// If I comment out this call, my app will duck others... 
// If it is commented in, rather than ducking, my app stops all other audio
[[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategoryAmbient
                                 withOptions:0
                                       error:nil];
[[AVAudioSession sharedInstance] setActive:YES error:nil];

// Do other stuff in the app and at some point the following code gets called

theOptions = AVAudioSessionCategoryOptionInterruptSpokenAudioAndMixWithOthers |
                     AVAudioSessionCategoryOptionDuckOthers

[[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategoryPlayback
                                 withOptions:theOptions
                                       error:nil];

我尝试过在更改之间停用会话,但这并没有带来任何不同,每次都激活它也没有什么不同。我能找到的允许我的应用程序播放音频并回避其他应用程序的唯一方法是在我的应用程序中的任何点设置环境会话,但我需要在应用程序中的某些点播放环境音频,所以这个解决方案不可行。请帮忙:)

ios objective-c avaudiosession
2个回答
1
投票

(Swift 4 答案)在 iOS 11 上测试 - 设置环境会话时应该使用 .duckOthers 或 .mixWithOthers

func prepareSessionForPlayback() {
    do {
        try AVAudioSession.sharedInstance().setCategory(AVAudioSessionCategoryAmbient, with: [.duckOthers]) // .duckOthers or .mixWithOthers
        do {
            try AVAudioSession.sharedInstance().setActive(true)
        } catch let error as NSError {
            print (error)
        }
    } catch let error as NSError {
        print (error)
    }
}

func sessionDidFinish() {
    do { try AVAudioSession.sharedInstance().setActive(false) } catch { }
}

SessionDidFinish 完成后,您可以设置不同的选项。如果您使用 TTS,您还需要确保在调用 sessionDidFinish 之前没有在最后一句话上设置 .postUtteranceDelay。使用 AVSpeechSynthesizerDelegate 方法来捕获话语何时真正完成。


0
投票

这是一个老问题,但我最近遇到了同样的问题。要解决这个问题,您需要在播放模式下开始新的音频会话之前结束环境音频会话:

// Ambient category being used here.

let session = AVAudioSession.sharedInstance()

try? session.setActive(false, options: .notifyOthersOnDeactivation)
try? session.setCategory(.playback, options: [.mixWithOthers, .duckOthers])
try? session.setActive(true)

// Playback category being used now.
© www.soinside.com 2019 - 2024. All rights reserved.