mirror of
https://github.com/samsonjs/media.git
synced 2026-04-27 15:07:40 +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;
|
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.
|
* 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,
|
private AdPlaybackState(long[] adGroupTimesUs, int[] adCounts, int[] adsLoadedCounts,
|
||||||
int[] adsPlayedCounts, Uri[][] adUris) {
|
int[] adsPlayedCounts, Uri[][] adUris, long adResumePositionUs) {
|
||||||
this.adGroupTimesUs = adGroupTimesUs;
|
this.adGroupTimesUs = adGroupTimesUs;
|
||||||
this.adCounts = adCounts;
|
this.adCounts = adCounts;
|
||||||
this.adsLoadedCounts = adsLoadedCounts;
|
this.adsLoadedCounts = adsLoadedCounts;
|
||||||
this.adsPlayedCounts = adsPlayedCounts;
|
this.adsPlayedCounts = adsPlayedCounts;
|
||||||
this.adUris = adUris;
|
this.adUris = adUris;
|
||||||
|
this.adResumePositionUs = adResumePositionUs;
|
||||||
adGroupCount = adGroupTimesUs.length;
|
adGroupCount = adGroupTimesUs.length;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -87,10 +93,8 @@ import java.util.Arrays;
|
||||||
adUris[i] = Arrays.copyOf(this.adUris[i], this.adUris[i].length);
|
adUris[i] = Arrays.copyOf(this.adUris[i], this.adUris[i].length);
|
||||||
}
|
}
|
||||||
return new AdPlaybackState(Arrays.copyOf(adGroupTimesUs, adGroupCount),
|
return new AdPlaybackState(Arrays.copyOf(adGroupTimesUs, adGroupCount),
|
||||||
Arrays.copyOf(adCounts, adGroupCount),
|
Arrays.copyOf(adCounts, adGroupCount), Arrays.copyOf(adsLoadedCounts, adGroupCount),
|
||||||
Arrays.copyOf(adsLoadedCounts, adGroupCount),
|
Arrays.copyOf(adsPlayedCounts, adGroupCount), adUris, adResumePositionUs);
|
||||||
Arrays.copyOf(adsPlayedCounts, adGroupCount),
|
|
||||||
adUris);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -114,7 +118,15 @@ import java.util.Arrays;
|
||||||
* Marks the last ad in the specified ad group as played.
|
* Marks the last ad in the specified ad group as played.
|
||||||
*/
|
*/
|
||||||
public void playedAd(int adGroupIndex) {
|
public void playedAd(int adGroupIndex) {
|
||||||
|
adResumePositionUs = 0;
|
||||||
adsPlayedCounts[adGroupIndex]++;
|
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);
|
player.addListener(this);
|
||||||
if (adPlaybackState != null) {
|
if (adPlaybackState != null) {
|
||||||
eventListener.onAdPlaybackState(adPlaybackState);
|
eventListener.onAdPlaybackState(adPlaybackState);
|
||||||
// TODO: Call adsManager.resume if an ad is playing.
|
if (playingAd) {
|
||||||
|
adsManager.resume();
|
||||||
|
}
|
||||||
} else if (adTagUri != null) {
|
} else if (adTagUri != null) {
|
||||||
requestAds();
|
requestAds();
|
||||||
}
|
}
|
||||||
|
|
@ -239,7 +241,8 @@ public final class ImaAdsLoader implements ExoPlayer.EventListener, VideoAdPlaye
|
||||||
*/
|
*/
|
||||||
/* package */ void detachPlayer() {
|
/* package */ void detachPlayer() {
|
||||||
if (player != null) {
|
if (player != null) {
|
||||||
if (adsManager != null && player.isPlayingAd()) {
|
if (adsManager != null && playingAd) {
|
||||||
|
adPlaybackState.setAdResumePositionUs(C.msToUs(player.getCurrentPosition()));
|
||||||
adsManager.pause();
|
adsManager.pause();
|
||||||
}
|
}
|
||||||
lastAdProgress = getAdProgress();
|
lastAdProgress = getAdProgress();
|
||||||
|
|
@ -449,12 +452,14 @@ public final class ImaAdsLoader implements ExoPlayer.EventListener, VideoAdPlaye
|
||||||
if (DEBUG) {
|
if (DEBUG) {
|
||||||
Log.d(TAG, "pauseAd");
|
Log.d(TAG, "pauseAd");
|
||||||
}
|
}
|
||||||
if (player == null || !imaPlayingAd) {
|
if (!imaPlayingAd) {
|
||||||
// This method is called after content is resumed, and may also be called after release.
|
// This method is called after content is resumed.
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
imaPausedInAd = true;
|
imaPausedInAd = true;
|
||||||
player.setPlayWhenReady(false);
|
if (player != null) {
|
||||||
|
player.setPlayWhenReady(false);
|
||||||
|
}
|
||||||
for (VideoAdPlayerCallback callback : adCallbacks) {
|
for (VideoAdPlayerCallback callback : adCallbacks) {
|
||||||
callback.onPause();
|
callback.onPause();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -210,7 +210,7 @@ public final class ImaAdsMediaSource implements MediaSource {
|
||||||
if (adPlaybackState != null && contentTimeline != null) {
|
if (adPlaybackState != null && contentTimeline != null) {
|
||||||
SinglePeriodAdTimeline timeline = new SinglePeriodAdTimeline(contentTimeline,
|
SinglePeriodAdTimeline timeline = new SinglePeriodAdTimeline(contentTimeline,
|
||||||
adPlaybackState.adGroupTimesUs, adPlaybackState.adCounts, adPlaybackState.adsLoadedCounts,
|
adPlaybackState.adGroupTimesUs, adPlaybackState.adCounts, adPlaybackState.adsLoadedCounts,
|
||||||
adPlaybackState.adsPlayedCounts, adDurationsUs);
|
adPlaybackState.adsPlayedCounts, adDurationsUs, adPlaybackState.adResumePositionUs);
|
||||||
listener.onSourceInfoRefreshed(timeline, contentManifest);
|
listener.onSourceInfoRefreshed(timeline, contentManifest);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -30,6 +30,7 @@ public final class SinglePeriodAdTimeline extends Timeline {
|
||||||
private final int[] adsLoadedCounts;
|
private final int[] adsLoadedCounts;
|
||||||
private final int[] adsPlayedCounts;
|
private final int[] adsPlayedCounts;
|
||||||
private final long[][] adDurationsUs;
|
private final long[][] adDurationsUs;
|
||||||
|
private final long adResumePositionUs;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a new timeline with a single period containing the specified ads.
|
* 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 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
|
* @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.
|
* 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,
|
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.getPeriodCount() == 1);
|
||||||
Assertions.checkState(contentTimeline.getWindowCount() == 1);
|
Assertions.checkState(contentTimeline.getWindowCount() == 1);
|
||||||
this.contentTimeline = contentTimeline;
|
this.contentTimeline = contentTimeline;
|
||||||
|
|
@ -56,6 +60,7 @@ public final class SinglePeriodAdTimeline extends Timeline {
|
||||||
this.adsLoadedCounts = adsLoadedCounts;
|
this.adsLoadedCounts = adsLoadedCounts;
|
||||||
this.adsPlayedCounts = adsPlayedCounts;
|
this.adsPlayedCounts = adsPlayedCounts;
|
||||||
this.adDurationsUs = adDurationsUs;
|
this.adDurationsUs = adDurationsUs;
|
||||||
|
this.adResumePositionUs = adResumePositionUs;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
@ -79,7 +84,7 @@ public final class SinglePeriodAdTimeline extends Timeline {
|
||||||
contentTimeline.getPeriod(periodIndex, period, setIds);
|
contentTimeline.getPeriod(periodIndex, period, setIds);
|
||||||
period.set(period.id, period.uid, period.windowIndex, period.durationUs,
|
period.set(period.id, period.uid, period.windowIndex, period.durationUs,
|
||||||
period.getPositionInWindowUs(), adGroupTimesUs, adCounts, adsLoadedCounts, adsPlayedCounts,
|
period.getPositionInWindowUs(), adGroupTimesUs, adCounts, adsLoadedCounts, adsPlayedCounts,
|
||||||
adDurationsUs);
|
adDurationsUs, adResumePositionUs);
|
||||||
return period;
|
return period;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -300,8 +300,10 @@ import com.google.android.exoplayer2.source.MediaSource.MediaPeriodId;
|
||||||
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, contentPositionUs, durationUs,
|
long startPositionUs = adIndexInAdGroup == period.getPlayedAdCount(adGroupIndex)
|
||||||
isLastInPeriod, isLastInTimeline);
|
? period.getAdResumePositionUs() : 0;
|
||||||
|
return new MediaPeriodInfo(id, startPositionUs, C.TIME_END_OF_SOURCE, contentPositionUs,
|
||||||
|
durationUs, isLastInPeriod, isLastInTimeline);
|
||||||
}
|
}
|
||||||
|
|
||||||
private MediaPeriodInfo getMediaPeriodInfoForContent(int periodIndex, long startPositionUs,
|
private MediaPeriodInfo getMediaPeriodInfoForContent(int periodIndex, long startPositionUs,
|
||||||
|
|
|
||||||
|
|
@ -270,6 +270,7 @@ public abstract class Timeline {
|
||||||
private int[] adsLoadedCounts;
|
private int[] adsLoadedCounts;
|
||||||
private int[] adsPlayedCounts;
|
private int[] adsPlayedCounts;
|
||||||
private long[][] adDurationsUs;
|
private long[][] adDurationsUs;
|
||||||
|
private long adResumePositionUs;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the data held by this period.
|
* 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,
|
public Period set(Object id, Object uid, int windowIndex, long durationUs,
|
||||||
long positionInWindowUs) {
|
long positionInWindowUs) {
|
||||||
return set(id, uid, windowIndex, durationUs, positionInWindowUs, null, null, null, null,
|
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 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
|
* @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.
|
* 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.
|
* @return This period, for convenience.
|
||||||
*/
|
*/
|
||||||
public Period set(Object id, Object uid, int windowIndex, long durationUs,
|
public Period set(Object id, Object uid, int windowIndex, long durationUs,
|
||||||
long positionInWindowUs, long[] adGroupTimesUs, int[] adCounts, int[] adsLoadedCounts,
|
long positionInWindowUs, long[] adGroupTimesUs, int[] adCounts, int[] adsLoadedCounts,
|
||||||
int[] adsPlayedCounts, long[][] adDurationsUs) {
|
int[] adsPlayedCounts, long[][] adDurationsUs, long adResumePositionUs) {
|
||||||
this.id = id;
|
this.id = id;
|
||||||
this.uid = uid;
|
this.uid = uid;
|
||||||
this.windowIndex = windowIndex;
|
this.windowIndex = windowIndex;
|
||||||
|
|
@ -325,6 +328,7 @@ public abstract class Timeline {
|
||||||
this.adsLoadedCounts = adsLoadedCounts;
|
this.adsLoadedCounts = adsLoadedCounts;
|
||||||
this.adsPlayedCounts = adsPlayedCounts;
|
this.adsPlayedCounts = adsPlayedCounts;
|
||||||
this.adDurationsUs = adDurationsUs;
|
this.adDurationsUs = adDurationsUs;
|
||||||
|
this.adResumePositionUs = adResumePositionUs;
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -479,6 +483,14 @@ public abstract class Timeline {
|
||||||
return adDurationsUs[adGroupIndex][adIndexInAdGroup];
|
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