يمكن استخدام ExoPlayer لإدراج الإعلانات من جهة العميل ومن جهة الخادم.
إدراج الإعلانات من جهة العميل
في عملية إدراج الإعلانات من جهة العميل، ينتقل المشغّل بين تحميل الوسائط من عناوين URL مختلفة أثناء الانتقال بين تشغيل المحتوى والإعلانات. يتم تحميل المعلومات حول الإعلانات بشكل منفصل عن الوسائط، مثلاً من علامة إعلان VAST أو VMAP بتنسيق XML. ويمكن أن يشمل ذلك مواضع إشارات الإعلانات بالنسبة إلى بداية المحتوى، ومعرّفات الموارد الموحّدة لوسائط الإعلانات الفعلية، والبيانات الوصفية، مثل ما إذا كان يمكن تخطّي إعلان معيّن.
عند استخدام 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 عند إنشاء المشغّل، ثم إدخال DefaultMediaSourceFactory:
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 IMA 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 HlsInterstitialsAdsLoader يتيح إدراج الإعلانات المحدّدة في قائمة تشغيل HLS تلقائيًا من جهة العميل. يمكنك الاطّلاع على القسم حول HlsInterstitialsAdsLoader في صفحة HLS.
مكتبة "إعلانات الوسائط التفاعلية" في ExoPlayer
توفّر مكتبة ExoPlayer IMA ImaAdsLoader، ما يسهّل دمج ميزة "إدراج الإعلان من جهة العميل" في تطبيقك. وهي تتضمّن وظائف حزمة تطوير البرامج لإعلانات الوسائط التفاعلية من جهة العميل من أجل إتاحة إدراج إعلانات VAST/VMAP. للحصول على تعليمات حول كيفية استخدام المكتبة، بما في ذلك كيفية التعامل مع التشغيل في الخلفية واستئنافه، يُرجى الاطّلاع على ملف README.
يستخدم التطبيق التجريبي مكتبة IMA، ويتضمّن العديد من نماذج علامات إعلانات VAST/VMAP في قائمة النماذج.
اعتبارات متعلقة بواجهة المستخدم
يخفي PlayerView عناصر التحكّم في النقل أثناء تشغيل الإعلانات تلقائيًا، ولكن يمكن للتطبيقات تبديل هذا السلوك من خلال استدعاء setControllerHideDuringAds. سيعرض حزمة تطوير البرامج (SDK) الخاصة بـ IMA طرق عرض إضافية فوق المشغّل أثناء عرض الإعلان (على سبيل المثال، رابط "مزيد من المعلومات" وزر تخطّي، إذا كان ذلك منطبقًا).
قد تُبلغ حزمة تطوير البرامج للإعلانات التفاعلية (IMA) عمّا إذا كانت الإعلانات محجوبة بسبب طرق العرض التي يوفّرها التطبيق ويتم عرضها فوق المشغّل. يجب أن تسجّل التطبيقات التي تحتاج إلى عرض عناصر مركّبة أساسية للتحكّم في التشغيل هذه العناصر باستخدام حزمة تطوير البرامج للإعلانات التفاعلية (IMA SDK) حتى يمكن استبعادها من عمليات احتساب إمكانية العرض. عند استخدام PlayerView كـ AdViewProvider، سيتم تلقائيًا تسجيل عناصر التحكّم المتراكبة. يجب أن تسجّل التطبيقات التي تستخدم واجهة مستخدم مخصّصة للمشغّل طرق عرض التراكب من خلال عرضها من AdViewProvider.getAdOverlayInfos.
لمزيد من المعلومات عن طرق العرض المتراكبة، يُرجى الاطّلاع على Open Measurement في حزمة تطوير البرامج (SDK) الخاصة بـ IMA.
إعلانات مصاحبة
تحتوي بعض علامات الإعلانات على إعلانات مصاحبة إضافية يمكن عرضها في "مساحات إعلانية" ضمن واجهة مستخدم التطبيق. يمكن تمرير هذه الخانات من خلال
ImaAdsLoader.Builder.setCompanionAdSlots(slots). لمزيد من المعلومات، اطّلِع على مقالة إضافة إعلانات مصاحبة.
الإعلانات المستقلة
تم تصميم "حزمة تطوير البرامج للإعلانات التفاعلية" لإدراج الإعلانات في محتوى الوسائط، وليس لتشغيل الإعلانات المستقلة وحدها. وبالتالي، لا تتيح مكتبة 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(MediaItem.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(MediaItem.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 MediaItem.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 MediaItem.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إدراج الإعلانات من جهة الخادمDefaultMediaSourceFactory لعناوين 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 IMA ImaServerSideAdInsertionMediaSource، ما يسهّل عملية الدمج مع بث إعلانات يتم إدخالها من جهة الخادم في تطبيقك. وهي تتضمّن وظائف حزمة تطوير البرامج (SDK) لإدخال الإعلانات ديناميكيًا من "إعلانات الوسائط التفاعلية" على 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);
حمِّل مفتاح مادة عرض IMA أو معرّف مصدر المحتوى ومعرّف الفيديو من خلال إنشاء عنوان 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 مخصّص يقبل معرّفات الموارد المنتظمة (URI) بنظام ssai:// مشابه لنظام ImaServerSideAdInsertionMediaSource.
يمكن تفويض المنطق الفعلي لإنشاء بنية الإعلان إلى ServerSideAdInsertionMediaSource العام، والذي يغلّف بثًا MediaSource ويسمح للمستخدم بضبط وتعديل AdPlaybackState الذي يمثّل البيانات الوصفية للإعلان.
في كثير من الأحيان، تحتوي حِزم بث الإعلانات المُدرَجة من جهة الخادم على أحداث محدّدة بوقت لإعلام اللاعب ببيانات وصفية عن الإعلان. يُرجى الاطّلاع على التنسيقات المتوافقة للحصول على معلومات حول تنسيقات البيانات الوصفية المستندة إلى الوقت التي تتوافق مع ExoPlayer. يمكن لعمليات تنفيذ حزمة تطوير البرامج (SDK) للإعلانات المخصّصة MediaSource
الاستماع إلى أحداث البيانات الوصفية المحدّدة المدة من المشغّل باستخدام
Player.Listener.onMetadata.