Deprecate HlsExtractorFactory.DEFAULT

`HlsExtractorFactory` instances are mutable, so storing one in a static
field is not safe, and can lead to state accidentally/surprisingly being
shared between different player instances.

PiperOrigin-RevId: 685701062
This commit is contained in:
ibaker 2024-10-14 07:34:13 -07:00 committed by Copybara-Service
parent 4a40fa6451
commit 9a23d9a611
3 changed files with 28 additions and 11 deletions

View File

@ -36,7 +36,12 @@ import java.util.Map;
@UnstableApi @UnstableApi
public interface HlsExtractorFactory { public interface HlsExtractorFactory {
HlsExtractorFactory DEFAULT = new DefaultHlsExtractorFactory(); /**
* @deprecated {@code HlsExtractorFactory} instances are mutable, so sharing one in a static field
* is not safe. Construct a new instance of {@link DefaultHlsExtractorFactory} for each usage
* instead.
*/
@Deprecated HlsExtractorFactory DEFAULT = new DefaultHlsExtractorFactory();
/** /**
* Creates an {@link Extractor} for extracting HLS media chunks. * Creates an {@link Extractor} for extracting HLS media chunks.

View File

@ -105,7 +105,9 @@ public final class HlsMediaSource extends BaseMediaSource
private final HlsDataSourceFactory hlsDataSourceFactory; private final HlsDataSourceFactory hlsDataSourceFactory;
private HlsExtractorFactory extractorFactory; @Nullable private HlsExtractorFactory extractorFactory;
@Nullable private SubtitleParser.Factory subtitleParserFactoryOverride;
private boolean parseSubtitlesDuringExtraction;
private HlsPlaylistParserFactory playlistParserFactory; private HlsPlaylistParserFactory playlistParserFactory;
private HlsPlaylistTracker.Factory playlistTrackerFactory; private HlsPlaylistTracker.Factory playlistTrackerFactory;
private CompositeSequenceableLoaderFactory compositeSequenceableLoaderFactory; private CompositeSequenceableLoaderFactory compositeSequenceableLoaderFactory;
@ -128,7 +130,7 @@ public final class HlsMediaSource extends BaseMediaSource
* <li>{@link DefaultDrmSessionManagerProvider} * <li>{@link DefaultDrmSessionManagerProvider}
* <li>{@link DefaultHlsPlaylistParserFactory} * <li>{@link DefaultHlsPlaylistParserFactory}
* <li>{@link DefaultHlsPlaylistTracker#FACTORY} * <li>{@link DefaultHlsPlaylistTracker#FACTORY}
* <li>{@link HlsExtractorFactory#DEFAULT} * <li>{@link DefaultHlsExtractorFactory}
* <li>{@link DefaultLoadErrorHandlingPolicy} * <li>{@link DefaultLoadErrorHandlingPolicy}
* <li>{@link DefaultCompositeSequenceableLoaderFactory} * <li>{@link DefaultCompositeSequenceableLoaderFactory}
* </ul> * </ul>
@ -150,7 +152,7 @@ public final class HlsMediaSource extends BaseMediaSource
* <li>{@link DefaultDrmSessionManagerProvider} * <li>{@link DefaultDrmSessionManagerProvider}
* <li>{@link DefaultHlsPlaylistParserFactory} * <li>{@link DefaultHlsPlaylistParserFactory}
* <li>{@link DefaultHlsPlaylistTracker#FACTORY} * <li>{@link DefaultHlsPlaylistTracker#FACTORY}
* <li>{@link HlsExtractorFactory#DEFAULT} * <li>{@link DefaultHlsExtractorFactory}
* <li>{@link DefaultLoadErrorHandlingPolicy} * <li>{@link DefaultLoadErrorHandlingPolicy}
* <li>{@link DefaultCompositeSequenceableLoaderFactory} * <li>{@link DefaultCompositeSequenceableLoaderFactory}
* </ul> * </ul>
@ -163,7 +165,6 @@ public final class HlsMediaSource extends BaseMediaSource
drmSessionManagerProvider = new DefaultDrmSessionManagerProvider(); drmSessionManagerProvider = new DefaultDrmSessionManagerProvider();
playlistParserFactory = new DefaultHlsPlaylistParserFactory(); playlistParserFactory = new DefaultHlsPlaylistParserFactory();
playlistTrackerFactory = DefaultHlsPlaylistTracker.FACTORY; playlistTrackerFactory = DefaultHlsPlaylistTracker.FACTORY;
extractorFactory = HlsExtractorFactory.DEFAULT;
loadErrorHandlingPolicy = new DefaultLoadErrorHandlingPolicy(); loadErrorHandlingPolicy = new DefaultLoadErrorHandlingPolicy();
compositeSequenceableLoaderFactory = new DefaultCompositeSequenceableLoaderFactory(); compositeSequenceableLoaderFactory = new DefaultCompositeSequenceableLoaderFactory();
metadataType = METADATA_TYPE_ID3; metadataType = METADATA_TYPE_ID3;
@ -174,7 +175,11 @@ public final class HlsMediaSource extends BaseMediaSource
/** /**
* Sets the factory for {@link Extractor}s for the segments. The default value is {@link * Sets the factory for {@link Extractor}s for the segments. The default value is {@link
* HlsExtractorFactory#DEFAULT}. * DefaultHlsExtractorFactory}.
*
* <p>Any values passed to {@link #setSubtitleParserFactory} or {@link
* #experimentalParseSubtitlesDuringExtraction} will be forwarded to the provided {@link
* HlsExtractorFactory} instance during {@link #createMediaSource}.
* *
* @param extractorFactory An {@link HlsExtractorFactory} for {@link Extractor}s for the * @param extractorFactory An {@link HlsExtractorFactory} for {@link Extractor}s for the
* segments. * segments.
@ -182,8 +187,7 @@ public final class HlsMediaSource extends BaseMediaSource
*/ */
@CanIgnoreReturnValue @CanIgnoreReturnValue
public Factory setExtractorFactory(@Nullable HlsExtractorFactory extractorFactory) { public Factory setExtractorFactory(@Nullable HlsExtractorFactory extractorFactory) {
this.extractorFactory = this.extractorFactory = extractorFactory;
extractorFactory != null ? extractorFactory : HlsExtractorFactory.DEFAULT;
return this; return this;
} }
@ -202,7 +206,7 @@ public final class HlsMediaSource extends BaseMediaSource
@CanIgnoreReturnValue @CanIgnoreReturnValue
@Override @Override
public Factory setSubtitleParserFactory(SubtitleParser.Factory subtitleParserFactory) { public Factory setSubtitleParserFactory(SubtitleParser.Factory subtitleParserFactory) {
extractorFactory.setSubtitleParserFactory(checkNotNull(subtitleParserFactory)); this.subtitleParserFactoryOverride = subtitleParserFactory;
return this; return this;
} }
@ -211,7 +215,7 @@ public final class HlsMediaSource extends BaseMediaSource
@CanIgnoreReturnValue @CanIgnoreReturnValue
public Factory experimentalParseSubtitlesDuringExtraction( public Factory experimentalParseSubtitlesDuringExtraction(
boolean parseSubtitlesDuringExtraction) { boolean parseSubtitlesDuringExtraction) {
extractorFactory.experimentalParseSubtitlesDuringExtraction(parseSubtitlesDuringExtraction); this.parseSubtitlesDuringExtraction = parseSubtitlesDuringExtraction;
return this; return this;
} }
@ -384,6 +388,14 @@ public final class HlsMediaSource extends BaseMediaSource
@Override @Override
public HlsMediaSource createMediaSource(MediaItem mediaItem) { public HlsMediaSource createMediaSource(MediaItem mediaItem) {
checkNotNull(mediaItem.localConfiguration); checkNotNull(mediaItem.localConfiguration);
if (extractorFactory == null) {
extractorFactory = new DefaultHlsExtractorFactory();
}
if (subtitleParserFactoryOverride != null) {
extractorFactory.setSubtitleParserFactory(subtitleParserFactoryOverride);
}
extractorFactory.experimentalParseSubtitlesDuringExtraction(parseSubtitlesDuringExtraction);
HlsExtractorFactory extractorFactory = this.extractorFactory;
HlsPlaylistParserFactory playlistParserFactory = this.playlistParserFactory; HlsPlaylistParserFactory playlistParserFactory = this.playlistParserFactory;
List<StreamKey> streamKeys = mediaItem.localConfiguration.streamKeys; List<StreamKey> streamKeys = mediaItem.localConfiguration.streamKeys;
if (!streamKeys.isEmpty()) { if (!streamKeys.isEmpty()) {

View File

@ -543,7 +543,7 @@ public class HlsChunkSourceTest {
private HlsChunkSource createHlsChunkSource(@Nullable CmcdConfiguration cmcdConfiguration) { private HlsChunkSource createHlsChunkSource(@Nullable CmcdConfiguration cmcdConfiguration) {
return new HlsChunkSource( return new HlsChunkSource(
HlsExtractorFactory.DEFAULT, new DefaultHlsExtractorFactory(),
mockPlaylistTracker, mockPlaylistTracker,
new Uri[] {IFRAME_URI, PLAYLIST_URI}, new Uri[] {IFRAME_URI, PLAYLIST_URI},
new Format[] {IFRAME_FORMAT, ExoPlayerTestRunner.VIDEO_FORMAT}, new Format[] {IFRAME_FORMAT, ExoPlayerTestRunner.VIDEO_FORMAT},