山寨一個Siri

SiriKit 從6月份的 WWDC2016 推出已經(jīng)有一段時間了,不少應(yīng)用也慢慢的適配了Siri,但是可能很多童鞋還沒有來得及去試試,下面我們先試一下:

QQ

我們可以在在設(shè)置里查看已經(jīng)適配Siri 的應(yīng)用,可以在這里將應(yīng)用打開權(quán)限,也可以在Siri 觸發(fā)的時候通過提示來打開。

目前我知道的已經(jīng)適配了Siri 的應(yīng)用

SiriKit 是以 Extension 的方式來給已有App 來提供支持,就目前Siri 支持的intent來說,還是有很多使用的限制,只能針對特定的詞匯通過命令來進(jìn)行識別處理。這里不介紹如何使用SiriKit ,下面我想利用iOS中 目前已經(jīng)公開的其他 API 實現(xiàn)一個應(yīng)用內(nèi)的語音助手,來理解Siri 的實現(xiàn)。

其實想要實現(xiàn)Siri,我們只需要先將語音進(jìn)行識別,然后再將語音內(nèi)容進(jìn)行分析,然后再將分析出來的結(jié)果進(jìn)行輸出,當(dāng)然這輸出不只是語音,也可能是一些反饋信息和一些事件處理。
下面我們先來實現(xiàn)語音識別。

語音識別

Speech framework 也是在WWDC 2016 推出的一個語音識別框架,并且支持多種語言,Siri 也是基于此框架來進(jìn)行語音識別。還在iOS 3 、4 時代的時候就已經(jīng)開始有一些第三方的語音識別框架,但那時候不是價格高就是識別不精準(zhǔn),導(dǎo)致很多應(yīng)用軟件對語音識別都望而卻步。但目前的語音識別技術(shù)都已經(jīng)爐火純青,就中文來說,不僅僅是已經(jīng)能夠識別出普通話,還能識別出粵語??拼笥嶏w在國內(nèi)應(yīng)該是語音識別技術(shù)做的最好的了,在幾年前就已經(jīng)實現(xiàn)了離線語音識別的功能。
Speech 當(dāng)然也不甘落后,也提供了離線的語音識別,速度和精準(zhǔn)度也不必多說。

蘋果一直都是呈現(xiàn)出來最簡單最易用的API 給開發(fā)者, 所以通過Speech 實現(xiàn)一個語音識別功能就是分分鐘搞定。

主要類有:

  1. SFSpeechRecognizer
  2. SFSpeechRecognitionRequest
    1). SFSpeechURLRecognitionRequest
    2). SFSpeechAudioBufferRecognitionRequest
  3. SFSpeechRecognitionTask
  4. SFSpeechRecognitionResult

簡單四步實現(xiàn)語音識別

// 請求獲取語音識別權(quán)限
SFSpeechRecognizer.requestAuthorization { (status) in   . . . }

// 初始化中文語音識別
let speechRecongnizer = SFSpeechRecognizer(locale: Locale(identifier: “zh_CN”))

// 初始化識別請求
let recognitionRequest = SFSpeechURLRecognitionRequest(url: NSURL(string: "...")!)

// 請求獲取語音識別
let recognitionTask = speechRecongnizer?.recognitionTask(with: recognitionRequest, resultHandler:{ (result, error) in
    if let result = result {
        print(result.bestTranscription.formattedString)
        let isFinal = result.isFinal
    }
 })

這里我們需要實現(xiàn)實時語音識別并轉(zhuǎn)化有效信息,就需要使用SFSpeechAudioBufferRecognitionRequest來通過緩沖流實時將語音轉(zhuǎn)化為有效文字信息。

let audioEngine = AVAudioEngine()
let recognitionRequest = SFSpeechAudioBufferRecognitionRequest()
guard let inputNode = audioEngine.inputNode else {
    fatalError("audioEngine error")
}
let recordingFormat = inputNode.outputFormat(forBus: 0)
inputNode.installTap(onBus: 0, bufferSize: 1024, format: recordingFormat) { (buffer, when) in
    recognitionRequest?.append(buffer)
}
let recognitionTask = speechRecongnizer?.recognitionTask(with: recognitionRequest, resultHandler: { (result, error) in
    var isFinal = false
    if let result = result {
        print(result.bestTranscription.formattedString)
    }
})

audioEngine.prepare()
do {
    try audioEngine.start()
} catch {
    print("couldn't start")
}

這樣我們就可以實時監(jiān)聽語音輸入流自動轉(zhuǎn)化為文字了,下面我們需要對文字進(jìn)行解析,然后將反饋信息讀出來。

語音朗讀

AVSpeechSynthesizer 是隨著iOS 7.0 而推出的一個文字轉(zhuǎn)語音的特性,幾行代碼就能實現(xiàn)文字轉(zhuǎn)成語音播放出來,

  1. AVSpeechSynthesizer
  2. AVSpeechUtterance
  3. AVSpeechSynthesisVoice
// 通過文字初始化話語
let utterance = AVSpeechUtterance(string: "語音轉(zhuǎn)文字")

// 設(shè)置語言
utterance.voice = AVSpeechSynthesisVoice(language: "zh-CN")

// 讀出來
let synthesizer = AVSpeechSynthesizer()
synthesizer.speak(utterance)

通過分詞解析并反饋

下面我們就可以解析出一些詞匯或命令來做出相應(yīng)的反饋。就比如

var string = ""
if action.contains("叫爸爸") || action.contains("喊爸爸") {
    string = "爸爸"
} else if action.contains("笑話") {
    string = "我有個直覺,圣誕節(jié)那天,可能會有個人捧著鮮花和禮物對我說, 讓一讓兄弟,擋路了。"
} else if action.contains("繞口令") {
    string = "黑化黑灰化肥灰會揮發(fā)發(fā)灰黑諱為黑灰花會回飛;灰化灰黑化肥會會揮發(fā)發(fā)黑灰為諱飛花回化為灰"
}

當(dāng)然,這只是一些很簡單的語音命令,如果要更精確的語音識別,肯定需要非常精準(zhǔn)的分詞算法來支持。
那么這樣一個山寨的應(yīng)用內(nèi)Siri 就算完成了。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容