Reklam ekleme

ExoPlayer, hem istemci hem de sunucu tarafı reklam ekleme için kullanılabilir.

İstemci tarafı reklam ekleme

İstemci tarafı reklam eklemede oynatıcı, oynatılan içerik ve reklamlar arasında geçiş yaparken farklı URL'lerden medya yükleme arasında geçiş yapar. Reklamlarla ilgili bilgiler, XML VAST veya VMAP reklam etiketi gibi medyadan ayrı olarak yüklenir. Bu, içeriğin başlangıcına göre reklam işaret konumları, gerçek reklam medya URI'ları ve belirli bir reklamın atlanabilir olup olmadığı gibi meta verileri içerebilir.

İstemci taraflı reklam ekleme için ExoPlayer'ın AdsMediaSource kullanıldığında oynatıcı, oynatılacak reklamlarla ilgili bilgilere sahip olur. Bunun pek çok avantajı 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ılmadığına bağlı olarak davranışlarını değiştirebilir.
  • Dahili olarak oynatıcı, reklamlar ve içerik arasındaki geçişlerde tutarlı bir tampon tutabilir.

Bu kurulumda, oynatıcı reklamlar ve içerikler arasında geçişle ilgilenir. Diğer bir deyişle, uygulamaların reklamlar ve içerikler için birden fazla ayrı arka plan/ön plan oynatıcısını kontrol etmeyle ilgilenmesi gerekmez.

İstemci tarafı reklam eklemeyle kullanılmak üzere içerik videoları ve reklam etiketleri hazırlarken, oynatıcının içerik oynatmaya sorunsuz bir şekilde devam edebilmesi için reklamların ideal olarak içerik videosundaki senkronizasyon örneklerine (animasyon kareleri) yerleştirilmesi gerekir.

Bildirim temelli reklam desteği

MediaItem oluşturulurken bir reklam etiketi URI'si 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 etiketlerinin belirtildiği medya öğelerine yönelik oynatıcı desteğini etkinleştirmek için, oynatıcı oluşturulurken AdsLoader.Provider ve AdViewProvider ile yapılandırılmış bir DefaultMediaSourceFactory oluşturulup yerleştirilmesi 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();

DefaultMediaSourceFactory, içerik medya kaynağını dahili olarak bir AdsMediaSource içine alır. AdsMediaSource, AdsLoader.Provider aracından bir AdsLoader alır ve medya öğesinin reklam etiketinde tanımlanan şekilde reklam eklemek için kullanır.

ExoPlayer'ın PlayerView uygulaması, AdViewProvider politikasını uygular. ExoPlayer IMA kitaplığı, aşağıda açıklandığı gibi kullanımı kolay bir AdsLoader sunar.

Reklam içeren oynatma listeleri

Birden fazla medya öğesi içeren bir oynatma listesini oynatırken, varsayılan davranış her bir medya kimliği, içerik URI'si ve reklam etiketi URI'si kombinasyonu için reklam etiketini istemek ve reklam oynatma durumunu bir kez depolamaktır. Diğer bir deyişle, reklam etiketi URI'leri eşleşse bile kullanıcılar ayrı bir medya kimliğine veya içerik URI'sine sahip reklamlara sahip her medya öğesi için reklam görür. Bir medya öğesi tekrarlanırsa kullanıcı, karşılık gelen reklamları yalnızca bir kez görür (reklam oynatma durumu, reklamların oynatılıp oynatılmadığını kaydeder; bu nedenle ilk defadan sonra atlanır).

Bu davranışı, nesne eşitliğine dayalı olarak belirli bir medya öğesi için reklam oynatma durumunun bağlantılı olduğu opak bir reklam tanımlayıcısı ileterek özelleştirmek mümkündür. Aşağıda, reklam oynatma durumunun reklam kimliği olarak reklam etiketi URI'sini ileterek medya kimliği ile reklam etiketi URI'sinin kombinasyonu yerine yalnızca reklam etiketi URI'sına bağlandığı bir örnek verilmiştir. Bunun sonucunda, reklamlar yalnızca bir kez yüklenir ve kullanıcı, oynatma listesini baştan sona oynatırken 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);

ExoPlayer IMA kitaplığı

ExoPlayer IMA kitaplığı, istemci taraflı reklam eklemeyi uygulamanıza entegre etmenizi kolaylaştıran ImaAdsLoader sağlar. VAST/VMAP reklamlarının eklenmesini desteklemek için istemci tarafı IMA SDK'sının işlevlerini sarmalar. Arka planda oynatma ve oynatmayı devam ettirme de dahil olmak üzere kitaplığın kullanımıyla ilgili talimatlar için lütfen BENİOKU bölümünü inceleyin.

Demo uygulaması, IMA kitaplığını kullanır ve örnek listede birkaç örnek VAST/VMAP reklam etiketi içerir.

Kullanıcı arayüzüyle ilgili dikkat edilmesi gereken noktalar

PlayerView, reklam oynatılırken aktarım denetimlerini varsayılan olarak gizler ancak uygulamalar setControllerHideDuringAds yöntemini çağırarak bu davranışı değiştirebilir. IMA SDK, reklam oynatılırken oynatıcının üst kısmında ek görünümler (örneğin, "daha fazla bilgi" bağlantısı ve varsa atla düğmesi) gösterir.

IMA SDK, oynatıcının üzerinde oluşturulan uygulama tarafından sağlanan görüntülemeler tarafından reklamların gizlenip engellenmediğini bildirebilir. Oynatmanın kontrol edilmesi için gerekli olan görünümleri yer paylaşımlı olarak kullanması gereken uygulamalar, görüntülenebilirlik hesaplamalarından çıkarılabilmesi için bunları IMA SDK'ya kaydetmelidir. AdViewProvider olarak PlayerView kullanıldığında, kontrol yer paylaşımlarını otomatik olarak kaydeder. Özel oynatıcı kullanıcı arayüzü kullanan uygulamalar, yer paylaşımlı görünümleri AdViewProvider.getAdOverlayInfos öğesinden döndürerek kaydetmelidir.

Yer paylaşımlı görünümler hakkında daha fazla bilgi için IMA SDK'da Open Measurement bölümüne bakın.

Tamamlayıcı reklamlar

Bazı reklam etiketleri, uygulama kullanıcı arayüzündeki "alanlarda" gösterilebilecek ek tamamlayıcı reklamlar içerir. Bu slotlar ImaAdsLoader.Builder.setCompanionAdSlots(slots) aracılığıyla aktarılabilir. Daha fazla bilgi için Tamamlayıcı Reklamlar Ekleme bölümüne bakın.

Bağımsız reklamlar

IMA SDK, bağımsız reklamları tek başına oynatmak için değil, medya içeriğine reklam eklemek için tasarlanmıştır. Bu nedenle, reklamların bağımsız olarak 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ı bir üçüncü taraf reklam SDK'sı aracılığıyla yüklemeniz gerekiyorsa SDK'nın hâlihazırda bir ExoPlayer entegrasyonu sağlayıp sağlamadığını kontrol etmek faydalı olacaktır. Aksi takdirde, yukarıda açıklanan AdsMediaSource avantajlarını sağladığı için üçüncü taraf reklam SDK'sını sarmalayan bir özel AdsLoader uygulamak önerilen yaklaşımdır. ImaAdsLoader, örnek bir uygulama işlevi 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(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);

Sunucu tarafı reklam ekleme

Sunucu tarafı reklam eklemede (dinamik reklam ekleme veya DAI olarak da adlandırılır) medya akışı hem reklam hem de içerik içerir. DASH manifesti, muhtemelen ayrı dönemlerde hem içeriğe hem de reklam segmentlerine işaret edebilir. HLS için reklamları oynatma listesine ekleme konulu Apple belgelerine 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ı görüntülemesi veya etkinlikleri bir reklam SDK'sına ya da reklam sunucusuna bildirmesi gerekebilir.

ExoPlayer'ın DefaultMediaSourceFactory öğesi, tüm bu görevleri ssai:// şemasını kullanarak URI'ler için sunucu tarafı reklam ekleme MediaSource ile paylaşabilir:

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 sağlayarak IMA'nın sunucu tarafında eklenen reklam akışlarıyla uygulamanıza entegre etmeyi kolaylaştırır. Android için IMA DAI SDK'sının işlevselliğini sarmalar ve sağlanan reklam meta verilerini oynatıcıya tamamen entegre eder. Örneğin bu, Player.isPlayingAd() gibi yöntemleri kullanmanıza, içerik-reklam geçişlerini dinlemenize ve oynatıcının önceden oynatılan reklamları atlamak gibi reklam oynatma mantığını işlemesine olanak tanır.

Bu sınıfı kullanmak için ImaServerSideAdInsertionMediaSource.AdsLoader ve ImaServerSideAdInsertionMediaSource.Factory öğelerini kurmanız ve 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 öğesi 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, artık kullanılmadığında reklam yükleyicinizi serbest bırakın:

Kotlin

adsLoader.release()

Java

adsLoader.release();

Kullanıcı arayüzüyle ilgili dikkat edilmesi gereken noktalar

İstemci tarafı reklam ekleme ile ilgili kullanıcı arayüzüyle ilgili dikkat edilmesi gereken noktalar, sunucu tarafı reklam ekleme için de geçerlidir.

Tamamlayıcı reklamlar

Bazı reklam etiketleri, uygulama kullanıcı arayüzündeki "alanlarda" gösterilebilecek ek tamamlayıcı reklamlar içerir. Bu slotlar ImaServerSideAdInsertionMediaSource.AdsLoader.Builder.setCompanionAdSlots(slots) aracılığıyla aktarılabilir. Daha fazla bilgi için Tamamlayıcı Reklamlar Ekleme bölümüne bakın.

Üçüncü taraf reklam SDK'sı kullanma

Üçüncü taraf reklam SDK'sı kullanarak reklam yüklemeniz gerekiyorsa SDK'nın hâlihazırda bir ExoPlayer entegrasyonu sağlayıp sağlamadığını kontrol etmek faydalı olacaktır. Aksi takdirde, ImaServerSideAdInsertionMediaSource'a benzer ssai:// şemasına sahip URI'leri kabul eden özel bir MediaSource sağlamanız önerilir.

Reklam yapısını oluşturmanın gerçek mantığı, genel amaçlı ServerSideAdInsertionMediaSource kullanılabilir. Bu, bir akışı sarmalar MediaSource ve kullanıcının reklam meta verilerini temsil eden AdPlaybackState öğesini ayarlayıp güncellemesine olanak tanır.

Sunucu tarafında eklenen reklam akışları, genellikle oynatıcıyı 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çimlere bakın. Özel reklam SDK'sı MediaSource uygulamaları, Player.Listener.onMetadata kullanarak oynatıcıdaki zamanlı meta veri etkinliklerini dinleyebilir.