mirror of
https://github.com/androidx/media.git
synced 2025-04-30 06:46:50 +08:00
Forward TransferListener from MediaSources to DataSources.
This wires up recent changes of passing a transfer listener to the MediaSource and allowing DataSources to accept new listeners. ------------- Created by MOE: https://github.com/google/moe MOE_MIGRATED_REVID=203280818
This commit is contained in:
parent
abb4d6ff70
commit
acbe52d0d7
@ -68,40 +68,6 @@ public final class ExtractorMediaSource extends BaseMediaSource
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* The default minimum number of times to retry loading prior to failing for on-demand streams.
|
||||
*/
|
||||
public static final int DEFAULT_MIN_LOADABLE_RETRY_COUNT_ON_DEMAND = 3;
|
||||
|
||||
/**
|
||||
* The default minimum number of times to retry loading prior to failing for live streams.
|
||||
*/
|
||||
public static final int DEFAULT_MIN_LOADABLE_RETRY_COUNT_LIVE = 6;
|
||||
|
||||
/**
|
||||
* Value for {@code minLoadableRetryCount} that causes the loader to retry
|
||||
* {@link #DEFAULT_MIN_LOADABLE_RETRY_COUNT_LIVE} times for live streams and
|
||||
* {@link #DEFAULT_MIN_LOADABLE_RETRY_COUNT_ON_DEMAND} for on-demand streams.
|
||||
*/
|
||||
public static final int MIN_RETRY_COUNT_DEFAULT_FOR_MEDIA = -1;
|
||||
|
||||
/**
|
||||
* The default number of bytes that should be loaded between each each invocation of
|
||||
* {@link MediaPeriod.Callback#onContinueLoadingRequested(SequenceableLoader)}.
|
||||
*/
|
||||
public static final int DEFAULT_LOADING_CHECK_INTERVAL_BYTES = 1024 * 1024;
|
||||
|
||||
private final Uri uri;
|
||||
private final DataSource.Factory dataSourceFactory;
|
||||
private final ExtractorsFactory extractorsFactory;
|
||||
private final int minLoadableRetryCount;
|
||||
private final String customCacheKey;
|
||||
private final int continueLoadingCheckIntervalBytes;
|
||||
private final @Nullable Object tag;
|
||||
|
||||
private long timelineDurationUs;
|
||||
private boolean timelineIsSeekable;
|
||||
|
||||
/** Factory for {@link ExtractorMediaSource}s. */
|
||||
public static final class Factory implements AdsMediaSource.MediaSourceFactory {
|
||||
|
||||
@ -244,6 +210,39 @@ public final class ExtractorMediaSource extends BaseMediaSource
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* The default minimum number of times to retry loading prior to failing for on-demand streams.
|
||||
*/
|
||||
public static final int DEFAULT_MIN_LOADABLE_RETRY_COUNT_ON_DEMAND = 3;
|
||||
|
||||
/** The default minimum number of times to retry loading prior to failing for live streams. */
|
||||
public static final int DEFAULT_MIN_LOADABLE_RETRY_COUNT_LIVE = 6;
|
||||
|
||||
/**
|
||||
* Value for {@code minLoadableRetryCount} that causes the loader to retry {@link
|
||||
* #DEFAULT_MIN_LOADABLE_RETRY_COUNT_LIVE} times for live streams and {@link
|
||||
* #DEFAULT_MIN_LOADABLE_RETRY_COUNT_ON_DEMAND} for on-demand streams.
|
||||
*/
|
||||
public static final int MIN_RETRY_COUNT_DEFAULT_FOR_MEDIA = -1;
|
||||
|
||||
/**
|
||||
* The default number of bytes that should be loaded between each each invocation of {@link
|
||||
* MediaPeriod.Callback#onContinueLoadingRequested(SequenceableLoader)}.
|
||||
*/
|
||||
public static final int DEFAULT_LOADING_CHECK_INTERVAL_BYTES = 1024 * 1024;
|
||||
|
||||
private final Uri uri;
|
||||
private final DataSource.Factory dataSourceFactory;
|
||||
private final ExtractorsFactory extractorsFactory;
|
||||
private final int minLoadableRetryCount;
|
||||
private final String customCacheKey;
|
||||
private final int continueLoadingCheckIntervalBytes;
|
||||
private final @Nullable Object tag;
|
||||
|
||||
private long timelineDurationUs;
|
||||
private boolean timelineIsSeekable;
|
||||
private @Nullable TransferListener<? super DataSource> transferListener;
|
||||
|
||||
/**
|
||||
* @param uri The {@link Uri} of the media stream.
|
||||
* @param dataSourceFactory A factory for {@link DataSource}s to read the media.
|
||||
@ -349,6 +348,7 @@ public final class ExtractorMediaSource extends BaseMediaSource
|
||||
ExoPlayer player,
|
||||
boolean isTopLevelSource,
|
||||
@Nullable TransferListener<? super DataSource> mediaTransferListener) {
|
||||
transferListener = mediaTransferListener;
|
||||
notifySourceInfoRefreshed(timelineDurationUs, /* isSeekable= */ false);
|
||||
}
|
||||
|
||||
@ -360,9 +360,13 @@ public final class ExtractorMediaSource extends BaseMediaSource
|
||||
@Override
|
||||
public MediaPeriod createPeriod(MediaPeriodId id, Allocator allocator) {
|
||||
Assertions.checkArgument(id.periodIndex == 0);
|
||||
DataSource dataSource = dataSourceFactory.createDataSource();
|
||||
if (transferListener != null) {
|
||||
dataSource.addTransferListener(transferListener);
|
||||
}
|
||||
return new ExtractorMediaPeriod(
|
||||
uri,
|
||||
dataSourceFactory.createDataSource(),
|
||||
dataSource,
|
||||
extractorsFactory.createExtractors(),
|
||||
minLoadableRetryCount,
|
||||
createEventDispatcher(id),
|
||||
|
@ -15,6 +15,7 @@
|
||||
*/
|
||||
package com.google.android.exoplayer2.source;
|
||||
|
||||
import android.support.annotation.Nullable;
|
||||
import com.google.android.exoplayer2.C;
|
||||
import com.google.android.exoplayer2.Format;
|
||||
import com.google.android.exoplayer2.FormatHolder;
|
||||
@ -28,6 +29,7 @@ import com.google.android.exoplayer2.upstream.Loader;
|
||||
import com.google.android.exoplayer2.upstream.Loader.LoadErrorAction;
|
||||
import com.google.android.exoplayer2.upstream.Loader.Loadable;
|
||||
import com.google.android.exoplayer2.upstream.StatsDataSource;
|
||||
import com.google.android.exoplayer2.upstream.TransferListener;
|
||||
import com.google.android.exoplayer2.util.MimeTypes;
|
||||
import com.google.android.exoplayer2.util.Util;
|
||||
import java.io.IOException;
|
||||
@ -47,6 +49,7 @@ import java.util.Arrays;
|
||||
|
||||
private final DataSpec dataSpec;
|
||||
private final DataSource.Factory dataSourceFactory;
|
||||
private final @Nullable TransferListener<? super DataSource> transferListener;
|
||||
private final int minLoadableRetryCount;
|
||||
private final EventDispatcher eventDispatcher;
|
||||
private final TrackGroupArray tracks;
|
||||
@ -67,6 +70,7 @@ import java.util.Arrays;
|
||||
public SingleSampleMediaPeriod(
|
||||
DataSpec dataSpec,
|
||||
DataSource.Factory dataSourceFactory,
|
||||
@Nullable TransferListener<? super DataSource> transferListener,
|
||||
Format format,
|
||||
long durationUs,
|
||||
int minLoadableRetryCount,
|
||||
@ -74,6 +78,7 @@ import java.util.Arrays;
|
||||
boolean treatLoadErrorsAsEndOfStream) {
|
||||
this.dataSpec = dataSpec;
|
||||
this.dataSourceFactory = dataSourceFactory;
|
||||
this.transferListener = transferListener;
|
||||
this.format = format;
|
||||
this.durationUs = durationUs;
|
||||
this.minLoadableRetryCount = minLoadableRetryCount;
|
||||
@ -138,11 +143,13 @@ import java.util.Arrays;
|
||||
if (loadingFinished || loader.isLoading()) {
|
||||
return false;
|
||||
}
|
||||
DataSource dataSource = dataSourceFactory.createDataSource();
|
||||
if (transferListener != null) {
|
||||
dataSource.addTransferListener(transferListener);
|
||||
}
|
||||
long elapsedRealtimeMs =
|
||||
loader.startLoading(
|
||||
new SourceLoadable(dataSpec, dataSourceFactory.createDataSource()),
|
||||
this,
|
||||
minLoadableRetryCount);
|
||||
new SourceLoadable(dataSpec, dataSource), /* callback= */ this, minLoadableRetryCount);
|
||||
eventDispatcher.loadStarted(
|
||||
dataSpec,
|
||||
dataSpec.uri,
|
||||
|
@ -169,6 +169,8 @@ public final class SingleSampleMediaSource extends BaseMediaSource {
|
||||
private final boolean treatLoadErrorsAsEndOfStream;
|
||||
private final Timeline timeline;
|
||||
|
||||
private @Nullable TransferListener<? super DataSource> transferListener;
|
||||
|
||||
/**
|
||||
* @param uri The {@link Uri} of the media stream.
|
||||
* @param dataSourceFactory The factory from which the {@link DataSource} to read the media will
|
||||
@ -273,6 +275,7 @@ public final class SingleSampleMediaSource extends BaseMediaSource {
|
||||
ExoPlayer player,
|
||||
boolean isTopLevelSource,
|
||||
@Nullable TransferListener<? super DataSource> mediaTransferListener) {
|
||||
transferListener = mediaTransferListener;
|
||||
refreshSourceInfo(timeline, /* manifest= */ null);
|
||||
}
|
||||
|
||||
@ -287,6 +290,7 @@ public final class SingleSampleMediaSource extends BaseMediaSource {
|
||||
return new SingleSampleMediaPeriod(
|
||||
dataSpec,
|
||||
dataSourceFactory,
|
||||
transferListener,
|
||||
format,
|
||||
durationUs,
|
||||
minLoadableRetryCount,
|
||||
|
@ -581,7 +581,8 @@ public final class ExoPlayerTest {
|
||||
MediaPeriodId id,
|
||||
TrackGroupArray trackGroupArray,
|
||||
Allocator allocator,
|
||||
EventDispatcher eventDispatcher) {
|
||||
EventDispatcher eventDispatcher,
|
||||
@Nullable TransferListener<? super DataSource> transferListener) {
|
||||
FakeMediaPeriod mediaPeriod = new FakeMediaPeriod(trackGroupArray, eventDispatcher);
|
||||
mediaPeriod.setSeekToUsOffset(10);
|
||||
return mediaPeriod;
|
||||
@ -615,7 +616,8 @@ public final class ExoPlayerTest {
|
||||
MediaPeriodId id,
|
||||
TrackGroupArray trackGroupArray,
|
||||
Allocator allocator,
|
||||
EventDispatcher eventDispatcher) {
|
||||
EventDispatcher eventDispatcher,
|
||||
@Nullable TransferListener<? super DataSource> transferListener) {
|
||||
FakeMediaPeriod mediaPeriod = new FakeMediaPeriod(trackGroupArray, eventDispatcher);
|
||||
mediaPeriod.setDiscontinuityPositionUs(10);
|
||||
return mediaPeriod;
|
||||
@ -640,7 +642,8 @@ public final class ExoPlayerTest {
|
||||
MediaPeriodId id,
|
||||
TrackGroupArray trackGroupArray,
|
||||
Allocator allocator,
|
||||
EventDispatcher eventDispatcher) {
|
||||
EventDispatcher eventDispatcher,
|
||||
@Nullable TransferListener<? super DataSource> transferListener) {
|
||||
FakeMediaPeriod mediaPeriod = new FakeMediaPeriod(trackGroupArray, eventDispatcher);
|
||||
mediaPeriod.setDiscontinuityPositionUs(0);
|
||||
return mediaPeriod;
|
||||
@ -876,7 +879,8 @@ public final class ExoPlayerTest {
|
||||
MediaPeriodId id,
|
||||
TrackGroupArray trackGroupArray,
|
||||
Allocator allocator,
|
||||
EventDispatcher eventDispatcher) {
|
||||
EventDispatcher eventDispatcher,
|
||||
@Nullable TransferListener<? super DataSource> transferListener) {
|
||||
// Defer completing preparation of the period until playback parameters have been set.
|
||||
fakeMediaPeriodHolder[0] =
|
||||
new FakeMediaPeriod(trackGroupArray, eventDispatcher, /* deferOnPrepared= */ true);
|
||||
|
@ -37,6 +37,8 @@ import com.google.android.exoplayer2.testutil.MediaSourceTestRunner;
|
||||
import com.google.android.exoplayer2.testutil.RobolectricUtil;
|
||||
import com.google.android.exoplayer2.testutil.TimelineAsserts;
|
||||
import com.google.android.exoplayer2.upstream.Allocator;
|
||||
import com.google.android.exoplayer2.upstream.DataSource;
|
||||
import com.google.android.exoplayer2.upstream.TransferListener;
|
||||
import java.io.IOException;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
@ -478,7 +480,8 @@ public final class ClippingMediaSourceTest {
|
||||
MediaPeriodId id,
|
||||
TrackGroupArray trackGroupArray,
|
||||
Allocator allocator,
|
||||
EventDispatcher eventDispatcher) {
|
||||
EventDispatcher eventDispatcher,
|
||||
@Nullable TransferListener<? super DataSource> transferListener) {
|
||||
eventDispatcher.downstreamFormatChanged(
|
||||
new MediaLoadData(
|
||||
C.DATA_TYPE_MEDIA,
|
||||
@ -488,7 +491,8 @@ public final class ClippingMediaSourceTest {
|
||||
/* trackSelectionData= */ null,
|
||||
C.usToMs(eventStartUs),
|
||||
C.usToMs(eventEndUs)));
|
||||
return super.createFakeMediaPeriod(id, trackGroupArray, allocator, eventDispatcher);
|
||||
return super.createFakeMediaPeriod(
|
||||
id, trackGroupArray, allocator, eventDispatcher, transferListener);
|
||||
}
|
||||
};
|
||||
final ClippingMediaSource clippingMediaSource =
|
||||
|
@ -21,7 +21,9 @@ import com.google.android.exoplayer2.source.chunk.ChunkSource;
|
||||
import com.google.android.exoplayer2.source.dash.PlayerEmsgHandler.PlayerTrackEmsgHandler;
|
||||
import com.google.android.exoplayer2.source.dash.manifest.DashManifest;
|
||||
import com.google.android.exoplayer2.trackselection.TrackSelection;
|
||||
import com.google.android.exoplayer2.upstream.DataSource;
|
||||
import com.google.android.exoplayer2.upstream.LoaderErrorThrower;
|
||||
import com.google.android.exoplayer2.upstream.TransferListener;
|
||||
|
||||
/**
|
||||
* An {@link ChunkSource} for DASH streams.
|
||||
@ -44,6 +46,8 @@ public interface DashChunkSource extends ChunkSource {
|
||||
* message track.
|
||||
* @param enableCea608Track Whether the chunks generated by the source may output a CEA-608
|
||||
* track.
|
||||
* @param transferListener The transfer listener which should be informed of any data transfers.
|
||||
* May be null if no listener is available.
|
||||
* @return The created {@link DashChunkSource}.
|
||||
*/
|
||||
DashChunkSource createDashChunkSource(
|
||||
@ -56,7 +60,8 @@ public interface DashChunkSource extends ChunkSource {
|
||||
long elapsedRealtimeOffsetMs,
|
||||
boolean enableEventMessageTrack,
|
||||
boolean enableCea608Track,
|
||||
@Nullable PlayerTrackEmsgHandler playerEmsgHandler);
|
||||
@Nullable PlayerTrackEmsgHandler playerEmsgHandler,
|
||||
@Nullable TransferListener<? super DataSource> transferListener);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -43,7 +43,9 @@ import com.google.android.exoplayer2.source.dash.manifest.Period;
|
||||
import com.google.android.exoplayer2.source.dash.manifest.Representation;
|
||||
import com.google.android.exoplayer2.trackselection.TrackSelection;
|
||||
import com.google.android.exoplayer2.upstream.Allocator;
|
||||
import com.google.android.exoplayer2.upstream.DataSource;
|
||||
import com.google.android.exoplayer2.upstream.LoaderErrorThrower;
|
||||
import com.google.android.exoplayer2.upstream.TransferListener;
|
||||
import com.google.android.exoplayer2.util.MimeTypes;
|
||||
import java.io.IOException;
|
||||
import java.lang.annotation.Retention;
|
||||
@ -61,6 +63,7 @@ import java.util.List;
|
||||
|
||||
/* package */ final int id;
|
||||
private final DashChunkSource.Factory chunkSourceFactory;
|
||||
private final @Nullable TransferListener<? super DataSource> transferListener;
|
||||
private final int minLoadableRetryCount;
|
||||
private final EventDispatcher eventDispatcher;
|
||||
private final long elapsedRealtimeOffset;
|
||||
@ -87,6 +90,7 @@ import java.util.List;
|
||||
DashManifest manifest,
|
||||
int periodIndex,
|
||||
DashChunkSource.Factory chunkSourceFactory,
|
||||
@Nullable TransferListener<? super DataSource> transferListener,
|
||||
int minLoadableRetryCount,
|
||||
EventDispatcher eventDispatcher,
|
||||
long elapsedRealtimeOffset,
|
||||
@ -98,6 +102,7 @@ import java.util.List;
|
||||
this.manifest = manifest;
|
||||
this.periodIndex = periodIndex;
|
||||
this.chunkSourceFactory = chunkSourceFactory;
|
||||
this.transferListener = transferListener;
|
||||
this.minLoadableRetryCount = minLoadableRetryCount;
|
||||
this.eventDispatcher = eventDispatcher;
|
||||
this.elapsedRealtimeOffset = elapsedRealtimeOffset;
|
||||
@ -562,7 +567,8 @@ import java.util.List;
|
||||
elapsedRealtimeOffset,
|
||||
enableEventMessageTrack,
|
||||
enableCea608Track,
|
||||
trackPlayerEmsgHandler);
|
||||
trackPlayerEmsgHandler,
|
||||
transferListener);
|
||||
ChunkSampleStream<DashChunkSource> stream =
|
||||
new ChunkSampleStream<>(
|
||||
trackGroupInfo.trackType,
|
||||
|
@ -315,6 +315,7 @@ public final class DashMediaSource extends BaseMediaSource {
|
||||
|
||||
private DataSource dataSource;
|
||||
private Loader loader;
|
||||
private @Nullable TransferListener<? super DataSource> mediaTransferListener;
|
||||
|
||||
private IOException manifestFatalError;
|
||||
private Handler handler;
|
||||
@ -550,6 +551,7 @@ public final class DashMediaSource extends BaseMediaSource {
|
||||
ExoPlayer player,
|
||||
boolean isTopLevelSource,
|
||||
@Nullable TransferListener<? super DataSource> mediaTransferListener) {
|
||||
this.mediaTransferListener = mediaTransferListener;
|
||||
if (sideloadedManifest) {
|
||||
processManifest(false);
|
||||
} else {
|
||||
@ -576,6 +578,7 @@ public final class DashMediaSource extends BaseMediaSource {
|
||||
manifest,
|
||||
periodIndex,
|
||||
chunkSourceFactory,
|
||||
mediaTransferListener,
|
||||
minLoadableRetryCount,
|
||||
periodEventDispatcher,
|
||||
elapsedRealtimeOffsetMs,
|
||||
|
@ -50,6 +50,7 @@ import com.google.android.exoplayer2.upstream.DataSource;
|
||||
import com.google.android.exoplayer2.upstream.DataSpec;
|
||||
import com.google.android.exoplayer2.upstream.HttpDataSource.InvalidResponseCodeException;
|
||||
import com.google.android.exoplayer2.upstream.LoaderErrorThrower;
|
||||
import com.google.android.exoplayer2.upstream.TransferListener;
|
||||
import com.google.android.exoplayer2.util.MimeTypes;
|
||||
import com.google.android.exoplayer2.util.Util;
|
||||
import java.io.IOException;
|
||||
@ -87,8 +88,12 @@ public class DefaultDashChunkSource implements DashChunkSource {
|
||||
long elapsedRealtimeOffsetMs,
|
||||
boolean enableEventMessageTrack,
|
||||
boolean enableCea608Track,
|
||||
@Nullable PlayerTrackEmsgHandler playerEmsgHandler) {
|
||||
@Nullable PlayerTrackEmsgHandler playerEmsgHandler,
|
||||
@Nullable TransferListener<? super DataSource> transferListener) {
|
||||
DataSource dataSource = dataSourceFactory.createDataSource();
|
||||
if (transferListener != null) {
|
||||
dataSource.addTransferListener(transferListener);
|
||||
}
|
||||
return new DefaultDashChunkSource(
|
||||
manifestLoaderErrorThrower,
|
||||
manifest,
|
||||
|
@ -17,6 +17,7 @@ package com.google.android.exoplayer2.source.hls;
|
||||
|
||||
import android.net.Uri;
|
||||
import android.os.SystemClock;
|
||||
import android.support.annotation.Nullable;
|
||||
import com.google.android.exoplayer2.C;
|
||||
import com.google.android.exoplayer2.Format;
|
||||
import com.google.android.exoplayer2.source.BehindLiveWindowException;
|
||||
@ -32,6 +33,7 @@ import com.google.android.exoplayer2.trackselection.BaseTrackSelection;
|
||||
import com.google.android.exoplayer2.trackselection.TrackSelection;
|
||||
import com.google.android.exoplayer2.upstream.DataSource;
|
||||
import com.google.android.exoplayer2.upstream.DataSpec;
|
||||
import com.google.android.exoplayer2.upstream.TransferListener;
|
||||
import com.google.android.exoplayer2.util.TimestampAdjuster;
|
||||
import com.google.android.exoplayer2.util.UriUtil;
|
||||
import com.google.android.exoplayer2.util.Util;
|
||||
@ -114,15 +116,22 @@ import java.util.List;
|
||||
* @param variants The available variants.
|
||||
* @param dataSourceFactory An {@link HlsDataSourceFactory} to create {@link DataSource}s for the
|
||||
* chunks.
|
||||
* @param timestampAdjusterProvider A provider of {@link TimestampAdjuster} instances. If
|
||||
* multiple {@link HlsChunkSource}s are used for a single playback, they should all share the
|
||||
* same provider.
|
||||
* @param mediaTransferListener The transfer listener which should be informed of any media data
|
||||
* transfers. May be null if no listener is available.
|
||||
* @param timestampAdjusterProvider A provider of {@link TimestampAdjuster} instances. If multiple
|
||||
* {@link HlsChunkSource}s are used for a single playback, they should all share the same
|
||||
* provider.
|
||||
* @param muxedCaptionFormats List of muxed caption {@link Format}s. Null if no closed caption
|
||||
* information is available in the master playlist.
|
||||
*/
|
||||
public HlsChunkSource(HlsExtractorFactory extractorFactory, HlsPlaylistTracker playlistTracker,
|
||||
HlsUrl[] variants, HlsDataSourceFactory dataSourceFactory,
|
||||
TimestampAdjusterProvider timestampAdjusterProvider, List<Format> muxedCaptionFormats) {
|
||||
public HlsChunkSource(
|
||||
HlsExtractorFactory extractorFactory,
|
||||
HlsPlaylistTracker playlistTracker,
|
||||
HlsUrl[] variants,
|
||||
HlsDataSourceFactory dataSourceFactory,
|
||||
@Nullable TransferListener<? super DataSource> mediaTransferListener,
|
||||
TimestampAdjusterProvider timestampAdjusterProvider,
|
||||
List<Format> muxedCaptionFormats) {
|
||||
this.extractorFactory = extractorFactory;
|
||||
this.playlistTracker = playlistTracker;
|
||||
this.variants = variants;
|
||||
@ -136,6 +145,9 @@ import java.util.List;
|
||||
initialTrackSelection[i] = i;
|
||||
}
|
||||
mediaDataSource = dataSourceFactory.createDataSource(C.DATA_TYPE_MEDIA);
|
||||
if (mediaTransferListener != null) {
|
||||
mediaDataSource.addTransferListener(mediaTransferListener);
|
||||
}
|
||||
encryptionDataSource = dataSourceFactory.createDataSource(C.DATA_TYPE_DRM);
|
||||
trackGroup = new TrackGroup(variantFormats);
|
||||
trackSelection = new InitializationTrackSelection(trackGroup, initialTrackSelection);
|
||||
|
@ -31,6 +31,8 @@ import com.google.android.exoplayer2.source.hls.playlist.HlsMasterPlaylist.HlsUr
|
||||
import com.google.android.exoplayer2.source.hls.playlist.HlsPlaylistTracker;
|
||||
import com.google.android.exoplayer2.trackselection.TrackSelection;
|
||||
import com.google.android.exoplayer2.upstream.Allocator;
|
||||
import com.google.android.exoplayer2.upstream.DataSource;
|
||||
import com.google.android.exoplayer2.upstream.TransferListener;
|
||||
import com.google.android.exoplayer2.util.Assertions;
|
||||
import com.google.android.exoplayer2.util.MimeTypes;
|
||||
import com.google.android.exoplayer2.util.Util;
|
||||
@ -50,6 +52,7 @@ public final class HlsMediaPeriod implements MediaPeriod, HlsSampleStreamWrapper
|
||||
private final HlsExtractorFactory extractorFactory;
|
||||
private final HlsPlaylistTracker playlistTracker;
|
||||
private final HlsDataSourceFactory dataSourceFactory;
|
||||
private final @Nullable TransferListener<? super DataSource> mediaTransferListener;
|
||||
private final int minLoadableRetryCount;
|
||||
private final EventDispatcher eventDispatcher;
|
||||
private final Allocator allocator;
|
||||
@ -70,6 +73,7 @@ public final class HlsMediaPeriod implements MediaPeriod, HlsSampleStreamWrapper
|
||||
HlsExtractorFactory extractorFactory,
|
||||
HlsPlaylistTracker playlistTracker,
|
||||
HlsDataSourceFactory dataSourceFactory,
|
||||
@Nullable TransferListener<? super DataSource> mediaTransferListener,
|
||||
int minLoadableRetryCount,
|
||||
EventDispatcher eventDispatcher,
|
||||
Allocator allocator,
|
||||
@ -78,6 +82,7 @@ public final class HlsMediaPeriod implements MediaPeriod, HlsSampleStreamWrapper
|
||||
this.extractorFactory = extractorFactory;
|
||||
this.playlistTracker = playlistTracker;
|
||||
this.dataSourceFactory = dataSourceFactory;
|
||||
this.mediaTransferListener = mediaTransferListener;
|
||||
this.minLoadableRetryCount = minLoadableRetryCount;
|
||||
this.eventDispatcher = eventDispatcher;
|
||||
this.allocator = allocator;
|
||||
@ -488,8 +493,15 @@ public final class HlsMediaPeriod implements MediaPeriod, HlsSampleStreamWrapper
|
||||
|
||||
private HlsSampleStreamWrapper buildSampleStreamWrapper(int trackType, HlsUrl[] variants,
|
||||
Format muxedAudioFormat, List<Format> muxedCaptionFormats, long positionUs) {
|
||||
HlsChunkSource defaultChunkSource = new HlsChunkSource(extractorFactory, playlistTracker,
|
||||
variants, dataSourceFactory, timestampAdjusterProvider, muxedCaptionFormats);
|
||||
HlsChunkSource defaultChunkSource =
|
||||
new HlsChunkSource(
|
||||
extractorFactory,
|
||||
playlistTracker,
|
||||
variants,
|
||||
dataSourceFactory,
|
||||
mediaTransferListener,
|
||||
timestampAdjusterProvider,
|
||||
muxedCaptionFormats);
|
||||
return new HlsSampleStreamWrapper(trackType, this, defaultChunkSource, allocator, positionUs,
|
||||
muxedAudioFormat, minLoadableRetryCount, eventDispatcher);
|
||||
}
|
||||
|
@ -265,6 +265,8 @@ public final class HlsMediaSource extends BaseMediaSource
|
||||
private final HlsPlaylistTracker playlistTracker;
|
||||
private final @Nullable Object tag;
|
||||
|
||||
private @Nullable TransferListener<? super DataSource> mediaTransferListener;
|
||||
|
||||
/**
|
||||
* @param manifestUri The {@link Uri} of the HLS manifest.
|
||||
* @param dataSourceFactory An {@link HlsDataSourceFactory} for {@link DataSource}s for manifests,
|
||||
@ -372,6 +374,7 @@ public final class HlsMediaSource extends BaseMediaSource
|
||||
ExoPlayer player,
|
||||
boolean isTopLevelSource,
|
||||
@Nullable TransferListener<? super DataSource> mediaTransferListener) {
|
||||
this.mediaTransferListener = mediaTransferListener;
|
||||
EventDispatcher eventDispatcher = createEventDispatcher(/* mediaPeriodId= */ null);
|
||||
playlistTracker.start(manifestUri, eventDispatcher, /* listener= */ this);
|
||||
}
|
||||
@ -389,6 +392,7 @@ public final class HlsMediaSource extends BaseMediaSource
|
||||
extractorFactory,
|
||||
playlistTracker,
|
||||
dataSourceFactory,
|
||||
mediaTransferListener,
|
||||
minLoadableRetryCount,
|
||||
eventDispatcher,
|
||||
allocator,
|
||||
|
@ -16,6 +16,7 @@
|
||||
package com.google.android.exoplayer2.source.smoothstreaming;
|
||||
|
||||
import android.net.Uri;
|
||||
import android.support.annotation.Nullable;
|
||||
import com.google.android.exoplayer2.C;
|
||||
import com.google.android.exoplayer2.Format;
|
||||
import com.google.android.exoplayer2.SeekParameters;
|
||||
@ -35,6 +36,7 @@ import com.google.android.exoplayer2.trackselection.TrackSelection;
|
||||
import com.google.android.exoplayer2.upstream.DataSource;
|
||||
import com.google.android.exoplayer2.upstream.DataSpec;
|
||||
import com.google.android.exoplayer2.upstream.LoaderErrorThrower;
|
||||
import com.google.android.exoplayer2.upstream.TransferListener;
|
||||
import com.google.android.exoplayer2.util.Util;
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
@ -53,10 +55,17 @@ public class DefaultSsChunkSource implements SsChunkSource {
|
||||
}
|
||||
|
||||
@Override
|
||||
public SsChunkSource createChunkSource(LoaderErrorThrower manifestLoaderErrorThrower,
|
||||
SsManifest manifest, int elementIndex, TrackSelection trackSelection,
|
||||
TrackEncryptionBox[] trackEncryptionBoxes) {
|
||||
public SsChunkSource createChunkSource(
|
||||
LoaderErrorThrower manifestLoaderErrorThrower,
|
||||
SsManifest manifest,
|
||||
int elementIndex,
|
||||
TrackSelection trackSelection,
|
||||
TrackEncryptionBox[] trackEncryptionBoxes,
|
||||
@Nullable TransferListener<? super DataSource> transferListener) {
|
||||
DataSource dataSource = dataSourceFactory.createDataSource();
|
||||
if (transferListener != null) {
|
||||
dataSource.addTransferListener(transferListener);
|
||||
}
|
||||
return new DefaultSsChunkSource(manifestLoaderErrorThrower, manifest, elementIndex,
|
||||
trackSelection, dataSource, trackEncryptionBoxes);
|
||||
}
|
||||
|
@ -15,11 +15,14 @@
|
||||
*/
|
||||
package com.google.android.exoplayer2.source.smoothstreaming;
|
||||
|
||||
import android.support.annotation.Nullable;
|
||||
import com.google.android.exoplayer2.extractor.mp4.TrackEncryptionBox;
|
||||
import com.google.android.exoplayer2.source.chunk.ChunkSource;
|
||||
import com.google.android.exoplayer2.source.smoothstreaming.manifest.SsManifest;
|
||||
import com.google.android.exoplayer2.trackselection.TrackSelection;
|
||||
import com.google.android.exoplayer2.upstream.DataSource;
|
||||
import com.google.android.exoplayer2.upstream.LoaderErrorThrower;
|
||||
import com.google.android.exoplayer2.upstream.TransferListener;
|
||||
|
||||
/**
|
||||
* A {@link ChunkSource} for SmoothStreaming.
|
||||
@ -37,6 +40,8 @@ public interface SsChunkSource extends ChunkSource {
|
||||
* @param streamElementIndex The index of the corresponding stream element in the manifest.
|
||||
* @param trackSelection The track selection.
|
||||
* @param trackEncryptionBoxes Track encryption boxes for the stream.
|
||||
* @param transferListener The transfer listener which should be informed of any data transfers.
|
||||
* May be null if no listener is available.
|
||||
* @return The created {@link SsChunkSource}.
|
||||
*/
|
||||
SsChunkSource createChunkSource(
|
||||
@ -44,7 +49,8 @@ public interface SsChunkSource extends ChunkSource {
|
||||
SsManifest manifest,
|
||||
int streamElementIndex,
|
||||
TrackSelection trackSelection,
|
||||
TrackEncryptionBox[] trackEncryptionBoxes);
|
||||
TrackEncryptionBox[] trackEncryptionBoxes,
|
||||
@Nullable TransferListener<? super DataSource> transferListener);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -32,7 +32,9 @@ import com.google.android.exoplayer2.source.smoothstreaming.manifest.SsManifest;
|
||||
import com.google.android.exoplayer2.source.smoothstreaming.manifest.SsManifest.ProtectionElement;
|
||||
import com.google.android.exoplayer2.trackselection.TrackSelection;
|
||||
import com.google.android.exoplayer2.upstream.Allocator;
|
||||
import com.google.android.exoplayer2.upstream.DataSource;
|
||||
import com.google.android.exoplayer2.upstream.LoaderErrorThrower;
|
||||
import com.google.android.exoplayer2.upstream.TransferListener;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
|
||||
@ -45,6 +47,7 @@ import java.util.ArrayList;
|
||||
private static final int INITIALIZATION_VECTOR_SIZE = 8;
|
||||
|
||||
private final SsChunkSource.Factory chunkSourceFactory;
|
||||
private final @Nullable TransferListener<? super DataSource> transferListener;
|
||||
private final LoaderErrorThrower manifestLoaderErrorThrower;
|
||||
private final int minLoadableRetryCount;
|
||||
private final EventDispatcher eventDispatcher;
|
||||
@ -59,11 +62,17 @@ import java.util.ArrayList;
|
||||
private SequenceableLoader compositeSequenceableLoader;
|
||||
private boolean notifiedReadingStarted;
|
||||
|
||||
public SsMediaPeriod(SsManifest manifest, SsChunkSource.Factory chunkSourceFactory,
|
||||
public SsMediaPeriod(
|
||||
SsManifest manifest,
|
||||
SsChunkSource.Factory chunkSourceFactory,
|
||||
@Nullable TransferListener<? super DataSource> transferListener,
|
||||
CompositeSequenceableLoaderFactory compositeSequenceableLoaderFactory,
|
||||
int minLoadableRetryCount, EventDispatcher eventDispatcher,
|
||||
LoaderErrorThrower manifestLoaderErrorThrower, Allocator allocator) {
|
||||
int minLoadableRetryCount,
|
||||
EventDispatcher eventDispatcher,
|
||||
LoaderErrorThrower manifestLoaderErrorThrower,
|
||||
Allocator allocator) {
|
||||
this.chunkSourceFactory = chunkSourceFactory;
|
||||
this.transferListener = transferListener;
|
||||
this.manifestLoaderErrorThrower = manifestLoaderErrorThrower;
|
||||
this.minLoadableRetryCount = minLoadableRetryCount;
|
||||
this.eventDispatcher = eventDispatcher;
|
||||
@ -214,8 +223,14 @@ import java.util.ArrayList;
|
||||
private ChunkSampleStream<SsChunkSource> buildSampleStream(TrackSelection selection,
|
||||
long positionUs) {
|
||||
int streamElementIndex = trackGroups.indexOf(selection.getTrackGroup());
|
||||
SsChunkSource chunkSource = chunkSourceFactory.createChunkSource(manifestLoaderErrorThrower,
|
||||
manifest, streamElementIndex, selection, trackEncryptionBoxes);
|
||||
SsChunkSource chunkSource =
|
||||
chunkSourceFactory.createChunkSource(
|
||||
manifestLoaderErrorThrower,
|
||||
manifest,
|
||||
streamElementIndex,
|
||||
selection,
|
||||
trackEncryptionBoxes,
|
||||
transferListener);
|
||||
return new ChunkSampleStream<>(
|
||||
manifest.streamElements[streamElementIndex].type,
|
||||
null,
|
||||
|
@ -285,6 +285,7 @@ public final class SsMediaSource extends BaseMediaSource
|
||||
private DataSource manifestDataSource;
|
||||
private Loader manifestLoader;
|
||||
private LoaderErrorThrower manifestLoaderErrorThrower;
|
||||
private @Nullable TransferListener<? super DataSource> mediaTransferListener;
|
||||
|
||||
private long manifestLoadStartTimestamp;
|
||||
private SsManifest manifest;
|
||||
@ -467,6 +468,7 @@ public final class SsMediaSource extends BaseMediaSource
|
||||
ExoPlayer player,
|
||||
boolean isTopLevelSource,
|
||||
@Nullable TransferListener<? super DataSource> mediaTransferListener) {
|
||||
this.mediaTransferListener = mediaTransferListener;
|
||||
if (sideloadedManifest) {
|
||||
manifestLoaderErrorThrower = new LoaderErrorThrower.Dummy();
|
||||
processManifest();
|
||||
@ -488,9 +490,16 @@ public final class SsMediaSource extends BaseMediaSource
|
||||
public MediaPeriod createPeriod(MediaPeriodId id, Allocator allocator) {
|
||||
Assertions.checkArgument(id.periodIndex == 0);
|
||||
EventDispatcher eventDispatcher = createEventDispatcher(id);
|
||||
SsMediaPeriod period = new SsMediaPeriod(manifest, chunkSourceFactory,
|
||||
compositeSequenceableLoaderFactory, minLoadableRetryCount, eventDispatcher,
|
||||
manifestLoaderErrorThrower, allocator);
|
||||
SsMediaPeriod period =
|
||||
new SsMediaPeriod(
|
||||
manifest,
|
||||
chunkSourceFactory,
|
||||
mediaTransferListener,
|
||||
compositeSequenceableLoaderFactory,
|
||||
minLoadableRetryCount,
|
||||
eventDispatcher,
|
||||
manifestLoaderErrorThrower,
|
||||
allocator);
|
||||
mediaPeriods.add(period);
|
||||
return period;
|
||||
}
|
||||
|
@ -15,6 +15,7 @@
|
||||
*/
|
||||
package com.google.android.exoplayer2.testutil;
|
||||
|
||||
import android.support.annotation.Nullable;
|
||||
import com.google.android.exoplayer2.source.CompositeSequenceableLoader;
|
||||
import com.google.android.exoplayer2.source.MediaPeriod;
|
||||
import com.google.android.exoplayer2.source.MediaSourceEventListener.EventDispatcher;
|
||||
@ -24,6 +25,8 @@ import com.google.android.exoplayer2.source.TrackGroupArray;
|
||||
import com.google.android.exoplayer2.source.chunk.ChunkSampleStream;
|
||||
import com.google.android.exoplayer2.trackselection.TrackSelection;
|
||||
import com.google.android.exoplayer2.upstream.Allocator;
|
||||
import com.google.android.exoplayer2.upstream.DataSource;
|
||||
import com.google.android.exoplayer2.upstream.TransferListener;
|
||||
import com.google.android.exoplayer2.util.MimeTypes;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
@ -37,6 +40,7 @@ public class FakeAdaptiveMediaPeriod extends FakeMediaPeriod
|
||||
|
||||
private final Allocator allocator;
|
||||
private final FakeChunkSource.Factory chunkSourceFactory;
|
||||
private final @Nullable TransferListener<? super DataSource> transferListener;
|
||||
private final long durationUs;
|
||||
|
||||
private Callback callback;
|
||||
@ -48,10 +52,12 @@ public class FakeAdaptiveMediaPeriod extends FakeMediaPeriod
|
||||
EventDispatcher eventDispatcher,
|
||||
Allocator allocator,
|
||||
FakeChunkSource.Factory chunkSourceFactory,
|
||||
long durationUs) {
|
||||
long durationUs,
|
||||
@Nullable TransferListener<? super DataSource> transferListener) {
|
||||
super(trackGroupArray, eventDispatcher);
|
||||
this.allocator = allocator;
|
||||
this.chunkSourceFactory = chunkSourceFactory;
|
||||
this.transferListener = transferListener;
|
||||
this.durationUs = durationUs;
|
||||
this.sampleStreams = newSampleStreamArray(0);
|
||||
}
|
||||
@ -128,7 +134,8 @@ public class FakeAdaptiveMediaPeriod extends FakeMediaPeriod
|
||||
|
||||
@Override
|
||||
protected SampleStream createSampleStream(TrackSelection trackSelection) {
|
||||
FakeChunkSource chunkSource = chunkSourceFactory.createChunkSource(trackSelection, durationUs);
|
||||
FakeChunkSource chunkSource =
|
||||
chunkSourceFactory.createChunkSource(trackSelection, durationUs, transferListener);
|
||||
return new ChunkSampleStream<>(
|
||||
MimeTypes.getTrackType(trackSelection.getSelectedFormat().sampleMimeType),
|
||||
null,
|
||||
|
@ -16,6 +16,7 @@
|
||||
package com.google.android.exoplayer2.testutil;
|
||||
|
||||
import android.os.Handler;
|
||||
import android.support.annotation.Nullable;
|
||||
import com.google.android.exoplayer2.Timeline;
|
||||
import com.google.android.exoplayer2.Timeline.Period;
|
||||
import com.google.android.exoplayer2.source.MediaSource;
|
||||
@ -23,6 +24,8 @@ import com.google.android.exoplayer2.source.MediaSourceEventListener;
|
||||
import com.google.android.exoplayer2.source.MediaSourceEventListener.EventDispatcher;
|
||||
import com.google.android.exoplayer2.source.TrackGroupArray;
|
||||
import com.google.android.exoplayer2.upstream.Allocator;
|
||||
import com.google.android.exoplayer2.upstream.DataSource;
|
||||
import com.google.android.exoplayer2.upstream.TransferListener;
|
||||
|
||||
/**
|
||||
* Fake {@link MediaSource} that provides a given timeline. Creating the period returns a
|
||||
@ -49,10 +52,16 @@ public class FakeAdaptiveMediaSource extends FakeMediaSource {
|
||||
MediaPeriodId id,
|
||||
TrackGroupArray trackGroupArray,
|
||||
Allocator allocator,
|
||||
EventDispatcher eventDispatcher) {
|
||||
EventDispatcher eventDispatcher,
|
||||
@Nullable TransferListener<? super DataSource> transferListener) {
|
||||
Period period = timeline.getPeriod(id.periodIndex, new Period());
|
||||
return new FakeAdaptiveMediaPeriod(
|
||||
trackGroupArray, eventDispatcher, allocator, chunkSourceFactory, period.durationUs);
|
||||
trackGroupArray,
|
||||
eventDispatcher,
|
||||
allocator,
|
||||
chunkSourceFactory,
|
||||
period.durationUs,
|
||||
transferListener);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -16,6 +16,7 @@
|
||||
package com.google.android.exoplayer2.testutil;
|
||||
|
||||
import android.net.Uri;
|
||||
import android.support.annotation.Nullable;
|
||||
import com.google.android.exoplayer2.C;
|
||||
import com.google.android.exoplayer2.Format;
|
||||
import com.google.android.exoplayer2.SeekParameters;
|
||||
@ -28,6 +29,7 @@ import com.google.android.exoplayer2.testutil.FakeDataSet.FakeData.Segment;
|
||||
import com.google.android.exoplayer2.trackselection.TrackSelection;
|
||||
import com.google.android.exoplayer2.upstream.DataSource;
|
||||
import com.google.android.exoplayer2.upstream.DataSpec;
|
||||
import com.google.android.exoplayer2.upstream.TransferListener;
|
||||
import com.google.android.exoplayer2.util.MimeTypes;
|
||||
import com.google.android.exoplayer2.util.Util;
|
||||
import java.io.IOException;
|
||||
@ -52,11 +54,17 @@ public final class FakeChunkSource implements ChunkSource {
|
||||
this.dataSourceFactory = dataSourceFactory;
|
||||
}
|
||||
|
||||
public FakeChunkSource createChunkSource(TrackSelection trackSelection, long durationUs) {
|
||||
public FakeChunkSource createChunkSource(
|
||||
TrackSelection trackSelection,
|
||||
long durationUs,
|
||||
@Nullable TransferListener<? super DataSource> transferListener) {
|
||||
FakeAdaptiveDataSet dataSet =
|
||||
dataSetFactory.createDataSet(trackSelection.getTrackGroup(), durationUs);
|
||||
dataSourceFactory.setFakeDataSet(dataSet);
|
||||
DataSource dataSource = dataSourceFactory.createDataSource();
|
||||
if (transferListener != null) {
|
||||
dataSource.addTransferListener(transferListener);
|
||||
}
|
||||
return new FakeChunkSource(trackSelection, dataSource, dataSet);
|
||||
}
|
||||
|
||||
|
@ -61,6 +61,7 @@ public class FakeMediaSource extends BaseMediaSource {
|
||||
private boolean preparedSource;
|
||||
private boolean releasedSource;
|
||||
private Handler sourceInfoRefreshHandler;
|
||||
private @Nullable TransferListener<? super DataSource> transferListener;
|
||||
|
||||
/**
|
||||
* Creates a {@link FakeMediaSource}. This media source creates {@link FakeMediaPeriod}s with a
|
||||
@ -93,6 +94,7 @@ public class FakeMediaSource extends BaseMediaSource {
|
||||
boolean isTopLevelSource,
|
||||
@Nullable TransferListener<? super DataSource> mediaTransferListener) {
|
||||
assertThat(preparedSource).isFalse();
|
||||
transferListener = mediaTransferListener;
|
||||
preparedSource = true;
|
||||
releasedSource = false;
|
||||
sourceInfoRefreshHandler = new Handler();
|
||||
@ -115,7 +117,7 @@ public class FakeMediaSource extends BaseMediaSource {
|
||||
EventDispatcher eventDispatcher =
|
||||
createEventDispatcher(period.windowIndex, id, period.getPositionInWindowMs());
|
||||
FakeMediaPeriod mediaPeriod =
|
||||
createFakeMediaPeriod(id, trackGroupArray, allocator, eventDispatcher);
|
||||
createFakeMediaPeriod(id, trackGroupArray, allocator, eventDispatcher, transferListener);
|
||||
activeMediaPeriods.add(mediaPeriod);
|
||||
createdMediaPeriods.add(id);
|
||||
return mediaPeriod;
|
||||
@ -195,13 +197,16 @@ public class FakeMediaSource extends BaseMediaSource {
|
||||
* @param trackGroupArray The {@link TrackGroupArray} supported by the media period.
|
||||
* @param allocator An {@link Allocator} from which to obtain media buffer allocations.
|
||||
* @param eventDispatcher An {@link EventDispatcher} to dispatch media source events.
|
||||
* @param transferListener The transfer listener which should be informed of any data transfers.
|
||||
* May be null if no listener is available.
|
||||
* @return A new {@link FakeMediaPeriod}.
|
||||
*/
|
||||
protected FakeMediaPeriod createFakeMediaPeriod(
|
||||
MediaPeriodId id,
|
||||
TrackGroupArray trackGroupArray,
|
||||
Allocator allocator,
|
||||
EventDispatcher eventDispatcher) {
|
||||
EventDispatcher eventDispatcher,
|
||||
@Nullable TransferListener<? super DataSource> transferListener) {
|
||||
return new FakeMediaPeriod(trackGroupArray, eventDispatcher);
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user