mirror of
https://github.com/samsonjs/media.git
synced 2026-04-10 12:05:47 +00:00
Support resuming ads
------------- Created by MOE: https://github.com/google/moe MOE_MIGRATED_REVID=161778560
This commit is contained in:
parent
6c74a31556
commit
70c5bf7052
6 changed files with 53 additions and 17 deletions
|
|
@ -51,6 +51,11 @@ import java.util.Arrays;
|
|||
*/
|
||||
public final Uri[][] adUris;
|
||||
|
||||
/**
|
||||
* The position offset in the first unplayed ad at which to begin playback, in microseconds.
|
||||
*/
|
||||
public long adResumePositionUs;
|
||||
|
||||
/**
|
||||
* Creates a new ad playback state with the specified ad group times.
|
||||
*
|
||||
|
|
@ -69,12 +74,13 @@ import java.util.Arrays;
|
|||
}
|
||||
|
||||
private AdPlaybackState(long[] adGroupTimesUs, int[] adCounts, int[] adsLoadedCounts,
|
||||
int[] adsPlayedCounts, Uri[][] adUris) {
|
||||
int[] adsPlayedCounts, Uri[][] adUris, long adResumePositionUs) {
|
||||
this.adGroupTimesUs = adGroupTimesUs;
|
||||
this.adCounts = adCounts;
|
||||
this.adsLoadedCounts = adsLoadedCounts;
|
||||
this.adsPlayedCounts = adsPlayedCounts;
|
||||
this.adUris = adUris;
|
||||
this.adResumePositionUs = adResumePositionUs;
|
||||
adGroupCount = adGroupTimesUs.length;
|
||||
}
|
||||
|
||||
|
|
@ -87,10 +93,8 @@ import java.util.Arrays;
|
|||
adUris[i] = Arrays.copyOf(this.adUris[i], this.adUris[i].length);
|
||||
}
|
||||
return new AdPlaybackState(Arrays.copyOf(adGroupTimesUs, adGroupCount),
|
||||
Arrays.copyOf(adCounts, adGroupCount),
|
||||
Arrays.copyOf(adsLoadedCounts, adGroupCount),
|
||||
Arrays.copyOf(adsPlayedCounts, adGroupCount),
|
||||
adUris);
|
||||
Arrays.copyOf(adCounts, adGroupCount), Arrays.copyOf(adsLoadedCounts, adGroupCount),
|
||||
Arrays.copyOf(adsPlayedCounts, adGroupCount), adUris, adResumePositionUs);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -114,7 +118,15 @@ import java.util.Arrays;
|
|||
* Marks the last ad in the specified ad group as played.
|
||||
*/
|
||||
public void playedAd(int adGroupIndex) {
|
||||
adResumePositionUs = 0;
|
||||
adsPlayedCounts[adGroupIndex]++;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the position offset in the first unplayed ad at which to begin playback, in microseconds.
|
||||
*/
|
||||
public void setAdResumePositionUs(long adResumePositionUs) {
|
||||
this.adResumePositionUs = adResumePositionUs;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -226,7 +226,9 @@ public final class ImaAdsLoader implements ExoPlayer.EventListener, VideoAdPlaye
|
|||
player.addListener(this);
|
||||
if (adPlaybackState != null) {
|
||||
eventListener.onAdPlaybackState(adPlaybackState);
|
||||
// TODO: Call adsManager.resume if an ad is playing.
|
||||
if (playingAd) {
|
||||
adsManager.resume();
|
||||
}
|
||||
} else if (adTagUri != null) {
|
||||
requestAds();
|
||||
}
|
||||
|
|
@ -239,7 +241,8 @@ public final class ImaAdsLoader implements ExoPlayer.EventListener, VideoAdPlaye
|
|||
*/
|
||||
/* package */ void detachPlayer() {
|
||||
if (player != null) {
|
||||
if (adsManager != null && player.isPlayingAd()) {
|
||||
if (adsManager != null && playingAd) {
|
||||
adPlaybackState.setAdResumePositionUs(C.msToUs(player.getCurrentPosition()));
|
||||
adsManager.pause();
|
||||
}
|
||||
lastAdProgress = getAdProgress();
|
||||
|
|
@ -449,12 +452,14 @@ public final class ImaAdsLoader implements ExoPlayer.EventListener, VideoAdPlaye
|
|||
if (DEBUG) {
|
||||
Log.d(TAG, "pauseAd");
|
||||
}
|
||||
if (player == null || !imaPlayingAd) {
|
||||
// This method is called after content is resumed, and may also be called after release.
|
||||
if (!imaPlayingAd) {
|
||||
// This method is called after content is resumed.
|
||||
return;
|
||||
}
|
||||
imaPausedInAd = true;
|
||||
player.setPlayWhenReady(false);
|
||||
if (player != null) {
|
||||
player.setPlayWhenReady(false);
|
||||
}
|
||||
for (VideoAdPlayerCallback callback : adCallbacks) {
|
||||
callback.onPause();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -210,7 +210,7 @@ public final class ImaAdsMediaSource implements MediaSource {
|
|||
if (adPlaybackState != null && contentTimeline != null) {
|
||||
SinglePeriodAdTimeline timeline = new SinglePeriodAdTimeline(contentTimeline,
|
||||
adPlaybackState.adGroupTimesUs, adPlaybackState.adCounts, adPlaybackState.adsLoadedCounts,
|
||||
adPlaybackState.adsPlayedCounts, adDurationsUs);
|
||||
adPlaybackState.adsPlayedCounts, adDurationsUs, adPlaybackState.adResumePositionUs);
|
||||
listener.onSourceInfoRefreshed(timeline, contentManifest);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -30,6 +30,7 @@ public final class SinglePeriodAdTimeline extends Timeline {
|
|||
private final int[] adsLoadedCounts;
|
||||
private final int[] adsPlayedCounts;
|
||||
private final long[][] adDurationsUs;
|
||||
private final long adResumePositionUs;
|
||||
|
||||
/**
|
||||
* Creates a new timeline with a single period containing the specified ads.
|
||||
|
|
@ -45,9 +46,12 @@ public final class SinglePeriodAdTimeline extends Timeline {
|
|||
* @param adsPlayedCounts The number of ads played so far in each ad group.
|
||||
* @param adDurationsUs The duration of each ad in each ad group, in microseconds. An element
|
||||
* may be {@link C#TIME_UNSET} if the duration is not yet known.
|
||||
* @param adResumePositionUs The position offset in the earliest unplayed ad at which to begin
|
||||
* playback, in microseconds.
|
||||
*/
|
||||
public SinglePeriodAdTimeline(Timeline contentTimeline, long[] adGroupTimesUs, int[] adCounts,
|
||||
int[] adsLoadedCounts, int[] adsPlayedCounts, long[][] adDurationsUs) {
|
||||
int[] adsLoadedCounts, int[] adsPlayedCounts, long[][] adDurationsUs,
|
||||
long adResumePositionUs) {
|
||||
Assertions.checkState(contentTimeline.getPeriodCount() == 1);
|
||||
Assertions.checkState(contentTimeline.getWindowCount() == 1);
|
||||
this.contentTimeline = contentTimeline;
|
||||
|
|
@ -56,6 +60,7 @@ public final class SinglePeriodAdTimeline extends Timeline {
|
|||
this.adsLoadedCounts = adsLoadedCounts;
|
||||
this.adsPlayedCounts = adsPlayedCounts;
|
||||
this.adDurationsUs = adDurationsUs;
|
||||
this.adResumePositionUs = adResumePositionUs;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
@ -79,7 +84,7 @@ public final class SinglePeriodAdTimeline extends Timeline {
|
|||
contentTimeline.getPeriod(periodIndex, period, setIds);
|
||||
period.set(period.id, period.uid, period.windowIndex, period.durationUs,
|
||||
period.getPositionInWindowUs(), adGroupTimesUs, adCounts, adsLoadedCounts, adsPlayedCounts,
|
||||
adDurationsUs);
|
||||
adDurationsUs, adResumePositionUs);
|
||||
return period;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -300,8 +300,10 @@ import com.google.android.exoplayer2.source.MediaSource.MediaPeriodId;
|
|||
boolean isLastInTimeline = isLastInTimeline(id, isLastInPeriod);
|
||||
long durationUs = timeline.getPeriod(id.periodIndex, period)
|
||||
.getAdDurationUs(id.adGroupIndex, id.adIndexInAdGroup);
|
||||
return new MediaPeriodInfo(id, 0, C.TIME_END_OF_SOURCE, contentPositionUs, durationUs,
|
||||
isLastInPeriod, isLastInTimeline);
|
||||
long startPositionUs = adIndexInAdGroup == period.getPlayedAdCount(adGroupIndex)
|
||||
? period.getAdResumePositionUs() : 0;
|
||||
return new MediaPeriodInfo(id, startPositionUs, C.TIME_END_OF_SOURCE, contentPositionUs,
|
||||
durationUs, isLastInPeriod, isLastInTimeline);
|
||||
}
|
||||
|
||||
private MediaPeriodInfo getMediaPeriodInfoForContent(int periodIndex, long startPositionUs,
|
||||
|
|
|
|||
|
|
@ -270,6 +270,7 @@ public abstract class Timeline {
|
|||
private int[] adsLoadedCounts;
|
||||
private int[] adsPlayedCounts;
|
||||
private long[][] adDurationsUs;
|
||||
private long adResumePositionUs;
|
||||
|
||||
/**
|
||||
* Sets the data held by this period.
|
||||
|
|
@ -287,7 +288,7 @@ public abstract class Timeline {
|
|||
public Period set(Object id, Object uid, int windowIndex, long durationUs,
|
||||
long positionInWindowUs) {
|
||||
return set(id, uid, windowIndex, durationUs, positionInWindowUs, null, null, null, null,
|
||||
null);
|
||||
null, C.TIME_UNSET);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -310,11 +311,13 @@ public abstract class Timeline {
|
|||
* @param adsPlayedCounts The number of ads played so far in each ad group.
|
||||
* @param adDurationsUs The duration of each ad in each ad group, in microseconds. An element
|
||||
* may be {@link C#TIME_UNSET} if the duration is not yet known.
|
||||
* @param adResumePositionUs The position offset in the first unplayed ad at which to begin
|
||||
* playback, in microseconds.
|
||||
* @return This period, for convenience.
|
||||
*/
|
||||
public Period set(Object id, Object uid, int windowIndex, long durationUs,
|
||||
long positionInWindowUs, long[] adGroupTimesUs, int[] adCounts, int[] adsLoadedCounts,
|
||||
int[] adsPlayedCounts, long[][] adDurationsUs) {
|
||||
int[] adsPlayedCounts, long[][] adDurationsUs, long adResumePositionUs) {
|
||||
this.id = id;
|
||||
this.uid = uid;
|
||||
this.windowIndex = windowIndex;
|
||||
|
|
@ -325,6 +328,7 @@ public abstract class Timeline {
|
|||
this.adsLoadedCounts = adsLoadedCounts;
|
||||
this.adsPlayedCounts = adsPlayedCounts;
|
||||
this.adDurationsUs = adDurationsUs;
|
||||
this.adResumePositionUs = adResumePositionUs;
|
||||
return this;
|
||||
}
|
||||
|
||||
|
|
@ -479,6 +483,14 @@ public abstract class Timeline {
|
|||
return adDurationsUs[adGroupIndex][adIndexInAdGroup];
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the position offset in the first unplayed ad at which to begin playback, in
|
||||
* microseconds.
|
||||
*/
|
||||
public long getAdResumePositionUs() {
|
||||
return adResumePositionUs;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
Loading…
Reference in a new issue