Project start position for preroll ad to content transitions
------------- Created by MOE: https://github.com/google/moe MOE_MIGRATED_REVID=216675981
This commit is contained in:
parent
048c8bd68f
commit
81a9293072
@ -22,6 +22,9 @@
|
|||||||
* Fix issue where buffered position is not updated correctly when transitioning
|
* Fix issue where buffered position is not updated correctly when transitioning
|
||||||
between periods
|
between periods
|
||||||
([#4899](https://github.com/google/ExoPlayer/issues/4899)).
|
([#4899](https://github.com/google/ExoPlayer/issues/4899)).
|
||||||
|
* IMA extension:
|
||||||
|
* For preroll to live stream transitions, project forward the loading position
|
||||||
|
to avoid being behind the live window.
|
||||||
|
|
||||||
### 2.9.0 ###
|
### 2.9.0 ###
|
||||||
|
|
||||||
|
@ -533,6 +533,11 @@ import com.google.android.exoplayer2.util.Assertions;
|
|||||||
// until the timeline is updated. Store whether the next timeline period is ready when the
|
// until the timeline is updated. Store whether the next timeline period is ready when the
|
||||||
// timeline is updated, to avoid repeatedly checking the same timeline.
|
// timeline is updated, to avoid repeatedly checking the same timeline.
|
||||||
MediaPeriodInfo mediaPeriodInfo = mediaPeriodHolder.info;
|
MediaPeriodInfo mediaPeriodInfo = mediaPeriodHolder.info;
|
||||||
|
// The expected delay until playback transitions to the new period is equal the duration of
|
||||||
|
// media that's currently buffered (assuming no interruptions). This is used to project forward
|
||||||
|
// the start position for transitions to new windows.
|
||||||
|
long bufferedDurationUs =
|
||||||
|
mediaPeriodHolder.getRendererOffset() + mediaPeriodInfo.durationUs - rendererPositionUs;
|
||||||
if (mediaPeriodInfo.isLastInTimelinePeriod) {
|
if (mediaPeriodInfo.isLastInTimelinePeriod) {
|
||||||
int currentPeriodIndex = timeline.getIndexOfPeriod(mediaPeriodInfo.id.periodUid);
|
int currentPeriodIndex = timeline.getIndexOfPeriod(mediaPeriodInfo.id.periodUid);
|
||||||
int nextPeriodIndex =
|
int nextPeriodIndex =
|
||||||
@ -550,19 +555,15 @@ import com.google.android.exoplayer2.util.Assertions;
|
|||||||
long windowSequenceNumber = mediaPeriodInfo.id.windowSequenceNumber;
|
long windowSequenceNumber = mediaPeriodInfo.id.windowSequenceNumber;
|
||||||
if (timeline.getWindow(nextWindowIndex, window).firstPeriodIndex == nextPeriodIndex) {
|
if (timeline.getWindow(nextWindowIndex, window).firstPeriodIndex == nextPeriodIndex) {
|
||||||
// We're starting to buffer a new window. When playback transitions to this window we'll
|
// We're starting to buffer a new window. When playback transitions to this window we'll
|
||||||
// want it to be from its default start position. The expected delay until playback
|
// want it to be from its default start position, so project the default start position
|
||||||
// transitions is equal the duration of media that's currently buffered (assuming no
|
// forward by the duration of the buffer, and start buffering from this point.
|
||||||
// interruptions). Hence we project the default start position forward by the duration of
|
|
||||||
// the buffer, and start buffering from this point.
|
|
||||||
long defaultPositionProjectionUs =
|
|
||||||
mediaPeriodHolder.getRendererOffset() + mediaPeriodInfo.durationUs - rendererPositionUs;
|
|
||||||
Pair<Object, Long> defaultPosition =
|
Pair<Object, Long> defaultPosition =
|
||||||
timeline.getPeriodPosition(
|
timeline.getPeriodPosition(
|
||||||
window,
|
window,
|
||||||
period,
|
period,
|
||||||
nextWindowIndex,
|
nextWindowIndex,
|
||||||
C.TIME_UNSET,
|
/* windowPositionUs= */ C.TIME_UNSET,
|
||||||
Math.max(0, defaultPositionProjectionUs));
|
/* defaultPositionProjectionUs= */ Math.max(0, bufferedDurationUs));
|
||||||
if (defaultPosition == null) {
|
if (defaultPosition == null) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
@ -603,11 +604,27 @@ import com.google.android.exoplayer2.util.Assertions;
|
|||||||
mediaPeriodInfo.contentPositionUs,
|
mediaPeriodInfo.contentPositionUs,
|
||||||
currentPeriodId.windowSequenceNumber);
|
currentPeriodId.windowSequenceNumber);
|
||||||
} else {
|
} else {
|
||||||
// Play content from the ad group position.
|
// Play content from the ad group position. As a special case, if we're transitioning from a
|
||||||
|
// preroll ad group to content and there are no other ad groups, project the start position
|
||||||
|
// forward as if this were a transition to a new window. No attempt is made to handle
|
||||||
|
// midrolls in live streams, as it's unclear what content position should play after an ad
|
||||||
|
// (server-side dynamic ad insertion is more appropriate for this use case).
|
||||||
|
long startPositionUs = mediaPeriodInfo.contentPositionUs;
|
||||||
|
if (period.getAdGroupCount() == 1 && period.getAdGroupTimeUs(0) == 0) {
|
||||||
|
Pair<Object, Long> defaultPosition =
|
||||||
|
timeline.getPeriodPosition(
|
||||||
|
window,
|
||||||
|
period,
|
||||||
|
period.windowIndex,
|
||||||
|
/* windowPositionUs= */ C.TIME_UNSET,
|
||||||
|
/* defaultPositionProjectionUs= */ Math.max(0, bufferedDurationUs));
|
||||||
|
if (defaultPosition == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
startPositionUs = defaultPosition.second;
|
||||||
|
}
|
||||||
return getMediaPeriodInfoForContent(
|
return getMediaPeriodInfoForContent(
|
||||||
currentPeriodId.periodUid,
|
currentPeriodId.periodUid, startPositionUs, currentPeriodId.windowSequenceNumber);
|
||||||
mediaPeriodInfo.contentPositionUs,
|
|
||||||
currentPeriodId.windowSequenceNumber);
|
|
||||||
}
|
}
|
||||||
} else if (mediaPeriodInfo.id.endPositionUs != C.TIME_END_OF_SOURCE) {
|
} else if (mediaPeriodInfo.id.endPositionUs != C.TIME_END_OF_SOURCE) {
|
||||||
// Play the next ad group if it's available.
|
// Play the next ad group if it's available.
|
||||||
|
Loading…
x
Reference in New Issue
Block a user