Exoplayer无法播放长时长本地视频且时长显示异常该如何解决
关于是否为MediaItem导致的问题说明
该问题并非由直接使用MediaItem而非MediaSource配置播放导致。ExoPlayer官方当前推荐优先使用MediaItem进行基础播放配置,传入MediaItem后底层会自动生成适配的MediaSource实例,常规场景下不会引发异常。
问题可能原因
- Uri访问方式错误:你当前使用
video.getPath获取文件系统路径构建MediaItem,Android 10及以上版本分区存储规则对直接访问文件路径做了严格限制,长视频文件体积大,读取过程中容易出现IO权限异常、读取中断的情况,进而引发卡顿、加载失败,同时元数据读取不完整会导致时长解析错误。 - 提取器配置默认值不适配长视频:ExoPlayer默认的媒体提取器预加载阈值较小,若长视频的元数据(如MP4的moov box)存放在文件尾部,默认预加载长度不足以读取到完整元数据,就会返回错误的默认时长99:34:56,同时元数据缺失也会导致播放加载异常。
- 缓冲配置不匹配:你当前使用默认的缓冲配置,该配置是为短视频优化的,长视频播放时缓冲水位不足会导致频繁卡顿,甚至因为无法连续加载足够数据触发播放失败。
修复方案
- 替换Uri获取方式:不再使用文件路径构建
MediaItem,直接使用从MediaStore查询得到的content://格式Uri,避免分区存储限制引发的IO异常。 - 自定义提取器配置,适配长视频元数据解析:
// 配置提取器支持读取存放在文件尾部的元数据 DefaultExtractorsFactory extractorsFactory = new DefaultExtractorsFactory() .setMp4ExtractorFlags(Mp4Extractor.FLAG_ENABLE_MOOV_BOX_AT_END);
- 调整缓冲配置,适配长视频播放:
LoadControl loadControl = new DefaultLoadControl.Builder() .setBufferDurationsMs(30000, 60000, 1500, 5000) .build();
- 构建播放器时传入自定义配置,原有播放逻辑可保持不变:
ExoPlayer player = new ExoPlayer.Builder(context) .setExtractorsFactory(extractorsFactory) .setLoadControl(loadControl) .build(); MediaItem mediaItem = MediaItem.fromUri(mediaStoreContentUri); player.setMediaItem(mediaItem); player.prepare(); player.play();
- 若调整后仍存在问题,可显式构建
ProgressiveMediaSource确保解析逻辑正确:
MediaSource mediaSource = new ProgressiveMediaSource.Factory(extractorsFactory) .createMediaSource(MediaItem.fromUri(mediaStoreContentUri)); player.setMediaSource(mediaSource); player.prepare(); player.play();
内容的提问来源于stack exchange,提问作者Ahmadu Suleiman
相关产品推荐
相关产品推荐

