Lecture d'annonces personnalisées avec le SDK IMA pour Android

Le moyen le plus rapide et le plus simple d'intégrer le SDK IMA pour Android à votre application consiste à faire en sorte qu'il gère toute la logique de lecture des annonces, tandis que votre application se concentre sur la lecture de contenus vidéo. Cette approche, appelée "Lecture d'annonces appartenant au SDK" est l'option par défaut dans Premiers pas.

Toutefois, si vous souhaitez également diffuser des annonces dans votre lecteur vidéo, le SDK fournit une interface correspondante. Cette approche est appelée "lecture d'annonces personnalisées". Le reste de ce guide en explique la mise en œuvre.

Conditions préalables

  • Une intégration IMA de base.

Si vous ne disposez pas actuellement d'une intégration IMA de base, nous vous recommandons de consulter l'exemple avancé sur GitHub comme point de départ. Cet exemple implémente déjà la lecture d'annonces personnalisées. Le reste de ce guide décrit les fonctionnalités nécessaires à la lecture d'annonces personnalisées avec les annonces IMA.

Interface avec VideoAdPlayer

La lecture d'annonces personnalisée nécessite que votre application implémente l'interface VideoAdPlayer. Cette interface est utilisée par le SDK pour demander à votre application de lire des vidéos publicitaires. Votre application utilise également cette interface pour informer le SDK des événements majeurs sur les annonces vidéo. Pour implémenter l'interface, procédez comme suit :

Créer un composant VideoAdPlayer

La première étape consiste à créer une classe VideoAdPlayer anonyme dans requestAds():

private VideoAdPlayer videoAdPlayer;
...

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

Ajouter des méthodes vidéo

Ensuite, ajoutez des méthodes qui indiquent au lecteur vidéo de lire, charger, arrêter et mettre en pause les vidéos publicitaires. Nous ajoutons également les méthodes pour libérer le lecteur et obtenir le volume ici:

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

Ces méthodes sont des wrappers légers qui entourent les méthodes similaires de votre lecteur vidéo. Notez que ces méthodes définissent une variable interne permettant de savoir si une annonce est diffusée. Lors de la lecture d'annonces personnalisées, le lecteur vidéo lit à la fois les annonces vidéo et les annonces vidéo. Vous devez donc savoir quelles annonces sont actuellement affichées.

Progression de la lecture de l'annonce

L'interface VideoAdPlayer implémente une autre interface, AdProgressProvider, que vous devez donc également implémenter. Il ne comporte qu'une seule méthode, getAdProgress(), qui est utilisée par le SDK pour obtenir des informations sur la lecture des annonces. Ajoutez-le à votre classe VideoAdPlayer anonyme, sous les autres méthodes:

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() renvoie un type VideoProgressUpdate, qui doit comprendre la position et la durée actuelles de la vidéo. Si le lecteur ne lit pas d'annonce ou si la durée n'est pas disponible, faites en sorte qu'il renvoie VideoProgressUpdate.VIDEO_TIME_NOT_READY, comme illustré dans l'exemple.

Gérer les rappels vidéo

La lecture d'annonces personnalisée nécessite que votre application informe le SDK des événements vidéo majeurs. Dans la vue du SDK, il s'agit de rappels décrits par l'interface VideoAdPlayer.VideoAdPlayerCallback. Avant d'accéder aux méthodes de rappel, vous devez être en mesure d'ajouter et de supprimer les rappels à la requête du SDK. Cette opération est effectuée dans VideoAdPlayer à l'aide de addCallback() et de 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);
        }
};

Cette implémentation utilise un List<> pour les rappels sur lesquels appeler les méthodes List<>.add() et remove().

Appeler les rappels

Maintenant que le SDK peut indiquer à votre application d'ajouter et de supprimer des rappels, définissez les emplacements où le rappel est appelé. Votre application doit appeler ces rappels lorsque des événements vidéo majeurs se produisent, tels que la lecture, la mise en pause ou la reprise d'une vidéo, ou lorsqu'une vidéo se termine ou rencontre une erreur.

Pour ce faire, développez SampleVideoPlayer afin de disposer d'un écouteur pour ces événements vidéo ajoutés à partir de VideoFragment. Il est recommandé de créer un écouteur distinct dans SampleVideoPlayer pour appeler ces rappels d'annonces, car SampleVideoPlayer ne connaît rien aux annonces. Vous devez donc transférer ses événements vidéo à un élément qui peut gérer les annonces.

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

Démarrer, mettre en pause et reprendre

Créez une énumération pour suivre l'état de la lecture et ajoutez de nouveaux forçages pour les méthodes start() et pause() dans 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();
    }
}

Gérer les erreurs

Remplacer l'écouteur d'erreur anonyme du lecteur vidéo que vous avez défini dans 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;
}

Implémenter l'écouteur

Revenez à VideoFragment et ajoutez un OnVideoEventsListener anonyme à votre instance 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();
            }
        }
    }
});

Modifiez la méthode onVideoCompleted() de OnVideoCompletedListener pour gérer la fin d'une vidéo publicitaire:

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

Basculer entre le contenu et les annonces

Cet exemple utilise la même instance du lecteur vidéo pour lire le contenu et les annonces. Vous devez donc ajouter une logique pour basculer entre le contenu et les annonces dans votre lecteur. Vous pouvez ensuite actualiser la page et rechercher la vidéo pour revenir au moment où l'annonce a commencé. Pour ce faire, ajoutez deux fonctions:

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

Celles-ci sont appelées lorsque les événements CONTENT_PAUSE_REQUESTED et CONTENT_RESUME_REQUESTED sont reçus, respectivement dans VideoFragment.onAdEvent():

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

Activer la lecture personnalisée des annonces

La dernière étape consiste à indiquer au SDK que vous utilisez la lecture d'annonces personnalisée. Pour ce faire, transmettez un VideoAdPlayer à votre AdDisplayContainer:

adDisplayContainer.setPlayer(videoAdPlayer);

Vous devez transmettre votre lecteur à setPlayer(). Sinon, le SDK utilise la lecture appartenant au SDK.

C'est tout. Vous avez réalisé toutes les étapes nécessaires pour ajouter la lecture d'annonce personnalisée à votre implémentation IMA. Si vous rencontrez un problème, vous pouvez comparer votre propre implémentation avec l'exemple avancé sur GitHub.