إدراج إعلان

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

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

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

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

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

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

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

إتاحة الإعلانات التعريفية

يمكن تحديد عنوان URL لعلامة الإعلان عند إنشاء 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) لعلامة الإعلان كمعرّف للإعلانات. نتيجةً لذلك، سيتم تحميل الإعلانات مرة واحدة فقط ولن يرى المستخدم إعلانات على العنصر الثاني عند تشغيل ملف الموسيقى العميق من البداية إلى النهاية.

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 IMA

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

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

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

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

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

لمزيد من المعلومات عن مشاهدات التراكب، يُرجى الاطّلاع على مقالة القياس المفتوح في حزمة تطوير البرامج لإعلانات الوسائط التفاعلية (IMA SDK).

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

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

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

تم تصميم حزمة تطوير البرامج IMA SDK لإدراج الإعلانات في محتوى الوسائط، وليس لتشغيل الإعلانات المستقلة بأنفسهم. وبالتالي، لا تتيح مكتبة IMA تشغيل الإعلانات المستقلة. ننصحك باستخدام حزمة تطوير البرامج (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 IMA

توفّر مكتبة ExoPlayer IMA ImaServerSideAdInsertionMediaSource، ما يسهّل الدمج مع أحداث إعلانات IMA المُدرَجة من جهة الخادم في تطبيقك. وهي تُغلِّف وظيفة حزمة تطوير البرامج لعرض الإعلانات الديناميكية في IMA لنظام التشغيل 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 الذي يمثّل البيانات الوصفيةMediaSource للإعلان وتعديلها.

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