Remove subtitle types allow-list from DefaultMediaSourceFactory

Removes subtitle allow-list by using SubtitleDecoderFactory.DEFAULT.
When the format is unsupported, the extractor registers one track and
sends the format with the Format#sampleMimeType set to TEXT_UNKNOWN and
Format#codecs field set to the actual subtitle MIME type.
The TextRenderer will recognize this MIME Type as not supported which is
gonna be visible in the event log.

PiperOrigin-RevId: 400679058
This commit is contained in:
ibaker 2021-10-04 11:47:44 +01:00 committed by bachinger
parent 68b17d3391
commit d4b9fe33b4

View File

@ -27,12 +27,17 @@ import com.google.android.exoplayer2.drm.DrmSessionManager;
import com.google.android.exoplayer2.drm.DrmSessionManagerProvider; import com.google.android.exoplayer2.drm.DrmSessionManagerProvider;
import com.google.android.exoplayer2.extractor.DefaultExtractorsFactory; import com.google.android.exoplayer2.extractor.DefaultExtractorsFactory;
import com.google.android.exoplayer2.extractor.Extractor; import com.google.android.exoplayer2.extractor.Extractor;
import com.google.android.exoplayer2.extractor.ExtractorInput;
import com.google.android.exoplayer2.extractor.ExtractorOutput;
import com.google.android.exoplayer2.extractor.ExtractorsFactory; import com.google.android.exoplayer2.extractor.ExtractorsFactory;
import com.google.android.exoplayer2.extractor.PositionHolder;
import com.google.android.exoplayer2.extractor.SeekMap;
import com.google.android.exoplayer2.extractor.TrackOutput;
import com.google.android.exoplayer2.offline.StreamKey; import com.google.android.exoplayer2.offline.StreamKey;
import com.google.android.exoplayer2.source.ads.AdsLoader; import com.google.android.exoplayer2.source.ads.AdsLoader;
import com.google.android.exoplayer2.source.ads.AdsMediaSource; import com.google.android.exoplayer2.source.ads.AdsMediaSource;
import com.google.android.exoplayer2.text.SubtitleDecoderFactory;
import com.google.android.exoplayer2.text.SubtitleExtractor; import com.google.android.exoplayer2.text.SubtitleExtractor;
import com.google.android.exoplayer2.text.webvtt.WebvttDecoder;
import com.google.android.exoplayer2.ui.AdViewProvider; import com.google.android.exoplayer2.ui.AdViewProvider;
import com.google.android.exoplayer2.upstream.DataSource; import com.google.android.exoplayer2.upstream.DataSource;
import com.google.android.exoplayer2.upstream.DataSpec; import com.google.android.exoplayer2.upstream.DataSpec;
@ -44,6 +49,7 @@ import com.google.android.exoplayer2.util.Log;
import com.google.android.exoplayer2.util.MimeTypes; import com.google.android.exoplayer2.util.MimeTypes;
import com.google.android.exoplayer2.util.Util; import com.google.android.exoplayer2.util.Util;
import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableList;
import java.io.IOException;
import java.util.Arrays; import java.util.Arrays;
import java.util.List; import java.util.List;
@ -381,27 +387,27 @@ public final class DefaultMediaSourceFactory implements MediaSourceFactory {
MediaSource[] mediaSources = new MediaSource[subtitleConfigurations.size() + 1]; MediaSource[] mediaSources = new MediaSource[subtitleConfigurations.size() + 1];
mediaSources[0] = mediaSource; mediaSources[0] = mediaSource;
for (int i = 0; i < subtitleConfigurations.size(); i++) { for (int i = 0; i < subtitleConfigurations.size(); i++) {
if (useProgressiveMediaSourceForSubtitles if (useProgressiveMediaSourceForSubtitles) {
&& MimeTypes.TEXT_VTT.equals(subtitleConfigurations.get(i).mimeType)) { Format format =
int index = i; new Format.Builder()
ProgressiveMediaSource.Factory progressiveMediaSourceFactory = .setSampleMimeType(subtitleConfigurations.get(i).mimeType)
new ProgressiveMediaSource.Factory( .setLanguage(subtitleConfigurations.get(i).language)
dataSourceFactory, .setSelectionFlags(subtitleConfigurations.get(i).selectionFlags)
() -> .setRoleFlags(subtitleConfigurations.get(i).roleFlags)
new Extractor[] { .setLabel(subtitleConfigurations.get(i).label)
new SubtitleExtractor( .build();
new WebvttDecoder(), ExtractorsFactory extractorsFactory =
new Format.Builder() () ->
.setSampleMimeType(subtitleConfigurations.get(index).mimeType) new Extractor[] {
.setLanguage(subtitleConfigurations.get(index).language) SubtitleDecoderFactory.DEFAULT.supportsFormat(format)
.setSelectionFlags(subtitleConfigurations.get(index).selectionFlags) ? new SubtitleExtractor(
.setRoleFlags(subtitleConfigurations.get(index).roleFlags) SubtitleDecoderFactory.DEFAULT.createDecoder(format), format)
.setLabel(subtitleConfigurations.get(index).label) : new UnknownSubtitlesExtractor(format)
.build()) };
});
mediaSources[i + 1] = mediaSources[i + 1] =
progressiveMediaSourceFactory.createMediaSource( new ProgressiveMediaSource.Factory(dataSourceFactory, extractorsFactory)
MediaItem.fromUri(subtitleConfigurations.get(i).uri.toString())); .createMediaSource(
MediaItem.fromUri(subtitleConfigurations.get(i).uri.toString()));
} else { } else {
SingleSampleMediaSource.Factory singleSampleSourceFactory = SingleSampleMediaSource.Factory singleSampleSourceFactory =
new SingleSampleMediaSource.Factory(dataSourceFactory) new SingleSampleMediaSource.Factory(dataSourceFactory)
@ -513,4 +519,47 @@ public final class DefaultMediaSourceFactory implements MediaSourceFactory {
C.TYPE_OTHER, new ProgressiveMediaSource.Factory(dataSourceFactory, extractorsFactory)); C.TYPE_OTHER, new ProgressiveMediaSource.Factory(dataSourceFactory, extractorsFactory));
return factories; return factories;
} }
private static final class UnknownSubtitlesExtractor implements Extractor {
private final Format format;
public UnknownSubtitlesExtractor(Format format) {
this.format = format;
}
@Override
public boolean sniff(ExtractorInput input) {
return true;
}
@Override
public void init(ExtractorOutput output) {
TrackOutput trackOutput = output.track(/* id= */ 0, C.TRACK_TYPE_TEXT);
output.seekMap(new SeekMap.Unseekable(C.TIME_UNSET));
output.endTracks();
trackOutput.format(
format
.buildUpon()
.setSampleMimeType(MimeTypes.TEXT_UNKNOWN)
.setCodecs(format.sampleMimeType)
.build());
}
@Override
public int read(ExtractorInput input, PositionHolder seekPosition) throws IOException {
int skipResult = input.skip(Integer.MAX_VALUE);
if (skipResult == C.RESULT_END_OF_INPUT) {
return RESULT_END_OF_INPUT;
}
return RESULT_CONTINUE;
}
@Override
public void seek(long position, long timeUs) {
return;
}
@Override
public void release() {}
}
} }