mirror of
https://github.com/androidx/media.git
synced 2025-04-30 06:46:50 +08:00
Store ad playback state in AdsLoader for resume after backgrounding
#minor-release PiperOrigin-RevId: 428763656
This commit is contained in:
parent
33afc4760b
commit
b9b1be4f3e
@ -151,6 +151,7 @@ public final class ImaServerSideAdInsertionMediaSource extends CompositeMediaSou
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public MediaSource createMediaSource(MediaItem mediaItem) {
|
public MediaSource createMediaSource(MediaItem mediaItem) {
|
||||||
|
checkNotNull(mediaItem.localConfiguration);
|
||||||
Player player = checkNotNull(adsLoader.player);
|
Player player = checkNotNull(adsLoader.player);
|
||||||
StreamPlayer streamPlayer = new StreamPlayer(player, mediaItem);
|
StreamPlayer streamPlayer = new StreamPlayer(player, mediaItem);
|
||||||
ImaSdkFactory imaSdkFactory = ImaSdkFactory.getInstance();
|
ImaSdkFactory imaSdkFactory = ImaSdkFactory.getInstance();
|
||||||
@ -163,6 +164,7 @@ public final class ImaServerSideAdInsertionMediaSource extends CompositeMediaSou
|
|||||||
new ImaServerSideAdInsertionMediaSource(
|
new ImaServerSideAdInsertionMediaSource(
|
||||||
mediaItem,
|
mediaItem,
|
||||||
player,
|
player,
|
||||||
|
adsLoader,
|
||||||
imaAdsLoader,
|
imaAdsLoader,
|
||||||
streamPlayer,
|
streamPlayer,
|
||||||
contentMediaSourceFactory,
|
contentMediaSourceFactory,
|
||||||
@ -185,6 +187,7 @@ public final class ImaServerSideAdInsertionMediaSource extends CompositeMediaSou
|
|||||||
@Nullable private ImaSdkSettings imaSdkSettings;
|
@Nullable private ImaSdkSettings imaSdkSettings;
|
||||||
@Nullable private AdEventListener adEventListener;
|
@Nullable private AdEventListener adEventListener;
|
||||||
@Nullable private AdErrorEvent.AdErrorListener adErrorListener;
|
@Nullable private AdErrorEvent.AdErrorListener adErrorListener;
|
||||||
|
private State state;
|
||||||
private ImmutableList<CompanionAdSlot> companionAdSlots;
|
private ImmutableList<CompanionAdSlot> companionAdSlots;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -197,6 +200,7 @@ public final class ImaServerSideAdInsertionMediaSource extends CompositeMediaSou
|
|||||||
this.context = context;
|
this.context = context;
|
||||||
this.adViewProvider = adViewProvider;
|
this.adViewProvider = adViewProvider;
|
||||||
companionAdSlots = ImmutableList.of();
|
companionAdSlots = ImmutableList.of();
|
||||||
|
state = new State(ImmutableMap.of());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -248,6 +252,19 @@ public final class ImaServerSideAdInsertionMediaSource extends CompositeMediaSou
|
|||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the optional state to resume with.
|
||||||
|
*
|
||||||
|
* <p>The state can be received when {@link #release() releasing} the {@link AdsLoader}.
|
||||||
|
*
|
||||||
|
* @param state The state to resume with.
|
||||||
|
* @return This builder, for convenience.
|
||||||
|
*/
|
||||||
|
public AdsLoader.Builder setAdsLoaderState(State state) {
|
||||||
|
this.state = state;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
/** Returns a new {@link AdsLoader}. */
|
/** Returns a new {@link AdsLoader}. */
|
||||||
public AdsLoader build() {
|
public AdsLoader build() {
|
||||||
@Nullable ImaSdkSettings imaSdkSettings = this.imaSdkSettings;
|
@Nullable ImaSdkSettings imaSdkSettings = this.imaSdkSettings;
|
||||||
@ -263,7 +280,17 @@ public final class ImaServerSideAdInsertionMediaSource extends CompositeMediaSou
|
|||||||
adErrorListener,
|
adErrorListener,
|
||||||
companionAdSlots,
|
companionAdSlots,
|
||||||
imaSdkSettings.isDebugMode());
|
imaSdkSettings.isDebugMode());
|
||||||
return new AdsLoader(context, configuration);
|
return new AdsLoader(context, configuration, state);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** The state of the {@link AdsLoader}. */
|
||||||
|
public static class State {
|
||||||
|
|
||||||
|
private final ImmutableMap<String, AdPlaybackState> adPlaybackStates;
|
||||||
|
|
||||||
|
private State(ImmutableMap<String, AdPlaybackState> adPlaybackStates) {
|
||||||
|
this.adPlaybackStates = adPlaybackStates;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -271,13 +298,19 @@ public final class ImaServerSideAdInsertionMediaSource extends CompositeMediaSou
|
|||||||
private final Context context;
|
private final Context context;
|
||||||
private final Map<ImaServerSideAdInsertionMediaSource, MediaSourceResourceHolder>
|
private final Map<ImaServerSideAdInsertionMediaSource, MediaSourceResourceHolder>
|
||||||
mediaSourceResources;
|
mediaSourceResources;
|
||||||
|
private final Map<String, AdPlaybackState> adPlaybackStateMap;
|
||||||
|
|
||||||
@Nullable private Player player;
|
@Nullable private Player player;
|
||||||
|
|
||||||
private AdsLoader(Context context, ImaUtil.ServerSideAdInsertionConfiguration configuration) {
|
private AdsLoader(
|
||||||
|
Context context, ImaUtil.ServerSideAdInsertionConfiguration configuration, State state) {
|
||||||
this.context = context.getApplicationContext();
|
this.context = context.getApplicationContext();
|
||||||
this.configuration = configuration;
|
this.configuration = configuration;
|
||||||
mediaSourceResources = new HashMap<>();
|
mediaSourceResources = new HashMap<>();
|
||||||
|
adPlaybackStateMap = new HashMap<>();
|
||||||
|
for (Map.Entry<String, AdPlaybackState> entry : state.adPlaybackStates.entrySet()) {
|
||||||
|
adPlaybackStateMap.put(entry.getKey(), entry.getValue());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -290,8 +323,12 @@ public final class ImaServerSideAdInsertionMediaSource extends CompositeMediaSou
|
|||||||
this.player = player;
|
this.player = player;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Releases resources when the ads loader is no longer needed. */
|
/**
|
||||||
public void release() {
|
* Releases resources.
|
||||||
|
*
|
||||||
|
* @return The {@link State} that can be used to resume with.
|
||||||
|
*/
|
||||||
|
public State release() {
|
||||||
for (MediaSourceResourceHolder resourceHolder : mediaSourceResources.values()) {
|
for (MediaSourceResourceHolder resourceHolder : mediaSourceResources.values()) {
|
||||||
resourceHolder.streamPlayer.release();
|
resourceHolder.streamPlayer.release();
|
||||||
resourceHolder.adsLoader.release();
|
resourceHolder.adsLoader.release();
|
||||||
@ -300,9 +337,12 @@ public final class ImaServerSideAdInsertionMediaSource extends CompositeMediaSou
|
|||||||
}
|
}
|
||||||
mediaSourceResources.clear();
|
mediaSourceResources.clear();
|
||||||
player = null;
|
player = null;
|
||||||
|
return new State(ImmutableMap.copyOf(adPlaybackStateMap));
|
||||||
}
|
}
|
||||||
|
|
||||||
/* package */ void addMediaSourceResources(
|
// Internal methods.
|
||||||
|
|
||||||
|
private void addMediaSourceResources(
|
||||||
ImaServerSideAdInsertionMediaSource mediaSource,
|
ImaServerSideAdInsertionMediaSource mediaSource,
|
||||||
StreamPlayer streamPlayer,
|
StreamPlayer streamPlayer,
|
||||||
com.google.ads.interactivemedia.v3.api.AdsLoader adsLoader) {
|
com.google.ads.interactivemedia.v3.api.AdsLoader adsLoader) {
|
||||||
@ -310,6 +350,15 @@ public final class ImaServerSideAdInsertionMediaSource extends CompositeMediaSou
|
|||||||
mediaSource, new MediaSourceResourceHolder(mediaSource, streamPlayer, adsLoader));
|
mediaSource, new MediaSourceResourceHolder(mediaSource, streamPlayer, adsLoader));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private AdPlaybackState getAdPlaybackState(String adsId) {
|
||||||
|
@Nullable AdPlaybackState adPlaybackState = adPlaybackStateMap.get(adsId);
|
||||||
|
return adPlaybackState != null ? adPlaybackState : AdPlaybackState.NONE;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void setAdPlaybackState(String adsId, AdPlaybackState adPlaybackState) {
|
||||||
|
this.adPlaybackStateMap.put(adsId, adPlaybackState);
|
||||||
|
}
|
||||||
|
|
||||||
private static final class MediaSourceResourceHolder {
|
private static final class MediaSourceResourceHolder {
|
||||||
public final ImaServerSideAdInsertionMediaSource imaServerSideAdInsertionMediaSource;
|
public final ImaServerSideAdInsertionMediaSource imaServerSideAdInsertionMediaSource;
|
||||||
public final StreamPlayer streamPlayer;
|
public final StreamPlayer streamPlayer;
|
||||||
@ -329,7 +378,8 @@ public final class ImaServerSideAdInsertionMediaSource extends CompositeMediaSou
|
|||||||
private final MediaItem mediaItem;
|
private final MediaItem mediaItem;
|
||||||
private final Player player;
|
private final Player player;
|
||||||
private final MediaSource.Factory contentMediaSourceFactory;
|
private final MediaSource.Factory contentMediaSourceFactory;
|
||||||
private final com.google.ads.interactivemedia.v3.api.AdsLoader adsLoader;
|
private final AdsLoader adsLoader;
|
||||||
|
private final com.google.ads.interactivemedia.v3.api.AdsLoader sdkAdsLoader;
|
||||||
@Nullable private final AdEventListener applicationAdEventListener;
|
@Nullable private final AdEventListener applicationAdEventListener;
|
||||||
@Nullable private final AdErrorListener applicationAdErrorListener;
|
@Nullable private final AdErrorListener applicationAdErrorListener;
|
||||||
private final boolean isLiveStream;
|
private final boolean isLiveStream;
|
||||||
@ -350,7 +400,8 @@ public final class ImaServerSideAdInsertionMediaSource extends CompositeMediaSou
|
|||||||
private ImaServerSideAdInsertionMediaSource(
|
private ImaServerSideAdInsertionMediaSource(
|
||||||
MediaItem mediaItem,
|
MediaItem mediaItem,
|
||||||
Player player,
|
Player player,
|
||||||
com.google.ads.interactivemedia.v3.api.AdsLoader adsLoader,
|
AdsLoader adsLoader,
|
||||||
|
com.google.ads.interactivemedia.v3.api.AdsLoader sdkAdsLoader,
|
||||||
StreamPlayer streamPlayer,
|
StreamPlayer streamPlayer,
|
||||||
MediaSource.Factory contentMediaSourceFactory,
|
MediaSource.Factory contentMediaSourceFactory,
|
||||||
@Nullable AdEventListener applicationAdEventListener,
|
@Nullable AdEventListener applicationAdEventListener,
|
||||||
@ -358,18 +409,19 @@ public final class ImaServerSideAdInsertionMediaSource extends CompositeMediaSou
|
|||||||
this.mediaItem = mediaItem;
|
this.mediaItem = mediaItem;
|
||||||
this.player = player;
|
this.player = player;
|
||||||
this.adsLoader = adsLoader;
|
this.adsLoader = adsLoader;
|
||||||
|
this.sdkAdsLoader = sdkAdsLoader;
|
||||||
this.streamPlayer = streamPlayer;
|
this.streamPlayer = streamPlayer;
|
||||||
this.contentMediaSourceFactory = contentMediaSourceFactory;
|
this.contentMediaSourceFactory = contentMediaSourceFactory;
|
||||||
this.applicationAdEventListener = applicationAdEventListener;
|
this.applicationAdEventListener = applicationAdEventListener;
|
||||||
this.applicationAdErrorListener = applicationAdErrorListener;
|
this.applicationAdErrorListener = applicationAdErrorListener;
|
||||||
componentListener = new ComponentListener();
|
componentListener = new ComponentListener();
|
||||||
adPlaybackState = AdPlaybackState.NONE;
|
|
||||||
mainHandler = Util.createHandlerForCurrentLooper();
|
mainHandler = Util.createHandlerForCurrentLooper();
|
||||||
Uri streamRequestUri = checkNotNull(mediaItem.localConfiguration).uri;
|
Uri streamRequestUri = checkNotNull(mediaItem.localConfiguration).uri;
|
||||||
isLiveStream = ImaServerSideAdInsertionUriBuilder.isLiveStream(streamRequestUri);
|
isLiveStream = ImaServerSideAdInsertionUriBuilder.isLiveStream(streamRequestUri);
|
||||||
adsId = ImaServerSideAdInsertionUriBuilder.getAdsId(streamRequestUri);
|
adsId = ImaServerSideAdInsertionUriBuilder.getAdsId(streamRequestUri);
|
||||||
loadVideoTimeoutMs = ImaServerSideAdInsertionUriBuilder.getLoadVideoTimeoutMs(streamRequestUri);
|
loadVideoTimeoutMs = ImaServerSideAdInsertionUriBuilder.getLoadVideoTimeoutMs(streamRequestUri);
|
||||||
streamRequest = ImaServerSideAdInsertionUriBuilder.createStreamRequest(streamRequestUri);
|
streamRequest = ImaServerSideAdInsertionUriBuilder.createStreamRequest(streamRequestUri);
|
||||||
|
adPlaybackState = adsLoader.getAdPlaybackState(adsId);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -386,7 +438,7 @@ public final class ImaServerSideAdInsertionMediaSource extends CompositeMediaSou
|
|||||||
player.addListener(componentListener);
|
player.addListener(componentListener);
|
||||||
StreamManagerLoadable streamManagerLoadable =
|
StreamManagerLoadable streamManagerLoadable =
|
||||||
new StreamManagerLoadable(
|
new StreamManagerLoadable(
|
||||||
adsLoader,
|
sdkAdsLoader,
|
||||||
streamRequest,
|
streamRequest,
|
||||||
streamPlayer,
|
streamPlayer,
|
||||||
applicationAdErrorListener,
|
applicationAdErrorListener,
|
||||||
@ -502,6 +554,10 @@ public final class ImaServerSideAdInsertionMediaSource extends CompositeMediaSou
|
|||||||
splitAdPlaybackStateForPeriods(adPlaybackState, contentTimeline);
|
splitAdPlaybackStateForPeriods(adPlaybackState, contentTimeline);
|
||||||
streamPlayer.setAdPlaybackStates(adsId, splitAdPlaybackStates, contentTimeline);
|
streamPlayer.setAdPlaybackStates(adsId, splitAdPlaybackStates, contentTimeline);
|
||||||
checkNotNull(serverSideAdInsertionMediaSource).setAdPlaybackStates(splitAdPlaybackStates);
|
checkNotNull(serverSideAdInsertionMediaSource).setAdPlaybackStates(splitAdPlaybackStates);
|
||||||
|
if (!ImaServerSideAdInsertionUriBuilder.isLiveStream(
|
||||||
|
checkNotNull(mediaItem.localConfiguration).uri)) {
|
||||||
|
adsLoader.setAdPlaybackState(adsId, adPlaybackState);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user