Promote method to control subtitle parsing to MediaSource.Factory

PiperOrigin-RevId: 586361222
This commit is contained in:
jbibik 2023-11-29 09:09:40 -08:00 committed by Copybara-Service
parent 8a8b875c72
commit 03564fdbc6
8 changed files with 53 additions and 48 deletions

View file

@ -27,6 +27,9 @@
* Fix issue where manual seeks outside of the * Fix issue where manual seeks outside of the
`LiveConfiguration.min/maxOffset` range keep adjusting the offset back `LiveConfiguration.min/maxOffset` range keep adjusting the offset back
to `min/maxOffset`. to `min/maxOffset`.
* Add experimental support for parsing subtitles during extraction. You
can enable this using
`MediaSource.Factory.experimentalParseSubtitlesDuringExtraction()`.
* Transformer: * Transformer:
* Add support for flattening H.265/HEVC SEF slow motion videos. * Add support for flattening H.265/HEVC SEF slow motion videos.
* Increase transmuxing speed, especially for 'remove video' edits. * Increase transmuxing speed, especially for 'remove video' edits.
@ -82,19 +85,10 @@
* HLS Extension: * HLS Extension:
* Reduce `HlsMediaPeriod` to package-private visibility. This type * Reduce `HlsMediaPeriod` to package-private visibility. This type
shouldn't be directly depended on from outside the HLS package. shouldn't be directly depended on from outside the HLS package.
* Add experimental support for parsing subtitles during extraction. You
can enable this using
`HlsMediaSource.Factory.experimentalParseSubtitlesDuringExtraction()`.
* DASH Extension: * DASH Extension:
* Extend experimental support for parsing subtitles during extraction to
work with standalone text files (previously it only worked with
subtitles muxed into MP4 segments).
* Parse "f800" as channel count of 5 for Dolby in DASH manifest * Parse "f800" as channel count of 5 for Dolby in DASH manifest
([#688](https://github.com/androidx/media/issues/688)). ([#688](https://github.com/androidx/media/issues/688)).
* Smooth Streaming Extension: * Smooth Streaming Extension:
* Add experimental support for parsing subtitles during extraction. You
can enable this using
`SsMediaSource.Factory.experimentalParseSubtitlesDuringExtraction()`.
* RTSP Extension: * RTSP Extension:
* Decoder Extensions (FFmpeg, VP9, AV1, MIDI, etc.): * Decoder Extensions (FFmpeg, VP9, AV1, MIDI, etc.):
* MIDI decoder: Ignore SysEx event messages * MIDI decoder: Ignore SysEx event messages

View file

@ -125,7 +125,7 @@ public final class DefaultMediaSourceFactory implements MediaSourceFactory {
private long liveMaxOffsetMs; private long liveMaxOffsetMs;
private float liveMinSpeed; private float liveMinSpeed;
private float liveMaxSpeed; private float liveMaxSpeed;
private boolean useProgressiveMediaSourceForSubtitles; private boolean parseSubtitlesDuringExtraction;
/** /**
* Creates a new instance. * Creates a new instance.
@ -191,21 +191,18 @@ public final class DefaultMediaSourceFactory implements MediaSourceFactory {
} }
/** /**
* Sets whether a {@link ProgressiveMediaSource} or {@link SingleSampleMediaSource} is constructed * {@inheritDoc}
* to handle {@link MediaItem.LocalConfiguration#subtitleConfigurations}. Defaults to false (i.e.
* {@link SingleSampleMediaSource}.
* *
* <p>This method is experimental, and will be renamed or removed in a future release. * <p>The current limitation is that this method will have no effect when progressive media with
* * muxed subtitles is {@linkplain #createMediaSource created}.
* @param useProgressiveMediaSourceForSubtitles Indicates that {@link ProgressiveMediaSource}
* should be used for subtitles instead of {@link SingleSampleMediaSource}.
* @return This factory, for convenience.
*/ */
@CanIgnoreReturnValue @CanIgnoreReturnValue
@UnstableApi @UnstableApi
public DefaultMediaSourceFactory experimentalUseProgressiveMediaSourceForSubtitles( @Override
boolean useProgressiveMediaSourceForSubtitles) { public DefaultMediaSourceFactory experimentalParseSubtitlesDuringExtraction(
this.useProgressiveMediaSourceForSubtitles = useProgressiveMediaSourceForSubtitles; boolean parseSubtitlesDuringExtraction) {
this.parseSubtitlesDuringExtraction = parseSubtitlesDuringExtraction;
delegateFactoryLoader.setParseSubtitlesDuringExtraction(parseSubtitlesDuringExtraction);
return this; return this;
} }
@ -508,7 +505,7 @@ 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 (parseSubtitlesDuringExtraction) {
Format format = Format format =
new Format.Builder() new Format.Builder()
.setSampleMimeType(subtitleConfigurations.get(i).mimeType) .setSampleMimeType(subtitleConfigurations.get(i).mimeType)
@ -610,6 +607,7 @@ public final class DefaultMediaSourceFactory implements MediaSourceFactory {
private final Map<Integer, MediaSource.Factory> mediaSourceFactories; private final Map<Integer, MediaSource.Factory> mediaSourceFactories;
private DataSource.@MonotonicNonNull Factory dataSourceFactory; private DataSource.@MonotonicNonNull Factory dataSourceFactory;
private boolean parseSubtitlesDuringExtraction;
@Nullable private CmcdConfiguration.Factory cmcdConfigurationFactory; @Nullable private CmcdConfiguration.Factory cmcdConfigurationFactory;
@Nullable private DrmSessionManagerProvider drmSessionManagerProvider; @Nullable private DrmSessionManagerProvider drmSessionManagerProvider;
@Nullable private LoadErrorHandlingPolicy loadErrorHandlingPolicy; @Nullable private LoadErrorHandlingPolicy loadErrorHandlingPolicy;
@ -649,6 +647,7 @@ public final class DefaultMediaSourceFactory implements MediaSourceFactory {
if (loadErrorHandlingPolicy != null) { if (loadErrorHandlingPolicy != null) {
mediaSourceFactory.setLoadErrorHandlingPolicy(loadErrorHandlingPolicy); mediaSourceFactory.setLoadErrorHandlingPolicy(loadErrorHandlingPolicy);
} }
mediaSourceFactory.experimentalParseSubtitlesDuringExtraction(parseSubtitlesDuringExtraction);
mediaSourceFactories.put(contentType, mediaSourceFactory); mediaSourceFactories.put(contentType, mediaSourceFactory);
return mediaSourceFactory; return mediaSourceFactory;
} }
@ -663,6 +662,14 @@ public final class DefaultMediaSourceFactory implements MediaSourceFactory {
} }
} }
public void setParseSubtitlesDuringExtraction(boolean parseSubtitlesDuringExtraction) {
this.parseSubtitlesDuringExtraction = parseSubtitlesDuringExtraction;
for (MediaSource.Factory mediaSourceFactory : mediaSourceFactories.values()) {
mediaSourceFactory.experimentalParseSubtitlesDuringExtraction(
parseSubtitlesDuringExtraction);
}
}
public void setCmcdConfigurationFactory(CmcdConfiguration.Factory cmcdConfigurationFactory) { public void setCmcdConfigurationFactory(CmcdConfiguration.Factory cmcdConfigurationFactory) {
this.cmcdConfigurationFactory = cmcdConfigurationFactory; this.cmcdConfigurationFactory = cmcdConfigurationFactory;
for (MediaSource.Factory mediaSourceFactory : mediaSourceFactories.values()) { for (MediaSource.Factory mediaSourceFactory : mediaSourceFactories.values()) {
@ -734,6 +741,7 @@ public final class DefaultMediaSourceFactory implements MediaSourceFactory {
mediaSourceFactorySupplier = () -> newInstance(clazz); mediaSourceFactorySupplier = () -> newInstance(clazz);
break; break;
case C.CONTENT_TYPE_OTHER: case C.CONTENT_TYPE_OTHER:
// TODO(181312195): potential setter on Default/ExtractorsFactory for subtitles
mediaSourceFactorySupplier = mediaSourceFactorySupplier =
() -> new ProgressiveMediaSource.Factory(dataSourceFactory, extractorsFactory); () -> new ProgressiveMediaSource.Factory(dataSourceFactory, extractorsFactory);
break; break;

View file

@ -98,6 +98,24 @@ public interface MediaSource {
@UnstableApi @UnstableApi
Factory setLoadErrorHandlingPolicy(LoadErrorHandlingPolicy loadErrorHandlingPolicy); Factory setLoadErrorHandlingPolicy(LoadErrorHandlingPolicy loadErrorHandlingPolicy);
/**
* Sets whether subtitles should be parsed as part of extraction (before being added to the
* sample queue) or as part of rendering (when being taken from the sample queue). Defaults to
* {@code false} (i.e. subtitles will be parsed as part of rendering).
*
* <p>This method is experimental and will be renamed or removed in a future release.
*
* @param parseSubtitlesDuringExtraction Whether to parse subtitles during extraction or
* rendering.
* @return This factory, for convenience.
*/
// TODO: b/289916598 - Flip the default of this to true.
@UnstableApi
default Factory experimentalParseSubtitlesDuringExtraction(
boolean parseSubtitlesDuringExtraction) {
return this;
}
/** /**
* Returns the {@link C.ContentType content types} supported by media sources created by this * Returns the {@link C.ContentType content types} supported by media sources created by this
* factory. * factory.

View file

@ -103,7 +103,7 @@ public final class PlaylistPlaybackTest {
new CapturingRenderersFactory(applicationContext); new CapturingRenderersFactory(applicationContext);
MediaSource.Factory mediaSourceFactory = MediaSource.Factory mediaSourceFactory =
new DefaultMediaSourceFactory(applicationContext) new DefaultMediaSourceFactory(applicationContext)
.experimentalUseProgressiveMediaSourceForSubtitles(true); .experimentalParseSubtitlesDuringExtraction(true);
ExoPlayer player = ExoPlayer player =
new ExoPlayer.Builder(applicationContext, capturingRenderersFactory) new ExoPlayer.Builder(applicationContext, capturingRenderersFactory)
.setClock(new FakeClock(/* isAutoAdvancing= */ true)) .setClock(new FakeClock(/* isAutoAdvancing= */ true))

View file

@ -60,7 +60,7 @@ public class WebvttPlaybackTest {
new CapturingRenderersFactory(applicationContext); new CapturingRenderersFactory(applicationContext);
MediaSource.Factory mediaSourceFactory = MediaSource.Factory mediaSourceFactory =
new DefaultMediaSourceFactory(applicationContext) new DefaultMediaSourceFactory(applicationContext)
.experimentalUseProgressiveMediaSourceForSubtitles(true); .experimentalParseSubtitlesDuringExtraction(true);
ExoPlayer player = ExoPlayer player =
new ExoPlayer.Builder(applicationContext, capturingRenderersFactory) new ExoPlayer.Builder(applicationContext, capturingRenderersFactory)
.setClock(new FakeClock(/* isAutoAdvancing= */ true)) .setClock(new FakeClock(/* isAutoAdvancing= */ true))

View file

@ -200,12 +200,7 @@ public final class DashMediaSource extends BaseMediaSource {
} }
/** /**
* Sets whether subtitles should be parsed as part of extraction (before the sample queue) or as * {@inheritDoc}
* part of rendering (after the sample queue). Defaults to false (i.e. subtitles will be parsed
* as part of rendering).
*
* <p>This method is experimental. Its default value may change, or it may be renamed or removed
* in a future release.
* *
* <p>This method may only be used with {@link DefaultDashChunkSource.Factory}. * <p>This method may only be used with {@link DefaultDashChunkSource.Factory}.
* *
@ -213,8 +208,8 @@ public final class DashMediaSource extends BaseMediaSource {
* rendering. * rendering.
* @return This factory, for convenience. * @return This factory, for convenience.
*/ */
// TODO: b/289916598 - Flip the default of this to true (probably wired up to a single method on // TODO: b/289916598 - Flip the default of this to true.
// DefaultMediaSourceFactory via the MediaSource.Factory interface). @Override
public Factory experimentalParseSubtitlesDuringExtraction( public Factory experimentalParseSubtitlesDuringExtraction(
boolean parseSubtitlesDuringExtraction) { boolean parseSubtitlesDuringExtraction) {
if (parseSubtitlesDuringExtraction) { if (parseSubtitlesDuringExtraction) {

View file

@ -200,12 +200,7 @@ public final class HlsMediaSource extends BaseMediaSource
} }
/** /**
* Sets whether subtitles should be parsed as part of extraction (before the sample queue) or as * {@inheritDoc}
* part of rendering (after the sample queue). Defaults to false (i.e. subtitles will be parsed
* as part of rendering).
*
* <p>This method is experimental. Its default value may change, or it may be renamed or removed
* in a future release.
* *
* <p>This method may only be used with {@link DefaultHlsExtractorFactory}. * <p>This method may only be used with {@link DefaultHlsExtractorFactory}.
* *
@ -213,8 +208,8 @@ public final class HlsMediaSource extends BaseMediaSource
* rendering. * rendering.
* @return This factory, for convenience. * @return This factory, for convenience.
*/ */
// TODO: b/289916598 - Flip the default of this to true (probably wired up to a single method on // TODO: b/289916598 - Flip the default of this to true.
// DefaultMediaSourceFactory via the MediaSource.Factory interface). @Override
public Factory experimentalParseSubtitlesDuringExtraction( public Factory experimentalParseSubtitlesDuringExtraction(
boolean parseSubtitlesDuringExtraction) { boolean parseSubtitlesDuringExtraction) {
if (parseSubtitlesDuringExtraction) { if (parseSubtitlesDuringExtraction) {

View file

@ -156,12 +156,7 @@ public final class SsMediaSource extends BaseMediaSource
} }
/** /**
* Sets whether subtitles should be parsed as part of extraction (before being added to the * {@inheritDoc}
* sample queue) or as part of rendering (when being taken from the sample queue). Defaults to
* {@code false} (i.e. subtitles will be parsed as part of rendering).
*
* <p>This method is experimental. Its default value may change, or it may be renamed or removed
* in a future release.
* *
* <p>This method may only be used with {@link DefaultSsChunkSource.Factory}. * <p>This method may only be used with {@link DefaultSsChunkSource.Factory}.
* *
@ -169,8 +164,8 @@ public final class SsMediaSource extends BaseMediaSource
* rendering. * rendering.
* @return This factory, for convenience. * @return This factory, for convenience.
*/ */
// TODO: b/289916598 - Flip the default of this to true (probably wired up to a single method on // TODO: b/289916598 - Flip the default of this to true.
// DefaultMediaSourceFactory via the MediaSource.Factory interface). @Override
public Factory experimentalParseSubtitlesDuringExtraction( public Factory experimentalParseSubtitlesDuringExtraction(
boolean parseSubtitlesDuringExtraction) { boolean parseSubtitlesDuringExtraction) {
if (parseSubtitlesDuringExtraction) { if (parseSubtitlesDuringExtraction) {