我正在尝试更改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);
}
我能够通过删除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;
}