Add HLS support for parsing TTML subs muxed into MP4 during extraction

This removes the flakiness of the HLS playback test as well.

Previously, this flow only worked for standalone WebVTT subtitles (7b762642db)

PiperOrigin-RevId: 582359383
This commit is contained in:
jbibik 2023-11-14 10:07:57 -08:00 committed by Copybara-Service
parent 67f770a786
commit b23b1bb693
4 changed files with 18 additions and 8 deletions

View File

@ -69,6 +69,8 @@
* Add experimental support for parsing subtitles during extraction. You * Add experimental support for parsing subtitles during extraction. You
can enable this using can enable this using
`HlsMediaSource.Factory.experimentalParseSubtitlesDuringExtraction()`. `HlsMediaSource.Factory.experimentalParseSubtitlesDuringExtraction()`.
This works for standalone WebVTT subtitles and IMSC1 subtitles muxed
into MP4.
* DASH Extension: * DASH Extension:
* Extend experimental support for parsing subtitles during extraction to * Extend experimental support for parsing subtitles during extraction to
work with standalone text files (previously it only worked with work with standalone text files (previously it only worked with

View File

@ -201,7 +201,11 @@ public final class DefaultHlsExtractorFactory implements HlsExtractorFactory {
case FileTypes.MP3: case FileTypes.MP3:
return new Mp3Extractor(/* flags= */ 0, /* forcedFirstSampleTimestampUs= */ 0); return new Mp3Extractor(/* flags= */ 0, /* forcedFirstSampleTimestampUs= */ 0);
case FileTypes.MP4: case FileTypes.MP4:
return createFragmentedMp4Extractor(timestampAdjuster, format, muxedCaptionFormats); Extractor mp4Extractor =
createFragmentedMp4Extractor(timestampAdjuster, format, muxedCaptionFormats);
return subtitleParserFactory != null
? new SubtitleTranscodingExtractor(mp4Extractor, subtitleParserFactory)
: mp4Extractor;
case FileTypes.TS: case FileTypes.TS:
return createTsExtractor( return createTsExtractor(
payloadReaderFactoryFlags, payloadReaderFactoryFlags,

View File

@ -32,7 +32,6 @@ import androidx.media3.test.utils.robolectric.ShadowMediaCodecConfig;
import androidx.media3.test.utils.robolectric.TestPlayerRunHelper; import androidx.media3.test.utils.robolectric.TestPlayerRunHelper;
import androidx.test.core.app.ApplicationProvider; import androidx.test.core.app.ApplicationProvider;
import androidx.test.ext.junit.runners.AndroidJUnit4; import androidx.test.ext.junit.runners.AndroidJUnit4;
import org.junit.Ignore;
import org.junit.Rule; import org.junit.Rule;
import org.junit.Test; import org.junit.Test;
import org.junit.runner.RunWith; import org.junit.runner.RunWith;
@ -72,14 +71,15 @@ public final class HlsPlaybackTest {
} }
@Test @Test
@Ignore(
"Disabled until subtitles are reliably asserted in robolectric tests [internal b/174661563].")
public void ttmlInMp4() throws Exception { public void ttmlInMp4() throws Exception {
Context applicationContext = ApplicationProvider.getApplicationContext(); Context applicationContext = ApplicationProvider.getApplicationContext();
CapturingRenderersFactory capturingRenderersFactory = CapturingRenderersFactory capturingRenderersFactory =
new CapturingRenderersFactory(applicationContext); new CapturingRenderersFactory(applicationContext);
ExoPlayer player = ExoPlayer player =
new ExoPlayer.Builder(applicationContext, capturingRenderersFactory) new ExoPlayer.Builder(applicationContext, capturingRenderersFactory)
.setMediaSourceFactory(
new HlsMediaSource.Factory(new DefaultDataSource.Factory(applicationContext))
.experimentalParseSubtitlesDuringExtraction(true))
.setClock(new FakeClock(/* isAutoAdvancing= */ true)) .setClock(new FakeClock(/* isAutoAdvancing= */ true))
.build(); .build();
player.setVideoSurface(new Surface(new SurfaceTexture(/* texName= */ 1))); player.setVideoSurface(new Surface(new SurfaceTexture(/* texName= */ 1)));

View File

@ -222,22 +222,26 @@ TextOutput:
presentationTimeUs = 0 presentationTimeUs = 0
Cues = [] Cues = []
Subtitle[1]: Subtitle[1]:
presentationTimeUs = 20000
Cue[0]:
text = First Subtitle after 20ms of silence
Subtitle[2]:
presentationTimeUs = 250000 presentationTimeUs = 250000
Cue[0]: Cue[0]:
text = First Subtitle after 20ms of silence text = First Subtitle after 20ms of silence
Second Subtitle overlaps with first Second Subtitle overlaps with first
Subtitle[2]: Subtitle[3]:
presentationTimeUs = 400000 presentationTimeUs = 400000
Cue[0]: Cue[0]:
text = First Subtitle after 20ms of silence text = First Subtitle after 20ms of silence
Subtitle[3]: Subtitle[4]:
presentationTimeUs = 500000 presentationTimeUs = 500000
Cues = [] Cues = []
Subtitle[4]: Subtitle[5]:
presentationTimeUs = 700000 presentationTimeUs = 700000
Cue[0]: Cue[0]:
text = Last subtitle text = Last subtitle
And More And More
Subtitle[5]: Subtitle[6]:
presentationTimeUs = 950000 presentationTimeUs = 950000
Cues = [] Cues = []