mirror of
https://github.com/androidx/media.git
synced 2025-05-15 19:49:50 +08:00
Don't drop updates of the playing period for skipped SSI ads
Before this change ExpPlayerImplInternal dropped a change of the playing period when a change in the timeline occurred that actually changed the playing period but we don't want to update the period queue. This logic also dropped the update of a skipped server side inserted preroll ad for which we want the periodQueue to 'seek' to the stream position after the preroll ad and trigger a SKIP discontinuity. This change now introduces an exception so that a skipped SSI ad is still causing an update in the period queue which leads to a 'seek' and a discontinuity of type SKIP. PiperOrigin-RevId: 411607299
This commit is contained in:
parent
a4368beb7b
commit
92c971ecd0
@ -15,6 +15,7 @@
|
|||||||
*/
|
*/
|
||||||
package com.google.android.exoplayer2;
|
package com.google.android.exoplayer2;
|
||||||
|
|
||||||
|
import static com.google.android.exoplayer2.source.ads.AdPlaybackState.AD_STATE_UNAVAILABLE;
|
||||||
import static com.google.android.exoplayer2.util.Assertions.checkArgument;
|
import static com.google.android.exoplayer2.util.Assertions.checkArgument;
|
||||||
import static com.google.android.exoplayer2.util.Assertions.checkState;
|
import static com.google.android.exoplayer2.util.Assertions.checkState;
|
||||||
import static java.lang.Math.max;
|
import static java.lang.Math.max;
|
||||||
@ -815,6 +816,21 @@ public abstract class Timeline implements Bundleable {
|
|||||||
return adGroup.count != C.LENGTH_UNSET ? adGroup.durationsUs[adIndexInAdGroup] : C.TIME_UNSET;
|
return adGroup.count != C.LENGTH_UNSET ? adGroup.durationsUs[adIndexInAdGroup] : C.TIME_UNSET;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the state of the ad at index {@code adIndexInAdGroup} in the ad group at {@code
|
||||||
|
* adGroupIndex}, or {@link AdPlaybackState#AD_STATE_UNAVAILABLE} if not yet known.
|
||||||
|
*
|
||||||
|
* @param adGroupIndex The ad group index.
|
||||||
|
* @return The state of the ad, or {@link AdPlaybackState#AD_STATE_UNAVAILABLE} if not yet
|
||||||
|
* known.
|
||||||
|
*/
|
||||||
|
public int getAdState(int adGroupIndex, int adIndexInAdGroup) {
|
||||||
|
AdPlaybackState.AdGroup adGroup = adPlaybackState.getAdGroup(adGroupIndex);
|
||||||
|
return adGroup.count != C.LENGTH_UNSET
|
||||||
|
? adGroup.states[adIndexInAdGroup]
|
||||||
|
: AD_STATE_UNAVAILABLE;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the position offset in the first unplayed ad at which to begin playback, in
|
* Returns the position offset in the first unplayed ad at which to begin playback, in
|
||||||
* microseconds.
|
* microseconds.
|
||||||
|
@ -44,6 +44,7 @@ import com.google.android.exoplayer2.source.MediaSource.MediaPeriodId;
|
|||||||
import com.google.android.exoplayer2.source.SampleStream;
|
import com.google.android.exoplayer2.source.SampleStream;
|
||||||
import com.google.android.exoplayer2.source.ShuffleOrder;
|
import com.google.android.exoplayer2.source.ShuffleOrder;
|
||||||
import com.google.android.exoplayer2.source.TrackGroupArray;
|
import com.google.android.exoplayer2.source.TrackGroupArray;
|
||||||
|
import com.google.android.exoplayer2.source.ads.AdPlaybackState;
|
||||||
import com.google.android.exoplayer2.text.TextRenderer;
|
import com.google.android.exoplayer2.text.TextRenderer;
|
||||||
import com.google.android.exoplayer2.trackselection.ExoTrackSelection;
|
import com.google.android.exoplayer2.trackselection.ExoTrackSelection;
|
||||||
import com.google.android.exoplayer2.trackselection.TrackSelector;
|
import com.google.android.exoplayer2.trackselection.TrackSelector;
|
||||||
@ -2648,15 +2649,14 @@ import java.util.concurrent.atomic.AtomicBoolean;
|
|||||||
&& earliestCuePointIsUnchangedOrLater;
|
&& earliestCuePointIsUnchangedOrLater;
|
||||||
// Drop update if the change is from/to server-side inserted ads at the same content position to
|
// Drop update if the change is from/to server-side inserted ads at the same content position to
|
||||||
// avoid any unintentional renderer reset.
|
// avoid any unintentional renderer reset.
|
||||||
timeline.getPeriodByUid(newPeriodUid, period);
|
|
||||||
boolean isInStreamAdChange =
|
boolean isInStreamAdChange =
|
||||||
sameOldAndNewPeriodUid
|
isIgnorableServerSideAdInsertionPeriodChange(
|
||||||
&& !isUsingPlaceholderPeriod
|
isUsingPlaceholderPeriod,
|
||||||
&& oldContentPositionUs == newContentPositionUs
|
oldPeriodId,
|
||||||
&& ((periodIdWithAds.isAd()
|
oldContentPositionUs,
|
||||||
&& period.isServerSideInsertedAdGroup(periodIdWithAds.adGroupIndex))
|
periodIdWithAds,
|
||||||
|| (oldPeriodId.isAd()
|
timeline.getPeriodByUid(newPeriodUid, period),
|
||||||
&& period.isServerSideInsertedAdGroup(oldPeriodId.adGroupIndex)));
|
newContentPositionUs);
|
||||||
MediaPeriodId newPeriodId =
|
MediaPeriodId newPeriodId =
|
||||||
onlyNextAdGroupIndexIncreased || isInStreamAdChange ? oldPeriodId : periodIdWithAds;
|
onlyNextAdGroupIndexIncreased || isInStreamAdChange ? oldPeriodId : periodIdWithAds;
|
||||||
|
|
||||||
@ -2682,6 +2682,30 @@ import java.util.concurrent.atomic.AtomicBoolean;
|
|||||||
setTargetLiveOffset);
|
setTargetLiveOffset);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static boolean isIgnorableServerSideAdInsertionPeriodChange(
|
||||||
|
boolean isUsingPlaceholderPeriod,
|
||||||
|
MediaPeriodId oldPeriodId,
|
||||||
|
long oldContentPositionUs,
|
||||||
|
MediaPeriodId newPeriodId,
|
||||||
|
Timeline.Period newPeriod,
|
||||||
|
long newContentPositionUs) {
|
||||||
|
if (isUsingPlaceholderPeriod
|
||||||
|
|| oldContentPositionUs != newContentPositionUs
|
||||||
|
|| !oldPeriodId.periodUid.equals(newPeriodId.periodUid)) {
|
||||||
|
// The period position changed.
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (oldPeriodId.isAd() && newPeriod.isServerSideInsertedAdGroup(oldPeriodId.adGroupIndex)) {
|
||||||
|
// Whether the old period was a server side ad that doesn't need skipping to the content.
|
||||||
|
return newPeriod.getAdState(oldPeriodId.adGroupIndex, oldPeriodId.adIndexInAdGroup)
|
||||||
|
!= AdPlaybackState.AD_STATE_ERROR
|
||||||
|
&& newPeriod.getAdState(oldPeriodId.adGroupIndex, oldPeriodId.adIndexInAdGroup)
|
||||||
|
!= AdPlaybackState.AD_STATE_SKIPPED;
|
||||||
|
}
|
||||||
|
// If the new period is a server side inserted ad, we can just continue playing.
|
||||||
|
return newPeriodId.isAd() && newPeriod.isServerSideInsertedAdGroup(newPeriodId.adGroupIndex);
|
||||||
|
}
|
||||||
|
|
||||||
private static boolean isUsingPlaceholderPeriod(
|
private static boolean isUsingPlaceholderPeriod(
|
||||||
PlaybackInfo playbackInfo, Timeline.Period period) {
|
PlaybackInfo playbackInfo, Timeline.Period period) {
|
||||||
MediaPeriodId periodId = playbackInfo.periodId;
|
MediaPeriodId periodId = playbackInfo.periodId;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user