Promote IMA DAI API to stable
PiperOrigin-RevId: 626064956
This commit is contained in:
parent
300e83414d
commit
09f2cda43c
@ -29,6 +29,9 @@
|
||||
* Effect:
|
||||
* Muxers:
|
||||
* IMA extension:
|
||||
* Promote API that is required for apps to play
|
||||
[DAI ad streams](https://developers.google.com/ad-manager/dynamic-ad-insertion/full-service)
|
||||
to stable.
|
||||
* Session:
|
||||
* Hide seekbar in the media notification for live streams by not setting
|
||||
the duration into the platform session metadata
|
||||
|
24
api.txt
24
api.txt
@ -1388,6 +1388,29 @@ package androidx.media3.exoplayer.ima {
|
||||
method public androidx.media3.exoplayer.ima.ImaAdsLoader build();
|
||||
}
|
||||
|
||||
public final class ImaServerSideAdInsertionMediaSource implements androidx.media3.exoplayer.source.MediaSource {
|
||||
}
|
||||
|
||||
public static final class ImaServerSideAdInsertionMediaSource.AdsLoader {
|
||||
method public androidx.media3.exoplayer.ima.ImaServerSideAdInsertionMediaSource.AdsLoader.State release();
|
||||
method public void setPlayer(androidx.media3.common.Player);
|
||||
}
|
||||
|
||||
public static final class ImaServerSideAdInsertionMediaSource.AdsLoader.Builder {
|
||||
ctor public ImaServerSideAdInsertionMediaSource.AdsLoader.Builder(android.content.Context, androidx.media3.common.AdViewProvider);
|
||||
method public androidx.media3.exoplayer.ima.ImaServerSideAdInsertionMediaSource.AdsLoader build();
|
||||
method public androidx.media3.exoplayer.ima.ImaServerSideAdInsertionMediaSource.AdsLoader.Builder setAdsLoaderState(androidx.media3.exoplayer.ima.ImaServerSideAdInsertionMediaSource.AdsLoader.State);
|
||||
}
|
||||
|
||||
public static class ImaServerSideAdInsertionMediaSource.AdsLoader.State {
|
||||
method public static androidx.media3.exoplayer.ima.ImaServerSideAdInsertionMediaSource.AdsLoader.State fromBundle(android.os.Bundle);
|
||||
method public android.os.Bundle toBundle();
|
||||
}
|
||||
|
||||
public static final class ImaServerSideAdInsertionMediaSource.Factory implements androidx.media3.exoplayer.source.MediaSource.Factory {
|
||||
ctor public ImaServerSideAdInsertionMediaSource.Factory(androidx.media3.exoplayer.ima.ImaServerSideAdInsertionMediaSource.AdsLoader, androidx.media3.exoplayer.source.MediaSource.Factory);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
package androidx.media3.exoplayer.source {
|
||||
@ -1397,6 +1420,7 @@ package androidx.media3.exoplayer.source {
|
||||
method public androidx.media3.exoplayer.source.DefaultMediaSourceFactory clearLocalAdInsertionComponents();
|
||||
method public androidx.media3.exoplayer.source.DefaultMediaSourceFactory setDataSourceFactory(androidx.media3.datasource.DataSource.Factory);
|
||||
method public androidx.media3.exoplayer.source.DefaultMediaSourceFactory setLocalAdInsertionComponents(androidx.media3.exoplayer.source.ads.AdsLoader.Provider, androidx.media3.common.AdViewProvider);
|
||||
method public androidx.media3.exoplayer.source.DefaultMediaSourceFactory setServerSideAdInsertionMediaSourceFactory(@Nullable androidx.media3.exoplayer.source.MediaSource.Factory);
|
||||
}
|
||||
|
||||
public interface MediaSource {
|
||||
|
@ -93,11 +93,8 @@ public class PlayerActivity extends AppCompatActivity
|
||||
|
||||
@Nullable private AdsLoader clientSideAdsLoader;
|
||||
|
||||
@OptIn(markerClass = UnstableApi.class)
|
||||
@Nullable
|
||||
private ImaServerSideAdInsertionMediaSource.AdsLoader serverSideAdsLoader;
|
||||
@Nullable private ImaServerSideAdInsertionMediaSource.AdsLoader serverSideAdsLoader;
|
||||
|
||||
@OptIn(markerClass = UnstableApi.class)
|
||||
private ImaServerSideAdInsertionMediaSource.AdsLoader.@MonotonicNonNull State
|
||||
serverSideAdsLoaderState;
|
||||
|
||||
@ -301,7 +298,7 @@ public class PlayerActivity extends AppCompatActivity
|
||||
return true;
|
||||
}
|
||||
|
||||
@OptIn(markerClass = UnstableApi.class) // SSAI configuration
|
||||
@OptIn(markerClass = UnstableApi.class) // DRM configuration
|
||||
private MediaSource.Factory createMediaSourceFactory() {
|
||||
DefaultDrmSessionManagerProvider drmSessionManagerProvider =
|
||||
new DefaultDrmSessionManagerProvider();
|
||||
@ -334,7 +331,6 @@ public class PlayerActivity extends AppCompatActivity
|
||||
playerBuilder.setRenderersFactory(renderersFactory);
|
||||
}
|
||||
|
||||
@OptIn(markerClass = UnstableApi.class)
|
||||
private void configurePlayerWithServerSideAdsLoader() {
|
||||
serverSideAdsLoader.setPlayer(player);
|
||||
}
|
||||
@ -403,7 +399,6 @@ public class PlayerActivity extends AppCompatActivity
|
||||
}
|
||||
}
|
||||
|
||||
@OptIn(markerClass = UnstableApi.class)
|
||||
private void releaseServerSideAdsLoader() {
|
||||
serverSideAdsLoaderState = serverSideAdsLoader.release();
|
||||
serverSideAdsLoader = null;
|
||||
@ -417,14 +412,12 @@ public class PlayerActivity extends AppCompatActivity
|
||||
}
|
||||
}
|
||||
|
||||
@OptIn(markerClass = UnstableApi.class)
|
||||
private void saveServerSideAdsLoaderState(Bundle outState) {
|
||||
if (serverSideAdsLoaderState != null) {
|
||||
outState.putBundle(KEY_SERVER_SIDE_ADS_LOADER_STATE, serverSideAdsLoaderState.toBundle());
|
||||
}
|
||||
}
|
||||
|
||||
@OptIn(markerClass = UnstableApi.class)
|
||||
private void restoreServerSideAdsLoaderState(Bundle savedInstanceState) {
|
||||
Bundle adsLoaderStateBundle = savedInstanceState.getBundle(KEY_SERVER_SIDE_ADS_LOADER_STATE);
|
||||
if (adsLoaderStateBundle != null) {
|
||||
@ -513,7 +506,7 @@ public class PlayerActivity extends AppCompatActivity
|
||||
|
||||
private class PlayerErrorMessageProvider implements ErrorMessageProvider<PlaybackException> {
|
||||
|
||||
@OptIn(markerClass = androidx.media3.common.util.UnstableApi.class)
|
||||
@OptIn(markerClass = UnstableApi.class) // Using decoder exceptions
|
||||
@Override
|
||||
public Pair<Integer, String> getErrorMessage(PlaybackException e) {
|
||||
String errorString = getString(R.string.error_generic);
|
||||
@ -554,7 +547,7 @@ public class PlayerActivity extends AppCompatActivity
|
||||
return mediaItems;
|
||||
}
|
||||
|
||||
@OptIn(markerClass = androidx.media3.common.util.UnstableApi.class)
|
||||
@OptIn(markerClass = UnstableApi.class) // Using Download API
|
||||
private static MediaItem maybeSetDownloadProperties(
|
||||
MediaItem item, @Nullable DownloadRequest downloadRequest) {
|
||||
if (downloadRequest == null) {
|
||||
|
@ -202,6 +202,7 @@ public abstract class BaseMediaSource implements MediaSource {
|
||||
return !mediaSourceCallers.isEmpty();
|
||||
}
|
||||
|
||||
@UnstableApi
|
||||
@Override
|
||||
public final void addEventListener(Handler handler, MediaSourceEventListener eventListener) {
|
||||
Assertions.checkNotNull(handler);
|
||||
@ -209,11 +210,13 @@ public abstract class BaseMediaSource implements MediaSource {
|
||||
eventDispatcher.addEventListener(handler, eventListener);
|
||||
}
|
||||
|
||||
@UnstableApi
|
||||
@Override
|
||||
public final void removeEventListener(MediaSourceEventListener eventListener) {
|
||||
eventDispatcher.removeEventListener(eventListener);
|
||||
}
|
||||
|
||||
@UnstableApi
|
||||
@Override
|
||||
public final void addDrmEventListener(Handler handler, DrmSessionEventListener eventListener) {
|
||||
Assertions.checkNotNull(handler);
|
||||
@ -221,11 +224,13 @@ public abstract class BaseMediaSource implements MediaSource {
|
||||
drmEventDispatcher.addEventListener(handler, eventListener);
|
||||
}
|
||||
|
||||
@UnstableApi
|
||||
@Override
|
||||
public final void removeDrmEventListener(DrmSessionEventListener eventListener) {
|
||||
drmEventDispatcher.removeEventListener(eventListener);
|
||||
}
|
||||
|
||||
@UnstableApi
|
||||
@SuppressWarnings("deprecation") // Overriding deprecated method to make it final.
|
||||
@Override
|
||||
public final void prepareSource(
|
||||
@ -233,6 +238,7 @@ public abstract class BaseMediaSource implements MediaSource {
|
||||
prepareSource(caller, mediaTransferListener, PlayerId.UNSET);
|
||||
}
|
||||
|
||||
@UnstableApi
|
||||
@Override
|
||||
public final void prepareSource(
|
||||
MediaSourceCaller caller,
|
||||
@ -253,6 +259,7 @@ public abstract class BaseMediaSource implements MediaSource {
|
||||
}
|
||||
}
|
||||
|
||||
@UnstableApi
|
||||
@Override
|
||||
public final void enable(MediaSourceCaller caller) {
|
||||
Assertions.checkNotNull(looper);
|
||||
@ -263,6 +270,7 @@ public abstract class BaseMediaSource implements MediaSource {
|
||||
}
|
||||
}
|
||||
|
||||
@UnstableApi
|
||||
@Override
|
||||
public final void disable(MediaSourceCaller caller) {
|
||||
boolean wasEnabled = !enabledMediaSourceCallers.isEmpty();
|
||||
@ -272,6 +280,7 @@ public abstract class BaseMediaSource implements MediaSource {
|
||||
}
|
||||
}
|
||||
|
||||
@UnstableApi
|
||||
@Override
|
||||
public final void releaseSource(MediaSourceCaller caller) {
|
||||
mediaSourceCallers.remove(caller);
|
||||
|
@ -313,7 +313,6 @@ public final class DefaultMediaSourceFactory implements MediaSourceFactory {
|
||||
* @return This factory, for convenience.
|
||||
*/
|
||||
@CanIgnoreReturnValue
|
||||
@UnstableApi
|
||||
public DefaultMediaSourceFactory setServerSideAdInsertionMediaSourceFactory(
|
||||
@Nullable MediaSource.Factory serverSideAdInsertionMediaSourceFactory) {
|
||||
this.serverSideAdInsertionMediaSourceFactory = serverSideAdInsertionMediaSourceFactory;
|
||||
|
@ -112,10 +112,10 @@ import java.util.Map;
|
||||
import java.util.Objects;
|
||||
|
||||
/** MediaSource for IMA server side inserted ad streams. */
|
||||
@UnstableApi
|
||||
public final class ImaServerSideAdInsertionMediaSource extends CompositeMediaSource<Void> {
|
||||
|
||||
/** A listener to be notified of stream events. */
|
||||
@UnstableApi
|
||||
public interface StreamEventListener {
|
||||
|
||||
/**
|
||||
@ -154,6 +154,7 @@ public final class ImaServerSideAdInsertionMediaSource extends CompositeMediaSou
|
||||
this.contentMediaSourceFactory = contentMediaSourceFactory;
|
||||
}
|
||||
|
||||
@UnstableApi
|
||||
@CanIgnoreReturnValue
|
||||
@Override
|
||||
public MediaSource.Factory setLoadErrorHandlingPolicy(
|
||||
@ -162,6 +163,7 @@ public final class ImaServerSideAdInsertionMediaSource extends CompositeMediaSou
|
||||
return this;
|
||||
}
|
||||
|
||||
@UnstableApi
|
||||
@CanIgnoreReturnValue
|
||||
@Override
|
||||
public MediaSource.Factory setDrmSessionManagerProvider(
|
||||
@ -170,11 +172,13 @@ public final class ImaServerSideAdInsertionMediaSource extends CompositeMediaSou
|
||||
return this;
|
||||
}
|
||||
|
||||
@UnstableApi
|
||||
@Override
|
||||
public @C.ContentType int[] getSupportedTypes() {
|
||||
return contentMediaSourceFactory.getSupportedTypes();
|
||||
}
|
||||
|
||||
@UnstableApi
|
||||
@Override
|
||||
public MediaSource createMediaSource(MediaItem mediaItem) {
|
||||
checkNotNull(mediaItem.localConfiguration);
|
||||
@ -248,6 +252,7 @@ public final class ImaServerSideAdInsertionMediaSource extends CompositeMediaSou
|
||||
* @param imaSdkSettings The {@link ImaSdkSettings}.
|
||||
* @return This builder, for convenience.
|
||||
*/
|
||||
@UnstableApi
|
||||
@CanIgnoreReturnValue
|
||||
public AdsLoader.Builder setImaSdkSettings(ImaSdkSettings imaSdkSettings) {
|
||||
this.imaSdkSettings = imaSdkSettings;
|
||||
@ -260,6 +265,7 @@ public final class ImaServerSideAdInsertionMediaSource extends CompositeMediaSou
|
||||
* @param streamEventListener The stream event listener.
|
||||
* @return This builder, for convenience.
|
||||
*/
|
||||
@UnstableApi
|
||||
@CanIgnoreReturnValue
|
||||
public AdsLoader.Builder setStreamEventListener(StreamEventListener streamEventListener) {
|
||||
this.streamEventListener = streamEventListener;
|
||||
@ -271,9 +277,14 @@ public final class ImaServerSideAdInsertionMediaSource extends CompositeMediaSou
|
||||
* StreamManager#addAdEventListener(AdEventListener)} when the stream manager becomes
|
||||
* available.
|
||||
*
|
||||
* <p>Note: This method can be considered a stable API as long as the {@link AdEventListener}
|
||||
* is provided by the IMA library. We can't declare this method stable because we don't have
|
||||
* the same guarantee from the library we depend on.
|
||||
*
|
||||
* @param adEventListener The ad event listener.
|
||||
* @return This builder, for convenience.
|
||||
*/
|
||||
@UnstableApi
|
||||
@CanIgnoreReturnValue
|
||||
public AdsLoader.Builder setAdEventListener(AdEventListener adEventListener) {
|
||||
this.adEventListener = adEventListener;
|
||||
@ -285,9 +296,14 @@ public final class ImaServerSideAdInsertionMediaSource extends CompositeMediaSou
|
||||
* StreamManager#addAdErrorListener(AdErrorEvent.AdErrorListener)} when the stream manager
|
||||
* becomes available.
|
||||
*
|
||||
* <p>Note: This method can be considered a stable API as long as the {@link
|
||||
* AdErrorEvent.AdErrorListener} is provided by the IMA library. We can't declare this method
|
||||
* stable because we don't have the same guarantee from the library we depend on.
|
||||
*
|
||||
* @param adErrorListener The {@link AdErrorEvent.AdErrorListener}.
|
||||
* @return This builder, for convenience.
|
||||
*/
|
||||
@UnstableApi
|
||||
@CanIgnoreReturnValue
|
||||
public AdsLoader.Builder setAdErrorListener(AdErrorEvent.AdErrorListener adErrorListener) {
|
||||
this.adErrorListener = adErrorListener;
|
||||
@ -301,6 +317,7 @@ public final class ImaServerSideAdInsertionMediaSource extends CompositeMediaSou
|
||||
* @return This builder, for convenience.
|
||||
* @see AdDisplayContainer#setCompanionSlots(Collection)
|
||||
*/
|
||||
@UnstableApi
|
||||
@CanIgnoreReturnValue
|
||||
public AdsLoader.Builder setCompanionAdSlots(Collection<CompanionAdSlot> companionAdSlots) {
|
||||
this.companionAdSlots = ImmutableList.copyOf(companionAdSlots);
|
||||
@ -330,6 +347,7 @@ public final class ImaServerSideAdInsertionMediaSource extends CompositeMediaSou
|
||||
* @return This builder, for convenience.
|
||||
* @see AdsRenderingSettings#setFocusSkipButtonWhenAvailable(boolean)
|
||||
*/
|
||||
@UnstableApi
|
||||
@CanIgnoreReturnValue
|
||||
public AdsLoader.Builder setFocusSkipButtonWhenAvailable(
|
||||
boolean focusSkipButtonWhenAvailable) {
|
||||
@ -405,6 +423,7 @@ public final class ImaServerSideAdInsertionMediaSource extends CompositeMediaSou
|
||||
*
|
||||
* @deprecated Use {@link #fromBundle} instead.
|
||||
*/
|
||||
@UnstableApi
|
||||
@Deprecated
|
||||
@SuppressWarnings("deprecation") // Deprecated instance of deprecated class
|
||||
public static final Bundleable.Creator<State> CREATOR = State::fromBundle;
|
||||
@ -458,6 +477,7 @@ public final class ImaServerSideAdInsertionMediaSource extends CompositeMediaSou
|
||||
*
|
||||
* @see StreamManager#focus()
|
||||
*/
|
||||
@UnstableApi
|
||||
public void focusSkipButton() {
|
||||
if (player == null) {
|
||||
return;
|
||||
@ -600,11 +620,13 @@ public final class ImaServerSideAdInsertionMediaSource extends CompositeMediaSou
|
||||
adPlaybackState = adsLoader.getAdPlaybackState(adsId);
|
||||
}
|
||||
|
||||
@UnstableApi
|
||||
@Override
|
||||
public synchronized MediaItem getMediaItem() {
|
||||
return mediaItem;
|
||||
}
|
||||
|
||||
@UnstableApi
|
||||
@Override
|
||||
public boolean canUpdateMediaItem(MediaItem mediaItem) {
|
||||
MediaItem existingMediaItem = getMediaItem();
|
||||
@ -619,11 +641,13 @@ public final class ImaServerSideAdInsertionMediaSource extends CompositeMediaSou
|
||||
&& existingMediaItem.liveConfiguration.equals(mediaItem.liveConfiguration);
|
||||
}
|
||||
|
||||
@UnstableApi
|
||||
@Override
|
||||
public synchronized void updateMediaItem(MediaItem mediaItem) {
|
||||
this.mediaItem = mediaItem;
|
||||
}
|
||||
|
||||
@UnstableApi
|
||||
@Override
|
||||
public void prepareSourceInternal(@Nullable TransferListener mediaTransferListener) {
|
||||
mainHandler.post(() -> assertSingleInstanceInPlaylist(checkNotNull(player)));
|
||||
@ -646,6 +670,7 @@ public final class ImaServerSideAdInsertionMediaSource extends CompositeMediaSou
|
||||
}
|
||||
}
|
||||
|
||||
@UnstableApi
|
||||
@Override
|
||||
protected void onChildSourceInfoRefreshed(
|
||||
Void childSourceId, MediaSource mediaSource, Timeline newTimeline) {
|
||||
@ -662,17 +687,20 @@ public final class ImaServerSideAdInsertionMediaSource extends CompositeMediaSou
|
||||
});
|
||||
}
|
||||
|
||||
@UnstableApi
|
||||
@Override
|
||||
public MediaPeriod createPeriod(MediaPeriodId id, Allocator allocator, long startPositionUs) {
|
||||
return checkNotNull(serverSideAdInsertionMediaSource)
|
||||
.createPeriod(id, allocator, startPositionUs);
|
||||
}
|
||||
|
||||
@UnstableApi
|
||||
@Override
|
||||
public void releasePeriod(MediaPeriod mediaPeriod) {
|
||||
checkNotNull(serverSideAdInsertionMediaSource).releasePeriod(mediaPeriod);
|
||||
}
|
||||
|
||||
@UnstableApi
|
||||
@Override
|
||||
public void maybeThrowSourceInfoRefreshError() throws IOException {
|
||||
super.maybeThrowSourceInfoRefreshError();
|
||||
@ -683,6 +711,7 @@ public final class ImaServerSideAdInsertionMediaSource extends CompositeMediaSou
|
||||
}
|
||||
}
|
||||
|
||||
@UnstableApi
|
||||
@Override
|
||||
protected void releaseSourceInternal() {
|
||||
super.releaseSourceInternal();
|
||||
|
Loading…
x
Reference in New Issue
Block a user