ExoPlayer kann sowohl für die clientseitige als auch für die serverseitige Anzeigenbereitstellung verwendet werden.
Clientseitige Anzeigenbereitstellung
Bei der clientseitigen Anzeigenbereitstellung wechselt der Player zwischen dem Laden der Medien beim Wechsel zwischen Content und Anzeigen unterschiedliche URLs. Informationen werden getrennt vom Medium geladen, etwa aus einem XML-VAST-Code oder VMAP-Anzeigen-Tag Dabei kann es sich um Cue-Positionen in Relation zum Anfang des die eigentlichen URIs und Metadaten der Anzeigenmedien, z. B. ob eine bestimmte Anzeige überspringbar.
Wenn AdsMediaSource
von ExoPlayer für die clientseitige Anzeigenbereitstellung verwendet wird,
enthält Informationen zu den wiederzugebenden Anzeigen. Dies hat mehrere Vorteile:
- Der Player kann über seine API Metadaten und Funktionen für Anzeigen verfügbar machen.
- Mit ExoPlayer-UI-Komponenten können automatisch Markierungen für Anzeigenpositionen angezeigt werden. und ihr Verhalten ändern, je nachdem, ob die Anzeige wiedergegeben wird oder nicht.
- Intern kann der Player einen konsistenten Zwischenspeicher zwischen Übergängen Anzeigen und Content.
Dabei wechselt der Player zwischen Anzeigen und Content. bedeutet, dass Apps nicht mehrere separate Hintergrund-/Vordergrund-Playern für Anzeigen und Inhalte.
Wenn Sie Contentvideos und Anzeigen-Tags für die clientseitige Anzeigenbereitstellung vorbereiten, Anzeigen sollten idealerweise in Synchronisierungsbeispielen (Keyframes) im Content-Video an, damit der Player die Wiedergabe nahtlos fortsetzen kann.
Unterstützung deklarativer Anzeigen
Beim Erstellen eines MediaItem
kann ein Anzeigen-Tag-URI angegeben werden:
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();
Damit Mediaelemente, die Anzeigen-Tags enthalten, im Player unterstützt werden, müssen Sie
ein DefaultMediaSourceFactory
erstellen und einfügen, das mit einem
AdsLoader.Provider
und AdViewProvider
beim Erstellen des Players:
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();
Intern umschließt DefaultMediaSourceFactory
die Content-Medienquelle in einem
AdsMediaSource
. AdsMediaSource
erhält ein AdsLoader
aus dem
AdsLoader.Provider
und verwenden Sie es zum Einfügen von Anzeigen, die in der Anzeige des Medienelements definiert sind.
Tag.
PlayerView
von ExoPlayer implementiert AdViewProvider
. ExoPlayer-IMA
Bibliothek ein einfach zu verwendendes AdsLoader
zur Verfügung, wie unten beschrieben.
Playlists mit Werbung
Beim Abspielen einer Playlist mit mehreren Medienelementen ist das Standardverhalten: um für jede Media-ID das Anzeigen-Tag anzufordern und den Status der Anzeigenwiedergabe zu speichern, die Kombination aus Inhalts-URI und Anzeigen-Tag-URI. Nutzer sehen also Anzeigen für jedes Medienelement mit Anzeigen, die eine eigene Media-ID oder Content-URI haben, selbst wenn die Anzeigen-Tag-URIs übereinstimmen. Wenn ein Medienelement wiederholt wird, sieht der Nutzer das Element zugehörige Anzeigen nur einmal. Im Status der Anzeigenwiedergabe wird gespeichert, ob Anzeigen abgespielt werden, sodass sie beim ersten Mal übersprungen werden).
Sie können dieses Verhalten anpassen, indem Sie eine intransparente Anzeigen-ID übergeben. mit welchem Status der Anzeigenwiedergabe für ein bestimmtes Medienelement verknüpft ist, basierend auf dem Objekt und Gleichheit. Hier ist ein Beispiel, in dem der Status der Anzeigenwiedergabe mit dem Anzeigen-Tag verknüpft ist. und nicht die Kombination aus Media-ID und Anzeigen-Tag-URI, durch die und übergeben den URI des Anzeigen-Tags als Anzeigen-ID. Das hat zur Folge, dass die Anzeigen und der Nutzer sieht beim Abspielen des Videos Playlist von Anfang bis Ende.
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-Bibliothek
Die ExoPlayer IMA-Bibliothek bietet ImaAdsLoader
. Damit können Sie
Integrieren Sie die clientseitige Anzeigenbereitstellung in Ihre App. Sie umfasst die Funktionen
das clientseitige IMA SDK verwenden, um das Einfügen von VAST/VMAP-Anzeigen zu unterstützen. Für
Anleitungen zur Verwendung der Bibliothek, einschließlich zum Umgang mit Hintergrundwiedergabe
und die Fortsetzung der Wiedergabe finden Sie in der README-Datei.
Die Demoanwendung verwendet die IMA-Bibliothek und enthält mehrere VAST/VMAP-Anzeigen-Tags aus der Beispielliste.
Hinweise zur Benutzeroberfläche
PlayerView
blendet während der Wiedergabe von Anzeigen die Transportsteuerelemente aus, indem
Standardeinstellung, aber Apps können dieses Verhalten ändern, indem sie
setControllerHideDuringAds
. Mit dem IMA SDK werden zusätzliche Ansichten über
während eine Anzeige wiedergegeben wird (z. B. ein "Weitere Infos"-Link und eine Schaltfläche "Überspringen",
falls zutreffend).
Über das IMA SDK kann angegeben werden, ob Anzeigen durch von der Anwendung bereitgestellte Aufrufe verdeckt werden.
die über dem Player gerendert werden. Apps, die Ansichten einblenden müssen,
die für die Wiedergabe erforderlich sind,
müssen sie beim IMA SDK registriert werden,
können sie bei den
Sichtbarkeitsberechnungen weggelassen werden. Bei Verwendung von PlayerView
als
die AdViewProvider
enthält, werden automatisch ihre Kontroll-Overlays registriert. Apps
die eine benutzerdefinierte Player-Benutzeroberfläche verwenden,
müssen Overlay-Ansichten registrieren, indem sie
AdViewProvider.getAdOverlayInfos
Weitere Informationen zu Overlay-Ansichten finden Sie unter Open Measurement im IMA SDK
Companion-Anzeigen
Einige Anzeigen-Tags enthalten zusätzliche Companion-Anzeigen, die in Anzeigenflächen erscheinen können. in einem
in der App-Benutzeroberfläche. Diese Slots können über
ImaAdsLoader.Builder.setCompanionAdSlots(slots)
Weitere Informationen finden Sie unter
Companion-Anzeigen hinzufügen
Eigenständige Anzeigen
Das IMA SDK ist für das Einfügen von Anzeigen in Medieninhalte vorgesehen, nicht zum Abspielen von Anzeigen. als eigenständige Anzeigen. Daher wird die Wiedergabe von eigenständigen Anzeigen nicht unterstützt. der IMA-Bibliothek enthalten. Wir empfehlen, stattdessen das Google Mobile Ads SDK zu verwenden. für diesen Anwendungsfall.
Mit dem Anzeigen-SDK eines Drittanbieters
Wenn Sie Anzeigen über das Anzeigen-SDK eines Drittanbieters laden müssen, sollten Sie prüfen,
bereits eine ExoPlayer-Integration vorhanden ist. Falls nicht, implementieren Sie
Der empfohlene Ansatz ist AdsLoader
, der das Anzeigen-SDK des Drittanbieters umschließt.
da es die oben beschriebenen Vorteile von AdsMediaSource
bietet.
ImaAdsLoader
dient als Beispielimplementierung.
Alternativ kannst du die Playlist-Unterstützung von ExoPlayer nutzen, um eine Sequenz zu erstellen. von Anzeigen und Inhaltsclips:
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);
Serverseitige Anzeigenbereitstellung
Bei der serverseitigen Anzeigenbereitstellung, auch als dynamische Anzeigenbereitstellung bezeichnet, der Medienstream sowohl Anzeigen als auch Content enthält. Ein DASH-Manifest kann auf beides verweisen und Anzeigensegmente, möglicherweise in separaten Zeiträumen. Informationen zu HLS finden Sie in der Dokumentation zum Einbinden von Anzeigen in eine Playlist
Wenn Sie die serverseitige Anzeigenbereitstellung verwenden, muss der Client möglicherweise die Medien eine dynamische URL verwenden, um den Stitching-Stream zu erhalten, müssen möglicherweise Anzeigen-Overlays eingeblendet werden. oder Ereignisse an ein Anzeigen-SDK oder einen Ad-Server melden.
DefaultMediaSourceFactory
von ExoPlayer kann alle diese Aufgaben an einen
serverseitige Anzeigenbereitstellung MediaSource
für URIs mit dem 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();
ExoPlayer-IMA-Bibliothek
Die ExoPlayer-IMA-Bibliothek stellt ImaServerSideAdInsertionMediaSource
,
mit denen sich die Integration der serverseitig eingefügten
IMA-Anzeigen-Streams in Ihren
Sie umfasst die Funktionen des IMA DAI SDK für Android
integriert die bereitgestellten Anzeigenmetadaten in den Player. So können Sie z. B.
Sie können Methoden wie Player.isPlayingAd()
verwenden und Übergänge zwischen Inhalt und Anzeige beobachten.
und der Player die Logik der Anzeigenwiedergabe
wie das Überspringen bereits abgespielter Anzeigen verarbeitet.
Um diesen Kurs zu verwenden, müssen Sie den
ImaServerSideAdInsertionMediaSource.AdsLoader
und die
ImaServerSideAdInsertionMediaSource.Factory
und verbinde sie mit dem 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);
Laden Sie den IMA-Assetschlüssel oder die ID der Contentquelle und die Video-ID, indem Sie eine URL erstellen
mit 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));
Geben Sie zum Schluss das Anzeigenladeprogramm frei, sobald es nicht mehr verwendet wird:
Kotlin
adsLoader.release()
Java
adsLoader.release();
Hinweise zur Benutzeroberfläche
Es gelten dieselben Überlegungen zur Benutzeroberfläche wie bei der clientseitigen Anzeigenbereitstellung serverseitige Anzeigenbereitstellung.
Companion-Anzeigen
Einige Anzeigen-Tags enthalten zusätzliche Companion-Anzeigen, die in Anzeigenflächen erscheinen können. in einem
in der App-Benutzeroberfläche. Diese Slots können über
ImaServerSideAdInsertionMediaSource.AdsLoader.Builder.setCompanionAdSlots(slots)
Weitere Informationen finden Sie unter Companion-Anzeigen hinzufügen.
Mit dem Anzeigen-SDK eines Drittanbieters
Wenn Sie Anzeigen mit einem Drittanbieteranzeigen-SDK laden müssen, sollten Sie prüfen,
bereits eine ExoPlayer-Integration vorhanden ist. Falls nicht, sollten Sie
eine benutzerdefinierte MediaSource
angeben, die URIs mit dem Schema ssai://
akzeptiert
ähnlich wie ImaServerSideAdInsertionMediaSource
.
Die eigentliche Logik zur Erstellung der Anzeigenstruktur kann an den allgemeinen
Zweck ServerSideAdInsertionMediaSource
, der einen Stream MediaSource
umschließt
Der Nutzer kann die AdPlaybackState
für die Anzeige festlegen und aktualisieren.
Metadaten.
Häufig enthalten serverseitig eingefügte Anzeigen-Streams zeitlich festgelegte Ereignisse, um den Player zu benachrichtigen.
zu Anzeigenmetadaten. Unter Unterstützte Formate finden Sie Informationen dazu,
Formate für zeitgesteuerte Metadaten werden von ExoPlayer unterstützt. SDK für benutzerdefinierte Anzeigen MediaSource
-Implementierungen können zeitgesteuerte Metadaten-Ereignisse aus dem Player mithilfe von
Player.Listener.onMetadata
.