Riproduzione di annunci personalizzati con l'SDK IMA per Android

Il modo più rapido e semplice per integrare l'SDK IMA per Android nella tua app è fare in modo che l'SDK gestisca tutta la logica di riproduzione degli annunci, mentre l'app si concentra sulla riproduzione dei video di contenuti. Questo approccio, chiamato "Riproduzione di annunci di proprietà dell'SDK", è l'opzione predefinita in Inizia.

Tuttavia, se vuoi riprodurre annunci anche nel tuo video player, l'SDK fornisce un'interfaccia dedicata. Questo approccio viene chiamato "riproduzione di annunci personalizzati" e il resto della guida ne spiega l'implementazione.

Prerequisiti

  • Un'integrazione IMA di base.

Ti consigliamo di consultare l'esempio avanzato su github come punto di partenza se al momento non disponi di un'integrazione IMA di base. Questo esempio implementa già la riproduzione degli annunci personalizzati. La parte restante di questa guida descrive le funzioni necessarie per la riproduzione di annunci personalizzati con gli annunci IMA.

Interfaccia con VideoAdPlayer

La riproduzione di annunci personalizzati richiede che la tua app implementi l'interfaccia VideoAdPlayer. Questa interfaccia viene utilizzata dall'SDK per notificare all'app la riproduzione dei video pubblicitari. La tua app utilizza questa interfaccia anche per comunicare all'SDK i principali eventi relativi agli annunci video. Per implementare l'interfaccia, procedi nel seguente modo.

Creazione di un VideoAdPlayer

Il primo passaggio consiste nel creare un corso VideoAdPlayer anonimo in requestAds():

private VideoAdPlayer videoAdPlayer;
...

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

Aggiungi metodi video

In seguito, aggiungi metodi che indicano al video player di riprodurre, caricare, interrompere e mettere in pausa i video pubblicitari. Aggiungiamo anche metodi per rilasciare il player e recuperare il volume qui:

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

Questi metodi sono involucri sottili che racchiudono i metodi simili del tuo video player. Tieni presente che questi metodi impostano una variabile interna utilizzata per tenere traccia della visualizzazione di un annuncio. Nella riproduzione degli annunci personalizzati, il video player riproduce sia gli annunci video di contenuti sia gli annunci video, quindi devi tenere traccia di quali sono attualmente visualizzati.

Avanzamento della riproduzione dell'annuncio

L'interfaccia VideoAdPlayer implementa un'altra interfaccia, AdProgressProvider, quindi devi implementarla anche tu. Ha un solo metodo, getAdProgress(), utilizzato dall'SDK per ottenere informazioni sulla riproduzione degli annunci. Aggiungilo alla classe VideoAdPlayer anonima, sotto gli altri metodi:

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() restituisce un tipo VideoProgressUpdate, che deve essere costituito dalla posizione e dalla durata correnti del video. Se il player non sta riproducendo un annuncio o se la durata non è disponibile, fai in modo che restituisca VideoProgressUpdate.VIDEO_TIME_NOT_READY come mostrato nell'esempio.

Gestire le richiamate video

Per poter usufruire della riproduzione di annunci personalizzati, la tua app deve comunicare all'SDK i principali eventi video. Dal punto di vista dell'SDK, si tratta dei callback descritti dall'interfaccia VideoAdPlayer.VideoAdPlayerCallback. Prima di accedere ai metodi di callback, devi essere in grado di aggiungere e rimuovere i callback su richiesta dell'SDK. Questa operazione viene eseguita all'interno di VideoAdPlayer utilizzando addCallback() e 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);
        }
};

Questa implementazione utilizza un List<> per i callback su cui chiamare i metodi List<>.add() e remove().

Chiama i callback

Ora che l'SDK ha modo di indicare alla tua app di aggiungere e rimuovere i callback, definisci i punti in cui viene chiamato il callback. La tua app deve richiamare questi callback quando si verificano eventi video importanti, come la riproduzione, la messa in pausa o il ripristino di un video oppure quando un video termina o si verifica un errore.

A questo scopo, espandi SampleVideoPlayer in modo da avere un listener per questi eventi video aggiunti da VideoFragment. Il motivo per creare in SampleVideoPlayer un listener separato per chiamare questi callback degli annunci è che SampleVideoPlayer non sa nulla sugli annunci, quindi devi inoltrare i suoi eventi video a un elemento in grado di gestire gli annunci.

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

Avviare, mettere in pausa e riprendere

Crea una nuova enum per tenere traccia dello stato di riproduzione e aggiungi nuovi override per i metodi start() e pause() in 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();
    }
}

Gestire gli errori

Esegui l'override del listener di errori anonimo del video player impostato in 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;
}

Implementa il listener

Torna a VideoFragment e aggiungi un OnVideoEventsListener anonimo alla tua istanza 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();
            }
        }
    }
});

Modifica il metodo onVideoCompleted() di OnVideoCompletedListener per gestire il caso in cui il video di un annuncio sia terminato:

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

Passare dai contenuti agli annunci e viceversa

Questo esempio utilizza la stessa istanza del video player per riprodurre sia i contenuti sia gli annunci, quindi devi aggiungere una logica per passare dai contenuti agli annunci e viceversa nel player. Puoi quindi ricaricare e cercare il video di contenuti per tornare al punto in cui è iniziato l'annuncio. Per farlo, aggiungi due funzioni:

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

Questi vengono chiamati quando vengono ricevuti gli eventi CONTENT_PAUSE_REQUESTED e CONTENT_RESUME_REQUESTED, rispettivamente in VideoFragment.onAdEvent():

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

Attiva riproduzione annuncio personalizzata

L'ultimo passaggio consiste nel comunicare all'SDK che stai utilizzando la riproduzione di annunci personalizzati. Per farlo, passa un VideoAdPlayer al tuo AdDisplayContainer:

adDisplayContainer.setPlayer(videoAdPlayer);

È necessario passare il player a setPlayer(). In caso contrario, l'SDK utilizza la riproduzione di proprietà dell'SDK.

È tutto. Questi sono tutti i passaggi necessari per aggiungere la riproduzione di annunci personalizzata all'implementazione IMA. Se riscontri un problema, puoi confrontare la tua implementazione con l'esempio avanzato su GitHub.