diff --git a/RELEASENOTES.md b/RELEASENOTES.md index 5cd9535b08..1ac2a4da39 100644 --- a/RELEASENOTES.md +++ b/RELEASENOTES.md @@ -50,6 +50,9 @@ ([#4403](https://github.com/google/ExoPlayer/issues/4413)). * Add support for multiple audio and video tracks in MPEG-PS streams ([#4406](https://github.com/google/ExoPlayer/issues/4406)). +* Add uri field to `LoadEventInfo` in `MediaSourceEventListener` or + `AnalyticsListener` callbacks. This uri is the redirected uri if redirection + occurred ([#2054](https://github.com/google/ExoPlayer/issues/2054)). ### 2.8.2 ### diff --git a/library/core/src/main/java/com/google/android/exoplayer2/source/ExtractorMediaPeriod.java b/library/core/src/main/java/com/google/android/exoplayer2/source/ExtractorMediaPeriod.java index 37b3ee4c53..f88a95e694 100644 --- a/library/core/src/main/java/com/google/android/exoplayer2/source/ExtractorMediaPeriod.java +++ b/library/core/src/main/java/com/google/android/exoplayer2/source/ExtractorMediaPeriod.java @@ -40,6 +40,7 @@ import com.google.android.exoplayer2.upstream.DataSpec; 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.util.Assertions; import com.google.android.exoplayer2.util.ConditionVariable; import com.google.android.exoplayer2.util.MimeTypes; @@ -491,6 +492,7 @@ import java.util.Arrays; } eventDispatcher.loadCompleted( loadable.dataSpec, + loadable.dataSource.getLastOpenedUri(), C.DATA_TYPE_MEDIA, C.TRACK_TYPE_UNKNOWN, /* trackFormat= */ null, @@ -500,7 +502,7 @@ import java.util.Arrays; durationUs, elapsedRealtimeMs, loadDurationMs, - loadable.bytesLoaded); + loadable.dataSource.getBytesRead()); copyLengthFromLoader(loadable); loadingFinished = true; callback.onContinueLoadingRequested(this); @@ -511,6 +513,7 @@ import java.util.Arrays; long loadDurationMs, boolean released) { eventDispatcher.loadCanceled( loadable.dataSpec, + loadable.dataSource.getLastOpenedUri(), C.DATA_TYPE_MEDIA, C.TRACK_TYPE_UNKNOWN, /* trackFormat= */ null, @@ -520,7 +523,7 @@ import java.util.Arrays; durationUs, elapsedRealtimeMs, loadDurationMs, - loadable.bytesLoaded); + loadable.dataSource.getBytesRead()); if (!released) { copyLengthFromLoader(loadable); for (SampleQueue sampleQueue : sampleQueues) { @@ -539,9 +542,23 @@ import java.util.Arrays; long loadDurationMs, IOException error, int errorCount) { - boolean isErrorFatal = isLoadableExceptionFatal(error); + copyLengthFromLoader(loadable); + LoadErrorAction retryAction; + if (isLoadableExceptionFatal(error)) { + retryAction = Loader.DONT_RETRY_FATAL; + } else { + int extractedSamplesCount = getExtractedSamplesCount(); + boolean madeProgress = extractedSamplesCount > extractedSamplesCountAtStartOfLoad; + retryAction = + configureRetry(loadable, extractedSamplesCount) + ? (madeProgress ? Loader.RETRY_RESET_ERROR_COUNT : Loader.RETRY) + : Loader.DONT_RETRY; + } + boolean wasCanceled = + retryAction == Loader.DONT_RETRY || retryAction == Loader.DONT_RETRY_FATAL; eventDispatcher.loadError( loadable.dataSpec, + loadable.dataSource.getLastOpenedUri(), C.DATA_TYPE_MEDIA, C.TRACK_TYPE_UNKNOWN, /* trackFormat= */ null, @@ -551,18 +568,10 @@ import java.util.Arrays; durationUs, elapsedRealtimeMs, loadDurationMs, - loadable.bytesLoaded, + loadable.dataSource.getBytesRead(), error, - /* wasCanceled= */ isErrorFatal); - copyLengthFromLoader(loadable); - if (isErrorFatal) { - return Loader.DONT_RETRY_FATAL; - } - int extractedSamplesCount = getExtractedSamplesCount(); - boolean madeProgress = extractedSamplesCount > extractedSamplesCountAtStartOfLoad; - return configureRetry(loadable, extractedSamplesCount) - ? (madeProgress ? Loader.RETRY_RESET_ERROR_COUNT : Loader.RETRY) - : Loader.DONT_RETRY; + wasCanceled); + return retryAction; } // ExtractorOutput implementation. Called by the loading thread. @@ -663,6 +672,7 @@ import java.util.Arrays; long elapsedRealtimeMs = loader.startLoading(loadable, this, actualMinLoadableRetryCount); eventDispatcher.loadStarted( loadable.dataSpec, + loadable.dataSpec.uri, C.DATA_TYPE_MEDIA, C.TRACK_TYPE_UNKNOWN, /* trackFormat= */ null, @@ -803,7 +813,7 @@ import java.util.Arrays; /* package */ final class ExtractingLoadable implements Loadable { private final Uri uri; - private final DataSource dataSource; + private final StatsDataSource dataSource; private final ExtractorHolder extractorHolder; private final ConditionVariable loadCondition; private final PositionHolder positionHolder; @@ -814,17 +824,17 @@ import java.util.Arrays; private long seekTimeUs; private DataSpec dataSpec; private long length; - private long bytesLoaded; public ExtractingLoadable(Uri uri, DataSource dataSource, ExtractorHolder extractorHolder, ConditionVariable loadCondition) { this.uri = Assertions.checkNotNull(uri); - this.dataSource = Assertions.checkNotNull(dataSource); + this.dataSource = new StatsDataSource(dataSource); this.extractorHolder = Assertions.checkNotNull(extractorHolder); this.loadCondition = loadCondition; this.positionHolder = new PositionHolder(); this.pendingExtractorSeek = true; this.length = C.LENGTH_UNSET; + dataSpec = new DataSpec(uri, positionHolder.position, C.LENGTH_UNSET, customCacheKey); } public void setLoadPosition(long position, long timeUs) { @@ -870,7 +880,6 @@ import java.util.Arrays; result = Extractor.RESULT_CONTINUE; } else if (input != null) { positionHolder.position = input.getPosition(); - bytesLoaded = positionHolder.position - dataSpec.absoluteStreamPosition; } Util.closeQuietly(dataSource); } diff --git a/library/core/src/main/java/com/google/android/exoplayer2/source/MediaSourceEventListener.java b/library/core/src/main/java/com/google/android/exoplayer2/source/MediaSourceEventListener.java index 9d1ba10866..844534a43d 100644 --- a/library/core/src/main/java/com/google/android/exoplayer2/source/MediaSourceEventListener.java +++ b/library/core/src/main/java/com/google/android/exoplayer2/source/MediaSourceEventListener.java @@ -15,6 +15,7 @@ */ package com.google.android.exoplayer2.source; +import android.net.Uri; import android.os.Handler; import android.os.Looper; import android.os.SystemClock; @@ -35,8 +36,14 @@ public interface MediaSourceEventListener { /** Media source load event information. */ final class LoadEventInfo { - /** Defines the data being loaded. */ + /** Defines the requested data. */ public final DataSpec dataSpec; + /** + * The {@link Uri} from which data is being read. The uri will be identical to the one in {@link + * #dataSpec}.uri unless redirection has occurred. If redirection has occurred, this is the uri + * after redirection. + */ + public final Uri uri; /** The value of {@link SystemClock#elapsedRealtime} at the time of the load event. */ public final long elapsedRealtimeMs; /** The duration of the load up to the event time. */ @@ -47,15 +54,20 @@ public interface MediaSourceEventListener { /** * Creates load event info. * - * @param dataSpec Defines the data being loaded. + * @param dataSpec Defines the requested data. + * @param uri The {@link Uri} from which data is being read. The uri must be identical to the + * one in {@code dataSpec.uri} unless redirection has occurred. If redirection has occurred, + * this is the uri after redirection. * @param elapsedRealtimeMs The value of {@link SystemClock#elapsedRealtime} at the time of the * load event. * @param loadDurationMs The duration of the load up to the event time. - * @param bytesLoaded The number of bytes that were loaded up to the event time. + * @param bytesLoaded The number of bytes that were loaded up to the event time. For compressed + * network responses, this is the decompressed size. */ public LoadEventInfo( - DataSpec dataSpec, long elapsedRealtimeMs, long loadDurationMs, long bytesLoaded) { + DataSpec dataSpec, Uri uri, long elapsedRealtimeMs, long loadDurationMs, long bytesLoaded) { this.dataSpec = dataSpec; + this.uri = uri; this.elapsedRealtimeMs = elapsedRealtimeMs; this.loadDurationMs = loadDurationMs; this.bytesLoaded = bytesLoaded; @@ -155,7 +167,8 @@ public interface MediaSourceEventListener { * @param windowIndex The window index in the timeline of the media source this load belongs to. * @param mediaPeriodId The {@link MediaPeriodId} this load belongs to. Null if the load does not * belong to a specific media period. - * @param loadEventInfo The {@link LoadEventInfo} defining the load event. + * @param loadEventInfo The {@link LoadEventInfo} corresponding to the event. The value of {@link + * LoadEventInfo#uri} won't reflect potential redirection yet. * @param mediaLoadData The {@link MediaLoadData} defining the data being loaded. */ void onLoadStarted( @@ -170,7 +183,10 @@ public interface MediaSourceEventListener { * @param windowIndex The window index in the timeline of the media source this load belongs to. * @param mediaPeriodId The {@link MediaPeriodId} this load belongs to. Null if the load does not * belong to a specific media period. - * @param loadEventInfo The {@link LoadEventInfo} defining the load event. + * @param loadEventInfo The {@link LoadEventInfo} corresponding to the event. The values of {@link + * LoadEventInfo#elapsedRealtimeMs} and {@link LoadEventInfo#bytesLoaded} are relative to the + * corresponding {@link #onLoadStarted(int, MediaPeriodId, LoadEventInfo, MediaLoadData)} + * event. * @param mediaLoadData The {@link MediaLoadData} defining the data being loaded. */ void onLoadCompleted( @@ -185,7 +201,10 @@ public interface MediaSourceEventListener { * @param windowIndex The window index in the timeline of the media source this load belongs to. * @param mediaPeriodId The {@link MediaPeriodId} this load belongs to. Null if the load does not * belong to a specific media period. - * @param loadEventInfo The {@link LoadEventInfo} defining the load event. + * @param loadEventInfo The {@link LoadEventInfo} corresponding to the event. The values of {@link + * LoadEventInfo#elapsedRealtimeMs} and {@link LoadEventInfo#bytesLoaded} are relative to the + * corresponding {@link #onLoadStarted(int, MediaPeriodId, LoadEventInfo, MediaLoadData)} + * event. * @param mediaLoadData The {@link MediaLoadData} defining the data being loaded. */ void onLoadCanceled( @@ -211,7 +230,10 @@ public interface MediaSourceEventListener { * @param windowIndex The window index in the timeline of the media source this load belongs to. * @param mediaPeriodId The {@link MediaPeriodId} this load belongs to. Null if the load does not * belong to a specific media period. - * @param loadEventInfo The {@link LoadEventInfo} defining the load event. + * @param loadEventInfo The {@link LoadEventInfo} corresponding to the event. The values of {@link + * LoadEventInfo#elapsedRealtimeMs} and {@link LoadEventInfo#bytesLoaded} are relative to the + * corresponding {@link #onLoadStarted(int, MediaPeriodId, LoadEventInfo, MediaLoadData)} + * event. * @param mediaLoadData The {@link MediaLoadData} defining the data being loaded. * @param error The load error. * @param wasCanceled Whether the load was canceled as a result of the error. @@ -268,7 +290,7 @@ public interface MediaSourceEventListener { /** Creates an event dispatcher. */ public EventDispatcher() { this( - /* listenerAndHandlers= */ new CopyOnWriteArrayList(), + /* listenerAndHandlers= */ new CopyOnWriteArrayList<>(), /* windowIndex= */ 0, /* mediaPeriodId= */ null, /* mediaTimeOffsetMs= */ 0); @@ -327,40 +349,31 @@ public interface MediaSourceEventListener { /** Dispatches {@link #onMediaPeriodCreated(int, MediaPeriodId)}. */ public void mediaPeriodCreated() { - Assertions.checkState(mediaPeriodId != null); + MediaPeriodId mediaPeriodId = Assertions.checkNotNull(this.mediaPeriodId); for (ListenerAndHandler listenerAndHandler : listenerAndHandlers) { final MediaSourceEventListener listener = listenerAndHandler.listener; postOrRun( listenerAndHandler.handler, - new Runnable() { - @Override - public void run() { - listener.onMediaPeriodCreated(windowIndex, mediaPeriodId); - } - }); + () -> listener.onMediaPeriodCreated(windowIndex, mediaPeriodId)); } } /** Dispatches {@link #onMediaPeriodReleased(int, MediaPeriodId)}. */ public void mediaPeriodReleased() { - Assertions.checkState(mediaPeriodId != null); + MediaPeriodId mediaPeriodId = Assertions.checkNotNull(this.mediaPeriodId); for (ListenerAndHandler listenerAndHandler : listenerAndHandlers) { final MediaSourceEventListener listener = listenerAndHandler.listener; postOrRun( listenerAndHandler.handler, - new Runnable() { - @Override - public void run() { - listener.onMediaPeriodReleased(windowIndex, mediaPeriodId); - } - }); + () -> listener.onMediaPeriodReleased(windowIndex, mediaPeriodId)); } } /** Dispatches {@link #onLoadStarted(int, MediaPeriodId, LoadEventInfo, MediaLoadData)}. */ - public void loadStarted(DataSpec dataSpec, int dataType, long elapsedRealtimeMs) { + public void loadStarted(DataSpec dataSpec, Uri uri, int dataType, long elapsedRealtimeMs) { loadStarted( dataSpec, + uri, dataType, C.TRACK_TYPE_UNKNOWN, null, @@ -374,6 +387,7 @@ public interface MediaSourceEventListener { /** Dispatches {@link #onLoadStarted(int, MediaPeriodId, LoadEventInfo, MediaLoadData)}. */ public void loadStarted( DataSpec dataSpec, + Uri uri, int dataType, int trackType, @Nullable Format trackFormat, @@ -384,7 +398,7 @@ public interface MediaSourceEventListener { long elapsedRealtimeMs) { loadStarted( new LoadEventInfo( - dataSpec, elapsedRealtimeMs, /* loadDurationMs= */ 0, /* bytesLoaded= */ 0), + dataSpec, uri, elapsedRealtimeMs, /* loadDurationMs= */ 0, /* bytesLoaded= */ 0), new MediaLoadData( dataType, trackType, @@ -396,29 +410,26 @@ public interface MediaSourceEventListener { } /** Dispatches {@link #onLoadStarted(int, MediaPeriodId, LoadEventInfo, MediaLoadData)}. */ - public void loadStarted(final LoadEventInfo loadEventInfo, final MediaLoadData mediaLoadData) { + public void loadStarted(LoadEventInfo loadEventInfo, MediaLoadData mediaLoadData) { for (ListenerAndHandler listenerAndHandler : listenerAndHandlers) { final MediaSourceEventListener listener = listenerAndHandler.listener; postOrRun( listenerAndHandler.handler, - new Runnable() { - @Override - public void run() { - listener.onLoadStarted(windowIndex, mediaPeriodId, loadEventInfo, mediaLoadData); - } - }); + () -> listener.onLoadStarted(windowIndex, mediaPeriodId, loadEventInfo, mediaLoadData)); } } /** Dispatches {@link #onLoadCompleted(int, MediaPeriodId, LoadEventInfo, MediaLoadData)}. */ public void loadCompleted( DataSpec dataSpec, + Uri uri, int dataType, long elapsedRealtimeMs, long loadDurationMs, long bytesLoaded) { loadCompleted( dataSpec, + uri, dataType, C.TRACK_TYPE_UNKNOWN, null, @@ -434,6 +445,7 @@ public interface MediaSourceEventListener { /** Dispatches {@link #onLoadCompleted(int, MediaPeriodId, LoadEventInfo, MediaLoadData)}. */ public void loadCompleted( DataSpec dataSpec, + Uri uri, int dataType, int trackType, @Nullable Format trackFormat, @@ -445,7 +457,7 @@ public interface MediaSourceEventListener { long loadDurationMs, long bytesLoaded) { loadCompleted( - new LoadEventInfo(dataSpec, elapsedRealtimeMs, loadDurationMs, bytesLoaded), + new LoadEventInfo(dataSpec, uri, elapsedRealtimeMs, loadDurationMs, bytesLoaded), new MediaLoadData( dataType, trackType, @@ -457,30 +469,27 @@ public interface MediaSourceEventListener { } /** Dispatches {@link #onLoadCompleted(int, MediaPeriodId, LoadEventInfo, MediaLoadData)}. */ - public void loadCompleted( - final LoadEventInfo loadEventInfo, final MediaLoadData mediaLoadData) { + public void loadCompleted(LoadEventInfo loadEventInfo, MediaLoadData mediaLoadData) { for (ListenerAndHandler listenerAndHandler : listenerAndHandlers) { final MediaSourceEventListener listener = listenerAndHandler.listener; postOrRun( listenerAndHandler.handler, - new Runnable() { - @Override - public void run() { - listener.onLoadCompleted(windowIndex, mediaPeriodId, loadEventInfo, mediaLoadData); - } - }); + () -> + listener.onLoadCompleted(windowIndex, mediaPeriodId, loadEventInfo, mediaLoadData)); } } /** Dispatches {@link #onLoadCanceled(int, MediaPeriodId, LoadEventInfo, MediaLoadData)}. */ public void loadCanceled( DataSpec dataSpec, + Uri uri, int dataType, long elapsedRealtimeMs, long loadDurationMs, long bytesLoaded) { loadCanceled( dataSpec, + uri, dataType, C.TRACK_TYPE_UNKNOWN, null, @@ -496,6 +505,7 @@ public interface MediaSourceEventListener { /** Dispatches {@link #onLoadCanceled(int, MediaPeriodId, LoadEventInfo, MediaLoadData)}. */ public void loadCanceled( DataSpec dataSpec, + Uri uri, int dataType, int trackType, @Nullable Format trackFormat, @@ -507,7 +517,7 @@ public interface MediaSourceEventListener { long loadDurationMs, long bytesLoaded) { loadCanceled( - new LoadEventInfo(dataSpec, elapsedRealtimeMs, loadDurationMs, bytesLoaded), + new LoadEventInfo(dataSpec, uri, elapsedRealtimeMs, loadDurationMs, bytesLoaded), new MediaLoadData( dataType, trackType, @@ -519,17 +529,13 @@ public interface MediaSourceEventListener { } /** Dispatches {@link #onLoadCanceled(int, MediaPeriodId, LoadEventInfo, MediaLoadData)}. */ - public void loadCanceled(final LoadEventInfo loadEventInfo, final MediaLoadData mediaLoadData) { + public void loadCanceled(LoadEventInfo loadEventInfo, MediaLoadData mediaLoadData) { for (ListenerAndHandler listenerAndHandler : listenerAndHandlers) { - final MediaSourceEventListener listener = listenerAndHandler.listener; + MediaSourceEventListener listener = listenerAndHandler.listener; postOrRun( listenerAndHandler.handler, - new Runnable() { - @Override - public void run() { - listener.onLoadCanceled(windowIndex, mediaPeriodId, loadEventInfo, mediaLoadData); - } - }); + () -> + listener.onLoadCanceled(windowIndex, mediaPeriodId, loadEventInfo, mediaLoadData)); } } @@ -539,6 +545,7 @@ public interface MediaSourceEventListener { */ public void loadError( DataSpec dataSpec, + Uri uri, int dataType, long elapsedRealtimeMs, long loadDurationMs, @@ -547,6 +554,7 @@ public interface MediaSourceEventListener { boolean wasCanceled) { loadError( dataSpec, + uri, dataType, C.TRACK_TYPE_UNKNOWN, null, @@ -567,6 +575,7 @@ public interface MediaSourceEventListener { */ public void loadError( DataSpec dataSpec, + Uri uri, int dataType, int trackType, @Nullable Format trackFormat, @@ -580,7 +589,7 @@ public interface MediaSourceEventListener { IOException error, boolean wasCanceled) { loadError( - new LoadEventInfo(dataSpec, elapsedRealtimeMs, loadDurationMs, bytesLoaded), + new LoadEventInfo(dataSpec, uri, elapsedRealtimeMs, loadDurationMs, bytesLoaded), new MediaLoadData( dataType, trackType, @@ -598,37 +607,28 @@ public interface MediaSourceEventListener { * boolean)}. */ public void loadError( - final LoadEventInfo loadEventInfo, - final MediaLoadData mediaLoadData, - final IOException error, - final boolean wasCanceled) { + LoadEventInfo loadEventInfo, + MediaLoadData mediaLoadData, + IOException error, + boolean wasCanceled) { for (ListenerAndHandler listenerAndHandler : listenerAndHandlers) { final MediaSourceEventListener listener = listenerAndHandler.listener; postOrRun( listenerAndHandler.handler, - new Runnable() { - @Override - public void run() { + () -> listener.onLoadError( - windowIndex, mediaPeriodId, loadEventInfo, mediaLoadData, error, wasCanceled); - } - }); + windowIndex, mediaPeriodId, loadEventInfo, mediaLoadData, error, wasCanceled)); } } /** Dispatches {@link #onReadingStarted(int, MediaPeriodId)}. */ public void readingStarted() { - Assertions.checkState(mediaPeriodId != null); + MediaPeriodId mediaPeriodId = Assertions.checkNotNull(this.mediaPeriodId); for (ListenerAndHandler listenerAndHandler : listenerAndHandlers) { final MediaSourceEventListener listener = listenerAndHandler.listener; postOrRun( listenerAndHandler.handler, - new Runnable() { - @Override - public void run() { - listener.onReadingStarted(windowIndex, mediaPeriodId); - } - }); + () -> listener.onReadingStarted(windowIndex, mediaPeriodId)); } } @@ -646,17 +646,13 @@ public interface MediaSourceEventListener { } /** Dispatches {@link #onUpstreamDiscarded(int, MediaPeriodId, MediaLoadData)}. */ - public void upstreamDiscarded(final MediaLoadData mediaLoadData) { + public void upstreamDiscarded(MediaLoadData mediaLoadData) { + MediaPeriodId mediaPeriodId = Assertions.checkNotNull(this.mediaPeriodId); for (ListenerAndHandler listenerAndHandler : listenerAndHandlers) { final MediaSourceEventListener listener = listenerAndHandler.listener; postOrRun( listenerAndHandler.handler, - new Runnable() { - @Override - public void run() { - listener.onUpstreamDiscarded(windowIndex, mediaPeriodId, mediaLoadData); - } - }); + () -> listener.onUpstreamDiscarded(windowIndex, mediaPeriodId, mediaLoadData)); } } @@ -679,17 +675,12 @@ public interface MediaSourceEventListener { } /** Dispatches {@link #onDownstreamFormatChanged(int, MediaPeriodId, MediaLoadData)}. */ - public void downstreamFormatChanged(final MediaLoadData mediaLoadData) { + public void downstreamFormatChanged(MediaLoadData mediaLoadData) { for (ListenerAndHandler listenerAndHandler : listenerAndHandlers) { final MediaSourceEventListener listener = listenerAndHandler.listener; postOrRun( listenerAndHandler.handler, - new Runnable() { - @Override - public void run() { - listener.onDownstreamFormatChanged(windowIndex, mediaPeriodId, mediaLoadData); - } - }); + () -> listener.onDownstreamFormatChanged(windowIndex, mediaPeriodId, mediaLoadData)); } } diff --git a/library/core/src/main/java/com/google/android/exoplayer2/source/SingleSampleMediaPeriod.java b/library/core/src/main/java/com/google/android/exoplayer2/source/SingleSampleMediaPeriod.java index 43f09e4a67..4de2a10f2e 100644 --- a/library/core/src/main/java/com/google/android/exoplayer2/source/SingleSampleMediaPeriod.java +++ b/library/core/src/main/java/com/google/android/exoplayer2/source/SingleSampleMediaPeriod.java @@ -27,6 +27,7 @@ import com.google.android.exoplayer2.upstream.DataSpec; 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.util.MimeTypes; import com.google.android.exoplayer2.util.Util; import java.io.IOException; @@ -144,6 +145,7 @@ import java.util.Arrays; minLoadableRetryCount); eventDispatcher.loadStarted( dataSpec, + dataSpec.uri, C.DATA_TYPE_MEDIA, C.TRACK_TYPE_UNKNOWN, format, @@ -192,8 +194,13 @@ import java.util.Arrays; @Override public void onLoadCompleted(SourceLoadable loadable, long elapsedRealtimeMs, long loadDurationMs) { + sampleSize = (int) loadable.dataSource.getBytesRead(); + sampleData = loadable.sampleData; + loadingFinished = true; + loadingSucceeded = true; eventDispatcher.loadCompleted( loadable.dataSpec, + loadable.dataSource.getLastOpenedUri(), C.DATA_TYPE_MEDIA, C.TRACK_TYPE_UNKNOWN, format, @@ -203,11 +210,7 @@ import java.util.Arrays; durationUs, elapsedRealtimeMs, loadDurationMs, - loadable.sampleSize); - sampleSize = loadable.sampleSize; - sampleData = loadable.sampleData; - loadingFinished = true; - loadingSucceeded = true; + sampleSize); } @Override @@ -215,6 +218,7 @@ import java.util.Arrays; boolean released) { eventDispatcher.loadCanceled( loadable.dataSpec, + loadable.dataSource.getLastOpenedUri(), C.DATA_TYPE_MEDIA, C.TRACK_TYPE_UNKNOWN, /* trackFormat= */ null, @@ -224,7 +228,7 @@ import java.util.Arrays; durationUs, elapsedRealtimeMs, loadDurationMs, - loadable.sampleSize); + loadable.dataSource.getBytesRead()); } @Override @@ -237,6 +241,7 @@ import java.util.Arrays; boolean cancel = treatLoadErrorsAsEndOfStream && errorCount >= minLoadableRetryCount; eventDispatcher.loadError( loadable.dataSpec, + loadable.dataSource.getLastOpenedUri(), C.DATA_TYPE_MEDIA, C.TRACK_TYPE_UNKNOWN, format, @@ -246,7 +251,7 @@ import java.util.Arrays; durationUs, elapsedRealtimeMs, loadDurationMs, - loadable.sampleSize, + loadable.dataSource.getBytesRead(), error, /* wasCanceled= */ cancel); if (cancel) { @@ -336,14 +341,13 @@ import java.util.Arrays; public final DataSpec dataSpec; - private final DataSource dataSource; + private final StatsDataSource dataSource; - private int sampleSize; private byte[] sampleData; public SourceLoadable(DataSpec dataSpec, DataSource dataSource) { this.dataSpec = dataSpec; - this.dataSource = dataSource; + this.dataSource = new StatsDataSource(dataSource); } @Override @@ -353,15 +357,15 @@ import java.util.Arrays; @Override public void load() throws IOException, InterruptedException { - // We always load from the beginning, so reset the sampleSize to 0. - sampleSize = 0; + // We always load from the beginning, so reset bytesRead to 0. + dataSource.resetBytesRead(); try { // Create and open the input. dataSource.open(dataSpec); // Load the sample data. int result = 0; while (result != C.RESULT_END_OF_INPUT) { - sampleSize += result; + int sampleSize = (int) dataSource.getBytesRead(); if (sampleData == null) { sampleData = new byte[INITIAL_SAMPLE_SIZE]; } else if (sampleSize == sampleData.length) { diff --git a/library/core/src/main/java/com/google/android/exoplayer2/source/ads/AdsMediaSource.java b/library/core/src/main/java/com/google/android/exoplayer2/source/ads/AdsMediaSource.java index 44c6bdc20d..5d765c78f5 100644 --- a/library/core/src/main/java/com/google/android/exoplayer2/source/ads/AdsMediaSource.java +++ b/library/core/src/main/java/com/google/android/exoplayer2/source/ads/AdsMediaSource.java @@ -539,6 +539,7 @@ public final class AdsMediaSource extends CompositeMediaSource { createEventDispatcher(/* mediaPeriodId= */ null) .loadError( dataSpec, + dataSpec.uri, C.DATA_TYPE_AD, C.TRACK_TYPE_UNKNOWN, /* loadDurationMs= */ 0, @@ -580,6 +581,7 @@ public final class AdsMediaSource extends CompositeMediaSource { createEventDispatcher(mediaPeriodId) .loadError( new DataSpec(adUri), + adUri, C.DATA_TYPE_AD, C.TRACK_TYPE_UNKNOWN, /* loadDurationMs= */ 0, diff --git a/library/core/src/main/java/com/google/android/exoplayer2/source/chunk/ChunkSampleStream.java b/library/core/src/main/java/com/google/android/exoplayer2/source/chunk/ChunkSampleStream.java index 2d183ac1e0..325a75ea28 100644 --- a/library/core/src/main/java/com/google/android/exoplayer2/source/chunk/ChunkSampleStream.java +++ b/library/core/src/main/java/com/google/android/exoplayer2/source/chunk/ChunkSampleStream.java @@ -386,9 +386,18 @@ public class ChunkSampleStream implements SampleStream, S @Override public void onLoadCompleted(Chunk loadable, long elapsedRealtimeMs, long loadDurationMs) { chunkSource.onChunkLoadCompleted(loadable); - eventDispatcher.loadCompleted(loadable.dataSpec, loadable.type, primaryTrackType, - loadable.trackFormat, loadable.trackSelectionReason, loadable.trackSelectionData, - loadable.startTimeUs, loadable.endTimeUs, elapsedRealtimeMs, loadDurationMs, + eventDispatcher.loadCompleted( + loadable.dataSpec, + loadable.getUri(), + loadable.type, + primaryTrackType, + loadable.trackFormat, + loadable.trackSelectionReason, + loadable.trackSelectionData, + loadable.startTimeUs, + loadable.endTimeUs, + elapsedRealtimeMs, + loadDurationMs, loadable.bytesLoaded()); callback.onContinueLoadingRequested(this); } @@ -396,9 +405,18 @@ public class ChunkSampleStream implements SampleStream, S @Override public void onLoadCanceled(Chunk loadable, long elapsedRealtimeMs, long loadDurationMs, boolean released) { - eventDispatcher.loadCanceled(loadable.dataSpec, loadable.type, primaryTrackType, - loadable.trackFormat, loadable.trackSelectionReason, loadable.trackSelectionData, - loadable.startTimeUs, loadable.endTimeUs, elapsedRealtimeMs, loadDurationMs, + eventDispatcher.loadCanceled( + loadable.dataSpec, + loadable.getUri(), + loadable.type, + primaryTrackType, + loadable.trackFormat, + loadable.trackSelectionReason, + loadable.trackSelectionData, + loadable.startTimeUs, + loadable.endTimeUs, + elapsedRealtimeMs, + loadDurationMs, loadable.bytesLoaded()); if (!released) { primarySampleQueue.reset(); @@ -436,10 +454,21 @@ public class ChunkSampleStream implements SampleStream, S } } } - eventDispatcher.loadError(loadable.dataSpec, loadable.type, primaryTrackType, - loadable.trackFormat, loadable.trackSelectionReason, loadable.trackSelectionData, - loadable.startTimeUs, loadable.endTimeUs, elapsedRealtimeMs, loadDurationMs, bytesLoaded, - error, canceled); + eventDispatcher.loadError( + loadable.dataSpec, + loadable.getUri(), + loadable.type, + primaryTrackType, + loadable.trackFormat, + loadable.trackSelectionReason, + loadable.trackSelectionData, + loadable.startTimeUs, + loadable.endTimeUs, + elapsedRealtimeMs, + loadDurationMs, + bytesLoaded, + error, + canceled); if (canceled) { callback.onContinueLoadingRequested(this); return Loader.DONT_RETRY; @@ -493,9 +522,17 @@ public class ChunkSampleStream implements SampleStream, S mediaChunks.add(mediaChunk); } long elapsedRealtimeMs = loader.startLoading(loadable, this, minLoadableRetryCount); - eventDispatcher.loadStarted(loadable.dataSpec, loadable.type, primaryTrackType, - loadable.trackFormat, loadable.trackSelectionReason, loadable.trackSelectionData, - loadable.startTimeUs, loadable.endTimeUs, elapsedRealtimeMs); + eventDispatcher.loadStarted( + loadable.dataSpec, + loadable.dataSpec.uri, + loadable.type, + primaryTrackType, + loadable.trackFormat, + loadable.trackSelectionReason, + loadable.trackSelectionData, + loadable.startTimeUs, + loadable.endTimeUs, + elapsedRealtimeMs); return true; } diff --git a/library/core/src/main/java/com/google/android/exoplayer2/upstream/ParsingLoadable.java b/library/core/src/main/java/com/google/android/exoplayer2/upstream/ParsingLoadable.java index 4a17b070a6..17d479daab 100644 --- a/library/core/src/main/java/com/google/android/exoplayer2/upstream/ParsingLoadable.java +++ b/library/core/src/main/java/com/google/android/exoplayer2/upstream/ParsingLoadable.java @@ -77,11 +77,10 @@ public final class ParsingLoadable implements Loadable { */ public final int type; - private final DataSource dataSource; + private final StatsDataSource dataSource; private final Parser parser; private volatile @Nullable T result; - private volatile long bytesLoaded; /** * @param dataSource A {@link DataSource} to use when loading the data. @@ -105,7 +104,7 @@ public final class ParsingLoadable implements Loadable { */ public ParsingLoadable(DataSource dataSource, DataSpec dataSpec, int type, Parser parser) { - this.dataSource = dataSource; + this.dataSource = new StatsDataSource(dataSource); this.dataSpec = dataSpec; this.type = type; this.parser = parser; @@ -118,12 +117,19 @@ public final class ParsingLoadable implements Loadable { /** * Returns the number of bytes loaded. In the case that the network response was compressed, the - * value returned is the size of the data after decompression. - * - * @return The number of bytes loaded. + * value returned is the size of the data after decompression. Must only be called after + * the load completed, failed, or was canceled. */ public long bytesLoaded() { - return bytesLoaded; + return dataSource.getBytesRead(); + } + + /** + * Returns the {@link Uri} from which data was read. If redirection occurred, this is the + * redirected uri. Must only be called after the load completed, failed, or was canceled. + */ + public Uri getUri() { + return dataSource.getLastOpenedUri(); } @Override @@ -133,13 +139,14 @@ public final class ParsingLoadable implements Loadable { @Override public final void load() throws IOException { + // We always load from the beginning, so reset bytesRead to 0. + dataSource.resetBytesRead(); DataSourceInputStream inputStream = new DataSourceInputStream(dataSource, dataSpec); try { inputStream.open(); Uri dataSourceUri = Assertions.checkNotNull(dataSource.getUri()); result = parser.parse(dataSourceUri, inputStream); } finally { - bytesLoaded = inputStream.bytesRead(); Util.closeQuietly(inputStream); } } diff --git a/library/core/src/main/java/com/google/android/exoplayer2/upstream/StatsDataSource.java b/library/core/src/main/java/com/google/android/exoplayer2/upstream/StatsDataSource.java index 71458b24a4..79868806d1 100644 --- a/library/core/src/main/java/com/google/android/exoplayer2/upstream/StatsDataSource.java +++ b/library/core/src/main/java/com/google/android/exoplayer2/upstream/StatsDataSource.java @@ -47,6 +47,11 @@ public final class StatsDataSource implements DataSource { lastResponseHeaders = Collections.emptyMap(); } + /** Resets the number of bytes read as returned from {@link #getBytesRead()} to zero. */ + public void resetBytesRead() { + bytesRead = 0; + } + /** Returns the total number of bytes that have been read from the data source. */ public long getBytesRead() { return bytesRead; diff --git a/library/dash/src/main/java/com/google/android/exoplayer2/source/dash/DashMediaSource.java b/library/dash/src/main/java/com/google/android/exoplayer2/source/dash/DashMediaSource.java index 530c41684d..d826e4165f 100644 --- a/library/dash/src/main/java/com/google/android/exoplayer2/source/dash/DashMediaSource.java +++ b/library/dash/src/main/java/com/google/android/exoplayer2/source/dash/DashMediaSource.java @@ -638,6 +638,7 @@ public final class DashMediaSource extends BaseMediaSource { long elapsedRealtimeMs, long loadDurationMs) { manifestEventDispatcher.loadCompleted( loadable.dataSpec, + loadable.getUri(), loadable.type, elapsedRealtimeMs, loadDurationMs, @@ -699,7 +700,9 @@ public final class DashMediaSource extends BaseMediaSource { synchronized (manifestUriLock) { // This condition checks that replaceManifestUri wasn't called between the start and end of // this load. If it was, we ignore the manifest location and prefer the manual replacement. - if (loadable.dataSpec.uri == manifestUri) { + @SuppressWarnings("ReferenceEquality") + boolean isSameUriInstance = loadable.dataSpec.uri == manifestUri; + if (isSameUriInstance) { manifestUri = manifest.location; } } @@ -725,6 +728,7 @@ public final class DashMediaSource extends BaseMediaSource { boolean isFatal = error instanceof ParserException; manifestEventDispatcher.loadError( loadable.dataSpec, + loadable.getUri(), loadable.type, elapsedRealtimeMs, loadDurationMs, @@ -738,6 +742,7 @@ public final class DashMediaSource extends BaseMediaSource { long elapsedRealtimeMs, long loadDurationMs) { manifestEventDispatcher.loadCompleted( loadable.dataSpec, + loadable.getUri(), loadable.type, elapsedRealtimeMs, loadDurationMs, @@ -752,6 +757,7 @@ public final class DashMediaSource extends BaseMediaSource { IOException error) { manifestEventDispatcher.loadError( loadable.dataSpec, + loadable.getUri(), loadable.type, elapsedRealtimeMs, loadDurationMs, @@ -766,6 +772,7 @@ public final class DashMediaSource extends BaseMediaSource { long loadDurationMs) { manifestEventDispatcher.loadCanceled( loadable.dataSpec, + loadable.getUri(), loadable.type, elapsedRealtimeMs, loadDurationMs, @@ -953,7 +960,8 @@ public final class DashMediaSource extends BaseMediaSource { private void startLoading(ParsingLoadable loadable, Loader.Callback> callback, int minRetryCount) { long elapsedRealtimeMs = loader.startLoading(loadable, callback, minRetryCount); - manifestEventDispatcher.loadStarted(loadable.dataSpec, loadable.type, elapsedRealtimeMs); + manifestEventDispatcher.loadStarted( + loadable.dataSpec, loadable.dataSpec.uri, loadable.type, elapsedRealtimeMs); } private long getNowUnixTimeUs() { diff --git a/library/hls/src/main/java/com/google/android/exoplayer2/source/hls/HlsSampleStreamWrapper.java b/library/hls/src/main/java/com/google/android/exoplayer2/source/hls/HlsSampleStreamWrapper.java index f55fc78b60..13f44aa3dd 100644 --- a/library/hls/src/main/java/com/google/android/exoplayer2/source/hls/HlsSampleStreamWrapper.java +++ b/library/hls/src/main/java/com/google/android/exoplayer2/source/hls/HlsSampleStreamWrapper.java @@ -562,9 +562,17 @@ import java.util.Arrays; mediaChunks.add(mediaChunk); } long elapsedRealtimeMs = loader.startLoading(loadable, this, minLoadableRetryCount); - eventDispatcher.loadStarted(loadable.dataSpec, loadable.type, trackType, loadable.trackFormat, - loadable.trackSelectionReason, loadable.trackSelectionData, loadable.startTimeUs, - loadable.endTimeUs, elapsedRealtimeMs); + eventDispatcher.loadStarted( + loadable.dataSpec, + loadable.dataSpec.uri, + loadable.type, + trackType, + loadable.trackFormat, + loadable.trackSelectionReason, + loadable.trackSelectionData, + loadable.startTimeUs, + loadable.endTimeUs, + elapsedRealtimeMs); return true; } @@ -578,9 +586,19 @@ import java.util.Arrays; @Override public void onLoadCompleted(Chunk loadable, long elapsedRealtimeMs, long loadDurationMs) { chunkSource.onChunkLoadCompleted(loadable); - eventDispatcher.loadCompleted(loadable.dataSpec, loadable.type, trackType, loadable.trackFormat, - loadable.trackSelectionReason, loadable.trackSelectionData, loadable.startTimeUs, - loadable.endTimeUs, elapsedRealtimeMs, loadDurationMs, loadable.bytesLoaded()); + eventDispatcher.loadCompleted( + loadable.dataSpec, + loadable.getUri(), + loadable.type, + trackType, + loadable.trackFormat, + loadable.trackSelectionReason, + loadable.trackSelectionData, + loadable.startTimeUs, + loadable.endTimeUs, + elapsedRealtimeMs, + loadDurationMs, + loadable.bytesLoaded()); if (!prepared) { continueLoading(lastSeekPositionUs); } else { @@ -591,9 +609,19 @@ import java.util.Arrays; @Override public void onLoadCanceled(Chunk loadable, long elapsedRealtimeMs, long loadDurationMs, boolean released) { - eventDispatcher.loadCanceled(loadable.dataSpec, loadable.type, trackType, loadable.trackFormat, - loadable.trackSelectionReason, loadable.trackSelectionData, loadable.startTimeUs, - loadable.endTimeUs, elapsedRealtimeMs, loadDurationMs, loadable.bytesLoaded()); + eventDispatcher.loadCanceled( + loadable.dataSpec, + loadable.getUri(), + loadable.type, + trackType, + loadable.trackFormat, + loadable.trackSelectionReason, + loadable.trackSelectionData, + loadable.startTimeUs, + loadable.endTimeUs, + elapsedRealtimeMs, + loadDurationMs, + loadable.bytesLoaded()); if (!released) { resetSampleQueues(); if (enabledTrackGroupCount > 0) { @@ -623,9 +651,20 @@ import java.util.Arrays; } canceled = true; } - eventDispatcher.loadError(loadable.dataSpec, loadable.type, trackType, loadable.trackFormat, - loadable.trackSelectionReason, loadable.trackSelectionData, loadable.startTimeUs, - loadable.endTimeUs, elapsedRealtimeMs, loadDurationMs, loadable.bytesLoaded(), error, + eventDispatcher.loadError( + loadable.dataSpec, + loadable.getUri(), + loadable.type, + trackType, + loadable.trackFormat, + loadable.trackSelectionReason, + loadable.trackSelectionData, + loadable.startTimeUs, + loadable.endTimeUs, + elapsedRealtimeMs, + loadDurationMs, + loadable.bytesLoaded(), + error, canceled); if (canceled) { if (!prepared) { diff --git a/library/hls/src/main/java/com/google/android/exoplayer2/source/hls/playlist/DefaultHlsPlaylistTracker.java b/library/hls/src/main/java/com/google/android/exoplayer2/source/hls/playlist/DefaultHlsPlaylistTracker.java index 15136236eb..97a4ecc181 100644 --- a/library/hls/src/main/java/com/google/android/exoplayer2/source/hls/playlist/DefaultHlsPlaylistTracker.java +++ b/library/hls/src/main/java/com/google/android/exoplayer2/source/hls/playlist/DefaultHlsPlaylistTracker.java @@ -102,7 +102,10 @@ public final class DefaultHlsPlaylistTracker long elapsedRealtime = initialPlaylistLoader.startLoading(masterPlaylistLoadable, this, minRetryCount); eventDispatcher.loadStarted( - masterPlaylistLoadable.dataSpec, masterPlaylistLoadable.type, elapsedRealtime); + masterPlaylistLoadable.dataSpec, + masterPlaylistLoadable.dataSpec.uri, + masterPlaylistLoadable.type, + elapsedRealtime); } @Override @@ -209,6 +212,7 @@ public final class DefaultHlsPlaylistTracker } eventDispatcher.loadCompleted( loadable.dataSpec, + loadable.getUri(), C.DATA_TYPE_MANIFEST, elapsedRealtimeMs, loadDurationMs, @@ -223,6 +227,7 @@ public final class DefaultHlsPlaylistTracker boolean released) { eventDispatcher.loadCanceled( loadable.dataSpec, + loadable.getUri(), C.DATA_TYPE_MANIFEST, elapsedRealtimeMs, loadDurationMs, @@ -239,6 +244,7 @@ public final class DefaultHlsPlaylistTracker boolean isFatal = error instanceof ParserException; eventDispatcher.loadError( loadable.dataSpec, + loadable.getUri(), C.DATA_TYPE_MANIFEST, elapsedRealtimeMs, loadDurationMs, @@ -463,6 +469,7 @@ public final class DefaultHlsPlaylistTracker processLoadedPlaylist((HlsMediaPlaylist) result); eventDispatcher.loadCompleted( loadable.dataSpec, + loadable.getUri(), C.DATA_TYPE_MANIFEST, elapsedRealtimeMs, loadDurationMs, @@ -480,6 +487,7 @@ public final class DefaultHlsPlaylistTracker boolean released) { eventDispatcher.loadCanceled( loadable.dataSpec, + loadable.getUri(), C.DATA_TYPE_MANIFEST, elapsedRealtimeMs, loadDurationMs, @@ -496,6 +504,7 @@ public final class DefaultHlsPlaylistTracker boolean isFatal = error instanceof ParserException; eventDispatcher.loadError( loadable.dataSpec, + loadable.getUri(), C.DATA_TYPE_MANIFEST, elapsedRealtimeMs, loadDurationMs, @@ -528,7 +537,10 @@ public final class DefaultHlsPlaylistTracker long elapsedRealtime = mediaPlaylistLoader.startLoading(mediaPlaylistLoadable, this, minRetryCount); eventDispatcher.loadStarted( - mediaPlaylistLoadable.dataSpec, mediaPlaylistLoadable.type, elapsedRealtime); + mediaPlaylistLoadable.dataSpec, + mediaPlaylistLoadable.dataSpec.uri, + mediaPlaylistLoadable.type, + elapsedRealtime); } private void processLoadedPlaylist(HlsMediaPlaylist loadedPlaylist) { diff --git a/library/smoothstreaming/src/main/java/com/google/android/exoplayer2/source/smoothstreaming/SsMediaSource.java b/library/smoothstreaming/src/main/java/com/google/android/exoplayer2/source/smoothstreaming/SsMediaSource.java index 7da0e92739..19335a78fa 100644 --- a/library/smoothstreaming/src/main/java/com/google/android/exoplayer2/source/smoothstreaming/SsMediaSource.java +++ b/library/smoothstreaming/src/main/java/com/google/android/exoplayer2/source/smoothstreaming/SsMediaSource.java @@ -519,6 +519,7 @@ public final class SsMediaSource extends BaseMediaSource long loadDurationMs) { manifestEventDispatcher.loadCompleted( loadable.dataSpec, + loadable.getUri(), loadable.type, elapsedRealtimeMs, loadDurationMs, @@ -534,6 +535,7 @@ public final class SsMediaSource extends BaseMediaSource long loadDurationMs, boolean released) { manifestEventDispatcher.loadCanceled( loadable.dataSpec, + loadable.getUri(), loadable.type, elapsedRealtimeMs, loadDurationMs, @@ -550,6 +552,7 @@ public final class SsMediaSource extends BaseMediaSource boolean isFatal = error instanceof ParserException; manifestEventDispatcher.loadError( loadable.dataSpec, + loadable.getUri(), loadable.type, elapsedRealtimeMs, loadDurationMs, @@ -643,7 +646,8 @@ public final class SsMediaSource extends BaseMediaSource ParsingLoadable loadable = new ParsingLoadable<>(manifestDataSource, manifestUri, C.DATA_TYPE_MANIFEST, manifestParser); long elapsedRealtimeMs = manifestLoader.startLoading(loadable, this, minLoadableRetryCount); - manifestEventDispatcher.loadStarted(loadable.dataSpec, loadable.type, elapsedRealtimeMs); + manifestEventDispatcher.loadStarted( + loadable.dataSpec, loadable.dataSpec.uri, loadable.type, elapsedRealtimeMs); } } diff --git a/testutils/src/main/java/com/google/android/exoplayer2/testutil/FakeMediaPeriod.java b/testutils/src/main/java/com/google/android/exoplayer2/testutil/FakeMediaPeriod.java index a251bd5ef0..8cef80766b 100644 --- a/testutils/src/main/java/com/google/android/exoplayer2/testutil/FakeMediaPeriod.java +++ b/testutils/src/main/java/com/google/android/exoplayer2/testutil/FakeMediaPeriod.java @@ -121,6 +121,7 @@ public class FakeMediaPeriod implements MediaPeriod { public synchronized void prepare(Callback callback, long positionUs) { eventDispatcher.loadStarted( FAKE_DATA_SPEC, + FAKE_DATA_SPEC.uri, C.DATA_TYPE_MEDIA, C.TRACK_TYPE_UNKNOWN, /* trackFormat= */ null, @@ -232,6 +233,7 @@ public class FakeMediaPeriod implements MediaPeriod { prepareCallback.onPrepared(this); eventDispatcher.loadCompleted( FAKE_DATA_SPEC, + FAKE_DATA_SPEC.uri, C.DATA_TYPE_MEDIA, C.TRACK_TYPE_UNKNOWN, /* trackFormat= */ null, diff --git a/testutils/src/main/java/com/google/android/exoplayer2/testutil/FakeMediaSource.java b/testutils/src/main/java/com/google/android/exoplayer2/testutil/FakeMediaSource.java index ec8bd6b75a..3b0823ad76 100644 --- a/testutils/src/main/java/com/google/android/exoplayer2/testutil/FakeMediaSource.java +++ b/testutils/src/main/java/com/google/android/exoplayer2/testutil/FakeMediaSource.java @@ -216,11 +216,16 @@ public class FakeMediaSource extends BaseMediaSource { EventDispatcher eventDispatcher = createEventDispatcher(/* mediaPeriodId= */ null); eventDispatcher.loadStarted( new LoadEventInfo( - FAKE_DATA_SPEC, elapsedRealTimeMs, /* loadDurationMs= */ 0, /* bytesLoaded= */ 0), + FAKE_DATA_SPEC, + FAKE_DATA_SPEC.uri, + elapsedRealTimeMs, + /* loadDurationMs= */ 0, + /* bytesLoaded= */ 0), mediaLoadData); eventDispatcher.loadCompleted( new LoadEventInfo( FAKE_DATA_SPEC, + FAKE_DATA_SPEC.uri, elapsedRealTimeMs, /* loadDurationMs= */ 0, /* bytesLoaded= */ MANIFEST_LOAD_BYTES),