Exoplayer即时更改字幕

问题描述 投票:0回答:1

我正在尝试更改Exoplayer中视频的副标题。视频可以有一个字幕,或者用户可以从内部存储添加新的字幕。我知道在启动播放器之前我们可以为字幕和视频创建Mediasource并使用MergingMediaSource进行合并。但是,我不确定如何替换/添加新的字幕到当前正在播放的视频?是否有可能使用DynamicConcatenatingMediaSource或任何其他方式这样做?

 MediaSource[] subTitleMediaSources = new MediaSource[uris.length];
        Format subtitleFormat = Format.createTextSampleFormat(
                null,
                MimeTypes.APPLICATION_SUBRIP,
                C.SELECTION_FLAG_DEFAULT,
                null);
        for (int i = 0; i < uris.length; i++) {
            String subTitle = getSubtitleFile(subs, uris[i]);
            if (subTitle != null) {
                subTitleMediaSources[i] = new SingleSampleMediaSource.Factory(mediaDataSourceFactory).
                        createMediaSource(Uri.parse(subTitle), subtitleFormat,
                                          C.TIME_UNSET);
            } else {
                subTitleMediaSources[i] = new SingleSampleMediaSource.Factory(mediaDataSourceFactory).
                        createMediaSource(Uri.parse("dummy"), subtitleFormat, C.TIME_UNSET);
            }
        }

        MediaSource mediaSource = mediaSources.length == 1 ? mediaSources[0]
                : new ConcatenatingMediaSource(mediaSources);

        MediaSource subsMediaSource = subTitleMediaSources.length == 1 ? subTitleMediaSources[0]
                : new ConcatenatingMediaSource(subTitleMediaSources);

        MediaSource mergedSource;

        if (subsMediaSource == null) {
            mergedSource = mediaSource;
        } else {
            mergedSource = new MergingMediaSource(mediaSource, subsMediaSource);
        }
android exoplayer
1个回答
0
投票

我能够通过删除Mediasource并再次添加它来实现这一点。我用过ConcatenatingMediaSource。我认为应该有一个更好/更简单的方法,只需在现有的MergingMediasource中添加新的字幕源。建议是最受欢迎的。

 public void onSubSelected(String path) {
    final long position = player.getCurrentPosition();

    if (path == null) {
        return;
    }

    List<MediaSource> subtitleSource = new ArrayList<>();
    Uri uri = uris[currentIndex];
    MediaSource trackSource = buildMediaSource(uri);
    List<String> subPaths;
    if (!pathSubtitleMapping.containsKey(uri)) {
        subPaths = new ArrayList<>();
        subPaths.add(path);
        subtitleSource.add(buildSubtitleSource(path));
        pathSubtitleMapping.put(uris[currentIndex], subPaths);
    } else {
        subPaths = pathSubtitleMapping.get(uri);
        if (!subPaths.contains(path)) {
            subPaths.add(path);
        }
        for (String path1 : subPaths) {
            subtitleSource.add(buildSubtitleSource(path1));
        }
    }
    MediaSource mediaSources[] = new MediaSource[subtitleSource.size() + 1];
    mediaSources[0] = trackSource;
    int index = 1;
    for (MediaSource source : subtitleSource) {
        mediaSources[index] = source;
        index++;
    }
    finalMediaSource.removeMediaSource(currentIndex);
    finalMediaSource.addMediaSource(currentIndex, new MergingMediaSource(mediaSources), new Runnable() {
        @Override
        public void run() {
            player.seekTo(currentIndex, position);
        }
    });

}

private Map<Uri, List<String>> pathSubtitleMapping = new HashMap<>(); // (uri, list of subs)

private MediaSource buildMediaSource(Uri uri) {
    MediaSource newSource = new ExtractorMediaSource.Factory(mediaDataSourceFactory).createMediaSource(uri);
    return newSource;

}

private MediaSource buildSubtitleSource(String path) {
    Format subtitleFormat = Format.createTextSampleFormat(
            null,
            MimeTypes.APPLICATION_SUBRIP,
            C.SELECTION_FLAG_DEFAULT,
            null);
    MediaSource mediaSource = new SingleSampleMediaSource.Factory(mediaDataSourceFactory).
            createMediaSource(Uri.parse(path), subtitleFormat, C.TIME_UNSET);
    return mediaSource;
}
© www.soinside.com 2019 - 2024. All rights reserved.