Android端ExoPlayer播放MOV流报错 求解决方案及兼容库推荐
Android ExoPlayer MOV格式流式播放报错排查方案
问题根因分析
从报错栈定位核心触发逻辑:
- 前置的
Extension not implemented类日志是高通平台OMX实现的常规打印,不属于崩溃根因。真正导致播放失败的是高通1080P规格HEVC硬件解码器OMX.qcom.video.decoder.hevc抛出硬件错误(错误码0x80001009),造成MediaCodec状态机异常,最终ExoPlayer调用dequeueOutputBuffer、stop接口时触发IllegalStateException - 触发硬件解码器错误的直接原因有两个:
- 常规非faststart编码的MOV文件默认将moov元数据块放在文件尾部,流式播放场景下ExoPlayer旧版本无法在未拉取完整文件的前提下解析正确的编码参数,传给解码器的profile值为0,触发解码器初始化失败
- 部分HEVC编码的MOV文件采用了对应机型高通硬解不支持的编码profile/level,ExoPlayer旧版本没有硬解失败自动切换软解的降级逻辑,直接抛出运行时错误
ExoPlayer侧修复步骤
按优先级依次验证:
- 第一步:配置MP4提取器的流式兼容flag,MOV容器与MP4容器基础结构一致,可直接复用Mp4Extractor解析逻辑,开启后支持moov块在尾部的文件边下边播:
DefaultExtractorsFactory extractorsFactory = new DefaultExtractorsFactory() .setMp4ExtractorFlags(Mp4Extractor.FLAG_WORKAROUND_IGNORE_EDIT_LISTS | Mp4Extractor.FLAG_ENABLE_HTTP_SEEK);
- 第二步:配置硬解黑名单,将存在兼容问题的高通HEVC解码器从可用列表中移除,强制ExoPlayer回退到FFmpeg软解播放,需要提前引入ExoPlayer的FFmpeg扩展依赖并编译对应平台so库:
DefaultRenderersFactory renderersFactory = new DefaultRenderersFactory(context) .setExtensionRendererMode(DefaultRenderersFactory.EXTENSION_RENDERER_MODE_PREFER) .setMediaCodecSelector(new MediaCodecSelector() { @Override public List<MediaCodecInfo> getDecoderInfos(MediaCodecList mediaCodecList, String mimeType, boolean requiresSecureDecoder) throws MediaCodecUtil.DecoderQueryException { List<MediaCodecInfo> defaultList = MediaCodecSelector.DEFAULT.getDecoderInfos(mediaCodecList, mimeType, requiresSecureDecoder); if (MimeTypes.VIDEO_HEVC.equals(mimeType)) { defaultList.removeIf(info -> info.name.toLowerCase().contains("qcom.decoder.hevc")); } return defaultList; } });
- 第三步:直接升级ExoPlayer到2.18及以上版本,该版本后官方修复了MOV容器流式解析时的参数传递bug,新增硬解失败自动重试软解的逻辑,无需手动配置解码器黑名单。
备选稳定支持MOV格式的第三方播放库
- 阿里云播放器SDK:内置自研容器解析层,自动适配moov块在文件尾部的MOV流式播放场景,针对高通、联发科、麒麟等主流芯片平台做了全量硬解兼容性适配,不需要业务侧手动处理编码参数兼容问题
- 腾讯云播放器SDK:同样不依赖系统原生MediaCodec的解析逻辑,支持MOV格式边下边播、在线Seek,兼容性表现优于原生ExoPlayer
- IjkPlayer:基于FFmpeg的开源播放器,全格式软解支持完善,MOV格式播放不存在兼容性问题,缺点是包体积较大,部分机型硬解适配需要自行处理bug
原始报错日志
E/ANDR-PERF-MPCTL: Invalid profile no. 0, total profiles 0 only E/OMX-VDEC-1080P: Extension: OMX.google.android.index.storeANWBufferInMetadata not implemented E/OMX-VDEC-1080P: Extension: OMX.google.android.index.storeANWBufferInMetadata not implemented E/OMX-VDEC-1080P: Extension: OMX.google.android.index.configureVideoTunnelMode not implemented E/OMX-VDEC-1080P: Extension: OMX.google.android.index.useAndroidNativeBuffer is supported E/OMX-VDEC-1080P: Extension: OMX.google.android.index.describeHDRStaticInfo not implemented E/OMX-VDEC-1080P: Does not handle dataspace request E/OMXNodeInstance: getConfig(2db0c3b:qcom.decoder.hevc, ??(0x7f000062)) ERROR: UnsupportedSetting(0x80001019) E/OMXNodeInstance: setConfig(2db0c3c:google.aac.decoder, ConfigPriority(0x6f800002)) ERROR: Undefined(0x80001001) E/OMXNodeInstance: setConfig(2db0c3c:google.aac.decoder, ConfigPriority(0x6f800002)) ERROR: Undefined(0x80001001) E/OMX-VDEC-1080P: OMX_COMPONENT_GENERATE_HARDWARE_ERROR E/OMX-VDEC-1080P: ERROR: Sending OMX_ErrorHardware to Client E/ACodec: [OMX.qcom.video.decoder.hevc] ERROR(0x80001009) E/ACodec: signalError(omxError 0x80001009, internalError -2147483648) E/MediaCodec: Codec reported err 0x80001009, actionCode 0, while in state 6 E/OMX-VDEC-1080P: Dropping message 11 since client expected to be in error state E/OMX-VDEC-1080P: Dropping message 11 since client expected to be in error state E/OMX-VDEC-1080P: Dropping message 11 since client expected to be in error state E/OMX-VDEC-1080P: Dropping message 11 since client expected to be in error state E/ExoPlayerImplInternal: Internal runtime error. java.lang.IllegalStateException at android.media.MediaCodec.native_dequeueOutputBuffer(Native Method) at android.media.MediaCodec.dequeueOutputBuffer(MediaCodec.java:2568) at com.google.android.exoplayer2.mediacodec.MediaCodecRenderer.drainOutputBuffer(MediaCodecRenderer.java:1033) at com.google.android.exoplayer2.mediacodec.MediaCodecRenderer.render(MediaCodecRenderer.java:582) at com.google.android.exoplayer2.ExoPlayerImplInternal.doSomeWork(ExoPlayerImplInternal.java:518) at com.google.android.exoplayer2.ExoPlayerImplInternal.handleMessage(ExoPlayerImplInternal.java:301) at android.os.Handler.dispatchMessage(Handler.java:98) at android.os.Looper.loop(Looper.java:165) at android.os.HandlerThread.run(HandlerThread.java:61) E/ExoPlayerImplInternal: Stop failed. java.lang.IllegalStateException at android.media.MediaCodec.native_stop(Native Method) at android.media.MediaCodec.stop(MediaCodec.java:2005) at com.google.android.exoplayer2.mediacodec.MediaCodecRenderer.releaseCodec(MediaCodecRenderer.java:527) at com.google.android.exoplayer2.video.MediaCodecVideoRenderer.releaseCodec(MediaCodecVideoRenderer.java:477) at com.google.android.exoplayer2.mediacodec.MediaCodecRenderer.onDisabled(MediaCodecRenderer.java:483) at com.google.android.exoplayer2.video.MediaCodecVideoRenderer.onDisabled(MediaCodecVideoRenderer.java:365) at com.google.android.exoplayer2.BaseRenderer.disable(BaseRenderer.java:153) at com.google.android.exoplayer2.ExoPlayerImplInternal.disableRenderer(ExoPlayerImplInternal.java:972) at com.google.android.exoplayer2.ExoPlayerImplInternal.resetInternal(ExoPlayerImplInternal.java:768) at com.google.android.exoplayer2.ExoPlayerImplInternal.stopInternal(ExoPlayerImplInternal.java:731) at com.google.android.exoplayer2.ExoPlayerImplInternal.handleMessage(ExoPlayerImplInternal.java:353) at android.os.Handler.dispatchMessage(Handler.java:98) at android.os.Looper.loop(Looper.java:165) at android.os.HandlerThread.run(HandlerThread.java:61)
内容的提问来源于stack exchange,提问作者OMAK
相关产品推荐
相关产品推荐

