Move default start position into Window
------------- Created by MOE: https://github.com/google/moe MOE_MIGRATED_REVID=130610236
This commit is contained in:
parent
3e0bae616f
commit
b2a28a140c
@ -495,14 +495,12 @@ import java.io.IOException;
|
||||
|
||||
private void seekToInternal(int periodIndex, long positionUs) throws ExoPlaybackException {
|
||||
try {
|
||||
if (positionUs == C.UNSET_TIME_US && mediaSource != null) {
|
||||
MediaSource.Position defaultStartPosition =
|
||||
mediaSource.getDefaultStartPosition(periodIndex);
|
||||
if (defaultStartPosition != null) {
|
||||
// We know the default position so seek to it now.
|
||||
periodIndex = defaultStartPosition.periodIndex;
|
||||
positionUs = defaultStartPosition.positionUs;
|
||||
}
|
||||
if (positionUs == C.UNSET_TIME_US && timeline != null
|
||||
&& periodIndex < timeline.getPeriodCount()) {
|
||||
// We know about the window, so seek to its default initial position now.
|
||||
Window window = timeline.getPeriodWindow(periodIndex);
|
||||
periodIndex = window.defaultInitialPeriodIndex;
|
||||
positionUs = window.defaultInitialTimeMs * 1000;
|
||||
}
|
||||
|
||||
if (periodIndex == playbackInfo.periodIndex
|
||||
@ -805,22 +803,18 @@ import java.io.IOException;
|
||||
return;
|
||||
}
|
||||
|
||||
// Release all loaded periods and seek to the new playing period index.
|
||||
// Release all loaded periods.
|
||||
releasePeriodsFrom(playingPeriod);
|
||||
playingPeriod = null;
|
||||
readingPeriod = null;
|
||||
loadingPeriod = null;
|
||||
|
||||
MediaSource.Position defaultStartPosition =
|
||||
mediaSource.getDefaultStartPosition(newPlayingPeriodIndex);
|
||||
long newPlayingPositionUs;
|
||||
if (defaultStartPosition != null) {
|
||||
newPlayingPeriodIndex = defaultStartPosition.periodIndex;
|
||||
newPlayingPositionUs = seekToPeriodPosition(defaultStartPosition.periodIndex,
|
||||
defaultStartPosition.positionUs);
|
||||
} else {
|
||||
newPlayingPositionUs = seekToPeriodPosition(newPlayingPeriodIndex, C.UNSET_TIME_US);
|
||||
}
|
||||
// Find the default initial position in the window and seek to it.
|
||||
Window window = timeline.getPeriodWindow(newPlayingPeriodIndex);
|
||||
newPlayingPeriodIndex = window.defaultInitialPeriodIndex;
|
||||
long newPlayingPositionUs = seekToPeriodPosition(newPlayingPeriodIndex,
|
||||
window.defaultInitialTimeMs);
|
||||
|
||||
playbackInfo = new PlaybackInfo(newPlayingPeriodIndex, newPlayingPositionUs);
|
||||
eventHandler.obtainMessage(MSG_POSITION_DISCONTINUITY, playbackInfo).sendToTarget();
|
||||
return;
|
||||
@ -901,33 +895,29 @@ import java.io.IOException;
|
||||
return;
|
||||
}
|
||||
|
||||
// Update the loading period.
|
||||
|
||||
if (loadingPeriod == null || (loadingPeriod.isFullyBuffered() && !loadingPeriod.isLast
|
||||
&& bufferAheadPeriodCount < MAXIMUM_BUFFER_AHEAD_PERIODS)) {
|
||||
int periodIndex = loadingPeriod == null ? playbackInfo.periodIndex : loadingPeriod.index + 1;
|
||||
long startPositionUs = playbackInfo.positionUs;
|
||||
if (loadingPeriod != null || startPositionUs == C.UNSET_TIME_US) {
|
||||
// We are starting to load the next period or seeking to the default position, so request a
|
||||
// period and position from the source.
|
||||
MediaSource.Position defaultStartPosition =
|
||||
mediaSource.getDefaultStartPosition(periodIndex);
|
||||
if (defaultStartPosition != null) {
|
||||
periodIndex = defaultStartPosition.periodIndex;
|
||||
startPositionUs = defaultStartPosition.positionUs;
|
||||
} else {
|
||||
startPositionUs = C.UNSET_TIME_US;
|
||||
}
|
||||
}
|
||||
|
||||
if (periodIndex >= timeline.getPeriodCount()) {
|
||||
// This period is not available yet.
|
||||
// We don't have a loading period or it's fully loaded, so try and create the next one.
|
||||
int newLoadingPeriodIndex = loadingPeriod == null ? playbackInfo.periodIndex
|
||||
: loadingPeriod.index + 1;
|
||||
if (newLoadingPeriodIndex >= timeline.getPeriodCount()) {
|
||||
// The period is not available yet.
|
||||
mediaSource.maybeThrowSourceInfoRefreshError();
|
||||
} else if (startPositionUs != C.UNSET_TIME_US) {
|
||||
MediaPeriod mediaPeriod = mediaSource.createPeriod(periodIndex, this,
|
||||
} else {
|
||||
Window window = timeline.getPeriodWindow(newLoadingPeriodIndex);
|
||||
long startPositionUs = loadingPeriod == null ? playbackInfo.positionUs : C.UNSET_TIME_US;
|
||||
if (startPositionUs == C.UNSET_TIME_US) {
|
||||
// This is the first period of a new window or we don't have a start position, so seek to
|
||||
// the default position for the window.
|
||||
newLoadingPeriodIndex = window.defaultInitialPeriodIndex;
|
||||
startPositionUs = window.defaultInitialTimeMs * 1000;
|
||||
}
|
||||
MediaPeriod mediaPeriod = mediaSource.createPeriod(newLoadingPeriodIndex, this,
|
||||
loadControl.getAllocator(), startPositionUs);
|
||||
Period newPeriod = new Period(renderers, rendererCapabilities, trackSelector, mediaSource,
|
||||
mediaPeriod, timeline.getPeriodId(periodIndex), startPositionUs);
|
||||
newPeriod.setIndex(timeline, periodIndex);
|
||||
mediaPeriod, timeline.getPeriodId(newLoadingPeriodIndex), startPositionUs);
|
||||
newPeriod.setIndex(timeline, newLoadingPeriodIndex);
|
||||
if (loadingPeriod != null) {
|
||||
loadingPeriod.setNextPeriod(newPeriod);
|
||||
newPeriod.offsetUs = loadingPeriod.offsetUs
|
||||
|
@ -21,8 +21,8 @@ package com.google.android.exoplayer2;
|
||||
public final class Window {
|
||||
|
||||
/**
|
||||
* Creates a new {@link Window} containing times from zero up to {@code durationUs} in the first
|
||||
* period.
|
||||
* Creates a new {@link Window} consisting of a single period starting at time zero and with the
|
||||
* specified duration. The default initial position is the start of the window.
|
||||
*
|
||||
* @param durationUs The duration of the window, in microseconds.
|
||||
* @param isSeekable Whether seeking is supported within the window.
|
||||
@ -30,7 +30,27 @@ public final class Window {
|
||||
*/
|
||||
public static Window createWindowFromZero(long durationUs, boolean isSeekable,
|
||||
boolean isDynamic) {
|
||||
return createWindow(0, 0, 0, durationUs, durationUs, isSeekable, isDynamic);
|
||||
return createWindow(0, 0, 0, durationUs, durationUs, isSeekable, isDynamic, 0, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new {@link Window} representing the specified time range. The default initial
|
||||
* position is the start of the window.
|
||||
*
|
||||
* @param startPeriodIndex The index of the period containing the start of the window.
|
||||
* @param startTimeUs The start time of the window in microseconds, relative to the start of the
|
||||
* specified start period.
|
||||
* @param endPeriodIndex The index of the period containing the end of the window.
|
||||
* @param endTimeUs The end time of the window in microseconds, relative to the start of the
|
||||
* specified end period.
|
||||
* @param durationUs The duration of the window in microseconds.
|
||||
* @param isSeekable Whether seeking is supported within the window.
|
||||
* @param isDynamic Whether this seek window may change when the timeline is updated.
|
||||
*/
|
||||
public static Window createWindow(int startPeriodIndex, long startTimeUs,
|
||||
int endPeriodIndex, long endTimeUs, long durationUs, boolean isSeekable, boolean isDynamic) {
|
||||
return createWindow(startPeriodIndex, startTimeUs, endPeriodIndex, endTimeUs, durationUs,
|
||||
isSeekable, isDynamic, startPeriodIndex, startTimeUs);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -45,13 +65,18 @@ public final class Window {
|
||||
* @param durationUs The duration of the window in microseconds.
|
||||
* @param isSeekable Whether seeking is supported within the window.
|
||||
* @param isDynamic Whether this seek window may change when the timeline is updated.
|
||||
* @param defaultInitialPeriodIndex The index of the period containing the default position from
|
||||
* which playback should start.
|
||||
* @param defaultInitialTimeUs The time of the default position from which playback should start
|
||||
* in microseconds, relative to the start of the period that contains it.
|
||||
*/
|
||||
public static Window createWindow(int startPeriodIndex, long startTimeUs,
|
||||
int endPeriodIndex, long endTimeUs, long durationUs, boolean isSeekable, boolean isDynamic) {
|
||||
int endPeriodIndex, long endTimeUs, long durationUs, boolean isSeekable, boolean isDynamic,
|
||||
int defaultInitialPeriodIndex, long defaultInitialTimeUs) {
|
||||
return new Window(startPeriodIndex, startTimeUs / 1000, endPeriodIndex,
|
||||
endTimeUs == C.UNSET_TIME_US ? ExoPlayer.UNKNOWN_TIME : (endTimeUs / 1000),
|
||||
durationUs == C.UNSET_TIME_US ? ExoPlayer.UNKNOWN_TIME : (durationUs / 1000),
|
||||
isSeekable, isDynamic);
|
||||
isSeekable, isDynamic, defaultInitialPeriodIndex, defaultInitialTimeUs / 1000);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -84,9 +109,19 @@ public final class Window {
|
||||
* Whether this seek window may change when the timeline is updated.
|
||||
*/
|
||||
public final boolean isDynamic;
|
||||
/**
|
||||
* The period index of the default position from which playback should start.
|
||||
*/
|
||||
public final int defaultInitialPeriodIndex;
|
||||
/**
|
||||
* The time of the default position relative to the start of the period at
|
||||
* {@link #defaultInitialPeriodIndex}, in milliseconds.
|
||||
*/
|
||||
public final long defaultInitialTimeMs;
|
||||
|
||||
private Window(int startPeriodIndex, long startTimeMs, int endPeriodIndex, long endTimeMs,
|
||||
long durationMs, boolean isSeekable, boolean isDynamic) {
|
||||
long durationMs, boolean isSeekable, boolean isDynamic, int defaultInitialPeriodIndex,
|
||||
long defaultInitialTimeMs) {
|
||||
this.startPeriodIndex = startPeriodIndex;
|
||||
this.startTimeMs = startTimeMs;
|
||||
this.endPeriodIndex = endPeriodIndex;
|
||||
@ -94,6 +129,8 @@ public final class Window {
|
||||
this.durationMs = durationMs;
|
||||
this.isSeekable = isSeekable;
|
||||
this.isDynamic = isDynamic;
|
||||
this.defaultInitialPeriodIndex = defaultInitialPeriodIndex;
|
||||
this.defaultInitialTimeMs = defaultInitialTimeMs;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -105,7 +142,8 @@ public final class Window {
|
||||
*/
|
||||
public Window copyOffsetByPeriodCount(int periodCount) {
|
||||
return new Window(startPeriodIndex + periodCount, startTimeMs, endPeriodIndex + periodCount,
|
||||
endTimeMs, durationMs, isSeekable, isDynamic);
|
||||
endTimeMs, durationMs, isSeekable, isDynamic, defaultInitialPeriodIndex + periodCount,
|
||||
defaultInitialTimeMs);
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -115,7 +153,10 @@ public final class Window {
|
||||
result = 31 * result + (int) startTimeMs;
|
||||
result = 31 * result + endPeriodIndex;
|
||||
result = 31 * result + (int) endTimeMs;
|
||||
result = 31 * result + (isSeekable ? 1 : 2);
|
||||
result = 31 * result + (isDynamic ? 1 : 2);
|
||||
result = 31 * result + defaultInitialPeriodIndex;
|
||||
result = 31 * result + (int) defaultInitialTimeMs;
|
||||
return result;
|
||||
}
|
||||
|
||||
@ -134,7 +175,9 @@ public final class Window {
|
||||
&& other.endTimeMs == endTimeMs
|
||||
&& other.durationMs == durationMs
|
||||
&& other.isSeekable == isSeekable
|
||||
&& other.isDynamic == isDynamic;
|
||||
&& other.isDynamic == isDynamic
|
||||
&& other.defaultInitialPeriodIndex == defaultInitialPeriodIndex
|
||||
&& other.defaultInitialTimeMs == defaultInitialTimeMs;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -82,16 +82,6 @@ public final class ConcatenatingMediaSource implements MediaSource {
|
||||
oldPlayingPeriodIndex - oldFirstPeriodIndex, oldTimeline.timelines[sourceIndex]);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Position getDefaultStartPosition(int index) {
|
||||
int sourceIndex = timeline.getSourceIndexForPeriod(index);
|
||||
int sourceFirstPeriodIndex = timeline.getFirstPeriodIndexInSource(sourceIndex);
|
||||
Position defaultStartPosition =
|
||||
mediaSources[sourceIndex].getDefaultStartPosition(index - sourceFirstPeriodIndex);
|
||||
return new Position(defaultStartPosition.periodIndex + sourceFirstPeriodIndex,
|
||||
defaultStartPosition.positionUs);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void maybeThrowSourceInfoRefreshError() throws IOException {
|
||||
for (MediaSource mediaSource : mediaSources) {
|
||||
|
@ -144,11 +144,6 @@ public final class ExtractorMediaSource implements MediaSource, MediaSource.List
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Position getDefaultStartPosition(int index) {
|
||||
return Position.DEFAULT;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void maybeThrowSourceInfoRefreshError() throws IOException {
|
||||
// Do nothing.
|
||||
|
@ -40,39 +40,6 @@ public interface MediaSource {
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* A position in the timeline.
|
||||
*/
|
||||
final class Position {
|
||||
|
||||
/**
|
||||
* A start position at the earliest time in the first period.
|
||||
*/
|
||||
public static final Position DEFAULT = new Position(0, 0);
|
||||
|
||||
/**
|
||||
* The index of the period containing the timeline position.
|
||||
*/
|
||||
public final int periodIndex;
|
||||
|
||||
/**
|
||||
* The position in microseconds within the period.
|
||||
*/
|
||||
public final long positionUs;
|
||||
|
||||
/**
|
||||
* Creates a new timeline position.
|
||||
*
|
||||
* @param periodIndex The index of the period containing the timeline position.
|
||||
* @param positionUs The position in microseconds within the period.
|
||||
*/
|
||||
public Position(int periodIndex, long positionUs) {
|
||||
this.periodIndex = periodIndex;
|
||||
this.positionUs = positionUs;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Starts preparation of the source.
|
||||
*
|
||||
@ -93,20 +60,6 @@ public interface MediaSource {
|
||||
*/
|
||||
int getNewPlayingPeriodIndex(int oldPlayingPeriodIndex, Timeline oldTimeline);
|
||||
|
||||
/**
|
||||
* Returns the default {@link Position} that the player should play when when starting to play the
|
||||
* period at {@code index}, or {@code null} if the default position is not yet known.
|
||||
* <p>
|
||||
* For example, sources can return a {@link Position} with the passed period {@code index} to play
|
||||
* the period at {@code index} immediately after the period at {@code index - 1}. Sources
|
||||
* providing multi-period live streams may return the index and position of the live edge when
|
||||
* passed {@code index == 0} to play from the live edge.
|
||||
*
|
||||
* @param index The index of the requested period.
|
||||
* @return The default start position.
|
||||
*/
|
||||
Position getDefaultStartPosition(int index);
|
||||
|
||||
/**
|
||||
* Throws any pending error encountered while loading or refreshing source information.
|
||||
*/
|
||||
|
@ -70,11 +70,6 @@ public final class MergingMediaSource implements MediaSource {
|
||||
return mediaSources[0].getNewPlayingPeriodIndex(oldPlayingPeriodIndex, oldTimeline);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Position getDefaultStartPosition(int index) {
|
||||
return mediaSources[0].getDefaultStartPosition(index);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void maybeThrowSourceInfoRefreshError() throws IOException {
|
||||
for (MediaSource mediaSource : mediaSources) {
|
||||
|
@ -94,11 +94,6 @@ public final class SingleSampleMediaSource implements MediaSource {
|
||||
return oldPlayingPeriodIndex;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Position getDefaultStartPosition(int index) {
|
||||
return Position.DEFAULT;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void maybeThrowSourceInfoRefreshError() throws IOException {
|
||||
// Do nothing.
|
||||
|
@ -59,14 +59,14 @@ public final class DashMediaSource implements MediaSource {
|
||||
public static final int DEFAULT_MIN_LOADABLE_RETRY_COUNT = 3;
|
||||
/**
|
||||
* A constant indicating that the live edge offset (the offset subtracted from the live edge
|
||||
* when calculating the default position returned by {@link #getDefaultStartPosition(int)}) should
|
||||
* be set to {@link DashManifest#suggestedPresentationDelay} if specified by the manifest, or
|
||||
* when calculating the default initial playback position) should be set to
|
||||
* {@link DashManifest#suggestedPresentationDelay} if specified by the manifest, or
|
||||
* {@link #DEFAULT_LIVE_EDGE_OFFSET_FIXED_MS} otherwise.
|
||||
*/
|
||||
public static final long DEFAULT_LIVE_EDGE_OFFSET_PREFER_MANIFEST_MS = -1;
|
||||
/**
|
||||
* A fixed default live edge offset (the offset subtracted from the live edge when calculating the
|
||||
* default position returned by {@link #getDefaultStartPosition(int)}).
|
||||
* default initial playback position).
|
||||
*/
|
||||
public static final long DEFAULT_LIVE_EDGE_OFFSET_FIXED_MS = 30000;
|
||||
/**
|
||||
@ -167,32 +167,6 @@ public final class DashMediaSource implements MediaSource {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Position getDefaultStartPosition(int index) {
|
||||
if (window == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (index == 0 && manifest.dynamic) {
|
||||
// The stream is live, so return a position a position offset from the live edge.
|
||||
int periodIndex = window.endPeriodIndex;
|
||||
long liveEdgeOffsetForManifest = liveEdgeOffsetMs;
|
||||
if (liveEdgeOffsetForManifest == DEFAULT_LIVE_EDGE_OFFSET_PREFER_MANIFEST_MS) {
|
||||
liveEdgeOffsetForManifest = manifest.suggestedPresentationDelay != -1
|
||||
? manifest.suggestedPresentationDelay : DEFAULT_LIVE_EDGE_OFFSET_FIXED_MS;
|
||||
}
|
||||
long positionMs = window.endTimeMs - liveEdgeOffsetForManifest;
|
||||
while (positionMs < 0 && periodIndex > window.startPeriodIndex) {
|
||||
periodIndex--;
|
||||
positionMs += manifest.getPeriodDurationMs(periodIndex);
|
||||
}
|
||||
positionMs = Math.max(positionMs,
|
||||
periodIndex == window.startPeriodIndex ? window.startTimeMs : 0);
|
||||
return new Position(periodIndex, positionMs * 1000);
|
||||
}
|
||||
return new Position(index, 0);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void maybeThrowSourceInfoRefreshError() throws IOException {
|
||||
loader.maybeThrowError();
|
||||
@ -405,8 +379,27 @@ public final class DashMediaSource implements MediaSource {
|
||||
for (int i = 0; i < manifest.getPeriodCount() - 1; i++) {
|
||||
windowDurationUs += manifest.getPeriodDurationUs(i);
|
||||
}
|
||||
int defaultInitialPeriodIndex = 0;
|
||||
long defaultInitialTimeUs = 0;
|
||||
if (manifest.dynamic) {
|
||||
defaultInitialPeriodIndex = lastPeriodIndex;
|
||||
long liveEdgeOffsetForManifestMs = liveEdgeOffsetMs;
|
||||
if (liveEdgeOffsetForManifestMs == DEFAULT_LIVE_EDGE_OFFSET_PREFER_MANIFEST_MS) {
|
||||
liveEdgeOffsetForManifestMs = manifest.suggestedPresentationDelay != -1
|
||||
? manifest.suggestedPresentationDelay : DEFAULT_LIVE_EDGE_OFFSET_FIXED_MS;
|
||||
}
|
||||
defaultInitialTimeUs = currentEndTimeUs - (liveEdgeOffsetForManifestMs * 1000);
|
||||
while (defaultInitialTimeUs < 0 && defaultInitialPeriodIndex > 0) {
|
||||
defaultInitialPeriodIndex--;
|
||||
defaultInitialTimeUs += manifest.getPeriodDurationUs(defaultInitialPeriodIndex);
|
||||
}
|
||||
if (defaultInitialPeriodIndex == 0) {
|
||||
defaultInitialTimeUs = Math.max(defaultInitialTimeUs, currentStartTimeUs);
|
||||
}
|
||||
}
|
||||
window = Window.createWindow(0, currentStartTimeUs, lastPeriodIndex, currentEndTimeUs,
|
||||
windowDurationUs, true /* isSeekable */, manifest.dynamic);
|
||||
windowDurationUs, true /* isSeekable */, manifest.dynamic, defaultInitialPeriodIndex,
|
||||
defaultInitialTimeUs);
|
||||
sourceListener.onSourceInfoRefreshed(new DashTimeline(firstPeriodId, manifest, window),
|
||||
manifest);
|
||||
}
|
||||
|
@ -73,12 +73,6 @@ public final class HlsMediaSource implements MediaSource {
|
||||
return oldPlayingPeriodIndex;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Position getDefaultStartPosition(int index) {
|
||||
// TODO: Return the position of the live edge, if applicable.
|
||||
return Position.DEFAULT;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void maybeThrowSourceInfoRefreshError() {
|
||||
// Do nothing.
|
||||
|
@ -52,7 +52,7 @@ public final class SsMediaSource implements MediaSource,
|
||||
public static final int DEFAULT_MIN_LOADABLE_RETRY_COUNT = 3;
|
||||
/**
|
||||
* A default live edge offset (the offset subtracted from the live edge when calculating the
|
||||
* default position returned by {@link #getDefaultStartPosition(int)}).
|
||||
* default initial playback position.
|
||||
*/
|
||||
public static final long DEFAULT_LIVE_EDGE_OFFSET_MS = 30000;
|
||||
|
||||
@ -73,7 +73,6 @@ public final class SsMediaSource implements MediaSource,
|
||||
|
||||
private long manifestLoadStartTimestamp;
|
||||
private SsManifest manifest;
|
||||
private Window window;
|
||||
|
||||
private Handler manifestRefreshHandler;
|
||||
|
||||
@ -114,19 +113,6 @@ public final class SsMediaSource implements MediaSource,
|
||||
return oldPlayingPeriodIndex;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Position getDefaultStartPosition(int index) {
|
||||
if (window == null) {
|
||||
return null;
|
||||
}
|
||||
if (manifest.isLive) {
|
||||
long startPositionUs = Math.max(window.startTimeMs,
|
||||
window.endTimeMs - liveEdgeOffsetMs) * 1000;
|
||||
return new Position(0, startPositionUs);
|
||||
}
|
||||
return Position.DEFAULT;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void maybeThrowSourceInfoRefreshError() throws IOException {
|
||||
manifestLoader.maybeThrowError();
|
||||
@ -196,15 +182,16 @@ public final class SsMediaSource implements MediaSource,
|
||||
startTimeUs = Math.max(startTimeUs, endTimeUs - manifest.dvrWindowLengthUs);
|
||||
}
|
||||
long durationUs = endTimeUs - startTimeUs;
|
||||
long defaultInitialStartPositionUs = Math.max(startTimeUs,
|
||||
endTimeUs - (liveEdgeOffsetMs * 1000));
|
||||
Window window = Window.createWindow(0, startTimeUs, 0, endTimeUs, durationUs,
|
||||
true /* isSeekable */, true /* isDynamic */);
|
||||
true /* isSeekable */, true /* isDynamic */, 0, defaultInitialStartPositionUs);
|
||||
timeline = new SinglePeriodTimeline(endTimeUs, window);
|
||||
}
|
||||
} else {
|
||||
boolean isSeekable = manifest.durationUs != C.UNSET_TIME_US;
|
||||
timeline = new SinglePeriodTimeline(manifest.durationUs, isSeekable);
|
||||
}
|
||||
window = timeline.getWindow(0);
|
||||
sourceListener.onSourceInfoRefreshed(timeline, manifest);
|
||||
scheduleManifestRefresh();
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user