Android使用LAME Mp3编码
下載地址:?LAME MP3 Encoder :: Site Map
當(dāng)前最新版本是3.100源碼下載后以源碼方式直接引用。在工程中創(chuàng)建main/cpp文件夾,將源碼中的libmp3lame文件夾和include文件夾下的所有.h/.c文件拷貝至cpp目錄下。配置CmakeLists.txt文件。
在build.gradle中配置時(shí)需要添加CFLAG 編譯時(shí)參數(shù) STDC_HEADERS,否則會(huì)在編譯期間報(bào)錯(cuò)
/cpp/lame/psymodel.c:2164: undefined reference to `bcopy' CMakeFiles/lamer.dir/lame/quantize.c.o:/cpp/lame/quantize.c:1287: more undefined references to `bcopy' follow因此額外添加:
externalNativeBuild {cmake {cFlags '-DSTDC_HEADERS'} }?至此,LAME mp3編碼庫(kù)導(dǎo)入完成,可以開(kāi)始編碼開(kāi)發(fā)工作。
整體分為四個(gè)階段: 初始化,編碼,刷新緩存,銷毀。
1. 初始化
mLameClient = lame_init(); lame_set_in_samplerate(mLameClient, sample_rate); lame_set_out_samplerate(mLameClient, sample_rate); lame_set_num_channels(mLameClient, 1); lame_set_brate(mLameClient, 32); lame_set_quality(mLameClient, 7); lame_init_params(mLameClient);- in_samplerate: 輸入采樣率,默認(rèn)44100HZ, 應(yīng)該使用AudioRecord時(shí)設(shè)置的采樣率。
- out_samplerate: 輸出采樣率,默認(rèn)是0,LAME支持的輸出頻率有限包括:
MP3全稱是MPEG-1 audio layer3
MPEG-1音頻分為3層,分別是MPEG-1 Layer1/2/3,高層兼容低層,第三層協(xié)議被稱為MPEG-1 Layer3,簡(jiǎn)稱MP3,2017年MP3專利過(guò)期已無(wú)專利保護(hù)任何人都可使用,已經(jīng)成為主流的音頻壓縮技術(shù)。壓縮近10倍,適合網(wǎng)絡(luò)傳輸。
因此這里輸出頻率定義為44100HZ即可。
- num_channels: 輸入流的聲道數(shù),最多支持2個(gè)聲道,默認(rèn)為2。根據(jù)AudioRecord采樣時(shí)的設(shè)置即可,
- brate: 在CBR模式下有效。bitrate與compress ratio功能相同,僅設(shè)置一個(gè)就行,compression默認(rèn)的壓縮率是11.025。
- quality: 影響壓縮算法,值范圍為0-9, 0質(zhì)量最好速度最慢,9質(zhì)量最差速度最快。源碼建議:3 near-best quality, not too slow;?5 good quality, fast;?7 ok quality, really fast。根據(jù)場(chǎng)景選擇。
- mode: 模式。立體聲或者單聲道。默認(rèn)不設(shè)置和輸入聲道保持一致。
- VBR:? 默認(rèn)是CBR。VBR是動(dòng)態(tài)碼率,適合于本地播放,根據(jù)編碼內(nèi)容的復(fù)雜程度動(dòng)態(tài)的分配比特,因此輸出質(zhì)量比較高;CBR是靜態(tài)碼率,比特率在流處理過(guò)程中保持恒定一致,質(zhì)量比變化比較明顯;vbr_off代表設(shè)置為cbr,vbr_mrth代表設(shè)置為vbr。其他參數(shù)可見(jiàn)代碼注釋。
2. 編碼
int lame_encode_buffer(lame_global_flags * gfp,const short int pcm_l[], const short int pcm_r[], const int nsamples,unsigned char *mp3buf, const int mp3buf_size)pcm_l: 左聲道數(shù)據(jù),short數(shù)組
pcm_r: 右聲道數(shù)據(jù),short數(shù)組
nsmples: 數(shù)組長(zhǎng)度,如果是單聲道,即對(duì)應(yīng)的short數(shù)組的長(zhǎng)度
mp3Buf: 編碼結(jié)果返回的數(shù)組,使用單字節(jié)長(zhǎng)度容器裝載。
mp3buf_size: 編碼結(jié)果返回的數(shù)組長(zhǎng)度,源碼中有建議給出
mp3buffer_size in bytes = 1.25*num_samples + 7200。
3.刷新緩存
在編碼結(jié)束之后,需要刷新編碼器的緩沖到mp3文件中。
int lame_encode_flush(lame_global_flags * gfp, unsigned char *mp3buffer, int mp3buffer_size)?4.關(guān)閉
int lame_close(lame_global_flags * gfp)以上即LAME編碼mp3的步驟。
我在項(xiàng)目中使用方式是邊錄邊編碼的方式,通過(guò)AudioRecord獲取到PCM數(shù)據(jù),立刻通知編碼器進(jìn)行編碼輸出到文件中。有兩個(gè)重要的點(diǎn):
1. 如何通知給編碼器。 編碼和錄音運(yùn)行在不同的線程中,如果編碼時(shí)機(jī)不對(duì)會(huì)造成遺漏數(shù)據(jù)的問(wèn)題,因此采用阻塞隊(duì)列的方式,在錄音線程開(kāi)始前即啟動(dòng)編碼線程,在編碼線程中從阻塞隊(duì)列中讀取數(shù)據(jù),如果沒(méi)有數(shù)據(jù)則阻塞等待,錄音線程獲取到數(shù)據(jù)后給隊(duì)列添加數(shù)據(jù)編碼線程開(kāi)始處理。即保證了處理的及時(shí)性,也沒(méi)有耗費(fèi)CPU資源。
2. 傳遞給LAME的PCM數(shù)據(jù)大小。有可能在錄音階段獲取的是byte數(shù)組,需要專為short數(shù)組,此時(shí)可以使用ByteBuffer轉(zhuǎn)換。在判斷是大端序還是小端序時(shí),調(diào)用ByteBuffer#nativeOrder即可。
總結(jié)
以上是生活随笔為你收集整理的Android使用LAME Mp3编码的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: YARN 作业执行流程
- 下一篇: android 通知写法_Android