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