Pakiety IMA SDK ułatwiają integrację reklam multimedialnych z witrynami i aplikacjami. Pakiety IMA SDK mogą żądać reklam z dowolnego serwera reklam zgodnego z VAST i zarządzać odtwarzaniem reklam w aplikacjach. Dzięki pakietom IMA DAI SDK aplikacje wysyłają żądanie strumienia reklamy i treści wideo (VOD lub treści na żywo). Pakiet SDK zwraca połączony strumień wideo, dzięki czemu nie musisz zarządzać przełączaniem się między reklamą a filmem z treściami w aplikacji.
Wybierz interesujące Cię rozwiązanie DAI
Pełna obsługa DAI
Ten przewodnik pokazuje, jak zintegrować pakiet IMA DAI SDK z prostym odtwarzaczem. Jeśli chcesz zobaczyć lub prześledzić przykładową integrację, pobierz BasicExample z GitHub.
Omówienie IMA DAI
Wdrożenie interfejsu IMA DAI wymaga 4 głównych komponentów pakietu SDK, jak opisano w tym przewodniku:
StreamDisplayContainer
: obiekt kontenera, który znajduje się nad elementem odtwarzania filmu i zawiera elementy interfejsu reklamy.AdsLoader
: Obiekt, który żąda strumieni i obsługuje zdarzenia wywołane przez obiekty odpowiedzi żądania strumienia. Należy utworzyć tylko 1 ładowarkę reklam, którą można ponownie wykorzystać w trakcie działania aplikacji.StreamRequest
: obiekt definiujący żądanie strumienia. Żądania strumieni mogą dotyczyć filmów na żądanie lub transmisji na żywo. Żądania zawierają identyfikator treści, a także klucz interfejsu API lub token uwierzytelniający oraz inne parametry.StreamManager
: obiekt, który obsługuje strumienie dynamicznego wstawiania reklam i interakcje z backendem DAI. Menedżer strumienia obsługuje też pingi śledzenia i przekazuje wydawcy zdarzenia związane z reklamą i strumieniem.
Wymagania wstępne
- Android Studio
- Przykładowa aplikacja odtwarzacza wideo do integracji z pakietem SDK
Pobieranie i uruchamianie przykładowej aplikacji odtwarzacza filmów
Przykładowa aplikacja zawiera działający odtwarzacz wideo, który odtwarza filmy HLS. Użyj tego jako punktu wyjścia do integracji funkcji DAI pakietu IMA DAI SDK.
Pobierz przykładową aplikację odtwarzacza filmów i wyodrębnij ją.
Uruchom Android Studio i kliknij Otwórz istniejący projekt Android Studio. Jeśli Android Studio jest już uruchomione, kliknij Plik > Nowy > Importuj projekt. Następnie kliknij
SampleVideoPlayer/build.gradle
.Aby zsynchronizować Gradle, wybierz Narzędzia > Android > Synchronizuj projekt z plikami Gradle.
Upewnij się, że aplikacja odtwarzacza jest skompilowana i działa na fizycznym urządzeniu z Androidem lub na urządzeniu wirtualnym Android za pomocą opcji Uruchom > Uruchom „aplikację”. Wczytywanie strumienia wideo może chwilę potrwać.
Sprawdzanie przykładowego odtwarzacza
Przykładowy odtwarzacz wideo nie zawiera jeszcze kodu integracji IMA DAI SDK. Przykładowa aplikacja składa się z 2 głównych części:
samplevideoplayer/SampleVideoPlayer.java
: odtwarzacz HLS oparty na ExoPlayer, który stanowi podstawę integracji IMA DAI.videoplayerapp/MyActivity.java
: ta aktywność tworzy odtwarzacz wideo i przekazuje mu wartościContext
iSimpleExoPlayerView
.
Dodaj pakiet IMA DAI SDK do aplikacji odtwarzacza
Musisz też dołączyć odwołanie do pakietu IMA DAI SDK. W Android Studio dodaj te informacje do pliku build.gradle
na poziomie aplikacji, który znajduje się w folderze 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.35.1'
}
Integracja pakietu IMA DAI SDK
Utwórz nową klasę o nazwie
SampleAdsWrapper
w pakiecievideoplayerapp
(w plikuapp/java/com.google.ads.interactivemedia.v3.samples/videoplayerapp/
), aby owijać istniejący elementSampleVideoPlayer
oraz dodawać logikę implementującą interfejs DAI IMA. Aby to zrobić, musisz najpierw utworzyćAdsLoader
, który służy do wysyłania żądań reklam do serwerów reklam.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()); } }
Dodaj do
AdsLoader
metodębuildStreamRequest()
, aby mogła poprosić o strumień z reklamami. Może to być transmisja na żywo z reklamami (domyślnie) lub strumień wideo na żądanie(VOD) z reklamami odtwarzającymi wcześniej nagrane treści. Aby włączyć strumień VOD, skomentuj żądanie transmisji na żywo i odkomentuj żądanie strumienia VOD.Aby współpracować z DAI, odtwarzacz musi przekazywać zdarzenia ID3 dotyczące transmisji na żywo do IMA DAI SDK. W poniższym przykładowym kodzie jest to realizowane za pomocą metody
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; }
Do odtwarzania strumienia potrzebny jest też obiekt
VideoStreamPlayer
, więc dodaj metodęcreateVideoStreamPlayer()
, która tworzy anonimową klasę implementującą interfejsVideoStreamPlayer
.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; }
Wdrożyć wymagane odbiorniki i dodać obsługę błędów.
Zwróć uwagę na implementację
AdErrorListener
, ponieważ wywołuje ona adres URL zapasowy, jeśli reklamy nie mogą się wyświetlić. Treści i reklamy znajdują się w jednym strumieniu, więc musisz być gotowy do wywołania strumienia zapasowego, jeśli strumień DAI napotka błąd.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; }
Dodaj kod do rejestrowania.
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); } }
Zmień
MyActivity
wvideoplayerapp
, aby utworzyć instancję i wywołać funkcjęSampleAdsWrapper
.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); } }); } ... }
Zmień plik układu aktywności
activity_my.xml
, aby dodać elementy interfejsu użytkownika do logowania.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> ...
Gratulacje! Reklamy wideo są teraz żądane i wyświetlane w Twojej aplikacji na Androida. Aby dostosować implementację, zapoznaj się z funkcjami Zakładki i Snapback oraz z dokumentacją API.
Rozwiązywanie problemów
Jeśli masz problemy z odtwarzaniem reklamy wideo, pobierz gotowy projekt BasicExample. Jeśli w przykładzie podstawowym wszystko działa prawidłowo, prawdopodobnie wystąpił problem z kodem integracji IMA Twojej aplikacji.
Jeśli nadal masz problemy, odwiedź forum IMA SDK.