Android使用LAME Mp3编码
下載地址:?LAME MP3 Encoder :: Site Map
當前最新版本是3.100源碼下載后以源碼方式直接引用。在工程中創(chuàng)建main/cpp文件夾,將源碼中的libmp3lame文件夾和include文件夾下的所有.h/.c文件拷貝至cpp目錄下。配置CmakeLists.txt文件。
在build.gradle中配置時需要添加CFLAG 編譯時參數(shù) STDC_HEADERS,否則會在編譯期間報錯
/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編碼庫導(dǎo)入完成,可以開始編碼開發(fā)工作。
整體分為四個階段: 初始化,編碼,刷新緩存,銷毀。
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: 輸入采樣率,默認44100HZ, 應(yīng)該使用AudioRecord時設(shè)置的采樣率。
- out_samplerate: 輸出采樣率,默認是0,LAME支持的輸出頻率有限包括:
MP3全稱是MPEG-1 audio layer3
MPEG-1音頻分為3層,分別是MPEG-1 Layer1/2/3,高層兼容低層,第三層協(xié)議被稱為MPEG-1 Layer3,簡稱MP3,2017年MP3專利過期已無專利保護任何人都可使用,已經(jīng)成為主流的音頻壓縮技術(shù)。壓縮近10倍,適合網(wǎng)絡(luò)傳輸。
因此這里輸出頻率定義為44100HZ即可。
- num_channels: 輸入流的聲道數(shù),最多支持2個聲道,默認為2。根據(jù)AudioRecord采樣時的設(shè)置即可,
- brate: 在CBR模式下有效。bitrate與compress ratio功能相同,僅設(shè)置一個就行,compression默認的壓縮率是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ù)場景選擇。
- mode: 模式。立體聲或者單聲道。默認不設(shè)置和輸入聲道保持一致。
- VBR:? 默認是CBR。VBR是動態(tài)碼率,適合于本地播放,根據(jù)編碼內(nèi)容的復(fù)雜程度動態(tài)的分配比特,因此輸出質(zhì)量比較高;CBR是靜態(tài)碼率,比特率在流處理過程中保持恒定一致,質(zhì)量比變化比較明顯;vbr_off代表設(shè)置為cbr,vbr_mrth代表設(shè)置為vbr。其他參數(shù)可見代碼注釋。
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ù)組長度,如果是單聲道,即對應(yīng)的short數(shù)組的長度
mp3Buf: 編碼結(jié)果返回的數(shù)組,使用單字節(jié)長度容器裝載。
mp3buf_size: 編碼結(jié)果返回的數(shù)組長度,源碼中有建議給出
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的步驟。
我在項目中使用方式是邊錄邊編碼的方式,通過AudioRecord獲取到PCM數(shù)據(jù),立刻通知編碼器進行編碼輸出到文件中。有兩個重要的點:
1. 如何通知給編碼器。 編碼和錄音運行在不同的線程中,如果編碼時機不對會造成遺漏數(shù)據(jù)的問題,因此采用阻塞隊列的方式,在錄音線程開始前即啟動編碼線程,在編碼線程中從阻塞隊列中讀取數(shù)據(jù),如果沒有數(shù)據(jù)則阻塞等待,錄音線程獲取到數(shù)據(jù)后給隊列添加數(shù)據(jù)編碼線程開始處理。即保證了處理的及時性,也沒有耗費CPU資源。
2. 傳遞給LAME的PCM數(shù)據(jù)大小。有可能在錄音階段獲取的是byte數(shù)組,需要專為short數(shù)組,此時可以使用ByteBuffer轉(zhuǎn)換。在判斷是大端序還是小端序時,調(diào)用ByteBuffer#nativeOrder即可。
總結(jié)
以上是生活随笔為你收集整理的Android使用LAME Mp3编码的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: YARN 作业执行流程
- 下一篇: android 通知写法_Android