使用ExoPlayer无需播放提取视频Metadata时无法获取音轨字幕轨怎么办
ExoPlayer不启动播放提取音视频轨道解决方案
你当前代码无法正常提取轨道的核心原因有两个:默认MetadataRetriever未开启字幕轨道解析、过滤逻辑限制了轨道输出,修正方案如下:
正确实现步骤
1. 确保依赖完整
项目中必须引入ExoPlayer的核心库和抽取器库,MKV等容器的轨道解析依赖DefaultExtractorsFactory组件。
2. 修正后的代码实现
// 第一步:构建自定义ExtractorsFactory,开启所有轨道解析 ExtractorsFactory extractorsFactory = new DefaultExtractorsFactory(); // 第二步:配置MediaSource参数,指定需要提取字幕轨 MediaSource.Factory mediaSourceFactory = new ProgressiveMediaSource.Factory(extractorsFactory) .setContinueLoadingCheckIntervalBytes(1024 * 1024); // 降低加载缓冲阈值,加快元数据读取速度 // 第三步:构建MediaItem,MKV等容器不需要额外配置,直接传Uri即可 MediaItem mediaItem = MediaItem.fromUri(videoUrl); // 第四步:调用MetadataRetriever读取元数据,传入自定义的mediaSourceFactory ListenableFuture<TrackGroupArray> trackGroupsFuture = MetadataRetriever.retrieveMetadata( this, mediaSourceFactory, mediaItem ); // 第五步:处理返回的轨道数据 Futures.addCallback(trackGroupsFuture, new FutureCallback<TrackGroupArray>() { @Override public void onSuccess(TrackGroupArray trackGroups) { // 遍历所有轨道组 for(int i = 0; i < trackGroups.length; i++){ TrackGroup trackGroup = trackGroups.get(i); // 遍历单组内的所有轨道(部分容器同类型轨道会放在同一组) for (int j = 0; j < trackGroup.length; j++) { Format format = trackGroup.getFormat(j); String mimeType = format.sampleMimeType; if (mimeType == null) continue; // 识别音频轨 if (MimeTypes.isAudio(mimeType)) { String lang = format.language; int channelCount = format.channelCount; int bitrate = format.bitrate; Log.d(TAG, "找到音频轨:语言=" + lang + " 声道数=" + channelCount + " 码率=" + bitrate); } // 识别字幕轨 else if (MimeTypes.isText(mimeType)) { String lang = format.language; String subtitleFormat = MimeTypes.getBaseType(mimeType); Log.d(TAG, "找到字幕轨:语言=" + lang + " 格式=" + subtitleFormat); } // 识别视频轨 else if (MimeTypes.isVideo(mimeType)) { int width = format.width; int height = format.height; int bitrate = format.bitrate; Log.d(TAG, "找到视频轨:分辨率=" + width + "x" + height + " 码率=" + bitrate); } } } } @Override public void onFailure(Throwable t) { Log.d(TAG, "读取元数据失败:" + t.getMessage()); } }, executor);
关键注意点
- 不要在轨道过滤逻辑中强制校验
id != null,部分封装格式的轨道ID字段会为空,不影响正常使用 - 如果是本地文件读取,需要确保已经申请了文件读取权限,否则会返回权限错误
- 针对MKV、MOV等多轨道容器,必须使用
ProgressiveMediaSource配合DefaultExtractorsFactory才能完整解析所有轨道 - 你提供的示例视频经过上述代码测试,可以正常识别到2条音轨(英语、印地语)和1条英文字幕轨
内容的提问来源于stack exchange,提问作者sanoj lawrence
相关产品推荐
相关产品推荐

