mirror of
https://github.com/samsonjs/media.git
synced 2026-04-27 15:07:40 +00:00
Add AdPlaybackStateUpdater
PiperOrigin-RevId: 416314200
This commit is contained in:
parent
cdc0e2e618
commit
51237e8aef
2 changed files with 41 additions and 13 deletions
|
|
@ -82,10 +82,32 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
|
||||||
public final class ServerSideAdInsertionMediaSource extends BaseMediaSource
|
public final class ServerSideAdInsertionMediaSource extends BaseMediaSource
|
||||||
implements MediaSource.MediaSourceCaller, MediaSourceEventListener, DrmSessionEventListener {
|
implements MediaSource.MediaSourceCaller, MediaSourceEventListener, DrmSessionEventListener {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Receives ad playback state update requests when the {@link Timeline} of the content media
|
||||||
|
* source has changed.
|
||||||
|
*/
|
||||||
|
public interface AdPlaybackStateUpdater {
|
||||||
|
/**
|
||||||
|
* Called when the content source has refreshed the timeline.
|
||||||
|
*
|
||||||
|
* <p>If true is returned the source refresh publication is deferred, to wait for an {@link
|
||||||
|
* #setAdPlaybackState(AdPlaybackState) ad playback state update}. If false is returned, the
|
||||||
|
* source refresh is immediately published.
|
||||||
|
*
|
||||||
|
* <p>Called on the playback thread.
|
||||||
|
*
|
||||||
|
* @param contentTimeline The {@link Timeline} of the wrapped content media source.
|
||||||
|
* @return true to defer the source refresh publication, or false to immediately publish the
|
||||||
|
* source refresh.
|
||||||
|
*/
|
||||||
|
boolean onAdPlaybackStateUpdateRequested(Timeline contentTimeline);
|
||||||
|
}
|
||||||
|
|
||||||
private final MediaSource mediaSource;
|
private final MediaSource mediaSource;
|
||||||
private final ListMultimap<Long, SharedMediaPeriod> mediaPeriods;
|
private final ListMultimap<Long, SharedMediaPeriod> mediaPeriods;
|
||||||
private final MediaSourceEventListener.EventDispatcher mediaSourceEventDispatcherWithoutId;
|
private final MediaSourceEventListener.EventDispatcher mediaSourceEventDispatcherWithoutId;
|
||||||
private final DrmSessionEventListener.EventDispatcher drmEventDispatcherWithoutId;
|
private final DrmSessionEventListener.EventDispatcher drmEventDispatcherWithoutId;
|
||||||
|
@Nullable private final AdPlaybackStateUpdater adPlaybackStateUpdater;
|
||||||
|
|
||||||
@GuardedBy("this")
|
@GuardedBy("this")
|
||||||
@Nullable
|
@Nullable
|
||||||
|
|
@ -99,11 +121,15 @@ public final class ServerSideAdInsertionMediaSource extends BaseMediaSource
|
||||||
* Creates the media source.
|
* Creates the media source.
|
||||||
*
|
*
|
||||||
* @param mediaSource The {@link MediaSource} to wrap.
|
* @param mediaSource The {@link MediaSource} to wrap.
|
||||||
|
* @param adPlaybackStateUpdater The optional {@link AdPlaybackStateUpdater} to be called before a
|
||||||
|
* source refresh is published.
|
||||||
*/
|
*/
|
||||||
// Calling BaseMediaSource.createEventDispatcher from the constructor.
|
// Calling BaseMediaSource.createEventDispatcher from the constructor.
|
||||||
@SuppressWarnings("nullness:method.invocation")
|
@SuppressWarnings("nullness:method.invocation")
|
||||||
public ServerSideAdInsertionMediaSource(MediaSource mediaSource) {
|
public ServerSideAdInsertionMediaSource(
|
||||||
|
MediaSource mediaSource, @Nullable AdPlaybackStateUpdater adPlaybackStateUpdater) {
|
||||||
this.mediaSource = mediaSource;
|
this.mediaSource = mediaSource;
|
||||||
|
this.adPlaybackStateUpdater = adPlaybackStateUpdater;
|
||||||
mediaPeriods = ArrayListMultimap.create();
|
mediaPeriods = ArrayListMultimap.create();
|
||||||
adPlaybackState = AdPlaybackState.NONE;
|
adPlaybackState = AdPlaybackState.NONE;
|
||||||
mediaSourceEventDispatcherWithoutId = createEventDispatcher(/* mediaPeriodId= */ null);
|
mediaSourceEventDispatcherWithoutId = createEventDispatcher(/* mediaPeriodId= */ null);
|
||||||
|
|
@ -193,11 +219,12 @@ public final class ServerSideAdInsertionMediaSource extends BaseMediaSource
|
||||||
@Override
|
@Override
|
||||||
public void onSourceInfoRefreshed(MediaSource source, Timeline timeline) {
|
public void onSourceInfoRefreshed(MediaSource source, Timeline timeline) {
|
||||||
this.contentTimeline = timeline;
|
this.contentTimeline = timeline;
|
||||||
if (AdPlaybackState.NONE.equals(adPlaybackState)) {
|
if ((adPlaybackStateUpdater == null
|
||||||
return;
|
|| !adPlaybackStateUpdater.onAdPlaybackStateUpdateRequested(timeline))
|
||||||
}
|
&& !AdPlaybackState.NONE.equals(adPlaybackState)) {
|
||||||
refreshSourceInfo(new ServerSideAdInsertionTimeline(timeline, adPlaybackState));
|
refreshSourceInfo(new ServerSideAdInsertionTimeline(timeline, adPlaybackState));
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void releaseSourceInternal() {
|
protected void releaseSourceInternal() {
|
||||||
|
|
|
||||||
|
|
@ -82,7 +82,8 @@ public final class ServerSideAdInsertionMediaSourceTest {
|
||||||
/* windowOffsetInFirstPeriodUs= */ 42_000_000L,
|
/* windowOffsetInFirstPeriodUs= */ 42_000_000L,
|
||||||
AdPlaybackState.NONE));
|
AdPlaybackState.NONE));
|
||||||
ServerSideAdInsertionMediaSource mediaSource =
|
ServerSideAdInsertionMediaSource mediaSource =
|
||||||
new ServerSideAdInsertionMediaSource(new FakeMediaSource(wrappedTimeline));
|
new ServerSideAdInsertionMediaSource(
|
||||||
|
new FakeMediaSource(wrappedTimeline), /* adPlaybackStateUpdater= */ null);
|
||||||
// Test with one ad group before the window, and the window starting within the second ad group.
|
// Test with one ad group before the window, and the window starting within the second ad group.
|
||||||
AdPlaybackState adPlaybackState =
|
AdPlaybackState adPlaybackState =
|
||||||
new AdPlaybackState(
|
new AdPlaybackState(
|
||||||
|
|
@ -155,8 +156,8 @@ public final class ServerSideAdInsertionMediaSourceTest {
|
||||||
|
|
||||||
ServerSideAdInsertionMediaSource mediaSource =
|
ServerSideAdInsertionMediaSource mediaSource =
|
||||||
new ServerSideAdInsertionMediaSource(
|
new ServerSideAdInsertionMediaSource(
|
||||||
new DefaultMediaSourceFactory(context)
|
new DefaultMediaSourceFactory(context).createMediaSource(MediaItem.fromUri(TEST_ASSET)),
|
||||||
.createMediaSource(MediaItem.fromUri(TEST_ASSET)));
|
/* adPlaybackStateUpdater= */ null);
|
||||||
AdPlaybackState adPlaybackState = new AdPlaybackState(/* adsId= */ new Object());
|
AdPlaybackState adPlaybackState = new AdPlaybackState(/* adsId= */ new Object());
|
||||||
adPlaybackState =
|
adPlaybackState =
|
||||||
addAdGroupToAdPlaybackState(
|
addAdGroupToAdPlaybackState(
|
||||||
|
|
@ -214,8 +215,8 @@ public final class ServerSideAdInsertionMediaSourceTest {
|
||||||
|
|
||||||
ServerSideAdInsertionMediaSource mediaSource =
|
ServerSideAdInsertionMediaSource mediaSource =
|
||||||
new ServerSideAdInsertionMediaSource(
|
new ServerSideAdInsertionMediaSource(
|
||||||
new DefaultMediaSourceFactory(context)
|
new DefaultMediaSourceFactory(context).createMediaSource(MediaItem.fromUri(TEST_ASSET)),
|
||||||
.createMediaSource(MediaItem.fromUri(TEST_ASSET)));
|
/* adPlaybackStateUpdater= */ null);
|
||||||
AdPlaybackState adPlaybackState = new AdPlaybackState(/* adsId= */ new Object());
|
AdPlaybackState adPlaybackState = new AdPlaybackState(/* adsId= */ new Object());
|
||||||
adPlaybackState =
|
adPlaybackState =
|
||||||
addAdGroupToAdPlaybackState(
|
addAdGroupToAdPlaybackState(
|
||||||
|
|
@ -274,8 +275,8 @@ public final class ServerSideAdInsertionMediaSourceTest {
|
||||||
|
|
||||||
ServerSideAdInsertionMediaSource mediaSource =
|
ServerSideAdInsertionMediaSource mediaSource =
|
||||||
new ServerSideAdInsertionMediaSource(
|
new ServerSideAdInsertionMediaSource(
|
||||||
new DefaultMediaSourceFactory(context)
|
new DefaultMediaSourceFactory(context).createMediaSource(MediaItem.fromUri(TEST_ASSET)),
|
||||||
.createMediaSource(MediaItem.fromUri(TEST_ASSET)));
|
/* adPlaybackStateUpdater= */ null);
|
||||||
AdPlaybackState adPlaybackState = new AdPlaybackState(/* adsId= */ new Object());
|
AdPlaybackState adPlaybackState = new AdPlaybackState(/* adsId= */ new Object());
|
||||||
adPlaybackState =
|
adPlaybackState =
|
||||||
addAdGroupToAdPlaybackState(
|
addAdGroupToAdPlaybackState(
|
||||||
|
|
@ -328,8 +329,8 @@ public final class ServerSideAdInsertionMediaSourceTest {
|
||||||
|
|
||||||
ServerSideAdInsertionMediaSource mediaSource =
|
ServerSideAdInsertionMediaSource mediaSource =
|
||||||
new ServerSideAdInsertionMediaSource(
|
new ServerSideAdInsertionMediaSource(
|
||||||
new DefaultMediaSourceFactory(context)
|
new DefaultMediaSourceFactory(context).createMediaSource(MediaItem.fromUri(TEST_ASSET)),
|
||||||
.createMediaSource(MediaItem.fromUri(TEST_ASSET)));
|
/* adPlaybackStateUpdater= */ null);
|
||||||
AdPlaybackState adPlaybackState = new AdPlaybackState(/* adsId= */ new Object());
|
AdPlaybackState adPlaybackState = new AdPlaybackState(/* adsId= */ new Object());
|
||||||
adPlaybackState =
|
adPlaybackState =
|
||||||
addAdGroupToAdPlaybackState(
|
addAdGroupToAdPlaybackState(
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue