1. 程式人生 > >android、ios音訊相容解決方法

android、ios音訊相容解決方法

前文書咱們說到IOS下如何錄製一個wav格式的音訊,然而現在的情況確實安卓不支援wav格式,於是有看官說了,你個二百五,就不能選個安卓支援的格式錄製麼,我很負責任的說,蘋果和谷歌掐架,苦的就是我們這幫苦逼的技術人員。。。安卓的格式蘋果全不支援,看好是全不,不是全部,反過來蘋果的格式,安卓也不慣著。。。。
當然上有政策下有對策是萬年不變的真理,Ios與安卓的音訊互通是難不倒我們偉大的程式設計師的,而目前解決這個問題方案有很多種但大致以下3種方式,且聽我細細道來。
第一種方案對於伺服器負荷較大,不論是安卓端亦或是IOS端都將音訊傳輸到伺服器,通過伺服器進行轉換再進行轉發。這種做法可以不受系統限制,但是資訊量較大時對伺服器負荷較大,對伺服器端的要求很高。據傳聞,微信就是採用這種方式進行的語音IM互動
第二種方案是不論IOS端還是安卓端都統一使用相同的第三方音訊庫進行編解碼處理,然後再進行網路傳輸,優點是可供選擇的音訊庫非常多,可以根據自己不同的需求選擇各種各樣的音訊格式,但是因為不論是IOS端還是安卓端都需要對其進行i編碼解碼處理,而專案初期並沒有設計這方面的需求所以如果雙端都進行修改修改量實在太大。同樣據傳聞,同為語音IM的成熟案例微米就是依靠Speex的三方開源庫來完成的,這種格式體積小,能降噪,是目前比較受推崇的方式。
我採用的是第三種方式,amr格式的音訊檔案是安卓系統中預設的錄音檔案,也算是安卓支援的很方便的音訊檔案,IOS系統曾經是支援這種格式的檔案,自4.3以後才取消了對amr的支援(原因應該不需要我多說。。。),可見,amr格式的音訊檔案並非IOS處理不了的,因為有了這樣的概念和潛意識的植入,我就開始一門心思在網路上找尋各種各樣的例項以及demo,我要做的就是把問題儘量都解決在IOS端。終於功夫不負有心人,最終讓我得以成功的在IOS端成功的轉換出安卓端可以使用的amr檔案。接下來,我們就說說如何在IOS端完成wav與amr檔案的互轉。
首先推薦給大夥提供一個demo在下面的連線下載。此demo轉載自中國開源社群,本人發自內心的向釋出者Jeans
大人致以最崇高的敬意。

http://www.oschina.net/code/snippet_562429_12400
demo下載開啟專案後將如下四個原始碼檔案以及兩個庫檔案拖入自己的專案,引用AudioToolbox.framework、CoreAudio.framework以及AVFouncation.framework即可完成類庫的匯入


開啟我們匯入的標頭檔案就會發現有又大量的struct,而在開啟ARC專案中是禁止使用struct和union的,而我們的專案確實可以開啟ARC的,這裡涉及到一個知識點,之前也在網路上看到有人提問在開啟ARC後改如何使用struct,我也是接觸這個專案之後開始涉及混編才瞭解該如何解決這個問題, 只要將Compile Sources As(設定編譯源)的設定為Ojbective-C 或者將包含到聲名struct和union標頭檔案的實作檔案的副檔名改為.mm就可以在專案中使用struct和union了,但是請注意此時你編寫的程式碼不再是純粹的Objective-C語言了,而是涉及到Objective-C ,此處涉及到混編的問題,我們再後面還會再講解混編相關的內容,但並不會很多,感興趣的看官可以自己查詢資料。回到原題,如果在匯入檔案後遇到了編譯錯誤,請點選專案的TARGETS下的Build best online casino
Settings找到以下編譯設定並按照圖內容修改

[圖片上傳中。。。(2)]

注意,如果是新建空專案Compile Sources mobile casino
As的設定在According to File Type(依照檔案型別選擇編譯源)的模式下應該也可以正常編譯,儘量不要設定為Ojbective-C 進行編譯,我是因為專案中含有其他的SDK需要用到所以才如此設定,一旦設定成Ojbective-C 會和我們之後講的網路傳輸篇中所使用的SDK產生一定衝突很那解決。所以此最好保持According to File Type。
檔案正常匯入之後就可以直接使用轉換方法了,和常規的SDK不同,這個庫並非以累的形式封裝的,而是數個功能函式,所以並不需要我們去構造物件,接下來我們說一下轉換時具體用到的方法,雖然這些方法簡單易用,但是我還是願意為大家提供一點便利,所謂幫人到底送佛送到西,下面我每一個方法的名稱、功能、引數說明以及使用示例貼出以供大家參考~。
哦~對了不要忘記,我們的第一步永遠都是匯入標頭檔案

import “amrFileCodec.h”;

接下來我們開始第一個函式EncodeWAVEFileToAMRFile從函式名稱中就可看出,此方法是將WAV轉換為AMR檔案的,我們先來看一下示例​​


引數列表也並不是很複雜4個引數分別問:1.WAV的檔案地址,2.AMR的檔案地址,3.音訊通道數,也就是我們上篇文章中所提到錄製音訊的最後一個引數,聲道數量。4.編碼位數,同樣在上一篇文章中我們也已經介紹過不再贅述。
接下來第二個函式,DecodeAMRFileToWAVEFile這個引數與前一個功能正好相反,是從amr轉換為WAV,下面是具體程式碼示例​


這個引數可以說較上一個更加簡單,第一個引數是需要一個AMR的檔案地址也就是源,第二個引數則是目標地址也就是一個WAV檔案的地址,簡單的兩個引數就可完成呼叫了。需要注意的是,此處所使用的地址和之前我們再使用AVFouncation的時候又不同了,它既不是要NSString的字串,也不是NSURL物件而是一個const char的指標,但是這並不是問題,例項程式碼中所轉換的方法並不是最簡的只是急於演示所以拖拽出來的,希望有心的看官可以自行過濾,過眼不過心是程式設計大忌。
相對於匯入可以說使用的方法簡單的一塌糊塗,並不需要我們多少功夫,也沒有那麼高深莫測,但是測試還是要下一定功夫的,經過實機檢測IOS下錄製出的WAV轉換為AMR之後放到安卓平臺可以正常播放,而安卓錄製的AMR檔案拿到IOS下轉換出WAV一樣可以播放完全沒有任何問題。但是這個方法也是有一定的弊端,音訊轉換的速度較慢,如果是時間較長的音訊檔案轉換起來會有短時間頓卡,但是用來實現語音IM聊天是完全可以滿足的
至此我們本地音訊處理篇的內容全部完結,也算是告一段落,但是我們現在只是在本地機器上實現了正確的音訊轉換以及播放,想要完成語音IM聊天我們還差關鍵的環節就是與伺服器的互動,詳細的內容,我們將在下一篇文章中介紹,盡請關注IOS、安卓IM語音聊天開發初探部分心得——非同步Socket傳輸篇