Support resuming content after ads
------------- Created by MOE: https://github.com/google/moe MOE_MIGRATED_REVID=161775394
This commit is contained in:
parent
4f2fae4fba
commit
6c74a31556
@ -406,7 +406,7 @@ public class PlayerActivity extends Activity implements OnClickListener, ExoPlay
|
|||||||
|
|
||||||
private void updateResumePosition() {
|
private void updateResumePosition() {
|
||||||
resumeWindow = player.getCurrentWindowIndex();
|
resumeWindow = player.getCurrentWindowIndex();
|
||||||
resumePosition = player.isCurrentWindowSeekable() ? Math.max(0, player.getCurrentPosition())
|
resumePosition = player.isCurrentWindowSeekable() ? Math.max(0, player.getContentPosition())
|
||||||
: C.TIME_UNSET;
|
: C.TIME_UNSET;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -536,6 +536,11 @@ public final class DynamicConcatenatingMediaSourceTest extends TestCase {
|
|||||||
throw new UnsupportedOperationException();
|
throw new UnsupportedOperationException();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public long getContentPosition() {
|
||||||
|
throw new UnsupportedOperationException();
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean handleMessage(Message msg) {
|
public boolean handleMessage(Message msg) {
|
||||||
ExoPlayerMessage[] messages = (ExoPlayerMessage[]) msg.obj;
|
ExoPlayerMessage[] messages = (ExoPlayerMessage[]) msg.obj;
|
||||||
|
@ -563,4 +563,11 @@ public interface ExoPlayer {
|
|||||||
*/
|
*/
|
||||||
int getCurrentAdIndexInAdGroup();
|
int getCurrentAdIndexInAdGroup();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* If {@link #isPlayingAd()} returns {@code true}, returns the content position that will be
|
||||||
|
* played once all ads in the ad group have finished playing, in milliseconds. If there is no ad
|
||||||
|
* playing, the returned position is the same as that returned by {@link #getCurrentPosition()}.
|
||||||
|
*/
|
||||||
|
long getContentPosition();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -367,6 +367,16 @@ import java.util.concurrent.CopyOnWriteArraySet;
|
|||||||
return pendingSeekAcks == 0 ? playbackInfo.periodId.adIndexInAdGroup : C.INDEX_UNSET;
|
return pendingSeekAcks == 0 ? playbackInfo.periodId.adIndexInAdGroup : C.INDEX_UNSET;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public long getContentPosition() {
|
||||||
|
if (isPlayingAd()) {
|
||||||
|
timeline.getPeriod(playbackInfo.periodId.periodIndex, period);
|
||||||
|
return period.getPositionInWindowMs() + C.usToMs(playbackInfo.contentPositionUs);
|
||||||
|
} else {
|
||||||
|
return getCurrentPosition();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getRendererCount() {
|
public int getRendererCount() {
|
||||||
return renderers.length;
|
return renderers.length;
|
||||||
|
@ -54,6 +54,7 @@ import java.io.IOException;
|
|||||||
|
|
||||||
public final MediaPeriodId periodId;
|
public final MediaPeriodId periodId;
|
||||||
public final long startPositionUs;
|
public final long startPositionUs;
|
||||||
|
public final long contentPositionUs;
|
||||||
|
|
||||||
public volatile long positionUs;
|
public volatile long positionUs;
|
||||||
public volatile long bufferedPositionUs;
|
public volatile long bufferedPositionUs;
|
||||||
@ -63,14 +64,20 @@ import java.io.IOException;
|
|||||||
}
|
}
|
||||||
|
|
||||||
public PlaybackInfo(MediaPeriodId periodId, long startPositionUs) {
|
public PlaybackInfo(MediaPeriodId periodId, long startPositionUs) {
|
||||||
|
this(periodId, startPositionUs, C.TIME_UNSET);
|
||||||
|
}
|
||||||
|
|
||||||
|
public PlaybackInfo(MediaPeriodId periodId, long startPositionUs, long contentPositionUs) {
|
||||||
this.periodId = periodId;
|
this.periodId = periodId;
|
||||||
this.startPositionUs = startPositionUs;
|
this.startPositionUs = startPositionUs;
|
||||||
|
this.contentPositionUs = contentPositionUs;
|
||||||
positionUs = startPositionUs;
|
positionUs = startPositionUs;
|
||||||
bufferedPositionUs = startPositionUs;
|
bufferedPositionUs = startPositionUs;
|
||||||
}
|
}
|
||||||
|
|
||||||
public PlaybackInfo copyWithPeriodId(MediaPeriodId periodId) {
|
public PlaybackInfo copyWithPeriodIndex(int periodIndex) {
|
||||||
PlaybackInfo playbackInfo = new PlaybackInfo(periodId.periodIndex, startPositionUs);
|
PlaybackInfo playbackInfo = new PlaybackInfo(periodId.copyWithPeriodIndex(periodIndex),
|
||||||
|
startPositionUs, contentPositionUs);
|
||||||
playbackInfo.positionUs = positionUs;
|
playbackInfo.positionUs = positionUs;
|
||||||
playbackInfo.bufferedPositionUs = bufferedPositionUs;
|
playbackInfo.bufferedPositionUs = bufferedPositionUs;
|
||||||
return playbackInfo;
|
return playbackInfo;
|
||||||
@ -486,7 +493,7 @@ import java.io.IOException;
|
|||||||
// position of the playing period to make sure none of the removed period is played.
|
// position of the playing period to make sure none of the removed period is played.
|
||||||
MediaPeriodId periodId = playingPeriodHolder.info.id;
|
MediaPeriodId periodId = playingPeriodHolder.info.id;
|
||||||
long newPositionUs = seekToPeriodPosition(periodId, playbackInfo.positionUs);
|
long newPositionUs = seekToPeriodPosition(periodId, playbackInfo.positionUs);
|
||||||
playbackInfo = new PlaybackInfo(periodId, newPositionUs);
|
playbackInfo = new PlaybackInfo(periodId, newPositionUs, playbackInfo.contentPositionUs);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -663,11 +670,11 @@ import java.io.IOException;
|
|||||||
boolean seekPositionAdjusted = seekPosition.windowPositionUs == C.TIME_UNSET;
|
boolean seekPositionAdjusted = seekPosition.windowPositionUs == C.TIME_UNSET;
|
||||||
int periodIndex = periodPosition.first;
|
int periodIndex = periodPosition.first;
|
||||||
long periodPositionUs = periodPosition.second;
|
long periodPositionUs = periodPosition.second;
|
||||||
|
long contentPositionUs = periodPositionUs;
|
||||||
MediaPeriodId periodId =
|
MediaPeriodId periodId =
|
||||||
mediaPeriodInfoSequence.resolvePeriodPositionForAds(periodIndex, periodPositionUs);
|
mediaPeriodInfoSequence.resolvePeriodPositionForAds(periodIndex, periodPositionUs);
|
||||||
if (periodId.isAd()) {
|
if (periodId.isAd()) {
|
||||||
seekPositionAdjusted = true;
|
seekPositionAdjusted = true;
|
||||||
// TODO: Resume content at periodPositionUs after the ad plays.
|
|
||||||
periodPositionUs = 0;
|
periodPositionUs = 0;
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
@ -680,7 +687,7 @@ import java.io.IOException;
|
|||||||
seekPositionAdjusted |= periodPositionUs != newPeriodPositionUs;
|
seekPositionAdjusted |= periodPositionUs != newPeriodPositionUs;
|
||||||
periodPositionUs = newPeriodPositionUs;
|
periodPositionUs = newPeriodPositionUs;
|
||||||
} finally {
|
} finally {
|
||||||
playbackInfo = new PlaybackInfo(periodId, periodPositionUs);
|
playbackInfo = new PlaybackInfo(periodId, periodPositionUs, contentPositionUs);
|
||||||
eventHandler.obtainMessage(MSG_SEEK_ACK, seekPositionAdjusted ? 1 : 0, 0, playbackInfo)
|
eventHandler.obtainMessage(MSG_SEEK_ACK, seekPositionAdjusted ? 1 : 0, 0, playbackInfo)
|
||||||
.sendToTarget();
|
.sendToTarget();
|
||||||
}
|
}
|
||||||
@ -985,16 +992,19 @@ import java.io.IOException;
|
|||||||
long positionUs = periodPosition.second;
|
long positionUs = periodPosition.second;
|
||||||
MediaPeriodId periodId =
|
MediaPeriodId periodId =
|
||||||
mediaPeriodInfoSequence.resolvePeriodPositionForAds(periodIndex, positionUs);
|
mediaPeriodInfoSequence.resolvePeriodPositionForAds(periodIndex, positionUs);
|
||||||
playbackInfo = new PlaybackInfo(periodId, periodId.isAd() ? 0 : positionUs);
|
playbackInfo = new PlaybackInfo(periodId, periodId.isAd() ? 0 : positionUs, positionUs);
|
||||||
} else if (playbackInfo.startPositionUs == C.TIME_UNSET) {
|
} else if (playbackInfo.startPositionUs == C.TIME_UNSET) {
|
||||||
if (timeline.isEmpty()) {
|
if (timeline.isEmpty()) {
|
||||||
handleSourceInfoRefreshEndedPlayback(manifest, processedInitialSeekCount);
|
handleSourceInfoRefreshEndedPlayback(manifest, processedInitialSeekCount);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
Pair<Integer, Long> defaultPosition = getPeriodPosition(0, C.TIME_UNSET);
|
Pair<Integer, Long> defaultPosition = getPeriodPosition(0, C.TIME_UNSET);
|
||||||
MediaPeriodId periodId = mediaPeriodInfoSequence.resolvePeriodPositionForAds(
|
int periodIndex = defaultPosition.first;
|
||||||
defaultPosition.first, defaultPosition.second);
|
long startPositionUs = defaultPosition.second;
|
||||||
playbackInfo = new PlaybackInfo(periodId, periodId.isAd() ? 0 : defaultPosition.second);
|
MediaPeriodId periodId = mediaPeriodInfoSequence.resolvePeriodPositionForAds(periodIndex,
|
||||||
|
startPositionUs);
|
||||||
|
playbackInfo = new PlaybackInfo(periodId, periodId.isAd() ? 0 : startPositionUs,
|
||||||
|
startPositionUs);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1047,8 +1057,7 @@ import java.io.IOException;
|
|||||||
// The current period is in the new timeline. Update the holder and playbackInfo.
|
// The current period is in the new timeline. Update the holder and playbackInfo.
|
||||||
periodHolder = updatePeriodInfo(periodHolder, periodIndex);
|
periodHolder = updatePeriodInfo(periodHolder, periodIndex);
|
||||||
if (periodIndex != playbackInfo.periodId.periodIndex) {
|
if (periodIndex != playbackInfo.periodId.periodIndex) {
|
||||||
playbackInfo =
|
playbackInfo = playbackInfo.copyWithPeriodIndex(periodIndex);
|
||||||
playbackInfo.copyWithPeriodId(playbackInfo.periodId.copyWithPeriodIndex(periodIndex));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// If there are subsequent holders, update the index for each of them. If we find a holder
|
// If there are subsequent holders, update the index for each of them. If we find a holder
|
||||||
@ -1070,7 +1079,8 @@ import java.io.IOException;
|
|||||||
// position of the playing period to make sure none of the removed period is played.
|
// position of the playing period to make sure none of the removed period is played.
|
||||||
long newPositionUs =
|
long newPositionUs =
|
||||||
seekToPeriodPosition(playingPeriodHolder.info.id, playbackInfo.positionUs);
|
seekToPeriodPosition(playingPeriodHolder.info.id, playbackInfo.positionUs);
|
||||||
playbackInfo = new PlaybackInfo(playingPeriodHolder.info.id, newPositionUs);
|
playbackInfo = new PlaybackInfo(playingPeriodHolder.info.id, newPositionUs,
|
||||||
|
playbackInfo.contentPositionUs);
|
||||||
} else {
|
} else {
|
||||||
// Update the loading period to be the last period that's still valid, and release all
|
// Update the loading period to be the last period that's still valid, and release all
|
||||||
// subsequent periods.
|
// subsequent periods.
|
||||||
@ -1223,7 +1233,7 @@ import java.io.IOException;
|
|||||||
playingPeriodHolder.release();
|
playingPeriodHolder.release();
|
||||||
setPlayingPeriodHolder(playingPeriodHolder.next);
|
setPlayingPeriodHolder(playingPeriodHolder.next);
|
||||||
playbackInfo = new PlaybackInfo(playingPeriodHolder.info.id,
|
playbackInfo = new PlaybackInfo(playingPeriodHolder.info.id,
|
||||||
playingPeriodHolder.info.startPositionUs);
|
playingPeriodHolder.info.startPositionUs, playingPeriodHolder.info.contentPositionUs);
|
||||||
updatePlaybackPositions();
|
updatePlaybackPositions();
|
||||||
eventHandler.obtainMessage(MSG_POSITION_DISCONTINUITY, playbackInfo).sendToTarget();
|
eventHandler.obtainMessage(MSG_POSITION_DISCONTINUITY, playbackInfo).sendToTarget();
|
||||||
}
|
}
|
||||||
|
@ -47,6 +47,11 @@ import com.google.android.exoplayer2.source.MediaSource.MediaPeriodId;
|
|||||||
* {@link C#TIME_END_OF_SOURCE} if the end position is the end of the media period.
|
* {@link C#TIME_END_OF_SOURCE} if the end position is the end of the media period.
|
||||||
*/
|
*/
|
||||||
public final long endPositionUs;
|
public final long endPositionUs;
|
||||||
|
/**
|
||||||
|
* If this is an ad, the position to play in the next content media period. {@link C#TIME_UNSET}
|
||||||
|
* otherwise.
|
||||||
|
*/
|
||||||
|
public final long contentPositionUs;
|
||||||
/**
|
/**
|
||||||
* The duration of the media to play within the media period, in microseconds, or
|
* The duration of the media to play within the media period, in microseconds, or
|
||||||
* {@link C#TIME_UNSET} if not known.
|
* {@link C#TIME_UNSET} if not known.
|
||||||
@ -64,10 +69,11 @@ import com.google.android.exoplayer2.source.MediaSource.MediaPeriodId;
|
|||||||
public final boolean isFinal;
|
public final boolean isFinal;
|
||||||
|
|
||||||
private MediaPeriodInfo(MediaPeriodId id, long startPositionUs, long endPositionUs,
|
private MediaPeriodInfo(MediaPeriodId id, long startPositionUs, long endPositionUs,
|
||||||
long durationUs, boolean isLastInTimelinePeriod, boolean isFinal) {
|
long contentPositionUs, long durationUs, boolean isLastInTimelinePeriod, boolean isFinal) {
|
||||||
this.id = id;
|
this.id = id;
|
||||||
this.startPositionUs = startPositionUs;
|
this.startPositionUs = startPositionUs;
|
||||||
this.endPositionUs = endPositionUs;
|
this.endPositionUs = endPositionUs;
|
||||||
|
this.contentPositionUs = contentPositionUs;
|
||||||
this.durationUs = durationUs;
|
this.durationUs = durationUs;
|
||||||
this.isLastInTimelinePeriod = isLastInTimelinePeriod;
|
this.isLastInTimelinePeriod = isLastInTimelinePeriod;
|
||||||
this.isFinal = isFinal;
|
this.isFinal = isFinal;
|
||||||
@ -79,14 +85,14 @@ import com.google.android.exoplayer2.source.MediaSource.MediaPeriodId;
|
|||||||
*/
|
*/
|
||||||
public MediaPeriodInfo copyWithPeriodIndex(int periodIndex) {
|
public MediaPeriodInfo copyWithPeriodIndex(int periodIndex) {
|
||||||
return new MediaPeriodInfo(id.copyWithPeriodIndex(periodIndex), startPositionUs,
|
return new MediaPeriodInfo(id.copyWithPeriodIndex(periodIndex), startPositionUs,
|
||||||
endPositionUs, durationUs, isLastInTimelinePeriod, isFinal);
|
endPositionUs, contentPositionUs, durationUs, isLastInTimelinePeriod, isFinal);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns a copy of this instance with the start position set to the specified value.
|
* Returns a copy of this instance with the start position set to the specified value.
|
||||||
*/
|
*/
|
||||||
public MediaPeriodInfo copyWithStartPositionUs(long startPositionUs) {
|
public MediaPeriodInfo copyWithStartPositionUs(long startPositionUs) {
|
||||||
return new MediaPeriodInfo(id, startPositionUs, endPositionUs, durationUs,
|
return new MediaPeriodInfo(id, startPositionUs, endPositionUs, contentPositionUs, durationUs,
|
||||||
isLastInTimelinePeriod, isFinal);
|
isLastInTimelinePeriod, isFinal);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -127,7 +133,8 @@ import com.google.android.exoplayer2.source.MediaSource.MediaPeriodId;
|
|||||||
* Returns the first {@link MediaPeriodInfo} to play, based on the specified playback position.
|
* Returns the first {@link MediaPeriodInfo} to play, based on the specified playback position.
|
||||||
*/
|
*/
|
||||||
public MediaPeriodInfo getFirstMediaPeriodInfo(PlaybackInfo playbackInfo) {
|
public MediaPeriodInfo getFirstMediaPeriodInfo(PlaybackInfo playbackInfo) {
|
||||||
return getMediaPeriodInfo(playbackInfo.periodId, playbackInfo.startPositionUs);
|
return getMediaPeriodInfo(playbackInfo.periodId, playbackInfo.contentPositionUs,
|
||||||
|
playbackInfo.startPositionUs);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -173,8 +180,8 @@ import com.google.android.exoplayer2.source.MediaSource.MediaPeriodId;
|
|||||||
} else {
|
} else {
|
||||||
startPositionUs = 0;
|
startPositionUs = 0;
|
||||||
}
|
}
|
||||||
return getMediaPeriodInfo(resolvePeriodPositionForAds(nextPeriodIndex, startPositionUs),
|
MediaPeriodId periodId = resolvePeriodPositionForAds(nextPeriodIndex, startPositionUs);
|
||||||
startPositionUs);
|
return getMediaPeriodInfo(periodId, startPositionUs, startPositionUs);
|
||||||
}
|
}
|
||||||
|
|
||||||
MediaPeriodId currentPeriodId = currentMediaPeriodInfo.id;
|
MediaPeriodId currentPeriodId = currentMediaPeriodInfo.id;
|
||||||
@ -190,18 +197,23 @@ import com.google.android.exoplayer2.source.MediaSource.MediaPeriodId;
|
|||||||
// Play the next ad in the ad group if it's available.
|
// Play the next ad in the ad group if it's available.
|
||||||
return !period.isAdAvailable(currentAdGroupIndex, nextAdIndexInAdGroup) ? null
|
return !period.isAdAvailable(currentAdGroupIndex, nextAdIndexInAdGroup) ? null
|
||||||
: getMediaPeriodInfoForAd(currentPeriodId.periodIndex, currentAdGroupIndex,
|
: getMediaPeriodInfoForAd(currentPeriodId.periodIndex, currentAdGroupIndex,
|
||||||
nextAdIndexInAdGroup);
|
nextAdIndexInAdGroup, currentMediaPeriodInfo.contentPositionUs);
|
||||||
} else {
|
} else {
|
||||||
// Play content from the ad group position.
|
// Play content from the ad group position.
|
||||||
return getMediaPeriodInfo(new MediaPeriodId(currentPeriodId.periodIndex),
|
int nextAdGroupIndex =
|
||||||
period.getAdGroupTimeUs(currentAdGroupIndex));
|
period.getAdGroupIndexAfterPositionUs(currentMediaPeriodInfo.contentPositionUs);
|
||||||
|
long endUs = nextAdGroupIndex == C.INDEX_UNSET ? C.TIME_END_OF_SOURCE
|
||||||
|
: period.getAdGroupTimeUs(nextAdGroupIndex);
|
||||||
|
return getMediaPeriodInfoForContent(currentPeriodId.periodIndex,
|
||||||
|
currentMediaPeriodInfo.contentPositionUs, endUs);
|
||||||
}
|
}
|
||||||
} else if (currentMediaPeriodInfo.endPositionUs != C.TIME_END_OF_SOURCE) {
|
} else if (currentMediaPeriodInfo.endPositionUs != C.TIME_END_OF_SOURCE) {
|
||||||
// Play the next ad group if it's available.
|
// Play the next ad group if it's available.
|
||||||
int nextAdGroupIndex =
|
int nextAdGroupIndex =
|
||||||
period.getAdGroupIndexForPositionUs(currentMediaPeriodInfo.endPositionUs);
|
period.getAdGroupIndexForPositionUs(currentMediaPeriodInfo.endPositionUs);
|
||||||
return !period.isAdAvailable(nextAdGroupIndex, 0) ? null
|
return !period.isAdAvailable(nextAdGroupIndex, 0) ? null
|
||||||
: getMediaPeriodInfoForAd(currentPeriodId.periodIndex, nextAdGroupIndex, 0);
|
: getMediaPeriodInfoForAd(currentPeriodId.periodIndex, nextAdGroupIndex, 0,
|
||||||
|
currentMediaPeriodInfo.endPositionUs);
|
||||||
} else {
|
} else {
|
||||||
// Check if the postroll ad should be played.
|
// Check if the postroll ad should be played.
|
||||||
int adGroupCount = period.getAdGroupCount();
|
int adGroupCount = period.getAdGroupCount();
|
||||||
@ -211,7 +223,8 @@ import com.google.android.exoplayer2.source.MediaSource.MediaPeriodId;
|
|||||||
|| !period.isAdAvailable(adGroupCount - 1, 0)) {
|
|| !period.isAdAvailable(adGroupCount - 1, 0)) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
return getMediaPeriodInfoForAd(currentPeriodId.periodIndex, adGroupCount - 1, 0);
|
return getMediaPeriodInfoForAd(currentPeriodId.periodIndex, adGroupCount - 1, 0,
|
||||||
|
currentMediaPeriodInfo.endPositionUs);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -223,8 +236,12 @@ import com.google.android.exoplayer2.source.MediaSource.MediaPeriodId;
|
|||||||
public MediaPeriodId resolvePeriodPositionForAds(int periodIndex, long positionUs) {
|
public MediaPeriodId resolvePeriodPositionForAds(int periodIndex, long positionUs) {
|
||||||
timeline.getPeriod(periodIndex, period);
|
timeline.getPeriod(periodIndex, period);
|
||||||
int adGroupIndex = period.getAdGroupIndexForPositionUs(positionUs);
|
int adGroupIndex = period.getAdGroupIndexForPositionUs(positionUs);
|
||||||
return adGroupIndex == C.INDEX_UNSET ? new MediaPeriodId(periodIndex)
|
if (adGroupIndex == C.INDEX_UNSET) {
|
||||||
: new MediaPeriodId(periodIndex, adGroupIndex, 0);
|
return new MediaPeriodId(periodIndex);
|
||||||
|
} else {
|
||||||
|
int adIndexInAdGroup = period.getPlayedAdCount(adGroupIndex);
|
||||||
|
return new MediaPeriodId(periodIndex, adGroupIndex, adIndexInAdGroup);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -255,17 +272,19 @@ import com.google.android.exoplayer2.source.MediaSource.MediaPeriodId;
|
|||||||
long durationUs = newId.isAd()
|
long durationUs = newId.isAd()
|
||||||
? period.getAdDurationUs(newId.adGroupIndex, newId.adIndexInAdGroup)
|
? period.getAdDurationUs(newId.adGroupIndex, newId.adIndexInAdGroup)
|
||||||
: (endPositionUs == C.TIME_END_OF_SOURCE ? period.getDurationUs() : endPositionUs);
|
: (endPositionUs == C.TIME_END_OF_SOURCE ? period.getDurationUs() : endPositionUs);
|
||||||
return new MediaPeriodInfo(newId, startPositionUs, endPositionUs, durationUs, isLastInPeriod,
|
return new MediaPeriodInfo(newId, startPositionUs, endPositionUs, info.contentPositionUs,
|
||||||
isLastInTimeline);
|
durationUs, isLastInPeriod, isLastInTimeline);
|
||||||
}
|
}
|
||||||
|
|
||||||
private MediaPeriodInfo getMediaPeriodInfo(MediaPeriodId id, long startPositionUs) {
|
private MediaPeriodInfo getMediaPeriodInfo(MediaPeriodId id, long contentPositionUs,
|
||||||
|
long startPositionUs) {
|
||||||
timeline.getPeriod(id.periodIndex, period);
|
timeline.getPeriod(id.periodIndex, period);
|
||||||
if (id.isAd()) {
|
if (id.isAd()) {
|
||||||
if (!period.isAdAvailable(id.adGroupIndex, id.adIndexInAdGroup)) {
|
if (!period.isAdAvailable(id.adGroupIndex, id.adIndexInAdGroup)) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
return getMediaPeriodInfoForAd(id.periodIndex, id.adGroupIndex, id.adIndexInAdGroup);
|
return getMediaPeriodInfoForAd(id.periodIndex, id.adGroupIndex, id.adIndexInAdGroup,
|
||||||
|
contentPositionUs);
|
||||||
} else {
|
} else {
|
||||||
int nextAdGroupIndex = period.getAdGroupIndexAfterPositionUs(startPositionUs);
|
int nextAdGroupIndex = period.getAdGroupIndexAfterPositionUs(startPositionUs);
|
||||||
long endUs = nextAdGroupIndex == C.INDEX_UNSET ? C.TIME_END_OF_SOURCE
|
long endUs = nextAdGroupIndex == C.INDEX_UNSET ? C.TIME_END_OF_SOURCE
|
||||||
@ -275,14 +294,14 @@ import com.google.android.exoplayer2.source.MediaSource.MediaPeriodId;
|
|||||||
}
|
}
|
||||||
|
|
||||||
private MediaPeriodInfo getMediaPeriodInfoForAd(int periodIndex, int adGroupIndex,
|
private MediaPeriodInfo getMediaPeriodInfoForAd(int periodIndex, int adGroupIndex,
|
||||||
int adIndexInAdGroup) {
|
int adIndexInAdGroup, long contentPositionUs) {
|
||||||
MediaPeriodId id = new MediaPeriodId(periodIndex, adGroupIndex, adIndexInAdGroup);
|
MediaPeriodId id = new MediaPeriodId(periodIndex, adGroupIndex, adIndexInAdGroup);
|
||||||
boolean isLastInPeriod = isLastInPeriod(id, C.TIME_END_OF_SOURCE);
|
boolean isLastInPeriod = isLastInPeriod(id, C.TIME_END_OF_SOURCE);
|
||||||
boolean isLastInTimeline = isLastInTimeline(id, isLastInPeriod);
|
boolean isLastInTimeline = isLastInTimeline(id, isLastInPeriod);
|
||||||
long durationUs = timeline.getPeriod(id.periodIndex, period)
|
long durationUs = timeline.getPeriod(id.periodIndex, period)
|
||||||
.getAdDurationUs(id.adGroupIndex, id.adIndexInAdGroup);
|
.getAdDurationUs(id.adGroupIndex, id.adIndexInAdGroup);
|
||||||
return new MediaPeriodInfo(id, 0, C.TIME_END_OF_SOURCE, durationUs, isLastInPeriod,
|
return new MediaPeriodInfo(id, 0, C.TIME_END_OF_SOURCE, contentPositionUs, durationUs,
|
||||||
isLastInTimeline);
|
isLastInPeriod, isLastInTimeline);
|
||||||
}
|
}
|
||||||
|
|
||||||
private MediaPeriodInfo getMediaPeriodInfoForContent(int periodIndex, long startPositionUs,
|
private MediaPeriodInfo getMediaPeriodInfoForContent(int periodIndex, long startPositionUs,
|
||||||
@ -292,7 +311,7 @@ import com.google.android.exoplayer2.source.MediaSource.MediaPeriodId;
|
|||||||
boolean isLastInTimeline = isLastInTimeline(id, isLastInPeriod);
|
boolean isLastInTimeline = isLastInTimeline(id, isLastInPeriod);
|
||||||
timeline.getPeriod(id.periodIndex, period);
|
timeline.getPeriod(id.periodIndex, period);
|
||||||
long durationUs = endUs == C.TIME_END_OF_SOURCE ? period.getDurationUs() : endUs;
|
long durationUs = endUs == C.TIME_END_OF_SOURCE ? period.getDurationUs() : endUs;
|
||||||
return new MediaPeriodInfo(id, startPositionUs, endUs, durationUs, isLastInPeriod,
|
return new MediaPeriodInfo(id, startPositionUs, endUs, C.TIME_UNSET, durationUs, isLastInPeriod,
|
||||||
isLastInTimeline);
|
isLastInTimeline);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -715,6 +715,11 @@ public class SimpleExoPlayer implements ExoPlayer {
|
|||||||
return player.getCurrentAdIndexInAdGroup();
|
return player.getCurrentAdIndexInAdGroup();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public long getContentPosition() {
|
||||||
|
return player.getContentPosition();
|
||||||
|
}
|
||||||
|
|
||||||
// Internal methods.
|
// Internal methods.
|
||||||
|
|
||||||
private void removeSurfaceCallbacks() {
|
private void removeSurfaceCallbacks() {
|
||||||
|
@ -378,6 +378,16 @@ public abstract class Timeline {
|
|||||||
return adGroupTimesUs[adGroupIndex];
|
return adGroupTimesUs[adGroupIndex];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the number of ads that have been played in the specified ad group in the period.
|
||||||
|
*
|
||||||
|
* @param adGroupIndex The ad group index.
|
||||||
|
* @return The number of ads that have been played.
|
||||||
|
*/
|
||||||
|
public int getPlayedAdCount(int adGroupIndex) {
|
||||||
|
return adsPlayedCounts[adGroupIndex];
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns whether the ad group at index {@code adGroupIndex} has been played.
|
* Returns whether the ad group at index {@code adGroupIndex} has been played.
|
||||||
*
|
*
|
||||||
|
Loading…
x
Reference in New Issue
Block a user