ExoPlayer to odtwarzacz multimedialny aplikacji na Androida. Z tego przewodnika dowiesz się, jak używać rozszerzenia ExoPlayer IMA, które pakuje pakiet IMA Android DAI SDK, aby wysyłać żądania i odtwarzać strumień multimediów zarówno z reklamami, jak i treściami.
Oto kilka zalet tego rozszerzenia:
- Upraszcza kod wymagany do integracji IMA z funkcjami.
- Krótszy czas potrzebny na aktualizację do nowych wersji IMA.
Rozszerzenie ExoPlayer IMA obsługuje protokoły strumieniowania HLS i DASH. Oto podsumowanie:
Obsługa strumienia w rozszerzeniu ExoPlayer-IMA | ||
---|---|---|
Transmisja na żywo | Strumienie VOD | |
HLS | ||
DASH |
Transmisje na żywo DASH są obsługiwane w systemie ExoPlayer-IMA w wersji 1.1.0 lub nowszej.
Ten przewodnik powstał na podstawie przewodnika ExoPlayer i pokazuje, jak utworzyć pełną aplikację i zintegrować rozszerzenie. Kompletną przykładową aplikację znajdziesz w artykule ExoPlayerExample
na GitHubie.
Wymagania wstępne
- Android Studio,
- Urządzenie AndroidX Media3 ExoPlayer w wersji 1.0.0 lub nowszej na potrzeby obsługi DAI.
Utwórz nowy projekt Android Studio
Aby utworzyć projekt Android Studio, wykonaj te czynności:
- Uruchom Android Studio.
- Wybierz Rozpocznij nowy projekt Android Studio.
- Na stronie Wybierz projekt zaznacz szablon Brak aktywności.
- Kliknij Dalej.
Na stronie Skonfiguruj projekt nadaj projektowi nazwę i wybierz język Java.
Kliknij Zakończ.
Dodaj do projektu rozszerzenie ExoPlayer IMA
Dodaj importy rozszerzenia do pliku build.gradle na poziomie aplikacji w sekcji dependencies
.
Skonfiguruj swoją aplikację i włącz multidex. Jest to konieczne ze względu na rozmiar rozszerzenia i wymagane w przypadku aplikacji z minSdkVersion
ustawionym na Androida 4.4W (poziom interfejsu API 20) lub niższym.
Oto przykład:
app/build.gradle,
android { ... defaultConfig { applicationId "com.google.ads.interactivemedia.v3.samples.videoplayerapp" minSdkVersion 19 targetSdkVersion 34 multiDexEnabled true versionCode 1 versionName "1.0" } ... } dependencies { implementation 'androidx.multidex:multidex:2.0.1' implementation 'androidx.media3:media3-ui:1.1.1' implementation 'androidx.media3:media3-exoplayer:1.1.1' implementation 'androidx.media3:media3-exoplayer-hls:1.1.1' implementation 'androidx.media3:media3-exoplayer-dash:1.1.1' // Adding the ExoPlayer IMA extension for ads will also include the IMA // SDK as a dependency. implementation 'androidx.media3:media3-exoplayer-ima:1.1.1' }
Dodaj uprawnienia użytkownika wymagane przez pakiet IMA SDK w przypadku żądania reklam:
app/src/main/AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.example.project name"> <!-- Required permissions for the IMA SDK --> <uses-permission android:name="android.permission.INTERNET"/> <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/> ... </manifest>
Dodaj deklaracje intencji
Jeśli Twoja aplikacja jest kierowana na Androida 11 (poziom interfejsu API 30) lub nowszego, obecne i najnowsze wersje pakietu IMA SDK wymagają wyraźnej deklaracji zamiaru otwierania linków internetowych. Dodaj ten fragment do pliku manifestu aplikacji, by umożliwić klikanie reklam (użytkownicy klikający przycisk Więcej informacji).
<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.example.project name"> ... </application> <queries> <intent> <action android:name="android.intent.action.VIEW" /> <data android:scheme="https" /> </intent> <intent> <action android:name="android.intent.action.VIEW" /> <data android:scheme="http" /> </intent> </queries> </manifest>
Skonfiguruj interfejs ExoPlayer
Utwórz obiekt PlayerView
, który będzie używany przez ExoPlayer.
Zmień androidx.constraintlayout.widget.ConstraintLayout
na LinearLayout
, który jest zalecany w przypadku rozszerzenia ExoPlayer IMA.
Oto przykład:
app/src/main/res/layout/activity_my.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:background="@android:color/black" android:id="@+id/container" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" tools:context=".MyActivity" tools:ignore="MergeRootFrame"> <androidx.media3.ui.PlayerView android:id="@+id/player_view" android:layout_width="match_parent" android:layout_height="match_parent" /> </LinearLayout>
Dodaj parametry strumienia
Na stronie przykładowego strumienia IMA znajdziesz przykładowe zasoby strumienia przeznaczone do testowania projektu. Informacje o konfigurowaniu własnych strumieni znajdziesz w sekcji dotyczącej DAI w usłudze Ad Manager.
Ten krok pokazuje konfigurowanie transmisji na żywo, ale rozszerzenie ExoPlayer IMA obsługuje też strumienie VOD z DAI. Zapoznaj się z instrukcją dotyczącą strumieni wideo na żądanie (VOD), aby dowiedzieć się, jakie zmiany musisz wprowadzić w swojej aplikacji, aby móc obsługiwać strumienie VOD.
Importowanie rozszerzenia ExoPlayer IMA
Dodaj instrukcje importu dla rozszerzenia ExoPlayer.
Dodaj do MyActivity.java
te zmienne prywatne:
PlayerView
ExoPlayer
ImaServerSideAdInsertionMediaSource.AdsLoader
ImaServerSideAdInsertionMediaSource.AdsLoader.State
Dodaj klucz zasobu strumienia HLS Big Buck Bunny (Live), aby przetestować go w tej transmisji. Więcej strumieni możesz przetestować na stronie przykładowej transmisji IMA.
Aby zapisać i pobrać stan AdsLoader
, utwórz stałą KEY_ADS_LOADER_STATE
.
Oto przykład:
app/src/main/java/com/example/project name/MyActivity.java
import static androidx.media3.common.C.CONTENT_TYPE_HLS; import android.app.Activity; import android.net.Uri; import android.os.Bundle; import androidx.annotation.Nullable; import androidx.annotation.OptIn; import androidx.media3.common.MediaItem; import androidx.media3.common.util.Util; import androidx.media3.datasource.DataSource; import androidx.media3.datasource.DefaultDataSource; import androidx.media3.exoplayer.ExoPlayer; import androidx.media3.exoplayer.ima.ImaServerSideAdInsertionMediaSource; import androidx.media3.exoplayer.ima.ImaServerSideAdInsertionUriBuilder; import androidx.media3.exoplayer.source.DefaultMediaSourceFactory; import androidx.media3.exoplayer.util.EventLogger; import androidx.media3.ui.PlayerView; import androidx.multidex.MultiDex; ... public class MyActivity extends Activity { private static final String KEY_ADS_LOADER_STATE = "ads_loader_state"; private static final String SAMPLE_ASSET_KEY = "c-rArva4ShKVIAkNfy6HUQ"; private PlayerView playerView; private ExoPlayer player; private ImaServerSideAdInsertionMediaSource.AdsLoader adsLoader; private ImaServerSideAdInsertionMediaSource.AdsLoader.State adsLoaderState; }
Tworzenie instancji adsLoader
Zastąp metodę onCreate
, aby znaleźć PlayerView
i sprawdzić, czy jest zapisany obiekt AdsLoader.State
, którego można użyć podczas inicjowania obiektu adsLoader
.
Dodatkowo włącz multidex, jeśli jest to wymagane przez liczbę metod aplikacji i minSdkVersion
(jak wyjaśniono w kroku 2).
Oto przykład:
app/src/main/java/com/example/project name/MyActivity.java
... public class MyActivity extends Activity { private static final String KEY_ADS_LOADER_STATE = "ads_loader_state"; private static final String SAMPLE_ASSET_KEY = "c-rArva4ShKVIAkNfy6HUQ"; private PlayerView playerView; private ExoPlayer player; private ImaServerSideAdInsertionMediaSource.AdsLoader adsLoader; private ImaServerSideAdInsertionMediaSource.AdsLoader.State adsLoaderState; @Override protected void onCreate(@Nullable Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_my); MultiDex.install(this); playerView = findViewById(R.id.player_view); // Checks if there is a saved AdsLoader state to be used later when // initiating the AdsLoader. if (savedInstanceState != null) { Bundle adsLoaderStateBundle = savedInstanceState.getBundle(KEY_ADS_LOADER_STATE); if (adsLoaderStateBundle != null) { adsLoaderState = ImaServerSideAdInsertionMediaSource.AdsLoader.State.CREATOR.fromBundle( adsLoaderStateBundle); } } } }
Dodaj metody zainicjowania odtwarzacza
Dodaj metodę zainicjowania odtwarzacza i wykonaj te czynności:
- Utwórz instancję
AdsLoader
. - Utwórz
ExoPlayer
. - Utwórz plik
MediaItem
za pomocą klucza pliku transmisji na żywo. - Ustaw
MediaItem
dla odtwarzacza.
Oto przykład:
app/src/main/java/com/example/project name/MyActivity.java
public class MyActivity extends Activity { ... // Create a server side ad insertion (SSAI) AdsLoader. private ImaServerSideAdInsertionMediaSource.AdsLoader createAdsLoader() { ImaServerSideAdInsertionMediaSource.AdsLoader.Builder adsLoaderBuilder = new ImaServerSideAdInsertionMediaSource.AdsLoader.Builder(this, playerView); // Attempt to set the AdsLoader state if available from a previous session. if (adsLoaderState != null) { adsLoaderBuilder.setAdsLoaderState(adsLoaderState); } return adsLoaderBuilder.build(); } private void initializePlayer() { adsLoader = createAdsLoader(); // Set up the factory for media sources, passing the ads loader. DataSource.Factory dataSourceFactory = new DefaultDataSource.Factory(this); DefaultMediaSourceFactory mediaSourceFactory = new DefaultMediaSourceFactory(dataSourceFactory); // MediaSource.Factory to create the ad sources for the current player. ImaServerSideAdInsertionMediaSource.Factory adsMediaSourceFactory = new ImaServerSideAdInsertionMediaSource.Factory(adsLoader, mediaSourceFactory); // 'mediaSourceFactory' is an ExoPlayer component for the DefaultMediaSourceFactory. // 'adsMediaSourceFactory' is an ExoPlayer component for a MediaSource factory for IMA server // side inserted ad streams. mediaSourceFactory.setServerSideAdInsertionMediaSourceFactory(adsMediaSourceFactory); // Create an ExoPlayer and set it as the player for content and ads. player = new ExoPlayer.Builder(this).setMediaSourceFactory(mediaSourceFactory).build(); playerView.setPlayer(player); adsLoader.setPlayer(player); // Build an IMA SSAI media item to prepare the player with. Uri ssaiLiveUri = new ImaServerSideAdInsertionUriBuilder() .setAssetKey(SAMPLE_ASSET_KEY) .setFormat(CONTENT_TYPE_HLS) // Use CONTENT_TYPE_DASH for dash streams. .build(); // Create the MediaItem to play, specifying the stream URI. MediaItem ssaiMediaItem = MediaItem.fromUri(ssaiLiveUri); // Prepare the content and ad to be played with the ExoPlayer. player.setMediaItem(ssaiMediaItem); player.prepare(); // Set PlayWhenReady. If true, content and ads will autoplay. player.setPlayWhenReady(false); } }
Dodaj metodę zwalniania odtwarzacza
Dodaj metodę, aby zwolnić odtwarzacz, w następującej kolejności:
- Ustaw odniesienia odtwarzacza na null i zwolnij jego zasoby.
- Zwolnij stan:
adsLoader
.
app/src/main/java/com/example/project name/MyActivity.java
public class MyActivity extends Activity { ... private void releasePlayer() { // Set the player references to null and release the player's resources. playerView.setPlayer(null); player.release(); player = null; // Release the adsLoader state so that it can be initiated again. adsLoaderState = adsLoader.release(); }
Obsługa zdarzeń odtwarzacza
Na koniec utwórz wywołania zwrotne dla zdarzeń cyklu życia aktywności, aby obsługiwać odtwarzanie strumienia.
Aby obsługiwać pakiet SDK do Androida w wersji 24 lub nowszej:
Aby obsługiwać pakiet SDK na Androida w wersji starszej niż 24:
– onResume()
– onPause()
Mapa onStart()
i onResume()
są mapowane na playerView.onResume()
, a onStop()
i onPause()
na playerView.onPause()
.
Ten krok używa też zdarzenia onSaveInstanceState()
do próby zapisania adsLoaderState
.
app/src/main/java/com/example/project name/MyActivity.java
public class MyActivity extends Activity { ... @Override public void onStart() { super.onStart(); if (Util.SDK_INT > 23) { initializePlayer(); if (playerView != null) { playerView.onResume(); } } } @Override public void onResume() { super.onResume(); if (Util.SDK_INT <= 23 || player == null) { initializePlayer(); if (playerView != null) { playerView.onResume(); } } } @Override public void onPause() { super.onPause(); if (Util.SDK_INT <= 23) { if (playerView != null) { playerView.onPause(); } releasePlayer(); } } @Override public void onStop() { super.onStop(); if (Util.SDK_INT > 23) { if (playerView != null) { playerView.onPause(); } releasePlayer(); } } @Override public void onSaveInstanceState(Bundle outState) { // Attempts to save the AdsLoader state to handle app backgrounding. if (adsLoaderState != null) { outState.putBundle(KEY_ADS_LOADER_STATE, adsLoaderState.toBundle()); } } ... }
Konfiguracja strumienia VOD (opcjonalnie)
Jeśli Twoja aplikacja musi odtwarzać treści VOD z reklamami, wykonaj te czynności:
- Dodaj
CMS ID
iVideo ID
do testowej transmisji VOD. - Utwórz identyfikator URI usługi SSAI VOD za pomocą polecenia
ImaServerSideAdInsertionUriBuilder()
. - Użyj tego nowego identyfikatora URI jako elementu multimedialnego odtwarzacza.
app/src/main/java/com/example/project name/MyActivity.java
public class MyActivity extends Activity { private static final String KEY_ADS_LOADER_STATE = "ads_loader_state"; private static final String SAMPLE_ASSET_KEY = "c-rArva4ShKVIAkNfy6HUQ"; private static final String SAMPLE_CMS_ID = "2528370"; private static final String SAMPLE_VIDEO_ID = "tears-of-steel"; ... private void initializePlayer() { ... Uri ssaiVodUri = new ImaServerSideAdInsertionUriBuilder() .setContentSourceId(SAMPLE_CMS_ID) .setVideoId(SAMPLE_VIDEO_ID) .setFormat(CONTENT_TYPE_HLS) .build(); // Create the MediaItem to play, specifying the stream URI. MediaItem ssaiMediaItem = MediaItem.fromUri(ssaiVodUri); // Prepare the content and ad to be played with the ExoPlayer. player.setMediaItem(ssaiMediaItem); player.prepare(); // Set PlayWhenReady. If true, content and ads will autoplay. player.setPlayWhenReady(false); }
Znakomicie. Żądasz strumienia multimediów i odtwarzasz go za pomocą rozszerzenia ExoPlayer. Pełny kod znajdziesz na przykładach funkcji DAI na Androidzie na GitHubie.