Day Vision

Reading Everyday,Extending Vision

SWIFT voice announcement, background announcement, background control

2023-02-28 04:02:19


Text broadcast import UIKitimport AVFoundationimport Speechimport MediaPlayerclass SpeechUtteranceManager: NSObject { /// Singleton Management Voice


demand

The more popular voice broadcasts in life are: WeChat payment arrival reminder, e-book reading and listening to books and other widely used.Apple launched the Speech framework in iOS 7.0, which supports voice broadcast function.Due to the need to broadcast the day's work schedule and other needs in the project without opening the app, I have checked a lot of information and encountered many pitfalls.

Text broadcast

import UIKit
import AVFoundation
import Speech
import MediaPlayer

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()
        synthesizer.delegate = self
    }
    
    /// 自定义语音播报方法
    /// 此处只举例播报一个String的情况
    func speechWeather(with weather: String) {
        if let _ = speechUtterance {
            synthesizer.stopSpeaking(at: .immediate)
        }
        speechUtterance = AVSpeechUtterance(string: weather)
        
        speechUtterance?.voice = voiceType
        speechUtterance?.rate = 0.5
        synthesizer.speak(speechUtterance!)
         UIApplication.shared.beginReceivingRemoteControlEvents()
         setLockView()
    }

    func stop()  {
        if synthesizer.isSpeaking {
          synthesizer.pauseSpeaking(at: .word)
        }
    }
    func Speaking()  {
        if synthesizer.isPaused {
            synthesizer.continueSpeaking()
        }
    }
//后台控制:显示标题、控制语速 可以添加显示图片等设置
    func setLockView(){
       let mpic =  MPNowPlayingInfoCenter.default()
            mpic.nowPlayingInfo = [
            MPMediaItemPropertyTitle:"语音播报",
            MPNowPlayingInfoPropertyPlaybackRate:1.0
        ]
    }
 
    func stopSpeaking() {
        if let _ = speechUtterance {
            synthesizer.stopSpeaking(at: .immediate)
        }
    }
}
extension SpeechUtteranceManager: AVSpeechSynthesizerDelegate {

    //开始播放
    func speechSynthesizer(_ synthesizer: AVSpeechSynthesizer, didStart utterance: AVSpeechUtterance) {
        
    }
    //播放完成
    func speechSynthesizer(_ synthesizer: AVSpeechSynthesizer, didFinish utterance: AVSpeechUtterance) {
        do {
            try AVAudioSession.sharedInstance().setActive(false, with: .notifyOthersOnDeactivation)
        } catch {
            print(error.localizedDescription)
        }
        speechUtterance = nil
    }
    //播放中止
    func speechSynthesizer(_ synthesizer: AVSpeechSynthesizer, didPause utterance: AVSpeechUtterance) {
    }
    //恢复播放
    func speechSynthesizer(_ synthesizer: AVSpeechSynthesizer, didContinue utterance: AVSpeechUtterance) {
        
    }
    //取消播放
    func speechSynthesizer(_ synthesizer: AVSpeechSynthesizer, didCancel utterance: AVSpeechUtterance) {
        
    }
}

Play method:

Play it in the background

Permissions need to be added: Targets->Capabilities->background modes, Audiu, AirPlay tick

Background control

In the UIViewController interface

//监听为第一响应者 这句话很重要,研究了好久,没有这句代码,锁屏检测不到
override var canBecomeFirstResponder: Bool{
        return true
    }
//后台控制按钮 没有补全 自行补全一下
    override func remoteControlReceived(with event: UIEvent?) {
        guard let event = event else {
            print("no event\n")
            return
        }
        
        if event.type == UIEventType.remoteControl {
            switch event.subtype {
            case .remoteControlTogglePlayPause:
                print("暂停/播放")
            case .remoteControlPreviousTrack:
                print("上一首")
            case .remoteControlNextTrack:
                print("下一首")
            case .remoteControlPlay:
                print("播放")
                SpeechUtteranceManager.shared.Speaking()
            case .remoteControlPause:
                print("暂停")
              SpeechUtteranceManager.shared.stop()
              
            default:
                break
            }
            
        }
    }

Extension: Add text according to the queue, background playback, background control, you can make a novel reading and listening function by yourself.