Mit IMA SDKs können Sie Multimedia-Anzeigen ganz einfach in Ihre Websites und Apps einbinden. IMA SDKs können Anzeigen von jedem VAST-kompatiblen Ad-Server anfordern und die Anzeigenwiedergabe in Ihren Apps verwalten. Mit IMA-SDKs für die dynamische Anzeigenbereitstellung stellen Apps eine Streamanfrage für Anzeigen- und Contentvideos – VOD- oder Livecontent. Das SDK gibt dann einen kombinierten Videostream zurück, damit Sie nicht mehr zwischen Anzeigen- und Contentvideos in Ihrer App wechseln müssen.
In diesem Leitfaden wird gezeigt, wie Sie das IMA SDK in eine einfache Videoplayer-App einbinden. Wenn Sie sich eine abgeschlossene Beispielintegration ansehen oder sie verfolgen möchten, laden Sie das BasicExample von GitHub herunter.
IMA-Plattform für die dynamische Anzeigenbereitstellung
Die Implementierung der IMA DAI umfasst vier SDK-Hauptkomponenten:
StreamDisplayContainer
: Ein Containerobjekt, das über dem Videowiedergabeelement platziert ist und die UI-Elemente der Anzeige enthält.AdsLoader
: Ein Objekt, das Streams anfordert und Ereignisse verarbeitet, die von Antwortobjekten für Streamanfragen ausgelöst werden. Sie sollten nur einen Anzeigen-Loader instanziieren, der während der gesamten Lebensdauer der Anwendung wiederverwendet werden kann.StreamRequest
: Ein Objekt, das eine Streamanfrage definiert. Streamanfragen können für Video-on-Demand- oder Livestreams erfolgen. Anfragen geben eine Content-ID sowie einen API-Schlüssel oder ein Authentifizierungstoken und andere Parameter an.StreamManager
: Ein Objekt, das dynamische Anzeigenbereitstellungsstreams und Interaktionen mit dem Back-End für die dynamische Anzeigenbereitstellung verarbeitet. Der Stream-Manager verarbeitet außerdem Tracking-Pings und leitet Stream- und Anzeigenereignisse an den Publisher weiter.
Voraussetzungen
- Android Studio
- Die Beispiel-Videoplayer-App, mit der Sie das SDK einbinden
Beispiel-Videoplayer-App herunterladen und ausführen
Die Beispiel-App bietet einen funktionierenden Videoplayer, der HLS-Videos wiedergibt. Nutzen Sie dies als Ausgangspunkt für die Integration der dynamischen Anzeigenbereitstellung des IMA Android SDKs.
- Lade die Beispiel-Videoplayer-App herunter und entpacke sie.
- Starten Sie Android Studio und wählen Sie Open an existing Android Studio project aus. Falls Android Studio bereits ausgeführt wird, wählen Sie Datei > Neu > Projekt importieren aus. Wählen Sie dann
SampleVideoPlayer/build.gradle
aus. - Wählen Sie Tools > Android > Projekt mit Gradle-Dateien synchronisieren aus, um eine Gradle-Synchronisierung auszuführen.
- Prüfe, ob die Player-App auf einem physischen Android-Gerät oder einem virtuellen Android-Gerät über Run > Run 'app' kompiliert und ausgeführt wird. Es dauert nicht lange, bis der Videostream geladen ist, bevor er abgespielt werden kann.
Beispiel-Videoplayer untersuchen
Der Beispielvideoplayer enthält noch keinen IMA SDK-Integrationscode. Die Beispielanwendung besteht aus zwei Hauptteilen:
samplevideoplayer/SampleVideoPlayer.java
: Ein einfacher HLS-Player, der auf ExoPlayer basiert und als Basis für die IMA-Integration mit der dynamischen Anzeigenbereitstellung dient.videoplayerapp/MyActivity.java
: Bei dieser Aktivität wird der Videoplayer erstellt undContext
undSimpleExoPlayerView
übergeben.
IMA SDK für Android zur Player-App hinzufügen
Außerdem muss ein Verweis auf das IMA SDK angegeben werden. Fügen Sie in Android Studio der Datei build.gradle
auf Anwendungsebene unter app/build.gradle
Folgendes hinzu:
repositories { google() jcenter() } dependencies { implementation 'androidx.appcompat:appcompat:1.2.0' implementation 'androidx.browser:browser:1.3.0' implementation 'com.google.android.exoplayer:exoplayer:2.18.1' implementation 'com.google.ads.interactivemedia.v3:interactivemedia:3.29.0' }
IMA SDK einbinden
-
Erstellen Sie eine neue Klasse mit dem Namen
SampleAdsWrapper
im Paketvideoplayerapp
(inapp/java/com.google.ads.interactivemedia.v3.samples/videoplayerapp/
), um den vorhandenenSampleVideoPlayer
-Wrapper einzuschließen und die Logik zur Implementierung der dynamischen Anzeigenbereitstellung von IMA hinzuzufügen. Dazu müssen Sie zuerst einenAdsLoader
erstellen, mit dem Anzeigen von Ad-Servern angefordert werden.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 { // Live stream 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 = "2528370"; 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()); } }
-
Fügen Sie eine Methode
buildStreamRequest()
zuAdsLoader
hinzu, damit ein Stream mit Anzeigen angefordert werden kann. Das ist entweder ein Livestream mit Anzeigen (Standardeinstellung) oder ein Video-on-Demand(VOD)-Stream, in dem vorab aufgezeichnete Inhalte mit Anzeigen wiedergegeben werden. Um den VOD-Stream zu aktivieren, kommentieren Sie die Anfrage für den Livestream aus und entfernen sie die Kommentarzeichen.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); } } }); // Live stream 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 live stream to a VOD stream. // StreamRequest request = sdkFactory.createVodStreamRequest(TEST_CONTENT_SOURCE_ID, // TEST_VIDEO_ID, null, displayContainer); return request; }
-
Sie benötigen außerdem eine
VideoStreamPlayer
, um den Stream wiederzugeben. Fügen Sie einecreateVideoStreamPlayer()
-Methode hinzu, die eine anonyme Klasse erstellt, dieVideoStreamPlayer
implementiert.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()); } }; return player; }
-
Implementieren Sie die erforderlichen Listener und fügen Sie Unterstützung für die Fehlerbehandlung hinzu.
Wichtig: Beachte, dass die Implementierung vonAdErrorListener
eine Fallback-URL ist, wenn die Anzeigen nicht wiedergegeben werden können. Da sich der Content und die Anzeigen in einem Stream befinden, müssen Sie für den Aufruf eines Fallback-Streams bereit sein, wenn ein Fehler beim Stream für die dynamische Anzeigenbereitstellung auftritt.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; }
-
Fügen Sie Code für die Protokollierung hinzu.
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); } }
- Ändern Sie
MyActivity
invideoplayerapp
, um zu instanziieren undSampleAdsWrapper
aufzurufen.videoplayerapp/MeineAktivitäten.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); } }); } … }
- Ändern Sie die Layoutdatei
activity_my.xml
der Aktivität, um UI-Elemente für das Logging hinzuzufügen.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> …
Herzlichen Glückwunsch – Sie fordern jetzt Videoanzeigen in Ihrer Android-App an und blenden sie ein. Informationen zur Feinabstimmung der Implementierung finden Sie in den Leitfäden für Lesezeichen und Snapback sowie in der API-Dokumentation.
Fehlerbehebung
Wenn bei der Wiedergabe von Videoanzeigen Probleme auftreten, laden Sie das ausgefüllte BasicExample-Objekt herunter. Wenn es im Basic-Beispiel richtig funktioniert, liegt wahrscheinlich ein Problem mit dem IMA-Integrationscode Ihrer App vor. Lesen Sie diesen Leitfaden und die API-Dokumentation, um Abweichungen zu erkennen.
Es gibt weiterhin Probleme? Dann nutzen Sie das IMA SDK-Forum.