首次集成ExoPlayer无法播放URL视频,遇MediaCodec音频解码错误
ExoPlayer集成播放失败问题排查与解决
首次集成ExoPlayer,参照两篇教程和官方文档后,视频始终无法播放,日志抛出以下异常:
E/MediaCodec: Codec reported err 0x80001001, actionCode 0, while in state 6 E/MediaCodecAudioRenderer: Audio codec error java.lang.IllegalStateException at android.media.MediaCodec.native_dequeueOutputBuffer(Native Method) at android.media.MediaCodec.dequeueOutputBuffer(MediaCodec.java:2698) at com.google.android.exoplayer2.mediacodec.SynchronousMediaCodecAdapter.dequeueOutputBufferIndex(SynchronousMediaCodecAdapter.java:106) at com.google.android.exoplayer2.mediacodec.MediaCodecRenderer.drainOutputBuffer(MediaCodecRenderer.java:1819) at com.google.android.exoplayer2.mediacodec.MediaCodecRenderer.render(MediaCodecRenderer.java:792) at com.google.android.exoplayer2.ExoPlayerImplInternal.doSomeWork(ExoPlayerImplInternal.java:989) at com.google.android.exoplayer2.ExoPlayerImplInternal.handleMessage(ExoPlayerImplInternal.java:490) at android.os.Handler.dispatchMessage(Handler.java:102) at android.os.Looper.loop(Looper.java:214) at android.os.HandlerThread.run(HandlerThread.java:65) E/ExoPlayerImplInternal: Playback error com.google.android.exoplayer2.ExoPlaybackException: MediaCodecAudioRenderer error, index=1, format=Format(2, null, null, audio/mp4a-latm, mp4a.40.0, 96000, en, [-1, -1, -1.0], [1, 44100]), format_supported=YES at com.google.android.exoplayer2.ExoPlayerImplInternal.handleMessage(ExoPlayerImplInternal.java:566) at android.os.Handler.dispatchMessage(Handler.java:102) at android.os.Looper.loop(Looper.java:214) at android.os.HandlerThread.run(HandlerThread.java:65) Caused by: com.google.android.exoplayer2.mediacodec.MediaCodecDecoderException: Decoder failed: OMX.google.aac.decoder at com.google.android.exoplayer2.mediacodec.MediaCodecRenderer.createDecoderException(MediaCodecRenderer.java:945) at com.google.android.exoplayer2.mediacodec.MediaCodecRenderer.render(MediaCodecRenderer.java:813) at com.google.android.exoplayer2.ExoPlayerImplInternal.doSomeWork(ExoPlayerImplInternal.java:989) at com.google.android.exoplayer2.ExoPlayerImplInternal.handleMessage(ExoPlayerImplInternal.java:490) at android.os.Handler.dispatchMessage(Handler.java:102) at android.os.Looper.loop(Looper.java:214) at android.os.HandlerThread.run(HandlerThread.java:65) Caused by: java.lang.IllegalStateException at android.media.MediaCodec.native_dequeueOutputBuffer(Native Method) at android.media.MediaCodec.dequeueOutputBuffer(MediaCodec.java:2698) at com.google.android.exoplayer2.mediacodec.SynchronousMediaCodecAdapter.dequeueOutputBufferIndex(SynchronousMediaCodecAdapter.java:106) at com.google.android.exoplayer2.mediacodec.MediaCodecRenderer.drainOutputBuffer(MediaCodecRenderer.java:1819) at com.google.android.exoplayer2.mediacodec.MediaCodecRenderer.render(MediaCodecRenderer.java:792) at com.google.android.exoplayer2.ExoPlayerImplInternal.doSomeWork(ExoPlayerImplInternal.java:989) at com.google.android.exoplayer2.ExoPlayerImplInternal.handleMessage(ExoPlayerImplInternal.java:490) at android.os.Handler.dispatchMessage(Handler.java:102) at android.os.Looper.loop(Looper.java:214) at android.os.HandlerThread.run(HandlerThread.java:65)
PlayerActivity中的代码如下:
playerView = findViewById(R.id.player_view); progressBar = findViewById(R.id.progress_bar); btnFullscreen = findViewById(R.id.btn_fullscreen); //Fullscreen activity getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN); //Get intent Extras String urlExtra = getIntent().getStringExtra("videoUrl"); //Parse video url Uri videoUri = Uri.parse(urlExtra); ExoPlayer player = new ExoPlayer.Builder(this).build(); // Bind the player to the view. playerView.setPlayer(player); // Build the media item. MediaItem mediaItem = MediaItem.fromUri(videoUri); // Set the media item to be played. player.setMediaItem(mediaItem); // Prepare the player. player.prepare(); // Start the playback. player.play();
排查与解决建议
检查音频解码器与视频文件
- 日志明确指向
OMX.google.aac.decoder解码失败,先换一个标准AAC编码的测试视频,排除原视频音频流损坏的可能 - 重启测试设备,修复系统音频解码器临时异常
- 日志明确指向
添加ExoPlayer解码器容错配置
修改播放器构建代码,开启解码器降级 fallback,让ExoPlayer在硬件解码器失败时自动切换到软件解码器:DefaultRenderersFactory renderersFactory = new DefaultRenderersFactory(this) .setEnableAudioDecoderFallback(true); ExoPlayer player = new ExoPlayer.Builder(this) .setRenderersFactory(renderersFactory) .build();完善播放器生命周期管理
当前代码未处理Activity生命周期,容易导致资源泄漏或状态异常,添加以下生命周期回调:@Override protected void onStart() { super.onStart(); player.play(); } @Override protected void onPause() { super.onPause(); player.pause(); } @Override protected void onStop() { super.onStop(); player.stop(); } @Override protected void onDestroy() { super.onDestroy(); player.release(); }确认网络权限(针对网络视频)
如果播放的是网络视频,确保AndroidManifest.xml中已添加必要权限:<uses-permission android:name="android.permission.INTERNET" /> <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
内容的提问来源于stack exchange,提问作者Bryne Phiri
相关产品推荐
相关产品推荐

