Los SDK de IMA facilitan la integración de anuncios multimedia en tus sitios web y aplicaciones. Los SDK de IMA pueden solicitar anuncios de cualquier servidor de anuncios compatible con VAST y administrar la reproducción de anuncios en tus apps. Con los SDK de IMA de DAI, las apps realizan una solicitud de transmisión para anuncios y videos de contenido, ya sea VOD o contenido en vivo. Luego, el SDK muestra una transmisión de video por Internet combinada para que no tengas que administrar el cambio entre el anuncio y el video de contenido dentro de tu app.
Seleccione la solución de DAI que le interesa
DAI de servicio completo
En esta guía, se muestra cómo integrar el SDK de IMA en una app simple de reproductor de video. Si deseas ver o seguir una integración de muestra completa, descarga BasicExample desde GitHub.
Descripción general de la DAI de IMA
La implementación de la DAI de IMA implica cuatro componentes principales del SDK, como se muestra en esta guía:
StreamDisplayContainer
: Es un objeto contenedor que se ubica sobre el elemento de reproducción de video y aloja los elementos de la IU del anuncio.AdsLoader
: Es un objeto que solicita transmisiones y controla los eventos activados por los objetos de respuesta a solicitudes de transmisión. Solo debes crear una instancia de un cargador de anuncios, que se puede volver a usar durante la vida útil de la aplicación.StreamRequest
: Es un objeto que define una solicitud de transmisión. Las solicitudes de transmisión pueden ser para transmisiones de video on demand o en vivo. Las solicitudes especifican un ID de contenido, así como una clave de API o un token de autenticación y otros parámetros.StreamManager
: Es un objeto que controla las interacciones y los flujos de inserción de anuncios dinámicos con el backend de la DAI. El administrador de transmisiones también controla el seguimiento de los pings y reenvía eventos de transmisión y anuncios al publicador.
Requisitos previos
- Android Studio
- App de reproductor de video de muestra para la integración del SDK
Descarga y ejecuta la app de muestra de reproductor de video
La app de ejemplo proporciona un reproductor de video en funcionamiento que reproduce video HLS. Úsalo como punto de partida para integrar las capacidades de DAI del SDK de IMA para Android.
Descarga la app de reproductor de video de muestra y extráela.
Inicia Android Studio y selecciona Open an existing Android Studio project o, si Android Studio ya se está ejecutando, selecciona File > New > Import Project. Luego, elige
SampleVideoPlayer/build.gradle
.Ejecuta una sincronización de Gradle seleccionando Tools > Android > Sync Project with Gradle Files.
Asegúrate de que la app del reproductor se compile y se ejecute en un dispositivo Android físico o en un dispositivo virtual de Android con Run > Run 'app'. Es normal que la transmisión de video demore unos minutos en cargarse antes de reproducirse.
Examina el reproductor de video de muestra
El reproductor de video de muestra aún no contiene ningún código de integración del SDK de IMA. La app de ejemplo consta de dos partes principales:
samplevideoplayer/SampleVideoPlayer.java
: Es un reproductor HLS basado en ExoPlayer que funciona como base para la integración de la DAI de IMA.videoplayerapp/MyActivity.java
: Esta actividad crea el reproductor de video y le pasa unContext
y unSimpleExoPlayerView
.
Agregue el SDK de IMA para Android a la aplicación del reproductor
También debe incluir una referencia al SDK de IMA. En Android Studio, agrega lo siguiente al archivo build.gradle
de nivel de aplicación, ubicado en app/build.gradle
:
repositories {
google()
mavenCentral()
}
dependencies {
implementation 'androidx.appcompat:appcompat:1.6.1'
implementation 'androidx.media3:media3-exoplayer:1.3.1'
implementation 'com.google.ads.interactivemedia.v3:interactivemedia:3.33.0'
}
Integración del SDK de IMA
Crea una clase nueva llamada
SampleAdsWrapper
en el paquetevideoplayerapp
(enapp/java/com.google.ads.interactivemedia.v3.samples/videoplayerapp/
) para unir elSampleVideoPlayer
existente y agregar lógica que implemente la DAI de IMA. Para ello, primero debes crear unAdsLoader
que se use para solicitar anuncios de servidores de anuncios.videoplayerapp/SampleAdsWrapper.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 { // Livestream 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 = "2548831"; 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()); } }
Agrega un método
buildStreamRequest()
aAdsLoader
para que pueda solicitar una transmisión con anuncios. Esta es una transmisión en vivo con anuncios (configurada de forma predeterminada) o una transmisión de video on demand(VOD) que reproduce contenido grabado con anuncios. Para habilitar la transmisión de VOD, marca como comentario la solicitud de transmisión en vivo y quita el comentario de la solicitud.Para trabajar con DAI, un jugador debe pasar eventos ID3 para las transmisiones en vivo a los SDK de IMA. En el siguiente código de muestra, esto se hace con el método
callback.onUserTextReceived()
.videoplayerapp/SampleAdsWrapper.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); } } }); // Livestream 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 livestream to a VOD stream. // StreamRequest request = sdkFactory.createVodStreamRequest(TEST_CONTENT_SOURCE_ID, // TEST_VIDEO_ID, null, displayContainer); return request; }
También necesitas una
VideoStreamPlayer
para reproducir la transmisión, así que agrega un métodocreateVideoStreamPlayer()
, que crea una clase anónima que implementaVideoStreamPlayer
.videoplayerapp/SampleAdsWrapper.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; }
Implementa los objetos de escucha necesarios y agrega compatibilidad para el manejo de errores.
Ten en cuenta la implementación de
AdErrorListener
, ya que llama a una URL de resguardo si no se reproducen los anuncios. Dado que el contenido y los anuncios están en una transmisión, debes estar listo para llamar a una transmisión de resguardo si la transmisión de DAI encuentra un error.videoplayerapp/SampleAdsWrapper.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; }
Agrega el código para el registro.
videoplayerapp/SampleAdsWrapper.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); } }
Modifica
MyActivity
envideoplayerapp
para crear una instancia y llamar aSampleAdsWrapper
.videoplayerapp/MyActivity.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); } }); } ... }
Modifica el archivo de diseño
activity_my.xml
de la actividad a fin de agregar elementos de la IU para el registro.res/layout/activity_my.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> ...
¡Felicitaciones! Ahora solicitas y muestras anuncios de video en tu app para Android. Para optimizar tu implementación, consulta Favoritos, Snapback y la documentación de la API.
Solución de problemas
Si tienes problemas para reproducir un anuncio de video, intenta descargar el BasicExample completo. Si funciona correctamente en BasicExample, es probable que haya un problema con el código de integración de IMA de la app.
Si los problemas persisten, visita el foro del SDK de IMA.