Add getMediaItem() to MediaSource

This change adds MediaSource.getMediaItem and deprecates MediaSource.getTag. For backwards compatibility, the tag is made available through the Window with `mediaItem.playbackProperties.tag` as well as in the deprecated `tag` attribute.

PiperOrigin-RevId: 316539752
This commit is contained in:
bachinger 2020-06-15 22:03:22 +01:00 committed by Andrew Lewis
parent 9719b66d20
commit 5b28cb5209
18 changed files with 165 additions and 27 deletions

View file

@ -18,6 +18,7 @@ package com.google.android.exoplayer2.source;
import androidx.annotation.IntDef;
import androidx.annotation.Nullable;
import com.google.android.exoplayer2.C;
import com.google.android.exoplayer2.MediaItem;
import com.google.android.exoplayer2.Timeline;
import com.google.android.exoplayer2.upstream.Allocator;
import com.google.android.exoplayer2.upstream.TransferListener;
@ -184,12 +185,22 @@ public final class ClippingMediaSource extends CompositeMediaSource<Void> {
window = new Timeline.Window();
}
/**
* @deprecated Use {@link #getMediaItem()} and {@link MediaItem.PlaybackProperties#tag} instead.
*/
@SuppressWarnings("deprecation")
@Deprecated
@Override
@Nullable
public Object getTag() {
return mediaSource.getTag();
}
@Override
public MediaItem getMediaItem() {
return mediaSource.getMediaItem();
}
@Override
protected void prepareSourceInternal(@Nullable TransferListener mediaTransferListener) {
super.prepareSourceInternal(mediaTransferListener);

View file

@ -442,7 +442,7 @@ public final class ConcatenatingMediaSource extends CompositeMediaSource<MediaSo
// CompositeMediaSource implementation.
// TODO(bachinger): add @Override annotation once the method is defined by MediaSource.
@Override
public MediaItem getMediaItem() {
// This method is actually never called because getInitialTimeline is implemented and hence the
// MaskingMediaSource does not need to create a dummy timeline for this media source.
@ -996,7 +996,7 @@ public final class ConcatenatingMediaSource extends CompositeMediaSource<MediaSo
// Do nothing.
}
// TODO(bachinger): add @Override annotation once the method is defined by MediaSource.
@Override
public MediaItem getMediaItem() {
return DUMMY_MEDIA_ITEM;
}

View file

@ -333,12 +333,22 @@ public final class ExtractorMediaSource extends CompositeMediaSource<Void> {
continueLoadingCheckIntervalBytes);
}
/**
* @deprecated Use {@link #getMediaItem()} and {@link MediaItem.PlaybackProperties#tag} instead.
*/
@SuppressWarnings("deprecation")
@Deprecated
@Override
@Nullable
public Object getTag() {
return progressiveMediaSource.getTag();
}
@Override
public MediaItem getMediaItem() {
return progressiveMediaSource.getMediaItem();
}
@Override
protected void prepareSourceInternal(@Nullable TransferListener mediaTransferListener) {
super.prepareSourceInternal(mediaTransferListener);

View file

@ -19,6 +19,7 @@ import androidx.annotation.Nullable;
import com.google.android.exoplayer2.AbstractConcatenatedTimeline;
import com.google.android.exoplayer2.C;
import com.google.android.exoplayer2.ExoPlayer;
import com.google.android.exoplayer2.MediaItem;
import com.google.android.exoplayer2.Player;
import com.google.android.exoplayer2.Timeline;
import com.google.android.exoplayer2.source.ShuffleOrder.UnshuffledShuffleOrder;
@ -65,12 +66,22 @@ public final class LoopingMediaSource extends CompositeMediaSource<Void> {
mediaPeriodToChildMediaPeriodId = new HashMap<>();
}
/**
* @deprecated Use {@link #getMediaItem()} and {@link MediaItem.PlaybackProperties#tag} instead.
*/
@SuppressWarnings("deprecation")
@Deprecated
@Override
@Nullable
public Object getTag() {
return maskingMediaSource.getTag();
}
@Override
public MediaItem getMediaItem() {
return maskingMediaSource.getMediaItem();
}
@Override
@Nullable
public Timeline getInitialTimeline() {

View file

@ -15,7 +15,6 @@
*/
package com.google.android.exoplayer2.source;
import android.net.Uri;
import android.util.Pair;
import androidx.annotation.Nullable;
import androidx.annotation.VisibleForTesting;
@ -68,10 +67,7 @@ public final class MaskingMediaSource extends CompositeMediaSource<Void> {
initialTimeline, /* firstWindowUid= */ null, /* firstPeriodUid= */ null);
hasRealTimeline = true;
} else {
// TODO(bachinger) Use mediasSource.getMediaItem() to provide the media item.
timeline =
MaskingTimeline.createWithDummyTimeline(
new MediaItem.Builder().setUri(Uri.EMPTY).setTag(mediaSource.getTag()).build());
timeline = MaskingTimeline.createWithDummyTimeline(mediaSource.getMediaItem());
}
}
@ -89,12 +85,22 @@ public final class MaskingMediaSource extends CompositeMediaSource<Void> {
}
}
/**
* @deprecated Use {@link #getMediaItem()} and {@link MediaItem.PlaybackProperties#tag} instead.
*/
@SuppressWarnings("deprecation")
@Deprecated
@Override
@Nullable
public Object getTag() {
return mediaSource.getTag();
}
@Override
public MediaItem getMediaItem() {
return mediaSource.getMediaItem();
}
@Override
@SuppressWarnings("MissingSuperCall")
public void maybeThrowSourceInfoRefreshError() {

View file

@ -18,6 +18,7 @@ package com.google.android.exoplayer2.source;
import android.os.Handler;
import androidx.annotation.Nullable;
import com.google.android.exoplayer2.C;
import com.google.android.exoplayer2.MediaItem;
import com.google.android.exoplayer2.Timeline;
import com.google.android.exoplayer2.drm.DrmSessionEventListener;
import com.google.android.exoplayer2.upstream.Allocator;
@ -273,12 +274,18 @@ public interface MediaSource {
return true;
}
/** Returns the tag set on the media source, or null if none was set. */
/**
* @deprecated Use {@link #getMediaItem()} and {@link MediaItem.PlaybackProperties#tag} instead.
*/
@Deprecated
@Nullable
default Object getTag() {
return null;
}
/** Returns the {@link MediaItem} whose media is provided by the source. */
MediaItem getMediaItem();
/**
* Registers a {@link MediaSourceCaller}. Starts source preparation if needed and enables the
* source for the creation of {@link MediaPeriod MediaPerods}.

View file

@ -17,6 +17,7 @@ package com.google.android.exoplayer2.source;
import androidx.annotation.IntDef;
import androidx.annotation.Nullable;
import com.google.android.exoplayer2.MediaItem;
import com.google.android.exoplayer2.Timeline;
import com.google.android.exoplayer2.upstream.Allocator;
import com.google.android.exoplayer2.upstream.TransferListener;
@ -65,6 +66,8 @@ public final class MergingMediaSource extends CompositeMediaSource<Integer> {
}
private static final int PERIOD_COUNT_UNSET = -1;
private static final MediaItem DUMMY_MEDIA_ITEM =
new MediaItem.Builder().setMediaId("MergingMediaSource").build();
private final boolean adjustPeriodTimeOffsets;
private final MediaSource[] mediaSources;
@ -121,12 +124,22 @@ public final class MergingMediaSource extends CompositeMediaSource<Integer> {
periodTimeOffsetsUs = new long[0][];
}
/**
* @deprecated Use {@link #getMediaItem()} and {@link MediaItem.PlaybackProperties#tag} instead.
*/
@SuppressWarnings("deprecation")
@Deprecated
@Override
@Nullable
public Object getTag() {
return mediaSources.length > 0 ? mediaSources[0].getTag() : null;
}
@Override
public MediaItem getMediaItem() {
return mediaSources.length > 0 ? mediaSources[0].getMediaItem() : DUMMY_MEDIA_ITEM;
}
@Override
protected void prepareSourceInternal(@Nullable TransferListener mediaTransferListener) {
super.prepareSourceInternal(mediaTransferListener);

View file

@ -244,14 +244,19 @@ public final class ProgressiveMediaSource extends BaseMediaSource
this.timelineDurationUs = C.TIME_UNSET;
}
/**
* @deprecated Use {@link #getMediaItem()} and {@link MediaItem.PlaybackProperties#tag} instead.
*/
@SuppressWarnings("deprecation")
@Deprecated
@Override
@Nullable
public Object getTag() {
return playbackProperties.tag;
}
@Nullable
public Object getMediaItem() {
@Override
public MediaItem getMediaItem() {
return mediaItem;
}

View file

@ -77,7 +77,7 @@ public final class SilenceMediaSource extends BaseMediaSource {
}
/** The media id used by any media item of silence media sources. */
public static final String MEDIA_ID = "com.google.android.exoplayer2.source.SilenceMediaSource";
public static final String MEDIA_ID = "SilenceMediaSource";
private static final int SAMPLE_RATE_HZ = 44100;
@C.PcmEncoding private static final int PCM_ENCODING = C.ENCODING_PCM_16BIT;
@ -145,18 +145,22 @@ public final class SilenceMediaSource extends BaseMediaSource {
@Override
public void releasePeriod(MediaPeriod mediaPeriod) {}
/** Returns the {@link MediaItem} of this media source. */
// TODO(bachinger): add @Override annotation once the method is defined by MediaSource.
public MediaItem getMediaItem() {
return mediaItem;
}
/**
* @deprecated Use {@link #getMediaItem()} and {@link MediaItem.PlaybackProperties#tag} instead.
*/
@SuppressWarnings("deprecation")
@Deprecated
@Nullable
@Override
public Object getTag() {
return Assertions.checkNotNull(mediaItem.playbackProperties).tag;
}
@Override
public MediaItem getMediaItem() {
return mediaItem;
}
@Override
protected void releaseSourceInternal() {}

View file

@ -294,13 +294,18 @@ public final class SingleSampleMediaSource extends BaseMediaSource {
// MediaSource implementation.
/**
* @deprecated Use {@link #getMediaItem()} and {@link MediaItem.PlaybackProperties#tag} instead.
*/
@SuppressWarnings("deprecation")
@Deprecated
@Override
@Nullable
public Object getTag() {
return castNonNull(mediaItem.playbackProperties).tag;
}
// TODO(bachinger) Add @Override annotation once the method is defined by MediaSource.
@Override
public MediaItem getMediaItem() {
return mediaItem;
}

View file

@ -22,6 +22,7 @@ import android.os.SystemClock;
import androidx.annotation.IntDef;
import androidx.annotation.Nullable;
import com.google.android.exoplayer2.C;
import com.google.android.exoplayer2.MediaItem;
import com.google.android.exoplayer2.Timeline;
import com.google.android.exoplayer2.source.CompositeMediaSource;
import com.google.android.exoplayer2.source.LoadEventInfo;
@ -181,12 +182,22 @@ public final class AdsMediaSource extends CompositeMediaSource<MediaPeriodId> {
adsLoader.setSupportedContentTypes(adMediaSourceFactory.getSupportedTypes());
}
/**
* @deprecated Use {@link #getMediaItem()} and {@link MediaItem.PlaybackProperties#tag} instead.
*/
@SuppressWarnings("deprecation")
@Deprecated
@Override
@Nullable
public Object getTag() {
return contentMediaSource.getTag();
}
@Override
public MediaItem getMediaItem() {
return contentMediaSource.getMediaItem();
}
@Override
protected void prepareSourceInternal(@Nullable TransferListener mediaTransferListener) {
super.prepareSourceInternal(mediaTransferListener);

View file

@ -140,7 +140,7 @@ public final class ExoPlayerTest {
public void playEmptyTimeline() throws Exception {
Timeline timeline = Timeline.EMPTY;
Timeline expectedMaskingTimeline =
new MaskingMediaSource.DummyTimeline(FakeTimeline.FAKE_MEDIA_ITEM);
new MaskingMediaSource.DummyTimeline(FakeMediaSource.FAKE_MEDIA_ITEM);
FakeRenderer renderer = new FakeRenderer(C.TRACK_TYPE_UNKNOWN);
ExoPlayerTestRunner testRunner =
new ExoPlayerTestRunner.Builder(context)
@ -3445,6 +3445,11 @@ public final class ExoPlayerTest {
return false;
}
@Override
public MediaItem getMediaItem() {
return underlyingSource.getMediaItem();
}
@Override
@Nullable
public Timeline getInitialTimeline() {

View file

@ -23,6 +23,7 @@ import static org.mockito.ArgumentMatchers.isNull;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import androidx.test.ext.junit.runners.AndroidJUnit4;
import com.google.android.exoplayer2.source.MediaSource;
@ -42,6 +43,8 @@ import org.junit.runner.RunWith;
public class MediaSourceListTest {
private static final int MEDIA_SOURCE_LIST_SIZE = 4;
private static final MediaItem MINIMAL_MEDIA_ITEM =
new MediaItem.Builder().setMediaId("").build();
private MediaSourceList mediaSourceList;
@ -76,7 +79,9 @@ public class MediaSourceListTest {
@Test
public void prepareAndReprepareAfterRelease_expectSourcePreparationAfterMediaSourceListPrepare() {
MediaSource mockMediaSource1 = mock(MediaSource.class);
when(mockMediaSource1.getMediaItem()).thenReturn(MINIMAL_MEDIA_ITEM);
MediaSource mockMediaSource2 = mock(MediaSource.class);
when(mockMediaSource2.getMediaItem()).thenReturn(MINIMAL_MEDIA_ITEM);
mediaSourceList.setMediaSources(
createFakeHoldersWithSources(
/* useLazyPreparation= */ false, mockMediaSource1, mockMediaSource2),
@ -115,7 +120,9 @@ public class MediaSourceListTest {
ShuffleOrder.DefaultShuffleOrder shuffleOrder =
new ShuffleOrder.DefaultShuffleOrder(/* length= */ 2);
MediaSource mockMediaSource1 = mock(MediaSource.class);
when(mockMediaSource1.getMediaItem()).thenReturn(MINIMAL_MEDIA_ITEM);
MediaSource mockMediaSource2 = mock(MediaSource.class);
when(mockMediaSource2.getMediaItem()).thenReturn(MINIMAL_MEDIA_ITEM);
List<MediaSourceList.MediaSourceHolder> mediaSources =
createFakeHoldersWithSources(
/* useLazyPreparation= */ false, mockMediaSource1, mockMediaSource2);
@ -132,8 +139,10 @@ public class MediaSourceListTest {
}
// Set media items again. The second holder is re-used.
MediaSource mockMediaSource3 = mock(MediaSource.class);
when(mockMediaSource3.getMediaItem()).thenReturn(MINIMAL_MEDIA_ITEM);
List<MediaSourceList.MediaSourceHolder> moreMediaSources =
createFakeHoldersWithSources(/* useLazyPreparation= */ false, mock(MediaSource.class));
createFakeHoldersWithSources(/* useLazyPreparation= */ false, mockMediaSource3);
moreMediaSources.add(mediaSources.get(1));
timeline = mediaSourceList.setMediaSources(moreMediaSources, shuffleOrder);
@ -157,7 +166,9 @@ public class MediaSourceListTest {
ShuffleOrder.DefaultShuffleOrder shuffleOrder =
new ShuffleOrder.DefaultShuffleOrder(/* length= */ 2);
MediaSource mockMediaSource1 = mock(MediaSource.class);
when(mockMediaSource1.getMediaItem()).thenReturn(MINIMAL_MEDIA_ITEM);
MediaSource mockMediaSource2 = mock(MediaSource.class);
when(mockMediaSource2.getMediaItem()).thenReturn(MINIMAL_MEDIA_ITEM);
List<MediaSourceList.MediaSourceHolder> mediaSources =
createFakeHoldersWithSources(
/* useLazyPreparation= */ false, mockMediaSource1, mockMediaSource2);
@ -174,8 +185,10 @@ public class MediaSourceListTest {
any(MediaSource.MediaSourceCaller.class), /* mediaTransferListener= */ isNull());
// Set media items again. The second holder is re-used.
MediaSource mockMediaSource3 = mock(MediaSource.class);
when(mockMediaSource3.getMediaItem()).thenReturn(MINIMAL_MEDIA_ITEM);
List<MediaSourceList.MediaSourceHolder> moreMediaSources =
createFakeHoldersWithSources(/* useLazyPreparation= */ false, mock(MediaSource.class));
createFakeHoldersWithSources(/* useLazyPreparation= */ false, mockMediaSource3);
moreMediaSources.add(mediaSources.get(1));
mediaSourceList.setMediaSources(moreMediaSources, shuffleOrder);
@ -193,7 +206,9 @@ public class MediaSourceListTest {
@Test
public void addMediaSources_mediaSourceListUnprepared_notUsingLazyPreparation_expectUnprepared() {
MediaSource mockMediaSource1 = mock(MediaSource.class);
when(mockMediaSource1.getMediaItem()).thenReturn(MINIMAL_MEDIA_ITEM);
MediaSource mockMediaSource2 = mock(MediaSource.class);
when(mockMediaSource2.getMediaItem()).thenReturn(MINIMAL_MEDIA_ITEM);
List<MediaSourceList.MediaSourceHolder> mediaSources =
createFakeHoldersWithSources(
/* useLazyPreparation= */ false, mockMediaSource1, mockMediaSource2);
@ -228,7 +243,9 @@ public class MediaSourceListTest {
@Test
public void addMediaSources_mediaSourceListPrepared_notUsingLazyPreparation_expectPrepared() {
MediaSource mockMediaSource1 = mock(MediaSource.class);
when(mockMediaSource1.getMediaItem()).thenReturn(MINIMAL_MEDIA_ITEM);
MediaSource mockMediaSource2 = mock(MediaSource.class);
when(mockMediaSource2.getMediaItem()).thenReturn(MINIMAL_MEDIA_ITEM);
mediaSourceList.prepare(/* mediaTransferListener= */ null);
mediaSourceList.addMediaSources(
/* index= */ 0,
@ -287,9 +304,13 @@ public class MediaSourceListTest {
@Test
public void removeMediaSources_whenUnprepared_expectNoRelease() {
MediaSource mockMediaSource1 = mock(MediaSource.class);
when(mockMediaSource1.getMediaItem()).thenReturn(MINIMAL_MEDIA_ITEM);
MediaSource mockMediaSource2 = mock(MediaSource.class);
when(mockMediaSource2.getMediaItem()).thenReturn(MINIMAL_MEDIA_ITEM);
MediaSource mockMediaSource3 = mock(MediaSource.class);
when(mockMediaSource3.getMediaItem()).thenReturn(MINIMAL_MEDIA_ITEM);
MediaSource mockMediaSource4 = mock(MediaSource.class);
when(mockMediaSource4.getMediaItem()).thenReturn(MINIMAL_MEDIA_ITEM);
ShuffleOrder.DefaultShuffleOrder shuffleOrder =
new ShuffleOrder.DefaultShuffleOrder(/* length= */ 4);
@ -319,9 +340,13 @@ public class MediaSourceListTest {
@Test
public void removeMediaSources_whenPrepared_expectRelease() {
MediaSource mockMediaSource1 = mock(MediaSource.class);
when(mockMediaSource1.getMediaItem()).thenReturn(MINIMAL_MEDIA_ITEM);
MediaSource mockMediaSource2 = mock(MediaSource.class);
when(mockMediaSource2.getMediaItem()).thenReturn(MINIMAL_MEDIA_ITEM);
MediaSource mockMediaSource3 = mock(MediaSource.class);
when(mockMediaSource3.getMediaItem()).thenReturn(MINIMAL_MEDIA_ITEM);
MediaSource mockMediaSource4 = mock(MediaSource.class);
when(mockMediaSource4.getMediaItem()).thenReturn(MINIMAL_MEDIA_ITEM);
ShuffleOrder.DefaultShuffleOrder shuffleOrder =
new ShuffleOrder.DefaultShuffleOrder(/* length= */ 4);
@ -350,6 +375,7 @@ public class MediaSourceListTest {
@Test
public void release_mediaSourceListUnprepared_expectSourcesNotReleased() {
MediaSource mockMediaSource = mock(MediaSource.class);
when(mockMediaSource.getMediaItem()).thenReturn(MINIMAL_MEDIA_ITEM);
MediaSourceList.MediaSourceHolder mediaSourceHolder =
new MediaSourceList.MediaSourceHolder(mockMediaSource, /* useLazyPreparation= */ false);
@ -367,6 +393,7 @@ public class MediaSourceListTest {
@Test
public void release_mediaSourceListPrepared_expectSourcesReleasedNotRemoved() {
MediaSource mockMediaSource = mock(MediaSource.class);
when(mockMediaSource.getMediaItem()).thenReturn(MINIMAL_MEDIA_ITEM);
MediaSourceList.MediaSourceHolder mediaSourceHolder =
new MediaSourceList.MediaSourceHolder(mockMediaSource, /* useLazyPreparation= */ false);
@ -387,7 +414,9 @@ public class MediaSourceListTest {
ShuffleOrder.DefaultShuffleOrder shuffleOrder =
new ShuffleOrder.DefaultShuffleOrder(/* length= */ 4);
MediaSource mockMediaSource1 = mock(MediaSource.class);
when(mockMediaSource1.getMediaItem()).thenReturn(MINIMAL_MEDIA_ITEM);
MediaSource mockMediaSource2 = mock(MediaSource.class);
when(mockMediaSource2.getMediaItem()).thenReturn(MINIMAL_MEDIA_ITEM);
List<MediaSourceList.MediaSourceHolder> holders =
createFakeHoldersWithSources(
/* useLazyPreparation= */ false, mockMediaSource1, mockMediaSource2);

View file

@ -655,13 +655,18 @@ public final class DashMediaSource extends BaseMediaSource {
// MediaSource implementation.
/**
* @deprecated Use {@link #getMediaItem()} and {@link MediaItem.PlaybackProperties#tag} instead.
*/
@SuppressWarnings("deprecation")
@Deprecated
@Override
@Nullable
public Object getTag() {
return playbackProperties.tag;
}
// TODO(bachinger): add @Override annotation once the method is defined by MediaSource.
@Override
public MediaItem getMediaItem() {
return mediaItem;
}

View file

@ -425,13 +425,18 @@ public final class HlsMediaSource extends BaseMediaSource
this.useSessionKeys = useSessionKeys;
}
/**
* @deprecated Use {@link #getMediaItem()} and {@link MediaItem.PlaybackProperties#tag} instead.
*/
@SuppressWarnings("deprecation")
@Deprecated
@Override
@Nullable
public Object getTag() {
return playbackProperties.tag;
}
// TODO(bachinger): add @Override annotation once the method is defined by MediaSource.
@Override
public MediaItem getMediaItem() {
return mediaItem;
}

View file

@ -593,13 +593,18 @@ public final class SsMediaSource extends BaseMediaSource
// MediaSource implementation.
/**
* @deprecated Use {@link #getMediaItem()} and {@link MediaItem.PlaybackProperties#tag} instead.
*/
@SuppressWarnings("deprecation")
@Deprecated
@Override
@Nullable
public Object getTag() {
return playbackProperties.tag;
}
// TODO(bachinger): add @Override annotation once the method is defined by MediaSource.
@Override
public MediaItem getMediaItem() {
return mediaItem;
}

View file

@ -71,7 +71,7 @@ public class FakeMediaSource extends BaseMediaSource {
/** The media item used by the fake media source. */
public static final MediaItem FAKE_MEDIA_ITEM =
new MediaItem.Builder().setUri("http://manifest.uri").build();
new MediaItem.Builder().setMediaId("FakeMediaSource").setUri("http://manifest.uri").build();
private static final DataSpec FAKE_DATA_SPEC =
new DataSpec(castNonNull(FAKE_MEDIA_ITEM.playbackProperties).uri);
@ -134,6 +134,11 @@ public class FakeMediaSource extends BaseMediaSource {
return timeline;
}
/**
* @deprecated Use {@link #getMediaItem()} and {@link MediaItem.PlaybackProperties#tag} instead.
*/
@SuppressWarnings("deprecation")
@Deprecated
@Override
@Nullable
public Object getTag() {
@ -143,7 +148,7 @@ public class FakeMediaSource extends BaseMediaSource {
return timeline.getWindow(0, new Timeline.Window()).tag;
}
// TODO(bachinger): add @Override annotation once the method is defined by MediaSource.
@Override
public MediaItem getMediaItem() {
if (timeline == null || timeline.isEmpty()) {
return FAKE_MEDIA_ITEM;

View file

@ -184,7 +184,8 @@ public final class FakeTimeline extends Timeline {
}
/** The fake media item used by the fake timeline. */
public static final MediaItem FAKE_MEDIA_ITEM = new MediaItem.Builder().setUri(Uri.EMPTY).build();
public static final MediaItem FAKE_MEDIA_ITEM =
new MediaItem.Builder().setMediaId("FakeTimeline").setUri(Uri.EMPTY).build();
private static final long AD_DURATION_US = 10 * C.MICROS_PER_SECOND;