Erste Schritte mit der ExoPlayer IMA-Erweiterung

ExoPlayer ist ein Media-Player auf Anwendungsebene für Android. In dieser Anleitung erfahren Sie, wie Sie die ExoPlayer IMA-Erweiterung verwenden, die das IMA DAI SDK umschließt, um einen Media-Stream mit Anzeigen und Inhalten anzufordern und abzuspielen.

Hier sind einige der Vorteile der Erweiterung:

  • Vereinfacht den Code, der für die Integration von IMA mit Funktionen erforderlich ist.
  • Die Entwicklungszeit für die Aktualisierung auf neue IMA-Versionen wird verkürzt.

Die ExoPlayer IMA-Erweiterung unterstützt die HLS- und DASH-Streamingprotokolle. Hier eine Zusammenfassung:

ExoPlayer-IMA-Erweiterung: Unterstützung für Streams
Livestream VOD-Streams
HLS Häkchen Häkchen
DASH Häkchen Häkchen

DASH-Livestreams werden ab ExoPlayer-IMA-Version 1.1.0 unterstützt.

Diese Anleitung basiert auf der ExoPlayer-Anleitung und zeigt, wie Sie eine vollständige App erstellen und die Erweiterung einbinden. Ein Beispiel mit einer vollständigen Beispiel-App finden Sie auf GitHub unter ExoPlayerExample.

Vorbereitung

Ein neues Android Studio-Projekt erstellen

So erstellen Sie Ihr Android Studio-Projekt:

  • Starte Android Studio.
  • Wählen Sie Start a new Android Studio project aus.
  • Wählen Sie auf der Seite Choose your project (Projekt auswählen) die Vorlage No Activity (Keine Aktivität) aus.
  • Klicken Sie auf Weiter.
  • Geben Sie auf der Seite Projekt konfigurieren einen Namen für Ihr Projekt ein und wählen Sie Java als Sprache aus.

  • Klicken Sie auf Fertig.

ExoPlayer IMA-Erweiterung in Ihr Projekt einbinden

Fügen Sie der build.gradle-Datei auf Anwendungsebene im Abschnitt dependencies Importe für die Erweiterung hinzu.

Konfigurieren Sie Ihre App und aktivieren Sie Multidex. Dies ist aufgrund der Größe der Erweiterung erforderlich und gilt für Apps, bei denen minSdkVersion auf Android 4.4W (API-Level 20) oder niedriger festgelegt ist.

Beispiel:

app/build.gradle

android {

  ...

  defaultConfig {
      applicationId "com.google.ads.interactivemedia.v3.samples.videoplayerapp"
      minSdkVersion 21
      targetSdkVersion 34
      multiDexEnabled true
      versionCode 1
      versionName "1.0"
  }

    ...
}
dependencies {
    implementation 'androidx.multidex:multidex:2.0.1'
    implementation 'androidx.media3:media3-ui:1.7.1'
    implementation 'androidx.media3:media3-exoplayer:1.7.1'
    implementation 'androidx.media3:media3-exoplayer-hls:1.7.1'
    implementation 'androidx.media3:media3-exoplayer-dash:1.7.1'

    // Adding the ExoPlayer IMA extension for ads will also include the IMA
    // SDK as a dependency.
    implementation 'androidx.media3:media3-exoplayer-ima:1.7.1'
}

Fügen Sie die Nutzerberechtigungen hinzu, die für das IMA DAI SDK zum Anfordern von Anzeigen erforderlich sind:

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 DAI SDK -->
    <uses-permission android:name="android.permission.INTERNET"/>
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>

    ...

</manifest>

Absichtserklärungen hinzufügen

Wenn Ihre App auf Android 11 (API‑Level 30) oder höher ausgerichtet ist, ist für die aktuellen und letzten Versionen des IMA DAI SDK eine explizite Absichtserklärung zum Öffnen von Weblinks erforderlich. Fügen Sie der Manifestdatei Ihrer App das folgende Snippet hinzu, um Ad-Clickthroughs zu aktivieren (Nutzer klicken auf die Schaltfläche Weitere Informationen).

  <?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>

ExoPlayer-UI einrichten

Erstellen Sie das PlayerView-Objekt, das von ExoPlayer verwendet werden soll.

Ändern Sie androidx.constraintlayout.widget.ConstraintLayout in LinearLayout. Das wird für die ExoPlayer IMA-Erweiterung empfohlen.

Beispiel:

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>

Streamparameter hinzufügen

Auf der Seite IMA-Beispielstream finden Sie Beispielstream-Assets zum Testen Ihres Projekts. Weitere Informationen zum Einrichten eigener Streams finden Sie im Ad Manager-Abschnitt zu DAI.

In diesem Schritt wird gezeigt, wie Sie einen Livestream einrichten. Die ExoPlayer IMA-Erweiterung unterstützt aber auch DAI-VOD-Streams. Im Schritt für Video-on-Demand-Streams erfährst du, welche Änderungen in deiner App erforderlich sind, um VOD-Streams zu verarbeiten.

ExoPlayer IMA-Erweiterung importieren

Fügen Sie die Importanweisungen für die ExoPlayer-Erweiterung hinzu.

Fügen Sie MyActivity.java die folgenden privaten Variablen hinzu:

Fügen Sie den Asset-Schlüssel des HLS-Streams Big Buck Bunny (Live) hinzu, um diesen Stream zu testen. Auf der Beispielstreamseite von IMA sind weitere Streams zum Testen verfügbar.

Erstellen Sie eine KEY_ADS_LOADER_STATE-Konstante, um den AdsLoader-Status zu speichern und abzurufen.

Beispiel:

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;
import com.google.ads.interactivemedia.v3.api.ImaSdkFactory;
import com.google.ads.interactivemedia.v3.api.ImaSdkSettings;

...

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 ImaSdkSettings imaSdkSettings;
  private ImaServerSideAdInsertionMediaSource.AdsLoader adsLoader;
  private ImaServerSideAdInsertionMediaSource.AdsLoader.State adsLoaderState;

}

adsLoader-Instanz erstellen

Überschreiben Sie die onCreate-Methode, um die PlayerView zu finden und nach einem gespeicherten AdsLoader.State zu suchen, der beim Initialisieren des adsLoader-Objekts verwendet werden kann.

Aktivieren Sie außerdem multidex, falls die Anzahl der Methoden Ihrer App und minSdkVersion dies erfordern (wie in Schritt 2 erläutert).

Beispiel:

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 ImaSdkSettings imaSdkSettings;
  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);

    // Initialize the IMA SDK as early as possible when the app starts. If your app already
    // overrides Application.onCreate(), call this method inside the onCreate() method.
    // https://developer.android.com/topic/performance/vitals/launch-time#app-creation
    ImaSdkFactory.getInstance().initialize(this, getImaSdkSettings());

    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.fromBundle(
                adsLoaderStateBundle);
      }
    }
  }

  private ImaSdkSettings getImaSdkSettings() {
    if (imaSdkSettings == null) {
      imaSdkSettings = ImaSdkFactory.getInstance().createImaSdkSettings();
      // Set any IMA SDK settings here.
    }
    return imaSdkSettings;
  }

}

Methoden zum Initialisieren des Players hinzufügen

Fügen Sie eine Methode zum Initialisieren des Players hinzu und gehen Sie so vor:

  • Erstellen Sie eine AdsLoader-Instanz.
  • Erstellen Sie ExoPlayer.
  • Erstelle ein MediaItem mit dem Asset-Schlüssel des Livestreams.
  • Legen Sie MediaItem auf Ihren Player fest.

Beispiel:

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
        .setImaSdkSettings(getImaSdkSettings())
        .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);
  }
}

Methode zum Freigeben des Players hinzufügen

Fügen Sie eine Methode hinzu, um den Player in dieser Sequenz freizugeben:

  • Setzen Sie die Player-Referenzen auf „null“ und geben Sie die Ressourcen des Players frei.
  • Geben Sie den Status des adsLoader frei.

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();
  }

Spielerereignisse verarbeiten

Erstelle schließlich Callbacks für die Lifecycle-Ereignisse der Aktivität, um die Streamwiedergabe zu verarbeiten.

So unterstützen Sie Android SDK-Version 24 und höher:

So unterstützen Sie Android SDK-Versionen unter 24:

onStart() und onResume() werden playerView.onResume() zugeordnet, onStop() und onPause() werden playerView.onPause() zugeordnet.

In diesem Schritt wird auch das Ereignis onSaveInstanceState() verwendet, um zu versuchen, adsLoaderState zu speichern.

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());
    }
  }

  ...

}

VOD-Stream einrichten (optional)

Wenn in Ihrer App VOD-Inhalte mit Anzeigen abgespielt werden müssen, müssen Sie Folgendes tun:

  1. Fügen Sie einen CMS ID und einen Video ID für einen VOD-Teststream hinzu.
  2. Erstellen Sie mit ImaServerSideAdInsertionUriBuilder() einen SSAI-VOD-URI.
  3. Verwenden Sie diesen neuen URI als Media-Element für Ihren Player.

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 = "2548831";
  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);
  }

Geschafft! Sie fordern jetzt einen Media-Stream mit der ExoPlayer IMA-Erweiterung an und spielen ihn ab. Den vollständigen Code finden Sie in den Android-DAI-Beispielen auf GitHub.