提交 5211f06d 编写于 作者: T tonihei 提交者: Oliver Woodman

Don't apply speed adjustment if windowStartTime is unknown.

This may happen for HLS live streams without program date time
information.

Issue: #8560

PiperOrigin-RevId: 356227729
上级 a0851431
# Release notes
### 2.13.1 (not yet released)
* Core library:
* Fix playback issue for HLS live streams without program date time
information ([#8560](https://github.com/google/ExoPlayer/issues/8560)).
### 2.13.0 (2021-02-04)
* Core library:
......
......@@ -880,7 +880,7 @@ import java.util.concurrent.atomic.AtomicBoolean;
// Adjust live playback speed to new position.
if (playbackInfo.playWhenReady
&& playbackInfo.playbackState == Player.STATE_READY
&& isCurrentPeriodInMovingLiveWindow()
&& shouldUseLivePlaybackSpeedControl(playbackInfo.timeline, playbackInfo.periodId)
&& playbackInfo.playbackParameters.speed == 1f) {
float adjustedSpeed =
livePlaybackSpeedControl.getAdjustedPlaybackSpeed(
......@@ -1051,17 +1051,14 @@ import java.util.concurrent.atomic.AtomicBoolean;
- (periodPositionUs + period.getPositionInWindowUs());
}
private boolean isCurrentPeriodInMovingLiveWindow() {
return isInMovingLiveWindow(playbackInfo.timeline, playbackInfo.periodId);
}
private boolean isInMovingLiveWindow(Timeline timeline, MediaPeriodId mediaPeriodId) {
private boolean shouldUseLivePlaybackSpeedControl(
Timeline timeline, MediaPeriodId mediaPeriodId) {
if (mediaPeriodId.isAd() || timeline.isEmpty()) {
return false;
}
int windowIndex = timeline.getPeriodByUid(mediaPeriodId.periodUid, period).windowIndex;
timeline.getWindow(windowIndex, window);
return window.isLive() && window.isDynamic;
return window.isLive() && window.isDynamic && window.windowStartTimeMs != C.TIME_UNSET;
}
private void scheduleNextWork(long thisOperationStartTimeMs, long intervalMs) {
......@@ -1725,7 +1722,7 @@ import java.util.concurrent.atomic.AtomicBoolean;
}
// Renderers are ready and we're loading. Ask the LoadControl whether to transition.
long targetLiveOffsetUs =
isInMovingLiveWindow(playbackInfo.timeline, queue.getPlayingPeriod().info.id)
shouldUseLivePlaybackSpeedControl(playbackInfo.timeline, queue.getPlayingPeriod().info.id)
? livePlaybackSpeedControl.getTargetLiveOffsetUs()
: C.TIME_UNSET;
MediaPeriodHolder loadingHolder = queue.getLoadingPeriod();
......@@ -1831,7 +1828,7 @@ import java.util.concurrent.atomic.AtomicBoolean;
Timeline oldTimeline,
MediaPeriodId oldPeriodId,
long positionForTargetOffsetOverrideUs) {
if (newTimeline.isEmpty() || !isInMovingLiveWindow(newTimeline, newPeriodId)) {
if (newTimeline.isEmpty() || !shouldUseLivePlaybackSpeedControl(newTimeline, newPeriodId)) {
// Live playback speed control is unused.
return;
}
......
......@@ -71,6 +71,7 @@ import com.google.android.exoplayer2.source.MediaSource;
import com.google.android.exoplayer2.source.MediaSource.MediaPeriodId;
import com.google.android.exoplayer2.source.MediaSourceEventListener;
import com.google.android.exoplayer2.source.SilenceMediaSource;
import com.google.android.exoplayer2.source.SinglePeriodTimeline;
import com.google.android.exoplayer2.source.TrackGroup;
import com.google.android.exoplayer2.source.TrackGroupArray;
import com.google.android.exoplayer2.source.ads.AdPlaybackState;
......@@ -83,6 +84,7 @@ import com.google.android.exoplayer2.testutil.ExoPlayerTestRunner;
import com.google.android.exoplayer2.testutil.FakeAdaptiveDataSet;
import com.google.android.exoplayer2.testutil.FakeAdaptiveMediaSource;
import com.google.android.exoplayer2.testutil.FakeChunkSource;
import com.google.android.exoplayer2.testutil.FakeClock;
import com.google.android.exoplayer2.testutil.FakeDataSource;
import com.google.android.exoplayer2.testutil.FakeMediaClockRenderer;
import com.google.android.exoplayer2.testutil.FakeMediaPeriod;
......@@ -8833,6 +8835,42 @@ public final class ExoPlayerTest {
assertThat(liveOffsetAtEnd).isIn(Range.closed(1_900L, 2_100L));
}
@Test
public void targetLiveOffsetInMedia_unknownWindowStartTime_doesNotAdjustLiveOffset()
throws Exception {
FakeClock fakeClock = new AutoAdvancingFakeClock(/* initialTimeMs= */ 987_654_321L);
ExoPlayer player = new TestExoPlayerBuilder(context).setClock(fakeClock).build();
MediaItem mediaItem =
new MediaItem.Builder().setUri(Uri.EMPTY).setLiveTargetOffsetMs(4_000).build();
Timeline liveTimeline =
new SinglePeriodTimeline(
/* presentationStartTimeMs= */ C.TIME_UNSET,
/* windowStartTimeMs= */ C.TIME_UNSET,
/* elapsedRealtimeEpochOffsetMs= */ C.TIME_UNSET,
/* periodDurationUs= */ 1000 * C.MICROS_PER_SECOND,
/* windowDurationUs= */ 1000 * C.MICROS_PER_SECOND,
/* windowPositionInPeriodUs= */ 0,
/* windowDefaultStartPositionUs= */ 0,
/* isSeekable= */ true,
/* isDynamic= */ true,
/* manifest= */ null,
mediaItem,
mediaItem.liveConfiguration);
player.pause();
player.setMediaSource(new FakeMediaSource(liveTimeline));
player.prepare();
TestPlayerRunHelper.runUntilPlaybackState(player, Player.STATE_READY);
long playbackStartTimeMs = fakeClock.elapsedRealtime();
TestPlayerRunHelper.playUntilPosition(player, /* windowIndex= */ 0, /* positionMs= */ 999_000);
long playbackEndTimeMs = fakeClock.elapsedRealtime();
player.release();
// Assert that the time it took to play 999 seconds of media is 999 seconds (asserting that no
// playback speed adjustment was used).
assertThat(playbackEndTimeMs - playbackStartTimeMs).isEqualTo(999_000);
}
@Test
public void noTargetLiveOffsetInMedia_doesNotAdjustLiveOffset() throws Exception {
long windowStartUnixTimeMs = 987_654_321_000L;
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册