在不停止的情况下在后台使用 AVSpeechSynthesizer f.e。音乐应用

Use AVSpeechSynthesizer in background without stopping f.e. music app

我想知道如何正确地让我的iPhone在我的应用程序处于后台时说一个句子然后return之前玩过

我的问题与 AVSpeechSynthesizer in background mode 非常相似,但不同之处在于我希望能够 "say something" 在后台 不必停止正在播放的音乐。因此,当我的 AVSpeechSynthesizer 说话时,音乐应该暂停(或声音小一点),但随后又会继续播放。即使我的应用程序当前处于后台。

我试图存档的是在我的健身应用程序中进行 GPS 跟踪时的跟踪统计口头摘要。而且您正在听音乐的可能性很高,我不想打扰用户...

对于swift 3,导入AVKit然后添加

try? AVAudioSession.sharedInstance().setCategory(AVAudioSessionCategoryPlayback)

我自己找到了答案...

重要的部分是使用 .duckOthers 选项配置 AVAudioSession

let audioSession = AVAudioSession.sharedInstance()
try audioSession.setCategory(AVAudioSessionCategoryPlayback, with: .duckOthers)

这将播放f.e。音乐不那么响亮,但这会使它即使在演讲结束时也不会那么响亮。这就是为什么你需要为 AVSpeechSynthesizer 设置一个委托,然后像这样处理它:

func speechSynthesizer(_ synthesizer: AVSpeechSynthesizer, didFinish utterance: AVSpeechUtterance) {
    guard !synthesizer.isSpeaking else { return }

    let audioSession = AVAudioSession.sharedInstance()
    try? audioSession.setActive(false)
}

这样,语音结束后音乐会以正常音量继续播放。

此外,就在演讲之前,我激活了我的 audioSession 以确保(不确定是否真的有必要,但既然我这样做了,我就没有更多问题了...)

对于 swift 4.2 / Xcode 10

很遗憾,.duckOthers 不再可用;我设法让它像那样工作:

    let audioSession = AVAudioSession.sharedInstance()
    try! audioSession.setCategory(AVAudioSession.Category.ambient, mode: .default)

通过这两行代码之前通常的文本到语音代码:

let audioSession = AVAudioSession.sharedInstance()
try!audioSession.setCategory(AVAudioSessionCategoryPlayback, with: AVAudioSessionCategoryOptions.mixWithOthers)

Swift 5.0

let synthesizer = AVSpeechSynthesizer()
let synthesizerVoice = AVSpeechSynthesisVoice(language: "en-US")

let str = "String"
let utterance = AVSpeechUtterance(string: str)

let audioSession = AVAudioSession.sharedInstance()
try! audioSession.setCategory(
    AVAudioSession.Category.playback,
    options: AVAudioSession.CategoryOptions.mixWithOthers
)
        
utterance.rate = 0.5
utterance.voice = synthesizerVoice

synthesizer.speak(utterance)