美文网首页开发技巧分类
iOS AVSpeechSynthesizer 语音播报以及后台

iOS AVSpeechSynthesizer 语音播报以及后台

作者: wiiale | 来源:发表于2017-04-19 20:41 被阅读846次

    Xcode配置

    • 如果需要后台播报语音,需要到Target->Capabilities选中Background Modes 的 Audio...选项。

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

    管理类文件

    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错误

    setActive

    将 AVAudioSession 置为活动状态

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

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

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

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

    相关文章

      网友评论

      • 何必轻言流年:播放中 手机给别人打电话的话会有干扰,请问作者怎么解决呢
        何必轻言流年:@wiiale 感谢作者 用你的方法 解决了:heart:
        wiiale:不如试试系统的AVAudioSessionInterruption通知做中断处理。
        enum AVAudioSessionInterruptionType:
        case began /* the system has interrupted your audio session */
        case ended /* the interruption has ended */

      本文标题:iOS AVSpeechSynthesizer 语音播报以及后台

      本文链接:https://www.haomeiwen.com/subject/gvdhzttx.html