CMDN Club第十五期活動已於3月15日順利舉行,本次活動以“移動平台語音技術的應用與實踐”主題,以語音技術開發為焦點,從語音基礎服務、語音產品開發、語音技術實現等多個維度,探索語音產品創新和技術實踐的熱點話題。我們邀請了北京愛圖騰科技進階iOS開發工程師張天虹,為大家帶來iOS即時語音交談技術實踐演講。
圖:北京愛圖騰科技進階iOS開發工程師張天虹在做演講
以下是文字實錄:
張天虹:大家好我是來自愛圖騰的張天虹,大家可能對愛圖騰有些人比較熟悉,有些人比較陌生,愛圖騰是主要以移動外包為主的一個公司,我們的特點是比較開放,因為我們在平時開發中包括我們開發人員、設計人員還有一些各種平台開發的時候一些人員他們在技術方面都是共用的一個思想,包括你可以去我們官方部落格上可以看到,我們的很多實現一些技術的實現我們已經貼到部落格上了大家可以討論。還有我們公司每周五下午都有一個技術交流會,之前我們也告訴大家可以到我們公司一起去研究這些技術、一起討論、一起踢館現在也可以去,每周五下午都可以去看一看。(主持人:我補充一下,愛圖騰也是工程式文化的公司,所以我們可以從愛圖騰裡面淘出又會技術又可以有這樣人出來,所以很鼓勵自己公司可以在自己公司內部以合作的方式有這樣的技術分享,無論是部落格或者是線下活動。)
DEMO介紹:主要就是一個功能,我不知道效果好不好,因為這個跟網路有關。現在可以看看效果,這就是IPHONE4S手機,我做這個DEMO就是這個,我們按住錄音發送出去,它可以根據我聲音的大小,我放手之後這個語音就發出去了,因為這是受網路的限制,我不知道效果好不好。因為這個跟網路有關,因為我們資料發出去以後。大家可以說一下結果是什嗎?他說話可以在上面就跟我們平時播放的米聊一樣的效果。我們看完了這個DEMO之後,大家已經知道它的準系統了,我們知道DEMO實現功能第一是錄製,錄製完了之後通過網路發送到伺服器,然後伺服器把這個語音傳回來之後,到另外一台裝置上進行播放,知道這個之後我們看看它是怎麼去實現的。
從技術上講主要就是錄音:把錄音檔案發到伺服器,再從伺服器傳到另外一個裝置進行播放,這個過程是非常簡單的,但是考慮一個問題就是要適合網路傳輸,因為網路是特別脆弱的,不管是發的時候還是收的時候它會佔到我們手機的流量,這個流量是大家比較關心的,因為這個網路確實太貴了,為了便於網路傳輸我們進行一個壓縮和解壓的過程,知道這個過程之後,我們可以進入我們iOS平台要講的東西。第一個是語音錄製、語音編解碼、語音播放,還有Audaio Session還有語音實踐。
這個項目開發中會有加密和解密這些東西,我們現在就不提它了,我們現在看看語音的錄製,在語音錄製裡面我們會講哪幾個,我們比較想瞭解就是IOS裡面錄製哪些語音格式,還有我們的API怎麼去使用,還有錄製的音量怎麼樣,錄製的時候波浪會隨著我們聲音大小變換,這個是IOS也支援的。
我們看看iOS支援預設語音錄製格式,他支援的格式不是很多,很多我們想要可能沒有,但是我們可以給大家介紹基本的格式它是支援的AAC壓縮比較高,效果比較好。還有ALAC,還有ILBC,這個用於網路傳輸的一個語音格式。IMA4這是一個壓縮效率很高,但是各方面因為效率高了,可能別的演算法、複雜度可能降一點,要求效率比較高考慮這種格式,還有LINEAR PCM,這個是無壓縮的,還有U—LAW和ALAW。
我們知道它預設的語音格式之後,就看看它怎麼去錄製,我們這裡面有一個很簡單的類叫AVAudioRecorder,設定錄音的目標檔案,還有設定錄音的檔案資訊,錄音方式很多種,得到格式也有很多種,在初始化的時候可以設定一個錄音的基本資料,包括錄音格式,這裡面在API裡面提供了很多格式支援,比如說PCM,以及剛才所提到的支援的格式都可以放到這個裡面可以產生。還有錄音採樣率,還有錄音通道有單通道和雙通道,還有線性採樣位元,這是我們可以根據我們的需要設定。
我們知道我們想要錄音的設定之後,我們執行個體AVAudioRecorder,建立錄音檔案,準備錄音,開始錄音。我們先建立再錄音這樣效率更高一些。
這是整個錄音的過程,受到指定任何一個本地檔案,蘋果比較建議是放在TEMP檔案裡面,然後還有是錄音的設定,這裡可以設定錄音格式,就是PCM的錄音格式,採用率,通道數還有位元,我們把這幾個參數傳進去建立錄音檔案,錄音就這麼簡單,我們錄音一個過程就可以實現了。蘋果的API比較規範的,很簡單就可以達到我們想要的效果。
錄音:錄音的時候捕捉話筒的音量,可能大家沒看的很清楚,就是話筒音量大要的播放,我們這個也很簡單,MeteringEnabled,也是屬於CODER的方法,很簡單通過兩個方法拿到這段時間一個音量的平均值,以及音量的峰值,這兩個值出來以後音量很顯然出來了。這是我們錄音時捕捉音量的方式。
還有就是面向音頻流的錄音方式。因為面向音頻流不是你錄的時候直接產生一個檔案,你想邊錄製邊傳輸就可以面向音頻流錄製這個檔案,這個不細講了,因為這裡面內容很多,你們可以上蘋果裡面下一個SPEAKhereDemo。我們可以一起交流它怎麼去使用,它的原理是什麼,我們如果靈活用它,也可以實現很多很強大的功能。
錄完了聲音,剛才我們只是說把錄音錄完了產生一個檔案過程,這時候我們想把通過檔案的方式發出去就要進行雲的編解碼,我們看一張圖,這張圖展示了從錄音到最後儲存到硬碟檔案的過程,錄音它最先錄製成PCM的格式,再轉成AAC,中間經過CODEC這裡面就是一個編碼解碼器主要作用是對音頻訊號進行壓縮和解壓縮。我們講講它一個基本過程,首先從話筒裡面錄製PCM出去,這個CODEC把PCM轉換成AAC格式,把AAC寫成硬碟檔案,就三步就可以達到一個效果,中間一個CODEC起到轉碼的過程,就瞭解到它怎麼錄出資料格式的辦法。
剛剛講CODEC,重點轉移到CODEC裡面,這個CODEC我們在錄製的聲音可能很多我們想要的聲音並不是IOS支援的,我們看看IOS支援的這些CODEC,包括我們剛剛提到這些格式這是預設的CODEC,而我們在平時的應用中或者說開發中可能我們想要提供更加廣泛的比如說MP3、WMA、MIDI、OGG、Speex可能大家之前不瞭解,但是我們今天瞭解一下到底是什麼樣的語音格式。我們想要錄製這些格式,但是IOS沒有預設支援的CODEC,怎麼辦呢?我們可以用開源的CODEC,因為CODEC是一些服務商提供的,他可能是收費的,我們這裡可以看看哪些開源的CODEC可以使用,它的工程在網上有很多開源的廠商提供了都是免費的,我們看Speex。
Speex是一個壓縮比較好的、便於網路傳輸的,而且有一些降噪的功能,這個就是說他比較適合的語音交談,還有LAME這個格式,還有蘋果的Lossless,這是去年年底才開源一個項目,這是蘋果無損壓縮的CODEC。還有FLAC這個是免費的無損CODEC,還有LBC也是適合於網路傳輸的CODEC。
我們下載到CODEC以後這時候有一個比較難的技術門檻,有了CODEC以後我們怎麼編程我們IOS串連庫呢?因為要用PCM,要拿到連結庫,這就需要編譯了,我們先瞭解Xcode,我們Xcode為了讓我們支援更好的IOS裝置,比如說IPHONE2或者3,更低版裝置我們就需要更多的處理器架構。首先我們看Xcode需要哪些處理架構呢?I386、ARMv6、ARMv7。我們知道這個處理架構以後,我們就要編譯我們的CODEC,首先編譯一個適合I386的CODEC,還有V6、和v7的,我們編譯好了以後才能拿來具體使用。編譯的方式我再跟大家提一下。
我們有了編譯好的連結庫以後就可以使用CODEC編碼器和解碼器。編碼過程是這樣的,首先錄製完了以後,因為我們想錄製成為我們自己的CODEC地所以我們預設為PCM檔案,PCM在IOS錄製出來是一個WAV的檔案格式,因為它不僅是一個資料,還要成為一個檔案在我們播放器裡播放的。我們看WAV格式,我們可以看到在網上可以搜到資料,這裡面的資料結構有很多塊資訊,但是我們最後可以瞭解到,我們真正需要的是這個塊資料,我們通過資料格式最後拿到這個,我們知道數字結構以後我們可以拿到採樣資料,這個我相信大家知道一點,知道怎麼去拿,不知道也可以線下交流一下。然後我們拿採樣資料已經扣上了,壓縮成我們想要的目標格式。最後我們壓縮的資料格式還不行,因為我們錄製好的格式不光是用裝置傳輸,可能我們還用別的平台,比如說IPHONE給ANDROID傳送的檔案,因為不知道壓縮是什麼東西,這時候加一個檔案結構,我們重新組裝壓縮後的檔案結構,這樣別人才知道我壓縮後的檔案是什麼格式。這是一個編碼過程。
這個編碼完成之後,我們就可以把這個資料放在另外一個裝置了,編碼結束了。別人拿了資料以後肯定考慮播放了,這個資料怎麼處理之前我們先講講IOS播放怎麼實現,IOS支援播放的格式,跟錄音的格式是差不多,只是多了一個MP3和ILBC的格式,多了MP3解碼的一個支援。我們看看播放怎麼用,相對錄來說播放簡單多了,首先這個傳輸的值可以從檔案裡面提取過來的資料就可以了,然後準備播放開始播放,就可以播放出來了,很簡單。
AAC檔案播放過程是怎麼做的?首先跟錄音過程是相反的,首先是解碼,解碼放到裡面播放,讀取AAC,播放PCM檔案。
知道播放原理以後,把我們剛才那多的CODEC到另外一個用戶端去解碼,解碼怎麼辦呢?這就是我們拿到一個資料,剛才編碼完成的資料是這樣的,發過來資料就應該這樣的,我們的解碼過程中又需要把這個資訊去掉了,因為我們只需要解碼中間的資料而不需要解析檔案具體的結構,而是關心編碼後的資料,這個也很簡單,CODECDecode的方法,因為PCM最後格式是WAVE檔案才能播放。這是一個解碼的過程。
整個過程大家應該瞭解了,我們想要用自己的一個CODEC錄音播放的過程。下面瞭解一下AUDIO Session。AUDIO Session是IOS中用於處理應用,比如說如何處理多個應用的音訊輸出,比如說我聽APPLE,這時候開啟另外一個應用,另外一個也有聲音的播放,這個時候怎麼處理呢?還有我們在鎖屏情況下我們的應用和播放聲音這時候我鎖屏了,還有我把音量鍵關到最小的時候有一些應用就不讓關,即使你玩遊戲音量鍵也關不了。還有就是是否在應用裡面支援錄音,還有是否支援語音的播放。AUDIO Session是管理這些過程的,我給大家一個比較直觀的圖,我這個應用,這是飛機一個控制台應用,首先第一架飛機正在飛,就是現正播放聲音,另外一個應用說我也要播放聲音了,這時候控制台把它記錄下來說它要播放聲音了,這個SPEAKHERE說也要播放聲音了,就是告訴控制台,我AUDIO
Session要播放聲音了,那控制台就告訴SpeakHere關閉聲音。
應用中可以設定的幾種音頻模式:你聲音調到靜音以及鎖屏的情況下聲音是否播放,另外一個情況就是我這個應用在使用的時候,是否支援別的應用,同時在使用這個聲音。還也就是我這個應用是否支援聲音的錄製或者播放,還有不同的組合,我們在應用裡面就是說我在鎖屏情況下不允許播放聲音,或者可以播放聲音。它怎麼使用呢?看看最下面這一行代碼,我們設定它一個模式就可以了,也是一句話事情,用起來非常方便。
我們講完了AUDIO Session,下面具體講講我們剛才的DEMO是怎麼做的?首先跟我們剛才講的過程是一樣的。
第一步要去下載Speex的CODEC,它的網頁裡面可以下載下來了,下載下來是一個C的工程,這時候我們編譯適合我們Xcode開發的一個Speex CODEC LIB就是開發庫。這裡舉一個例子在我們編譯一個基於模擬器的DEMO怎麼做,我們可以直接在這裡打包Host和build,就可以了。將LIBSpeex.A引入Xcode開發環境中,這個設定要非常細心,指定好標頭檔,指定好了以後,我們可以引入Speex.H檔案。
我們有了我們檔案庫以後,擷取錄製的PCM檔案的音頻資料把這個代碼提取出來,就是採樣的檔案提取出來,這個過程可能相對繁瑣一點,只要找到這個塊就可以把採樣資料拿到。拿到這個採樣資料以後我們才對它進行一個編碼。Speex一個編碼的函數,這種方法是基於幀的,並不是一個檔案一個檔案處理,而是定一個幀的長度基於幀的編碼為你想要的一個Speex格式,最後Speex添加Speex檔案的頭資訊,然後通過Socket發送Speex檔案資料到伺服器,伺服器傳到另外一台裝置,裝置接受為Speex檔案並解碼為PCM音頻資料。這個Speex還有很多很多的功能,包括錄製之前的設定和降噪都可以設定。通過解碼將PCM資料恢複為WAVE檔案格式,可以播放這個檔案。今天講主要是這麼多。
線下希望共同的交流包括技術上的問題,因為我看現在語音發展特別快,我看訊飛和UC做的非常好了,非常人性化,包括這方面的技術到底怎麼去實現和解決的技術交流,我們可以一起交流,不管是微博各種平台都可以交流,謝謝大家。