درج آگهی

ExoPlayer می تواند برای درج آگهی در سمت مشتری و سرور استفاده شود.

درج آگهی سمت مشتری

در درج آگهی در سمت سرویس گیرنده، پخش کننده بین بارگیری رسانه از URL های مختلف هنگام انتقال بین پخش محتوا و تبلیغات، جابجا می شود. اطلاعات مربوط به تبلیغات به طور جداگانه از رسانه بارگیری می شود، مانند یک برچسب تبلیغاتی XML VAST یا VMAP . این می‌تواند شامل موقعیت‌های نشانه آگهی نسبت به شروع محتوا، URI‌های واقعی رسانه تبلیغاتی و ابرداده‌ها باشد، مانند اینکه آیا یک تبلیغ خاص قابل رد شدن است یا خیر.

هنگام استفاده از ExoPlayer's AdsMediaSource برای درج آگهی در سمت سرویس گیرنده، پخش کننده اطلاعاتی در مورد تبلیغاتی که قرار است پخش شود دارد. این چندین مزیت دارد:

  • پخش کننده می تواند ابرداده ها و عملکردهای مربوط به تبلیغات را با استفاده از API خود در معرض نمایش بگذارد.
  • اجزای رابط کاربری ExoPlayer می توانند نشانگرهایی را برای موقعیت های تبلیغاتی به طور خودکار نشان دهند و بسته به پخش شدن آگهی، رفتار آنها را تغییر دهند.
  • در داخل، پخش کننده می تواند یک بافر ثابت در انتقال بین تبلیغات و محتوا نگه دارد.

در این راه‌اندازی، پخش‌کننده از جابه‌جایی بین تبلیغات و محتوا مراقبت می‌کند، به این معنی که برنامه‌ها نیازی به کنترل چندین پخش‌کننده پس‌زمینه/پیش‌زمینه جداگانه برای تبلیغات و محتوا ندارند.

هنگام تهیه ویدیوهای محتوا و برچسب‌های تبلیغاتی برای استفاده با درج آگهی در سمت مشتری، تبلیغات باید در حالت ایده‌آل در نمونه‌های همگام‌سازی (فریم‌های کلیدی) در ویدیوی محتوا قرار گیرند تا پخش‌کننده بتواند به طور یکپارچه پخش محتوا را از سر بگیرد.

پشتیبانی تبلیغاتی اعلامی

یک URI تگ آگهی را می توان در هنگام ساخت یک MediaItem مشخص کرد:

کاتلین

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

جاوا

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

برای فعال کردن پشتیبانی پخش کننده برای آیتم های رسانه ای که برچسب های تبلیغاتی را مشخص می کنند، لازم است هنگام ایجاد پخش کننده، یک DefaultMediaSourceFactory پیکربندی شده با یک AdsLoader.Provider و یک AdViewProvider ایجاد و تزریق کنید:

کاتلین

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

جاوا

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 دریافت می کند و از آن برای درج تبلیغات همانطور که توسط تگ تبلیغ آیتم رسانه تعریف شده است استفاده می کند.

ExoPlayer's PlayerView AdViewProvider را پیاده سازی می کند. کتابخانه ExoPlayer IMA یک AdsLoader آسان برای استفاده را فراهم می کند، همانطور که در زیر توضیح داده شده است.

لیست پخش با تبلیغات

هنگام پخش یک لیست پخش با چندین آیتم رسانه، رفتار پیش‌فرض این است که برای هر شناسه رسانه، URI محتوا و ترکیب URI برچسب آگهی، یک بار درخواست برچسب آگهی و ذخیره وضعیت پخش آگهی شود. این بدان معناست که کاربران برای هر آیتم رسانه ای تبلیغاتی را مشاهده خواهند کرد که دارای شناسه رسانه یا URI محتوای مشخصی است، حتی اگر URIهای برچسب آگهی مطابقت داشته باشند. اگر یک آیتم رسانه تکرار شود، کاربر تبلیغات مربوطه را فقط یک بار می بیند (وضعیت پخش آگهی ذخیره می کند که آیا تبلیغات پخش شده اند یا نه، بنابراین پس از اولین بار از آنها صرفنظر می شود).

می‌توان این رفتار را با ارسال یک شناسه تبلیغات غیرشفاف که وضعیت پخش آگهی برای یک مورد رسانه خاص با آن مرتبط است، بر اساس برابری شی، سفارشی کرد. در اینجا مثالی وجود دارد که در آن وضعیت پخش آگهی تنها به URI تگ آگهی، به جای ترکیبی از شناسه رسانه و URI تگ آگهی، با ارسال URI تگ آگهی به عنوان شناسه آگهی، مرتبط می شود. اثر این است که تبلیغات فقط یک بار بارگذاری می شود و کاربر هنگام پخش لیست پخش از ابتدا تا انتها، تبلیغات مورد دوم را نمی بیند.

کاتلین

// 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)

جاوا

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

کتابخانه ExoPlayer IMA ImaAdsLoader را ارائه می‌کند و ادغام درج آگهی سمت مشتری در برنامه شما را آسان می‌کند. این کارکرد IMA SDK سمت کلاینت را برای پشتیبانی از درج تبلیغات VAST/VMAP می‌پوشاند. برای دستورالعمل‌های نحوه استفاده از کتابخانه، از جمله نحوه مدیریت پس‌زمینه و از سرگیری پخش، لطفاً به README مراجعه کنید.

برنامه آزمایشی از کتابخانه IMA استفاده می کند و شامل چندین نمونه برچسب تبلیغاتی VAST/VMAP در لیست نمونه است.

ملاحظات UI

PlayerView کنترل های حمل و نقل خود را در حین پخش تبلیغات به طور پیش فرض پنهان می کند، اما برنامه ها می توانند این رفتار را با فراخوانی setControllerHideDuringAds تغییر دهند. در حین پخش آگهی، IMA SDK نماهای اضافی را در بالای پخش کننده نشان می دهد (به عنوان مثال، پیوند "اطلاعات بیشتر" و دکمه رد شدن، در صورت وجود).

IMA SDK ممکن است گزارش دهد که آیا تبلیغات توسط نماهای ارائه شده از برنامه ارائه شده در بالای پخش کننده پنهان شده است یا خیر. برنامه‌هایی که نیاز به همپوشانی نماهایی دارند که برای کنترل بازپخش ضروری هستند، باید آن‌ها را در IMA SDK ثبت کنند تا از محاسبات قابلیت مشاهده حذف شوند. هنگام استفاده از PlayerView به عنوان AdViewProvider ، به طور خودکار پوشش های کنترلی خود را ثبت می کند. برنامه‌هایی که از رابط کاربری پخش‌کننده سفارشی استفاده می‌کنند باید نماهای همپوشانی را با بازگرداندن آنها از AdViewProvider.getAdOverlayInfos ثبت کنند.

برای اطلاعات بیشتر در مورد نماهای همپوشانی، به Open Measurement در IMA SDK مراجعه کنید.

تبلیغات همراه

برخی از تگ‌های تبلیغاتی حاوی تبلیغات همراه دیگری هستند که می‌توانند در «شاخه‌ها» در رابط کاربری برنامه نشان داده شوند. این اسلات‌ها را می‌توان از طریق ImaAdsLoader.Builder.setCompanionAdSlots(slots) ارسال کرد. برای اطلاعات بیشتر، به افزودن تبلیغات همراه مراجعه کنید.

تبلیغات مستقل

IMA SDK برای درج تبلیغات در محتوای رسانه طراحی شده است، نه برای پخش تبلیغات مستقل به تنهایی. از این رو پخش تبلیغات مستقل توسط کتابخانه IMA پشتیبانی نمی شود. توصیه می کنیم به جای آن از Google Mobile Ads SDK برای این مورد استفاده کنید.

استفاده از یک SDK تبلیغات شخص ثالث

اگر نیاز به بارگیری تبلیغات از طریق یک SDK تبلیغات شخص ثالث دارید، ارزش بررسی این را دارد که آیا قبلاً یکپارچه سازی ExoPlayer را ارائه می دهد یا خیر. در غیر این صورت، پیاده‌سازی یک AdsLoader سفارشی که SDK تبلیغات شخص ثالث را پوشش می‌دهد، رویکرد توصیه‌شده است، زیرا مزایای AdsMediaSource که در بالا توضیح داده شد را ارائه می‌کند. ImaAdsLoader به عنوان نمونه ای از پیاده سازی عمل می کند.

از طرف دیگر، می توانید از پشتیبانی لیست پخش ExoPlayer برای ساخت دنباله ای از تبلیغات و کلیپ های محتوا استفاده کنید:

کاتلین

// 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)

جاوا

// 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، به مستندات اپل در مورد گنجاندن تبلیغات در لیست پخش مراجعه کنید.

هنگام استفاده از درج آگهی سمت سرور، مشتری ممکن است نیاز داشته باشد URL رسانه را به صورت پویا حل کند تا جریان دوخته شده را دریافت کند، ممکن است نیاز به نمایش همپوشانی تبلیغات در رابط کاربری داشته باشد یا ممکن است لازم باشد رویدادها را به یک SDK تبلیغات یا سرور تبلیغات گزارش دهد.

DefaultMediaSourceFactory ExoPlayer می تواند تمام این وظایف را به MediaSource درج آگهی سمت سرور برای URI ها با استفاده از طرح ssai:// واگذار کند:

کاتلین

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

جاوا

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

کتابخانه ExoPlayer IMA

کتابخانه ExoPlayer IMA ImaServerSideAdInsertionMediaSource را ارائه می‌کند و ادغام با جریان‌های تبلیغاتی درج شده در سمت سرور IMA را در برنامه شما آسان می‌کند. این کارکرد IMA DAI SDK برای Android را در بر می گیرد و ابرداده های تبلیغاتی ارائه شده را به طور کامل در پخش کننده ادغام می کند. به عنوان مثال، این به شما امکان می‌دهد از روش‌هایی مانند Player.isPlayingAd() استفاده کنید، به انتقال محتوا-تبلیغ گوش دهید و به پخش کننده اجازه دهید منطق پخش آگهی را مدیریت کند، مانند پرش از تبلیغات پخش شده از قبل.

برای استفاده از این کلاس، باید ImaServerSideAdInsertionMediaSource.AdsLoader و ImaServerSideAdInsertionMediaSource.Factory را راه اندازی کرده و آنها را به پخش کننده متصل کنید:

کاتلین

// 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)

جاوا

// 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 ، کلید دارایی IMA یا شناسه منبع محتوا و شناسه ویدیوی خود را بارگیری کنید:

کاتلین

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

جاوا

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

در نهایت، پس از عدم استفاده از لودر تبلیغات خود را آزاد کنید:

کاتلین

adsLoader.release()

جاوا

adsLoader.release();

ملاحظات UI

همان ملاحظات UI که برای درج آگهی سمت سرویس گیرنده وجود دارد، برای درج آگهی سمت سرور نیز اعمال می شود.

تبلیغات همراه

برخی از تگ‌های تبلیغاتی حاوی تبلیغات همراه دیگری هستند که می‌توانند در «شاخه‌ها» در رابط کاربری برنامه نشان داده شوند. این اسلات ها را می توان از طریق ImaServerSideAdInsertionMediaSource.AdsLoader.Builder.setCompanionAdSlots(slots) ارسال کرد. برای اطلاعات بیشتر به افزودن تبلیغات همراه مراجعه کنید.

استفاده از یک SDK تبلیغات شخص ثالث

اگر نیاز به بارگیری تبلیغات با استفاده از یک SDK تبلیغات شخص ثالث دارید، باید بررسی کنید که آیا قبلاً یکپارچه سازی ExoPlayer را ارائه می دهد یا خیر. اگر نه، توصیه می شود یک MediaSource سفارشی ارائه کنید که URI ها را با ssai:// مشابه ImaServerSideAdInsertionMediaSource بپذیرد.

منطق واقعی ایجاد ساختار تبلیغات را می توان به ServerSideAdInsertionMediaSource با هدف کلی تفویض کرد، که یک جریان MediaSource را می پوشاند و به کاربر اجازه می دهد AdPlaybackState که نشان دهنده فراداده تبلیغات است تنظیم و به روز کند.

اغلب، جریان‌های تبلیغاتی درج‌شده در سمت سرور حاوی رویدادهای زمان‌بندی‌شده برای اطلاع‌رسانی به پخش‌کننده درباره ابرداده‌های آگهی هستند. لطفاً فرمت‌های پشتیبانی شده را برای اطلاعات در مورد فرمت‌های فراداده زمان‌بندی‌شده توسط ExoPlayer ببینید. تبلیغات سفارشی پیاده سازی های SDK MediaSource می توانند با استفاده از Player.Listener.onMetadata به رویدادهای فراداده زمان بندی شده از پخش کننده گوش دهند.