إدراج إعلان

يمكن استخدام ExoPlayer لإدراج الإعلانات من جهة العميل ومن جهة الخادم.

إدراج الإعلانات من جهة العميل

في ميزة إدراج الإعلان من جهة العميل، يبدِّل المشغّل بين تحميل الوسائط من عناوين URL مختلفة أثناء انتقاله بين تشغيل المحتوى والإعلانات. يتم تحميل المعلومات المتعلّقة بالإعلانات بشكل منفصل عن الوسائط، مثلاً من خلال علامة إعلانات XML VAST أو VMAP. يمكن أن يشمل ذلك مواضع إشارات الإعلان ذات الصلة ببداية المحتوى وعناوين URL الفعلية لوسائط الإعلان والبيانات الوصفية، مثلاً ما إذا كان إعلان معيّن قابلاً للتخطّي أم لا.

عند استخدام AdsMediaSource في ExoPlayer لإدراج الإعلان من جهة العميل، يكون لدى المشغّل معلومات عن الإعلانات التي سيتم تشغيلها. وهذا له فوائد عديدة:

  • يمكن للمشغّل عرض بيانات وصفية ووظائف مرتبطة بالإعلانات باستخدام واجهة برمجة التطبيقات الخاصة به.
  • قد تعرض مكونات واجهة مستخدم ExoPlayer علامات لمواضع الإعلانات تلقائيًا، وتغيّر سلوكها استنادًا إلى ما إذا كان يتم عرض الإعلان أم لا.
  • داخليًا، يمكن للمشغّل الحفاظ على مورد احتياطي متسق بين الانتقالات بين الإعلانات والمحتوى.

في عملية الإعداد هذه، يتولّى المشغّل التبديل بين الإعلانات والمحتوى، ما يعني أنّ التطبيقات لن تحتاج إلى التحكّم في العديد من المشغّلات المنفصلة التي تعمل في الخلفية أو في المقدّمة لعرض الإعلانات والمحتوى.

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

دعم الإعلانات التعريفية

يمكن تحديد معرّف الموارد المنتظم (URI) لعلامة الإعلان عند إنشاء MediaItem:

Kotlin

val mediaItem =
  MediaItem.Builder()
    .setUri(videoUri)
    .setAdsConfiguration(MediaItem.AdsConfiguration.Builder(adTagUri).build())
    .build()

Java

MediaItem mediaItem =
    new MediaItem.Builder()
        .setUri(videoUri)
        .setAdsConfiguration(
            new MediaItem.AdsConfiguration.Builder(adTagUri).build())
        .build();

لإتاحة استخدام المشغّل لعناصر الوسائط التي تحدّد علامات الإعلانات، يجب إنشاء وإدخال DefaultMediaSourceFactory تم ضبطها باستخدام AdsLoader.Provider وAdViewProvider عند إنشاء المشغّل:

Kotlin

val mediaSourceFactory: MediaSource.Factory =
  DefaultMediaSourceFactory(context).setLocalAdInsertionComponents(adsLoaderProvider, playerView)
val player = ExoPlayer.Builder(context).setMediaSourceFactory(mediaSourceFactory).build()

Java

MediaSource.Factory mediaSourceFactory =
    new DefaultMediaSourceFactory(context)
        .setLocalAdInsertionComponents(adsLoaderProvider, /* adViewProvider= */ playerView);
ExoPlayer player =
    new ExoPlayer.Builder(context).setMediaSourceFactory(mediaSourceFactory).build();

داخليًا، ستعمل ميزة DefaultMediaSourceFactory على تضمين مصدر وسائط المحتوى في AdsMediaSource. سيحصل AdsMediaSource على AdsLoader من AdsLoader.Provider ويستخدمه لإدراج الإعلانات على النحو المحدّد من خلال علامة الإعلان الخاصة بملف الوسائط.

ينفِّذ PlayerView في ExoPlayer AdViewProvider. توفّر مكتبة إعلانات الوسائط التفاعلية في ExoPlayer طريقة AdsLoader سهلة الاستخدام، كما هو موضَّح أدناه.

قوائم تشغيل تتضمّن إعلانات

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

من الممكن تخصيص هذا السلوك عن طريق تمرير معرّف إعلانات مبهم ترتبط به حالة تشغيل الإعلان لعنصر وسائط معيّن، بناءً على تساوي العنصر. وفي ما يلي مثال يتم فيه ربط حالة تشغيل الإعلان بمعرّف الموارد المنتظم (URI) لعلامة الإعلان فقط، بدلاً من الجمع بين معرّف الوسائط وعنوان URI لعلامة الإعلان، من خلال تمرير معرّف الموارد المنتظم (URI) لعلامة الإعلان، على أنّه معرّف الإعلانات. نتيجةً لذلك، سيتم تحميل الإعلانات مرة واحدة فقط ولن تظهر للمستخدم إعلانات في العنصر الثاني عند تشغيل قائمة التشغيل من البداية إلى النهاية.

Kotlin

// Build the media items, passing the same ads identifier for both items,
// which means they share ad playback state so ads play only once.
val firstItem =
  MediaItem.Builder()
    .setUri(firstVideoUri)
    .setAdsConfiguration(MediaItem.AdsConfiguration.Builder(adTagUri).setAdsId(adTagUri).build())
    .build()
val secondItem =
  MediaItem.Builder()
    .setUri(secondVideoUri)
    .setAdsConfiguration(MediaItem.AdsConfiguration.Builder(adTagUri).setAdsId(adTagUri).build())
    .build()
player.addMediaItem(firstItem)
player.addMediaItem(secondItem)

Java

// Build the media items, passing the same ads identifier for both items,
// which means they share ad playback state so ads play only once.
MediaItem firstItem =
    new MediaItem.Builder()
        .setUri(firstVideoUri)
        .setAdsConfiguration(
            new MediaItem.AdsConfiguration.Builder(adTagUri).setAdsId(adTagUri).build())
        .build();
MediaItem secondItem =
    new MediaItem.Builder()
        .setUri(secondVideoUri)
        .setAdsConfiguration(
            new MediaItem.AdsConfiguration.Builder(adTagUri).setAdsId(adTagUri).build())
        .build();
player.addMediaItem(firstItem);
player.addMediaItem(secondItem);

مكتبة إعلانات الوسائط التفاعلية في ExoPlayer

توفّر مكتبة ExoPlayer لإعلانات الوسائط التفاعلية ImaAdsLoader، ما يُسهِّل دمج ميزة إدراج الإعلانات من جهة العميل في تطبيقك. وتضم هذه المكتبة وظائف حزمة تطوير البرامج لإعلانات الوسائط التفاعلية من جهة العميل لإتاحة إدراج إعلانات VAST/VMAP. للحصول على إرشادات حول كيفية استخدام المكتبة، بما في ذلك كيفية التعامل مع الخلفية واستئناف التشغيل، يُرجى الاطلاع على README.

يستخدم التطبيق التجريبي مكتبة IMA، ويتضمّن عدّة نماذج لعلامات إعلانات VAST/VMAP في قائمة النماذج.

اعتبارات واجهة المستخدم

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

قد تُبلغ حزمة تطوير البرامج لإعلانات الوسائط التفاعلية ما إذا كانت الإعلانات محجوبة بسبب طرق عرض التطبيق التي يتم عرضها أعلى المشغّل. ويجب على التطبيقات التي تحتاج إلى تراكب طرق العرض، التي تعتبر ضرورية للتحكم في التشغيل، تسجيلها باستخدام حزمة تطوير البرامج لإعلانات الوسائط التفاعلية، بحيث يمكن حذفها من حسابات إمكانية العرض. عند استخدام PlayerView على أنّه AdViewProvider، سيتم تسجيل عناصر التحكّم الخاصة بها تلقائيًا. إنّ التطبيقات التي تستخدم واجهة مستخدم لمشغّل مخصّص يجب أن تسجّل مشاهدات التراكب من خلال عرضها من AdViewProvider.getAdOverlayInfos.

لمزيد من المعلومات عن طرق عرض التراكب، اطّلِع على فتح القياس في حزمة تطوير البرامج لإعلانات الوسائط التفاعلية.

إعلانات مصاحبة

تحتوي بعض علامات الإعلانات على إعلانات مصاحبة إضافية يمكن عرضها في "خانات" في واجهة مستخدم التطبيق. يمكن تمرير هذه الخانات عبر ImaAdsLoader.Builder.setCompanionAdSlots(slots). لمزيد من المعلومات، راجع إضافة الإعلانات المصاحبة.

الإعلانات المستقلة

تم تصميم أداة تطوير البرامج لإعلانات الوسائط التفاعلية لإدراج الإعلانات في محتوى الوسائط، وليس لتشغيل الإعلانات المستقلة بحد ذاتها. وبالتالي، لا تتيح مكتبة إعلانات الوسائط التفاعلية تشغيل الإعلانات المستقلة. ننصحك باستخدام حزمة SDK لإعلانات Google على الأجهزة الجوّالة بدلاً من ذلك لحالة الاستخدام هذه.

استخدام حزمة تطوير برامج (SDK) لعرض الإعلانات تابعة لجهة خارجية

إذا كنت بحاجة إلى تحميل إعلانات من خلال حزمة تطوير برامج (SDK) لعرض الإعلانات تابعة لجهة خارجية، ننصحك بالتحقق مما إذا كانت هذه الحزمة توفّر عملية دمج ExoPlayer. وإذا لم يكن الأمر كذلك، ننصحك بتنفيذ طريقة AdsLoader مخصّصة تضم حزمة تطوير برامج (SDK) لإعلانات الجهات الخارجية، لأنها توفِّر مزايا AdsMediaSource الموضّحة أعلاه. تُعدّ السمة ImaAdsLoader مثالاً على عملية التنفيذ.

بدلاً من ذلك، يمكنك استخدام قائمة التشغيل المتوافقة مع ExoPlayer لإنشاء سلسلة من الإعلانات ومقاطع المحتوى:

Kotlin

// A pre-roll ad.
val preRollAd = MediaItem.fromUri(preRollAdUri)
// The start of the content.
val contentStart =
  MediaItem.Builder()
    .setUri(contentUri)
    .setClippingConfiguration(ClippingConfiguration.Builder().setEndPositionMs(120000).build())
    .build()
// A mid-roll ad.
val midRollAd = MediaItem.fromUri(midRollAdUri)
// The rest of the content
val contentEnd =
  MediaItem.Builder()
    .setUri(contentUri)
    .setClippingConfiguration(ClippingConfiguration.Builder().setStartPositionMs(120000).build())
    .build()

// Build the playlist.
player.addMediaItem(preRollAd)
player.addMediaItem(contentStart)
player.addMediaItem(midRollAd)
player.addMediaItem(contentEnd)

Java

// A pre-roll ad.
MediaItem preRollAd = MediaItem.fromUri(preRollAdUri);
// The start of the content.
MediaItem contentStart =
    new MediaItem.Builder()
        .setUri(contentUri)
        .setClippingConfiguration(
            new ClippingConfiguration.Builder().setEndPositionMs(120_000).build())
        .build();
// A mid-roll ad.
MediaItem midRollAd = MediaItem.fromUri(midRollAdUri);
// The rest of the content
MediaItem contentEnd =
    new MediaItem.Builder()
        .setUri(contentUri)
        .setClippingConfiguration(
            new ClippingConfiguration.Builder().setStartPositionMs(120_000).build())
        .build();

// Build the playlist.
player.addMediaItem(preRollAd);
player.addMediaItem(contentStart);
player.addMediaItem(midRollAd);
player.addMediaItem(contentEnd);

إدراج إعلان من جهة الخادم

في ميزة إدراج الإعلانات من جهة الخادم (المعروفة أيضًا باسم إدراج الإعلان الديناميكي أو DAI)، تحتوي ساحة مشاركات الوسائط على كلٍّ من الإعلانات والمحتوى. قد يشير بيان DASH إلى كلٍّ من المحتوى وشرائح الإعلانات، وربما في فترات منفصلة. بالنسبة إلى بروتوكول HLS، يمكنك مراجعة مستندات Apple حول دمج الإعلانات في قائمة تشغيل.

عند استخدام ميزة إدراج الإعلانات من جهة الخادم، قد يحتاج العميل إلى حلّ عنوان URL للوسائط بشكلٍ ديناميكي لبدء البث المدمَج، أو قد يحتاج إلى عرض الإعلانات المركّبة في واجهة المستخدم أو قد يحتاج إلى إعداد تقارير عن الأحداث إلى حزمة تطوير البرامج (SDK) للإعلانات أو خادم الإعلانات.

يمكن لـ DefaultMediaSourceFactory في ExoPlayer تفويض كل هذه المهام إلى إدراج إعلان من جهة الخادم MediaSource لعناوين URI باستخدام المخطط ssai://:

Kotlin

val player =
  ExoPlayer.Builder(context)
    .setMediaSourceFactory(
      DefaultMediaSourceFactory(context).setServerSideAdInsertionMediaSourceFactory(ssaiFactory)
    )
    .build()

Java

Player player =
    new ExoPlayer.Builder(context)
        .setMediaSourceFactory(
            new DefaultMediaSourceFactory(context)
                .setServerSideAdInsertionMediaSourceFactory(ssaiFactory))
        .build();

مكتبة إعلانات الوسائط التفاعلية في ExoPlayer

توفّر مكتبة ExoPlayer لإعلانات الوسائط التفاعلية ImaServerSideAdInsertionMediaSource، ما يسهّل عملية الدمج مع مصادر بيانات الإعلانات المُدرَجة من جهة الخادم لإعلانات الوسائط التفاعلية في تطبيقك. وتضم هذه المكتبة وظائف حزمة تطوير البرامج لإدراج إعلان ديناميكي لإعلانات الوسائط التفاعلية لنظام التشغيل Android، كما تدمج بشكلٍ كامل البيانات الوصفية للإعلان المقدَّمة في المشغّل. على سبيل المثال، يتيح لك ذلك استخدام طرق مثل Player.isPlayingAd()، والاستماع إلى الانتقالات بين الإعلانات والمحتوى، والسماح للمشغّل بالتعامل مع منطق تشغيل الإعلان مثل تخطّي الإعلانات التي سبق أن تم تشغيلها.

لاستخدام هذا الصف، عليك إعداد ImaServerSideAdInsertionMediaSource.AdsLoader وImaServerSideAdInsertionMediaSource.Factory وربطهما بالمشغّل:

Kotlin

// MediaSource.Factory to load the actual media stream.
val defaultMediaSourceFactory = DefaultMediaSourceFactory(context)
// AdsLoader that can be reused for multiple playbacks.
val adsLoader =
  ImaServerSideAdInsertionMediaSource.AdsLoader.Builder(context, adViewProvider).build()
// MediaSource.Factory to create the ad sources for the current player.
val adsMediaSourceFactory =
  ImaServerSideAdInsertionMediaSource.Factory(adsLoader, defaultMediaSourceFactory)
// Configure DefaultMediaSourceFactory to create both IMA DAI sources and
// regular media sources. If you just play IMA DAI streams, you can also use
// adsMediaSourceFactory directly.
defaultMediaSourceFactory.setServerSideAdInsertionMediaSourceFactory(adsMediaSourceFactory)
// Set the MediaSource.Factory on the Player.
val player = ExoPlayer.Builder(context).setMediaSourceFactory(defaultMediaSourceFactory).build()
// Set the player on the AdsLoader
adsLoader.setPlayer(player)

Java

// MediaSource.Factory to load the actual media stream.
DefaultMediaSourceFactory defaultMediaSourceFactory = new DefaultMediaSourceFactory(context);
// AdsLoader that can be reused for multiple playbacks.
ImaServerSideAdInsertionMediaSource.AdsLoader adsLoader =
    new ImaServerSideAdInsertionMediaSource.AdsLoader.Builder(context, adViewProvider).build();
// MediaSource.Factory to create the ad sources for the current player.
ImaServerSideAdInsertionMediaSource.Factory adsMediaSourceFactory =
    new ImaServerSideAdInsertionMediaSource.Factory(adsLoader, defaultMediaSourceFactory);
// Configure DefaultMediaSourceFactory to create both IMA DAI sources and
// regular media sources. If you just play IMA DAI streams, you can also use
// adsMediaSourceFactory directly.
defaultMediaSourceFactory.setServerSideAdInsertionMediaSourceFactory(adsMediaSourceFactory);
// Set the MediaSource.Factory on the Player.
Player player =
    new ExoPlayer.Builder(context).setMediaSourceFactory(defaultMediaSourceFactory).build();
// Set the player on the AdsLoader
adsLoader.setPlayer(player);

يمكنك تحميل مفتاح مادة عرض إعلانات الوسائط التفاعلية، أو رقم تعريف مصدر المحتوى ومعرّف الفيديو، من خلال إنشاء عنوان URL باستخدام ImaServerSideAdInsertionUriBuilder:

Kotlin

val ssaiUri =
  ImaServerSideAdInsertionUriBuilder()
    .setAssetKey(assetKey)
    .setFormat(C.CONTENT_TYPE_HLS)
    .build()
player.setMediaItem(MediaItem.fromUri(ssaiUri))

Java

Uri ssaiUri =
    new ImaServerSideAdInsertionUriBuilder()
        .setAssetKey(assetKey)
        .setFormat(C.CONTENT_TYPE_HLS)
        .build();
player.setMediaItem(MediaItem.fromUri(ssaiUri));

أخيرًا، ارفع إصبعك عن أداة تحميل الإعلانات بعد التوقّف عن استخدامها:

Kotlin

adsLoader.release()

Java

adsLoader.release();

اعتبارات واجهة المستخدم

تنطبق اعتبارات واجهة المستخدم نفسها المتعلقة بإدراج الإعلانات من جهة العميل على إدراج الإعلانات من جهة الخادم أيضًا.

إعلانات مصاحبة

تحتوي بعض علامات الإعلانات على إعلانات مصاحبة إضافية يمكن عرضها في "خانات" في واجهة مستخدم التطبيق. يمكن تمرير هذه الخانات عبر ImaServerSideAdInsertionMediaSource.AdsLoader.Builder.setCompanionAdSlots(slots). لمزيد من المعلومات، راجع إضافة الإعلانات المصاحبة.

استخدام حزمة تطوير برامج (SDK) لعرض الإعلانات تابعة لجهة خارجية

إذا كنت بحاجة إلى تحميل إعلانات باستخدام حزمة تطوير برامج (SDK) لعرض الإعلانات تابعة لجهة خارجية، ننصحك بالتحقق مما إذا كانت هذه الحزمة توفّر عملية دمج ExoPlayer. إذا لم يكن الأمر كذلك، ننصحك بتوفير سمة MediaSource مخصّصة تقبل عناوين URL مع مخطط ssai:// المشابه لـ ImaServerSideAdInsertionMediaSource.

يمكن تفويض المنطق الفعلي لإنشاء بنية الإعلان إلى الغرض العام من ServerSideAdInsertionMediaSource، والذي يلتف على ساحة المشاركات MediaSource ويسمح للمستخدم بضبط وتعديل AdPlaybackState التي تمثل البيانات الوصفية للإعلان.

غالبًا ما تتضمّن مجموعات بث الإعلانات المُدرَجة من جهة الخادم أحداثًا محدّدة زمنيًا لإشعار المشغّل ببيانات وصفية للإعلان. يُرجى الاطّلاع على التنسيقات المتوافقة للحصول على معلومات حول تنسيقات البيانات الوصفية المحدّدة زمنيًا التي يمكن استخدامها في ExoPlayer. إنّ عمليات تنفيذ MediaSource لحزمة تطوير البرامج (SDK) للإعلانات المخصّصة يمكنها الاستماع إلى أحداث البيانات الوصفية المحدّدة زمنيًا من المشغّل باستخدام Player.Listener.onMetadata.