mirror of
https://github.com/samsonjs/media.git
synced 2026-04-02 10:45:51 +00:00
add manifest to Timeline.Window
- Remove manifest argument from callbacks of Player.EventListener and SourceInfoRefreshListener. Instead make it accessible through Player.getCurrentManifest() and Timeline.Window.manifest. - Fix all MediaSource implementation to include the manifest in the Timeline instead of passing it to the SourceInfoRefreshListener. - Refactor ExoPlayerTestRunner, FakeTimeline, FakeMediaSource to reflect these changes and make tests pass. PiperOrigin-RevId: 257359662
This commit is contained in:
parent
877923ce5f
commit
49a2e5a5cb
53 changed files with 316 additions and 330 deletions
|
|
@ -15,6 +15,9 @@
|
|||
* Add VR player demo.
|
||||
* Wrap decoder exceptions in a new `DecoderException` class and report as
|
||||
renderer error.
|
||||
* Do not pass the manifest to callbacks of Player.EventListener and
|
||||
SourceInfoRefreshListener anymore. Instead make it accessible through
|
||||
Player.getCurrentManifest() and Timeline.Window.manifest.
|
||||
|
||||
### 2.10.3 ###
|
||||
|
||||
|
|
|
|||
|
|
@ -264,8 +264,7 @@ import org.json.JSONObject;
|
|||
}
|
||||
|
||||
@Override
|
||||
public void onTimelineChanged(
|
||||
Timeline timeline, @Nullable Object manifest, @TimelineChangeReason int reason) {
|
||||
public void onTimelineChanged(Timeline timeline, @TimelineChangeReason int reason) {
|
||||
updateCurrentItemIndex();
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -460,11 +460,6 @@ public final class CastPlayer extends BasePlayer {
|
|||
return currentTimeline;
|
||||
}
|
||||
|
||||
@Override
|
||||
@Nullable public Object getCurrentManifest() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getCurrentPeriodIndex() {
|
||||
return getCurrentWindowIndex();
|
||||
|
|
@ -592,8 +587,7 @@ public final class CastPlayer extends BasePlayer {
|
|||
waitingForInitialTimeline = false;
|
||||
notificationsBatch.add(
|
||||
new ListenerNotificationTask(
|
||||
listener ->
|
||||
listener.onTimelineChanged(currentTimeline, /* manifest= */ null, reason)));
|
||||
listener -> listener.onTimelineChanged(currentTimeline, reason)));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -117,6 +117,7 @@ import java.util.Arrays;
|
|||
Object tag = setTag ? ids[windowIndex] : null;
|
||||
return window.set(
|
||||
tag,
|
||||
/* manifest= */ null,
|
||||
/* presentationStartTimeMs= */ C.TIME_UNSET,
|
||||
/* windowStartTimeMs= */ C.TIME_UNSET,
|
||||
/* isSeekable= */ !isDynamic,
|
||||
|
|
|
|||
|
|
@ -946,8 +946,7 @@ public final class ImaAdsLoader
|
|||
// Player.EventListener implementation.
|
||||
|
||||
@Override
|
||||
public void onTimelineChanged(
|
||||
Timeline timeline, @Nullable Object manifest, @Player.TimelineChangeReason int reason) {
|
||||
public void onTimelineChanged(Timeline timeline, @Player.TimelineChangeReason int reason) {
|
||||
if (timeline.isEmpty()) {
|
||||
// The player is being reset or contains no media.
|
||||
return;
|
||||
|
|
|
|||
|
|
@ -51,9 +51,7 @@ import java.util.ArrayList;
|
|||
public void updateTimeline(Timeline timeline) {
|
||||
for (Player.EventListener listener : listeners) {
|
||||
listener.onTimelineChanged(
|
||||
timeline,
|
||||
null,
|
||||
prepared ? TIMELINE_CHANGE_REASON_DYNAMIC : TIMELINE_CHANGE_REASON_PREPARED);
|
||||
timeline, prepared ? TIMELINE_CHANGE_REASON_DYNAMIC : TIMELINE_CHANGE_REASON_PREPARED);
|
||||
}
|
||||
prepared = true;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -288,8 +288,7 @@ public final class LeanbackPlayerAdapter extends PlayerAdapter implements Runnab
|
|||
}
|
||||
|
||||
@Override
|
||||
public void onTimelineChanged(
|
||||
Timeline timeline, @Nullable Object manifest, @TimelineChangeReason int reason) {
|
||||
public void onTimelineChanged(Timeline timeline, @TimelineChangeReason int reason) {
|
||||
Callback callback = getCallback();
|
||||
callback.onDurationChanged(LeanbackPlayerAdapter.this);
|
||||
callback.onCurrentPositionChanged(LeanbackPlayerAdapter.this);
|
||||
|
|
|
|||
|
|
@ -1020,8 +1020,7 @@ public final class MediaSessionConnector {
|
|||
// Player.EventListener implementation.
|
||||
|
||||
@Override
|
||||
public void onTimelineChanged(
|
||||
Timeline timeline, @Nullable Object manifest, @Player.TimelineChangeReason int reason) {
|
||||
public void onTimelineChanged(Timeline timeline, @Player.TimelineChangeReason int reason) {
|
||||
Player player = Assertions.checkNotNull(MediaSessionConnector.this.player);
|
||||
int windowCount = player.getCurrentTimeline().getWindowCount();
|
||||
int windowIndex = player.getCurrentWindowIndex();
|
||||
|
|
|
|||
|
|
@ -94,11 +94,19 @@ public abstract class BasePlayer implements Player {
|
|||
@Override
|
||||
@Nullable
|
||||
public final Object getCurrentTag() {
|
||||
int windowIndex = getCurrentWindowIndex();
|
||||
Timeline timeline = getCurrentTimeline();
|
||||
return windowIndex >= timeline.getWindowCount()
|
||||
return timeline.isEmpty()
|
||||
? null
|
||||
: timeline.getWindow(windowIndex, window, /* setTag= */ true).tag;
|
||||
: timeline.getWindow(getCurrentWindowIndex(), window, /* setTag= */ true).tag;
|
||||
}
|
||||
|
||||
@Override
|
||||
@Nullable
|
||||
public final Object getCurrentManifest() {
|
||||
Timeline timeline = getCurrentTimeline();
|
||||
return timeline.isEmpty()
|
||||
? null
|
||||
: timeline.getWindow(getCurrentWindowIndex(), window, /* setTag= */ false).manifest;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
|||
|
|
@ -547,11 +547,6 @@ import java.util.concurrent.CopyOnWriteArrayList;
|
|||
return playbackInfo.timeline;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getCurrentManifest() {
|
||||
return playbackInfo.manifest;
|
||||
}
|
||||
|
||||
// Not private so it can be called from an inner class without going through a thunk method.
|
||||
/* package */ void handleEvent(Message msg) {
|
||||
switch (msg.what) {
|
||||
|
|
@ -639,7 +634,6 @@ import java.util.concurrent.CopyOnWriteArrayList;
|
|||
long contentPositionUs = resetPosition ? C.TIME_UNSET : playbackInfo.contentPositionUs;
|
||||
return new PlaybackInfo(
|
||||
resetState ? Timeline.EMPTY : playbackInfo.timeline,
|
||||
resetState ? null : playbackInfo.manifest,
|
||||
mediaPeriodId,
|
||||
startPositionUs,
|
||||
contentPositionUs,
|
||||
|
|
@ -713,7 +707,7 @@ import java.util.concurrent.CopyOnWriteArrayList;
|
|||
private final @Player.TimelineChangeReason int timelineChangeReason;
|
||||
private final boolean seekProcessed;
|
||||
private final boolean playbackStateChanged;
|
||||
private final boolean timelineOrManifestChanged;
|
||||
private final boolean timelineChanged;
|
||||
private final boolean isLoadingChanged;
|
||||
private final boolean trackSelectorResultChanged;
|
||||
private final boolean playWhenReady;
|
||||
|
|
@ -737,9 +731,7 @@ import java.util.concurrent.CopyOnWriteArrayList;
|
|||
this.seekProcessed = seekProcessed;
|
||||
this.playWhenReady = playWhenReady;
|
||||
playbackStateChanged = previousPlaybackInfo.playbackState != playbackInfo.playbackState;
|
||||
timelineOrManifestChanged =
|
||||
previousPlaybackInfo.timeline != playbackInfo.timeline
|
||||
|| previousPlaybackInfo.manifest != playbackInfo.manifest;
|
||||
timelineChanged = previousPlaybackInfo.timeline != playbackInfo.timeline;
|
||||
isLoadingChanged = previousPlaybackInfo.isLoading != playbackInfo.isLoading;
|
||||
trackSelectorResultChanged =
|
||||
previousPlaybackInfo.trackSelectorResult != playbackInfo.trackSelectorResult;
|
||||
|
|
@ -747,12 +739,10 @@ import java.util.concurrent.CopyOnWriteArrayList;
|
|||
|
||||
@Override
|
||||
public void run() {
|
||||
if (timelineOrManifestChanged || timelineChangeReason == TIMELINE_CHANGE_REASON_PREPARED) {
|
||||
if (timelineChanged || timelineChangeReason == TIMELINE_CHANGE_REASON_PREPARED) {
|
||||
invokeAll(
|
||||
listenerSnapshot,
|
||||
listener ->
|
||||
listener.onTimelineChanged(
|
||||
playbackInfo.timeline, playbackInfo.manifest, timelineChangeReason));
|
||||
listener -> listener.onTimelineChanged(playbackInfo.timeline, timelineChangeReason));
|
||||
}
|
||||
if (positionDiscontinuity) {
|
||||
invokeAll(
|
||||
|
|
|
|||
|
|
@ -267,9 +267,10 @@ import java.util.concurrent.atomic.AtomicBoolean;
|
|||
// MediaSource.SourceInfoRefreshListener implementation.
|
||||
|
||||
@Override
|
||||
public void onSourceInfoRefreshed(MediaSource source, Timeline timeline, Object manifest) {
|
||||
handler.obtainMessage(MSG_REFRESH_SOURCE_INFO,
|
||||
new MediaSourceRefreshInfo(source, timeline, manifest)).sendToTarget();
|
||||
public void onSourceInfoRefreshed(MediaSource source, Timeline timeline) {
|
||||
handler
|
||||
.obtainMessage(MSG_REFRESH_SOURCE_INFO, new MediaSourceRefreshInfo(source, timeline))
|
||||
.sendToTarget();
|
||||
}
|
||||
|
||||
// MediaPeriod.Callback implementation.
|
||||
|
|
@ -899,7 +900,6 @@ import java.util.concurrent.atomic.AtomicBoolean;
|
|||
playbackInfo =
|
||||
new PlaybackInfo(
|
||||
resetState ? Timeline.EMPTY : playbackInfo.timeline,
|
||||
resetState ? null : playbackInfo.manifest,
|
||||
mediaPeriodId,
|
||||
startPositionUs,
|
||||
contentPositionUs,
|
||||
|
|
@ -1276,9 +1276,8 @@ import java.util.concurrent.atomic.AtomicBoolean;
|
|||
|
||||
Timeline oldTimeline = playbackInfo.timeline;
|
||||
Timeline timeline = sourceRefreshInfo.timeline;
|
||||
Object manifest = sourceRefreshInfo.manifest;
|
||||
queue.setTimeline(timeline);
|
||||
playbackInfo = playbackInfo.copyWithTimeline(timeline, manifest);
|
||||
playbackInfo = playbackInfo.copyWithTimeline(timeline);
|
||||
resolvePendingMessagePositions();
|
||||
|
||||
MediaPeriodId newPeriodId = playbackInfo.periodId;
|
||||
|
|
@ -1881,12 +1880,10 @@ import java.util.concurrent.atomic.AtomicBoolean;
|
|||
|
||||
public final MediaSource source;
|
||||
public final Timeline timeline;
|
||||
public final Object manifest;
|
||||
|
||||
public MediaSourceRefreshInfo(MediaSource source, Timeline timeline, Object manifest) {
|
||||
public MediaSourceRefreshInfo(MediaSource source, Timeline timeline) {
|
||||
this.source = source;
|
||||
this.timeline = timeline;
|
||||
this.manifest = manifest;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -16,7 +16,6 @@
|
|||
package com.google.android.exoplayer2;
|
||||
|
||||
import androidx.annotation.CheckResult;
|
||||
import androidx.annotation.Nullable;
|
||||
import com.google.android.exoplayer2.source.MediaSource.MediaPeriodId;
|
||||
import com.google.android.exoplayer2.source.TrackGroupArray;
|
||||
import com.google.android.exoplayer2.trackselection.TrackSelectorResult;
|
||||
|
|
@ -35,8 +34,6 @@ import com.google.android.exoplayer2.trackselection.TrackSelectorResult;
|
|||
|
||||
/** The current {@link Timeline}. */
|
||||
public final Timeline timeline;
|
||||
/** The current manifest. */
|
||||
@Nullable public final Object manifest;
|
||||
/** The {@link MediaPeriodId} of the currently playing media period in the {@link #timeline}. */
|
||||
public final MediaPeriodId periodId;
|
||||
/**
|
||||
|
|
@ -91,7 +88,6 @@ import com.google.android.exoplayer2.trackselection.TrackSelectorResult;
|
|||
long startPositionUs, TrackSelectorResult emptyTrackSelectorResult) {
|
||||
return new PlaybackInfo(
|
||||
Timeline.EMPTY,
|
||||
/* manifest= */ null,
|
||||
DUMMY_MEDIA_PERIOD_ID,
|
||||
startPositionUs,
|
||||
/* contentPositionUs= */ C.TIME_UNSET,
|
||||
|
|
@ -109,7 +105,6 @@ import com.google.android.exoplayer2.trackselection.TrackSelectorResult;
|
|||
* Create playback info.
|
||||
*
|
||||
* @param timeline See {@link #timeline}.
|
||||
* @param manifest See {@link #manifest}.
|
||||
* @param periodId See {@link #periodId}.
|
||||
* @param startPositionUs See {@link #startPositionUs}.
|
||||
* @param contentPositionUs See {@link #contentPositionUs}.
|
||||
|
|
@ -124,7 +119,6 @@ import com.google.android.exoplayer2.trackselection.TrackSelectorResult;
|
|||
*/
|
||||
public PlaybackInfo(
|
||||
Timeline timeline,
|
||||
@Nullable Object manifest,
|
||||
MediaPeriodId periodId,
|
||||
long startPositionUs,
|
||||
long contentPositionUs,
|
||||
|
|
@ -137,7 +131,6 @@ import com.google.android.exoplayer2.trackselection.TrackSelectorResult;
|
|||
long totalBufferedDurationUs,
|
||||
long positionUs) {
|
||||
this.timeline = timeline;
|
||||
this.manifest = manifest;
|
||||
this.periodId = periodId;
|
||||
this.startPositionUs = startPositionUs;
|
||||
this.contentPositionUs = contentPositionUs;
|
||||
|
|
@ -187,7 +180,6 @@ import com.google.android.exoplayer2.trackselection.TrackSelectorResult;
|
|||
long totalBufferedDurationUs) {
|
||||
return new PlaybackInfo(
|
||||
timeline,
|
||||
manifest,
|
||||
periodId,
|
||||
positionUs,
|
||||
periodId.isAd() ? contentPositionUs : C.TIME_UNSET,
|
||||
|
|
@ -202,17 +194,15 @@ import com.google.android.exoplayer2.trackselection.TrackSelectorResult;
|
|||
}
|
||||
|
||||
/**
|
||||
* Copies playback info with new timeline and manifest.
|
||||
* Copies playback info with the new timeline.
|
||||
*
|
||||
* @param timeline New timeline. See {@link #timeline}.
|
||||
* @param manifest New manifest. See {@link #manifest}.
|
||||
* @return Copied playback info with new timeline and manifest.
|
||||
* @return Copied playback info with the new timeline.
|
||||
*/
|
||||
@CheckResult
|
||||
public PlaybackInfo copyWithTimeline(Timeline timeline, Object manifest) {
|
||||
public PlaybackInfo copyWithTimeline(Timeline timeline) {
|
||||
return new PlaybackInfo(
|
||||
timeline,
|
||||
manifest,
|
||||
periodId,
|
||||
startPositionUs,
|
||||
contentPositionUs,
|
||||
|
|
@ -236,7 +226,6 @@ import com.google.android.exoplayer2.trackselection.TrackSelectorResult;
|
|||
public PlaybackInfo copyWithPlaybackState(int playbackState) {
|
||||
return new PlaybackInfo(
|
||||
timeline,
|
||||
manifest,
|
||||
periodId,
|
||||
startPositionUs,
|
||||
contentPositionUs,
|
||||
|
|
@ -260,7 +249,6 @@ import com.google.android.exoplayer2.trackselection.TrackSelectorResult;
|
|||
public PlaybackInfo copyWithIsLoading(boolean isLoading) {
|
||||
return new PlaybackInfo(
|
||||
timeline,
|
||||
manifest,
|
||||
periodId,
|
||||
startPositionUs,
|
||||
contentPositionUs,
|
||||
|
|
@ -286,7 +274,6 @@ import com.google.android.exoplayer2.trackselection.TrackSelectorResult;
|
|||
TrackGroupArray trackGroups, TrackSelectorResult trackSelectorResult) {
|
||||
return new PlaybackInfo(
|
||||
timeline,
|
||||
manifest,
|
||||
periodId,
|
||||
startPositionUs,
|
||||
contentPositionUs,
|
||||
|
|
@ -310,7 +297,6 @@ import com.google.android.exoplayer2.trackselection.TrackSelectorResult;
|
|||
public PlaybackInfo copyWithLoadingMediaPeriodId(MediaPeriodId loadingMediaPeriodId) {
|
||||
return new PlaybackInfo(
|
||||
timeline,
|
||||
manifest,
|
||||
periodId,
|
||||
startPositionUs,
|
||||
contentPositionUs,
|
||||
|
|
|
|||
|
|
@ -324,6 +324,29 @@ public interface Player {
|
|||
*/
|
||||
interface EventListener {
|
||||
|
||||
/**
|
||||
* Called when the timeline has been refreshed.
|
||||
*
|
||||
* <p>Note that if the timeline has changed then a position discontinuity may also have
|
||||
* occurred. For example, the current period index may have changed as a result of periods being
|
||||
* added or removed from the timeline. This will <em>not</em> be reported via a separate call to
|
||||
* {@link #onPositionDiscontinuity(int)}.
|
||||
*
|
||||
* @param timeline The latest timeline. Never null, but may be empty.
|
||||
* @param reason The {@link TimelineChangeReason} responsible for this timeline change.
|
||||
*/
|
||||
@SuppressWarnings("deprecation")
|
||||
default void onTimelineChanged(Timeline timeline, @TimelineChangeReason int reason) {
|
||||
Object manifest = null;
|
||||
if (timeline.getWindowCount() == 1) {
|
||||
// Legacy behavior was to report the manifest for single window timelines only.
|
||||
Timeline.Window window = new Timeline.Window();
|
||||
manifest = timeline.getWindow(0, window).manifest;
|
||||
}
|
||||
// Call deprecated version.
|
||||
onTimelineChanged(timeline, manifest, reason);
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when the timeline and/or manifest has been refreshed.
|
||||
*
|
||||
|
|
@ -335,7 +358,11 @@ public interface Player {
|
|||
* @param timeline The latest timeline. Never null, but may be empty.
|
||||
* @param manifest The latest manifest. May be null.
|
||||
* @param reason The {@link TimelineChangeReason} responsible for this timeline change.
|
||||
* @deprecated Use {@link #onTimelineChanged(Timeline, int)} instead. The manifest can be
|
||||
* accessed by using {@link #getCurrentManifest()} or {@code timeline.getWindow(windowIndex,
|
||||
* window).manifest} for a given window index.
|
||||
*/
|
||||
@Deprecated
|
||||
default void onTimelineChanged(
|
||||
Timeline timeline, @Nullable Object manifest, @TimelineChangeReason int reason) {}
|
||||
|
||||
|
|
@ -396,8 +423,7 @@ public interface Player {
|
|||
* when the source introduces a discontinuity internally).
|
||||
*
|
||||
* <p>When a position discontinuity occurs as a result of a change to the timeline this method
|
||||
* is <em>not</em> called. {@link #onTimelineChanged(Timeline, Object, int)} is called in this
|
||||
* case.
|
||||
* is <em>not</em> called. {@link #onTimelineChanged(Timeline, int)} is called in this case.
|
||||
*
|
||||
* @param reason The {@link DiscontinuityReason} responsible for the discontinuity.
|
||||
*/
|
||||
|
|
@ -428,6 +454,19 @@ public interface Player {
|
|||
@Deprecated
|
||||
abstract class DefaultEventListener implements EventListener {
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("deprecation")
|
||||
public void onTimelineChanged(Timeline timeline, @TimelineChangeReason int reason) {
|
||||
Object manifest = null;
|
||||
if (timeline.getWindowCount() == 1) {
|
||||
// Legacy behavior was to report the manifest for single window timelines only.
|
||||
Timeline.Window window = new Timeline.Window();
|
||||
manifest = timeline.getWindow(0, window).manifest;
|
||||
}
|
||||
// Call deprecated version.
|
||||
onTimelineChanged(timeline, manifest, reason);
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("deprecation")
|
||||
public void onTimelineChanged(
|
||||
|
|
@ -436,7 +475,7 @@ public interface Player {
|
|||
onTimelineChanged(timeline, manifest);
|
||||
}
|
||||
|
||||
/** @deprecated Use {@link EventListener#onTimelineChanged(Timeline, Object, int)} instead. */
|
||||
/** @deprecated Use {@link EventListener#onTimelineChanged(Timeline, int)} instead. */
|
||||
@Deprecated
|
||||
public void onTimelineChanged(Timeline timeline, @Nullable Object manifest) {
|
||||
// Do nothing.
|
||||
|
|
|
|||
|
|
@ -1070,13 +1070,6 @@ public class SimpleExoPlayer extends BasePlayer
|
|||
return player.getCurrentTimeline();
|
||||
}
|
||||
|
||||
@Override
|
||||
@Nullable
|
||||
public Object getCurrentManifest() {
|
||||
verifyApplicationThread();
|
||||
return player.getCurrentManifest();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getCurrentPeriodIndex() {
|
||||
verifyApplicationThread();
|
||||
|
|
|
|||
|
|
@ -122,6 +122,9 @@ public abstract class Timeline {
|
|||
/** A tag for the window. Not necessarily unique. */
|
||||
@Nullable public Object tag;
|
||||
|
||||
/** The manifest of the window. May be {@code null}. */
|
||||
@Nullable public Object manifest;
|
||||
|
||||
/**
|
||||
* The start time of the presentation to which this window belongs in milliseconds since the
|
||||
* epoch, or {@link C#TIME_UNSET} if unknown or not applicable. For informational purposes only.
|
||||
|
|
@ -179,6 +182,7 @@ public abstract class Timeline {
|
|||
/** Sets the data held by this window. */
|
||||
public Window set(
|
||||
@Nullable Object tag,
|
||||
@Nullable Object manifest,
|
||||
long presentationStartTimeMs,
|
||||
long windowStartTimeMs,
|
||||
boolean isSeekable,
|
||||
|
|
@ -189,6 +193,7 @@ public abstract class Timeline {
|
|||
int lastPeriodIndex,
|
||||
long positionInFirstPeriodUs) {
|
||||
this.tag = tag;
|
||||
this.manifest = manifest;
|
||||
this.presentationStartTimeMs = presentationStartTimeMs;
|
||||
this.windowStartTimeMs = windowStartTimeMs;
|
||||
this.isSeekable = isSeekable;
|
||||
|
|
|
|||
|
|
@ -437,8 +437,7 @@ public class AnalyticsCollector
|
|||
// having slightly different real times.
|
||||
|
||||
@Override
|
||||
public final void onTimelineChanged(
|
||||
Timeline timeline, @Nullable Object manifest, @Player.TimelineChangeReason int reason) {
|
||||
public final void onTimelineChanged(Timeline timeline, @Player.TimelineChangeReason int reason) {
|
||||
mediaPeriodQueueTracker.onTimelineChanged(timeline);
|
||||
EventTime eventTime = generatePlayingMediaPeriodEventTime();
|
||||
for (AnalyticsListener listener : listeners) {
|
||||
|
|
|
|||
|
|
@ -335,6 +335,7 @@ public final class DownloadHelper {
|
|||
private final RendererCapabilities[] rendererCapabilities;
|
||||
private final SparseIntArray scratchSet;
|
||||
private final Handler callbackHandler;
|
||||
private final Timeline.Window window;
|
||||
|
||||
private boolean isPreparedWithMedia;
|
||||
private @MonotonicNonNull Callback callback;
|
||||
|
|
@ -374,6 +375,7 @@ public final class DownloadHelper {
|
|||
trackSelector.setParameters(trackSelectorParameters);
|
||||
trackSelector.init(/* listener= */ () -> {}, new DummyBandwidthMeter());
|
||||
callbackHandler = new Handler(Util.getLooper());
|
||||
window = new Timeline.Window();
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -409,7 +411,9 @@ public final class DownloadHelper {
|
|||
return null;
|
||||
}
|
||||
assertPreparedWithMedia();
|
||||
return mediaPreparer.manifest;
|
||||
return mediaPreparer.timeline.getWindowCount() > 0
|
||||
? mediaPreparer.timeline.getWindow(/* windowIndex= */ 0, window).manifest
|
||||
: null;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -814,7 +818,6 @@ public final class DownloadHelper {
|
|||
private final HandlerThread mediaSourceThread;
|
||||
private final Handler mediaSourceHandler;
|
||||
|
||||
@Nullable public Object manifest;
|
||||
public @MonotonicNonNull Timeline timeline;
|
||||
public MediaPeriod @MonotonicNonNull [] mediaPeriods;
|
||||
|
||||
|
|
@ -892,14 +895,12 @@ public final class DownloadHelper {
|
|||
// MediaSource.SourceInfoRefreshListener implementation.
|
||||
|
||||
@Override
|
||||
public void onSourceInfoRefreshed(
|
||||
MediaSource source, Timeline timeline, @Nullable Object manifest) {
|
||||
public void onSourceInfoRefreshed(MediaSource source, Timeline timeline) {
|
||||
if (this.timeline != null) {
|
||||
// Ignore dynamic updates.
|
||||
return;
|
||||
}
|
||||
this.timeline = timeline;
|
||||
this.manifest = manifest;
|
||||
mediaPeriods = new MediaPeriod[timeline.getPeriodCount()];
|
||||
for (int i = 0; i < mediaPeriods.length; i++) {
|
||||
MediaPeriod mediaPeriod =
|
||||
|
|
|
|||
|
|
@ -27,8 +27,8 @@ import java.util.ArrayList;
|
|||
* Base {@link MediaSource} implementation to handle parallel reuse and to keep a list of {@link
|
||||
* MediaSourceEventListener}s.
|
||||
*
|
||||
* <p>Whenever an implementing subclass needs to provide a new timeline and/or manifest, it must
|
||||
* call {@link #refreshSourceInfo(Timeline, Object)} to notify all listeners.
|
||||
* <p>Whenever an implementing subclass needs to provide a new timeline, it must call {@link
|
||||
* #refreshSourceInfo(Timeline)} to notify all listeners.
|
||||
*/
|
||||
public abstract class BaseMediaSource implements MediaSource {
|
||||
|
||||
|
|
@ -37,7 +37,6 @@ public abstract class BaseMediaSource implements MediaSource {
|
|||
|
||||
@Nullable private Looper looper;
|
||||
@Nullable private Timeline timeline;
|
||||
@Nullable private Object manifest;
|
||||
|
||||
public BaseMediaSource() {
|
||||
sourceInfoListeners = new ArrayList<>(/* initialCapacity= */ 1);
|
||||
|
|
@ -65,13 +64,11 @@ public abstract class BaseMediaSource implements MediaSource {
|
|||
* Updates timeline and manifest and notifies all listeners of the update.
|
||||
*
|
||||
* @param timeline The new {@link Timeline}.
|
||||
* @param manifest The new manifest. May be null.
|
||||
*/
|
||||
protected final void refreshSourceInfo(Timeline timeline, @Nullable Object manifest) {
|
||||
protected final void refreshSourceInfo(Timeline timeline) {
|
||||
this.timeline = timeline;
|
||||
this.manifest = manifest;
|
||||
for (SourceInfoRefreshListener listener : sourceInfoListeners) {
|
||||
listener.onSourceInfoRefreshed(/* source= */ this, timeline, manifest);
|
||||
listener.onSourceInfoRefreshed(/* source= */ this, timeline);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -139,7 +136,7 @@ public abstract class BaseMediaSource implements MediaSource {
|
|||
this.looper = looper;
|
||||
prepareSourceInternal(mediaTransferListener);
|
||||
} else if (timeline != null) {
|
||||
listener.onSourceInfoRefreshed(/* source= */ this, timeline, manifest);
|
||||
listener.onSourceInfoRefreshed(/* source= */ this, timeline);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -149,7 +146,6 @@ public abstract class BaseMediaSource implements MediaSource {
|
|||
if (sourceInfoListeners.isEmpty()) {
|
||||
looper = null;
|
||||
timeline = null;
|
||||
manifest = null;
|
||||
releaseSourceInternal();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -87,7 +87,6 @@ public final class ClippingMediaSource extends CompositeMediaSource<Void> {
|
|||
private final ArrayList<ClippingMediaPeriod> mediaPeriods;
|
||||
private final Timeline.Window window;
|
||||
|
||||
@Nullable private Object manifest;
|
||||
@Nullable private ClippingTimeline clippingTimeline;
|
||||
@Nullable private IllegalClippingException clippingError;
|
||||
private long periodStartUs;
|
||||
|
|
@ -235,12 +234,10 @@ public final class ClippingMediaSource extends CompositeMediaSource<Void> {
|
|||
}
|
||||
|
||||
@Override
|
||||
protected void onChildSourceInfoRefreshed(
|
||||
Void id, MediaSource mediaSource, Timeline timeline, @Nullable Object manifest) {
|
||||
protected void onChildSourceInfoRefreshed(Void id, MediaSource mediaSource, Timeline timeline) {
|
||||
if (clippingError != null) {
|
||||
return;
|
||||
}
|
||||
this.manifest = manifest;
|
||||
refreshClippedTimeline(timeline);
|
||||
}
|
||||
|
||||
|
|
@ -280,7 +277,7 @@ public final class ClippingMediaSource extends CompositeMediaSource<Void> {
|
|||
clippingError = e;
|
||||
return;
|
||||
}
|
||||
refreshSourceInfo(clippingTimeline, manifest);
|
||||
refreshSourceInfo(clippingTimeline);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
|||
|
|
@ -73,17 +73,15 @@ public abstract class CompositeMediaSource<T> extends BaseMediaSource {
|
|||
* @param id The unique id used to prepare the child source.
|
||||
* @param mediaSource The child source whose source info has been refreshed.
|
||||
* @param timeline The timeline of the child source.
|
||||
* @param manifest The manifest of the child source.
|
||||
*/
|
||||
protected abstract void onChildSourceInfoRefreshed(
|
||||
T id, MediaSource mediaSource, Timeline timeline, @Nullable Object manifest);
|
||||
T id, MediaSource mediaSource, Timeline timeline);
|
||||
|
||||
/**
|
||||
* Prepares a child source.
|
||||
*
|
||||
* <p>{@link #onChildSourceInfoRefreshed(Object, MediaSource, Timeline, Object)} will be called
|
||||
* when the child source updates its timeline and/or manifest with the same {@code id} passed to
|
||||
* this method.
|
||||
* <p>{@link #onChildSourceInfoRefreshed(Object, MediaSource, Timeline)} will be called when the
|
||||
* child source updates its timeline with the same {@code id} passed to this method.
|
||||
*
|
||||
* <p>Any child sources that aren't explicitly released with {@link #releaseChildSource(Object)}
|
||||
* will be released in {@link #releaseSourceInternal()}.
|
||||
|
|
@ -94,7 +92,12 @@ public abstract class CompositeMediaSource<T> extends BaseMediaSource {
|
|||
protected final void prepareChildSource(final T id, MediaSource mediaSource) {
|
||||
Assertions.checkArgument(!childSources.containsKey(id));
|
||||
SourceInfoRefreshListener sourceListener =
|
||||
(source, timeline, manifest) -> onChildSourceInfoRefreshed(id, source, timeline, manifest);
|
||||
new SourceInfoRefreshListener() {
|
||||
@Override
|
||||
public void onSourceInfoRefreshed(MediaSource source, Timeline timeline) {
|
||||
onChildSourceInfoRefreshed(id, source, timeline);
|
||||
}
|
||||
};
|
||||
MediaSourceEventListener eventListener = new ForwardingEventListener(id);
|
||||
childSources.put(id, new MediaSourceAndListener(mediaSource, sourceListener, eventListener));
|
||||
mediaSource.addEventListener(Assertions.checkNotNull(eventHandler), eventListener);
|
||||
|
|
|
|||
|
|
@ -474,10 +474,7 @@ public final class ConcatenatingMediaSource extends CompositeMediaSource<MediaSo
|
|||
|
||||
@Override
|
||||
protected void onChildSourceInfoRefreshed(
|
||||
MediaSourceHolder mediaSourceHolder,
|
||||
MediaSource mediaSource,
|
||||
Timeline timeline,
|
||||
@Nullable Object manifest) {
|
||||
MediaSourceHolder mediaSourceHolder, MediaSource mediaSource, Timeline timeline) {
|
||||
updateMediaSourceInternal(mediaSourceHolder, timeline);
|
||||
}
|
||||
|
||||
|
|
@ -679,8 +676,7 @@ public final class ConcatenatingMediaSource extends CompositeMediaSource<MediaSo
|
|||
timelineUpdateScheduled = false;
|
||||
Set<HandlerAndRunnable> onCompletionActions = nextTimelineUpdateOnCompletionActions;
|
||||
nextTimelineUpdateOnCompletionActions = new HashSet<>();
|
||||
refreshSourceInfo(
|
||||
new ConcatenatedTimeline(mediaSourceHolders, shuffleOrder, isAtomic), /* manifest= */ null);
|
||||
refreshSourceInfo(new ConcatenatedTimeline(mediaSourceHolders, shuffleOrder, isAtomic));
|
||||
getPlaybackThreadHandlerOnPlaybackThread()
|
||||
.obtainMessage(MSG_ON_COMPLETION, onCompletionActions)
|
||||
.sendToTarget();
|
||||
|
|
|
|||
|
|
@ -364,9 +364,8 @@ public final class ExtractorMediaSource extends BaseMediaSource
|
|||
}
|
||||
|
||||
@Override
|
||||
public void onSourceInfoRefreshed(
|
||||
MediaSource source, Timeline timeline, @Nullable Object manifest) {
|
||||
refreshSourceInfo(timeline, manifest);
|
||||
public void onSourceInfoRefreshed(MediaSource source, Timeline timeline) {
|
||||
refreshSourceInfo(timeline);
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
|
|
|
|||
|
|
@ -100,13 +100,12 @@ public final class LoopingMediaSource extends CompositeMediaSource<Void> {
|
|||
}
|
||||
|
||||
@Override
|
||||
protected void onChildSourceInfoRefreshed(
|
||||
Void id, MediaSource mediaSource, Timeline timeline, @Nullable Object manifest) {
|
||||
protected void onChildSourceInfoRefreshed(Void id, MediaSource mediaSource, Timeline timeline) {
|
||||
Timeline loopingTimeline =
|
||||
loopCount != Integer.MAX_VALUE
|
||||
? new LoopingTimeline(timeline, loopCount)
|
||||
: new InfinitelyLoopingTimeline(timeline);
|
||||
refreshSourceInfo(loopingTimeline, manifest);
|
||||
refreshSourceInfo(loopingTimeline);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
|||
|
|
@ -119,7 +119,7 @@ public final class MaskingMediaSource extends CompositeMediaSource<Void> {
|
|||
|
||||
@Override
|
||||
protected void onChildSourceInfoRefreshed(
|
||||
Void id, MediaSource mediaSource, Timeline newTimeline, @Nullable Object manifest) {
|
||||
Void id, MediaSource mediaSource, Timeline newTimeline) {
|
||||
if (isPrepared) {
|
||||
timeline = timeline.cloneWithUpdatedTimeline(newTimeline);
|
||||
} else if (newTimeline.isEmpty()) {
|
||||
|
|
@ -162,7 +162,7 @@ public final class MaskingMediaSource extends CompositeMediaSource<Void> {
|
|||
}
|
||||
}
|
||||
isPrepared = true;
|
||||
refreshSourceInfo(this.timeline, manifest);
|
||||
refreshSourceInfo(this.timeline);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
|
|
@ -274,6 +274,7 @@ public final class MaskingMediaSource extends CompositeMediaSource<Void> {
|
|||
int windowIndex, Window window, boolean setTag, long defaultPositionProjectionUs) {
|
||||
return window.set(
|
||||
tag,
|
||||
/* manifest= */ null,
|
||||
/* presentationStartTimeMs= */ C.TIME_UNSET,
|
||||
/* windowStartTimeMs= */ C.TIME_UNSET,
|
||||
/* isSeekable= */ false,
|
||||
|
|
|
|||
|
|
@ -58,8 +58,8 @@ public interface MediaPeriod extends SequenceableLoader {
|
|||
*
|
||||
* <p>If preparation succeeds and results in a source timeline change (e.g. the period duration
|
||||
* becoming known), {@link
|
||||
* MediaSource.SourceInfoRefreshListener#onSourceInfoRefreshed(MediaSource, Timeline, Object)}
|
||||
* will be called before {@code callback.onPrepared}.
|
||||
* MediaSource.SourceInfoRefreshListener#onSourceInfoRefreshed(MediaSource, Timeline)} will be
|
||||
* called before {@code callback.onPrepared}.
|
||||
*
|
||||
* @param callback Callback to receive updates from this period, including being notified when
|
||||
* preparation completes.
|
||||
|
|
|
|||
|
|
@ -49,16 +49,16 @@ public interface MediaSource {
|
|||
interface SourceInfoRefreshListener {
|
||||
|
||||
/**
|
||||
* Called when manifest and/or timeline has been refreshed.
|
||||
* <p>
|
||||
* Called on the playback thread.
|
||||
* Called when the timeline has been refreshed.
|
||||
*
|
||||
* <p>Called on the playback thread.
|
||||
*
|
||||
* @param source The {@link MediaSource} whose info has been refreshed.
|
||||
* @param timeline The source's timeline.
|
||||
* @param manifest The loaded manifest. May be null.
|
||||
*/
|
||||
void onSourceInfoRefreshed(MediaSource source, Timeline timeline, @Nullable Object manifest);
|
||||
|
||||
default void onSourceInfoRefreshed(MediaSource source, Timeline timeline) {
|
||||
// Do nothing.
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -71,7 +71,6 @@ public final class MergingMediaSource extends CompositeMediaSource<Integer> {
|
|||
private final ArrayList<MediaSource> pendingTimelineSources;
|
||||
private final CompositeSequenceableLoaderFactory compositeSequenceableLoaderFactory;
|
||||
|
||||
@Nullable private Object primaryManifest;
|
||||
private int periodCount;
|
||||
@Nullable private IllegalMergeException mergeError;
|
||||
|
||||
|
|
@ -143,7 +142,6 @@ public final class MergingMediaSource extends CompositeMediaSource<Integer> {
|
|||
protected void releaseSourceInternal() {
|
||||
super.releaseSourceInternal();
|
||||
Arrays.fill(timelines, null);
|
||||
primaryManifest = null;
|
||||
periodCount = PERIOD_COUNT_UNSET;
|
||||
mergeError = null;
|
||||
pendingTimelineSources.clear();
|
||||
|
|
@ -152,7 +150,7 @@ public final class MergingMediaSource extends CompositeMediaSource<Integer> {
|
|||
|
||||
@Override
|
||||
protected void onChildSourceInfoRefreshed(
|
||||
Integer id, MediaSource mediaSource, Timeline timeline, @Nullable Object manifest) {
|
||||
Integer id, MediaSource mediaSource, Timeline timeline) {
|
||||
if (mergeError == null) {
|
||||
mergeError = checkTimelineMerges(timeline);
|
||||
}
|
||||
|
|
@ -161,11 +159,8 @@ public final class MergingMediaSource extends CompositeMediaSource<Integer> {
|
|||
}
|
||||
pendingTimelineSources.remove(mediaSource);
|
||||
timelines[id] = timeline;
|
||||
if (mediaSource == mediaSources[0]) {
|
||||
primaryManifest = manifest;
|
||||
}
|
||||
if (pendingTimelineSources.isEmpty()) {
|
||||
refreshSourceInfo(timelines[0], primaryManifest);
|
||||
refreshSourceInfo(timelines[0]);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -287,7 +287,10 @@ public final class ProgressiveMediaSource extends BaseMediaSource
|
|||
// TODO: Make timeline dynamic until its duration is known. This is non-trivial. See b/69703223.
|
||||
refreshSourceInfo(
|
||||
new SinglePeriodTimeline(
|
||||
timelineDurationUs, timelineIsSeekable, /* isDynamic= */ false, tag),
|
||||
/* manifest= */ null);
|
||||
timelineDurationUs,
|
||||
timelineIsSeekable,
|
||||
/* isDynamic= */ false,
|
||||
/* manifest= */ null,
|
||||
tag));
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -68,8 +68,7 @@ public final class SilenceMediaSource extends BaseMediaSource {
|
|||
@Override
|
||||
protected void prepareSourceInternal(@Nullable TransferListener mediaTransferListener) {
|
||||
refreshSourceInfo(
|
||||
new SinglePeriodTimeline(durationUs, /* isSeekable= */ true, /* isDynamic= */ false),
|
||||
/* manifest= */ null);
|
||||
new SinglePeriodTimeline(durationUs, /* isSeekable= */ true, /* isDynamic= */ false));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
|||
|
|
@ -36,6 +36,7 @@ public final class SinglePeriodTimeline extends Timeline {
|
|||
private final boolean isSeekable;
|
||||
private final boolean isDynamic;
|
||||
@Nullable private final Object tag;
|
||||
@Nullable private final Object manifest;
|
||||
|
||||
/**
|
||||
* Creates a timeline containing a single period and a window that spans it.
|
||||
|
|
@ -45,7 +46,7 @@ public final class SinglePeriodTimeline extends Timeline {
|
|||
* @param isDynamic Whether the window may change when the timeline is updated.
|
||||
*/
|
||||
public SinglePeriodTimeline(long durationUs, boolean isSeekable, boolean isDynamic) {
|
||||
this(durationUs, isSeekable, isDynamic, /* tag= */ null);
|
||||
this(durationUs, isSeekable, isDynamic, /* manifest= */ null, /* tag= */ null);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -54,10 +55,15 @@ public final class SinglePeriodTimeline extends Timeline {
|
|||
* @param durationUs The duration of the period, in microseconds.
|
||||
* @param isSeekable Whether seeking is supported within the period.
|
||||
* @param isDynamic Whether the window may change when the timeline is updated.
|
||||
* @param tag A tag used for {@link Timeline.Window#tag}.
|
||||
* @param manifest The manifest. May be {@code null}.
|
||||
* @param tag A tag used for {@link Window#tag}.
|
||||
*/
|
||||
public SinglePeriodTimeline(
|
||||
long durationUs, boolean isSeekable, boolean isDynamic, @Nullable Object tag) {
|
||||
long durationUs,
|
||||
boolean isSeekable,
|
||||
boolean isDynamic,
|
||||
@Nullable Object manifest,
|
||||
@Nullable Object tag) {
|
||||
this(
|
||||
durationUs,
|
||||
durationUs,
|
||||
|
|
@ -65,6 +71,7 @@ public final class SinglePeriodTimeline extends Timeline {
|
|||
/* windowDefaultStartPositionUs= */ 0,
|
||||
isSeekable,
|
||||
isDynamic,
|
||||
manifest,
|
||||
tag);
|
||||
}
|
||||
|
||||
|
|
@ -80,6 +87,7 @@ public final class SinglePeriodTimeline extends Timeline {
|
|||
* which to begin playback, in microseconds.
|
||||
* @param isSeekable Whether seeking is supported within the window.
|
||||
* @param isDynamic Whether the window may change when the timeline is updated.
|
||||
* @param manifest The manifest. May be (@code null}.
|
||||
* @param tag A tag used for {@link Timeline.Window#tag}.
|
||||
*/
|
||||
public SinglePeriodTimeline(
|
||||
|
|
@ -89,6 +97,7 @@ public final class SinglePeriodTimeline extends Timeline {
|
|||
long windowDefaultStartPositionUs,
|
||||
boolean isSeekable,
|
||||
boolean isDynamic,
|
||||
@Nullable Object manifest,
|
||||
@Nullable Object tag) {
|
||||
this(
|
||||
/* presentationStartTimeMs= */ C.TIME_UNSET,
|
||||
|
|
@ -99,6 +108,7 @@ public final class SinglePeriodTimeline extends Timeline {
|
|||
windowDefaultStartPositionUs,
|
||||
isSeekable,
|
||||
isDynamic,
|
||||
manifest,
|
||||
tag);
|
||||
}
|
||||
|
||||
|
|
@ -117,6 +127,7 @@ public final class SinglePeriodTimeline extends Timeline {
|
|||
* which to begin playback, in microseconds.
|
||||
* @param isSeekable Whether seeking is supported within the window.
|
||||
* @param isDynamic Whether the window may change when the timeline is updated.
|
||||
* @param manifest The manifest. May be {@code null}.
|
||||
* @param tag A tag used for {@link Timeline.Window#tag}.
|
||||
*/
|
||||
public SinglePeriodTimeline(
|
||||
|
|
@ -128,6 +139,7 @@ public final class SinglePeriodTimeline extends Timeline {
|
|||
long windowDefaultStartPositionUs,
|
||||
boolean isSeekable,
|
||||
boolean isDynamic,
|
||||
@Nullable Object manifest,
|
||||
@Nullable Object tag) {
|
||||
this.presentationStartTimeMs = presentationStartTimeMs;
|
||||
this.windowStartTimeMs = windowStartTimeMs;
|
||||
|
|
@ -137,6 +149,7 @@ public final class SinglePeriodTimeline extends Timeline {
|
|||
this.windowDefaultStartPositionUs = windowDefaultStartPositionUs;
|
||||
this.isSeekable = isSeekable;
|
||||
this.isDynamic = isDynamic;
|
||||
this.manifest = manifest;
|
||||
this.tag = tag;
|
||||
}
|
||||
|
||||
|
|
@ -165,6 +178,7 @@ public final class SinglePeriodTimeline extends Timeline {
|
|||
}
|
||||
return window.set(
|
||||
tag,
|
||||
manifest,
|
||||
presentationStartTimeMs,
|
||||
windowStartTimeMs,
|
||||
isSeekable,
|
||||
|
|
|
|||
|
|
@ -290,7 +290,8 @@ public final class SingleSampleMediaSource extends BaseMediaSource {
|
|||
this.tag = tag;
|
||||
dataSpec = new DataSpec(uri, DataSpec.FLAG_ALLOW_GZIP);
|
||||
timeline =
|
||||
new SinglePeriodTimeline(durationUs, /* isSeekable= */ true, /* isDynamic= */ false, tag);
|
||||
new SinglePeriodTimeline(
|
||||
durationUs, /* isSeekable= */ true, /* isDynamic= */ false, /* manifest= */ null, tag);
|
||||
}
|
||||
|
||||
// MediaSource implementation.
|
||||
|
|
@ -304,7 +305,7 @@ public final class SingleSampleMediaSource extends BaseMediaSource {
|
|||
@Override
|
||||
protected void prepareSourceInternal(@Nullable TransferListener mediaTransferListener) {
|
||||
transferListener = mediaTransferListener;
|
||||
refreshSourceInfo(timeline, /* manifest= */ null);
|
||||
refreshSourceInfo(timeline);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
|||
|
|
@ -134,7 +134,6 @@ public final class AdsMediaSource extends CompositeMediaSource<MediaPeriodId> {
|
|||
// Accessed on the player thread.
|
||||
@Nullable private ComponentListener componentListener;
|
||||
@Nullable private Timeline contentTimeline;
|
||||
@Nullable private Object contentManifest;
|
||||
@Nullable private AdPlaybackState adPlaybackState;
|
||||
private @NullableType MediaSource[][] adGroupMediaSources;
|
||||
private @NullableType Timeline[][] adGroupTimelines;
|
||||
|
|
@ -265,7 +264,6 @@ public final class AdsMediaSource extends CompositeMediaSource<MediaPeriodId> {
|
|||
componentListener = null;
|
||||
maskingMediaPeriodByAdMediaSource.clear();
|
||||
contentTimeline = null;
|
||||
contentManifest = null;
|
||||
adPlaybackState = null;
|
||||
adGroupMediaSources = new MediaSource[0][];
|
||||
adGroupTimelines = new Timeline[0][];
|
||||
|
|
@ -274,16 +272,13 @@ public final class AdsMediaSource extends CompositeMediaSource<MediaPeriodId> {
|
|||
|
||||
@Override
|
||||
protected void onChildSourceInfoRefreshed(
|
||||
MediaPeriodId mediaPeriodId,
|
||||
MediaSource mediaSource,
|
||||
Timeline timeline,
|
||||
@Nullable Object manifest) {
|
||||
MediaPeriodId mediaPeriodId, MediaSource mediaSource, Timeline timeline) {
|
||||
if (mediaPeriodId.isAd()) {
|
||||
int adGroupIndex = mediaPeriodId.adGroupIndex;
|
||||
int adIndexInAdGroup = mediaPeriodId.adIndexInAdGroup;
|
||||
onAdSourceInfoRefreshed(mediaSource, adGroupIndex, adIndexInAdGroup, timeline);
|
||||
} else {
|
||||
onContentSourceInfoRefreshed(timeline, manifest);
|
||||
onContentSourceInfoRefreshed(timeline);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -308,10 +303,9 @@ public final class AdsMediaSource extends CompositeMediaSource<MediaPeriodId> {
|
|||
maybeUpdateSourceInfo();
|
||||
}
|
||||
|
||||
private void onContentSourceInfoRefreshed(Timeline timeline, @Nullable Object manifest) {
|
||||
private void onContentSourceInfoRefreshed(Timeline timeline) {
|
||||
Assertions.checkArgument(timeline.getPeriodCount() == 1);
|
||||
contentTimeline = timeline;
|
||||
contentManifest = manifest;
|
||||
maybeUpdateSourceInfo();
|
||||
}
|
||||
|
||||
|
|
@ -340,7 +334,7 @@ public final class AdsMediaSource extends CompositeMediaSource<MediaPeriodId> {
|
|||
adPlaybackState.adGroupCount == 0
|
||||
? contentTimeline
|
||||
: new SinglePeriodAdTimeline(contentTimeline, adPlaybackState);
|
||||
refreshSourceInfo(timeline, contentManifest);
|
||||
refreshSourceInfo(timeline);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -113,8 +113,8 @@ public final class ExoPlayerTest {
|
|||
/** Tests playback of a source that exposes a single period. */
|
||||
@Test
|
||||
public void testPlaySinglePeriodTimeline() throws Exception {
|
||||
Timeline timeline = new FakeTimeline(/* windowCount= */ 1);
|
||||
Object manifest = new Object();
|
||||
Timeline timeline = new FakeTimeline(/* windowCount= */ 1, manifest);
|
||||
FakeRenderer renderer = new FakeRenderer(Builder.VIDEO_FORMAT);
|
||||
ExoPlayerTestRunner testRunner =
|
||||
new Builder()
|
||||
|
|
@ -126,7 +126,6 @@ public final class ExoPlayerTest {
|
|||
.blockUntilEnded(TIMEOUT_MS);
|
||||
testRunner.assertNoPositionDiscontinuities();
|
||||
testRunner.assertTimelinesEqual(timeline);
|
||||
testRunner.assertManifestsEqual(manifest);
|
||||
testRunner.assertTimelineChangeReasonsEqual(Player.TIMELINE_CHANGE_REASON_PREPARED);
|
||||
testRunner.assertTrackGroupsEqual(new TrackGroupArray(new TrackGroup(Builder.VIDEO_FORMAT)));
|
||||
assertThat(renderer.formatReadCount).isEqualTo(1);
|
||||
|
|
@ -256,15 +255,16 @@ public final class ExoPlayerTest {
|
|||
|
||||
@Test
|
||||
public void testRepreparationGivesFreshSourceInfo() throws Exception {
|
||||
Timeline timeline = new FakeTimeline(/* windowCount= */ 1);
|
||||
FakeRenderer renderer = new FakeRenderer(Builder.VIDEO_FORMAT);
|
||||
Object firstSourceManifest = new Object();
|
||||
MediaSource firstSource =
|
||||
new FakeMediaSource(timeline, firstSourceManifest, Builder.VIDEO_FORMAT);
|
||||
Timeline firstTimeline = new FakeTimeline(/* windowCount= */ 1, firstSourceManifest);
|
||||
MediaSource firstSource = new FakeMediaSource(firstTimeline, Builder.VIDEO_FORMAT);
|
||||
final CountDownLatch queuedSourceInfoCountDownLatch = new CountDownLatch(1);
|
||||
final CountDownLatch completePreparationCountDownLatch = new CountDownLatch(1);
|
||||
|
||||
Timeline secondTimeline = new FakeTimeline(/* windowCount= */ 1);
|
||||
MediaSource secondSource =
|
||||
new FakeMediaSource(timeline, new Object(), Builder.VIDEO_FORMAT) {
|
||||
new FakeMediaSource(secondTimeline, Builder.VIDEO_FORMAT) {
|
||||
@Override
|
||||
public synchronized void prepareSourceInternal(
|
||||
@Nullable TransferListener mediaTransferListener) {
|
||||
|
|
@ -281,8 +281,8 @@ public final class ExoPlayerTest {
|
|||
}
|
||||
};
|
||||
Object thirdSourceManifest = new Object();
|
||||
MediaSource thirdSource =
|
||||
new FakeMediaSource(timeline, thirdSourceManifest, Builder.VIDEO_FORMAT);
|
||||
Timeline thirdTimeline = new FakeTimeline(/* windowCount= */ 1, thirdSourceManifest);
|
||||
MediaSource thirdSource = new FakeMediaSource(thirdTimeline, Builder.VIDEO_FORMAT);
|
||||
|
||||
// Prepare the player with a source with the first manifest and a non-empty timeline. Prepare
|
||||
// the player again with a source and a new manifest, which will never be exposed. Allow the
|
||||
|
|
@ -290,7 +290,7 @@ public final class ExoPlayerTest {
|
|||
// the test thread's call to prepare() has returned.
|
||||
ActionSchedule actionSchedule =
|
||||
new ActionSchedule.Builder("testRepreparation")
|
||||
.waitForTimelineChanged(timeline)
|
||||
.waitForTimelineChanged(firstTimeline)
|
||||
.prepareSource(secondSource)
|
||||
.executeRunnable(
|
||||
() -> {
|
||||
|
|
@ -315,8 +315,7 @@ public final class ExoPlayerTest {
|
|||
// The first source's preparation completed with a non-empty timeline. When the player was
|
||||
// re-prepared with the second source, it immediately exposed an empty timeline, but the source
|
||||
// info refresh from the second source was suppressed as we re-prepared with the third source.
|
||||
testRunner.assertTimelinesEqual(timeline, Timeline.EMPTY, timeline);
|
||||
testRunner.assertManifestsEqual(firstSourceManifest, null, thirdSourceManifest);
|
||||
testRunner.assertTimelinesEqual(firstTimeline, Timeline.EMPTY, thirdTimeline);
|
||||
testRunner.assertTimelineChangeReasonsEqual(
|
||||
Player.TIMELINE_CHANGE_REASON_PREPARED,
|
||||
Player.TIMELINE_CHANGE_REASON_RESET,
|
||||
|
|
@ -376,9 +375,9 @@ public final class ExoPlayerTest {
|
|||
public void testShuffleModeEnabledChanges() throws Exception {
|
||||
Timeline fakeTimeline = new FakeTimeline(/* windowCount= */ 1);
|
||||
MediaSource[] fakeMediaSources = {
|
||||
new FakeMediaSource(fakeTimeline, null, Builder.VIDEO_FORMAT),
|
||||
new FakeMediaSource(fakeTimeline, null, Builder.VIDEO_FORMAT),
|
||||
new FakeMediaSource(fakeTimeline, null, Builder.VIDEO_FORMAT)
|
||||
new FakeMediaSource(fakeTimeline, Builder.VIDEO_FORMAT),
|
||||
new FakeMediaSource(fakeTimeline, Builder.VIDEO_FORMAT),
|
||||
new FakeMediaSource(fakeTimeline, Builder.VIDEO_FORMAT)
|
||||
};
|
||||
ConcatenatingMediaSource mediaSource =
|
||||
new ConcatenatingMediaSource(false, new FakeShuffleOrder(3), fakeMediaSources);
|
||||
|
|
@ -437,8 +436,7 @@ public final class ExoPlayerTest {
|
|||
/* isDynamic= */ false,
|
||||
/* durationUs= */ C.MICROS_PER_SECOND,
|
||||
errorAdPlaybackState));
|
||||
final FakeMediaSource fakeMediaSource =
|
||||
new FakeMediaSource(fakeTimeline, /* manifest= */ null, Builder.VIDEO_FORMAT);
|
||||
final FakeMediaSource fakeMediaSource = new FakeMediaSource(fakeTimeline, Builder.VIDEO_FORMAT);
|
||||
ActionSchedule actionSchedule =
|
||||
new ActionSchedule.Builder("testAdGroupWithLoadErrorIsSkipped")
|
||||
.pause()
|
||||
|
|
@ -585,7 +583,7 @@ public final class ExoPlayerTest {
|
|||
public void testSeekDiscontinuityWithAdjustment() throws Exception {
|
||||
FakeTimeline timeline = new FakeTimeline(1);
|
||||
FakeMediaSource mediaSource =
|
||||
new FakeMediaSource(timeline, null, Builder.VIDEO_FORMAT) {
|
||||
new FakeMediaSource(timeline, Builder.VIDEO_FORMAT) {
|
||||
@Override
|
||||
protected FakeMediaPeriod createFakeMediaPeriod(
|
||||
MediaPeriodId id,
|
||||
|
|
@ -620,7 +618,7 @@ public final class ExoPlayerTest {
|
|||
public void testInternalDiscontinuityAtNewPosition() throws Exception {
|
||||
FakeTimeline timeline = new FakeTimeline(1);
|
||||
FakeMediaSource mediaSource =
|
||||
new FakeMediaSource(timeline, null, Builder.VIDEO_FORMAT) {
|
||||
new FakeMediaSource(timeline, Builder.VIDEO_FORMAT) {
|
||||
@Override
|
||||
protected FakeMediaPeriod createFakeMediaPeriod(
|
||||
MediaPeriodId id,
|
||||
|
|
@ -646,7 +644,7 @@ public final class ExoPlayerTest {
|
|||
public void testInternalDiscontinuityAtInitialPosition() throws Exception {
|
||||
FakeTimeline timeline = new FakeTimeline(1);
|
||||
FakeMediaSource mediaSource =
|
||||
new FakeMediaSource(timeline, null, Builder.VIDEO_FORMAT) {
|
||||
new FakeMediaSource(timeline, Builder.VIDEO_FORMAT) {
|
||||
@Override
|
||||
protected FakeMediaPeriod createFakeMediaPeriod(
|
||||
MediaPeriodId id,
|
||||
|
|
@ -673,7 +671,7 @@ public final class ExoPlayerTest {
|
|||
public void testAllActivatedTrackSelectionAreReleasedForSinglePeriod() throws Exception {
|
||||
Timeline timeline = new FakeTimeline(/* windowCount= */ 1);
|
||||
MediaSource mediaSource =
|
||||
new FakeMediaSource(timeline, null, Builder.VIDEO_FORMAT, Builder.AUDIO_FORMAT);
|
||||
new FakeMediaSource(timeline, Builder.VIDEO_FORMAT, Builder.AUDIO_FORMAT);
|
||||
FakeRenderer videoRenderer = new FakeRenderer(Builder.VIDEO_FORMAT);
|
||||
FakeRenderer audioRenderer = new FakeRenderer(Builder.AUDIO_FORMAT);
|
||||
FakeTrackSelector trackSelector = new FakeTrackSelector();
|
||||
|
|
@ -702,7 +700,7 @@ public final class ExoPlayerTest {
|
|||
public void testAllActivatedTrackSelectionAreReleasedForMultiPeriods() throws Exception {
|
||||
Timeline timeline = new FakeTimeline(/* windowCount= */ 2);
|
||||
MediaSource mediaSource =
|
||||
new FakeMediaSource(timeline, null, Builder.VIDEO_FORMAT, Builder.AUDIO_FORMAT);
|
||||
new FakeMediaSource(timeline, Builder.VIDEO_FORMAT, Builder.AUDIO_FORMAT);
|
||||
FakeRenderer videoRenderer = new FakeRenderer(Builder.VIDEO_FORMAT);
|
||||
FakeRenderer audioRenderer = new FakeRenderer(Builder.AUDIO_FORMAT);
|
||||
FakeTrackSelector trackSelector = new FakeTrackSelector();
|
||||
|
|
@ -732,7 +730,7 @@ public final class ExoPlayerTest {
|
|||
throws Exception {
|
||||
Timeline timeline = new FakeTimeline(/* windowCount= */ 1);
|
||||
MediaSource mediaSource =
|
||||
new FakeMediaSource(timeline, null, Builder.VIDEO_FORMAT, Builder.AUDIO_FORMAT);
|
||||
new FakeMediaSource(timeline, Builder.VIDEO_FORMAT, Builder.AUDIO_FORMAT);
|
||||
FakeRenderer videoRenderer = new FakeRenderer(Builder.VIDEO_FORMAT);
|
||||
FakeRenderer audioRenderer = new FakeRenderer(Builder.AUDIO_FORMAT);
|
||||
final FakeTrackSelector trackSelector = new FakeTrackSelector();
|
||||
|
|
@ -771,7 +769,7 @@ public final class ExoPlayerTest {
|
|||
throws Exception {
|
||||
Timeline timeline = new FakeTimeline(/* windowCount= */ 1);
|
||||
MediaSource mediaSource =
|
||||
new FakeMediaSource(timeline, null, Builder.VIDEO_FORMAT, Builder.AUDIO_FORMAT);
|
||||
new FakeMediaSource(timeline, Builder.VIDEO_FORMAT, Builder.AUDIO_FORMAT);
|
||||
FakeRenderer videoRenderer = new FakeRenderer(Builder.VIDEO_FORMAT);
|
||||
FakeRenderer audioRenderer = new FakeRenderer(Builder.AUDIO_FORMAT);
|
||||
final FakeTrackSelector trackSelector = new FakeTrackSelector(/* reuse track selection */ true);
|
||||
|
|
@ -810,7 +808,7 @@ public final class ExoPlayerTest {
|
|||
public void testDynamicTimelineChangeReason() throws Exception {
|
||||
Timeline timeline1 = new FakeTimeline(new TimelineWindowDefinition(false, false, 100000));
|
||||
final Timeline timeline2 = new FakeTimeline(new TimelineWindowDefinition(false, false, 20000));
|
||||
final FakeMediaSource mediaSource = new FakeMediaSource(timeline1, null, Builder.VIDEO_FORMAT);
|
||||
final FakeMediaSource mediaSource = new FakeMediaSource(timeline1, Builder.VIDEO_FORMAT);
|
||||
ActionSchedule actionSchedule =
|
||||
new ActionSchedule.Builder("testDynamicTimelineChangeReason")
|
||||
.pause()
|
||||
|
|
@ -841,14 +839,14 @@ public final class ExoPlayerTest {
|
|||
new ConcatenatingMediaSource(
|
||||
/* isAtomic= */ false,
|
||||
new FakeShuffleOrder(/* length= */ 2),
|
||||
new FakeMediaSource(fakeTimeline, null, Builder.VIDEO_FORMAT),
|
||||
new FakeMediaSource(fakeTimeline, null, Builder.VIDEO_FORMAT));
|
||||
new FakeMediaSource(fakeTimeline, Builder.VIDEO_FORMAT),
|
||||
new FakeMediaSource(fakeTimeline, Builder.VIDEO_FORMAT));
|
||||
ConcatenatingMediaSource secondMediaSource =
|
||||
new ConcatenatingMediaSource(
|
||||
/* isAtomic= */ false,
|
||||
new FakeShuffleOrder(/* length= */ 2),
|
||||
new FakeMediaSource(fakeTimeline, null, Builder.VIDEO_FORMAT),
|
||||
new FakeMediaSource(fakeTimeline, null, Builder.VIDEO_FORMAT));
|
||||
new FakeMediaSource(fakeTimeline, Builder.VIDEO_FORMAT),
|
||||
new FakeMediaSource(fakeTimeline, Builder.VIDEO_FORMAT));
|
||||
ActionSchedule actionSchedule =
|
||||
new ActionSchedule.Builder("testRepreparationWithShuffle")
|
||||
// Wait for first preparation and enable shuffling. Plays period 0.
|
||||
|
|
@ -877,7 +875,7 @@ public final class ExoPlayerTest {
|
|||
final CountDownLatch createPeriodCalledCountDownLatch = new CountDownLatch(1);
|
||||
final FakeMediaPeriod[] fakeMediaPeriodHolder = new FakeMediaPeriod[1];
|
||||
MediaSource mediaSource =
|
||||
new FakeMediaSource(new FakeTimeline(/* windowCount= */ 1), null, Builder.VIDEO_FORMAT) {
|
||||
new FakeMediaSource(new FakeTimeline(/* windowCount= */ 1), Builder.VIDEO_FORMAT) {
|
||||
@Override
|
||||
protected FakeMediaPeriod createFakeMediaPeriod(
|
||||
MediaPeriodId id,
|
||||
|
|
@ -1017,8 +1015,7 @@ public final class ExoPlayerTest {
|
|||
@Test
|
||||
public void testStopWithoutResetReleasesMediaSource() throws Exception {
|
||||
Timeline timeline = new FakeTimeline(/* windowCount= */ 1);
|
||||
final FakeMediaSource mediaSource =
|
||||
new FakeMediaSource(timeline, /* manifest= */ null, Builder.VIDEO_FORMAT);
|
||||
final FakeMediaSource mediaSource = new FakeMediaSource(timeline, Builder.VIDEO_FORMAT);
|
||||
ActionSchedule actionSchedule =
|
||||
new ActionSchedule.Builder("testStopReleasesMediaSource")
|
||||
.waitForPlaybackState(Player.STATE_READY)
|
||||
|
|
@ -1038,8 +1035,7 @@ public final class ExoPlayerTest {
|
|||
@Test
|
||||
public void testStopWithResetReleasesMediaSource() throws Exception {
|
||||
Timeline timeline = new FakeTimeline(/* windowCount= */ 1);
|
||||
final FakeMediaSource mediaSource =
|
||||
new FakeMediaSource(timeline, /* manifest= */ null, Builder.VIDEO_FORMAT);
|
||||
final FakeMediaSource mediaSource = new FakeMediaSource(timeline, Builder.VIDEO_FORMAT);
|
||||
ActionSchedule actionSchedule =
|
||||
new ActionSchedule.Builder("testStopReleasesMediaSource")
|
||||
.waitForPlaybackState(Player.STATE_READY)
|
||||
|
|
@ -1059,7 +1055,7 @@ public final class ExoPlayerTest {
|
|||
@Test
|
||||
public void testRepreparationDoesNotResetAfterStopWithReset() throws Exception {
|
||||
Timeline timeline = new FakeTimeline(/* windowCount= */ 1);
|
||||
MediaSource secondSource = new FakeMediaSource(timeline, null, Builder.VIDEO_FORMAT);
|
||||
MediaSource secondSource = new FakeMediaSource(timeline, Builder.VIDEO_FORMAT);
|
||||
ActionSchedule actionSchedule =
|
||||
new ActionSchedule.Builder("testRepreparationAfterStop")
|
||||
.waitForPlaybackState(Player.STATE_READY)
|
||||
|
|
@ -1087,7 +1083,7 @@ public final class ExoPlayerTest {
|
|||
public void testSeekBeforeRepreparationPossibleAfterStopWithReset() throws Exception {
|
||||
Timeline timeline = new FakeTimeline(/* windowCount= */ 1);
|
||||
Timeline secondTimeline = new FakeTimeline(/* windowCount= */ 2);
|
||||
MediaSource secondSource = new FakeMediaSource(secondTimeline, null, Builder.VIDEO_FORMAT);
|
||||
MediaSource secondSource = new FakeMediaSource(secondTimeline, Builder.VIDEO_FORMAT);
|
||||
ActionSchedule actionSchedule =
|
||||
new ActionSchedule.Builder("testSeekAfterStopWithReset")
|
||||
.waitForPlaybackState(Player.STATE_READY)
|
||||
|
|
@ -1122,7 +1118,7 @@ public final class ExoPlayerTest {
|
|||
Timeline secondTimeline =
|
||||
new FakeTimeline(
|
||||
new TimelineWindowDefinition(/* periodCount= */ 1, /* id= */ new Object()));
|
||||
MediaSource secondSource = new FakeMediaSource(secondTimeline, /* manifest= */ null);
|
||||
MediaSource secondSource = new FakeMediaSource(secondTimeline);
|
||||
AtomicLong positionAfterReprepare = new AtomicLong();
|
||||
ActionSchedule actionSchedule =
|
||||
new ActionSchedule.Builder("testReprepareAndKeepPositionWithNewMediaSource")
|
||||
|
|
@ -1211,9 +1207,7 @@ public final class ExoPlayerTest {
|
|||
.throwPlaybackException(ExoPlaybackException.createForSource(new IOException()))
|
||||
.waitForPlaybackState(Player.STATE_IDLE)
|
||||
.prepareSource(
|
||||
new FakeMediaSource(timeline, /* manifest= */ null),
|
||||
/* resetPosition= */ true,
|
||||
/* resetState= */ false)
|
||||
new FakeMediaSource(timeline), /* resetPosition= */ true, /* resetState= */ false)
|
||||
.waitForPlaybackState(Player.STATE_READY)
|
||||
.build();
|
||||
ExoPlayerTestRunner testRunner =
|
||||
|
|
@ -1252,9 +1246,7 @@ public final class ExoPlayerTest {
|
|||
}
|
||||
})
|
||||
.prepareSource(
|
||||
new FakeMediaSource(timeline, /* manifest= */ null),
|
||||
/* resetPosition= */ false,
|
||||
/* resetState= */ false)
|
||||
new FakeMediaSource(timeline), /* resetPosition= */ false, /* resetState= */ false)
|
||||
.waitForPlaybackState(Player.STATE_READY)
|
||||
.executeRunnable(
|
||||
new PlayerRunnable() {
|
||||
|
|
@ -1287,8 +1279,7 @@ public final class ExoPlayerTest {
|
|||
@Test
|
||||
public void testInvalidSeekPositionAfterSourceInfoRefreshStillUpdatesTimeline() throws Exception {
|
||||
final Timeline timeline = new FakeTimeline(/* windowCount= */ 1);
|
||||
final FakeMediaSource mediaSource =
|
||||
new FakeMediaSource(/* timeline= */ null, /* manifest= */ null);
|
||||
final FakeMediaSource mediaSource = new FakeMediaSource(/* timeline= */ null);
|
||||
ActionSchedule actionSchedule =
|
||||
new ActionSchedule.Builder("testInvalidSeekPositionSourceInfoRefreshStillUpdatesTimeline")
|
||||
.waitForPlaybackState(Player.STATE_BUFFERING)
|
||||
|
|
@ -1312,8 +1303,7 @@ public final class ExoPlayerTest {
|
|||
public void
|
||||
testInvalidSeekPositionAfterSourceInfoRefreshWithShuffleModeEnabledUsesCorrectFirstPeriod()
|
||||
throws Exception {
|
||||
FakeMediaSource mediaSource =
|
||||
new FakeMediaSource(new FakeTimeline(/* windowCount= */ 1), /* manifest= */ null);
|
||||
FakeMediaSource mediaSource = new FakeMediaSource(new FakeTimeline(/* windowCount= */ 1));
|
||||
ConcatenatingMediaSource concatenatingMediaSource =
|
||||
new ConcatenatingMediaSource(
|
||||
/* isAtomic= */ false, new FakeShuffleOrder(0), mediaSource, mediaSource);
|
||||
|
|
@ -1347,7 +1337,7 @@ public final class ExoPlayerTest {
|
|||
public void testRestartAfterEmptyTimelineWithShuffleModeEnabledUsesCorrectFirstPeriod()
|
||||
throws Exception {
|
||||
Timeline timeline = new FakeTimeline(/* windowCount= */ 1);
|
||||
FakeMediaSource mediaSource = new FakeMediaSource(timeline, /* manifest= */ null);
|
||||
FakeMediaSource mediaSource = new FakeMediaSource(timeline);
|
||||
ConcatenatingMediaSource concatenatingMediaSource =
|
||||
new ConcatenatingMediaSource(/* isAtomic= */ false, new FakeShuffleOrder(0));
|
||||
AtomicInteger windowIndexAfterAddingSources = new AtomicInteger();
|
||||
|
|
@ -1386,8 +1376,7 @@ public final class ExoPlayerTest {
|
|||
final Timeline timeline = new FakeTimeline(/* windowCount= */ 2);
|
||||
final long[] positionHolder = new long[3];
|
||||
final int[] windowIndexHolder = new int[3];
|
||||
final FakeMediaSource secondMediaSource =
|
||||
new FakeMediaSource(/* timeline= */ null, /* manifest= */ null);
|
||||
final FakeMediaSource secondMediaSource = new FakeMediaSource(/* timeline= */ null);
|
||||
ActionSchedule actionSchedule =
|
||||
new ActionSchedule.Builder("testPlaybackErrorDoesNotResetPosition")
|
||||
.pause()
|
||||
|
|
@ -1450,8 +1439,7 @@ public final class ExoPlayerTest {
|
|||
@Test
|
||||
public void testPlaybackErrorTwiceStillKeepsTimeline() throws Exception {
|
||||
final Timeline timeline = new FakeTimeline(/* windowCount= */ 1);
|
||||
final FakeMediaSource mediaSource2 =
|
||||
new FakeMediaSource(/* timeline= */ null, /* manifest= */ null);
|
||||
final FakeMediaSource mediaSource2 = new FakeMediaSource(/* timeline= */ null);
|
||||
ActionSchedule actionSchedule =
|
||||
new ActionSchedule.Builder("testPlaybackErrorDoesNotResetPosition")
|
||||
.pause()
|
||||
|
|
@ -1609,9 +1597,7 @@ public final class ExoPlayerTest {
|
|||
// messages sent at end of playback are received before test ends.
|
||||
.waitForPlaybackState(Player.STATE_ENDED)
|
||||
.prepareSource(
|
||||
new FakeMediaSource(timeline, null),
|
||||
/* resetPosition= */ false,
|
||||
/* resetState= */ true)
|
||||
new FakeMediaSource(timeline), /* resetPosition= */ false, /* resetState= */ true)
|
||||
.waitForPlaybackState(Player.STATE_BUFFERING)
|
||||
.waitForPlaybackState(Player.STATE_ENDED)
|
||||
.build();
|
||||
|
|
@ -1774,7 +1760,7 @@ public final class ExoPlayerTest {
|
|||
new FakeTimeline(
|
||||
new TimelineWindowDefinition(/* periodCount= */ 1, /* id= */ 1),
|
||||
new TimelineWindowDefinition(/* periodCount= */ 1, /* id= */ 0));
|
||||
final FakeMediaSource mediaSource = new FakeMediaSource(timeline, null, Builder.VIDEO_FORMAT);
|
||||
final FakeMediaSource mediaSource = new FakeMediaSource(timeline, Builder.VIDEO_FORMAT);
|
||||
PositionGrabbingMessageTarget target = new PositionGrabbingMessageTarget();
|
||||
ActionSchedule actionSchedule =
|
||||
new ActionSchedule.Builder("testSendMessages")
|
||||
|
|
@ -1847,7 +1833,7 @@ public final class ExoPlayerTest {
|
|||
new FakeTimeline(
|
||||
new TimelineWindowDefinition(/* periodCount= */ 1, /* id= */ 1),
|
||||
new TimelineWindowDefinition(/* periodCount= */ 1, /* id= */ 0));
|
||||
final FakeMediaSource mediaSource = new FakeMediaSource(timeline, null, Builder.VIDEO_FORMAT);
|
||||
final FakeMediaSource mediaSource = new FakeMediaSource(timeline, Builder.VIDEO_FORMAT);
|
||||
PositionGrabbingMessageTarget target = new PositionGrabbingMessageTarget();
|
||||
ActionSchedule actionSchedule =
|
||||
new ActionSchedule.Builder("testSendMessages")
|
||||
|
|
@ -1873,9 +1859,9 @@ public final class ExoPlayerTest {
|
|||
public void testSendMessagesNonLinearPeriodOrder() throws Exception {
|
||||
Timeline fakeTimeline = new FakeTimeline(/* windowCount= */ 1);
|
||||
MediaSource[] fakeMediaSources = {
|
||||
new FakeMediaSource(fakeTimeline, null, Builder.VIDEO_FORMAT),
|
||||
new FakeMediaSource(fakeTimeline, null, Builder.VIDEO_FORMAT),
|
||||
new FakeMediaSource(fakeTimeline, null, Builder.VIDEO_FORMAT)
|
||||
new FakeMediaSource(fakeTimeline, Builder.VIDEO_FORMAT),
|
||||
new FakeMediaSource(fakeTimeline, Builder.VIDEO_FORMAT),
|
||||
new FakeMediaSource(fakeTimeline, Builder.VIDEO_FORMAT)
|
||||
};
|
||||
ConcatenatingMediaSource mediaSource =
|
||||
new ConcatenatingMediaSource(false, new FakeShuffleOrder(3), fakeMediaSources);
|
||||
|
|
@ -2022,8 +2008,7 @@ public final class ExoPlayerTest {
|
|||
new FakeTimeline(
|
||||
new TimelineWindowDefinition(/* periodCount= */ 1, /* id= */ 1),
|
||||
new TimelineWindowDefinition(/* periodCount= */ 1, /* id= */ 3));
|
||||
final FakeMediaSource mediaSource =
|
||||
new FakeMediaSource(timeline1, /* manifest= */ null, Builder.VIDEO_FORMAT);
|
||||
final FakeMediaSource mediaSource = new FakeMediaSource(timeline1, Builder.VIDEO_FORMAT);
|
||||
ActionSchedule actionSchedule =
|
||||
new ActionSchedule.Builder("testTimelineUpdateDropsPeriods")
|
||||
.pause()
|
||||
|
|
@ -2069,7 +2054,7 @@ public final class ExoPlayerTest {
|
|||
/* isSeekable= */ true,
|
||||
/* isDynamic= */ false,
|
||||
/* durationUs= */ 10 * C.MICROS_PER_SECOND));
|
||||
FakeMediaSource mediaSource = new FakeMediaSource(timeline, /* manifest= */ null);
|
||||
FakeMediaSource mediaSource = new FakeMediaSource(timeline);
|
||||
ActionSchedule actionSchedule =
|
||||
new ActionSchedule.Builder("testSeekToUnpreparedPeriod")
|
||||
.pause()
|
||||
|
|
@ -2163,7 +2148,7 @@ public final class ExoPlayerTest {
|
|||
final EventListener eventListener =
|
||||
new EventListener() {
|
||||
@Override
|
||||
public void onTimelineChanged(Timeline timeline, @Nullable Object manifest, int reason) {
|
||||
public void onTimelineChanged(Timeline timeline, int reason) {
|
||||
if (timeline.isEmpty()) {
|
||||
playerReference.get().setPlayWhenReady(/* playWhenReady= */ false);
|
||||
}
|
||||
|
|
@ -2208,7 +2193,7 @@ public final class ExoPlayerTest {
|
|||
long expectedDurationUs = 700_000;
|
||||
MediaSource mediaSource =
|
||||
new ClippingMediaSource(
|
||||
new FakeMediaSource(new FakeTimeline(/* windowCount= */ 1), /* manifest= */ null),
|
||||
new FakeMediaSource(new FakeTimeline(/* windowCount= */ 1)),
|
||||
startPositionUs,
|
||||
startPositionUs + expectedDurationUs);
|
||||
Clock clock = new AutoAdvancingFakeClock();
|
||||
|
|
@ -2274,8 +2259,8 @@ public final class ExoPlayerTest {
|
|||
new TimelineWindowDefinition(
|
||||
/* isSeekable= */ true, /* isDynamic= */ false, /* durationUs= */ C.TIME_UNSET));
|
||||
MediaSource[] fakeMediaSources = {
|
||||
new FakeMediaSource(fakeTimeline, null, Builder.VIDEO_FORMAT),
|
||||
new FakeMediaSource(fakeTimeline, null, Builder.AUDIO_FORMAT)
|
||||
new FakeMediaSource(fakeTimeline, Builder.VIDEO_FORMAT),
|
||||
new FakeMediaSource(fakeTimeline, Builder.AUDIO_FORMAT)
|
||||
};
|
||||
MediaSource mediaSource = new ConcatenatingMediaSource(fakeMediaSources);
|
||||
FakeRenderer renderer = new FakeRenderer(Builder.VIDEO_FORMAT);
|
||||
|
|
@ -2326,10 +2311,9 @@ public final class ExoPlayerTest {
|
|||
/* isSeekable= */ true,
|
||||
/* isDynamic= */ false,
|
||||
/* durationUs= */ 10 * C.MICROS_PER_SECOND));
|
||||
MediaSource workingMediaSource =
|
||||
new FakeMediaSource(fakeTimeline, /* manifest= */ null, Builder.VIDEO_FORMAT);
|
||||
MediaSource workingMediaSource = new FakeMediaSource(fakeTimeline, Builder.VIDEO_FORMAT);
|
||||
MediaSource failingMediaSource =
|
||||
new FakeMediaSource(/* timeline= */ null, /* manifest= */ null, Builder.VIDEO_FORMAT) {
|
||||
new FakeMediaSource(/* timeline= */ null, Builder.VIDEO_FORMAT) {
|
||||
@Override
|
||||
public void maybeThrowSourceInfoRefreshError() throws IOException {
|
||||
throw new IOException();
|
||||
|
|
@ -2363,10 +2347,9 @@ public final class ExoPlayerTest {
|
|||
/* isSeekable= */ true,
|
||||
/* isDynamic= */ false,
|
||||
/* durationUs= */ 10 * C.MICROS_PER_SECOND));
|
||||
MediaSource workingMediaSource =
|
||||
new FakeMediaSource(fakeTimeline, /* manifest= */ null, Builder.VIDEO_FORMAT);
|
||||
MediaSource workingMediaSource = new FakeMediaSource(fakeTimeline, Builder.VIDEO_FORMAT);
|
||||
MediaSource failingMediaSource =
|
||||
new FakeMediaSource(/* timeline= */ null, /* manifest= */ null, Builder.VIDEO_FORMAT) {
|
||||
new FakeMediaSource(/* timeline= */ null, Builder.VIDEO_FORMAT) {
|
||||
@Override
|
||||
public void maybeThrowSourceInfoRefreshError() throws IOException {
|
||||
throw new IOException();
|
||||
|
|
@ -2408,7 +2391,7 @@ public final class ExoPlayerTest {
|
|||
/* durationUs= */ 10 * C.MICROS_PER_SECOND));
|
||||
AtomicReference<Boolean> wasReadyOnce = new AtomicReference<>(false);
|
||||
MediaSource mediaSource =
|
||||
new FakeMediaSource(fakeTimeline, /* manifest= */ null, Builder.VIDEO_FORMAT) {
|
||||
new FakeMediaSource(fakeTimeline, Builder.VIDEO_FORMAT) {
|
||||
@Override
|
||||
public void maybeThrowSourceInfoRefreshError() throws IOException {
|
||||
if (wasReadyOnce.get()) {
|
||||
|
|
@ -2446,7 +2429,7 @@ public final class ExoPlayerTest {
|
|||
new FakeTimeline(
|
||||
new TimelineWindowDefinition(
|
||||
/* isSeekable= */ true, /* isDynamic= */ true, /* durationUs= */ 100_000));
|
||||
MediaSource mediaSource = new FakeMediaSource(timeline, /* manifest= */ null);
|
||||
MediaSource mediaSource = new FakeMediaSource(timeline);
|
||||
ConcatenatingMediaSource concatenatingMediaSource = new ConcatenatingMediaSource(mediaSource);
|
||||
ActionSchedule actionSchedule =
|
||||
new ActionSchedule.Builder("removingLoopingLastPeriodFromPlaylistDoesNotThrow")
|
||||
|
|
@ -2471,7 +2454,7 @@ public final class ExoPlayerTest {
|
|||
public void seekToUnpreparedWindowWithNonZeroOffsetInConcatenationStartsAtCorrectPosition()
|
||||
throws Exception {
|
||||
Timeline timeline = new FakeTimeline(/* windowCount= */ 1);
|
||||
FakeMediaSource mediaSource = new FakeMediaSource(/* timeline= */ null, /* manifest= */ null);
|
||||
FakeMediaSource mediaSource = new FakeMediaSource(/* timeline= */ null);
|
||||
MediaSource clippedMediaSource =
|
||||
new ClippingMediaSource(
|
||||
mediaSource,
|
||||
|
|
@ -2519,7 +2502,7 @@ public final class ExoPlayerTest {
|
|||
/* isSeekable= */ true,
|
||||
/* isDynamic= */ false,
|
||||
/* durationUs= */ 2 * periodDurationMs * 1000));
|
||||
FakeMediaSource mediaSource = new FakeMediaSource(/* timeline= */ null, /* manifest= */ null);
|
||||
FakeMediaSource mediaSource = new FakeMediaSource(/* timeline= */ null);
|
||||
MediaSource concatenatedMediaSource = new ConcatenatingMediaSource(mediaSource);
|
||||
AtomicInteger periodIndexWhenReady = new AtomicInteger();
|
||||
AtomicLong positionWhenReady = new AtomicLong();
|
||||
|
|
|
|||
|
|
@ -353,7 +353,6 @@ public final class MediaPeriodQueueTest {
|
|||
playbackInfo =
|
||||
new PlaybackInfo(
|
||||
timeline,
|
||||
/* manifest= */ null,
|
||||
mediaPeriodQueue.resolveMediaPeriodIdForAds(periodUid, initialPositionUs),
|
||||
/* startPositionUs= */ 0,
|
||||
/* contentPositionUs= */ 0,
|
||||
|
|
|
|||
|
|
@ -125,7 +125,9 @@ public final class AnalyticsCollectorTest {
|
|||
public void testEmptyTimeline() throws Exception {
|
||||
FakeMediaSource mediaSource =
|
||||
new FakeMediaSource(
|
||||
Timeline.EMPTY, /* manifest= */ null, Builder.VIDEO_FORMAT, Builder.AUDIO_FORMAT);
|
||||
Timeline.EMPTY,
|
||||
ExoPlayerTestRunner.Builder.VIDEO_FORMAT,
|
||||
ExoPlayerTestRunner.Builder.AUDIO_FORMAT);
|
||||
TestAnalyticsListener listener = runAnalyticsTest(mediaSource);
|
||||
|
||||
assertThat(listener.getEvents(EVENT_PLAYER_STATE_CHANGED))
|
||||
|
|
@ -140,7 +142,6 @@ public final class AnalyticsCollectorTest {
|
|||
FakeMediaSource mediaSource =
|
||||
new FakeMediaSource(
|
||||
SINGLE_PERIOD_TIMELINE,
|
||||
/* manifest= */ null,
|
||||
Builder.VIDEO_FORMAT,
|
||||
Builder.AUDIO_FORMAT);
|
||||
TestAnalyticsListener listener = runAnalyticsTest(mediaSource);
|
||||
|
|
@ -183,12 +184,10 @@ public final class AnalyticsCollectorTest {
|
|||
new ConcatenatingMediaSource(
|
||||
new FakeMediaSource(
|
||||
SINGLE_PERIOD_TIMELINE,
|
||||
/* manifest= */ null,
|
||||
Builder.VIDEO_FORMAT,
|
||||
Builder.AUDIO_FORMAT),
|
||||
new FakeMediaSource(
|
||||
SINGLE_PERIOD_TIMELINE,
|
||||
/* manifest= */ null,
|
||||
Builder.VIDEO_FORMAT,
|
||||
Builder.AUDIO_FORMAT));
|
||||
TestAnalyticsListener listener = runAnalyticsTest(mediaSource);
|
||||
|
|
@ -242,9 +241,8 @@ public final class AnalyticsCollectorTest {
|
|||
public void testPeriodTransitionWithRendererChange() throws Exception {
|
||||
MediaSource mediaSource =
|
||||
new ConcatenatingMediaSource(
|
||||
new FakeMediaSource(SINGLE_PERIOD_TIMELINE, /* manifest= */ null, Builder.VIDEO_FORMAT),
|
||||
new FakeMediaSource(
|
||||
SINGLE_PERIOD_TIMELINE, /* manifest= */ null, Builder.AUDIO_FORMAT));
|
||||
new FakeMediaSource(SINGLE_PERIOD_TIMELINE, Builder.VIDEO_FORMAT),
|
||||
new FakeMediaSource(SINGLE_PERIOD_TIMELINE, Builder.AUDIO_FORMAT));
|
||||
TestAnalyticsListener listener = runAnalyticsTest(mediaSource);
|
||||
|
||||
populateEventIds(listener.lastReportedTimeline);
|
||||
|
|
@ -296,9 +294,8 @@ public final class AnalyticsCollectorTest {
|
|||
public void testSeekToOtherPeriod() throws Exception {
|
||||
MediaSource mediaSource =
|
||||
new ConcatenatingMediaSource(
|
||||
new FakeMediaSource(SINGLE_PERIOD_TIMELINE, /* manifest= */ null, Builder.VIDEO_FORMAT),
|
||||
new FakeMediaSource(
|
||||
SINGLE_PERIOD_TIMELINE, /* manifest= */ null, Builder.AUDIO_FORMAT));
|
||||
new FakeMediaSource(SINGLE_PERIOD_TIMELINE, Builder.VIDEO_FORMAT),
|
||||
new FakeMediaSource(SINGLE_PERIOD_TIMELINE, Builder.AUDIO_FORMAT));
|
||||
ActionSchedule actionSchedule =
|
||||
new ActionSchedule.Builder("AnalyticsCollectorTest")
|
||||
.pause()
|
||||
|
|
@ -361,12 +358,9 @@ public final class AnalyticsCollectorTest {
|
|||
public void testSeekBackAfterReadingAhead() throws Exception {
|
||||
MediaSource mediaSource =
|
||||
new ConcatenatingMediaSource(
|
||||
new FakeMediaSource(SINGLE_PERIOD_TIMELINE, /* manifest= */ null, Builder.VIDEO_FORMAT),
|
||||
new FakeMediaSource(SINGLE_PERIOD_TIMELINE, Builder.VIDEO_FORMAT),
|
||||
new FakeMediaSource(
|
||||
SINGLE_PERIOD_TIMELINE,
|
||||
/* manifest= */ null,
|
||||
Builder.VIDEO_FORMAT,
|
||||
Builder.AUDIO_FORMAT));
|
||||
SINGLE_PERIOD_TIMELINE, Builder.VIDEO_FORMAT, Builder.AUDIO_FORMAT));
|
||||
long periodDurationMs =
|
||||
SINGLE_PERIOD_TIMELINE.getWindow(/* windowIndex= */ 0, new Window()).getDurationMs();
|
||||
ActionSchedule actionSchedule =
|
||||
|
|
@ -443,10 +437,8 @@ public final class AnalyticsCollectorTest {
|
|||
|
||||
@Test
|
||||
public void testPrepareNewSource() throws Exception {
|
||||
MediaSource mediaSource1 =
|
||||
new FakeMediaSource(SINGLE_PERIOD_TIMELINE, /* manifest= */ null, Builder.VIDEO_FORMAT);
|
||||
MediaSource mediaSource2 =
|
||||
new FakeMediaSource(SINGLE_PERIOD_TIMELINE, /* manifest= */ null, Builder.VIDEO_FORMAT);
|
||||
MediaSource mediaSource1 = new FakeMediaSource(SINGLE_PERIOD_TIMELINE, Builder.VIDEO_FORMAT);
|
||||
MediaSource mediaSource2 = new FakeMediaSource(SINGLE_PERIOD_TIMELINE, Builder.VIDEO_FORMAT);
|
||||
ActionSchedule actionSchedule =
|
||||
new ActionSchedule.Builder("AnalyticsCollectorTest")
|
||||
.pause()
|
||||
|
|
@ -507,8 +499,7 @@ public final class AnalyticsCollectorTest {
|
|||
|
||||
@Test
|
||||
public void testReprepareAfterError() throws Exception {
|
||||
MediaSource mediaSource =
|
||||
new FakeMediaSource(SINGLE_PERIOD_TIMELINE, /* manifest= */ null, Builder.VIDEO_FORMAT);
|
||||
MediaSource mediaSource = new FakeMediaSource(SINGLE_PERIOD_TIMELINE, Builder.VIDEO_FORMAT);
|
||||
ActionSchedule actionSchedule =
|
||||
new ActionSchedule.Builder("AnalyticsCollectorTest")
|
||||
.waitForPlaybackState(Player.STATE_READY)
|
||||
|
|
@ -570,7 +561,7 @@ public final class AnalyticsCollectorTest {
|
|||
@Test
|
||||
public void testDynamicTimelineChange() throws Exception {
|
||||
MediaSource childMediaSource =
|
||||
new FakeMediaSource(SINGLE_PERIOD_TIMELINE, /* manifest= */ null, Builder.VIDEO_FORMAT);
|
||||
new FakeMediaSource(SINGLE_PERIOD_TIMELINE, Builder.VIDEO_FORMAT);
|
||||
final ConcatenatingMediaSource concatenatedMediaSource =
|
||||
new ConcatenatingMediaSource(childMediaSource, childMediaSource);
|
||||
long periodDurationMs =
|
||||
|
|
@ -639,7 +630,7 @@ public final class AnalyticsCollectorTest {
|
|||
|
||||
@Test
|
||||
public void testNotifyExternalEvents() throws Exception {
|
||||
MediaSource mediaSource = new FakeMediaSource(SINGLE_PERIOD_TIMELINE, /* manifest= */ null);
|
||||
MediaSource mediaSource = new FakeMediaSource(SINGLE_PERIOD_TIMELINE);
|
||||
ActionSchedule actionSchedule =
|
||||
new ActionSchedule.Builder("AnalyticsCollectorTest")
|
||||
.pause()
|
||||
|
|
|
|||
|
|
@ -60,9 +60,11 @@ public class DownloadHelperTest {
|
|||
|
||||
private static final String TEST_DOWNLOAD_TYPE = "downloadType";
|
||||
private static final String TEST_CACHE_KEY = "cacheKey";
|
||||
private static final Timeline TEST_TIMELINE =
|
||||
new FakeTimeline(new TimelineWindowDefinition(/* periodCount= */ 2, /* id= */ new Object()));
|
||||
private static final Object TEST_MANIFEST = new Object();
|
||||
private static final Timeline TEST_TIMELINE =
|
||||
new FakeTimeline(
|
||||
new Object[] {TEST_MANIFEST},
|
||||
new TimelineWindowDefinition(/* periodCount= */ 2, /* id= */ new Object()));
|
||||
|
||||
private static final Format VIDEO_FORMAT_LOW = createVideoFormat(/* bitrate= */ 200_000);
|
||||
private static final Format VIDEO_FORMAT_HIGH = createVideoFormat(/* bitrate= */ 800_000);
|
||||
|
|
@ -491,7 +493,7 @@ public class DownloadHelperTest {
|
|||
private static final class TestMediaSource extends FakeMediaSource {
|
||||
|
||||
public TestMediaSource() {
|
||||
super(TEST_TIMELINE, TEST_MANIFEST);
|
||||
super(TEST_TIMELINE);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
|||
|
|
@ -185,6 +185,7 @@ public final class ClippingMediaSourceTest {
|
|||
/* windowDefaultStartPositionUs= */ TEST_CLIP_AMOUNT_US,
|
||||
/* isSeekable= */ true,
|
||||
/* isDynamic= */ true,
|
||||
/* manifest= */ null,
|
||||
/* tag= */ null);
|
||||
|
||||
Timeline clippedTimeline = getClippedTimeline(timeline, /* durationUs= */ TEST_CLIP_AMOUNT_US);
|
||||
|
|
@ -206,6 +207,7 @@ public final class ClippingMediaSourceTest {
|
|||
/* windowDefaultStartPositionUs= */ TEST_CLIP_AMOUNT_US,
|
||||
/* isSeekable= */ true,
|
||||
/* isDynamic= */ true,
|
||||
/* manifest= */ null,
|
||||
/* tag= */ null);
|
||||
Timeline timeline2 =
|
||||
new SinglePeriodTimeline(
|
||||
|
|
@ -215,6 +217,7 @@ public final class ClippingMediaSourceTest {
|
|||
/* windowDefaultStartPositionUs= */ TEST_CLIP_AMOUNT_US,
|
||||
/* isSeekable= */ true,
|
||||
/* isDynamic= */ true,
|
||||
/* manifest= */ null,
|
||||
/* tag= */ null);
|
||||
|
||||
Timeline[] clippedTimelines =
|
||||
|
|
@ -253,6 +256,7 @@ public final class ClippingMediaSourceTest {
|
|||
/* windowDefaultStartPositionUs= */ TEST_CLIP_AMOUNT_US,
|
||||
/* isSeekable= */ true,
|
||||
/* isDynamic= */ true,
|
||||
/* manifest= */ null,
|
||||
/* tag= */ null);
|
||||
Timeline timeline2 =
|
||||
new SinglePeriodTimeline(
|
||||
|
|
@ -262,6 +266,7 @@ public final class ClippingMediaSourceTest {
|
|||
/* windowDefaultStartPositionUs= */ TEST_CLIP_AMOUNT_US,
|
||||
/* isSeekable= */ true,
|
||||
/* isDynamic= */ true,
|
||||
/* manifest= */ null,
|
||||
/* tag= */ null);
|
||||
|
||||
Timeline[] clippedTimelines =
|
||||
|
|
@ -300,6 +305,7 @@ public final class ClippingMediaSourceTest {
|
|||
/* windowDefaultStartPositionUs= */ TEST_CLIP_AMOUNT_US,
|
||||
/* isSeekable= */ true,
|
||||
/* isDynamic= */ true,
|
||||
/* manifest= */ null,
|
||||
/* tag= */ null);
|
||||
Timeline timeline2 =
|
||||
new SinglePeriodTimeline(
|
||||
|
|
@ -309,6 +315,7 @@ public final class ClippingMediaSourceTest {
|
|||
/* windowDefaultStartPositionUs= */ TEST_CLIP_AMOUNT_US,
|
||||
/* isSeekable= */ true,
|
||||
/* isDynamic= */ true,
|
||||
/* manifest= */ null,
|
||||
/* tag= */ null);
|
||||
|
||||
Timeline[] clippedTimelines =
|
||||
|
|
@ -348,6 +355,7 @@ public final class ClippingMediaSourceTest {
|
|||
/* windowDefaultStartPositionUs= */ TEST_CLIP_AMOUNT_US,
|
||||
/* isSeekable= */ true,
|
||||
/* isDynamic= */ true,
|
||||
/* manifest= */ null,
|
||||
/* tag= */ null);
|
||||
Timeline timeline2 =
|
||||
new SinglePeriodTimeline(
|
||||
|
|
@ -357,6 +365,7 @@ public final class ClippingMediaSourceTest {
|
|||
/* windowDefaultStartPositionUs= */ TEST_CLIP_AMOUNT_US,
|
||||
/* isSeekable= */ true,
|
||||
/* isDynamic= */ true,
|
||||
/* manifest= */ null,
|
||||
/* tag= */ null);
|
||||
|
||||
Timeline[] clippedTimelines =
|
||||
|
|
@ -473,7 +482,7 @@ public final class ClippingMediaSourceTest {
|
|||
new SinglePeriodTimeline(
|
||||
TEST_PERIOD_DURATION_US, /* isSeekable= */ true, /* isDynamic= */ false);
|
||||
FakeMediaSource fakeMediaSource =
|
||||
new FakeMediaSource(timeline, /* manifest= */ null) {
|
||||
new FakeMediaSource(timeline) {
|
||||
@Override
|
||||
protected FakeMediaPeriod createFakeMediaPeriod(
|
||||
MediaPeriodId id,
|
||||
|
|
@ -530,7 +539,7 @@ public final class ClippingMediaSourceTest {
|
|||
*/
|
||||
private static Timeline getClippedTimeline(Timeline timeline, long startUs, long endUs)
|
||||
throws IOException {
|
||||
FakeMediaSource fakeMediaSource = new FakeMediaSource(timeline, /* manifest= */ null);
|
||||
FakeMediaSource fakeMediaSource = new FakeMediaSource(timeline);
|
||||
ClippingMediaSource mediaSource = new ClippingMediaSource(fakeMediaSource, startUs, endUs);
|
||||
return getClippedTimelines(fakeMediaSource, mediaSource)[0];
|
||||
}
|
||||
|
|
@ -540,7 +549,7 @@ public final class ClippingMediaSourceTest {
|
|||
*/
|
||||
private static Timeline getClippedTimeline(Timeline timeline, long durationUs)
|
||||
throws IOException {
|
||||
FakeMediaSource fakeMediaSource = new FakeMediaSource(timeline, /* manifest= */ null);
|
||||
FakeMediaSource fakeMediaSource = new FakeMediaSource(timeline);
|
||||
ClippingMediaSource mediaSource = new ClippingMediaSource(fakeMediaSource, durationUs);
|
||||
return getClippedTimelines(fakeMediaSource, mediaSource)[0];
|
||||
}
|
||||
|
|
@ -557,7 +566,7 @@ public final class ClippingMediaSourceTest {
|
|||
Timeline firstTimeline,
|
||||
Timeline... additionalTimelines)
|
||||
throws IOException {
|
||||
FakeMediaSource fakeMediaSource = new FakeMediaSource(firstTimeline, /* manifest= */ null);
|
||||
FakeMediaSource fakeMediaSource = new FakeMediaSource(firstTimeline);
|
||||
ClippingMediaSource mediaSource =
|
||||
new ClippingMediaSource(
|
||||
fakeMediaSource,
|
||||
|
|
|
|||
|
|
@ -226,7 +226,7 @@ public final class ConcatenatingMediaSourceTest {
|
|||
FakeMediaSource[] fastSources = createMediaSources(2);
|
||||
final FakeMediaSource[] lazySources = new FakeMediaSource[4];
|
||||
for (int i = 0; i < 4; i++) {
|
||||
lazySources[i] = new FakeMediaSource(null, null);
|
||||
lazySources[i] = new FakeMediaSource(null);
|
||||
}
|
||||
|
||||
// Add lazy sources and normal sources before preparation. Also remove one lazy source again
|
||||
|
|
@ -307,16 +307,16 @@ public final class ConcatenatingMediaSourceTest {
|
|||
Timeline timeline = testRunner.prepareSource();
|
||||
TimelineAsserts.assertEmpty(timeline);
|
||||
|
||||
mediaSource.addMediaSource(new FakeMediaSource(Timeline.EMPTY, null));
|
||||
mediaSource.addMediaSource(new FakeMediaSource(Timeline.EMPTY));
|
||||
timeline = testRunner.assertTimelineChangeBlocking();
|
||||
TimelineAsserts.assertEmpty(timeline);
|
||||
|
||||
mediaSource.addMediaSources(
|
||||
Arrays.asList(
|
||||
new MediaSource[] {
|
||||
new FakeMediaSource(Timeline.EMPTY, null), new FakeMediaSource(Timeline.EMPTY, null),
|
||||
new FakeMediaSource(Timeline.EMPTY, null), new FakeMediaSource(Timeline.EMPTY, null),
|
||||
new FakeMediaSource(Timeline.EMPTY, null), new FakeMediaSource(Timeline.EMPTY, null)
|
||||
new FakeMediaSource(Timeline.EMPTY), new FakeMediaSource(Timeline.EMPTY),
|
||||
new FakeMediaSource(Timeline.EMPTY), new FakeMediaSource(Timeline.EMPTY),
|
||||
new FakeMediaSource(Timeline.EMPTY), new FakeMediaSource(Timeline.EMPTY)
|
||||
}));
|
||||
timeline = testRunner.assertTimelineChangeBlocking();
|
||||
TimelineAsserts.assertEmpty(timeline);
|
||||
|
|
@ -362,9 +362,9 @@ public final class ConcatenatingMediaSourceTest {
|
|||
public void testDynamicChangeOfEmptyTimelines() throws IOException {
|
||||
FakeMediaSource[] childSources =
|
||||
new FakeMediaSource[] {
|
||||
new FakeMediaSource(Timeline.EMPTY, /* manifest= */ null),
|
||||
new FakeMediaSource(Timeline.EMPTY, /* manifest= */ null),
|
||||
new FakeMediaSource(Timeline.EMPTY, /* manifest= */ null),
|
||||
new FakeMediaSource(Timeline.EMPTY),
|
||||
new FakeMediaSource(Timeline.EMPTY),
|
||||
new FakeMediaSource(Timeline.EMPTY),
|
||||
};
|
||||
Timeline nonEmptyTimeline = new FakeTimeline(/* windowCount = */ 1);
|
||||
|
||||
|
|
@ -387,7 +387,7 @@ public final class ConcatenatingMediaSourceTest {
|
|||
|
||||
@Test
|
||||
public void testIllegalArguments() {
|
||||
MediaSource validSource = new FakeMediaSource(createFakeTimeline(1), null);
|
||||
MediaSource validSource = new FakeMediaSource(createFakeTimeline(1));
|
||||
|
||||
// Null sources.
|
||||
try {
|
||||
|
|
@ -660,8 +660,8 @@ public final class ConcatenatingMediaSourceTest {
|
|||
10 * C.MICROS_PER_SECOND,
|
||||
FakeTimeline.createAdPlaybackState(
|
||||
/* adsPerAdGroup= */ 1, /* adGroupTimesUs= */ 0)));
|
||||
FakeMediaSource mediaSourceContentOnly = new FakeMediaSource(timelineContentOnly, null);
|
||||
FakeMediaSource mediaSourceWithAds = new FakeMediaSource(timelineWithAds, null);
|
||||
FakeMediaSource mediaSourceContentOnly = new FakeMediaSource(timelineContentOnly);
|
||||
FakeMediaSource mediaSourceWithAds = new FakeMediaSource(timelineWithAds);
|
||||
mediaSource.addMediaSource(mediaSourceContentOnly);
|
||||
mediaSource.addMediaSource(mediaSourceWithAds);
|
||||
|
||||
|
|
@ -807,7 +807,7 @@ public final class ConcatenatingMediaSourceTest {
|
|||
@Test
|
||||
public void testDuplicateMediaSources() throws IOException, InterruptedException {
|
||||
Timeline childTimeline = new FakeTimeline(/* windowCount= */ 2);
|
||||
FakeMediaSource childSource = new FakeMediaSource(childTimeline, /* manifest= */ null);
|
||||
FakeMediaSource childSource = new FakeMediaSource(childTimeline);
|
||||
|
||||
mediaSource.addMediaSource(childSource);
|
||||
mediaSource.addMediaSource(childSource);
|
||||
|
|
@ -840,7 +840,7 @@ public final class ConcatenatingMediaSourceTest {
|
|||
@Test
|
||||
public void testDuplicateNestedMediaSources() throws IOException, InterruptedException {
|
||||
Timeline childTimeline = new FakeTimeline(/* windowCount= */ 1);
|
||||
FakeMediaSource childSource = new FakeMediaSource(childTimeline, /* manifest= */ null);
|
||||
FakeMediaSource childSource = new FakeMediaSource(childTimeline);
|
||||
ConcatenatingMediaSource nestedConcatenation = new ConcatenatingMediaSource();
|
||||
|
||||
testRunner.prepareSource();
|
||||
|
|
@ -874,8 +874,7 @@ public final class ConcatenatingMediaSourceTest {
|
|||
public void testClear() throws IOException {
|
||||
DummyMainThread dummyMainThread = new DummyMainThread();
|
||||
final FakeMediaSource preparedChildSource = createFakeMediaSource();
|
||||
final FakeMediaSource unpreparedChildSource =
|
||||
new FakeMediaSource(/* timeline= */ null, /* manifest= */ null);
|
||||
final FakeMediaSource unpreparedChildSource = new FakeMediaSource(/* timeline= */ null);
|
||||
dummyMainThread.runOnMainThread(
|
||||
() -> {
|
||||
mediaSource.addMediaSource(preparedChildSource);
|
||||
|
|
@ -1092,13 +1091,13 @@ public final class ConcatenatingMediaSourceTest {
|
|||
private static FakeMediaSource[] createMediaSources(int count) {
|
||||
FakeMediaSource[] sources = new FakeMediaSource[count];
|
||||
for (int i = 0; i < count; i++) {
|
||||
sources[i] = new FakeMediaSource(createFakeTimeline(i), null);
|
||||
sources[i] = new FakeMediaSource(createFakeTimeline(i));
|
||||
}
|
||||
return sources;
|
||||
}
|
||||
|
||||
private static FakeMediaSource createFakeMediaSource() {
|
||||
return new FakeMediaSource(createFakeTimeline(/* index */ 0), null);
|
||||
return new FakeMediaSource(createFakeTimeline(/* index */ 0));
|
||||
}
|
||||
|
||||
private static FakeTimeline createFakeTimeline(int index) {
|
||||
|
|
|
|||
|
|
@ -135,7 +135,7 @@ public class LoopingMediaSourceTest {
|
|||
* Wraps the specified timeline in a {@link LoopingMediaSource} and returns the looping timeline.
|
||||
*/
|
||||
private static Timeline getLoopingTimeline(Timeline timeline, int loopCount) throws IOException {
|
||||
FakeMediaSource fakeMediaSource = new FakeMediaSource(timeline, null);
|
||||
FakeMediaSource fakeMediaSource = new FakeMediaSource(timeline);
|
||||
LoopingMediaSource mediaSource = new LoopingMediaSource(fakeMediaSource, loopCount);
|
||||
MediaSourceTestRunner testRunner = new MediaSourceTestRunner(mediaSource, null);
|
||||
try {
|
||||
|
|
@ -153,7 +153,7 @@ public class LoopingMediaSourceTest {
|
|||
* the looping timeline can be created and prepared.
|
||||
*/
|
||||
private static void testMediaPeriodCreation(Timeline timeline, int loopCount) throws Exception {
|
||||
FakeMediaSource fakeMediaSource = new FakeMediaSource(timeline, null);
|
||||
FakeMediaSource fakeMediaSource = new FakeMediaSource(timeline);
|
||||
LoopingMediaSource mediaSource = new LoopingMediaSource(fakeMediaSource, loopCount);
|
||||
MediaSourceTestRunner testRunner = new MediaSourceTestRunner(mediaSource, null);
|
||||
try {
|
||||
|
|
|
|||
|
|
@ -68,8 +68,7 @@ public class MergingMediaSourceTest {
|
|||
public void testMergingMediaSourcePeriodCreation() throws Exception {
|
||||
FakeMediaSource[] mediaSources = new FakeMediaSource[2];
|
||||
for (int i = 0; i < mediaSources.length; i++) {
|
||||
mediaSources[i] =
|
||||
new FakeMediaSource(new FakeTimeline(/* windowCount= */ 2), /* manifest= */ null);
|
||||
mediaSources[i] = new FakeMediaSource(new FakeTimeline(/* windowCount= */ 2));
|
||||
}
|
||||
MergingMediaSource mediaSource = new MergingMediaSource(mediaSources);
|
||||
MediaSourceTestRunner testRunner = new MediaSourceTestRunner(mediaSource, null);
|
||||
|
|
@ -92,7 +91,7 @@ public class MergingMediaSourceTest {
|
|||
private static void testMergingMediaSourcePrepare(Timeline... timelines) throws IOException {
|
||||
FakeMediaSource[] mediaSources = new FakeMediaSource[timelines.length];
|
||||
for (int i = 0; i < timelines.length; i++) {
|
||||
mediaSources[i] = new FakeMediaSource(timelines[i], null);
|
||||
mediaSources[i] = new FakeMediaSource(timelines[i]);
|
||||
}
|
||||
MergingMediaSource mergingMediaSource = new MergingMediaSource(mediaSources);
|
||||
MediaSourceTestRunner testRunner = new MediaSourceTestRunner(mergingMediaSource, null);
|
||||
|
|
|
|||
|
|
@ -62,6 +62,7 @@ public final class SinglePeriodTimelineTest {
|
|||
/* windowDefaultStartPositionUs= */ 0,
|
||||
/* isSeekable= */ false,
|
||||
/* isDynamic= */ true,
|
||||
/* manifest= */ null,
|
||||
/* tag= */ null);
|
||||
// Should return null with a positive position projection beyond window duration.
|
||||
Pair<Object, Long> position =
|
||||
|
|
@ -84,6 +85,7 @@ public final class SinglePeriodTimelineTest {
|
|||
/* durationUs= */ C.TIME_UNSET,
|
||||
/* isSeekable= */ false,
|
||||
/* isDynamic= */ false,
|
||||
/* manifest= */ null,
|
||||
/* tag= */ null);
|
||||
|
||||
assertThat(timeline.getWindow(/* windowIndex= */ 0, window, /* setTag= */ false).tag).isNull();
|
||||
|
|
@ -100,7 +102,11 @@ public final class SinglePeriodTimelineTest {
|
|||
Object tag = new Object();
|
||||
SinglePeriodTimeline timeline =
|
||||
new SinglePeriodTimeline(
|
||||
/* durationUs= */ C.TIME_UNSET, /* isSeekable= */ false, /* isDynamic= */ false, tag);
|
||||
/* durationUs= */ C.TIME_UNSET,
|
||||
/* isSeekable= */ false,
|
||||
/* isDynamic= */ false,
|
||||
/* manifest= */ null,
|
||||
tag);
|
||||
|
||||
assertThat(timeline.getWindow(/* windowIndex= */ 0, window, /* setTag= */ false).tag).isNull();
|
||||
assertThat(timeline.getWindow(/* windowIndex= */ 0, window, /* setTag= */ true).tag)
|
||||
|
|
@ -114,6 +120,7 @@ public final class SinglePeriodTimelineTest {
|
|||
/* durationUs= */ C.TIME_UNSET,
|
||||
/* isSeekable= */ false,
|
||||
/* isDynamic= */ false,
|
||||
/* manifest= */ null,
|
||||
/* tag= */ null);
|
||||
Object uid = timeline.getPeriod(/* periodIndex= */ 0, period, /* setIds= */ true).uid;
|
||||
|
||||
|
|
|
|||
|
|
@ -994,7 +994,7 @@ public final class DashMediaSource extends BaseMediaSource {
|
|||
windowDefaultStartPositionUs,
|
||||
manifest,
|
||||
tag);
|
||||
refreshSourceInfo(timeline, manifest);
|
||||
refreshSourceInfo(timeline);
|
||||
|
||||
if (!sideloadedManifest) {
|
||||
// Remove any pending simulated refresh.
|
||||
|
|
@ -1193,6 +1193,7 @@ public final class DashMediaSource extends BaseMediaSource {
|
|||
&& manifest.durationMs == C.TIME_UNSET;
|
||||
return window.set(
|
||||
tag,
|
||||
manifest,
|
||||
presentationStartTimeMs,
|
||||
windowStartTimeMs,
|
||||
/* isSeekable= */ true,
|
||||
|
|
|
|||
|
|
@ -383,6 +383,7 @@ public final class HlsMediaSource extends BaseMediaSource
|
|||
? windowStartTimeMs
|
||||
: C.TIME_UNSET;
|
||||
long windowDefaultStartPositionUs = playlist.startOffsetUs;
|
||||
HlsManifest manifest = new HlsManifest(playlistTracker.getMasterPlaylist(), playlist);
|
||||
if (playlistTracker.isLive()) {
|
||||
long offsetFromInitialStartTimeUs =
|
||||
playlist.startTimeUs - playlistTracker.getInitialStartTimeUs();
|
||||
|
|
@ -403,6 +404,7 @@ public final class HlsMediaSource extends BaseMediaSource
|
|||
windowDefaultStartPositionUs,
|
||||
/* isSeekable= */ true,
|
||||
/* isDynamic= */ !playlist.hasEndTag,
|
||||
manifest,
|
||||
tag);
|
||||
} else /* not live */ {
|
||||
if (windowDefaultStartPositionUs == C.TIME_UNSET) {
|
||||
|
|
@ -418,9 +420,10 @@ public final class HlsMediaSource extends BaseMediaSource
|
|||
windowDefaultStartPositionUs,
|
||||
/* isSeekable= */ true,
|
||||
/* isDynamic= */ false,
|
||||
manifest,
|
||||
tag);
|
||||
}
|
||||
refreshSourceInfo(timeline, new HlsManifest(playlistTracker.getMasterPlaylist(), playlist));
|
||||
refreshSourceInfo(timeline);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -669,6 +669,7 @@ public final class SsMediaSource extends BaseMediaSource
|
|||
/* windowDefaultStartPositionUs= */ 0,
|
||||
/* isSeekable= */ true,
|
||||
manifest.isLive,
|
||||
manifest,
|
||||
tag);
|
||||
} else if (manifest.isLive) {
|
||||
if (manifest.dvrWindowLengthUs != C.TIME_UNSET && manifest.dvrWindowLengthUs > 0) {
|
||||
|
|
@ -690,6 +691,7 @@ public final class SsMediaSource extends BaseMediaSource
|
|||
defaultStartPositionUs,
|
||||
/* isSeekable= */ true,
|
||||
/* isDynamic= */ true,
|
||||
manifest,
|
||||
tag);
|
||||
} else {
|
||||
long durationUs = manifest.durationUs != C.TIME_UNSET ? manifest.durationUs
|
||||
|
|
@ -702,9 +704,10 @@ public final class SsMediaSource extends BaseMediaSource
|
|||
/* windowDefaultStartPositionUs= */ 0,
|
||||
/* isSeekable= */ true,
|
||||
/* isDynamic= */ false,
|
||||
manifest,
|
||||
tag);
|
||||
}
|
||||
refreshSourceInfo(timeline, manifest);
|
||||
refreshSourceInfo(timeline);
|
||||
}
|
||||
|
||||
private void scheduleManifestRefresh() {
|
||||
|
|
|
|||
|
|
@ -1212,8 +1212,7 @@ public class PlayerControlView extends FrameLayout {
|
|||
}
|
||||
|
||||
@Override
|
||||
public void onTimelineChanged(
|
||||
Timeline timeline, @Nullable Object manifest, @Player.TimelineChangeReason int reason) {
|
||||
public void onTimelineChanged(Timeline timeline, @Player.TimelineChangeReason int reason) {
|
||||
updateNavigation();
|
||||
updateTimeline();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1286,7 +1286,7 @@ public class PlayerNotificationManager {
|
|||
}
|
||||
|
||||
@Override
|
||||
public void onTimelineChanged(Timeline timeline, @Nullable Object manifest, int reason) {
|
||||
public void onTimelineChanged(Timeline timeline, int reason) {
|
||||
startOrUpdateNotification();
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -542,9 +542,7 @@ public abstract class Action {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Waits for {@link Player.EventListener#onTimelineChanged(Timeline, Object, int)}.
|
||||
*/
|
||||
/** Waits for {@link Player.EventListener#onTimelineChanged(Timeline, int)}. */
|
||||
public static final class WaitForTimelineChanged extends Action {
|
||||
|
||||
@Nullable private final Timeline expectedTimeline;
|
||||
|
|
@ -575,9 +573,7 @@ public abstract class Action {
|
|||
new Player.EventListener() {
|
||||
@Override
|
||||
public void onTimelineChanged(
|
||||
Timeline timeline,
|
||||
@Nullable Object manifest,
|
||||
@Player.TimelineChangeReason int reason) {
|
||||
Timeline timeline, @Player.TimelineChangeReason int reason) {
|
||||
if (expectedTimeline == null || timeline.equals(expectedTimeline)) {
|
||||
player.removeListener(this);
|
||||
nextAction.schedule(player, trackSelector, surface, handler);
|
||||
|
|
|
|||
|
|
@ -309,9 +309,9 @@ public final class ExoPlayerTestRunner implements Player.EventListener, ActionSc
|
|||
}
|
||||
if (mediaSource == null) {
|
||||
if (timeline == null) {
|
||||
timeline = new FakeTimeline(1);
|
||||
timeline = new FakeTimeline(/* windowCount= */ 1, manifest);
|
||||
}
|
||||
mediaSource = new FakeMediaSource(timeline, manifest, supportedFormats);
|
||||
mediaSource = new FakeMediaSource(timeline, supportedFormats);
|
||||
}
|
||||
if (expectedPlayerEndedCount == null) {
|
||||
expectedPlayerEndedCount = 1;
|
||||
|
|
@ -347,7 +347,6 @@ public final class ExoPlayerTestRunner implements Player.EventListener, ActionSc
|
|||
private final CountDownLatch endedCountDownLatch;
|
||||
private final CountDownLatch actionScheduleFinishedCountDownLatch;
|
||||
private final ArrayList<Timeline> timelines;
|
||||
private final ArrayList<Object> manifests;
|
||||
private final ArrayList<Integer> timelineChangeReasons;
|
||||
private final ArrayList<Integer> periodIndices;
|
||||
private final ArrayList<Integer> discontinuityReasons;
|
||||
|
|
@ -380,7 +379,6 @@ public final class ExoPlayerTestRunner implements Player.EventListener, ActionSc
|
|||
this.eventListener = eventListener;
|
||||
this.analyticsListener = analyticsListener;
|
||||
this.timelines = new ArrayList<>();
|
||||
this.manifests = new ArrayList<>();
|
||||
this.timelineChangeReasons = new ArrayList<>();
|
||||
this.periodIndices = new ArrayList<>();
|
||||
this.discontinuityReasons = new ArrayList<>();
|
||||
|
|
@ -469,9 +467,8 @@ public final class ExoPlayerTestRunner implements Player.EventListener, ActionSc
|
|||
// Assertions called on the test thread after test finished.
|
||||
|
||||
/**
|
||||
* Asserts that the timelines reported by
|
||||
* {@link Player.EventListener#onTimelineChanged(Timeline, Object, int)} are equal to the provided
|
||||
* timelines.
|
||||
* Asserts that the timelines reported by {@link Player.EventListener#onTimelineChanged(Timeline,
|
||||
* int)} are equal to the provided timelines.
|
||||
*
|
||||
* @param timelines A list of expected {@link Timeline}s.
|
||||
*/
|
||||
|
|
@ -479,21 +476,10 @@ public final class ExoPlayerTestRunner implements Player.EventListener, ActionSc
|
|||
assertThat(this.timelines).containsExactlyElementsIn(Arrays.asList(timelines)).inOrder();
|
||||
}
|
||||
|
||||
/**
|
||||
* Asserts that the manifests reported by
|
||||
* {@link Player.EventListener#onTimelineChanged(Timeline, Object, int)} are equal to the provided
|
||||
* manifest.
|
||||
*
|
||||
* @param manifests A list of expected manifests.
|
||||
*/
|
||||
public void assertManifestsEqual(Object... manifests) {
|
||||
assertThat(this.manifests).containsExactlyElementsIn(Arrays.asList(manifests)).inOrder();
|
||||
}
|
||||
|
||||
/**
|
||||
* Asserts that the timeline change reasons reported by {@link
|
||||
* Player.EventListener#onTimelineChanged(Timeline, Object, int)} are equal to the provided
|
||||
* timeline change reasons.
|
||||
* Player.EventListener#onTimelineChanged(Timeline, int)} are equal to the provided timeline
|
||||
* change reasons.
|
||||
*/
|
||||
public void assertTimelineChangeReasonsEqual(Integer... reasons) {
|
||||
assertThat(timelineChangeReasons).containsExactlyElementsIn(Arrays.asList(reasons)).inOrder();
|
||||
|
|
@ -573,10 +559,8 @@ public final class ExoPlayerTestRunner implements Player.EventListener, ActionSc
|
|||
// Player.EventListener
|
||||
|
||||
@Override
|
||||
public void onTimelineChanged(
|
||||
Timeline timeline, @Nullable Object manifest, @Player.TimelineChangeReason int reason) {
|
||||
public void onTimelineChanged(Timeline timeline, @Player.TimelineChangeReason int reason) {
|
||||
timelines.add(timeline);
|
||||
manifests.add(manifest);
|
||||
timelineChangeReasons.add(reason);
|
||||
if (reason == Player.TIMELINE_CHANGE_REASON_PREPARED) {
|
||||
periodIndices.add(player.getCurrentPeriodIndex());
|
||||
|
|
|
|||
|
|
@ -34,10 +34,9 @@ public class FakeAdaptiveMediaSource extends FakeMediaSource {
|
|||
|
||||
public FakeAdaptiveMediaSource(
|
||||
Timeline timeline,
|
||||
Object manifest,
|
||||
TrackGroupArray trackGroupArray,
|
||||
FakeChunkSource.Factory chunkSourceFactory) {
|
||||
super(timeline, manifest, trackGroupArray);
|
||||
super(timeline, trackGroupArray);
|
||||
this.chunkSourceFactory = chunkSourceFactory;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -56,7 +56,6 @@ public class FakeMediaSource extends BaseMediaSource {
|
|||
private final ArrayList<MediaPeriodId> createdMediaPeriods;
|
||||
|
||||
protected Timeline timeline;
|
||||
private Object manifest;
|
||||
private boolean preparedSource;
|
||||
private boolean releasedSource;
|
||||
private Handler sourceInfoRefreshHandler;
|
||||
|
|
@ -68,8 +67,8 @@ public class FakeMediaSource extends BaseMediaSource {
|
|||
* null to prevent an immediate source info refresh message when preparing the media source. It
|
||||
* can be manually set later using {@link #setNewSourceInfo(Timeline, Object)}.
|
||||
*/
|
||||
public FakeMediaSource(@Nullable Timeline timeline, Object manifest, Format... formats) {
|
||||
this(timeline, manifest, buildTrackGroupArray(formats));
|
||||
public FakeMediaSource(@Nullable Timeline timeline, Format... formats) {
|
||||
this(timeline, buildTrackGroupArray(formats));
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -78,10 +77,8 @@ public class FakeMediaSource extends BaseMediaSource {
|
|||
* immediate source info refresh message when preparing the media source. It can be manually set
|
||||
* later using {@link #setNewSourceInfo(Timeline, Object)}.
|
||||
*/
|
||||
public FakeMediaSource(@Nullable Timeline timeline, Object manifest,
|
||||
TrackGroupArray trackGroupArray) {
|
||||
public FakeMediaSource(@Nullable Timeline timeline, TrackGroupArray trackGroupArray) {
|
||||
this.timeline = timeline;
|
||||
this.manifest = manifest;
|
||||
this.activeMediaPeriods = new ArrayList<>();
|
||||
this.createdMediaPeriods = new ArrayList<>();
|
||||
this.trackGroupArray = trackGroupArray;
|
||||
|
|
@ -158,12 +155,10 @@ public class FakeMediaSource extends BaseMediaSource {
|
|||
assertThat(releasedSource).isFalse();
|
||||
assertThat(preparedSource).isTrue();
|
||||
timeline = newTimeline;
|
||||
manifest = newManifest;
|
||||
finishSourcePreparation();
|
||||
});
|
||||
} else {
|
||||
timeline = newTimeline;
|
||||
manifest = newManifest;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -212,7 +207,7 @@ public class FakeMediaSource extends BaseMediaSource {
|
|||
}
|
||||
|
||||
private void finishSourcePreparation() {
|
||||
refreshSourceInfo(timeline, manifest);
|
||||
refreshSourceInfo(timeline);
|
||||
if (!timeline.isEmpty()) {
|
||||
MediaLoadData mediaLoadData =
|
||||
new MediaLoadData(
|
||||
|
|
|
|||
|
|
@ -112,6 +112,7 @@ public final class FakeTimeline extends Timeline {
|
|||
private static final long AD_DURATION_US = 10 * C.MICROS_PER_SECOND;
|
||||
|
||||
private final TimelineWindowDefinition[] windowDefinitions;
|
||||
private final Object[] manifests;
|
||||
private final int[] periodOffsets;
|
||||
|
||||
/**
|
||||
|
|
@ -140,9 +141,10 @@ public final class FakeTimeline extends Timeline {
|
|||
* with a duration of {@link TimelineWindowDefinition#DEFAULT_WINDOW_DURATION_US} each.
|
||||
*
|
||||
* @param windowCount The number of windows.
|
||||
* @param manifests The manifests of the windows.
|
||||
*/
|
||||
public FakeTimeline(int windowCount) {
|
||||
this(createDefaultWindowDefinitions(windowCount));
|
||||
public FakeTimeline(int windowCount, Object... manifests) {
|
||||
this(manifests, createDefaultWindowDefinitions(windowCount));
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -151,6 +153,18 @@ public final class FakeTimeline extends Timeline {
|
|||
* @param windowDefinitions A list of {@link TimelineWindowDefinition}s.
|
||||
*/
|
||||
public FakeTimeline(TimelineWindowDefinition... windowDefinitions) {
|
||||
this(new Object[0], windowDefinitions);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a fake timeline with the given window definitions.
|
||||
*
|
||||
* @param windowDefinitions A list of {@link TimelineWindowDefinition}s.
|
||||
*/
|
||||
public FakeTimeline(Object[] manifests, TimelineWindowDefinition... windowDefinitions) {
|
||||
this.manifests = new Object[windowDefinitions.length];
|
||||
System.arraycopy(
|
||||
manifests, 0, this.manifests, 0, Math.min(this.manifests.length, manifests.length));
|
||||
this.windowDefinitions = windowDefinitions;
|
||||
periodOffsets = new int[windowDefinitions.length + 1];
|
||||
periodOffsets[0] = 0;
|
||||
|
|
@ -171,6 +185,7 @@ public final class FakeTimeline extends Timeline {
|
|||
Object tag = setTag ? windowDefinition.id : null;
|
||||
return window.set(
|
||||
tag,
|
||||
manifests[windowIndex],
|
||||
/* presentationStartTimeMs= */ C.TIME_UNSET,
|
||||
/* windowStartTimeMs= */ C.TIME_UNSET,
|
||||
windowDefinition.isSeekable,
|
||||
|
|
|
|||
|
|
@ -345,7 +345,7 @@ public class MediaSourceTestRunner {
|
|||
// SourceInfoRefreshListener methods.
|
||||
|
||||
@Override
|
||||
public void onSourceInfoRefreshed(MediaSource source, Timeline timeline, Object manifest) {
|
||||
public void onSourceInfoRefreshed(MediaSource source, Timeline timeline) {
|
||||
Assertions.checkState(Looper.myLooper() == playbackThread.getLooper());
|
||||
timelines.addLast(timeline);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -195,11 +195,6 @@ public abstract class StubExoPlayer extends BasePlayer implements ExoPlayer {
|
|||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getCurrentManifest() {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Timeline getCurrentTimeline() {
|
||||
throw new UnsupportedOperationException();
|
||||
|
|
|
|||
Loading…
Reference in a new issue