ExoPlayer, hem istemci tarafı hem de sunucu tarafı reklam ekleme için kullanılabilir.
İstemci tarafı reklam ekleme
İstemci taraflı reklam eklemede oynatıcı, içerik ve reklam oynatma arasında geçiş yaparken farklı URL'lerden medya yüklemeye geçer. Reklamlarla ilgili bilgiler, medyadan ayrı olarak (ör. XML VAST veya VMAP reklam etiketinden) yüklenir. Bu, içeriğin başlangıcına göre reklam işaretinin konumlarını, gerçek reklam medyası URI'lerini ve belirli bir reklamın atlanabilir olup olmadığı gibi meta verileri içerebilir.
İstemci tarafında reklam ekleme için ExoPlayer'ın AdsMediaSource özelliği kullanılırken oynatıcı, oynatılacak reklamlarla ilgili bilgilere sahiptir. Bu durumun çeşitli avantajları vardır:
- Oynatıcı, API'sini kullanarak reklamlarla ilgili meta verileri ve işlevleri gösterebilir.
- ExoPlayer kullanıcı arayüzü bileşenleri, reklam konumları için işaretçileri otomatik olarak gösterebilir ve reklamın oynatılıp oynatılmamasına bağlı olarak davranışlarını değiştirebilir.
- Oynatıcı, reklamlar ve içerik arasındaki geçişlerde dahili olarak tutarlı bir arabellek kullanabilir.
Bu kurulumda oynatıcı, reklamlar ve içerikler arasında geçiş yapmayı sağlar. Bu nedenle uygulamaların, reklamlar ve içerikler için birden fazla ayrı arka plan/ön plan oynatıcısını kontrol etmesi gerekmez.
İstemci taraflı reklam ekleme ile kullanılacak içerik videoları ve reklam etiketleri hazırlanırken reklamlar, oynatıcının içerik oynatmaya sorunsuz bir şekilde devam edebilmesi için ideal olarak içerik videosundaki senkronizasyon örneklerine (anahtar kareler) yerleştirilmelidir.
Bildirimsel reklam desteği
Bir reklam etiketi URI'si, MediaItem oluşturulurken belirtilebilir:
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();
Reklam etiketleri belirten medya öğeleri için oynatıcı desteğini etkinleştirmek üzere oynatıcıyı oluştururken DefaultMediaSourceFactory ve AdViewProvider ile yapılandırılmış bir AdsLoader.Provider oluşturup yerleştirmeniz gerekir:
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();
Dahili olarak DefaultMediaSourceFactory, içerik medya kaynağını AdsMediaSource ile sarmalar. AdsMediaSource, AdsLoader.Provider'den AdsLoader alır ve bunu, medya öğesinin reklam etiketi tarafından tanımlanan reklamları eklemek için kullanır.
ExoPlayer'ın PlayerView uygulamaları AdViewProvider. ExoPlayer IMA kitaplığı, aşağıda açıklandığı gibi kullanımı kolay bir AdsLoader sağlar.
Reklam içeren oynatma listeleri
Birden fazla medya öğesi içeren bir oynatma listesi oynatılırken varsayılan davranış, her bir medya kimliği, içerik URI'si ve reklam etiketi URI'si kombinasyonu için reklam etiketini bir kez istemek ve reklam oynatma durumunu depolamaktır. Bu, reklam etiketi URI'leri eşleşse bile kullanıcıların, reklam içeren ve farklı bir medya kimliğine veya içerik URI'sine sahip her medya öğesi için reklam göreceği anlamına gelir. Bir medya öğesi tekrar edilirse kullanıcı, ilgili reklamları yalnızca bir kez görür (reklam oynatma durumu, reklamların oynatılıp oynatılmadığını saklar. Bu nedenle, ilk gösterimden sonra atlanır).
Bu davranışı, belirli bir medya öğesinin reklam oynatma durumuyla ilişkilendirilen opak bir reklam tanımlayıcısı ileterek özelleştirmek mümkündür. Bu işlem, nesne eşitliğine göre yapılır. Burada, reklam etiketi URI'si reklam tanımlayıcısı olarak geçirilerek reklam oynatma durumunun yalnızca reklam etiketi URI'siyle (medya kimliği ve reklam etiketi URI'sinin kombinasyonu yerine) bağlantılı olduğu bir örnek verilmiştir. Bu durumda reklamlar yalnızca bir kez yüklenir ve kullanıcı, oynatma listesini baştan sona oynattığında ikinci öğede reklam görmez.
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);
Sunucu yönlendirmeli istemci tarafı reklam ekleme
ExoPlayer, HLS oynatma listesinde tanımlanan reklamların istemci tarafına otomatik olarak eklenmesini destekleyen HlsInterstitialsAdsLoader ile birlikte gelir. HLS sayfasındaki HlsInterstitialsAdsLoader ile ilgili bölümü inceleyin.
ExoPlayer IMA kitaplığı
ExoPlayer IMA kitaplığı, ImaAdsLoader sağlayarak istemci tarafı reklam eklemeyi uygulamanıza entegre etmeyi kolaylaştırır. VAST/VMAP reklamlarının eklenmesini desteklemek için istemci tarafı IMA SDK'sının işlevselliğini kapsar. Kitaplığın nasıl kullanılacağıyla ilgili talimatlar (arka planda çalıştırma ve oynatmaya devam etme dahil) için lütfen README dosyasını inceleyin.
Demo uygulaması, IMA kitaplığını kullanır ve örnek listede çeşitli örnek VAST/VMAP reklam etiketleri bulunur.
Kullanıcı arayüzü ile ilgili dikkat edilmesi gereken noktalar
PlayerView, reklam oynatılırken varsayılan olarak oynatma kontrollerini gizler ancak uygulamalar setControllerHideDuringAds işlevini çağırarak bu davranışı değiştirebilir. IMA SDK, bir reklam oynatılırken oynatıcının üzerinde ek görünümler gösterir (örneğin, varsa "daha fazla bilgi" bağlantısı ve atlama düğmesi).
IMA SDK, reklamların oynatıcının üzerinde oluşturulan uygulama tarafından sağlanan görünümlerle gizlenip gizlenmediğini bildirebilir. Oynatmayı kontrol etmek için gerekli olan görünümleri yerleştirmesi gereken uygulamalar, bu görünümleri IMA SDK'ya kaydettirmelidir. Böylece bu görünümler, görüntülenebilirlik hesaplamalarına dahil edilmez. PlayerView, AdViewProvider olarak kullanıldığında kontrol katmanlarını otomatik olarak kaydeder. Özel oynatıcı kullanıcı arayüzü kullanan uygulamaların, AdViewProvider.getAdOverlayInfos işlevinden döndürerek yer paylaşımı görünümlerini kaydetmesi gerekir.
Yer paylaşımı görünümleri hakkında daha fazla bilgi için IMA SDK'sında Açık Ölçüm başlıklı makaleyi inceleyin.
Tamamlayıcı reklamlar
Bazı reklam etiketleri, bir uygulama kullanıcı arayüzündeki "yuvalarda" gösterilebilen ek tamamlayıcı reklamlar içerir. Bu yuvalar ImaAdsLoader.Builder.setCompanionAdSlots(slots) aracılığıyla iletilebilir. Daha fazla bilgi için Eşlik eden reklamlar ekleme başlıklı makaleyi inceleyin.
Bağımsız reklamlar
IMA SDK, reklamları medya içeriğine yerleştirmek için tasarlanmıştır. Tek başına reklam oynatmak için tasarlanmamıştır. Bu nedenle, bağımsız reklamların oynatılması IMA kitaplığı tarafından desteklenmez. Bu kullanım alanı için bunun yerine Google Mobile Ads SDK'sını kullanmanızı öneririz.
Üçüncü taraf reklam SDK'sı kullanma
Reklamları üçüncü taraf reklam SDK'sı üzerinden yüklemeniz gerekiyorsa bu SDK'nın ExoPlayer entegrasyonu sağlayıp sağlamadığını kontrol etmeniz gerekir. Aksi takdirde, yukarıda açıklanan AdsMediaSource avantajlarını sağladığı için üçüncü taraf reklam SDK'sını sarmalayan özel bir AdsLoader uygulaması önerilir.
ImaAdsLoader, örnek uygulama olarak işlev görür.
Alternatif olarak, bir reklam ve içerik klibi dizisi oluşturmak için ExoPlayer'ın oynatma listesi desteğini kullanabilirsiniz:
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);
Sunucu taraflı reklam ekleme
Sunucu taraflı reklam ekleme (dinamik reklam ekleme veya DAI olarak da adlandırılır) çözümünde medya akışı hem reklamları hem de içeriği barındırır. Bir DASH manifesti, muhtemelen ayrı dönemlerde hem içerik hem de reklam segmentlerine işaret edebilir. HLS için Apple'ın reklamları oynatma listesine dahil etme ile ilgili dokümanlarına bakın.
Sunucu tarafı reklam ekleme kullanılırken istemcinin, birleştirilmiş akışı almak için medya URL'sini dinamik olarak çözmesi, kullanıcı arayüzünde reklam yer paylaşımlarını göstermesi veya etkinlikleri bir reklam SDK'sına ya da reklam sunucusuna bildirmesi gerekebilir.
ExoPlayer'ın DefaultMediaSourceFactory, ssai:// şemasını kullanan URI'ler için bu görevlerin tümünü bir MediaSource sunucu tarafı reklam ekleme işlemine devredebilir:
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 kitaplığı
ExoPlayer IMA kitaplığı, ImaServerSideAdInsertionMediaSource işlevi sunar. Bu sayede, IMA'nın sunucu tarafında eklenen reklam akışlarını uygulamanıza kolayca entegre edebilirsiniz. Android için IMA DAI SDK'sının işlevini kapsar ve sağlanan reklam meta verilerini oynatıcıya tamamen entegre eder. Örneğin, bu sayede Player.isPlayingAd() gibi yöntemler kullanabilir, içerik-reklam geçişlerini dinleyebilir ve oynatıcının, oynatılmış reklamları atlama gibi reklam oynatma mantığını işlemesine izin verebilirsiniz.
Bu sınıfı kullanmak için ImaServerSideAdInsertionMediaSource.AdsLoader ve ImaServerSideAdInsertionMediaSource.Factory öğelerini ayarlayıp oynatıcıya bağlamanız gerekir:
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);
ImaServerSideAdInsertionUriBuilder ile bir URL oluşturarak IMA öğe anahtarınızı veya içerik kaynağı kimliğinizi ve video kimliğinizi yükleyin:
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));
Son olarak, kullanılmadığında reklam yükleyicinizi serbest bırakın:
Kotlin
adsLoader.release()
Java
adsLoader.release();
Kullanıcı arayüzü ile ilgili dikkat edilmesi gereken noktalar
İstemci taraflı reklam ekleme için geçerli olan kullanıcı arayüzüyle ilgili hususlar, sunucu taraflı reklam ekleme için de geçerlidir.
Tamamlayıcı reklamlar
Bazı reklam etiketleri, bir uygulama kullanıcı arayüzündeki "yuvalarda" gösterilebilen ek tamamlayıcı reklamlar içerir. Bu yuvalar ImaServerSideAdInsertionMediaSource.AdsLoader.Builder.setCompanionAdSlots(slots) aracılığıyla iletilebilir.
Daha fazla bilgi için Eşlik eden reklamlar ekleme başlıklı makaleyi inceleyin.
Üçüncü taraf reklam SDK'sı kullanma
Üçüncü taraf reklam SDK'sı kullanarak reklam yüklemeniz gerekiyorsa bu SDK'nın ExoPlayer entegrasyonu sağlayıp sağlamadığını kontrol etmeniz gerekir. Aksi takdirde, ImaServerSideAdInsertionMediaSource'ye benzer ssai:// şemalı URI'leri kabul eden özel bir MediaSource sağlamanız önerilir.
Reklam yapısını oluşturma mantığı, akışı sarmalayan ServerSideAdInsertionMediaSource genel amaçlı MediaSource öğesine devredilebilir ve kullanıcının reklam meta verilerini temsil eden AdPlaybackState öğesini ayarlayıp güncellemesine olanak tanır.
Genellikle sunucu tarafında eklenen reklam yayınları, oyuncuyu reklam meta verileri hakkında bilgilendirmek için zamanlanmış etkinlikler içerir. ExoPlayer'ın desteklediği zamanlanmış meta veri biçimleri hakkında bilgi için lütfen desteklenen biçimler bölümüne bakın. Özel reklam SDK'sı MediaSource
uygulamaları, Player.Listener.onMetadata kullanarak oynatıcıdan gelen zamanlanmış meta veri etkinliklerini dinleyebilir.