Pierwsze kroki z pakietem IMA DAI SDK

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.

  1. Pobierz przykładową aplikację odtwarzacza wideo i rozpakuj ją.
  2. 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.
  3. Uruchom synchronizację Gradle, wybierając Narzędzia > Android > Synchronizuj projekt z plikami Gradle.
  4. 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ści Context oraz SimpleExoPlayerView.

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'
}

Punkt kontrolny: aplikacja powinna się skompilować i uruchomić, ale nie zawiera jeszcze żadnych elementów interfejsu ani kodu umożliwiającego wysyłanie żądań i wyświetlanie reklam.

Integracja pakietu IMA SDK

  1. Utwórz nową klasę o nazwie SampleAdsWrapper w pakiecie videoplayerapp (w app/java/com.google.ads.interactivemedia.v3.samples/videoplayerapp/), aby opakować istniejący SampleVideoPlayer 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());
        }
    }
              
  2. 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;
    }
    
  3. 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;
    }
    
  4. Zaimplementuj wymagane detektory i dodaj obsługę obsługi błędów.

    Ważne: pamiętaj o implementacji tagu AdErrorListener, 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;
    }
    
  5. 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);
        }
    }
    
  6. Zmodyfikuj MyActivity w videoplayerapp, 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);
                }
            });
        }
    …
    }
  7. 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.