在 iOS 中分析文本到语音的字符串

Analyse string for text-to-Speech in iOS

我想分析一下 String 并检查它是否包含某些关键字,例如 “1 分钟” 在文本由系统发音时。

AVSpeechSynthesizer 一次获取整个字符串并执行其操作时,我遇到了问题。我无法控制在播放期间分析字符串以检查出现的那些关键字。

我的文字转语音代码如下:

func Speech()  {
    do {
        try AVAudioSession.sharedInstance().setCategory(AVAudioSessionCategoryPlayback, with: .mixWithOthers)
        try AVAudioSession.sharedInstance().setActive(true)
        print("Session is Active")
    } catch {
        print(error)
    }

    if !speechSynthesizer.isSpeaking {
        self.VoiceString = self.VoiceString+self.DirectionsString
        let speechUtterance = AVSpeechUtterance(string: self.VoiceString)
        var voiceToUse: AVSpeechSynthesisVoice?
        speechUtterance.voice = voiceToUse
        speechUtterance.rate = Float(self.RangeSlider.selectedMinValue/2)
        speechSynthesizer.speak(speechUtterance)
    }
    else {
        speechSynthesizer.continueSpeaking()
    }
    animateActionButtonAppearance(shouldHideSpeakButton: true)
}

Is it possible to detect specific string by using AVSpeechSynthesizer or have you any other approach?

您应该实现 AVSpeechSynthesizer 的委托并添加以下代码:

var myText = "This is my text, which will be detect on text-to-speech operation"

override func viewDidLoad() {
    super.viewDidLoad()
    speechSynthesizer.delegate = self
}

已实现 willSpeakRangeOfSpeechString,系统会调用文本字符串中的每个口语单词。您可以实现 String 类型的 contains() 方法来检测文本中的特定字符串。

extension TextToSpeechVC: AVSpeechSynthesizerDelegate {

    func speechSynthesizer(_ synthesizer: AVSpeechSynthesizer, willSpeakRangeOfSpeechString characterRange: NSRange, utterance: AVSpeechUtterance) {

        let string = self.myText[characterRange.lowerBound..<characterRange.upperBound]

        if string.trim == "operation" {
            print("string = \(string)")
        }
    }
}

为范围下标添加 String 扩展名。

extension String {

    var trim: String {
        return self.trimmingCharacters(in: .whitespacesAndNewlines)
    }


    subscript (bounds: CountableClosedRange<Int>) -> String {
        let start = index(startIndex, offsetBy: bounds.lowerBound)
        let end = index(startIndex, offsetBy: bounds.upperBound)
        return String(self[start...end])
    }

    subscript (bounds: CountableRange<Int>) -> String {
        let start = index(startIndex, offsetBy: bounds.lowerBound)
        let end = index(startIndex, offsetBy: bounds.upperBound)
        return String(self[start..<end])
    }
}

希望对您有所帮助。