Benutzerdefinierte Anzeigenwiedergabe mit dem IMA SDK für Android

Am schnellsten und einfachsten lässt sich das IMA SDK für Android in Ihre App einbinden, wenn das SDK die gesamte Logik für die Anzeigenwiedergabe übernimmt, während in der App hauptsächlich Contentvideos wiedergegeben werden. Dieser Ansatz, der als „SDK-eigene Anzeigenwiedergabe“ bezeichnet wird, ist die Standardoption unter Jetzt starten.

Wenn Sie jedoch auch Anzeigen in Ihrem Videoplayer wiedergeben möchten, bietet das SDK eine entsprechende Oberfläche. Wir bezeichnen diesen Ansatz als "benutzerdefinierte Anzeigenwiedergabe". Im weiteren Verlauf dieses Leitfadens wird die Implementierung erläutert.

Voraussetzungen

  • Eine grundlegende IMA-Integration.

Wenn Sie derzeit keine grundlegende IMA-Integration haben, sollten Sie sich das erweiterte Beispiel auf GitHub als Ausgangspunkt ansehen. In diesem Beispiel wird bereits die benutzerdefinierte Anzeigenwiedergabe implementiert. Im weiteren Verlauf dieses Leitfadens werden die Funktionen beschrieben, die für die benutzerdefinierte Anzeigenwiedergabe mit IMA-Anzeigen erforderlich sind.

Schnittstelle mit VideoAdPlayer

Für die benutzerdefinierte Anzeigenwiedergabe muss in Ihrer App die VideoAdPlayer-Oberfläche implementiert sein. Diese Schnittstelle wird vom SDK verwendet, um Ihre App zum Abspielen von Anzeigenvideos zu veranlassen. In Ihrer App wird diese Benutzeroberfläche außerdem verwendet, um das SDK über wichtige Ereignisse für Videoanzeigen zu informieren. Führen Sie die folgenden Schritte aus, um die -Schnittstelle zu implementieren.

VideoAdPlayer erstellen

Der erste Schritt besteht darin, eine anonyme VideoAdPlayer-Klasse in requestAds() zu erstellen:

private VideoAdPlayer videoAdPlayer;
...

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

Videomethoden hinzufügen

Als Nächstes fügen Sie Methoden hinzu, die Ihrem Videoplayer ermöglichen, Anzeigenvideos abzuspielen, zu laden, zu stoppen und zu pausieren. Wir fügen auch die Methoden zum Loslassen des Players und zum Abrufen der Lautstärke hier hinzu:

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();
        }
};

Diese Methoden sind schlanke Wrapper um die eigenen ähnlichen Methoden Ihres Videoplayers. Mit diesen Methoden wird eine interne Variable festgelegt, mit der erfasst wird, ob eine Anzeige ausgeliefert wird. Bei der benutzerdefinierten Anzeigenwiedergabe werden im Videoplayer sowohl Content- als auch Videoanzeigen wiedergegeben. Daher sollten Sie wissen, welches gerade zu sehen ist.

Fortschritt der Anzeigenwiedergabe

Mit der Schnittstelle VideoAdPlayer wird eine weitere Schnittstelle, AdProgressProvider, implementiert, also müssen Sie sie ebenfalls implementieren. Sie hat nur die Methode getAdProgress(), die vom SDK verwendet wird, um Wiedergabeinformationen für Anzeigen abzurufen. Fügen Sie sie Ihrer anonymen VideoAdPlayer-Klasse unter den anderen Methoden hinzu:

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() gibt einen VideoProgressUpdate-Typ zurück, der aus der aktuellen Position und der Dauer des Videos bestehen muss. Wenn im Player keine Anzeige wiedergegeben wird oder die Dauer nicht verfügbar ist, muss VideoProgressUpdate.VIDEO_TIME_NOT_READY zurückgegeben werden, wie im Beispiel gezeigt.

Videoanrufe verwalten

Für die Wiedergabe benutzerdefinierter Anzeigen muss Ihre App das SDK über wichtige Videoereignisse informieren. Aus der Sicht des SDK sind dies Callbacks, die von der VideoAdPlayer.VideoAdPlayerCallback-Schnittstelle beschrieben werden. Bevor Sie auf die Callback-Methoden zugreifen können, müssen Sie die Callbacks auf Anfrage des SDK hinzufügen und entfernen können. Dies geschieht in VideoAdPlayer mit addCallback() und 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);
        }
};

Diese Implementierung verwendet List<> für die Callbacks, über die die Methoden List<>.add() und remove() aufgerufen werden.

Rückrufe aufrufen

Das SDK verfügt nun über die Möglichkeit, Ihrer App mitzuteilen, dass Callbacks hinzugefügt und entfernt werden sollen. Definieren Sie nun die Stellen, an denen der Callback aufgerufen wird. Ihre App muss diese Callbacks aufrufen, wenn wichtige Videoereignisse auftreten, z. B. wenn ein Video abgespielt, angehalten oder fortgesetzt wird, wenn ein Video zu Ende ist oder ein Fehler auftritt.

Maximieren Sie dazu SampleVideoPlayer, um einen Listener für diese Videoereignisse zu erhalten, die aus VideoFragment hinzugefügt werden. Sie sollten in SampleVideoPlayer einen separaten Listener erstellen, um diese Anzeigen-Callbacks aufzurufen, weil SampleVideoPlayer nichts über Anzeigen weiß. Daher müssen Sie die Videoereignisse an einen Ort weiterleiten, der Anzeigen verarbeiten kann.

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);
}

Starten, pausieren und fortsetzen

Erstellen Sie eine neue Enum, um den Wiedergabestatus zu verfolgen, und fügen Sie neue Überschreibungen für die Methoden start() und pause() in SampleVideoPlayer hinzu:

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();
    }
}

Fehler verarbeiten

Überschreiben Sie den anonymen Fehler-Listener des Videoplayers, den Sie in init() festgelegt haben:

@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;
}

Listener implementieren

Kehren Sie zu VideoFragment zurück und fügen Sie Ihrer SampleVideoPlayer-Instanz eine anonyme OnVideoEventsListener hinzu:

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();
            }
        }
    }
});

Ändern Sie die Methode onVideoCompleted() von OnVideoCompletedListener, um den Fall zu berücksichtigen, dass ein Anzeigenvideo beendet wurde:

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

Zwischen Content- und Anzeigenwerbung wechseln

In diesem Beispiel wird dieselbe Instanz des Videoplayers verwendet, um sowohl Content als auch Anzeigen wiederzugeben. Sie müssen also eine Logik hinzufügen, um zwischen Content und Anzeigen in Ihrem Player zu wechseln. Anschließend können Sie das Video neu laden und zu dem Startpunkt der Anzeige zurückkehren. Fügen Sie dazu zwei Funktionen hinzu:

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

Sie werden aufgerufen, wenn die Ereignisse CONTENT_PAUSE_REQUESTED und CONTENT_RESUME_REQUESTED in VideoFragment.onAdEvent() empfangen werden:

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

Benutzerdefinierte Anzeigenwiedergabe aktivieren

Im letzten Schritt teilen Sie dem SDK mit, dass Sie die benutzerdefinierte Anzeigenwiedergabe verwenden. Dazu wird ein VideoAdPlayer an AdDisplayContainer übergeben:

adDisplayContainer.setPlayer(videoAdPlayer);

Sie müssen den Player an setPlayer() übergeben. Andernfalls verwendet das SDK die SDK-eigene Wiedergabe.

Das wars. Dies sind alle erforderlichen Schritte, um Ihrer IMA-Implementierung eine benutzerdefinierte Anzeigenwiedergabe hinzuzufügen. Sie können Ihre eigene Implementierung mit dem erweiterten Beispiel auf GitHub vergleichen, wenn ein Problem auftritt.