Les SDK IMA facilitent l'intégration d'annonces multimédias dans vos sites Web et applications. Les SDK IMA peuvent demander des annonces à partir de n'importe quel ad server compatible avec la norme VAST et gérer la lecture des annonces dans vos applications. Avec les SDK IMA DAI, les applications envoient une demande de flux pour des annonces et des contenus vidéo (VOD ou en direct). Le SDK renvoie ensuite un flux vidéo combiné pour vous éviter d'avoir à gérer le basculement entre l'annonce et la vidéo de contenu dans votre application.
Sélectionnez la solution d'insertion dynamique d'annonce qui vous intéresse
Insertion dynamique d'annonces à service complet
Ce guide explique comment intégrer le SDK IMA DAI dans une application de lecteur vidéo simple. Si vous souhaitez consulter ou suivre un exemple d'intégration complet, téléchargez BasicExample sur GitHub.
Présentation de l'insertion dynamique d'annonces IMA
Comme le montre ce guide, l'implémentation de l'IMA DAI implique quatre composants principaux du SDK:
StreamDisplayContainer
: objet de conteneur situé au-dessus de l'élément de lecture vidéo et hébergeant les éléments d'interface utilisateur de l'annonce.AdsLoader
: objet qui demande des flux et gère les événements déclenchés par des objets de réponse aux requêtes de flux. Vous ne devez instancier qu'un seul chargeur d'annonces, qui peut être réutilisé tout au long de la vie de l'application.StreamRequest
: objet qui définit une requête de flux. Les demandes de flux peuvent être pour des vidéos à la demande ou des diffusions en direct. Les requêtes spécifient un ID de contenu, ainsi qu'une clé API ou un jeton d'authentification, ainsi que d'autres paramètres.StreamManager
: objet qui gère les flux d'insertion d'annonces dynamiques et les interactions avec le backend d'insertion dynamique d'annonce. Le gestionnaire de flux gère également les pings de suivi, et transfère les événements de flux et d'annonce à l'éditeur.
Conditions préalables
- Android Studio
- Exemple d'application de lecteur vidéo pour l'intégration du SDK
Télécharger et exécuter l'application exemple de lecteur vidéo
L'application exemple fournit un lecteur vidéo fonctionnel qui lit une vidéo HLS. Utilisez-le comme point de départ pour intégrer les fonctionnalités d'insertion dynamique d'annonce du SDK IMA DAI.
Téléchargez l'exemple d'application de lecteur vidéo et extrayez-le.
Lancez Android Studio, puis sélectionnez Open an existing Android Studio project (Ouvrir un projet Android Studio existant). Si Android Studio est déjà en cours d'exécution, sélectionnez File > New > Import Project (Fichier > Nouveau > Importer un projet). Choisissez ensuite
SampleVideoPlayer/build.gradle
.Exécutez une synchronisation Gradle en sélectionnant Tools > Android > Sync Project with Gradle Files (Outils > Android > Synchroniser le projet avec les fichiers Gradle).
Assurez-vous que l'application du lecteur se compile et s'exécute sur un appareil Android physique ou un appareil virtuel Android en sélectionnant Run > Run 'app' (Exécuter > Exécuter l'application). Il est normal que le flux vidéo mette quelques instants à se charger avant de se lire.
Examiner l'exemple de lecteur vidéo
L'exemple de lecteur vidéo ne contient pas encore de code d'intégration du SDK IMA DAI. L'application exemple se compose de deux parties principales:
samplevideoplayer/SampleVideoPlayer.java
: lecteur HLS basé sur ExoPlayer qui sert de base pour l'intégration de l'insertion dynamique d'annonces dans IMA.videoplayerapp/MyActivity.java
: cette activité crée le lecteur vidéo, et le transmet àContext
etSimpleExoPlayerView
.
Ajouter le SDK IMA DAI à l'application Player
Vous devez également inclure une référence au SDK IMA DAI. Dans Android Studio, ajoutez le code suivant à votre fichier build.gradle
au niveau de l'application, situé dans app/build.gradle
:
repositories {
google()
mavenCentral()
}
dependencies {
implementation 'androidx.appcompat:appcompat:1.6.1'
implementation 'androidx.media3:media3-exoplayer:1.3.1'
implementation 'com.google.ads.interactivemedia.v3:interactivemedia:3.34.0'
}
Intégrer le SDK IMA DAI
Créez une classe appelée
SampleAdsWrapper
dans le packagevideoplayerapp
(dansapp/java/com.google.ads.interactivemedia.v3.samples/videoplayerapp/
) pour encapsuler leSampleVideoPlayer
existant et ajouter une logique d'implémentation de l'insertion dynamique d'annonces IMA. Pour ce faire, vous devez d'abord créer unAdsLoader
qui permet de demander des annonces aux ad servers.videoplayerapp/SampleAdsWrapper.java
package com.google.ads.interactivemedia.v3.samples.videoplayerapp; import android.annotation.TargetApi; import android.content.Context; import android.os.Build; import android.view.ViewGroup; import android.webkit.WebView; import com.google.ads.interactivemedia.v3.api.AdErrorEvent; import com.google.ads.interactivemedia.v3.api.AdEvent; import com.google.ads.interactivemedia.v3.api.AdsLoader; import com.google.ads.interactivemedia.v3.api.AdsManagerLoadedEvent; import com.google.ads.interactivemedia.v3.api.CuePoint; import com.google.ads.interactivemedia.v3.api.ImaSdkFactory; import com.google.ads.interactivemedia.v3.api.ImaSdkSettings; import com.google.ads.interactivemedia.v3.api.StreamDisplayContainer; import com.google.ads.interactivemedia.v3.api.StreamManager; import com.google.ads.interactivemedia.v3.api.StreamRequest; import com.google.ads.interactivemedia.v3.api.player.VideoProgressUpdate; import com.google.ads.interactivemedia.v3.api.player.VideoStreamPlayer; import com.google.ads.interactivemedia.v3.samples.samplevideoplayer.SampleVideoPlayer; import java.util.ArrayList; import java.util.HashMap; import java.util.List; public class SampleAdsWrapper implements AdEvent.AdEventListener, AdErrorEvent.AdErrorListener, AdsLoader.AdsLoadedListener { // Livestream asset key. private static final String TEST_ASSET_KEY = "sN_IYUG8STe1ZzhIIE_ksA"; // VOD content source and video IDs. private static final String TEST_CONTENT_SOURCE_ID = "2548831"; private static final String TEST_VIDEO_ID = "tears-of-steel"; private static final String PLAYER_TYPE = "DAISamplePlayer"; /** * Log interface, so you can output the log commands to the UI or similar. */ public interface Logger { void log(String logMessage); } private ImaSdkFactory sdkFactory; private AdsLoader adsLoader; private StreamDisplayContainer displayContainer; private StreamManager streamManager; private List<VideoStreamPlayer.VideoStreamPlayerCallback> playerCallbacks; private SampleVideoPlayer videoPlayer; private Context context; private ViewGroup adUiContainer; private String fallbackUrl; private Logger logger; public SampleAdsWrapper(Context context, SampleVideoPlayer videoPlayer, ViewGroup adUiContainer) { this.videoPlayer = videoPlayer; this.context = context; this.adUiContainer = adUiContainer; sdkFactory = ImaSdkFactory.getInstance(); playerCallbacks = new ArrayList<>(); createAdsLoader(); displayContainer = sdkFactory.createStreamDisplayContainer( this.adUiContainer, videoStreamPlayer ); } private void createAdsLoader() { ImaSdkSettings settings = new ImaSdkSettings(); adsLoader = sdkFactory.createAdsLoader(context); } public void requestAndPlayAds() { adsLoader.addAdErrorListener(this); adsLoader.addAdsLoadedListener(this); adsLoader.requestStream(buildStreamRequest()); } }
Ajoutez une méthode
buildStreamRequest()
àAdsLoader
pour qu'il puisse demander un flux avec des annonces. Il s'agit d'une diffusion en direct avec des annonces (définie par défaut) ou d'un flux de vidéo à la demande(VOD) qui lit du contenu préenregistré avec des annonces. Pour activer le flux de vidéo à la demande, mettez en commentaire la requête de diffusion en direct et annulez la mise en commentaire.Pour utiliser l'insertion dynamique d'annonce, le joueur doit transmettre les événements ID3 des diffusions en direct aux SDK IMA pour l'insertion dynamique d'annonce. Dans l'exemple de code suivant, cette opération est effectuée par la méthode
callback.onUserTextReceived()
.videoplayerapp/SampleAdsWrapper.java
private StreamRequest buildStreamRequest() { VideoStreamPlayer videoStreamPlayer = createVideoStreamPlayer(); videoPlayer.setSampleVideoPlayerCallback( new SampleVideoPlayer.SampleVideoPlayerCallback() { @Override public void onUserTextReceived(String userText) { for (VideoStreamPlayer.VideoStreamPlayerCallback callback : playerCallbacks) { callback.onUserTextReceived(userText); } } @Override public void onSeek(int windowIndex, long positionMs) { // See if you would seek past an ad, and if so, jump back to it. long newSeekPositionMs = positionMs; if (streamManager != null) { CuePoint prevCuePoint = streamManager.getPreviousCuePointForStreamTime(positionMs / 1000); if (prevCuePoint != null && !prevCuePoint.isPlayed()) { newSeekPositionMs = (long) (prevCuePoint.getStartTime() * 1000); } } videoPlayer.seekTo(windowIndex, newSeekPositionMs); } @Override public void onContentComplete() { for (VideoStreamPlayer.VideoStreamPlayerCallback callback : playerCallbacks) { callback.onContentComplete(); } } @Override public void onPause() { for (VideoStreamPlayer.VideoStreamPlayerCallback callback : playerCallbacks) { callback.onPause(); } } @Override public void onResume() { for (VideoStreamPlayer.VideoStreamPlayerCallback callback : playerCallbacks) { callback.onResume(); } } @Override public void onVolumeChanged(int percentage) { for (VideoStreamPlayer.VideoStreamPlayerCallback callback : playerCallbacks) { callback.onVolumeChanged(percentage); } } }); // Livestream request. StreamRequest request = sdkFactory.createLiveStreamRequest( TEST_ASSET_KEY, null, displayContainer); // VOD request. Comment the createLiveStreamRequest() line above and uncomment this // createVodStreamRequest() below to switch from a livestream to a VOD stream. // StreamRequest request = sdkFactory.createVodStreamRequest(TEST_CONTENT_SOURCE_ID, // TEST_VIDEO_ID, null, displayContainer); return request; }
Vous avez également besoin d'un
VideoStreamPlayer
pour lire le flux. Vous devez donc ajouter une méthodecreateVideoStreamPlayer()
, qui crée une classe anonyme qui implémenteVideoStreamPlayer
.videoplayerapp/SampleAdsWrapper.java
private VideoStreamPlayer createVideoStreamPlayer() { VideoStreamPlayer player = new VideoStreamPlayer() { @Override public void loadUrl(String url, List<HashMap<String, String>> subtitles) { videoPlayer.setStreamUrl(url); videoPlayer.play(); } @Override public void addCallback( VideoStreamPlayerCallback videoStreamPlayerCallback) { playerCallbacks.add(videoStreamPlayerCallback); } @Override public void removeCallback( VideoStreamPlayerCallback videoStreamPlayerCallback) { playerCallbacks.remove(videoStreamPlayerCallback); } @Override public void onAdBreakStarted() { // Disable player controls. videoPlayer.enableControls(false); log("Ad Break Started\n"); } @Override public void onAdBreakEnded() { // Re-enable player controls. videoPlayer.enableControls(true); log("Ad Break Ended\n"); } @Override public VideoProgressUpdate getContentProgress() { return new VideoProgressUpdate(videoPlayer.getCurrentPosition(), videoPlayer.getDuration()); } @Override public int getVolume() { return videoPlayer.getVolume(); } }; return player; }
Implémentez les écouteurs requis et ajoutez la prise en charge de la gestion des erreurs.
Notez l'implémentation de
AdErrorListener
, car elle appelle une URL de remplacement si la lecture des annonces échoue. Le contenu et les annonces étant dans un seul flux, vous devez être prêt à appeler un flux de remplacement si le flux d'insertion dynamique d'annonce rencontre une erreur.videoplayerapp/SampleAdsWrapper.java
/** AdErrorListener implementation **/ @Override public void onAdError(AdErrorEvent event) { // play fallback URL. videoPlayer.setStreamUrl(fallbackUrl); videoPlayer.enableControls(true); videoPlayer.play(); } /** AdEventListener implementation **/ @Override public void onAdEvent(AdEvent event) { switch (event.getType()) { case AD_PROGRESS: // Do nothing or else log are filled by these messages. break; default: log(String.format("Event: %s\n", event.getType())); break; } } /** AdsLoadedListener implementation **/ @Override public void onAdsManagerLoaded(AdsManagerLoadedEvent event) { streamManager = event.getStreamManager(); streamManager.addAdErrorListener(this); streamManager.addAdEventListener(this); streamManager.init(); } /** Sets fallback URL in case ads stream fails. **/ void setFallbackUrl(String url) { fallbackUrl = url; }
Ajoutez du code pour la journalisation.
videoplayerapp/SampleAdsWrapper.java
/** Sets logger for displaying events to screen. Optional. **/ void setLogger(Logger logger) { this.logger = logger; } private void log(String message) { if (logger != null) { logger.log(message); } }
Modifiez
MyActivity
dansvideoplayerapp
pour instancier et appelerSampleAdsWrapper
.videoplayerapp/MyActivity.java
import android.view.ViewGroup; import android.widget.ScrollView; ... public class MyActivity extends AppCompatActivity { ... @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_my); View rootView = findViewById(R.id.videoLayout); videoPlayer = new SampleVideoPlayer(rootView.getContext(), (SimpleExoPlayerView) rootView.findViewById(R.id.playerView)); videoPlayer.enableControls(false); final SampleAdsWrapper sampleAdsWrapper = new SampleAdsWrapper(this, videoPlayer, (ViewGroup) rootView.findViewById(R.id.adUiContainer)); sampleAdsWrapper.setFallbackUrl(DEFAULT_STREAM_URL); final ScrollView scrollView = (ScrollView) findViewById(R.id.logScroll); final TextView textView = (TextView) findViewById(R.id.logText); sampleAdsWrapper.setLogger(new SampleAdsWrapper.Logger() { @Override public void log(String logMessage) { Log.i(APP_LOG_TAG, logMessage); if (textView != null) { textView.append(logMessage); } if (scrollView != null) { scrollView.post(new Runnable() { @Override public void run() { scrollView.fullScroll(View.FOCUS_DOWN); } }); } } }); playButton = (ImageButton) rootView.findViewById(R.id.playButton); // Set up play button listener to play video then hide play button. playButton.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { sampleAdsWrapper.requestAndPlayAds(); playButton.setVisibility(View.GONE); } }); } ... }
Modifiez le fichier de mise en page
activity_my.xml
de l'activité pour ajouter des éléments d'interface utilisateur pour la journalisation.res/layout/activity_my.xml
... <TextView android:id="@+id/playerDescription" android:text="@string/video_description" android:textAlignment="center" android:gravity="center_horizontal" android:layout_width="match_parent" android:layout_height="0dp" android:layout_weight="0.1" android:textSize="@dimen/font_size" /> <!-- UI element for viewing SDK event log --> <ScrollView android:id="@+id/logScroll" android:layout_width="match_parent" android:layout_height="0dp" android:layout_weight="0.5" android:padding="5dp" android:background="#DDDDDD"> <TextView android:id="@+id/logText" android:layout_width="match_parent" android:layout_height="wrap_content"> </TextView> </ScrollView> ...
Félicitations ! Vous demandez et affichez maintenant des annonces vidéo dans votre application Android. Pour affiner votre implémentation, consultez les pages Favoris, Snapback et la documentation de l'API.
Dépannage
Si vous rencontrez des problèmes lors de la lecture d'une annonce vidéo, essayez de télécharger la version complète de BasicExample. Si cela fonctionne correctement dans l'exemple de base, il y a probablement un problème avec le code d'intégration IMA de votre application.
Si le problème persiste, consultez le forum sur le SDK IMA.