درج آگهی

ExoPlayer می‌تواند هم برای درج تبلیغات سمت کلاینت و هم برای درج تبلیغات سمت سرور استفاده شود.

درج آگهی سمت کلاینت

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

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

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

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

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

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

می‌توان هنگام ساخت یک MediaItem یک URI تگ تبلیغ (ad tag) مشخص کرد:

کاتلین

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

PlayerView مربوط به ExoPlayer، AdViewProvider پیاده‌سازی می‌کند. کتابخانه IMA مربوط به ExoPlayer، یک 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 به همراه HlsInterstitialsAdsLoader ارائه می‌شود که از تبلیغات تعریف‌شده در لیست پخش HLS برای درج خودکار در سمت کلاینت پشتیبانی می‌کند. به بخش مربوط به HlsInterstitialsAdsLoader در صفحه HLS مراجعه کنید.

کتابخانه IMA اکسو پلیر

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

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

ملاحظات رابط کاربری

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

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

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

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

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

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

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

استفاده از 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(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)

جاوا

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

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

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

کاتلین

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

جاوا

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

کتابخانه IMA اکسو پلیر

کتابخانه ExoPlayer IMA ، ImaServerSideAdInsertionMediaSource را ارائه می‌دهد که ادغام با جریان‌های تبلیغاتی درج‌شده سمت سرور IMA را در برنامه شما آسان می‌کند. این کتابخانه، قابلیت‌های IMA DAI SDK برای اندروید را در بر می‌گیرد و متادیتای تبلیغاتی ارائه شده را به طور کامل در پخش‌کننده ادغام می‌کند. به عنوان مثال، این به شما امکان می‌دهد از روش‌هایی مانند 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();

ملاحظات رابط کاربری

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

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

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

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

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

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

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