ExoPlayer IMA uzantısını kullanmaya başlayın

ExoPlayer, Android için uygulama düzeyinde bir medya oynatıcıdır. Bu kılavuzda, hem reklam hem de içerik içeren bir medya akışı istemek ve oynatmak için IMA DAI SDK'sını sarmalayan ExoPlayer IMA uzantısını nasıl kullanabileceğiniz gösterilmektedir.

Uzantının bazı avantajları şunlardır:

  • IMA'yı özelliklerle entegre etmek için gereken kodu basitleştirir.
  • IMA'nın yeni sürümlerine güncellemek için gereken geliştirme süresini kısaltır.

ExoPlayer IMA uzantısı, HLS ve DASH akış protokollerini destekler. Aşağıda bu sürecin bir özeti verilmiştir:

ExoPlayer-IMA uzantısı akış desteği
Canlı yayın VOD akışları
HLS Onay işareti Onay işareti
DASH Onay işareti Onay işareti

DASH canlı yayınları, ExoPlayer-IMA 1.1.0 ve sonraki sürümlerinde desteklenir.

Bu kılavuz, ExoPlayer kılavuzuna dayanmaktadır ve tam bir uygulama oluşturup uzantıyı entegre etme adımlarını gösterir. Tam örnek uygulama içeren bir örnek için ExoPlayerExample from GitHub'a bakın.

Başlangıç kılavuzu'ndaki talimatları uygulayın.

Ön koşullar

Yeni bir Android Studio projesi oluşturma

Android Studio projenizi oluşturmak için aşağıdaki adımları tamamlayın:

  • Android Studio'yu başlatın.
  • Yeni bir Android Studio projesi başlat'ı seçin.
  • Projenizi seçin sayfasında Etkinlik Yok şablonunu seçin.
  • İleri'yi tıklayın.
  • Projenizi yapılandırın sayfasında projenize ad verin ve dil olarak Java'yı seçin.

  • Son'u tıklayın.

ExoPlayer IMA uzantısını projenize ekleyin

Uzantı için içe aktarma işlemlerini dependencies bölümündeki uygulama düzeyinde build.gradle dosyasına ekleyin.

Uygulamanızı yapılandırın ve multidex'i etkinleştirin. Bu, uzantının boyutu nedeniyle gereklidir ve minSdkVersion Android 4.4W (API düzeyi 20) veya daha düşük olarak ayarlanmış uygulamalar için zorunludur.

Aşağıda bununla ilgili bir örnek verilmiştir:

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

Reklam istemek için IMA DAI SDK'nın gerektirdiği kullanıcı izinlerini ekleyin:

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>

Niyet beyanları ekleme

Uygulamanız Android 11'i (API düzeyi 30) veya sonraki sürümleri hedefliyorsa IMA DAI SDK'nın mevcut ve son sürümlerinde web bağlantılarını açma amacının açıkça belirtilmesi gerekir. Reklam tıklamalarını (kullanıcıların Daha fazla bilgi düğmesini tıklaması) etkinleştirmek için aşağıdaki snippet'i uygulamanızın manifest dosyasına ekleyin.

  <?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'ın kullanıcı arayüzünü ayarlama

ExoPlayer tarafından kullanılacak PlayerView nesnesini oluşturun.

androidx.constraintlayout.widget.ConstraintLayout simgesini, ExoPlayer IMA uzantısı için önerilen LinearLayout olarak değiştirin.

Aşağıda bununla ilgili bir örnek verilmiştir:

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>

Akış parametrelerinizi ekleme

Projenizi test etmek için örnek yayın öğeleriyle ilgili IMA örnek yayın sayfasına bakın. Kendi yayınlarınızı ayarlama hakkında bilgi edinmek için DAI ile ilgili Ad Manager bölümüne de bakın.

Bu adımda canlı yayın oluşturma gösterilmektedir ancak ExoPlayer IMA uzantısı, DAI VOD yayınlarını da destekler. Uygulamanızın VOD yayınlarını işlemek için hangi değişiklikleri yapması gerektiğini öğrenmek üzere seç-izle video (VOD) yayınlarıyla ilgili adımı inceleyin.

ExoPlayer IMA uzantısını içe aktarma

ExoPlayer uzantısı için içe aktarma ifadelerini ekleyin.

MyActivity.java öğesine aşağıdaki özel değişkenleri ekleyin:

Bu akışla test etmek için Big Buck Bunny (Live) HLS akışının öğe anahtarını ekleyin. IMA'nın örnek akış sayfasında test edilebilecek daha fazla akış mevcuttur.

Durumu KEY_ADS_LOADER_STATE kaydetmek ve almak için bir sabit AdsLoader oluşturun.

Aşağıda bununla ilgili bir örnek verilmiştir:

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 örneği oluşturma

PlayerView öğesini bulmak için onCreate yönteminin üzerine yazın ve AdsLoader.State öğesinin kaydedilip kaydedilmediğini kontrol edin. Kaydedilmişse adsLoader nesnesi başlatılırken kullanılabilir.

Ayrıca, uygulamanızın yöntem sayısı gerektiriyorsa multidex'i etkinleştirin minSdkVersion (2. adımda açıklandığı gibi).

Aşağıda bununla ilgili bir örnek verilmiştir:

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

}

Oynatıcıyı başlatmak için yöntemler ekleyin

Oynatıcıyı başlatmak için bir yöntem ekleyin ve aşağıdakileri yapın:

  • AdsLoader örneği oluşturun.
  • ExoPlayer oluşturun.
  • Canlı yayının öğe anahtarıyla MediaItem oluşturun.
  • MediaItem değerini oynatıcınıza ayarlayın.

Aşağıda bununla ilgili bir örnek verilmiştir:

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

Oyuncuyu serbest bırakmak için bir yöntem ekleme

Bu sırayla oynatıcıyı serbest bırakacak bir yöntem ekleyin:

  • Oyuncu referanslarını null olarak ayarlayın ve oyuncunun kaynaklarını serbest bırakın.
  • adsLoader durumunu serbest bırakın.

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

Oynatıcı etkinliklerini işleme

Son olarak, akış oynatmayı yönetmek için etkinliğin yaşam döngüsü etkinlikleri için geri aramalar oluşturun.

Android SDK sürümü 24 ve sonraki sürümleri desteklemek için:

24'ten düşük Android SDK sürümlerini desteklemek için:

onStart() ve onResume(), playerView.onResume()'ye, onStop() ve onPause() ise playerView.onPause()'ye eşlenir.

Bu adımda, adsLoaderState öğesini kaydetmeye çalışmak için onSaveInstanceState() etkinliği de kullanılır.

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 akışı kurulumu (isteğe bağlı)

Uygulamanızın reklam içeren VOD içeriği oynatması gerekiyorsa aşağıdakileri yapmanız gerekir:

  1. VOD test akışı için CMS ID ve Video ID ekleyin.
  2. ImaServerSideAdInsertionUriBuilder() kullanarak bir SSAI VOD URI'si oluşturun.
  3. Bu yeni URI'yi oynatıcınızın medya öğesi olarak kullanın.

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

İşte bu kadar. Artık ExoPlayer IMA uzantısıyla bir medya akışı isteyip oynatıyorsunuz. Tam kod için GitHub'daki Android DAI örneklerine göz atın.