diff --git a/demos/main/src/main/java/com/google/android/exoplayer2/demo/PlayerActivity.java b/demos/main/src/main/java/com/google/android/exoplayer2/demo/PlayerActivity.java index ffa9bafa4f..31d6d332dd 100644 --- a/demos/main/src/main/java/com/google/android/exoplayer2/demo/PlayerActivity.java +++ b/demos/main/src/main/java/com/google/android/exoplayer2/demo/PlayerActivity.java @@ -534,6 +534,9 @@ public class PlayerActivity extends Activity mediaSource = null; trackSelector = null; } + if (adsLoader != null) { + adsLoader.setPlayer(null); + } releaseMediaDrm(); } @@ -597,6 +600,7 @@ public class PlayerActivity extends Activity // The demo app has a non-null overlay frame layout. playerView.getOverlayFrameLayout().addView(adUiViewGroup); } + adsLoader.setPlayer(player); AdsMediaSource.MediaSourceFactory adMediaSourceFactory = new AdsMediaSource.MediaSourceFactory() { @Override diff --git a/extensions/ima/src/main/java/com/google/android/exoplayer2/ext/ima/ImaAdsLoader.java b/extensions/ima/src/main/java/com/google/android/exoplayer2/ext/ima/ImaAdsLoader.java index 9b4b66125c..985408cb70 100644 --- a/extensions/ima/src/main/java/com/google/android/exoplayer2/ext/ima/ImaAdsLoader.java +++ b/extensions/ima/src/main/java/com/google/android/exoplayer2/ext/ima/ImaAdsLoader.java @@ -46,7 +46,6 @@ import com.google.ads.interactivemedia.v3.api.player.VideoAdPlayer; import com.google.ads.interactivemedia.v3.api.player.VideoProgressUpdate; import com.google.android.exoplayer2.C; import com.google.android.exoplayer2.ExoPlaybackException; -import com.google.android.exoplayer2.ExoPlayer; import com.google.android.exoplayer2.ExoPlayerLibraryInfo; import com.google.android.exoplayer2.Player; import com.google.android.exoplayer2.Timeline; @@ -73,7 +72,13 @@ import java.util.List; import java.util.Map; import java.util.Set; -/** Loads ads using the IMA SDK. All methods are called on the main thread. */ +/** + * {@link AdsLoader} using the IMA SDK. All methods must be called on the main thread. + * + *
The player instance that will play the loaded ads must be set before playback using {@link
+ * #setPlayer(Player)}. If the ads loader is no longer required, it must be released by calling
+ * {@link #release()}.
+ */
public final class ImaAdsLoader
implements Player.EventListener,
AdsLoader,
@@ -92,9 +97,9 @@ public final class ImaAdsLoader
private final Context context;
- private @Nullable ImaSdkSettings imaSdkSettings;
- private @Nullable AdEventListener adEventListener;
- private @Nullable Set {@link #attachPlayer(ExoPlayer, EventListener, ViewGroup)} will be called when the ads media
- * source first initializes, at which point the loader can request ads. If the player enters the
- * background, {@link #detachPlayer()} will be called. Loaders should maintain any ad playback state
- * in preparation for a later call to {@link #attachPlayer(ExoPlayer, EventListener, ViewGroup)}. If
- * an ad is playing when the player is detached, update the ad playback state with the current
- * playback position using {@link AdPlaybackState#withAdResumePositionUs(long)}.
+ * {@link #start(EventListener, ViewGroup)} will be called when the ads media source first
+ * initializes, at which point the loader can request ads. If the player enters the background,
+ * {@link #stop()} will be called. Loaders should maintain any ad playback state in preparation for
+ * a later call to {@link #start(EventListener, ViewGroup)}. If an ad is playing when the player is
+ * detached, update the ad playback state with the current playback position using {@link
+ * AdPlaybackState#withAdResumePositionUs(long)}.
*
* If {@link EventListener#onAdPlaybackState(AdPlaybackState)} has been called, the
- * implementation of {@link #attachPlayer(ExoPlayer, EventListener, ViewGroup)} should invoke the
- * same listener to provide the existing playback state to the new player.
+ * implementation of {@link #start(EventListener, ViewGroup)} should invoke the same listener to
+ * provide the existing playback state to the new player.
*/
public interface AdsLoader {
@@ -75,9 +76,34 @@ public interface AdsLoader {
}
+ // Methods called by the application.
+
/**
- * Sets the supported content types for ad media. Must be called before the first call to
- * {@link #attachPlayer(ExoPlayer, EventListener, ViewGroup)}. Subsequent calls may be ignored.
+ * Sets the player that will play the loaded ads.
+ *
+ * This method must be called before the player is prepared with media using this ads loader.
+ *
+ * This method must also be called on the main thread and only players which are accessed on
+ * the main thread are supported ({@code player.getApplicationLooper() ==
+ * Looper.getMainLooper()}).
+ *
+ * @param player The player instance that will play the loaded ads. May be null to delete the
+ * reference to a previously set player.
+ */
+ void setPlayer(@Nullable Player player);
+
+ /**
+ * Releases the loader. Must be called by the application on the main thread when the instance is
+ * no longer needed.
+ */
+ void release();
+
+ // Methods called by AdsMediaSource.
+
+ /**
+ * Sets the supported content types for ad media. Must be called before the first call to {@link
+ * #start(EventListener, ViewGroup)}. Subsequent calls may be ignored. Called on the main thread
+ * by {@link AdsMediaSource}.
*
* @param contentTypes The supported content types for ad media. Each element must be one of
* {@link C#TYPE_DASH}, {@link C#TYPE_HLS}, {@link C#TYPE_SS} and {@link C#TYPE_OTHER}.
@@ -85,32 +111,23 @@ public interface AdsLoader {
void setSupportedContentTypes(@C.ContentType int... contentTypes);
/**
- * Attaches a player that will play ads loaded using this instance. Called on the main thread by
- * {@link AdsMediaSource}.
+ * Starts using the ads loader for playback. Called on the main thread by {@link AdsMediaSource}.
*
- * @param player The player instance that will play the loaded ads. Only players which are
- * accessed on the main thread are supported ({@code player.getApplicationLooper() ==
- * Looper.getMainLooper()}).
* @param eventListener Listener for ads loader events.
* @param adUiViewGroup A {@link ViewGroup} on top of the player that will show any ad UI.
*/
- void attachPlayer(ExoPlayer player, EventListener eventListener, ViewGroup adUiViewGroup);
+ void start(EventListener eventListener, ViewGroup adUiViewGroup);
/**
- * Detaches the attached player and event listener. Called on the main thread by
- * {@link AdsMediaSource}.
+ * Stops using the ads loader for playback and deregisters the event listener. Called on the main
+ * thread by {@link AdsMediaSource}.
*/
- void detachPlayer();
-
- /**
- * Releases the loader. Called by the application on the main thread when the instance is no
- * longer needed.
- */
- void release();
+ void stop();
/**
* Notifies the ads loader that the player was not able to prepare media for a given ad.
* Implementations should update the ad playback state as the specified ad has failed to load.
+ * Called on the main thread by {@link AdsMediaSource}.
*
* @param adGroupIndex The index of the ad group.
* @param adIndexInAdGroup The index of the ad in the ad group.
diff --git a/library/core/src/main/java/com/google/android/exoplayer2/source/ads/AdsMediaSource.java b/library/core/src/main/java/com/google/android/exoplayer2/source/ads/AdsMediaSource.java
index 4bf661ddc0..a8ae3938af 100644
--- a/library/core/src/main/java/com/google/android/exoplayer2/source/ads/AdsMediaSource.java
+++ b/library/core/src/main/java/com/google/android/exoplayer2/source/ads/AdsMediaSource.java
@@ -337,7 +337,7 @@ public final class AdsMediaSource extends CompositeMediaSource