use of androidx.media3.extractor.text.SubtitleExtractor in project media by androidx.
the class DefaultMediaSourceFactory method createMediaSource.
@UnstableApi
@Override
public MediaSource createMediaSource(MediaItem mediaItem) {
Assertions.checkNotNull(mediaItem.localConfiguration);
@Nullable String scheme = mediaItem.localConfiguration.uri.getScheme();
if (scheme != null && scheme.equals(C.SSAI_SCHEME)) {
return checkNotNull(serverSideAdInsertionMediaSourceFactory).createMediaSource(mediaItem);
}
@C.ContentType int type = Util.inferContentTypeForUriAndMimeType(mediaItem.localConfiguration.uri, mediaItem.localConfiguration.mimeType);
@Nullable MediaSource.Factory mediaSourceFactory = delegateFactoryLoader.getMediaSourceFactory(type);
checkStateNotNull(mediaSourceFactory, "No suitable media source factory found for content type: " + type);
MediaItem.LiveConfiguration.Builder liveConfigurationBuilder = mediaItem.liveConfiguration.buildUpon();
if (mediaItem.liveConfiguration.targetOffsetMs == C.TIME_UNSET) {
liveConfigurationBuilder.setTargetOffsetMs(liveTargetOffsetMs);
}
if (mediaItem.liveConfiguration.minPlaybackSpeed == C.RATE_UNSET) {
liveConfigurationBuilder.setMinPlaybackSpeed(liveMinSpeed);
}
if (mediaItem.liveConfiguration.maxPlaybackSpeed == C.RATE_UNSET) {
liveConfigurationBuilder.setMaxPlaybackSpeed(liveMaxSpeed);
}
if (mediaItem.liveConfiguration.minOffsetMs == C.TIME_UNSET) {
liveConfigurationBuilder.setMinOffsetMs(liveMinOffsetMs);
}
if (mediaItem.liveConfiguration.maxOffsetMs == C.TIME_UNSET) {
liveConfigurationBuilder.setMaxOffsetMs(liveMaxOffsetMs);
}
MediaItem.LiveConfiguration liveConfiguration = liveConfigurationBuilder.build();
// Make sure to retain the very same media item instance, if no value needs to be overridden.
if (!liveConfiguration.equals(mediaItem.liveConfiguration)) {
mediaItem = mediaItem.buildUpon().setLiveConfiguration(liveConfiguration).build();
}
MediaSource mediaSource = mediaSourceFactory.createMediaSource(mediaItem);
List<MediaItem.SubtitleConfiguration> subtitleConfigurations = castNonNull(mediaItem.localConfiguration).subtitleConfigurations;
if (!subtitleConfigurations.isEmpty()) {
MediaSource[] mediaSources = new MediaSource[subtitleConfigurations.size() + 1];
mediaSources[0] = mediaSource;
for (int i = 0; i < subtitleConfigurations.size(); i++) {
if (useProgressiveMediaSourceForSubtitles) {
Format format = new Format.Builder().setSampleMimeType(subtitleConfigurations.get(i).mimeType).setLanguage(subtitleConfigurations.get(i).language).setSelectionFlags(subtitleConfigurations.get(i).selectionFlags).setRoleFlags(subtitleConfigurations.get(i).roleFlags).setLabel(subtitleConfigurations.get(i).label).setId(subtitleConfigurations.get(i).id).build();
ExtractorsFactory extractorsFactory = () -> new Extractor[] { SubtitleDecoderFactory.DEFAULT.supportsFormat(format) ? new SubtitleExtractor(SubtitleDecoderFactory.DEFAULT.createDecoder(format), format) : new UnknownSubtitlesExtractor(format) };
mediaSources[i + 1] = new ProgressiveMediaSource.Factory(dataSourceFactory, extractorsFactory).setLoadErrorHandlingPolicy(loadErrorHandlingPolicy).createMediaSource(MediaItem.fromUri(subtitleConfigurations.get(i).uri.toString()));
} else {
mediaSources[i + 1] = new SingleSampleMediaSource.Factory(dataSourceFactory).setLoadErrorHandlingPolicy(loadErrorHandlingPolicy).createMediaSource(subtitleConfigurations.get(i), /* durationUs= */
C.TIME_UNSET);
}
}
mediaSource = new MergingMediaSource(mediaSources);
}
return maybeWrapWithAdsMediaSource(mediaItem, maybeClipMediaSource(mediaItem, mediaSource));
}
use of androidx.media3.extractor.text.SubtitleExtractor in project media by androidx.
the class SubtitleExtractorTest method seek_withoutInit_fails.
@Test
public void seek_withoutInit_fails() {
SubtitleExtractor extractor = new SubtitleExtractor(new WebvttDecoder(), new Format.Builder().build());
assertThrows(IllegalStateException.class, () -> extractor.seek(0, 0));
}
use of androidx.media3.extractor.text.SubtitleExtractor in project media by androidx.
the class SubtitleExtractorTest method extractor_seekAfterExtracting_outputsCues.
@Test
public void extractor_seekAfterExtracting_outputsCues() throws Exception {
CueDecoder decoder = new CueDecoder();
FakeExtractorOutput output = new FakeExtractorOutput();
FakeExtractorInput input = new FakeExtractorInput.Builder().setData(Util.getUtf8Bytes(TEST_DATA)).setSimulatePartialReads(true).build();
SubtitleExtractor extractor = new SubtitleExtractor(new WebvttDecoder(), new Format.Builder().setSampleMimeType(MimeTypes.TEXT_VTT).build());
extractor.init(output);
FakeTrackOutput trackOutput = output.trackOutputs.get(0);
while (extractor.read(input, null) != Extractor.RESULT_END_OF_INPUT) {
}
extractor.seek((int) output.seekMap.getSeekPoints(2_445_000L).first.position, 2_445_000L);
input.setPosition((int) output.seekMap.getSeekPoints(2_445_000L).first.position);
trackOutput.clear();
while (extractor.read(input, null) != Extractor.RESULT_END_OF_INPUT) {
}
assertThat(trackOutput.lastFormat.sampleMimeType).isEqualTo(MimeTypes.TEXT_EXOPLAYER_CUES);
assertThat(trackOutput.lastFormat.codecs).isEqualTo(MimeTypes.TEXT_VTT);
assertThat(trackOutput.getSampleCount()).isEqualTo(4);
// Check sample timestamps.
assertThat(trackOutput.getSampleTimeUs(0)).isEqualTo(2_345_000L);
assertThat(trackOutput.getSampleTimeUs(1)).isEqualTo(2_600_000L);
assertThat(trackOutput.getSampleTimeUs(2)).isEqualTo(3_456_000L);
assertThat(trackOutput.getSampleTimeUs(3)).isEqualTo(4_567_000L);
// Check sample content.
List<Cue> cues0 = decoder.decode(trackOutput.getSampleData(0));
assertThat(cues0).hasSize(1);
assertThat(cues0.get(0).text.toString()).isEqualTo("This is the second subtitle.");
List<Cue> cues1 = decoder.decode(trackOutput.getSampleData(1));
assertThat(cues1).hasSize(2);
assertThat(cues1.get(0).text.toString()).isEqualTo("This is the second subtitle.");
assertThat(cues1.get(1).text.toString()).isEqualTo("This is the third subtitle.");
List<Cue> cues2 = decoder.decode(trackOutput.getSampleData(2));
assertThat(cues2).hasSize(1);
assertThat(cues2.get(0).text.toString()).isEqualTo("This is the third subtitle.");
List<Cue> cues3 = decoder.decode(trackOutput.getSampleData(3));
assertThat(cues3).isEmpty();
}
use of androidx.media3.extractor.text.SubtitleExtractor in project media by androidx.
the class SubtitleExtractorTest method extractor_seekBetweenReads_outputsCues.
@Test
public void extractor_seekBetweenReads_outputsCues() throws Exception {
CueDecoder decoder = new CueDecoder();
FakeExtractorOutput output = new FakeExtractorOutput();
FakeExtractorInput input = new FakeExtractorInput.Builder().setData(Util.getUtf8Bytes(TEST_DATA)).setSimulatePartialReads(true).build();
SubtitleExtractor extractor = new SubtitleExtractor(new WebvttDecoder(), new Format.Builder().setSampleMimeType(MimeTypes.TEXT_VTT).build());
extractor.init(output);
FakeTrackOutput trackOutput = output.trackOutputs.get(0);
assertThat(extractor.read(input, null)).isNotEqualTo(Extractor.RESULT_END_OF_INPUT);
extractor.seek((int) output.seekMap.getSeekPoints(2_345_000L).first.position, 2_345_000L);
input.setPosition((int) output.seekMap.getSeekPoints(2_345_000L).first.position);
trackOutput.clear();
while (extractor.read(input, null) != Extractor.RESULT_END_OF_INPUT) {
}
assertThat(trackOutput.lastFormat.sampleMimeType).isEqualTo(MimeTypes.TEXT_EXOPLAYER_CUES);
assertThat(trackOutput.lastFormat.codecs).isEqualTo(MimeTypes.TEXT_VTT);
assertThat(trackOutput.getSampleCount()).isEqualTo(4);
// Check sample timestamps.
assertThat(trackOutput.getSampleTimeUs(0)).isEqualTo(2_345_000L);
assertThat(trackOutput.getSampleTimeUs(1)).isEqualTo(2_600_000L);
assertThat(trackOutput.getSampleTimeUs(2)).isEqualTo(3_456_000L);
assertThat(trackOutput.getSampleTimeUs(3)).isEqualTo(4_567_000L);
// Check sample content.
List<Cue> cues0 = decoder.decode(trackOutput.getSampleData(0));
assertThat(cues0).hasSize(1);
assertThat(cues0.get(0).text.toString()).isEqualTo("This is the second subtitle.");
List<Cue> cues1 = decoder.decode(trackOutput.getSampleData(1));
assertThat(cues1).hasSize(2);
assertThat(cues1.get(0).text.toString()).isEqualTo("This is the second subtitle.");
assertThat(cues1.get(1).text.toString()).isEqualTo("This is the third subtitle.");
List<Cue> cues2 = decoder.decode(trackOutput.getSampleData(2));
assertThat(cues2).hasSize(1);
assertThat(cues2.get(0).text.toString()).isEqualTo("This is the third subtitle.");
List<Cue> cues3 = decoder.decode(trackOutput.getSampleData(3));
assertThat(cues3).isEmpty();
}
use of androidx.media3.extractor.text.SubtitleExtractor in project media by androidx.
the class SubtitleExtractorTest method read_withoutInit_fails.
@Test
public void read_withoutInit_fails() {
FakeExtractorInput input = new FakeExtractorInput.Builder().setData(new byte[0]).build();
SubtitleExtractor extractor = new SubtitleExtractor(new WebvttDecoder(), new Format.Builder().build());
assertThrows(IllegalStateException.class, () -> extractor.read(input, null));
}
Aggregations