You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.14 22:17:33