使用ExoPlayer播放类Reels视频时出现解码器初始化内存错误
解决ExoPlayer播放短视频时解码器内存不足的问题
针对播放5-6个短视频后出现NO_MEMORY导致解码器初始化失败、设备冻结的问题,可通过以下方案解决:
1. 严格管理Player实例生命周期
- 短视频滑出可视区域或播放完成时,立即释放Player资源:调用
player.release()并将实例置为null,确保硬件解码器被及时回收,避免资源泄漏。 - 在RecyclerView场景中,重写
onViewRecycled方法,回收对应item的Player实例,禁止让不可见item的Player保持活跃状态。
2. 限制同时活跃的Player数量
- 垂直滑动的Reels场景中,仅保留当前可见的1-2个Player实例,其余不可见item直接销毁Player。
- 通过
RecyclerView.OnScrollListener监听滑动状态,滑动停止后仅初始化当前和相邻的1个item的Player,其余全部释放,避免预加载过多解码器。
3. 配置ExoPlayer的内存优化参数
- 启用解码器降级:当硬件解码器内存不足时自动切换到软件解码器
DefaultRenderersFactory renderersFactory = new DefaultRenderersFactory(context) .setEnableDecoderFallback(true); ExoPlayer player = new ExoPlayer.Builder(context, renderersFactory).build(); - 限制缓存大小,避免缓存占用过多内存:
// 设置最大缓存为50MB,使用LRU策略清理旧缓存 Cache cache = new SimpleCache( new File(context.getCacheDir(), "exo_short_cache"), new LeastRecentlyUsedCacheEvictor(50 * 1024 * 1024) ); DataSource.Factory dataSourceFactory = new CacheDataSource.Factory() .setCache(cache) .setUpstreamDataSourceFactory(new DefaultHttpDataSource.Factory());
4. 添加异常 fallback 逻辑
- 捕获解码器初始化失败异常,强制切换到软件解码器重试:
player.addListener(new Player.Listener() { @Override public void onPlayerError(PlaybackException error) { if (error.getCause() instanceof MediaCodecRenderer.DecoderInitializationException) { // 创建强制使用软件解码器的Player实例 DefaultRenderersFactory factory = new DefaultRenderersFactory(context) .setForceEnableSoftwareDecoder(true); ExoPlayer newPlayer = new ExoPlayer.Builder(context, factory).build(); // 替换旧Player,恢复当前视频播放 bindPlayerToView(newPlayer, currentVideoUri); } } });
5. 优化视频轨道选择
- 选择适配设备的低分辨率轨道,降低解码器内存压力:
DefaultTrackSelector trackSelector = new DefaultTrackSelector(context); trackSelector.setParameters( trackSelector.buildUponParameters() .setMaxVideoSizeSd() // 限制为标清分辨率 .setMaxVideoFrameRate(30) // 限制帧率为30fps ); ExoPlayer player = new ExoPlayer.Builder(context).setTrackSelector(trackSelector).build();
6. 排查内存泄漏
- 使用Android Studio Profiler监控内存,检查是否存在Player实例、MediaCodec实例未被正确回收的情况。
- 避免使用静态变量或全局单例持有Player实例,防止内存泄漏累积。
内容的提问来源于stack exchange,提问作者prabhat biswal
相关产品推荐
相关产品推荐

