Android使用webview怎么加载uri_Android 多媒体之音频
在開(kāi)發(fā)上,習(xí)慣的將音頻、視頻功能的使用稱(chēng)之為多媒體,實(shí)際上如果講的寬泛一些的話,相機(jī)的使用,比如拍照,錄制視頻等,也可以劃分到多媒體的范疇里面。
從本節(jié)課開(kāi)始,我們就來(lái)看看Android中多媒體的API使用和具體的功能。
本篇文章我們先從音頻開(kāi)發(fā)聊起。
零、音頻開(kāi)發(fā)場(chǎng)景、內(nèi)容和基本概念
在說(shuō)音頻開(kāi)發(fā)之前,我們可以先想一想自己琢磨一下,哪些應(yīng)用場(chǎng)景會(huì)用到音頻開(kāi)發(fā)。主要的應(yīng)用場(chǎng)景大致包括:
- 音頻播放器
- 錄音機(jī)
- 語(yǔ)音電話
- 音視頻監(jiān)控應(yīng)用
- 音視頻直播應(yīng)用
- 音頻編輯/處理軟件
- 藍(lán)牙耳機(jī)/音箱
- ... ...
如果我們要成系統(tǒng)的學(xué)習(xí)多媒體和音視頻的開(kāi)發(fā),大致會(huì)有涉及到哪些方面的知識(shí)呢,歸納來(lái)看主要有一下幾個(gè)方面的內(nèi)容:
- 音頻采集/播放:已有音頻如何播放;如何采集一段音頻;
- 音頻算法處理:主要包括去噪、靜音檢測(cè)、回聲消除、音效處理、功放/增強(qiáng)、混音/分離,等等
- 音頻的編解碼和格式轉(zhuǎn)換:不同格式之間的轉(zhuǎn)碼操作
- 音頻傳輸協(xié)議的開(kāi)發(fā):主要包括SIP,A2DP、AVRCP,等等
另外,如果要進(jìn)行音頻開(kāi)發(fā),需要了解一些音頻的概念作為前置知識(shí),一些常見(jiàn)的概念如下所示:
- SampleRate:采樣率,每秒采集聲音的數(shù)量,它用赫茲(Hz)來(lái)表示。采樣頻率越高,音頻質(zhì)量越好。常用的音頻采樣頻率有:8kHz、16kHz、44.1kHz、48kHz 等。
- Channel:聲道數(shù),表示聲音錄制時(shí)的音源數(shù)量或回放時(shí)相應(yīng)的揚(yáng)聲器數(shù)量。常用的是單聲道(Mono)和雙聲道(Stereo)。要記住這兩個(gè)詞:Stereo和Mono。
- BitDepth:采樣精度,每個(gè)采樣點(diǎn)用多少數(shù)據(jù)量表示,它以位(Bit)為單位。位數(shù)越多,表示得就越精細(xì),聲音質(zhì)量自然就越好,當(dāng)然數(shù)據(jù)量也越大。常見(jiàn)的位寬是:8bit 或者 16bit。
- BitRate:比特率,每秒音頻占用的比特?cái)?shù)量,單位是 bps(Bit Per Second),比特率越高,壓縮比越小,聲音質(zhì)量越好,音頻體積也越大。
一、音頻播放
說(shuō)到音視頻多媒體,首先就有一個(gè)概念叫:媒體格式。也就是我們常說(shuō)的不同格式的音視頻文件。在Android這個(gè)開(kāi)放系統(tǒng)平臺(tái)中,支持的媒體格式還是很豐富的,詳細(xì)內(nèi)容如下:
音頻格式和編解碼器
總結(jié)來(lái)說(shuō),Android中常見(jiàn)的音頻壓縮格式有:MP3,AAC,OGG,WMA,Opus,FLAC,APE,m4a,AMR,等等。
1.1 音頻的播放
1.1.1 MediaPlayer
首先認(rèn)識(shí)兩個(gè)基礎(chǔ)的概念和API:
- MediaPlayer:用于播放聲音和視頻的主要 API。Android 多媒體框架支持播放各種常見(jiàn)媒體類(lèi)型,可以輕松地將音頻、視頻和圖片集成到應(yīng)用中。可以使用 MediaPlayer API,播放存儲(chǔ)在應(yīng)用資源(原始資源)內(nèi)的媒體文件、文件系統(tǒng)中的獨(dú)立文件或者通過(guò)網(wǎng)絡(luò)連接獲得的數(shù)據(jù)流中的音頻或視頻。
- AudioManager:該類(lèi)API用于管理設(shè)備上的音頻源和音頻輸出。
另外需要說(shuō)一下,MediaPlayerl除了能夠獲取、解碼以及播放音頻和視頻,而且只需很簡(jiǎn)單的設(shè)置即可以外。它還支持多種不同的媒體源,比如:
- 本地資源:即res目錄下的音頻資源。
- URI:比如可能是通過(guò)Content Provider解析到的某個(gè)資源URI
- 網(wǎng)絡(luò):通過(guò)網(wǎng)絡(luò),獲取流式傳輸數(shù)據(jù)進(jìn)行播放。
使用步驟
- 1、初始化MediaPlayer對(duì)象
- 2、準(zhǔn)備播放工作:準(zhǔn)備工作主要是音頻數(shù)據(jù)源的獲取或者是音頻數(shù)據(jù)的解碼操作等,該過(guò)程屬于耗時(shí)操作,因此需要在工作線程中進(jìn)行。
- 3、音頻狀態(tài)管理:在準(zhǔn)備工作過(guò)后,可以對(duì)音頻進(jìn)行播放、暫停等操作。同時(shí)需要注意的是MediaPlayer是有狀態(tài)的,包括:Idle、Initialized、Prepared、Started、Paused、PlaybackCompleted等狀態(tài)。當(dāng)在進(jìn)行狀態(tài)的切換時(shí),需要注意幾個(gè)點(diǎn):
- ① Started(開(kāi)始)/Paused(暫停)到Stopped(停止)是單向轉(zhuǎn)換,無(wú)法再?gòu)腟topped直接轉(zhuǎn)換到Started,需要經(jīng)歷Prepared重新裝載才可以重新播放。
- ② Initialized(初始化)狀態(tài)需要裝載數(shù)據(jù)才可以進(jìn)行start()播放,但是如果使用prepareAsync()方法異步準(zhǔn)備,需要等待準(zhǔn)備完成再開(kāi)始播放,這里需要使用一個(gè)回調(diào)方法:setOnPreparedListener(),它會(huì)在異步裝載完成后調(diào)用。
- ③ End(結(jié)束)狀態(tài)是游離在其他狀態(tài)之外的,在任何狀態(tài)皆可切換,一般在不需要繼續(xù)使用MediaPlayer的時(shí)候,才會(huì)使用release()回收資源。
- ④ Error(錯(cuò)誤)狀態(tài)是游離在其他狀態(tài)之外的,只有在MediaPlayer發(fā)生錯(cuò)誤的時(shí)候才會(huì)轉(zhuǎn)換。為了保持應(yīng)用的用戶體驗(yàn),通常會(huì)監(jiān)聽(tīng)setOnErrorListener()回調(diào)方法,它會(huì)在MediaPlayer發(fā)生錯(cuò)誤的時(shí)候被回調(diào)。
注意事項(xiàng)
- 1、使用Service播放音頻。在使用MediaPlayer播放音頻流時(shí),推薦使用一個(gè)Service來(lái)承載MediaPlayer,而不是直接在Activity里使用。
- 2、使用喚醒鎖。Android系統(tǒng)的功耗設(shè)計(jì)里,為了節(jié)約電池消耗,如果設(shè)備處于睡眠狀態(tài),系統(tǒng)將試圖降低或者關(guān)閉一些沒(méi)設(shè)備必須的特性,包括CPU和Wifi硬件。如果是一個(gè)后臺(tái)播放音樂(lè)的應(yīng)用,降低CPU可能導(dǎo)致在后臺(tái)運(yùn)行的時(shí)候干擾音頻的正常播放,關(guān)閉Wifi將可能導(dǎo)致網(wǎng)絡(luò)音頻流的獲取出現(xiàn)錯(cuò)誤。因此為了保證功能的正常使用,我們必須阻止系統(tǒng)關(guān)閉服務(wù)。可以使用wake locks(喚醒鎖),它會(huì)告訴系統(tǒng)你正在使用某些功能,這樣就可以一直保持該功能處于喚醒狀態(tài),即使鎖屏無(wú)操作也能繼續(xù)使用。這個(gè)鎖會(huì)在paused和stoped狀態(tài)下釋放。
1.1.2 SoundPool
如果應(yīng)用程序經(jīng)常播放密集、急促而又短暫的音效(如游戲音效)那么使用MediaPlayer顯得有些不太適合了。因?yàn)镸ediaPlayer存在如下缺點(diǎn):
- 1、延時(shí)時(shí)間較長(zhǎng),且資源占用率高。
- 2、不支持多個(gè)音頻同時(shí)播放。
Android中除了MediaPlayer播放音頻之外還提供了SoundPool來(lái)播放音效,SoundPool使用音效池的概念來(lái)管理多個(gè)短促的音效,例如它可以開(kāi)始就加載20個(gè)音效,以后在程序中按音效的ID進(jìn)行播放。SoundPool的特點(diǎn)和使用長(zhǎng)江如下:
- 1、主要用于播放一些較短的聲音片段。
- 2、SoundPool對(duì)CPU資源占用量低和反應(yīng)延遲小。
- 3、SoundPool還支持自行設(shè)置聲音的品質(zhì)、音量、 播放比率等參數(shù)。
SoundPool的API說(shuō)明如下:
- 1、SoundPool(int maxStreams, int streamType, int srcQuality):指定它總共支持多少個(gè)聲音(也就是池的大小)、聲音的品質(zhì)。該方法屬于5.0以下版本使用。
- 2、SoundPool.Builder:從5.0版本開(kāi)始使用的是SoundPool.Builder模式。
- 3、load(Context context, int resld, int priority):從 resld 所對(duì)應(yīng)的資源加載聲音。
- 4、load(FileDescriptor fd, long offset, long length, int priority):加載 fd 所對(duì)應(yīng)的文件的offset開(kāi)始、長(zhǎng)度為length的聲音。
- 5、load(AssetFileDescriptor afd, int priority):從afd 所對(duì)應(yīng)的文件中加載聲音。
- 6、load(String path, int priority):從path 對(duì)應(yīng)的文件去加載聲音。
- 說(shuō)明:4個(gè)load方法中都有一個(gè)priority參數(shù),該參數(shù)目前還沒(méi)有任何作用,Android建議將該 參數(shù)設(shè)為1,保持和未來(lái)的兼容性。
- play(int soundID, float leftVolume, float rightVolume, int priority, int loop, float rate):指定播放哪個(gè)聲音,2和3參數(shù)的意思是音量,priority指定播放的優(yōu)先級(jí),數(shù)值越大優(yōu)先級(jí)越高;loop用于指定是否循環(huán),0不循環(huán),-1位循環(huán);rate指定播放的比率,可選值為0.5 - 2 ,1為正常比率。
1.1.3 AudioTrack
AudioTrack屬于更偏底層的音頻播放,在Android的framework層有MediaPlayerService,其內(nèi)部就是使用了AudioTrack。AudioTrack用于單個(gè)音頻播放和管理,相比于MediaPlayer具有:精煉、高效的優(yōu)點(diǎn)。因此,對(duì)于AutioTrack可以總結(jié)如下:
- 使用場(chǎng)景:更適合實(shí)時(shí)產(chǎn)生播放數(shù)據(jù)的情況,如加密的音頻,MediaPlayer是束手無(wú)策的,AudioTrack可以處理。
- 要求:AudioTrack用于播放PCM(PCM無(wú)壓縮的音頻格式)音樂(lè)流的回放,如果要播需放其它格式音頻,需要相應(yīng)的解碼器,這也是AudioTrack用的比較少的原因,原因在于需要程序開(kāi)發(fā)者自己解碼音頻。
- 播放模式:
- ① AudioTrack播放音頻有兩種播放模式,一種是靜態(tài)模式,即加載的數(shù)據(jù)和資源可以直接全部加載完畢,加載方式簡(jiǎn)單,效率也比較高。但是如果數(shù)據(jù)量很大,往往不適合;
- ② 流模式和網(wǎng)絡(luò)上播放視頻是類(lèi)似的,即數(shù)據(jù)是按照一定規(guī)律不斷地傳遞給接收方的。音頻文件過(guò)大 音頻屬性要求高,比如采樣率高、深度大的數(shù)據(jù);另外如果音頻數(shù)據(jù)是實(shí)時(shí)產(chǎn)生的,這種情況就只能用流模式。
使用AudioTrack公有三個(gè)步驟:
共有三個(gè)步驟:
另外,其實(shí)AudioTrack以外,還有一個(gè)Audio系統(tǒng),在該系統(tǒng)中主要包含三個(gè)核心的API,分別是:
- AudioManager:主要是用來(lái)管理Audio系統(tǒng)的。
- AudioTrack:主要是用來(lái)播放聲音。
- AudioRecord:主要是用來(lái)錄音。
1.1.4 RingtoneManager
Ringtone為鈴聲、通知和其他類(lèi)似聲音提供快速播放的方法,該種方式播放音頻時(shí),還會(huì)涉及到一個(gè)核心的管理類(lèi)”RingtoneManager”,該類(lèi)作為管理類(lèi)提供系統(tǒng)鈴聲列表檢索方法,并且RingtoneManager可以生成Ringtone實(shí)例。具體的Ringtone的使用步驟和相關(guān)的方法如下所示:
- 1、獲取Ringtone對(duì)象實(shí)例:
- 2、RingtoneManager中重要的方法:
1.1.5 音頻及音效的播放總結(jié)
經(jīng)過(guò)如上幾種音效的播放方式的講解,我們可以對(duì)音效的播放做簡(jiǎn)單的總結(jié)如下所示:
- 1.對(duì)于延遲度要求不高,并且希望能夠更全面的控制音樂(lè)的播放,MediaPlayer比較適合。
- 2.聲音短小,延遲度小,并且需要幾種聲音同時(shí)播放的場(chǎng)景,適合使用SoundPool。
- 3.播放大文件音樂(lè),如WAV無(wú)損音頻和PCM無(wú)壓縮音頻,可使用更底層的播放方式AudioTrack。它支持流式播放,可以讀取(可來(lái)自本地和網(wǎng)絡(luò))音頻流,卻播放延遲較小。
- 4、AudioTrack直接支持WAV和PCM,其他音頻需要解碼成PCM格式才能播放。 .jet的音頻比較少見(jiàn)(有的游戲中在使用),可使用專(zhuān)門(mén)的播放器JetPlayer播放。
- 5.對(duì)于系統(tǒng)類(lèi)聲音的播放和操作,Ringtone更適合。
二、音頻的采集
手機(jī)一般都有麥克風(fēng)和攝像頭,而Android系統(tǒng)就可以利用這些硬件來(lái)錄制音視頻了。為了增加對(duì)錄制音視頻的支持,Android系統(tǒng)提供了一個(gè)MediaRecorder的類(lèi)。
與MediaPlayer類(lèi)非常相似MediaRecorder也有它自己的狀態(tài)圖,MediaRecorder的各個(gè)狀態(tài)介紹如下:
- Initial:初始化狀態(tài)。使用new()方法創(chuàng)建MediaRecorder對(duì)象或者調(diào)用了reset()方法時(shí),該MediaRecorder對(duì)象處于Initial狀態(tài)。
- Initialized:已初始化狀態(tài),在Initial狀態(tài)調(diào)用setAudioSource()或setVideoSource()方法進(jìn)入該狀態(tài)。在這個(gè)狀態(tài)可以通過(guò)setOutputFormat()方法設(shè)置輸出格式,此時(shí)MediaRecorder轉(zhuǎn)換為DataSourceConfigured狀態(tài)。另外,通過(guò)reset()重新進(jìn)入Initial狀態(tài)。
- DataSourceConfigured:數(shù)據(jù)源配置狀態(tài),這期間可以設(shè)定編碼方式、輸出文件、屏幕旋轉(zhuǎn)、預(yù)覽顯示等等。可以在Initialized狀態(tài)通過(guò)setOutputFormat()方法進(jìn)入該狀態(tài)。可以通過(guò)prepare()方法到達(dá)Prepared狀態(tài)。
- Prepared:就緒狀態(tài),在DataSourceConfigured狀態(tài)通過(guò)prepare()方法進(jìn)入該狀態(tài)。可以通過(guò)start()進(jìn)入錄制狀態(tài)。另外,可以通過(guò)reset()方法回到Initialized狀態(tài)。
- Recording:錄制狀態(tài),通過(guò)調(diào)用start()方法進(jìn)入該狀態(tài)。另外,它可以通過(guò)stop()方法或reset()方法回到Initial狀態(tài)。
- Released:釋放狀態(tài),可以通過(guò)在Initial狀態(tài)調(diào)用release()方法來(lái)進(jìn)入這個(gè)狀態(tài),這時(shí)將會(huì)釋放所有和MediaRecorder對(duì)象綁定的資源。
- Error:錯(cuò)誤狀態(tài),當(dāng)錯(cuò)誤發(fā)生的時(shí)候進(jìn)入這個(gè)狀態(tài),它可以通過(guò)reset()方法進(jìn)入Initial狀態(tài)。
需要說(shuō)明的是,與MediaPlayer相似,使用MediaRecorder錄音錄像時(shí)需要嚴(yán)格遵守狀態(tài)函數(shù)調(diào)用的先后順序,在不同的狀態(tài)調(diào)用不同的函數(shù),否則會(huì)出現(xiàn)異常。如上的文字描述可以轉(zhuǎn)換為如下?tīng)顟B(tài)圖:
三、Android中多音視頻編解碼
音視頻的原始數(shù)據(jù)非常龐大,難以存儲(chǔ)和傳輸。要解決音視頻數(shù)據(jù)的存儲(chǔ)和傳輸問(wèn)題,需要做如下處理:
- 音視頻編碼:即對(duì)數(shù)據(jù)進(jìn)行壓縮,音視頻數(shù)據(jù)壓縮技術(shù)就是音視頻編碼。編碼的目的就是在最小圖像或音頻信息丟失情況下得到最大的壓縮。
- 音視頻解碼:解碼是相對(duì)編碼的,其目的是最大限度的還原原始圖像或聲音信息。
- 編解碼的作用:編解碼的意義就是便于數(shù)據(jù)傳輸和存儲(chǔ)。
而我們知道音視頻編解碼格式非常多(h264、h265、vp8、vp9、aac、opus……),實(shí)現(xiàn)每種編解碼都需要引入外部庫(kù),導(dǎo)致項(xiàng)目臃腫、包體積過(guò)大且運(yùn)行性能差。
因此Google提出了一套標(biāo)準(zhǔn),這就是MediaCodec。具體來(lái)說(shuō),了解MediaCodec可以從以下幾個(gè)方面來(lái)說(shuō):
- 定義:MediaCodec是Google公司專(zhuān)門(mén)為Android開(kāi)發(fā)者和芯片廠商搭建的一套用于調(diào)用硬件編解碼器組件的統(tǒng)一接口,全部遵循該接口規(guī)范即可簡(jiǎn)單的使用,主要的目的在于統(tǒng)一標(biāo)準(zhǔn)。
- 特點(diǎn):與常規(guī)編解碼庫(kù)相比,MediaCodec具有非常明顯的優(yōu)勢(shì),它速度快、效率高、CPU占用率低、內(nèi)存小、節(jié)省包體積。使用MediaCodec可以解決項(xiàng)目臃腫、減小包體積和提升編解碼性能。
關(guān)于MediaCodec的工作原理,可以參見(jiàn)下圖所示:
工作步驟如下所示:
- MediaCodec處理輸入數(shù)據(jù)后生成輸出數(shù)據(jù)。通過(guò)異步方式處理數(shù)據(jù),并使用一組輸入和輸出緩沖區(qū)。
- 輸入端:請(qǐng)求一個(gè)空的輸入緩沖區(qū),用數(shù)據(jù)填充它并將其發(fā)送到編解碼器進(jìn)行處理。
- 輸出端:編解碼器處理完數(shù)據(jù)并將其轉(zhuǎn)換到一個(gè)空的輸出緩沖區(qū)。最后,請(qǐng)求一個(gè)已填滿的輸出緩沖區(qū),使用它的內(nèi)容并將其釋放回編解碼器。
可以操作的數(shù)據(jù)類(lèi)型
MediaCodec可以對(duì)三種數(shù)據(jù)進(jìn)行操作,分別是:
- 編碼數(shù)據(jù)
- 原始音頻數(shù)據(jù)
- 原始視頻數(shù)據(jù)
MediaCodec的狀態(tài)管理
MediaCodec存在三種狀態(tài):停止(stoped)、執(zhí)行(executing)、釋放(released)。
- 停止?fàn)顟B(tài):包含三個(gè)子狀態(tài):配置(configured)、未初始化(uninitialized)、錯(cuò)誤(error)
- 執(zhí)行狀態(tài):包含三個(gè)子狀態(tài):刷新(flushed)、運(yùn)行(running)、結(jié)束流(end-of-stream)
MediaCodec 發(fā)展
Android系統(tǒng)中關(guān)于MediaCodec的介紹,可以參考Android的官方網(wǎng)站提供的信息:https://developer.android.google.cn/reference/kotlin/android/media/MediaCodec
MediaCodec 是在 Android 4.1版本(API16 )中出現(xiàn)并可用的,它提供了一種極其原始的接口。MediaCodec類(lèi)同時(shí)存在 Java和C++層中,但是只有前者是公共訪問(wèn)方法。
在Android 4.3 (API18)中,MediaCodec被擴(kuò)展為通過(guò) Surface 提供輸入的方法(通過(guò) createInputSurface方法),允許來(lái)自于相機(jī)的預(yù)覽或者是經(jīng)過(guò)OpenGL ES呈現(xiàn)。在該版本中,MediaCodec是第一個(gè)過(guò)了CTS測(cè)試的版本。所謂的CTS,全稱(chēng)是Compatibility Test Suite,主要是google推出的一種設(shè)備兼容性測(cè)試規(guī)范,用來(lái)保證不同設(shè)備一致的用戶體驗(yàn)的規(guī)范。
除此之外,4.3版本還引入了 MediaMuxer。MediaMuxer允許將AVC編解碼器(原始H.264基本流)的輸出轉(zhuǎn)換為.MP4格式,可以和音頻流一起轉(zhuǎn)碼也可以單獨(dú)轉(zhuǎn)換。
音視頻編輯
MediaCodec通常與MediaExtractor、MediaSync、MediaMuxer、MediaCrypto、MediaDrm、Image、Surface和AudioTrack一起使用,幾乎可以實(shí)現(xiàn)大部分音視頻相關(guān)功能。主要的操作步驟如下所示:
- 1、初始化。
- 2、MediaExtractor:提取音視頻編碼數(shù)據(jù),MediaExtractor用于對(duì)音視頻文件解封裝,提取出已編碼的媒體數(shù)據(jù)。
- 3、MediaCodec:使用解碼器進(jìn)行解碼。
- 4、處理:對(duì)音視頻進(jìn)行處理。
- 5、編碼:使用MediaCodec編碼器對(duì)音視頻數(shù)據(jù)編碼。
- 6、合成:MediaMuxer合成音視頻文件。MediaMuxer用于封裝編碼后的音視頻數(shù)據(jù),目前支持MP4、Webm和3GP文件作為輸出。
- 7、 釋放資源。
代碼中的體現(xiàn)如下:
-使用MediaCodec編碼音頻
- 初始化MediaCodec對(duì)象,如下所示:
- 讀取PCM數(shù)據(jù),執(zhí)行編碼操作。
以上是MediaCodec的編碼執(zhí)行操作。如果是解碼,與編碼過(guò)程相反即可完成。
總結(jié)
- 優(yōu)點(diǎn):MediaCodec是Android重要的底層多媒體組件,合理使用MediaCodec可以實(shí)現(xiàn)播放器、直播、視頻編輯、視頻錄制、視頻通話、視頻會(huì)議等幾乎所有音視頻相關(guān)的編解碼功能,且與常規(guī)編解碼庫(kù)相比擁有絕對(duì)的性能優(yōu)勢(shì)。
- 不足:MediaCodec也存在一些缺點(diǎn),兼容性、穩(wěn)定性都比較差,開(kāi)發(fā)過(guò)程中會(huì)經(jīng)常遇到機(jī)型、版本等適配問(wèn)題,這些都可以通過(guò)適配合理解決。
四、音頻NDK API開(kāi)發(fā)
如果遇到一些要求更高的項(xiàng)目開(kāi)發(fā),對(duì)音頻有高性能的需求,比如說(shuō):所需的不僅僅是簡(jiǎn)單的聲音播放或錄制功能。它們需要響應(yīng)式實(shí)時(shí)系統(tǒng)行為。一些典型用例如:音頻合成器、電子鼓、音樂(lè)學(xué)習(xí)應(yīng)用、DJ 混音、音效、視頻/音頻會(huì)議等這類(lèi)要求特別高的需求時(shí)。就要從更深層次的底層來(lái)提供功能支持,這里就會(huì)用到NDK開(kāi)發(fā)。
首先來(lái)了解一下NDK,全稱(chēng)是Native Development Kit,翻譯為原生開(kāi)發(fā)工具包,主要的作用是可以讓開(kāi)發(fā)者在Android應(yīng)用中利用C和c++代碼的工具,可用以從自己的源代碼構(gòu)建,或者利用現(xiàn)有的預(yù)構(gòu)建庫(kù)。
本部分的內(nèi)容可以在如下的Android官方網(wǎng)站中進(jìn)行查看和學(xué)習(xí):https://developer.android.google.cn/ndk/guides/audio
Android官方給提供了如下選擇:
- OpenSL ES:全稱(chēng)為Open Sound Library for Embedded Systems,嵌入式音頻加速標(biāo)準(zhǔn)。OpenSL ES是無(wú)授權(quán)費(fèi)、跨平臺(tái)、針對(duì)嵌入式系統(tǒng)精心優(yōu)化的硬件音頻加速 API,為嵌入式移動(dòng)多媒體設(shè)備上的本地 應(yīng)用程序開(kāi)發(fā)者提供了標(biāo)準(zhǔn)化、高性能、低響應(yīng)時(shí)間的音頻功能實(shí)現(xiàn)方法,同時(shí)還實(shí)現(xiàn)了軟/硬件音頻性能的直接跨平臺(tái)部署,不僅降低了執(zhí)行難度,而且促進(jìn)了高級(jí)音頻市場(chǎng)的發(fā)展。
- 與Android的關(guān)系:Android 2.3即API9時(shí)開(kāi)始支持 OpenSL ES 標(biāo)準(zhǔn),通過(guò) NDK 提供相應(yīng)的 API 開(kāi)發(fā)接口。Android 實(shí)現(xiàn)的OpenSL ES只是OpenSL的子集,然后進(jìn)行了擴(kuò)展。
- Android 中OpenSL ES的相關(guān)資料:https://developer.android.google.cn/ndk/guides/audio/opensl
- AAudio:在 Android 8.0 版本后引入的音頻庫(kù) , 該音頻庫(kù)需要使用C語(yǔ)言在Native層進(jìn)行調(diào)用 , 屬于NDK開(kāi)發(fā)范疇 。AAudio是OpenSL ES 庫(kù)的輕量級(jí)實(shí)現(xiàn),同樣具有低延遲 , 高性能的特點(diǎn)。需要特別注意的是,AAudio作為一款定位為輕量級(jí)的音頻庫(kù),只提供寫(xiě)入音頻流進(jìn)行發(fā)音的功能 , 不負(fù)責(zé)音頻設(shè)備管理 , 文件 I / O , 音頻編解碼 等操作 ;
- 音頻輸入:從話筒 , 耳機(jī)等音頻輸入設(shè)備中 , 使用AAudio音頻流采集音頻數(shù)據(jù) , 讀取性能高 , 低延遲 。
- 音頻輸出:將音頻流寫(xiě)入到 AAudio,以極高性能方式將音頻流輸出到發(fā)音設(shè)備中 。
- Oboe:該庫(kù)是基于AAudio封裝的一個(gè)開(kāi)源庫(kù),在github上有開(kāi)源的地址,鏈接如下:https://github.com/google/oboe 該庫(kù)與AAudio是使用C++編寫(xiě)的適用于Android開(kāi)發(fā)的高效率的音頻開(kāi)發(fā),依然屬于NDK開(kāi)發(fā)的范疇。Google官方推薦使用該庫(kù)。
五、音頻算法的開(kāi)源庫(kù)
FFmpeg:路人皆知
FFmpeg是一套可以用來(lái)記錄、轉(zhuǎn)換數(shù)字音頻、視頻,并能將其轉(zhuǎn)化為流的開(kāi)源程序。它提供了錄制、轉(zhuǎn)換以及流化音視頻的完整解決方案。它包含了非常先進(jìn)的音頻/視頻編解碼庫(kù)libavcodec,為了保證高可移植性和編解碼質(zhì)量,libavcodec里很多code都是從頭開(kāi)發(fā)的。
只要是做音視頻開(kāi)發(fā)的開(kāi)發(fā)者,幾乎沒(méi)有不知道FFmpeg庫(kù)的。在github上可以找到FFmpeg的主頁(yè)地址如下:https://github.com/FFmpeg/FFmpeg 官方網(wǎng)站的地址是:https://ffmpeg.org/
其中包含的庫(kù)主要包括:
- libavcodec:音/視頻編碼庫(kù)。
- libavformat:音視頻格式的生成和解析等操作。
- libavutil:公共的工具函數(shù)。
該程序最初在Linux平臺(tái)上開(kāi)發(fā)和使用,目前在windows、mac上均可以使用。
在Android中使用FFmpeg
如果需要在Android中使用FFmpeg,需要進(jìn)行集成。需要經(jīng)過(guò)幾個(gè)步驟:
- 編譯:首先要下載FFmpeg,并進(jìn)行編譯,編譯出Android中需要的文件。
- 將編譯后的內(nèi)容集成到Android項(xiàng)目中。
- 測(cè)試并調(diào)用集成的FFmpeg中的方法。
Speex
Speex主要是針對(duì)語(yǔ)音的開(kāi)源免費(fèi),無(wú)專(zhuān)利保護(hù)的一種音頻壓縮格式,是專(zhuān)門(mén)為碼率在2-44kbps的語(yǔ)音壓縮而設(shè)計(jì)。Speex的特點(diǎn)主要包括:
- 窄帶(8kHz),寬帶(16kHz)和超寬帶(32kHz)壓縮于同一位流
- 可變比特率(VBR)
- 非連續(xù)傳輸(DTX)
- 感官回聲消除(AEC)
- 噪音屏蔽
Slik
Slik算法主要的作用是實(shí)現(xiàn)語(yǔ)音和音頻的編解碼,其主要的特點(diǎn)是:
- 支持4種采樣率:8KHz、12KHz、16KHz、24KHz;三種復(fù)雜度:低、中、高。
- 編碼碼率在 6~40kbps。
- 提供了定點(diǎn)C代碼,非常有利于向ARM、DSP移植和優(yōu)化。
六、總結(jié)
本篇文檔,我們用很長(zhǎng)的篇幅介紹了多媒體開(kāi)發(fā)中的音頻功能的開(kāi)發(fā)和使用,在具體的開(kāi)發(fā)和應(yīng)用中,重點(diǎn)應(yīng)該放在對(duì)整體知識(shí)的理解和架構(gòu)的梳理上,不要拘泥于某個(gè)API的使用,參數(shù)的作用等。歸根到底,不同的實(shí)現(xiàn)方案,不同的解決方案最終的落腳點(diǎn)和代碼操作步驟幾乎是相同的。再次回顧總結(jié)我們本篇內(nèi)容:
- 音頻的播放:MediaPlayer、SoundPool、AudioTrack、RingtoneManager
- 音頻的采集:MediaRecorder
- 音頻格式的轉(zhuǎn)換:MediaCodec
- 底層庫(kù)的支持和使用:OpenSL ES、AAudio、Oboe
- 開(kāi)源庫(kù)的了解和介紹:FFmpeg
總結(jié)
以上是生活随笔為你收集整理的Android使用webview怎么加载uri_Android 多媒体之音频的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: django2使用html模板,Djan
- 下一篇: 基于ANSYS Twin Builder