iOS AVSpeechSynthesizer 语音播报以及后台播报设置(Swift)

iOS AVSpeechSynthesizer 语音播报以及后台播报设置(Swift)_第1张图片

Xcode配置

  • 如果需要后台播报语音,需要到Target->Capabilities选中Background Modes 的 Audio...选项。
iOS AVSpeechSynthesizer 语音播报以及后台播报设置(Swift)_第2张图片

若不勾选此项,程序在后台运行的时候调用语音播报会报出codeCannotStartPlaying错误。

iOS AVSpeechSynthesizer 语音播报以及后台播报设置(Swift)_第3张图片

管理类文件

import AVFoundation

class SpeechUtteranceManager: NSObject {
    
    /// 单例管理语音播报 比较适用于多种类型语音播报管理
    public static let shared = SpeechUtteranceManager()
    
    var synthesizer = AVSpeechSynthesizer()
    var speechUtterance: AVSpeechUtterance?
    var voiceType = AVSpeechSynthesisVoice(language: Locale.current.languageCode)
    
    private override init() {
        super.init()
        do {
            try AVAudioSession.sharedInstance().setCategory(AVAudioSessionCategoryPlayback, with: .duckOthers)
        } catch {
            print(error.localizedDescription)
        }
        synthesizer.delegate = self
    }
    
    /// 自定义语音播报方法 
    /// 此处只举例播报一个String的情况
    func speechWeather(with weather: String) {
        if let _ = speechUtterance {
            synthesizer.stopSpeaking(at: .immediate)
        }
        
        do {
            try AVAudioSession.sharedInstance().setActive(true)
        } catch {
            print(error.localizedDescription)
        }
        
        speechUtterance = AVSpeechUtterance(string: weather)
        
        speechUtterance?.voice = voiceType
        speechUtterance?.rate = 0.5
        synthesizer.speak(speechUtterance!)
    }
}

extension SpeechUtteranceManager: AVSpeechSynthesizerDelegate {
    func speechSynthesizer(_ synthesizer: AVSpeechSynthesizer, didFinish utterance: AVSpeechUtterance) {
        do {
            try AVAudioSession.sharedInstance().setActive(false, with: .notifyOthersOnDeactivation)
        } catch {
            print(error.localizedDescription)
        }
        speechUtterance = nil
    }
}

使用

/// 例如播报天气
/// 若要兼容语言国际化
/// NSLocalizedString 搭配 Locale.current.languageCode 食用效果更佳
SpeechUtteranceManager.shared.speechWeather(with: NSLocalizedString("The Rainy Day", comment: ""))

关键代码

setCategory

do {
    try AVAudioSession.sharedInstance().setCategory(AVAudioSessionCategoryPlayback, with: .duckOthers)
} catch {
    print(error.localizedDescription)
}
  • AVAudioSessionCategoryPlayback:后台播报
  • .duckOthers:混合通道,语音播报时其他软件声音变小(音乐)

若不设置混合通道,在后台播报时会报codeCannotInterruptOthers错误

iOS AVSpeechSynthesizer 语音播报以及后台播报设置(Swift)_第4张图片

setActive

将 AVAudioSession 置为活动状态

do {
    try AVAudioSession.sharedInstance().setActive(true)
} catch {
    print(error.localizedDescription)
}

记得在结束调用时将活动状态置为false

do {
    try AVAudioSession.sharedInstance().setActive(false)
} catch {
    print(error.localizedDescription)
}

语音播报简单使用
语音播报详细属性

你可能感兴趣的:(iOS AVSpeechSynthesizer 语音播报以及后台播报设置(Swift))