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

ExoPlayer播放直播URL时挂起、崩溃问题如何排查解决

ExoPlayer 直播流场景偶现挂起、崩溃修复方案

当前实现没有针对直播流场景做适配,默认配置在弱网、资源加载超时、字幕资源异常时很容易触发播放器线程阻塞、ANR甚至崩溃,和预判的超时原因吻合。

现有问题代码

Uri assetSrtUri = Uri.parse(vvtFilePath);
MediaItem.SubtitleConfiguration subtitle = new MediaItem.SubtitleConfiguration.Builder(assetSrtUri)
        .setMimeType(MimeTypes.TEXT_VTT)
        .setLanguage("en")
        .setSelectionFlags(C.SELECTION_FLAG_DEFAULT)
        .build();

MediaItem mediaItem = new MediaItem.Builder()
        .setUri(uri)
        .setSubtitleConfigurations(ImmutableList.of(subtitle))
        .build();

player.setMediaItem(mediaItem);
player.prepare();

异常截图

异常问题截图

核心问题点

  • 默认LoadControl的缓冲参数针对点播场景设计,直播流长连接无数据时会持续等待,直接触发挂起
  • 默认数据源网络超时时间过长,主直播流、字幕资源加载阻塞时会卡住播放器内部调度
  • 未配置播放器错误监听,异常发生时没有兜底处理逻辑,错误累积最终触发崩溃

修复实现

  1. 引入OkHttp数据源扩展,配置合理的网络超时参数,替换默认数据源:
    // 按需调整超时时间,直播场景不建议超过15s
    OkHttpClient okHttpClient = new OkHttpClient.Builder()
            .connectTimeout(10, TimeUnit.SECONDS)
            .readTimeout(10, TimeUnit.SECONDS)
            .writeTimeout(10, TimeUnit.SECONDS)
            .build();
    OkHttpDataSource.Factory networkFactory = new OkHttpDataSource.Factory(okHttpClient);
    DefaultDataSource.Factory dataSourceFactory = new DefaultDataSource.Factory(getApplicationContext(), networkFactory);
    
  2. 针对直播流自定义缓冲控制参数,避免无意义的长时间缓冲等待:
    DefaultLoadControl liveLoadControl = new DefaultLoadControl.Builder()
            .setBufferDurationsMs(
                    2000, // 最小缓冲时长2s
                    5000, // 最大缓冲时长5s
                    1000, // 初始缓冲1s即可起播
                    1000  // 卡顿时缓冲1s就尝试恢复播放
            )
            .setPrioritizeTimeOverSizeThresholds(true)
            .build();
    
  3. 初始化播放器时传入自定义配置,添加错误监听做兜底处理:
    SimpleExoPlayer player = new SimpleExoPlayer.Builder(getApplicationContext())
            .setDataSourceFactory(dataSourceFactory)
            .setLoadControl(liveLoadControl)
            .build();
    
    // 监听播放器错误,异常时及时释放阻塞,按需做重试逻辑
    player.addListener(new Player.Listener() {
        @Override
        public void onPlayerError(PlaybackException error) {
            player.stop();
            // 网络类错误可触发有限次重试,其他错误直接上报做降级处理
            if (error.errorCode == PlaybackException.ERROR_CODE_IO_NETWORK_CONNECTION_TIMEOUT
                    || error.errorCode == PlaybackException.ERROR_CODE_IO_NETWORK_CONNECTION_FAILED) {
                // 实现自定义重试逻辑,注意加重试次数限制,避免无限重试
            }
        }
    });
    
    // 原有MediaItem构建逻辑可保留,注意提前校验字幕资源地址的可达性
    Uri assetSrtUri = Uri.parse(vvtFilePath);
    MediaItem.SubtitleConfiguration subtitle = new MediaItem.SubtitleConfiguration.Builder(assetSrtUri)
            .setMimeType(MimeTypes.TEXT_VTT)
            .setLanguage("en")
            .setSelectionFlags(C.SELECTION_FLAG_DEFAULT)
            .build();
    
    MediaItem mediaItem = new MediaItem.Builder()
            .setUri(uri)
            .setSubtitleConfigurations(ImmutableList.of(subtitle))
            .build();
    
    player.setMediaItem(mediaItem);
    player.prepare();
    

额外注意:如果使用HLS/DASH等协议的直播流,可以在构建MediaItem时通过setLiveConfiguration配置直播最大偏移容忍度,进一步降低挂起概率;如果字幕是远程资源,需要确认服务端支持Range请求,避免字幕加载失败连带触发播放器异常。

内容的提问来源于stack exchange,提问作者Hemant Bharti

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.29 23:30:38