Erste Schritte mit der ExoPlayer IMA-Erweiterung

ExoPlayer ist ein Mediaplayer auf Anwendungsebene für Android. In dieser Anleitung wird gezeigt, wie du mit der IMA-Erweiterung von ExoPlayer, die das IMA DAI SDK umschließt, einen Medienstream mit Anzeigen und Inhalten anfordern und wiedergeben kannst.

Hier sind einige Vorteile der Erweiterung:

  • Er vereinfacht den Code, der zum Einbinden von IMA in Funktionen erforderlich ist.
  • Reduziert die Entwicklungszeit für das Upgrade auf neue IMA-Versionen.

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

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

DASH-Livestreams werden von der ExoPlayer-IMA-Version 1.1.0 und höher unterstützt.

Dieser Leitfaden basiert auf dem ExoPlayer-Leitfaden und zeigt, wie du eine vollständige App erstellst und die Erweiterung einbindest. In der ExoPlayerExample auf GitHub finden Sie ein Beispiel mit einer vollständigen Beispiel-App.

Vorbereitung

Ein neues Android Studio-Projekt erstellen

So erstellen Sie ein Android Studio-Projekt:

  • Starte Android Studio.
  • Wählen Sie Start a new Android Studio project (Neues Android Studio-Projekt starten) aus.
  • Wählen Sie auf der Seite Projekt auswählen die Vorlage Keine Aktivität aus.
  • Klicken Sie auf Weiter.
  • Geben Sie auf der Seite Projekt konfigurieren einen Namen für das Projekt ein und wählen Sie „Java“ als Sprache aus.

  • Klicken Sie auf Fertig.

ExoPlayer IMA-Erweiterung zum Projekt hinzufügen

Fügen Sie der Datei build.gradle 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, für die 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.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'
}

Fügen Sie die Nutzerberechtigungen hinzu, die vom IMA DAI SDK für das 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>

Intent-Erklärungen hinzufügen

Wenn Ihre App auf Android 11 (API-Level 30) oder höher ausgerichtet ist, erfordern die aktuellen und letzten Versionen des IMA DAI SDK eine ausdrückliche Absichtserklärung zum Öffnen von Weblinks. Fügen Sie der Manifestdatei Ihrer App das folgende Snippet hinzu, um Klicks auf Anzeigen 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-Benutzeroberfläche einrichten

Erstelle das PlayerView-Objekt, das von ExoPlayer verwendet werden soll.

Ändere das androidx.constraintlayout.widget.ConstraintLayout in ein LinearLayout, was für die ExoPlayer-IMA-Erweiterung empfohlen wird.

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 IMA-Seite für Beispielstreams findest du Beispielstream-Assets, mit denen du dein Projekt testen kannst. Informationen zum Einrichten eigener Streams findest du auch im Ad Manager-Abschnitt zu dynamischer Anzeigenbereitstellung.

In diesem Schritt wird das Einrichten eines Livestreams veranschaulicht. Die ExoPlayer-IMA-Erweiterung unterstützt aber auch VOD-Streams mit dynamischer Anzeigenbereitstellung. Im Schritt für Video-on-Demand-Streams (VOD) erfahren Sie, welche Änderungen an Ihrer App für die Verarbeitung von VOD-Streams erforderlich sind.

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üge den Asset-Schlüssel des HLS-Streams Big Buck Bunny (Live) hinzu, um ihn mit diesem Stream zu testen. Weitere Streams zum Testen findest du auf der Beispielstreamseite der IMA.

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;

...

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;

}

adsLoader-Instanz erstellen

Überschreiben Sie die Methode onCreate, um die PlayerView zu finden, und prüfen Sie, ob eine gespeicherte AdsLoader.State vorhanden ist, die beim Initiieren des adsLoader-Objekts verwendet werden kann.

Aktivieren Sie außerdem Multidex, falls die Methodenanzahl 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 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.fromBundle(
                adsLoaderStateBundle);
      }
    }
  }

}

Methoden zum Initialisieren des Players hinzufügen

Füge eine Methode zum Initialisieren des Players hinzu und führe die folgenden Schritte aus:

  • Erstellen Sie eine AdsLoader-Instanz.
  • Erstellen Sie ExoPlayer.
  • Erstelle eine 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.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 in dieser Sequenz eine Methode zum Freigeben des Players hinzu:

  • Setze die Spielerreferenzen auf „null“ und gib die Ressourcen des Spielers frei.
  • Lassen Sie den Status des adsLoader los.

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 abschließend Callbacks für die Lebenszyklusereignisse der Aktivität, um die Wiedergabe des Streams zu steuern.

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

So unterstützen Sie Android SDK-Versionen niedriger als 24: - onResume() - onPause()

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

In diesem Schritt wird auch das Ereignis onSaveInstanceState() verwendet, um zu versuchen, die 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 Werbung abgespielt werden müssen, müssen Sie Folgendes tun:

  1. Füge für einen VOD-Teststream ein CMS ID und ein Video ID hinzu.
  2. Erstelle mit ImaServerSideAdInsertionUriBuilder() einen SSAI-VOD-URI.
  3. Verwende diesen neuen URI als Medienelement deines Players.

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! Du rufst jetzt einen Medienstream mit der IMA-Erweiterung von ExoPlayer ab und spielst ihn ab. Den vollständigen Code finden Sie in den Android-DAI-Beispielen auf GitHub.