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