Niestandardowe odtwarzanie reklam za pomocą pakietu IMA SDK na Androida

Najszybszym i najprostszym sposobem na zintegrowanie pakietu IMA SDK na Androida z aplikacją jest przekazanie przez pakiet SDK całej logiki odtwarzania reklam, podczas gdy aplikacja skupia się na odtwarzaniu treści wideo. To podejście, zwane „odtwarzaniem reklam przez pakiet SDK”, jest opcją domyślną na stronie Pierwsze kroki.

Jeśli jednak chcesz wyświetlać reklamy także w odtwarzaczu, pakiet SDK zapewnia odpowiedni interfejs. Takie podejście nazywamy „odtwarzaniem reklamy niestandardowych”. W pozostałej części tego przewodnika dowiesz się, jak to zrobić.

Wymagania wstępne

  • Podstawowa integracja z IMA.

Jeśli nie masz obecnie podstawowej integracji z IMA, zalecamy skorzystanie z przykładu zaawansowanego na githubie. W tym przykładzie zaimplementowano już niestandardowe odtwarzanie reklamy. W pozostałej części tego przewodnika znajdziesz opis funkcji niezbędnych do niestandardowego odtwarzania reklam w ramach reklam IMA.

Interfejs z VideoAdPlayer

Niestandardowe odtwarzanie reklam wymaga zaimplementowania w aplikacji interfejsu VideoAdPlayer. Pakiet SDK używa tego interfejsu, aby powiadamiać aplikację o możliwości odtwarzania filmów reklamowych. Aplikacja używa też tego interfejsu, aby informować pakiet SDK o ważnych zdarzeniach reklam wideo. Aby wdrożyć interfejs, wykonaj te czynności:

Tworzenie odtwarzacza VideoAdPlayer

Pierwszym krokiem jest utworzenie anonimowej klasy VideoAdPlayer w requestAds():

private VideoAdPlayer videoAdPlayer;
...

private void requestAds(String adTagUrl) {
    videoAdPlayer = new VideoAdPlayer() {
    };
}

Dodaj metody wideo

Następnie dodaj metody, które spowodują, że odtwarzacz wideo będzie odtwarzać, wczytywać, zatrzymywać i wstrzymywać filmy. Dodajemy też metody zwalniania odtwarzacza i uzyskiwania głośności w tym miejscu:

videoAdPlayer = new VideoAdPlayer() {
        @Override
        public void playAd() {
            if (mIsAdDisplayed) {
                videoPlayer.resume();
            } else {
                isAdDisplayed = true;
                videoPlayer.play();
            }
        }

        @Override
        public void loadAd(String url) {
            isAdDisplayed = true;
            videoPlayer.setVideoPath(url);
        }
        @Override
        public void stopAd() {
            videoPlayer.stopPlayback();
        }
        @Override
        public void pauseAd() {
            videoPlayer.pause();
        }

        @Override
        public void release() {
            // any clean up that needs to be done
        }

        @Override
        public int getVolume() {
            return videoPlayer.getVolume();
        }
};

Są to „cienkie” opakowania podobnych metod odtwarzacza wideo. Pamiętaj, że te metody ustawiają zmienną wewnętrzną, która służy do śledzenia, czy reklama się wyświetla. W przypadku niestandardowego odtwarzania reklamy odtwarzacz wideo odtwarza zarówno treści wideo, jak i reklamy wideo, więc musisz śledzić, co jest aktualnie wyświetlane.

Postęp odtwarzania reklamy

Interfejs VideoAdPlayer ma zaimplementowany inny interfejs, AdProgressProvider, więc Ty też musisz go zaimplementować. Ma tylko jedną metodę: getAdProgress(), której pakiet SDK używa do uzyskiwania informacji o odtwarzaniu reklam. Dodaj go do anonimowej klasy VideoAdPlayer pod innymi metodami:

VideoAdPlayer videoAdPlayer = new VideoAdPlayer() {
        ...
        @Override
        public VideoProgressUpdate getAdProgress() {
            if (!isAdDisplayed || videoPlayer.getDuration() <= 0) {
                return VideoProgressUpdate.VIDEO_TIME_NOT_READY;
            }
            return new VideoProgressUpdate(videoPlayer.getCurrentPosition(),
                    videoPlayer.getDuration());
        }
};

getAdProgress() zwraca typ VideoProgressUpdate, który musi składać się z bieżącej pozycji i czasu trwania filmu. Jeśli odtwarzacz nie odtwarza reklamy lub czas jest niedostępny, ustaw zwracanie wartości VideoProgressUpdate.VIDEO_TIME_NOT_READY, jak pokazano w przykładzie.

Zarządzanie rozmowami wideo

Niestandardowe odtwarzanie reklam wymaga, aby aplikacja informowała pakiet SDK o ważnych zdarzeniach związanych z reklamami wideo. Z punktu widzenia pakietu SDK są to wywołania zwrotne opisane w interfejsie VideoAdPlayer.VideoAdPlayerCallback. Zanim zapoznasz się z metodami wywołań zwrotnych, musisz mieć możliwość dodawania i usuwania wywołań zwrotnych na żądanie pakietu SDK. Robi się to w VideoAdPlayer przy użyciu elementów addCallback() i removeCallback():

private List<VideoAdPlayerCallback> adCallbacks = new ArrayList<>(1);

VideoAdPlayer videoAdPlayer = new VideoAdPlayer() {
        ...
        @Override
        public void addCallback(VideoAdPlayerCallback videoAdPlayerCallback) {
            adCallbacks.add(videoAdPlayerCallback);
        }

        @Override
        public void removeCallback(VideoAdPlayerCallback videoAdPlayerCallback) {
            adCallbacks.remove(videoAdPlayerCallback);
        }
};

Ta implementacja wykorzystuje tag List<> do wywołań zwrotnych, które służą do wywoływania metod List<>.add() i remove().

Wywoływanie połączeń zwrotnych

Teraz gdy pakiet SDK pozwala aplikacji na dodawanie i usuwanie wywołań zwrotnych, określ miejsca, w których odbywa się wywołanie zwrotne. Aplikacja musi wywoływać te wywołania zwrotne w przypadku ważnych zdarzeń związanych z wideo, takich jak odtworzenie, wstrzymanie lub wznowienie filmu, zakończenie filmu lub wystąpienie błędu.

Aby to zrobić, rozwiń SampleVideoPlayer, by dodać odbiornik tych zdarzeń wideo dodanych z VideoFragment. Powodem utworzenia osobnego odbiornika w elemencie SampleVideoPlayer na potrzeby wywoływania tych wywołań zwrotnych jest to, że SampleVideoPlayer nie wie nic o reklamach, więc musisz przekierować te zdarzenia wideo do funkcji, która obsługuje reklamy.

public interface OnVideoEventsListener {
    void onPlay();
    void onResume();
    void onPause();
    void onError();
}

private final List<OnVideoEventsListener> onVideoEventsListeners = new ArrayList<>(1);

public void addVideoEventsListener(OnVideoEventsListener listener) {
    onVideoEventsListeners.add(listener);
}

Uruchamianie, wstrzymywanie i wznawianie

Utwórz nową wyliczenie, aby śledzić stan odtwarzania i dodawać nowe zastąpienia metod start() i pause() w SampleVideoPlayer:

private enum PlaybackState {
    STOPPED, PAUSED, PLAYING
}

private PlaybackState playbackState = PlaybackState.STOPPED;

@Override
public void start() {
    super.start();
    switch (playbackState) {
        case STOPPED:
            for (OnVideoEventsListener listener : onVideoEventsListeners) {
                listener.onPlay();
            }
            break;
        case PAUSED:
            for (OnVideoEventsListener listener : onVideoEventsListeners) {
                listener.onResume();
            }
            break;
        default:
            // Already playing; do nothing.
            break;
    }
    playbackState = PlaybackState.PLAYING;
}

@Override
public void pause() {
    super.pause();
    playbackState = PlaybackState.PAUSED;
    for (OnVideoEventsListener listener : onVideoEventsListeners) {
        listener.onPause();
    }
}

Obsługa błędów

Zastąp anonimowy detektor błędów odtwarzacza ustawiony w init():

@Override
public boolean onError(MediaPlayer mp, int what, int extra) {
    playbackState = PlaybackState.STOPPED;
    for (OnVideoEventsListener listener : onVideoEventsListeners) {
        listener.onError();
    }

    // Returning true signals to MediaPlayer that the error was handled.
    // This  prevents the completion handler from being called.
    return true;
}

Wdróż detektor

Wróć do VideoFragment i dodaj anonimowe OnVideoEventsListener do instancji SampleVideoPlayer:

mVideoPlayer.addVideoEventsListener(new OnVideoEventsListener() {
    @Override
    public void onPlay() {
        if (isAdDisplayed) {
            for (VideoAdPlayerCallback callback : adCallbacks) {
                callback.onPlay();
            }
        }
    }

    @Override
    public void onResume() {
        if (isAdDisplayed) {
            for (VideoAdPlayerCallback callback : adCallbacks) {
                callback.onResume();
            }
        }
    }

    @Override
    public void onPause() {
        if (isAdDisplayed) {
            for (VideoAdPlayerCallback callback : adCallbacks) {
                callback.onPause();
            }
        }
    }

    @Override
    public void onError() {
        if (isAdDisplayed) {
            for (VideoAdPlayerCallback callback : adCallbacks) {
                callback.onError();
            }
        }
    }
});

Zmień metodę onVideoCompleted() obiektu OnVideoCompletedListener, by obsługiwało się, gdy reklama wideo się zakończyła:

public void onVideoCompleted() {
    // Handle completed event for playing post-rolls.
    if (isAdDisplayed) {
        for (VideoAdPlayerCallback callback : adCallbacks) {
            callback.onEnded();
        }
    } else {
        if (adsLoader != null) {
            adsLoader.contentComplete();
    }
}

Przełączanie między treścią a reklamami

W tym przykładzie do odtwarzania treści i reklam zostało użyte to samo wystąpienie odtwarzacza wideo, więc trzeba dodać logikę, aby przełączać się między treścią a reklamami w odtwarzaczu. Następnie możesz ponownie załadować film i przewinąć go, aby powrócić do momentu, w którym rozpoczęła się reklama. Aby to zrobić, dodaj 2 funkcje:

private int savedContentPosition = 0;

private void pauseContent() {
    savedContentPosition = videoPlayer.getCurrentPosition();
    videoPlayer.stopPlayback();
    isAdDisplayed = true;
}

private void resumeContent() {
    videoPlayer.setVideoPath(getString(R.string.content_url));
    videoPlayer.seekTo(mSavedContentPosition);
    videoPlayer.play();
    isAdDisplayed = false;
}

Są one wywoływane po otrzymaniu zdarzeń CONTENT_PAUSE_REQUESTED i CONTENT_RESUME_REQUESTED odpowiednio w komponencie VideoFragment.onAdEvent():

case CONTENT_PAUSE_REQUESTED:
    pauseContent();
    break;
case CONTENT_RESUME_REQUESTED:
    resumeContent();
    break;

Włącz niestandardowe odtwarzanie reklam

Na koniec poinformuj pakiet SDK, że używasz niestandardowego odtwarzania reklam. W tym celu należy przekazać VideoAdPlayer do AdDisplayContainer:

adDisplayContainer.setPlayer(videoAdPlayer);

Musisz przekazać swój odtwarzacz do: setPlayer(). W przeciwnym razie pakiet SDK korzysta z odtwarzania należącego do pakietu SDK.

To wszystko. To wszystkie kroki, które musisz wykonać, aby dodać niestandardowe odtwarzanie reklamy do implementacji IMA. Jeśli napotkasz problem, możesz porównać własną implementację z przykładem zaawansowanym na GitHubie.