網(wǎng)站制作rss千萬不要去電商公司上班
ExoPlayer 是一個開源的 Android 媒體播放庫,由 Google 開發(fā)和維護,用于替代 Android 系統(tǒng)自帶的 MediaPlayer
。它提供了更強大的功能、更好的性能和更高的靈活性,適用于各種復雜的媒體播放場景。所以被廣泛用于各種播放器場景。
最近項目中也使用了Exoplayer進行歌曲播放,但遇到報錯:
02-14 18:26:05.078 2194 3425 I ACodec : codec does not support config operating rate (err -2147483648)
02-14 18:26:05.085 1958 3430 E SoftMP3 : mp3 decoder returned error 1
02-14 18:26:05.085 2194 3425 E ACodec : [OMX.google.mp3.decoder] ERROR(0x80001001)
02-14 18:26:05.085 2194 3425 E ACodec : signalError(omxError 0x80001001, internalError -2147483648)
02-14 18:26:05.085 2194 3425 E MediaCodec: Codec reported err 0x80001001, actionCode 0, while in state 6
02-14 18:26:05.086 2194 2290 E MediaCodecAudioRenderer: Audio codec error
02-14 18:26:05.086 2194 2290 E MediaCodecAudioRenderer: java.lang.IllegalStateException
02-14 18:26:05.086 2194 2290 E MediaCodecAudioRenderer: at android.media.MediaCodec.native_dequeueInputBuffer(Native Method)
02-14 18:26:05.086 2194 2290 E MediaCodecAudioRenderer: at android.media.MediaCodec.dequeueInputBuffer(MediaCodec.java:2505)
02-14 18:26:05.086 2194 2290 E MediaCodecAudioRenderer: at androidx.media3.exoplayer.mediacodec.SynchronousMediaCodecAdapter.dequeueInputBufferIndex(SynchronousMediaCodecAdapter.java:101)
02-14 18:26:05.086 2194 2290 E MediaCodecAudioRenderer: at androidx.media3.exoplayer.mediacodec.MediaCodecRenderer.feedInputBuffer(MediaCodecRenderer.java:1224)
02-14 18:26:05.086 2194 2290 E MediaCodecAudioRenderer: at androidx.media3.exoplayer.mediacodec.MediaCodecRenderer.render(MediaCodecRenderer.java:818)
02-14 18:26:05.086 2194 2290 E MediaCodecAudioRenderer: at androidx.media3.exoplayer.ExoPlayerImplInternal.doSomeWork(ExoPlayerImplInternal.java:1047)
02-14 18:26:05.086 2194 2290 E MediaCodecAudioRenderer: at androidx.media3.exoplayer.ExoPlayerImplInternal.handleMessage(ExoPlayerImplInternal.java:522)
02-14 18:26:05.086 2194 2290 E MediaCodecAudioRenderer: at android.os.Handler.dispatchMessage(Handler.java:98)
02-14 18:26:05.086 2194 2290 E MediaCodecAudioRenderer: at android.os.Looper.loop(Looper.java:154)
02-14 18:26:05.086 2194 2290 E MediaCodecAudioRenderer: at android.os.HandlerThread.run(HandlerThread.java:61)
02-14 18:26:05.088 2194 2290 E ExoPlayerImplInternal: Playback error
android設備系統(tǒng)自帶的mp3解碼器報錯[OMX.google.mp3.decoder],在不同的平臺上測試結(jié)果都報一樣的錯, 硬解碼不行那就只能想辦法進行軟解了。查資料得知Exoplayer是支持通過擴展FFmpeg進行音頻軟解碼的,官方擴展模塊說明文檔為decoder_ffmpeg,那么接下來就是按照官方文檔進行集成擴展了。
decoder_ffmpeg模塊最終會被編譯打包成aar文件供Android調(diào)用,由于依賴FFmpeg,先要下載FFmpeg源碼進行編譯得到所依賴的庫才能成功打包aar。下面詳細介紹整個流程:參考該文章ExoPlayer(AndroidX Media3) 擴展ffmpeg實現(xiàn)音頻軟解碼
環(huán)境準備:
1.Ubuntu 20.04.4 LTS
2.AndroidNDK版本r26C
3.AndroidStudio 2023.1.1(配置好SDK和JDK 17.0.10)
4.ffmpeg6.0源碼
5.ExoPlayer源碼,AndroidX Media release分支版本
?由于一般都是在Windows上進行安卓開發(fā),所以還需要先安裝虛擬機,然后在虛擬機上安裝Ubuntu,通過linux系統(tǒng)完成整個編譯過程。
一、安裝虛擬機
Wmware下載看這里WM秘鑰
安裝教程看這里WM安裝教程
破解秘鑰:
秘鑰許可證
4A4RR-813DK-M81A9-4U35H-06KNDNZ4RR-FTK5H-H81C1-Q30QH-1V2LAJU090-6039P-08409-8J0QH-2YR7F4Y09U-AJK97-089Z0-A3054-83KLA4C21U-2KK9Q-M8130-4V2QH-CF810MC60H-DWHD5-H80U9-6V85M-8280DZA30U-DXF84-4850Q-UMMXZ-W6K8FAC590-2XW97-48EFZ-TZPQE-MYHEAYF39K-DLFE5-H856Z-6NWZE-XQ2XDAC15R-FNZ16-H8DWQ-WFPNV-M28E2CZ1J8-A0D82-489LZ-ZMZQT-P3KX6YA11K-6YE8H-H89ZZ-EXM59-Y6AR0
?二、安裝虛Ubuntu
參考Ubuntu下載安裝教程?
Ubuntu與Windows共享文件夾和復制粘貼
三、下載Exoplayer和FFmpeg最新源碼
目前官方已廢棄Exopler2,代碼已經(jīng)遷移到AndroidX Media,下載完成設置FFMPEG_MODULE_PATH變量
在Ubuntu的File根目錄創(chuàng)建Android/Project目錄存放各種資源,根據(jù)自己實際放任意創(chuàng)建位置即可
打開ubuntu終端窗口,進入到上面新建的目錄下:
cd?Android/Project
git clone https://github.com/androidx/media
cd media && FFMPEG_MODULE_PATH="$(pwd)/libraries/decoder_ffmpeg/src/main"echo $FFMPEG_MODULE_PATH /home/xxx/Android/Project/media/libraries/decoder_ffmpeg/src/main
沒有安裝git的話根據(jù)提示進行安裝即可。
四、下載NDK并配置NDK環(huán)境
1.官網(wǎng)下載NDK,根據(jù)官方說明,需要選擇NDK版本ndk-linux-r26d.zip,虛擬機下載較慢,可在windows上先下好拷貝到虛擬機Ubuntu上,并解壓到/Android/Project/目錄下
2.下載完成后解壓,設置NDK_PATH變量
cd Android/Project
unzip android-ndk-r26d-linux.zip
cd android-ndk-r26c && NDK_PATH="$(pwd)"echo $NDK_PATH /home/xxx/Android/Project/android-ndk-r26d
3.在當前NDK目錄下,執(zhí)行設置編譯環(huán)境指令
//設置編譯平臺Lunux為
HOST_PLATFORM="linux-x86_64"//設置最小支持Android版本,通常為項目設置的minSDK版本,NDKr26最小支持SDK為21
ANDROID_ABI=21
?五、下載FFmpeg源碼并配置環(huán)境變量
進入Android/Project目錄進行ffmpeg源碼下載,MediaX中的Exoplayer要求FFmpeg版本6.0
git clone git://source.ffmpeg.org/ffmpeg
cd ffmpeg
//拉取與最新Exoplayer匹配的版本
git checkout release/6.0
//配置環(huán)境變量
FFMPEG_PATH="$(pwd)"echo $FFMPEG_PATH /home/xxx/Android/Project/ffmpeg
六、配置所需要支持的音頻解碼器類型
ffmpeg所支持音頻格式官方說明點擊這里查看?
//在ffmpeg目錄下執(zhí)行
ENABLED_DECODERS=(aac ac3 mp3 flac)
七、Exoplayer源碼關聯(lián)FFmpeg源碼
將ExoPlayer源碼中ffmpeg模塊jni與ffmpeg源碼關聯(lián),關聯(lián)成功后會在jni目錄中生成一個快捷方式指向ffmpeg源碼目錄
//在ffmpeg目錄下執(zhí)行關聯(lián)指令cd "${FFMPEG_MODULE_PATH}/jni"
ln -s "$FFMPEG_PATH" ffmpeg?
八、編譯FFmpeg
Exoplayer源碼中已經(jīng)幫我們配好了編譯腳本build_ffmpeg.sh,執(zhí)行即可,帶上之前配置的環(huán)境變量
//在Exoplayer源碼decoder_ffmpeg模塊,jni目錄下執(zhí)行編譯./build_ffmpeg.sh \ "${FFMPEG_MODULE_PATH}" "${NDK_PATH}" "${HOST_PLATFORM}" "${ANDROID_ABI}" "${ENABLED_DECODERS[@]}"
編譯過程可能報錯,基本根據(jù)報錯信息處理就可以了,我碰到的問題是關聯(lián)的ffmpeg目錄找不到,實際上是關聯(lián)成功了的,腳本中直接把關聯(lián)路徑改成絕對路徑就可以了,報錯的位置如下:
?編譯成功后,會在ffmepg目錄下生成一個android-libs目錄?
?里面有各個不同架構(gòu)平臺的庫,默認生成的是.a靜態(tài)庫文件,android上要用動態(tài)so庫文件,修改一下編譯腳本重新編譯即可:
結(jié)果如下:
?九、編譯decoder_ffmpge模塊打包成aar文件供android調(diào)用
進入到Exoplayer源碼更目錄執(zhí)行編譯打包指令
./gradlew lib-decoder-ffmpeg:assembleRelease
報錯的話更近提示進行處理即可,大概率就是JDK和SDK沒有安裝或者環(huán)境沒有配置對
Ubuntu安裝android sdk教程
Ubuntu安裝JDK教程
編譯成功后會在\libraries\decoder_ffmpeg\buildout\outputs\aar\目錄生成aar包?
十、Android項目中使用aar實現(xiàn)音頻軟解碼?
復制生成的aar包到項目libs目錄,修改app下的build.gradle文件,引用aar包
implementation(files("libs/extension-ffmpeg-release.aar"))
自定義DefaultRenderersFactory,構(gòu)造ExoPlayer實例時傳入,日志中有ffmpeg相關信息代表加載成功。
public class PluginRenderFactory extends DefaultRenderersFactory {/*** @param context A {@link Context}.*/public PluginRenderFactory(Context context) {super(context);}@Overrideprotected void buildAudioRenderers(Context context, int extensionRendererMode, MediaCodecSelector mediaCodecSelector, boolean enableDecoderFallback, AudioSink audioSink, Handler eventHandler, AudioRendererEventListener eventListener, ArrayList<Renderer> out) {ffmpegAudioRenderer = new FfmpegAudioRenderer(eventHandler, eventListener, audioSink);out.add(ffmpegAudioRenderer);super.buildAudioRenderers(context, extensionRendererMode, mediaCodecSelector, enableDecoderFallback, audioSink, eventHandler, eventListener, out);}}mExoPlayer = new ExoPlayer.Builder(context, renderersFactory).build();
?Android中使用可能出現(xiàn)編譯不通過問題,大概率是Android項目使用的各種編譯環(huán)境版本與編譯aar時使用的不一致,Exoplayer源碼使用如下配置:
建議盡量使用相同配置 ,還有就是我Ubuntu配置的JDK是17.0.14版本,所以AndroidStudio編譯也要使用 相同版本JDK
至此大功告成!?
下一篇介紹Exoplayer+FFmpeg實現(xiàn)K歌場景中的切換原伴唱功能K歌中單雙音軌實現(xiàn)原伴唱