بدء استخدام إضافة ExoPlayer لإعلانات الوسائط التفاعلية

ExoPlayer هو مشغّل وسائط على مستوى التطبيق لنظام التشغيل Android. يوضّح هذا الدليل كيفية استخدام إضافة ExoPlayer لإعلانات الوسائط التفاعلية التي تتضمّن حزمة تطوير البرامج (SDK) لـ "إعلانات البث المباشر" من "إعلانات الوسائط التفاعلية"، وذلك لطلب بث وسائط يتضمّن الإعلانات والمحتوى وتشغيله.

في ما يلي بعض مزايا الإضافة:

  • تبسّط هذه المكتبة الرمز البرمجي اللازم لدمج IMA مع الميزات.
  • يقلّل من وقت التطوير اللازم للتحديث إلى إصدارات جديدة من IMA.

يتوافق برنامج ExoPlayer IMA الإضافي مع بروتوكولَي بث HLS وDASH. في ما يلي ملخّص:

إتاحة بث ExoPlayer-IMA
بث مباشر فيديوهات عند الطلب
HLS علامة اختيار علامة اختيار
DASH علامة اختيار علامة اختيار

تتوفّر أحداث البث المباشر بتنسيق DASH على الإصدار 1.1.0 والإصدارات الأحدث من ExoPlayer-IMA.

يستند هذا الدليل إلى دليل ExoPlayer، ويوضّح كيفية إنشاء تطبيق كامل ودمج الإضافة. يمكنك الاطّلاع على ExoPlayerExample من GitHub للحصول على مثال يتضمّن تطبيقًا نموذجيًا كاملاً.

المتطلبات الأساسية

إنشاء مشروع جديد في "استوديو Android"

لإنشاء مشروع Android Studio، أكمِل الخطوات التالية:

  • ابدأ تشغيل "استوديو Android".
  • اختَر بدء مشروع جديد في "استوديو Android".
  • في صفحة اختيار مشروعك، اختَر نموذج بدون نشاط.
  • انقر على التالي.
  • في صفحة إعداد مشروعك، حدِّد اسمًا لمشروعك واختَر Java كلغة.

  • انقر على إنهاء.

إضافة إضافة ExoPlayer IMA إلى مشروعك

أضِف عمليات استيراد للمكوّن الإضافي إلى ملف build.gradle على مستوى التطبيق في القسم dependencies.

اضبط تطبيقك وفعِّل multidex. وهذا الإجراء ضروري بسبب حجم الحزمة الإضافية، وهو مطلوب للتطبيقات التي تم ضبط minSdkVersion فيها على Android 4.4W (المستوى 20 لواجهة برمجة التطبيقات) أو إصدار أقدم.

وفي ما يلي مثال لذلك:

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

أضِف أذونات المستخدم المطلوبة من حزمة تطوير البرامج لإعلانات الوسائط التفاعلية (IMA) في "الإعلانات الديناميكية أثناء البث" (DAI) لطلب الإعلانات:

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>

إضافة بيانات عن النية

إذا كان تطبيقك يستهدف الإصدار 11 من نظام التشغيل Android (المستوى 30 لواجهة برمجة التطبيقات) أو الإصدارات الأحدث، تتطلّب الإصدارات الحالية والحديثة من حزمة تطوير البرامج (SDK) لخدمة "إعلانات البث المباشر" من "إعلانات الوسائط التفاعلية" بيانًا صريحًا عن النية لفتح روابط الويب. أضِف المقتطف التالي إلى ملف بيان تطبيقك من أجل تفعيل عمليات النقر على الإعلانات (أي عندما ينقر المستخدمون على الزر مزيد من المعلومات).

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

أنشئ عنصر PlayerView لاستخدامه في ExoPlayer.

غيِّر androidx.constraintlayout.widget.ConstraintLayout إلى LinearLayout، وهو الإعداد الذي يُنصح به لإضافة ExoPlayer IMA.

وفي ما يلي مثال لذلك:

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>

إضافة مَعلمات البث

يمكنك الاطّلاع على صفحة عيّنة البث في IMA للحصول على عيّنات من مواد عرض البث لاختبار مشروعك. يمكنك أيضًا الاطّلاع على قسم "مدير إعلانات Google" حول DAI للحصول على معلومات حول إعداد قنوات البث الخاصة بك.

توضّح هذه الخطوة كيفية إعداد بث مباشر، ولكن يتيح أيضًا برنامج ExoPlayer IMA الإضافي بث محتوى عند الطلب باستخدام ميزة "إدراج الإعلانات الديناميكي". اطّلِع على خطوة فيديوهات البث عند الطلب لمعرفة التغييرات التي يجب أن يتعامل معها تطبيقك لتشغيل فيديوهات البث عند الطلب.

استيراد إضافة ExoPlayer IMA

أضِف عبارات الاستيراد الخاصة بإضافة ExoPlayer.

أضِف المتغيّرات الخاصة التالية إلى MyActivity.java:

أضِف مفتاح أصل بث HLS الخاص بـ Big Buck Bunny (Live) لاختبار هذا البث. تتوفّر المزيد من قنوات البث لاختبارها على صفحة عيّنة قناة البث في IMA.

أنشئ KEY_ADS_LOADER_STATE ثابتًا لحفظ الحالة واستردادها.AdsLoader

وفي ما يلي مثال لذلك:

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

يمكنك إعادة كتابة طريقة onCreate للعثور على PlayerView والتحقّق من وجود AdsLoader.State محفوظ، ويمكن استخدام هذا العنصر عند بدء العنصر adsLoader.

فعِّل أيضًا ميزة multidex إذا كان عدد الطرق في تطبيقك يتطلّب ذلك وminSdkVersion(كما هو موضّح في الخطوة 2).

وفي ما يلي مثال لذلك:

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

}

إضافة طرق لتهيئة المشغّل

أضِف طريقة لإعداد المشغّل واتّبِع الخطوات التالية:

  • أنشئ مثيلاً من AdsLoader.
  • أنشئ ExoPlayer.
  • أنشئ MediaItem باستخدام مفتاح أصل البث المباشر.
  • اضبط قيمة MediaItem على المشغّل.

وفي ما يلي مثال لذلك:

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

إضافة طريقة لإيقاف المشغّل

أضِف طريقة لإيقاف المشغّل بالتسلسل التالي:

  • اضبط مراجع المشغّل على القيمة الخالية وحرِّر موارد المشغّل.
  • أطلِق حالة 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();
  }

التعامل مع أحداث اللاعب

أخيرًا، أنشئ استدعاءات لأحداث دورة حياة النشاط من أجل التعامل مع تشغيل البث.

لإتاحة الإصدار 24 من حزمة تطوير البرامج (SDK) لنظام التشغيل Android أو الإصدارات الأحدث، اتّبِع الخطوات التالية:

لإتاحة إصدارات حزمة تطوير البرامج (SDK) لنظام التشغيل Android الأقل من 24، اتّبِع الخطوات التالية:

يتم ربط onStart() وonResume() بـ playerView.onResume()، ويتم ربط onStop() وonPause() بـ playerView.onPause().

تستخدِم هذه الخطوة أيضًا حدث onSaveInstanceState() للمحاولة بحفظ 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());
    }
  }

  ...

}

إعداد بث الفيديو عند الطلب (اختياري)

إذا كان تطبيقك يتطلّب تشغيل محتوى فيديو عند الطلب مع إعلانات، عليك اتّخاذ الإجراءات التالية:

  1. أضِف CMS ID وVideo ID لإنشاء بث تجريبي عند الطلب.
  2. أنشئ معرّف الموارد المنتظم (URI) الخاص بالمحتوى المسجّل الذي يستخدم ميزة "إدراج الإعلانات من جهة الخادم" (SSAI) باستخدام ImaServerSideAdInsertionUriBuilder().
  3. استخدِم معرّف الموارد الموحّد الجديد هذا كعنصر وسائط للمشغّل.

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

هذا كل شيء! أنت الآن تطلب بث وسائط وتشغّله باستخدام إضافة ExoPlayer IMA. يمكنك الاطّلاع على نماذج DAI على Android على GitHub للحصول على الرمز الكامل.