Pakiety IMA SDK ułatwiają integrację reklam multimedialnych w witrynach i aplikacjach. Pakiety IMA SDK mogą żądać reklam z dowolnego serwera reklam zgodnego z VAST i zarządzać odtwarzaniem reklam w aplikacjach. W przypadku pakietów IMA DAI SDK aplikacje wysyłają żądania strumienia reklam i treści wideo – VOD lub na żywo. SDK będzie wtedy wyświetlać obraz z połączonych strumieni wideo, dzięki czemu nie będzie trzeba przełączać się między reklamami i treściami wideo w aplikacji.
Z tego przewodnika dowiesz się, jak zintegrować pakiet IMA SDK z prostą aplikacją do odtwarzaczy wideo. Jeśli chcesz obejrzeć lub wykonać przykładową integrację, pobierz BasicExample z GitHuba.
Omówienie DAI DAI
Implementacja IMA DAI obejmuje 4 główne komponenty pakietu SDK, które omówiliśmy w tym przewodniku:
StreamDisplayContainer
: obiekt kontenera umieszczony nad elementem odtwarzania wideo i zawierający elementy interfejsu reklamy.AdsLoader
: obiekt, który wysyła żądania strumieni i obsługuje zdarzenia wywoływane przez obiekty odpowiedzi na żądanie strumienia. Trzeba utworzyć tylko jeden program wczytujący reklamy, którego można używać wielokrotnie w trakcie działania aplikacji.StreamRequest
: obiekt definiujący żądanie strumienia, Żądania strumieni mogą obejmować żądania wideo lub transmisje na żywo. Żądania określają identyfikator treści, klucz interfejsu API lub token uwierzytelniania i inne parametry.StreamManager
: obiekt obsługujący strumienie reklam dynamicznych i interakcje z backendem DAI. Menedżer strumieniowania obsługuje też pingi śledzenia i przekazuje wydawcy oraz zdarzenia strumienia i reklamy.
Wymagania wstępne
- Android Studio
- przykładowa aplikacja do odtwarzania filmów, która posłuży do integracji pakietu SDK.
Pobieranie i uruchamianie przykładowej aplikacji odtwarzacza wideo
Przykładowa aplikacja zawiera działający odtwarzacz, który odtwarza wideo HLS. Użyj go jako punktu wyjścia do integracji funkcji DAI w pakiecie IMA Android SDK.
- Pobierz przykładową aplikację odtwarzacza wideo i rozpakuj ją.
- Uruchom Android Studio i wybierz Otwórz istniejący projekt Android Studio. Jeśli Android Studio jest już uruchomiony, kliknij Plik > Nowy > Importuj projekt. Następnie wybierz
SampleVideoPlayer/build.gradle
. - Uruchom synchronizację Gradle, wybierając Narzędzia > Android > Synchronizuj projekt z plikami Gradle.
- Upewnij się, że aplikacja odtwarzacza skompiluje i uruchomi się na urządzeniu z Androidem lub wirtualnym urządzeniu z Androidem za pomocą opcji Uruchom > Uruchom „aplikacja”. To normalne, że zanim strumień wideo zacznie się wczytywać, może minąć kilka chwil.
Sprawdzanie przykładowego odtwarzacza
Przykładowy odtwarzacz wideo nie zawiera jeszcze żadnego kodu integracji IMA SDK. Przykładowa aplikacja składa się z 2 głównych części:
samplevideoplayer/SampleVideoPlayer.java
– prosty odtwarzacz HLS oparty na ExoPlayer, który jest podstawą do integracji DAI DAI.videoplayerapp/MyActivity.java
– ta aktywność tworzy odtwarzacz wideo i przekazuje mu właściwościContext
orazSimpleExoPlayerView
.
Dodaj pakiet IMA SDK do aplikacji odtwarzacza
Musisz też uwzględnić odwołanie do pakietu IMA SDK. W Android Studio dodaj do pliku build.gradle
na poziomie aplikacji ten fragment app/build.gradle
:
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.19.0' implementation 'com.google.ads.interactivemedia.v3:interactivemedia:3.31.0' }
Integracja pakietu IMA SDK
-
Utwórz nową klasę o nazwie
SampleAdsWrapper
w pakiecievideoplayerapp
(wapp/java/com.google.ads.interactivemedia.v3.samples/videoplayerapp/
), aby opakować istniejącySampleVideoPlayer
i dodać logikę implementacji dynamicznego wstawiania reklam DAI (DAI). Aby to zrobić, musisz najpierw utworzyć tabelęAdsLoader
, która będzie używana do wysyłania żądań reklam z serwerów reklam.aplikacjawideo/przykładowareklamaWrapper.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()); } }
-
Dodaj do metody
AdsLoader
metodębuildStreamRequest()
, by umożliwić żądanie strumienia z reklamami. Jest to transmisja na żywo z reklamami (ustawienie domyślne) lub wideo na żądanie, która odtwarza nagrane wcześniej reklamy z wykorzystaniem reklam. Aby włączyć strumień VOD, dodaj komentarz do żądania transmisji na żywo i usuń znacznik komentarza do żądania strumienia VOD.aplikacjawideo/przykładowareklamaWrapper.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; }
-
Do odtworzenia strumienia potrzebujesz też
VideoStreamPlayer
, więc dodaj metodęcreateVideoStreamPlayer()
, która tworzy anonimową klasę implementującąVideoStreamPlayer
.aplikacjawideo/przykładowareklamaWrapper.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; }
-
Zaimplementuj wymagane detektory i dodaj obsługę obsługi błędów.
Ważne: pamiętaj o implementacji taguAdErrorListener
, ponieważ wywołuje on zastępczy URL, jeśli nie uda się odtworzyć reklamy. Ponieważ treści i reklamy są w jednym strumieniu, w przypadku wystąpienia strumienia z dynamicznym wstawianiem reklam musisz przygotować wywołanie awaryjne.aplikacjawideo/przykładowareklamaWrapper.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; }
-
Dodaj kod logowania.
aplikacjawideo/przykładowareklamaWrapper.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); } }
- Zmodyfikuj
MyActivity
wvideoplayerapp
, aby utworzyć instancję i wywołać metodęSampleAdsWrapper
.aplikacjawideoodtwarzacza/aktywność.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); } }); } … }
- Zmodyfikuj plik układu działania
activity_my.xml
, aby dodać elementy interfejsu do logowania.res/layout/aktywność_moja.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> …
Świetnie! Prosisz o wyświetlanie reklam wideo w swojej aplikacji na Androida. Aby dostosować implementację, przeczytaj przewodniki dotyczące zakładek i wycofywania oraz dokumentację interfejsu API.
Rozwiązywanie problemów
Jeśli masz problemy z odtworzeniem reklamy wideo, spróbuj pobrać Podstawowy przykład. Jeśli w podstawowym przykładzie działa ona prawidłowo, prawdopodobnie wystąpił problem z kodem integracji IMA aplikacji. Zapoznaj się z tym przewodnikiem oraz z dokumentacją interfejsu API, aby wykrywać wszelkie rozbieżności.
Nadal masz problem? Napisz na forum IMA SDK.