ExoPlayer può essere utilizzato per l'inserimento di annunci sia lato client che lato server.
Inserimento di annunci lato client
Durante l'inserimento di annunci lato client, il player passa dal caricamento di contenuti multimediali all'altro URL diversi durante la transizione dai contenuti in riproduzione agli annunci. Informazioni sugli annunci viene caricato separatamente dai contenuti multimediali, ad esempio da un file XML VAST o Tag annuncio VMAP. Possono essere incluse le posizioni del segnale dell'annuncio rispetto all'inizio del contenuti, gli effettivi URI degli annunci multimediali e i metadati, ad esempio se un determinato annuncio è ignorabili.
Quando utilizzi AdsMediaSource
di ExoPlayer per l'inserimento di annunci lato client, il player
contiene informazioni sugli annunci da riprodurre. Questo approccio comporta diversi vantaggi:
- Il player può esporre metadati e funzionalità relativi agli annunci utilizzando la sua API.
- I componenti dell'interfaccia utente di ExoPlayer possono mostrare automaticamente gli indicatori per le posizioni degli annunci. e modificare il proprio comportamento a seconda che l'annuncio venga riprodotto o meno.
- Internamente, il player può mantenere un buffer coerente tra le transizioni annunci e contenuti.
In questa configurazione, il player si occupa di passare dagli annunci ai contenuti e viceversa, significa che le app non devono occuparsi di controllare più istanze player in background/in primo piano per annunci e contenuti.
Quando prepari contenuti, video e tag annuncio da usare con l'inserimento di annunci lato client, gli annunci dovrebbero essere posizionati in corrispondenza di campioni di sincronizzazione (frame chiave) nella di contenuti video in modo che il player possa riprendere la riproduzione dei contenuti senza problemi.
Supporto degli annunci dichiarativi
È possibile specificare un URI del tag annuncio durante la creazione di un 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();
Per attivare il supporto del player per gli elementi multimediali che specificano tag annuncio, è necessario
crea e inserisci un valore DefaultMediaSourceFactory
configurato con un
AdsLoader.Provider
e AdViewProvider
durante la creazione del player:
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();
Internamente, DefaultMediaSourceFactory
aggrega la fonte multimediale dei contenuti in un
AdsMediaSource
. AdsMediaSource
otterrà AdsLoader
dal
AdsLoader.Provider
e utilizzalo per inserire gli annunci come definito dall'annuncio dell'elemento multimediale
del tag.
PlayerView
di ExoPlayer implementa AdViewProvider
. L'IMA di ExoPlayer
libreria offre un'AdsLoader
di facile utilizzo, come descritto di seguito.
Playlist con annunci
Quando riproduci una playlist con più elementi multimediali, il comportamento predefinito è per richiedere il tag annuncio e memorizzare lo stato di riproduzione dell'annuncio una volta per ogni ID elemento multimediale, combinazione di URI content e URI tag annuncio. Ciò significa che gli utenti vedranno annunci per ogni elemento multimediale con annunci che ha un ID media o un URI contenuto distinto, anche se gli URI dei tag annuncio corrispondano. Se un elemento multimediale viene ripetuto, l'utente vedrà l'etichetta gli annunci corrispondenti soltanto una volta (lo stato di riproduzione dell'annuncio indica se gli annunci sono stati vengono riprodotti, quindi vengono ignorati dopo la loro prima occorrenza).
È possibile personalizzare questo comportamento trasmettendo un identificatore di annunci opaco a cui è collegato lo stato di riproduzione dell'annuncio per un determinato elemento multimediale, in base all'oggetto l'uguaglianza. Ecco un esempio in cui lo stato di riproduzione dell'annuncio è collegato al tag annuncio anziché la combinazione di ID elemento multimediale e URI del tag annuncio, per passando l'URI del tag annuncio come identificatore degli annunci. L'effetto è che gli annunci vengono caricati una volta sola e l'utente non vedrà annunci sul secondo elemento mentre riproduce il dall'inizio alla fine.
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);
libreria IMA di ExoPlayer
La libreria IMA di ExoPlayer fornisce ImaAdsLoader
per semplificare la
integrare l'inserimento di annunci lato client nella tua app. Aggrega la funzionalità
L'SDK IMA lato client per supportare l'inserimento di annunci VAST/VMAP. Per
Istruzioni sull'utilizzo della libreria, incluse le istruzioni per gestire il background
e riprendere la riproduzione, consulta il file README.
L'applicazione demo utilizza la libreria IMA e include diversi esempi Tag annuncio VAST/VMAP nell'elenco di esempio.
Considerazioni sull'interfaccia utente
PlayerView
nasconde i controlli per il trasporto durante la riproduzione degli annunci di
è la scelta predefinita, ma le app possono attivare/disattivare questo comportamento richiamando
setControllerHideDuringAds
. L'SDK IMA mostra visualizzazioni aggiuntive oltre a
nel player mentre è in riproduzione un annuncio (ad esempio, un link "altre informazioni" e un pulsante Salta,
se applicabile).
L'SDK IMA può segnalare se gli annunci sono oscurati dalle viste fornite dall'applicazione
visualizzate nella parte superiore del player. App che devono sovrapporre visualizzazioni che sono
essenziali per il controllo della riproduzione, devono registrarle con l'SDK IMA in modo che
possono essere omesse dai calcoli della visibilità. Quando utilizzi PlayerView
come
il AdViewProvider
, registrerà automaticamente i suoi overlay di controllo. App
che utilizzano un'interfaccia utente di un player personalizzato devono registrare visualizzazioni overlay restituendole da
AdViewProvider.getAdOverlayInfos
.
Per ulteriori informazioni sulle visualizzazioni in overlay, consulta Apri Measurement nell'SDK IMA.
Annunci companion
Alcuni tag annuncio contengono annunci companion aggiuntivi che possono essere mostrati in "slot" in un
UI dell'app. Questi slot possono essere trasmessi tramite
ImaAdsLoader.Builder.setCompanionAdSlots(slots)
. Per ulteriori informazioni, vedi
Aggiunta di annunci companion.
Annunci autonomi
L'SDK IMA è progettato per inserire annunci nei contenuti multimediali, non per la riproduzione singoli annunci autonomi. La riproduzione di annunci autonomi non è quindi supportata dalla libreria IMA. Ti consigliamo di utilizzare invece l'SDK Google Mobile Ads. per questo caso d'uso.
Utilizzare un SDK per gli annunci di terze parti
Se devi caricare annunci tramite un SDK per gli annunci di terze parti, vale la pena verificare se
fornisce già un'integrazione con ExoPlayer. In caso contrario, se implementi una richiesta
L'approccio consigliato è AdsLoader
che aggrega l'SDK per gli annunci di terze parti,
poiché offre i vantaggi di AdsMediaSource
descritti sopra.
ImaAdsLoader
funge da implementazione di esempio.
In alternativa, puoi utilizzare il supporto delle playlist di ExoPlayer per creare una sequenza di annunci e clip di contenuti:
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);
Inserimento di annunci lato server
Nell'inserimento di annunci lato server (chiamato anche inserimento di annunci dinamici o DAI), la lo stream multimediale include sia annunci che contenuti. Un manifest DASH può puntare a entrambi contenuti e segmenti di annunci, possibilmente in periodi distinti. Per HLS, vedi la sezione documentazione sull'incorporamento di annunci in una playlist.
Quando utilizza l'inserimento di annunci lato server, il cliente potrebbe dover risolvere URL dinamico per ottenere lo stream unito, potrebbe essere necessario visualizzare gli overlay degli annunci nell'interfaccia utente o potrebbe dover segnalare gli eventi a un ad SDK o ad server degli annunci.
DefaultMediaSourceFactory
di ExoPlayer può delegare tutte queste attività a un
inserimento di annunci lato server MediaSource
per gli URI che utilizzano lo schema 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();
libreria IMA di ExoPlayer
La libreria IMA di ExoPlayer fornisce ImaServerSideAdInsertionMediaSource
,
facilitando l'integrazione con gli stream di annunci inseriti lato server di IMA nel tuo
dell'app. Include le funzionalità dell'SDK IMA DAI per Android e
integra i metadati dell'annuncio forniti nel player. Ad esempio, questo consente
di utilizzare metodi come Player.isPlayingAd()
, ascoltare le transizioni contenuto-annuncio
e lasciare che sia il player a gestire la logica di riproduzione degli annunci, ad esempio saltando quelli già riprodotti.
Per utilizzare questo corso, devi configurare
ImaServerSideAdInsertionMediaSource.AdsLoader
e
ImaServerSideAdInsertionMediaSource.Factory
e collegalo al player:
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);
Carica la chiave asset IMA o l'ID origine di contenuto e l'ID video creando un URL
con 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));
Infine, rilascia il caricatore di annunci una volta che non viene più utilizzato:
Kotlin
adsLoader.release()
Java
adsLoader.release();
Considerazioni sull'interfaccia utente
Le stesse considerazioni relative all'interfaccia utente valide per l'inserimento di annunci lato client si applicano l'inserimento di annunci lato server.
Annunci companion
Alcuni tag annuncio contengono annunci companion aggiuntivi che possono essere mostrati in "slot" in un
UI dell'app. Questi slot possono essere trasmessi tramite
ImaServerSideAdInsertionMediaSource.AdsLoader.Builder.setCompanionAdSlots(slots)
.
Per ulteriori informazioni, consulta la sezione Aggiunta di annunci companion.
Utilizzare un SDK per gli annunci di terze parti
Se devi caricare annunci utilizzando un SDK per gli annunci di terze parti, vale la pena verificare
fornisce già un'integrazione con ExoPlayer. In caso contrario, ti consigliamo di
fornisci un valore MediaSource
personalizzato che accetta URI con lo schema ssai://
simile a ImaServerSideAdInsertionMediaSource
.
La logica effettiva di creazione della struttura degli annunci può essere delegata alla
lo scopo ServerSideAdInsertionMediaSource
, che aggrega uno stream MediaSource
e consente all'utente di impostare e aggiornare il AdPlaybackState
che rappresenta l'annuncio
metadati.
Spesso, gli stream di annunci inseriti lato server contengono eventi a tempo che inviano una notifica al player
sui metadati degli annunci. Consulta i formati supportati per informazioni su cosa
I formati di metadati con timestamp sono supportati da ExoPlayer. SDK per annunci personalizzati MediaSource
le implementazioni possono ascoltare gli eventi di metadati a tempo del player utilizzando
Player.Listener.onMetadata
.