Make HlsMediaSource.Builder a factory for HlsMediaSources

-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=178384204
This commit is contained in:
andrewlewis 2017-12-08 09:07:55 -08:00 committed by Oliver Woodman
parent 8947950b52
commit ba32d95dc4
3 changed files with 85 additions and 96 deletions

View File

@ -396,9 +396,7 @@ import java.util.ArrayList;
new DefaultDashChunkSource.Factory(DATA_SOURCE_FACTORY), DATA_SOURCE_FACTORY) new DefaultDashChunkSource.Factory(DATA_SOURCE_FACTORY), DATA_SOURCE_FACTORY)
.createMediaSource(uri); .createMediaSource(uri);
case DemoUtil.MIME_TYPE_HLS: case DemoUtil.MIME_TYPE_HLS:
return HlsMediaSource.Builder return new HlsMediaSource.Factory(DATA_SOURCE_FACTORY).createMediaSource(uri);
.forDataSource(uri, DATA_SOURCE_FACTORY)
.build();
case DemoUtil.MIME_TYPE_VIDEO_MP4: case DemoUtil.MIME_TYPE_VIDEO_MP4:
return new ExtractorMediaSource.Builder(uri, DATA_SOURCE_FACTORY).build(); return new ExtractorMediaSource.Builder(uri, DATA_SOURCE_FACTORY).build();
default: { default: {

View File

@ -375,10 +375,8 @@ public class PlayerActivity extends Activity implements OnClickListener,
buildDataSourceFactory(false)) buildDataSourceFactory(false))
.createMediaSource(uri, mainHandler, eventLogger); .createMediaSource(uri, mainHandler, eventLogger);
case C.TYPE_HLS: case C.TYPE_HLS:
return HlsMediaSource.Builder return new HlsMediaSource.Factory(mediaDataSourceFactory)
.forDataSource(uri, mediaDataSourceFactory) .createMediaSource(uri, mainHandler, eventLogger);
.setEventListener(mainHandler, eventLogger)
.build();
case C.TYPE_OTHER: case C.TYPE_OTHER:
return new ExtractorMediaSource.Builder(uri, mediaDataSourceFactory) return new ExtractorMediaSource.Builder(uri, mediaDataSourceFactory)
.setEventListener(mainHandler, eventLogger) .setEventListener(mainHandler, eventLogger)

View File

@ -17,6 +17,7 @@ package com.google.android.exoplayer2.source.hls;
import android.net.Uri; import android.net.Uri;
import android.os.Handler; import android.os.Handler;
import android.support.annotation.Nullable;
import com.google.android.exoplayer2.C; import com.google.android.exoplayer2.C;
import com.google.android.exoplayer2.ExoPlayer; import com.google.android.exoplayer2.ExoPlayer;
import com.google.android.exoplayer2.ExoPlayerLibraryInfo; import com.google.android.exoplayer2.ExoPlayerLibraryInfo;
@ -29,6 +30,7 @@ import com.google.android.exoplayer2.source.MediaSourceEventListener;
import com.google.android.exoplayer2.source.MediaSourceEventListener.EventDispatcher; import com.google.android.exoplayer2.source.MediaSourceEventListener.EventDispatcher;
import com.google.android.exoplayer2.source.SequenceableLoader; import com.google.android.exoplayer2.source.SequenceableLoader;
import com.google.android.exoplayer2.source.SinglePeriodTimeline; import com.google.android.exoplayer2.source.SinglePeriodTimeline;
import com.google.android.exoplayer2.source.ads.AdsMediaSource;
import com.google.android.exoplayer2.source.hls.playlist.HlsMediaPlaylist; import com.google.android.exoplayer2.source.hls.playlist.HlsMediaPlaylist;
import com.google.android.exoplayer2.source.hls.playlist.HlsPlaylist; import com.google.android.exoplayer2.source.hls.playlist.HlsPlaylist;
import com.google.android.exoplayer2.source.hls.playlist.HlsPlaylistParser; import com.google.android.exoplayer2.source.hls.playlist.HlsPlaylistParser;
@ -50,68 +52,54 @@ public final class HlsMediaSource implements MediaSource,
ExoPlayerLibraryInfo.registerModule("goog.exo.hls"); ExoPlayerLibraryInfo.registerModule("goog.exo.hls");
} }
/** /** Factory for {@link HlsMediaSource}s. */
* Builder for {@link HlsMediaSource}. Each builder instance can only be used once. public static final class Factory implements AdsMediaSource.MediaSourceFactory {
*/
public static final class Builder {
private final Uri manifestUri;
private final HlsDataSourceFactory hlsDataSourceFactory; private final HlsDataSourceFactory hlsDataSourceFactory;
private HlsExtractorFactory extractorFactory; private HlsExtractorFactory extractorFactory;
private ParsingLoadable.Parser<HlsPlaylist> playlistParser; private @Nullable ParsingLoadable.Parser<HlsPlaylist> playlistParser;
private MediaSourceEventListener eventListener;
private Handler eventHandler;
private CompositeSequenceableLoaderFactory compositeSequenceableLoaderFactory; private CompositeSequenceableLoaderFactory compositeSequenceableLoaderFactory;
private int minLoadableRetryCount; private int minLoadableRetryCount;
private boolean allowChunklessPreparation; private boolean allowChunklessPreparation;
private boolean isCreateCalled;
private boolean isBuildCalled;
/** /**
* Creates a {@link Builder} for a {@link HlsMediaSource} with a loadable manifest Uri and * Creates a new factory for {@link HlsMediaSource}s.
* a {@link DataSource.Factory}.
* *
* @param manifestUri The {@link Uri} of the HLS manifest. * @param dataSourceFactory A data source factory that will be wrapped by a {@link
* @param dataSourceFactory A data source factory that will be wrapped by a * DefaultHlsDataSourceFactory} to create {@link DataSource}s for manifests, segments and
* {@link DefaultHlsDataSourceFactory} to build {@link DataSource}s for manifests, * keys.
* segments and keys.
* @return A new builder.
*/ */
public static Builder forDataSource(Uri manifestUri, DataSource.Factory dataSourceFactory) { public Factory(DataSource.Factory dataSourceFactory) {
return new Builder(manifestUri, new DefaultHlsDataSourceFactory(dataSourceFactory)); this(new DefaultHlsDataSourceFactory(dataSourceFactory));
} }
/** /**
* Creates a {@link Builder} for a {@link HlsMediaSource} with a loadable manifest Uri and * Creates a new factory for {@link HlsMediaSource}s.
* a {@link HlsDataSourceFactory}.
* *
* @param manifestUri The {@link Uri} of the HLS manifest. * @param hlsDataSourceFactory An {@link HlsDataSourceFactory} for {@link DataSource}s for
* @param dataSourceFactory An {@link HlsDataSourceFactory} for {@link DataSource}s for
* manifests, segments and keys. * manifests, segments and keys.
* @return A new builder.
*/ */
public static Builder forHlsDataSource(Uri manifestUri, public Factory(HlsDataSourceFactory hlsDataSourceFactory) {
HlsDataSourceFactory dataSourceFactory) { this.hlsDataSourceFactory = Assertions.checkNotNull(hlsDataSourceFactory);
return new Builder(manifestUri, dataSourceFactory); extractorFactory = HlsExtractorFactory.DEFAULT;
}
private Builder(Uri manifestUri, HlsDataSourceFactory hlsDataSourceFactory) {
this.manifestUri = manifestUri;
this.hlsDataSourceFactory = hlsDataSourceFactory;
minLoadableRetryCount = DEFAULT_MIN_LOADABLE_RETRY_COUNT; minLoadableRetryCount = DEFAULT_MIN_LOADABLE_RETRY_COUNT;
compositeSequenceableLoaderFactory = new DefaultCompositeSequenceableLoaderFactory();
} }
/** /**
* Sets the factory for {@link Extractor}s for the segments. Default value is * Sets the factory for {@link Extractor}s for the segments. The default value is {@link
* {@link HlsExtractorFactory#DEFAULT}. * HlsExtractorFactory#DEFAULT}.
* *
* @param extractorFactory An {@link HlsExtractorFactory} for {@link Extractor}s for the * @param extractorFactory An {@link HlsExtractorFactory} for {@link Extractor}s for the
* segments. * segments.
* @return This builder. * @return This factory, for convenience.
* @throws IllegalStateException If one of the {@code create} methods has already been called.
*/ */
public Builder setExtractorFactory(HlsExtractorFactory extractorFactory) { public Factory setExtractorFactory(HlsExtractorFactory extractorFactory) {
this.extractorFactory = extractorFactory; Assertions.checkState(!isCreateCalled);
this.extractorFactory = Assertions.checkNotNull(extractorFactory);
return this; return this;
} }
@ -119,54 +107,46 @@ public final class HlsMediaSource implements MediaSource,
* Sets the minimum number of times to retry if a loading error occurs. The default value is * Sets the minimum number of times to retry if a loading error occurs. The default value is
* {@link #DEFAULT_MIN_LOADABLE_RETRY_COUNT}. * {@link #DEFAULT_MIN_LOADABLE_RETRY_COUNT}.
* *
* @param minLoadableRetryCount The minimum number of times loads must be retried before * @param minLoadableRetryCount The minimum number of times to retry if a loading error occurs.
* errors are propagated. * @return This factory, for convenience.
* @return This builder. * @throws IllegalStateException If one of the {@code create} methods has already been called.
*/ */
public Builder setMinLoadableRetryCount(int minLoadableRetryCount) { public Factory setMinLoadableRetryCount(int minLoadableRetryCount) {
Assertions.checkState(!isCreateCalled);
this.minLoadableRetryCount = minLoadableRetryCount; this.minLoadableRetryCount = minLoadableRetryCount;
return this; return this;
} }
/** /**
* Sets the listener to respond to adaptive {@link MediaSource} events and the handler to * Sets the parser to parse HLS playlists. The default is an instance of {@link
* deliver these events. * HlsPlaylistParser}.
*
* @param eventHandler A handler for events.
* @param eventListener A listener of events.
* @return This builder.
*/
public Builder setEventListener(Handler eventHandler, MediaSourceEventListener eventListener) {
this.eventHandler = eventHandler;
this.eventListener = eventListener;
return this;
}
/**
* Sets the parser to parse HLS playlists. The default is an instance of
* {@link HlsPlaylistParser}.
* *
* @param playlistParser A {@link ParsingLoadable.Parser} for HLS playlists. * @param playlistParser A {@link ParsingLoadable.Parser} for HLS playlists.
* @return This builder. * @return This factory, for convenience.
* @throws IllegalStateException If one of the {@code create} methods has already been called.
*/ */
public Builder setPlaylistParser(ParsingLoadable.Parser<HlsPlaylist> playlistParser) { public Factory setPlaylistParser(ParsingLoadable.Parser<HlsPlaylist> playlistParser) {
this.playlistParser = playlistParser; Assertions.checkState(!isCreateCalled);
this.playlistParser = Assertions.checkNotNull(playlistParser);
return this; return this;
} }
/** /**
* Sets the factory to create composite {@link SequenceableLoader}s for when this media source * Sets the factory to create composite {@link SequenceableLoader}s for when this media source
* loads data from multiple streams (video, audio etc...). The default is an instance of * loads data from multiple streams (video, audio etc...). The default is an instance of {@link
* {@link DefaultCompositeSequenceableLoaderFactory}. * DefaultCompositeSequenceableLoaderFactory}.
* *
* @param compositeSequenceableLoaderFactory A factory to create composite * @param compositeSequenceableLoaderFactory A factory to create composite {@link
* {@link SequenceableLoader}s for when this media source loads data from multiple streams * SequenceableLoader}s for when this media source loads data from multiple streams (video,
* (video, audio etc...). * audio etc...).
* @return This builder. * @return This factory, for convenience.
* @throws IllegalStateException If one of the {@code create} methods has already been called.
*/ */
public Builder setCompositeSequenceableLoaderFactory( public Factory setCompositeSequenceableLoaderFactory(
CompositeSequenceableLoaderFactory compositeSequenceableLoaderFactory) { CompositeSequenceableLoaderFactory compositeSequenceableLoaderFactory) {
this.compositeSequenceableLoaderFactory = compositeSequenceableLoaderFactory; Assertions.checkState(!isCreateCalled);
this.compositeSequenceableLoaderFactory =
Assertions.checkNotNull(compositeSequenceableLoaderFactory);
return this; return this;
} }
@ -175,35 +155,44 @@ public final class HlsMediaSource implements MediaSource,
* will be enabled for streams that provide sufficient information in their master playlist. * will be enabled for streams that provide sufficient information in their master playlist.
* *
* @param allowChunklessPreparation Whether chunkless preparation is allowed. * @param allowChunklessPreparation Whether chunkless preparation is allowed.
* @return This builder. * @return This factory, for convenience.
* @throws IllegalStateException If one of the {@code create} methods has already been called.
*/ */
public Builder setAllowChunklessPreparation(boolean allowChunklessPreparation) { public Factory setAllowChunklessPreparation(boolean allowChunklessPreparation) {
Assertions.checkState(!isCreateCalled);
this.allowChunklessPreparation = allowChunklessPreparation; this.allowChunklessPreparation = allowChunklessPreparation;
return this; return this;
} }
/** /**
* Builds a new {@link HlsMediaSource} using the current parameters. * Returns a new {@link HlsMediaSource} using the current parameters. Media source events will
* <p> * not be delivered.
* After this call, the builder should not be re-used.
* *
* @return The newly built {@link HlsMediaSource}. * @return The new {@link HlsMediaSource}.
*/ */
public HlsMediaSource build() { public MediaSource createMediaSource(Uri playlistUri) {
Assertions.checkArgument((eventListener == null) == (eventHandler == null)); return createMediaSource(playlistUri, null, null);
Assertions.checkState(!isBuildCalled); }
isBuildCalled = true;
if (extractorFactory == null) { /**
extractorFactory = HlsExtractorFactory.DEFAULT; * Returns a new {@link HlsMediaSource} using the current parameters.
} *
* @param playlistUri The playlist {@link Uri}.
* @param eventHandler A handler for events.
* @param eventListener A listener of events.
* @return The new {@link HlsMediaSource}.
*/
@Override
public MediaSource createMediaSource(
Uri playlistUri,
@Nullable Handler eventHandler,
@Nullable MediaSourceEventListener eventListener) {
isCreateCalled = true;
if (playlistParser == null) { if (playlistParser == null) {
playlistParser = new HlsPlaylistParser(); playlistParser = new HlsPlaylistParser();
} }
if (compositeSequenceableLoaderFactory == null) {
compositeSequenceableLoaderFactory = new DefaultCompositeSequenceableLoaderFactory();
}
return new HlsMediaSource( return new HlsMediaSource(
manifestUri, playlistUri,
hlsDataSourceFactory, hlsDataSourceFactory,
extractorFactory, extractorFactory,
compositeSequenceableLoaderFactory, compositeSequenceableLoaderFactory,
@ -214,6 +203,10 @@ public final class HlsMediaSource implements MediaSource,
allowChunklessPreparation); allowChunklessPreparation);
} }
@Override
public int[] getSupportedTypes() {
return new int[] {C.TYPE_HLS};
}
} }
/** /**
@ -240,7 +233,7 @@ public final class HlsMediaSource implements MediaSource,
* @param eventHandler A handler for events. May be null if delivery of events is not required. * @param eventHandler A handler for events. May be null if delivery of events is not required.
* @param eventListener A {@link MediaSourceEventListener}. May be null if delivery of events is * @param eventListener A {@link MediaSourceEventListener}. May be null if delivery of events is
* not required. * not required.
* @deprecated Use {@link Builder} instead. * @deprecated Use {@link Factory} instead.
*/ */
@Deprecated @Deprecated
public HlsMediaSource( public HlsMediaSource(
@ -261,7 +254,7 @@ public final class HlsMediaSource implements MediaSource,
* @param eventHandler A handler for events. May be null if delivery of events is not required. * @param eventHandler A handler for events. May be null if delivery of events is not required.
* @param eventListener A {@link MediaSourceEventListener}. May be null if delivery of events is * @param eventListener A {@link MediaSourceEventListener}. May be null if delivery of events is
* not required. * not required.
* @deprecated Use {@link Builder} instead. * @deprecated Use {@link Factory} instead.
*/ */
@Deprecated @Deprecated
public HlsMediaSource( public HlsMediaSource(
@ -286,7 +279,7 @@ public final class HlsMediaSource implements MediaSource,
* @param eventListener A {@link MediaSourceEventListener}. May be null if delivery of events is * @param eventListener A {@link MediaSourceEventListener}. May be null if delivery of events is
* not required. * not required.
* @param playlistParser A {@link ParsingLoadable.Parser} for HLS playlists. * @param playlistParser A {@link ParsingLoadable.Parser} for HLS playlists.
* @deprecated Use {@link Builder} instead. * @deprecated Use {@link Factory} instead.
*/ */
@Deprecated @Deprecated
public HlsMediaSource( public HlsMediaSource(