Reklam ekleme

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

İstemci tarafı reklam ekleme

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

İstemci tarafı reklam ekleme için ExoPlayer'ın AdsMediaSource özelliği kullanılırken oynatılacak reklamlarla ilgili bilgiler oynatıcıya verilir. Bunun bazı 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ılmadığına bağlı olarak davranışlarını değiştirebilir.
  • Oynatıcı, dahili olarak reklamlar ile içerik arasındaki geçişlerde tutarlı bir arabelleğe sahip olabilir.

Bu kurulumda, reklamlar ve içerik arasında geçişi oynatıcı yapar. Bu da uygulamaların reklamlar ve içerik için birden fazla ayrı arka plan/ön plan oynatıcıyı kontrol etmesine gerek olmadığı anlamına gelir.

İçerik videolarını ve reklam etiketlerini istemci taraflı reklam eklemede kullanılmak üzere hazırlarken reklamların ideal olarak içerik videosundaki senkronizasyon örneklerine (animasyon kareleri) yerleştirilmesi gerekir. Böylece, oynatıcılar içeriği oynatmaya sorunsuz bir şekilde devam edebilir.

Bildirim temelli reklam desteği

MediaItem oluşturulurken 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 etiketlerini belirten medya öğelerinde oynatıcı desteğini etkinleştirmek için oynatıcıyı oluştururken AdsLoader.Provider ve AdViewProvider ile yapılandırılmış bir DefaultMediaSourceFactory oluşturup yerleştirmek 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ı bir AdsMediaSource içine sarar. AdsMediaSource, AdsLoader.Provider öğesinden bir AdsLoader alır ve bunu medya öğesinin reklam etiketi tarafından tanımlandığı şekilde reklam eklemek için kullanır.

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

Reklam içeren oynatma listeleri

Birden fazla medya öğesi içeren bir oynatma listesi oynatıldığında varsayılan davranış, reklam etiketini istemek ve reklam oynatma durumunu her medya kimliği, içerik URI'si ve reklam etiketi URI'si kombinasyonu için bir kez depolamaktır. Bu, reklam etiketi URI'leri eşleşse bile kullanıcıların farklı bir medya kimliği veya içerik URI'si olan reklamların bulunduğu her medya öğesinin reklamlarını göreceği anlamına gelir. Bir medya öğesi tekrarlanırsa kullanıcı, ilgili reklamları yalnızca bir kez görür (reklam oynatma durumu, reklamların oynatılıp oynatılmadığını depolar. Bu nedenle, reklamlar ilk kez oynatıldıktan sonra atlanır).

Bu davranışı, nesne eşitliğine bağlı olarak belirli bir medya öğesi için reklam oynatma durumunun bağlandığı opak bir reklam tanımlayıcısı ileterek özelleştirmek mümkündür. Reklam oynatma durumunun, reklam etiketi URI'sinin reklam tanımlayıcısı olarak iletilmesiyle medya kimliği ve reklam etiketi URI'sinin birleşimi yerine yalnızca reklam etiketi URI'sine bağlandığı bir örnek aşağıda verilmiştir. Bu sayede 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 tarafı reklam eklemeyi uygulamanıza entegre etmeyi kolaylaştıran ImaAdsLoader sağlar. VAST/VMAP reklamlarının eklenmesini desteklemek için istemci tarafı IMA SDK'sının işlevini sarmalar. Arka planlama ve oynatmaya devam etme de dahil olmak üzere kitaplığın nasıl kullanılacağıyla ilgili talimatlar için lütfen BENİOKU bölümüne bakın.

Demo uygulama, IMA kitaplığını kullanır ve örnek listede çeşitli örnek VAST/VMAP reklam etiketleri içerir.

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

PlayerView varsayılan olarak reklamlar oynatılırken aktarım kontrollerini gizler. Ancak uygulamalar setControllerHideDuringAds çağrısı yaparak bu davranışı devre dışı bırakabilir. IMA SDK'sı, reklam oynatılırken oynatıcının üstünde ek görüntülemeler gösterir (örneğin, "daha fazla bilgi" bağlantısı ve varsa atlama düğmesi).

IMA SDK, reklamların oynatıcının üstünde oluşturulan uygulama tarafından sağlanan görüntüler tarafından engellenip engellenmediğini bildirebilir. Oynatma işlemini kontrol etmek için gerekli olan görünümlerin yer paylaşımı yapması gereken uygulamaların, görüntülenebilirlik hesaplamalarından çıkarılabilmeleri için bu görünümleri IMA SDK'sına kaydettirmesi gerekir. PlayerView, AdViewProvider olarak kullanıldığında kontrol yer paylaşımlarını otomatik olarak kaydeder. Özel oynatıcı kullanıcı arayüzü kullanan uygulamalar, yer paylaşımı görünümlerini AdViewProvider.getAdOverlayInfos üzerinden döndürerek kaydetmelidir.

Yer paylaşımı görünümleri hakkında daha fazla bilgi için IMA SDK'sında Open Measurement başlıklı makaleyi inceleyin.

Tamamlayıcı reklamlar

Bazı reklam etiketleri, uygulama kullanıcı arayüzündeki "alanlarda" gösterilebilecek ek tamamlayıcı reklamlar içerir. Bu alanlar ImaAdsLoader.Builder.setCompanionAdSlots(slots) ile iletilebilir. Daha fazla bilgi için Tamamlayıcı Reklam Ekleme bölümüne bakın.

Bağımsız reklamlar

IMA SDK'sı, 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, 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 bir reklam SDK'sı aracılığıyla yüklemeniz gerekiyorsa bu SDK'nın halihazırda ExoPlayer entegrasyonu sağlayıp sağlamadığını kontrol etmeniz önerilir. Aksi takdirde, yukarıda açıklanan AdsMediaSource avantajlarını sağladığı için üçüncü taraf reklam SDK'sını sarmalayan özel bir AdsLoader uygulanması önerilen yaklaşımdır. ImaAdsLoader, örnek uygulama olarak işlev görür.

Alternatif olarak, bir dizi reklam ve içerik klibi 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 bilinir), medya akışı hem reklamları hem de içeriği içerir. DASH manifesti hem içeriğe hem de reklam segmentlerine, muhtemelen ayrı dönemlerde, işaret edebilir. HLS için reklamları oynatma listelerine dahil etme ile ilgili Apple 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 Ads SDK'sına ya da reklam sunucusuna bildirmesi gerekebilir.

ExoPlayer'ın DefaultMediaSourceFactory, ssai:// şemasını kullanan URI'ler için tüm bu görevleri sunucu tarafı reklam ekleme MediaSource'ye 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 sağlar ve uygulamanızda IMA'nın sunucu tarafına yerleştirilmiş reklam akışlarıyla entegrasyonu kolaylaştırır. Android için IMA DAI SDK'sının işlevini sarmalayarak sağlanan reklam meta verilerini oynatıcıya tamamen entegre eder. Örneğin, bu sayede Player.isPlayingAd() gibi yöntemleri kullanabilir, içerik-reklam geçişlerini dinleyebilir ve oynatıcının, daha önce oynatılan reklamları atlama gibi reklam oynatma mantığını yönetmesine 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, artık kullanılmayan reklam yükleyicinizi yayından kaldırın:

Kotlin

adsLoader.release()

Java

adsLoader.release();

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

İstemci tarafı reklam eklemeyle ilgili kullanıcı arayüzü hususları sunucu tarafı reklam ekleme için de geçerlidir.

Tamamlayıcı reklamlar

Bazı reklam etiketleri, uygulama kullanıcı arayüzündeki "slot'larda gösterilebilecek ek tamamlayıcı reklamlar içerir. Bu alanlar ImaServerSideAdInsertionMediaSource.AdsLoader.Builder.setCompanionAdSlots(slots) aracılığıyla iletilebilir. Daha fazla bilgi için Tamamlayıcı reklam ekleme başlıklı makaleyi inceleyin.

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

Reklamları bir üçüncü taraf reklam SDK'sı kullanarak yüklemeniz gerekiyorsa halihazırda bir ExoPlayer entegrasyonu sağlayıp sağlamadığını kontrol etmenizi öneririz. Aksi takdirde, ImaServerSideAdInsertionMediaSource'ye benzer şekilde 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ığı, bir akışı MediaSource sarmalayan ve kullanıcının reklam meta verilerini temsil eden AdPlaybackState öğesini ayarlayıp güncellemesine olanak tanıyan ServerSideAdInsertionMediaSource genel amacına devredilebilir.

Sunucu tarafına yerleştirilen reklam akışları genellikle oynatıcıyı reklam meta verileri hakkında bilgilendirmek için zamanlanmış etkinlikler içerir. ExoPlayer tarafından desteklenen 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 zamanlanmış meta veri etkinliklerini izleyebilir.