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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.24 18:54:03