Insertion d'annonces

ExoPlayer peut être utilisé pour insérer des annonces côté client et côté serveur.

Insertion d'annonces côté client

Avec l'insertion d'annonces côté client, le lecteur bascule entre le chargement différentes URL lors du passage du contenu aux annonces. Informations sur les annonces est chargé séparément du support, par exemple à partir d'un fichier XML VAST ou VMAP. Il peut s'agir de positions de repères d'annonce par rapport au début de la les URI du support publicitaire et les métadonnées, indiquant par exemple si une annonce donnée désactivables.

Lorsque vous utilisez AdsMediaSource d'ExoPlayer pour insérer des annonces côté client, le lecteur contient des informations sur les annonces diffusées. Cela présente plusieurs avantages :

  • Le lecteur peut exposer les métadonnées et les fonctionnalités liées aux annonces à l'aide de son API.
  • Les composants de l'interface utilisateur d'ExoPlayer peuvent afficher automatiquement des repères pour la position des annonces. et modifier leur comportement selon que l'annonce est diffusée ou non.
  • En interne, le lecteur peut conserver une mémoire tampon cohérente entre les transitions des annonces et du contenu.

Dans cette configuration, le lecteur se charge de basculer entre les annonces et le contenu, ce qui Cela signifie que les applications n'ont pas besoin de contrôler plusieurs des lecteurs d'arrière-plan/de premier plan pour les annonces et le contenu.

Lorsque vous préparez des contenus, des vidéos et des tags d'emplacement publicitaire pour l'insertion d'annonces côté client, Idéalement, les annonces doivent être positionnées au niveau des exemples de synchronisation (images clés) pour que le lecteur puisse reprendre la lecture du contenu sans interruption.

Prise en charge des annonces déclaratives

Vous pouvez spécifier un URI de tag d'emplacement publicitaire lors de la création d'une MediaItem:

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();

Pour permettre la compatibilité du lecteur avec les éléments multimédias spécifiant des tags d'emplacement publicitaire, il est nécessaire de compiler et injecter un DefaultMediaSourceFactory configuré avec une AdsLoader.Provider et AdViewProvider lors de la création du lecteur:

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();

En interne, DefaultMediaSourceFactory encapsule la source multimédia du contenu dans un AdsMediaSource AdsMediaSource obtiendra un AdsLoader à partir de AdsLoader.Provider et l'utiliser pour insérer des annonces telles que définies par l'annonce de l'élément multimédia .

Le PlayerView d'ExoPlayer implémente AdViewProvider. Le SDK IMA d'ExoPlayer fournit un AdsLoader facile à utiliser, comme décrit ci-dessous.

Playlists avec annonces

Lors de la lecture d'une playlist contenant plusieurs éléments multimédias, le comportement par défaut est pour demander le tag d'emplacement publicitaire et stocker l'état de lecture de l'annonce une fois pour chaque ID d'élément multimédia, l'URI du contenu et l'URI du tag d'emplacement publicitaire. Cela signifie que les utilisateurs verront des annonces pour chaque élément multimédia avec des annonces ayant un ID multimédia ou un URI de contenu distinct, même si les URI du tag d'emplacement publicitaire correspondent. Si un élément multimédia est répété, l'utilisateur voit les annonces correspondantes une seule fois (l'état de lecture de l'annonce enregistre si les annonces ont été et sont donc ignorées après la première occurrence).

Il est possible de personnaliser ce comportement en transmettant un identifiant d'annonce opaque. auquel l'état de lecture d'une annonce est associé pour un élément multimédia donné, en fonction l'égalité. Dans cet exemple, l'état de lecture d'une annonce est associé au tag d'emplacement publicitaire. (et non la combinaison de l'ID média et de l'URI du tag d'emplacement publicitaire), par qui transmet l'URI du tag d'emplacement publicitaire en tant qu'identifiant d'annonce. Les annonces se chargent alors pour qu'aucune annonce ne s'affiche sur le deuxième élément du début à la fin.

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

Bibliothèque IMA d'ExoPlayer

La bibliothèque IMA d'ExoPlayer fournit ImaAdsLoader, ce qui permet de intégrer l'insertion d'annonces côté client dans votre application. Il englobe la fonctionnalité le SDK IMA côté client pour permettre l'insertion d'annonces VAST/VMAP. Pour Des instructions sur l'utilisation de la bibliothèque, y compris la gestion de la mise en arrière-plan et reprendre la lecture, consultez le fichier README.

L'application de démonstration utilise la bibliothèque IMA et inclut plusieurs exemples Tags d'emplacement publicitaire VAST/VMAP dans la liste d'exemples.

Considérations relatives à l'interface utilisateur

PlayerView masque ses commandes de transport pendant la lecture des annonces en par défaut, mais les applications peuvent modifier ce comportement en appelant setControllerHideDuringAds Le SDK IMA affichera des vues supplémentaires le lecteur pendant la lecture d'une annonce (un lien "plus d'infos" et un bouton "Ignorer", par exemple) ; le cas échéant).

Le SDK IMA peut indiquer si les annonces sont masquées par des vues fournies par l'application. affiché en haut du lecteur. Applications qui doivent superposer des vues essentielles pour contrôler la lecture doivent les enregistrer auprès du SDK IMA elles peuvent être omises des calculs de visibilité. Lorsque vous utilisez PlayerView en tant que AdViewProvider, il enregistre automatiquement ses commandes en superposition. Applications qui utilisent une interface utilisateur de lecteur personnalisée doivent enregistrer les vues de superposition en les renvoyant depuis AdViewProvider.getAdOverlayInfos

Pour en savoir plus sur les vues de superposition, consultez Open Measurement dans le SDK IMA.

Annonces associées

Certains tags d'emplacement publicitaire contiennent des annonces associées supplémentaires qui peuvent s'afficher dans des "emplacements". dans un l'UI de l'application. Ces emplacements peuvent être transmis ImaAdsLoader.Builder.setCompanionAdSlots(slots) Pour en savoir plus, consultez Ajoutez des annonces associées.

Annonces autonomes

Le SDK IMA est conçu pour insérer des annonces dans les contenus multimédias, et non pour les diffuser. des annonces autonomes. Par conséquent, la lecture d'annonces autonomes n'est pas acceptée. par la bibliothèque IMA. Nous vous recommandons d'utiliser plutôt le SDK Google Mobile Ads. pour ce cas d'utilisation.

Utiliser un SDK publicitaire tiers

Si vous devez charger des annonces via un SDK publicitaire tiers, nous vous conseillons de vérifier il fournit déjà une intégration ExoPlayer. Si ce n'est pas le cas, la mise en œuvre Nous vous recommandons d'utiliser AdsLoader qui encapsule le SDK publicitaire tiers. car il offre les avantages de AdsMediaSource décrits ci-dessus. ImaAdsLoader sert d'exemple d'implémentation.

Vous pouvez également utiliser la compatibilité des playlists d'ExoPlayer pour créer une séquence d'annonces et de clips de contenu:

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

Insertion d'annonces côté serveur

Avec l'insertion d'annonces côté serveur (également appelée "insertion dynamique d'annonce"), le flux multimédia contient à la fois des annonces et du contenu. Un fichier manifeste DASH peut pointer vers et de segments d'annonces, éventuellement dans des périodes distinctes. Pour le HLS, consultez le Intégrer des annonces dans une playlist

Avec l'insertion d'annonces côté serveur, le client peut avoir besoin de résoudre le média URL dynamique pour obtenir le flux assemblé, il devra peut-être afficher des annonces en superposition dans l'UI, ou de signaler des événements à un SDK publicitaire ou à un ad server.

Le DefaultMediaSourceFactory d'ExoPlayer peut déléguer toutes ces tâches à un Insertion d'annonces côté serveur MediaSource pour les URI utilisant le schéma ssai://:

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();

Bibliothèque IMA d'ExoPlayer

La bibliothèque IMA d'ExoPlayer fournit des ImaServerSideAdInsertionMediaSource, ce qui facilite l'intégration avec les flux d'annonces insérés côté serveur d'IMA l'application. Elle englobe les fonctionnalités du SDK IMA DAI pour Android et intègre les métadonnées d'annonce fournies dans le lecteur. Par exemple, cela permet d'utiliser des méthodes comme Player.isPlayingAd(), d'écouter les transitions entre le contenu et l'annonce et laisser le lecteur gérer la logique de lecture des annonces, par exemple en ignorant les annonces déjà lues.

Pour utiliser cette classe, vous devez configurer ImaServerSideAdInsertionMediaSource.AdsLoader et les ImaServerSideAdInsertionMediaSource.Factory et connectez-les au lecteur:

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

Chargez la clé d'élément IMA, ou l'ID de la source du contenu et l'ID vidéo, en créant une URL. avec ImaServerSideAdInsertionUriBuilder:

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

Enfin, relâchez le chargeur d'annonces lorsqu'il n'est plus utilisé:

Kotlin

adsLoader.release()

Java

adsLoader.release();

Considérations relatives à l'interface utilisateur

Les mêmes considérations relatives à l'interface utilisateur que pour l'insertion d'annonces côté client s'appliquent l'insertion d'annonces côté serveur.

Annonces associées

Certains tags d'emplacement publicitaire contiennent des annonces associées supplémentaires qui peuvent s'afficher dans des "emplacements". dans un l'UI de l'application. Ces emplacements peuvent être transmis ImaServerSideAdInsertionMediaSource.AdsLoader.Builder.setCompanionAdSlots(slots) Pour en savoir plus, consultez la section Ajout d'annonces associées.

Utiliser un SDK publicitaire tiers

Si vous devez charger des annonces à l'aide d'un SDK publicitaire tiers, nous vous conseillons de vérifier il fournit déjà une intégration ExoPlayer. Si ce n'est pas le cas, nous vous recommandons fournir un MediaSource personnalisé qui accepte les URI avec le schéma ssai:// ; semblable à ImaServerSideAdInsertionMediaSource.

La logique de création de la structure d'annonce peut être déléguée l'objet ServerSideAdInsertionMediaSource, qui encapsule un flux MediaSource. et permet à l'utilisateur de définir et de mettre à jour le AdPlaybackState représentant l'annonce. de métadonnées.

Souvent, les flux d'annonces insérés côté serveur contiennent des événements programmés pour avertir le lecteur sur les métadonnées des annonces. Veuillez consulter les formats compatibles pour en savoir plus les formats de métadonnées minutés sont compatibles avec ExoPlayer. SDK MediaSource pour les annonces personnalisées les implémentations peuvent écouter les événements de métadonnées chronométrés du lecteur en utilisant Player.Listener.onMetadata