2014年1月28日 星期二

iOS 7 提供 AVSpeechSynthesizer 支援 TTS 功能

iOS 7 開始,終於有開放的內建 TTS 功能了。

相關的類別是在 AVFoundation framework 裡的 AVSpeechSynthesizer 、AVSpeechUtterance,以及 AVSpeechSynthesisVoice。
使用的方式如下:

1. 加入 AVFoundation.framework 這個 library,並於 client 類別中 import <AVFoundation/AVFoundation.h> 。

2. 建立 AVSpeechSynthesizer 實體。要讓它"說話",可以傳送 speakUtterance 訊息給它,這個方法接受一個 AVSpeechUtterance 實體作為參數。

3. AVSpeechUtterance 用於封裝語言種類 (AVSpeechSynthesisVoice 的實體)、要朗讀的文字內容,以及朗讀的延遲時間…等。


以下來思考一下這些類別的封裝原則。

1. AVSpeechSynthesisVoice:這個類別明顯地關注於語言種類本身。
以 voiceWithLanguage: 這個類別方法建立實體,其接受一個字串參數,該參數用於指定語言種類,若傳進 nil 則使用系統語系。至於支援的範圍請見 「BCP-47 language tag」。

2. AVSpeechUtterance:這個類別將 AVSpeechSynthesisVoice 實體以及要進行朗讀的文字內容綁定,並且封裝了朗讀速度、延遲、音量…等元素。感覺上很像一個 player。

3. AVSpeechSynthesizer:這個類別是最後負責把聲音發出來的類別。
感覺上,怎麼不是由AVSpeechUtterance 進行發聲呢?原因是需要顧及進行朗讀時,播放中可能得視情形進行中斷(停止或暫停),這時需要一個明定的規則來進行調派。就像交通警察一樣的角色。AVSpeechSynthesizer 就是這個作用。相關的方法有:stopSpeakingAtBoundary: 、pauseSpeakingAtBoundary:、continueSpeaking。

其中,stopSpeakingAtBoundary/pauseSpeakingAtBoundary 接受一個 AVSpeechBoundary 列舉,該列舉的值包括:AVSpeechBoundaryImmediate 及 AVSpeechBoundaryWord。

舉例來說,若在傳送 stopSpeakingAtBoundary 訊息時夾帶 AVSpeechBoundaryImmediate 這個列舉作為參數的話,當有別的聲音事件進來時,AVSpeechSynthesizer 就會立即停止自己所列管的 AVSpeechUtterance 實體的播放。

由於網路上不乏範例,而且自己就著原理寫一次才能學到東西,所以這裡就不加上範例程式囉。




沒有留言:

張貼留言