Android ExoPlayer本地项目中DefaultRenderersFactory缺失操作模式方法求助
解决ExoPlayer 2.18.5中设置MediaCodec异步模式的问题
问题原因
你参考的DefaultRenderersFactory中设置MediaCodec操作模式的方法是在ExoPlayer 2.19.0及以上版本才新增的,2.18.5版本尚未引入该API,因此找不到对应方法。
解决办法
方案1:升级ExoPlayer版本到2.19.0+
直接将Gradle依赖升级到2.19.0或更高版本,即可使用官方封装的方法:
implementation 'com.google.android.exoplayer:exoplayer:2.19.0'
升级后,可通过以下代码设置异步模式:
DefaultRenderersFactory renderersFactory = new DefaultRenderersFactory(context) .setMediaCodecOperationMode(DefaultRenderersFactory.MEDIA_CODEC_OPERATION_MODE_ASYNCHRONOUS); ExoPlayer player = new ExoPlayer.Builder(context) .setRenderersFactory(renderersFactory) .build();
方案2:在2.18.5版本中自定义MediaCodecSelector
若不想升级版本,可通过自定义MediaCodecSelector手动开启异步模式:
- 实现自定义Selector类:
public class AsyncMediaCodecSelector extends DefaultMediaCodecSelector { @Override public MediaCodec createCodec(String codecName) throws IOException { MediaCodec codec = super.createCodec(codecName); // 绑定异步回调处理缓冲区 codec.setCallback(new MediaCodec.Callback() { @Override public void onInputBufferAvailable(MediaCodec codec, int index) { // 处理输入缓冲区逻辑 } @Override public void onOutputBufferAvailable(MediaCodec codec, int index, MediaCodec.BufferInfo info) { // 处理输出缓冲区逻辑 } @Override public void onError(MediaCodec codec, MediaCodec.CodecException e) { // 错误处理逻辑 } @Override public void onOutputFormatChanged(MediaCodec codec, MediaFormat format) { // 格式变更处理逻辑 } }); return codec; } }
- 将自定义Selector传入DefaultRenderersFactory:
DefaultRenderersFactory renderersFactory = new DefaultRenderersFactory(context); renderersFactory.setMediaCodecSelector(new AsyncMediaCodecSelector()); ExoPlayer player = new ExoPlayer.Builder(context) .setRenderersFactory(renderersFactory) .build();
方案3:自定义MediaCodecRenderer并替换默认实现
通过继承MediaCodecRenderer实现异步模式,再替换默认Renderer:
- 自定义异步视频Renderer:
public class AsyncMediaCodecVideoRenderer extends MediaCodecVideoRenderer { public AsyncMediaCodecVideoRenderer(Context context, MediaCodecSelector mediaCodecSelector, long allowedJoiningTimeMs) { super(context, mediaCodecSelector, allowedJoiningTimeMs); } @Override protected MediaCodec createMediaCodec(String codecName) throws IOException { MediaCodec codec = super.createMediaCodec(codecName); codec.setCallback(new MediaCodec.Callback() { // 实现回调逻辑(同方案2) @Override public void onInputBufferAvailable(MediaCodec codec, int index) {} @Override public void onOutputBufferAvailable(MediaCodec codec, int index, MediaCodec.BufferInfo info) {} @Override public void onError(MediaCodec codec, MediaCodec.CodecException e) {} @Override public void onOutputFormatChanged(MediaCodec codec, MediaFormat format) {} }); return codec; } }
- 自定义RenderersFactory替换默认视频Renderer:
public class AsyncRenderersFactory extends DefaultRenderersFactory { public AsyncRenderersFactory(Context context) { super(context); } @Override protected void buildVideoRenderers(Context context, int extensionRendererMode, MediaCodecSelector mediaCodecSelector, boolean enableDecoderFallback, VideoRendererEventListener eventListener, long allowedJoiningTimeMs, List<Renderer> out) { out.add(new AsyncMediaCodecVideoRenderer(context, mediaCodecSelector, allowedJoiningTimeMs)); // 可按需保留其他默认Renderer } }
- 使用自定义Factory创建ExoPlayer:
ExoPlayer player = new ExoPlayer.Builder(context) .setRenderersFactory(new AsyncRenderersFactory(context)) .build();
内容的提问来源于stack exchange,提问作者Malo
相关产品推荐
相关产品推荐

