Inizia a utilizzare l'estensione IMA ExoPlayer

ExoPlayer è un media player a livello di applicazione per Android. Questa guida illustra come utilizzare l'estensione IMA ExoPlayer, che aggrega l'SDK IMA per Android DAI, per richiedere e riprodurre uno stream multimediale con annunci e contenuti.

Ecco alcuni dei vantaggi dell'estensione:

  • Semplifica il codice necessario per integrare l'IMA con le funzionalità.
  • Riduce il tempo di sviluppo necessario per eseguire l'aggiornamento alle nuove versioni di IMA.

L'estensione IMA ExoPlayer supporta i protocolli di streaming HLS e DASH. Ecco un riepilogo:

Supporto per lo streaming con estensione ExoPlayer-IMA
Live streaming Stream VOD
HLS Segno di spunta Segno di spunta
DASH Segno di spunta Segno di spunta

I live streaming DASH sono supportati su ExoPlayer-IMA versione 1.1.0 o successive.

Questa guida si basa sulla guida di ExoPlayer e mostra come creare un'app completa e integrare l'estensione. Consulta ExoPlayerExample di GitHub per un esempio con un'app di esempio completa.

Prerequisiti

Creare un nuovo progetto Android Studio

Per creare il tuo progetto Android Studio, completa i seguenti passaggi:

  • Avvia Android Studio.
  • Seleziona Avvia un nuovo progetto Android Studio.
  • Nella pagina Scegli il tuo progetto, seleziona il modello Nessuna attività.
  • Tocca Avanti.
  • Nella pagina Configura il tuo progetto, assegna un nome al progetto e seleziona Java per il linguaggio.

  • Fai clic su Fine.

Aggiungere l'estensione IMA ExoPlayer al progetto

Aggiungi le importazioni dell'estensione al file build.gradle a livello di applicazione nella sezione dependencies.

Configura la tua app e attiva multidex. Questa operazione è necessaria a causa delle dimensioni dell'estensione ed è obbligatoria per le app con minSdkVersion impostata su Android 4, 4 W (livello API 20) o su una versione precedente.

Esempio:

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'
}

Aggiungi le autorizzazioni dell'utente richieste dall'SDK IMA per richiedere gli annunci:

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>

Aggiungi dichiarazioni di intent

Se la tua app ha come target Android 11 (livello API 30) o versioni successive, le versioni attuali e recenti dell'SDK IMA richiedono una dichiarazione di intent esplicita per aprire i link web. Aggiungi il seguente snippet al file manifest della tua app per attivare i clickthrough degli annunci (utenti che fanno clic sul pulsante Scopri di più).

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

Configurazione dell'UI di ExoPlayer

Crea l'oggetto PlayerView che verrà utilizzato da ExoPlayer.

Modifica androidx.constraintlayout.widget.ConstraintLayout in LinearLayout, che è consigliato per l'estensione IMA di ExoPlayer.

Esempio:

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>

Aggiungere i parametri dello stream

Consulta la pagina di esempio dello stream IMA per gli asset dello stream di esempio per testare il tuo progetto. Consulta anche la sezione Ad Manager sull'inserimento di annunci dinamici per informazioni sulla configurazione dei tuoi stream.

Questo passaggio illustra la configurazione di un live streaming, ma l'estensione IMA di ExoPlayer supporta anche gli stream VOD DAI. Consulta la procedura per gli stream video on demand (VOD) per conoscere le modifiche necessarie alla tua app per gestire gli stream VOD.

Importare l'estensione IMA di ExoPlayer

Aggiungi le istruzioni di importazione per l'estensione ExoPlayer.

Aggiungi le seguenti variabili private a MyActivity.java:

Aggiungi la chiave asset dello stream HLS Big Buck Bunny (live) da testare con questo stream. Sono disponibili altri stream da testare nella pagina stream di esempio di IMA.

Crea una costante KEY_ADS_LOADER_STATE per salvare e recuperare lo stato AdsLoader.

Esempio:

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;

}

Crea un'istanza adsLoader

Sovrascrivi il metodo onCreate per trovare PlayerView e verifica la presenza di un elemento AdsLoader.State salvato, che può essere utilizzato quando avvii l'oggetto adsLoader.

Inoltre, abilita il multidex se richiesto dal conteggio dei metodi dell'app e da minSdkVersion (come spiegato nel passaggio 2).

Esempio:

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

}

Aggiungi metodi per inizializzare il player

Aggiungi un metodo per inizializzare il player e procedi nel seguente modo:

  • Creare un'istanza AdsLoader.
  • Crea il ExoPlayer.
  • Crea un MediaItem con la chiave asset del live streaming.
  • Imposta MediaItem sul player.

Esempio:

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

Aggiungi un metodo per rilasciare il player

Aggiungi un metodo per rilasciare il player in questa sequenza:

  • Imposta i riferimenti del player su null e rilascia le risorse del player.
  • Rilascia lo stato di 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();
  }

Gestire gli eventi dei giocatori

Infine, crea dei callback per gli eventi del ciclo di vita dell'attività in modo da gestire la riproduzione dello stream.

Per supportare l'SDK per Android versione 24 o successive:

Per supportare le versioni dell'SDK Android precedenti alla 24: - onResume() - onPause()

onStart() e onResume() corrispondono a playerView.onResume(), mentre onStop() e onPause() corrispondono a playerView.onPause().

Questo passaggio utilizza anche l'evento onSaveInstanceState() per tentare di salvare 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());
    }
  }

  ...

}

(Facoltativo) Configurazione dello streaming VOD

Se la tua app è obbligatoria per riprodurre contenuti VOD con annunci, dovrai fare quanto segue:

  1. Aggiungi CMS ID e Video ID per uno stream di prova VOD.
  2. Crea un URI VOD SSAI utilizzando ImaServerSideAdInsertionUriBuilder().
  3. Utilizza questo nuovo URI come elemento multimediale del 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 = "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);
  }

È tutto. Ora stai richiedendo e riproducendo uno stream multimediale con l'estensione IMA ExoPlayer. Per il codice completo, consulta gli esempi di DAI Android su GitHub.