在后台模式下使用AVSpeechSynthesizer

27

我在iOS 7下无法使AVSpeechSynthesizer在我的iOS应用程序处于后台模式时工作。我已将"App plays audio"键添加到应用程序支持的后台模式中,但仍无法使其正常工作。

我还调查了创建一个带有AVSpeechSynthesizer话语的AVMutableCompositionTrack的可能性,然后以某种方式使用能够在后台运行的播放器进行播放,但没有成功。

是否有人在后台使用AVSpeechSynthesizer方面比我更加成功?

4个回答

43
  1. 您必须���“音频和AirPlay”设置为后台模式。
  2. 您需要配置音频会话:
    NSError *error = NULL;
    AVAudioSession *session = [AVAudioSession sharedInstance];
    [session setCategory:AVAudioSessionCategoryPlayback error:&error];
    if(error) {
        // Do some error handling
    }
    [session setActive:YES error:&error];
    if (error) {
        // Do some error handling
    }

这真的允许你在音频后台模式下播放吗? - Chris Truman
1
@ChrisTruman,我可以确认它有效。imihaly,"session setActive"调用是否会导致您的应用程序在后台运行并增加应用程序的功率要求?我将进行一些测试,但我猜答案是肯定的,因此您需要在上面进行调用,播放合成语音,然后在完成后将会话的活动状态设置回“否”。 - Duncan C
1
@imihaly,我用了你的代码,很好用。(+1)根据我的测试,应用程序似乎不能在后台持续运行。然而,我正在开发的应用程序旨在长时间运行在后台,并且在其生命周期内可能会被多次挂起。有时候语音合成出现问题,原因我不明白。有什么想法? - Duncan C
在8.3模拟器中对我有效。 - Andrew Duncan
我可以补充一下,AVAudioSessionCategorySoloAmbient 在模拟器中可以正常工作(音频可以在后台播放),但在硬件上不行。至少在我的情况下(通过 handleWatckKitExtensionRequest 触发音频)。按照上面建议的更改类别为 Playback 可以解决问题。 - Andrew Duncan
显示剩余2条评论

9

这段代码在Swift 5中对我有效。

    do {
       try AVAudioSession.sharedInstance().setCategory(.playback, mode: .default, options: AVAudioSession.CategoryOptions.mixWithOthers)
       try AVAudioSession.sharedInstance().setActive(true)
    } catch {
        print(error)
    }

    let utterance = AVSpeechUtterance(string: voiceOutdata)


    let synth = AVSpeechSynthesizer()
    synth.speak(utterance)

根据https://forums.developer.apple.com/thread/38917, 当会话可混合时,AVAudioSessionCategoryOptionMixWithOthers选项与播放类别一起添加, 在允许播放音频之前会进行一些内部检查,以确定应用程序唤醒的原因。

9

对于Swift 3,导入AVKit(或AVFoundation),然后添加以下代码:

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

可以使用viewWillAppear()来实现音频播放,无论静音开关的状态和屏幕是否关闭。

* 编辑:AVAudioSession定义在AVFoundation中,同时也可与AVKit一起使用。

* 编辑2:自动完成屏幕截图显示AVAudioSession可在AVKit中使用。

输入图片描述


AVKit必须被AVFoundation替换,并且在后台模式中设置“音频和AirPlay”仍然是必需的。 - cristallo
AVKit是更高级别的框架,AVFoundation是用于更精细控制的框架,但AVKit并不会被AVFoundation取代。 - Chris
我并不是在说AVFoundation是AVKit的替代品。我只是在说AVAudioSession不包含在AVKit中,而是在AVFoundation中。因此,在这种情况下,你应该包含AVFoundation。 - cristallo

0

@imihaly说过:“你必须在后台模式中设置“音频和AirPlay”。” 这是可以理解的看图片

你需要从那里启用它, 其次,在AVSpeechSynthesizer代码部分,你必须编写以下代码

 let audioSession = AVAudioSession.sharedInstance()
            try! audioSession.setCategory(
                AVAudioSession.Category.playback,
                options: AVAudioSession.CategoryOptions.duckOthers
            )
                 

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