Add response headers to LoadEventInfo.

The response headers of the last load are available from the loading source
when creating media source events and can be easily forwarded.

Issue:#4361
Issue:#4615

-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=209900693
This commit is contained in:
tonihei 2018-08-23 02:00:37 -07:00 committed by Oliver Woodman
parent 4bf5e4991c
commit 74e2384fb6
13 changed files with 88 additions and 20 deletions

View file

@ -101,6 +101,10 @@
* 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)).
* Add response headers field to `LoadEventInfo` in `MediaSourceEventListener` or
`AnalyticsListener` callbacks
([#4361](https://github.com/google/ExoPlayer/issues/4361) and
[#4615](https://github.com/google/ExoPlayer/issues/4615)).
* Allow `MediaCodecSelector`s to return multiple compatible decoders for
`MediaCodecRenderer`, and provide an (optional) `MediaCodecSelector` that
falls back to less preferred decoders like `MediaCodec.createDecoderByType`

View file

@ -503,6 +503,7 @@ import org.checkerframework.checker.nullness.compatqual.NullableType;
eventDispatcher.loadCompleted(
loadable.dataSpec,
loadable.dataSource.getLastOpenedUri(),
loadable.dataSource.getLastResponseHeaders(),
C.DATA_TYPE_MEDIA,
C.TRACK_TYPE_UNKNOWN,
/* trackFormat= */ null,
@ -524,6 +525,7 @@ import org.checkerframework.checker.nullness.compatqual.NullableType;
eventDispatcher.loadCanceled(
loadable.dataSpec,
loadable.dataSource.getLastOpenedUri(),
loadable.dataSource.getLastResponseHeaders(),
C.DATA_TYPE_MEDIA,
C.TRACK_TYPE_UNKNOWN,
/* trackFormat= */ null,
@ -570,6 +572,7 @@ import org.checkerframework.checker.nullness.compatqual.NullableType;
eventDispatcher.loadError(
loadable.dataSpec,
loadable.dataSource.getLastOpenedUri(),
loadable.dataSource.getLastResponseHeaders(),
C.DATA_TYPE_MEDIA,
C.TRACK_TYPE_UNKNOWN,
/* trackFormat= */ null,
@ -697,7 +700,6 @@ import org.checkerframework.checker.nullness.compatqual.NullableType;
loadable, this, loadErrorHandlingPolicy.getMinimumLoadableRetryCount(dataType));
eventDispatcher.loadStarted(
loadable.dataSpec,
loadable.dataSpec.uri,
C.DATA_TYPE_MEDIA,
C.TRACK_TYPE_UNKNOWN,
/* trackFormat= */ null,

View file

@ -28,6 +28,9 @@ import com.google.android.exoplayer2.source.MediaSource.MediaPeriodId;
import com.google.android.exoplayer2.upstream.DataSpec;
import com.google.android.exoplayer2.util.Assertions;
import java.io.IOException;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.concurrent.CopyOnWriteArrayList;
/** Interface for callbacks to be notified of {@link MediaSource} events. */
@ -44,6 +47,8 @@ public interface MediaSourceEventListener {
* after redirection.
*/
public final Uri uri;
/** The response headers associated with the load, or an empty map if unavailable. */
public final Map<String, List<String>> responseHeaders;
/** 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. */
@ -58,6 +63,8 @@ public interface MediaSourceEventListener {
* @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 responseHeaders The response headers associated with the load, or an empty map if
* unavailable.
* @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.
@ -65,9 +72,15 @@ public interface MediaSourceEventListener {
* network responses, this is the decompressed size.
*/
public LoadEventInfo(
DataSpec dataSpec, Uri uri, long elapsedRealtimeMs, long loadDurationMs, long bytesLoaded) {
DataSpec dataSpec,
Uri uri,
Map<String, List<String>> responseHeaders,
long elapsedRealtimeMs,
long loadDurationMs,
long bytesLoaded) {
this.dataSpec = dataSpec;
this.uri = uri;
this.responseHeaders = responseHeaders;
this.elapsedRealtimeMs = elapsedRealtimeMs;
this.loadDurationMs = loadDurationMs;
this.bytesLoaded = bytesLoaded;
@ -168,7 +181,8 @@ public interface MediaSourceEventListener {
* @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} corresponding to the event. The value of {@link
* LoadEventInfo#uri} won't reflect potential redirection yet.
* LoadEventInfo#uri} won't reflect potential redirection yet and {@link
* LoadEventInfo#responseHeaders} will be empty.
* @param mediaLoadData The {@link MediaLoadData} defining the data being loaded.
*/
void onLoadStarted(
@ -370,10 +384,9 @@ public interface MediaSourceEventListener {
}
/** Dispatches {@link #onLoadStarted(int, MediaPeriodId, LoadEventInfo, MediaLoadData)}. */
public void loadStarted(DataSpec dataSpec, Uri uri, int dataType, long elapsedRealtimeMs) {
public void loadStarted(DataSpec dataSpec, int dataType, long elapsedRealtimeMs) {
loadStarted(
dataSpec,
uri,
dataType,
C.TRACK_TYPE_UNKNOWN,
null,
@ -387,7 +400,6 @@ public interface MediaSourceEventListener {
/** Dispatches {@link #onLoadStarted(int, MediaPeriodId, LoadEventInfo, MediaLoadData)}. */
public void loadStarted(
DataSpec dataSpec,
Uri uri,
int dataType,
int trackType,
@Nullable Format trackFormat,
@ -398,7 +410,12 @@ public interface MediaSourceEventListener {
long elapsedRealtimeMs) {
loadStarted(
new LoadEventInfo(
dataSpec, uri, elapsedRealtimeMs, /* loadDurationMs= */ 0, /* bytesLoaded= */ 0),
dataSpec,
dataSpec.uri,
/* responseHeaders= */ Collections.emptyMap(),
elapsedRealtimeMs,
/* loadDurationMs= */ 0,
/* bytesLoaded= */ 0),
new MediaLoadData(
dataType,
trackType,
@ -423,6 +440,7 @@ public interface MediaSourceEventListener {
public void loadCompleted(
DataSpec dataSpec,
Uri uri,
Map<String, List<String>> responseHeaders,
int dataType,
long elapsedRealtimeMs,
long loadDurationMs,
@ -430,6 +448,7 @@ public interface MediaSourceEventListener {
loadCompleted(
dataSpec,
uri,
responseHeaders,
dataType,
C.TRACK_TYPE_UNKNOWN,
null,
@ -446,6 +465,7 @@ public interface MediaSourceEventListener {
public void loadCompleted(
DataSpec dataSpec,
Uri uri,
Map<String, List<String>> responseHeaders,
int dataType,
int trackType,
@Nullable Format trackFormat,
@ -457,7 +477,8 @@ public interface MediaSourceEventListener {
long loadDurationMs,
long bytesLoaded) {
loadCompleted(
new LoadEventInfo(dataSpec, uri, elapsedRealtimeMs, loadDurationMs, bytesLoaded),
new LoadEventInfo(
dataSpec, uri, responseHeaders, elapsedRealtimeMs, loadDurationMs, bytesLoaded),
new MediaLoadData(
dataType,
trackType,
@ -483,6 +504,7 @@ public interface MediaSourceEventListener {
public void loadCanceled(
DataSpec dataSpec,
Uri uri,
Map<String, List<String>> responseHeaders,
int dataType,
long elapsedRealtimeMs,
long loadDurationMs,
@ -490,6 +512,7 @@ public interface MediaSourceEventListener {
loadCanceled(
dataSpec,
uri,
responseHeaders,
dataType,
C.TRACK_TYPE_UNKNOWN,
null,
@ -506,6 +529,7 @@ public interface MediaSourceEventListener {
public void loadCanceled(
DataSpec dataSpec,
Uri uri,
Map<String, List<String>> responseHeaders,
int dataType,
int trackType,
@Nullable Format trackFormat,
@ -517,7 +541,8 @@ public interface MediaSourceEventListener {
long loadDurationMs,
long bytesLoaded) {
loadCanceled(
new LoadEventInfo(dataSpec, uri, elapsedRealtimeMs, loadDurationMs, bytesLoaded),
new LoadEventInfo(
dataSpec, uri, responseHeaders, elapsedRealtimeMs, loadDurationMs, bytesLoaded),
new MediaLoadData(
dataType,
trackType,
@ -546,6 +571,7 @@ public interface MediaSourceEventListener {
public void loadError(
DataSpec dataSpec,
Uri uri,
Map<String, List<String>> responseHeaders,
int dataType,
long elapsedRealtimeMs,
long loadDurationMs,
@ -555,6 +581,7 @@ public interface MediaSourceEventListener {
loadError(
dataSpec,
uri,
responseHeaders,
dataType,
C.TRACK_TYPE_UNKNOWN,
null,
@ -576,6 +603,7 @@ public interface MediaSourceEventListener {
public void loadError(
DataSpec dataSpec,
Uri uri,
Map<String, List<String>> responseHeaders,
int dataType,
int trackType,
@Nullable Format trackFormat,
@ -589,7 +617,8 @@ public interface MediaSourceEventListener {
IOException error,
boolean wasCanceled) {
loadError(
new LoadEventInfo(dataSpec, uri, elapsedRealtimeMs, loadDurationMs, bytesLoaded),
new LoadEventInfo(
dataSpec, uri, responseHeaders, elapsedRealtimeMs, loadDurationMs, bytesLoaded),
new MediaLoadData(
dataType,
trackType,

View file

@ -155,7 +155,6 @@ import java.util.Arrays;
loadErrorHandlingPolicy.getMinimumLoadableRetryCount(C.DATA_TYPE_MEDIA));
eventDispatcher.loadStarted(
dataSpec,
dataSpec.uri,
C.DATA_TYPE_MEDIA,
C.TRACK_TYPE_UNKNOWN,
format,
@ -211,6 +210,7 @@ import java.util.Arrays;
eventDispatcher.loadCompleted(
loadable.dataSpec,
loadable.dataSource.getLastOpenedUri(),
loadable.dataSource.getLastResponseHeaders(),
C.DATA_TYPE_MEDIA,
C.TRACK_TYPE_UNKNOWN,
format,
@ -229,6 +229,7 @@ import java.util.Arrays;
eventDispatcher.loadCanceled(
loadable.dataSpec,
loadable.dataSource.getLastOpenedUri(),
loadable.dataSource.getLastResponseHeaders(),
C.DATA_TYPE_MEDIA,
C.TRACK_TYPE_UNKNOWN,
/* trackFormat= */ null,
@ -269,6 +270,7 @@ import java.util.Arrays;
eventDispatcher.loadError(
loadable.dataSpec,
loadable.dataSource.getLastOpenedUri(),
loadable.dataSource.getLastResponseHeaders(),
C.DATA_TYPE_MEDIA,
C.TRACK_TYPE_UNKNOWN,
format,

View file

@ -43,6 +43,7 @@ import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@ -556,6 +557,7 @@ public final class AdsMediaSource extends CompositeMediaSource<MediaPeriodId> {
.loadError(
dataSpec,
dataSpec.uri,
/* responseHeaders= */ Collections.emptyMap(),
C.DATA_TYPE_AD,
C.TRACK_TYPE_UNKNOWN,
/* loadDurationMs= */ 0,
@ -595,6 +597,7 @@ public final class AdsMediaSource extends CompositeMediaSource<MediaPeriodId> {
.loadError(
new DataSpec(adUri),
adUri,
/* responseHeaders= */ Collections.emptyMap(),
C.DATA_TYPE_AD,
C.TRACK_TYPE_UNKNOWN,
/* loadDurationMs= */ 0,

View file

@ -432,6 +432,7 @@ public class ChunkSampleStream<T extends ChunkSource> implements SampleStream, S
eventDispatcher.loadCompleted(
loadable.dataSpec,
loadable.getUri(),
loadable.getResponseHeaders(),
loadable.type,
primaryTrackType,
loadable.trackFormat,
@ -451,6 +452,7 @@ public class ChunkSampleStream<T extends ChunkSource> implements SampleStream, S
eventDispatcher.loadCanceled(
loadable.dataSpec,
loadable.getUri(),
loadable.getResponseHeaders(),
loadable.type,
primaryTrackType,
loadable.trackFormat,
@ -518,6 +520,7 @@ public class ChunkSampleStream<T extends ChunkSource> implements SampleStream, S
eventDispatcher.loadError(
loadable.dataSpec,
loadable.getUri(),
loadable.getResponseHeaders(),
loadable.type,
primaryTrackType,
loadable.trackFormat,
@ -585,7 +588,6 @@ public class ChunkSampleStream<T extends ChunkSource> implements SampleStream, S
loadable, this, loadErrorHandlingPolicy.getMinimumLoadableRetryCount(loadable.type));
eventDispatcher.loadStarted(
loadable.dataSpec,
loadable.dataSpec.uri,
loadable.type,
primaryTrackType,
loadable.trackFormat,

View file

@ -24,6 +24,8 @@ import com.google.android.exoplayer2.util.Assertions;
import com.google.android.exoplayer2.util.Util;
import java.io.IOException;
import java.io.InputStream;
import java.util.List;
import java.util.Map;
/**
* A {@link Loadable} for objects that can be parsed from binary data using a {@link Parser}.
@ -132,6 +134,14 @@ public final class ParsingLoadable<T> implements Loadable {
return dataSource.getLastOpenedUri();
}
/**
* Returns the response headers associated with the load. Must only be called after the load
* completed, failed, or was canceled.
*/
public Map<String, List<String>> getResponseHeaders() {
return dataSource.getLastResponseHeaders();
}
@Override
public final void cancelLoad() {
// Do nothing.

View file

@ -709,6 +709,7 @@ public final class DashMediaSource extends BaseMediaSource {
manifestEventDispatcher.loadCompleted(
loadable.dataSpec,
loadable.getUri(),
loadable.getResponseHeaders(),
loadable.type,
elapsedRealtimeMs,
loadDurationMs,
@ -800,6 +801,7 @@ public final class DashMediaSource extends BaseMediaSource {
manifestEventDispatcher.loadError(
loadable.dataSpec,
loadable.getUri(),
loadable.getResponseHeaders(),
loadable.type,
elapsedRealtimeMs,
loadDurationMs,
@ -814,6 +816,7 @@ public final class DashMediaSource extends BaseMediaSource {
manifestEventDispatcher.loadCompleted(
loadable.dataSpec,
loadable.getUri(),
loadable.getResponseHeaders(),
loadable.type,
elapsedRealtimeMs,
loadDurationMs,
@ -829,6 +832,7 @@ public final class DashMediaSource extends BaseMediaSource {
manifestEventDispatcher.loadError(
loadable.dataSpec,
loadable.getUri(),
loadable.getResponseHeaders(),
loadable.type,
elapsedRealtimeMs,
loadDurationMs,
@ -844,6 +848,7 @@ public final class DashMediaSource extends BaseMediaSource {
manifestEventDispatcher.loadCanceled(
loadable.dataSpec,
loadable.getUri(),
loadable.getResponseHeaders(),
loadable.type,
elapsedRealtimeMs,
loadDurationMs,
@ -1031,8 +1036,7 @@ public final class DashMediaSource extends BaseMediaSource {
private <T> void startLoading(ParsingLoadable<T> loadable,
Loader.Callback<ParsingLoadable<T>> callback, int minRetryCount) {
long elapsedRealtimeMs = loader.startLoading(loadable, callback, minRetryCount);
manifestEventDispatcher.loadStarted(
loadable.dataSpec, loadable.dataSpec.uri, loadable.type, elapsedRealtimeMs);
manifestEventDispatcher.loadStarted(loadable.dataSpec, loadable.type, elapsedRealtimeMs);
}
private long getNowUnixTimeUs() {

View file

@ -571,7 +571,6 @@ import java.util.List;
loadable, this, loadErrorHandlingPolicy.getMinimumLoadableRetryCount(loadable.type));
eventDispatcher.loadStarted(
loadable.dataSpec,
loadable.dataSpec.uri,
loadable.type,
trackType,
loadable.trackFormat,
@ -596,6 +595,7 @@ import java.util.List;
eventDispatcher.loadCompleted(
loadable.dataSpec,
loadable.getUri(),
loadable.getResponseHeaders(),
loadable.type,
trackType,
loadable.trackFormat,
@ -619,6 +619,7 @@ import java.util.List;
eventDispatcher.loadCanceled(
loadable.dataSpec,
loadable.getUri(),
loadable.getResponseHeaders(),
loadable.type,
trackType,
loadable.trackFormat,
@ -680,6 +681,7 @@ import java.util.List;
eventDispatcher.loadError(
loadable.dataSpec,
loadable.getUri(),
loadable.getResponseHeaders(),
loadable.type,
trackType,
loadable.trackFormat,

View file

@ -123,7 +123,6 @@ public final class DefaultHlsPlaylistTracker
loadErrorHandlingPolicy.getMinimumLoadableRetryCount(masterPlaylistLoadable.type));
eventDispatcher.loadStarted(
masterPlaylistLoadable.dataSpec,
masterPlaylistLoadable.dataSpec.uri,
masterPlaylistLoadable.type,
elapsedRealtime);
}
@ -234,6 +233,7 @@ public final class DefaultHlsPlaylistTracker
eventDispatcher.loadCompleted(
loadable.dataSpec,
loadable.getUri(),
loadable.getResponseHeaders(),
C.DATA_TYPE_MANIFEST,
elapsedRealtimeMs,
loadDurationMs,
@ -249,6 +249,7 @@ public final class DefaultHlsPlaylistTracker
eventDispatcher.loadCanceled(
loadable.dataSpec,
loadable.getUri(),
loadable.getResponseHeaders(),
C.DATA_TYPE_MANIFEST,
elapsedRealtimeMs,
loadDurationMs,
@ -269,6 +270,7 @@ public final class DefaultHlsPlaylistTracker
eventDispatcher.loadError(
loadable.dataSpec,
loadable.getUri(),
loadable.getResponseHeaders(),
C.DATA_TYPE_MANIFEST,
elapsedRealtimeMs,
loadDurationMs,
@ -496,6 +498,7 @@ public final class DefaultHlsPlaylistTracker
eventDispatcher.loadCompleted(
loadable.dataSpec,
loadable.getUri(),
loadable.getResponseHeaders(),
C.DATA_TYPE_MANIFEST,
elapsedRealtimeMs,
loadDurationMs,
@ -514,6 +517,7 @@ public final class DefaultHlsPlaylistTracker
eventDispatcher.loadCanceled(
loadable.dataSpec,
loadable.getUri(),
loadable.getResponseHeaders(),
C.DATA_TYPE_MANIFEST,
elapsedRealtimeMs,
loadDurationMs,
@ -555,6 +559,7 @@ public final class DefaultHlsPlaylistTracker
eventDispatcher.loadError(
loadable.dataSpec,
loadable.getUri(),
loadable.getResponseHeaders(),
C.DATA_TYPE_MANIFEST,
elapsedRealtimeMs,
loadDurationMs,
@ -583,7 +588,6 @@ public final class DefaultHlsPlaylistTracker
loadErrorHandlingPolicy.getMinimumLoadableRetryCount(mediaPlaylistLoadable.type));
eventDispatcher.loadStarted(
mediaPlaylistLoadable.dataSpec,
mediaPlaylistLoadable.dataSpec.uri,
mediaPlaylistLoadable.type,
elapsedRealtime);
}

View file

@ -569,6 +569,7 @@ public final class SsMediaSource extends BaseMediaSource
manifestEventDispatcher.loadCompleted(
loadable.dataSpec,
loadable.getUri(),
loadable.getResponseHeaders(),
loadable.type,
elapsedRealtimeMs,
loadDurationMs,
@ -585,6 +586,7 @@ public final class SsMediaSource extends BaseMediaSource
manifestEventDispatcher.loadCanceled(
loadable.dataSpec,
loadable.getUri(),
loadable.getResponseHeaders(),
loadable.type,
elapsedRealtimeMs,
loadDurationMs,
@ -602,6 +604,7 @@ public final class SsMediaSource extends BaseMediaSource
manifestEventDispatcher.loadError(
loadable.dataSpec,
loadable.getUri(),
loadable.getResponseHeaders(),
loadable.type,
elapsedRealtimeMs,
loadDurationMs,
@ -692,8 +695,7 @@ public final class SsMediaSource extends BaseMediaSource
long elapsedRealtimeMs =
manifestLoader.startLoading(
loadable, this, loadErrorHandlingPolicy.getMinimumLoadableRetryCount(loadable.type));
manifestEventDispatcher.loadStarted(
loadable.dataSpec, loadable.dataSpec.uri, loadable.type, elapsedRealtimeMs);
manifestEventDispatcher.loadStarted(loadable.dataSpec, loadable.type, elapsedRealtimeMs);
}
}

View file

@ -31,6 +31,7 @@ import com.google.android.exoplayer2.source.TrackGroupArray;
import com.google.android.exoplayer2.trackselection.TrackSelection;
import com.google.android.exoplayer2.upstream.DataSpec;
import java.io.IOException;
import java.util.Collections;
/**
* Fake {@link MediaPeriod} that provides tracks from the given {@link TrackGroupArray}. Selecting
@ -115,7 +116,6 @@ 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,
@ -228,6 +228,7 @@ public class FakeMediaPeriod implements MediaPeriod {
eventDispatcher.loadCompleted(
FAKE_DATA_SPEC,
FAKE_DATA_SPEC.uri,
/* responseHeaders= */ Collections.emptyMap(),
C.DATA_TYPE_MEDIA,
C.TRACK_TYPE_UNKNOWN,
/* trackFormat= */ null,

View file

@ -40,6 +40,7 @@ import com.google.android.exoplayer2.upstream.TransferListener;
import com.google.android.exoplayer2.util.Assertions;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
/**
@ -225,6 +226,7 @@ public class FakeMediaSource extends BaseMediaSource {
new LoadEventInfo(
FAKE_DATA_SPEC,
FAKE_DATA_SPEC.uri,
/* responseHeaders= */ Collections.emptyMap(),
elapsedRealTimeMs,
/* loadDurationMs= */ 0,
/* bytesLoaded= */ 0),
@ -233,6 +235,7 @@ public class FakeMediaSource extends BaseMediaSource {
new LoadEventInfo(
FAKE_DATA_SPEC,
FAKE_DATA_SPEC.uri,
/* responseHeaders= */ Collections.emptyMap(),
elapsedRealTimeMs,
/* loadDurationMs= */ 0,
/* bytesLoaded= */ MANIFEST_LOAD_BYTES),