Los SDK de IMA facilitan la integración de anuncios multimedia en sus sitios web y aplicaciones. Los SDK de IMA pueden solicitar anuncios de cualquier servidor de anuncios compatible con VAST y administra la reproducción de anuncios en tus apps. Con los SDK de IMA de DAI, las aplicaciones solicitud de transmisión para anuncios y videos de contenido, ya sea VOD o contenido en vivo. Luego, el SDK muestra un una transmisión de video por Internet combinada, de modo que no tenga que administrar el cambio entre el video del anuncio y el de contenido dentro de la app.
Selecciona la solución de DAI que te interesa
DAI de servicio completo
En esta guía, se muestra cómo integrar el SDK de IMA de DAI en un reproductor de video simple . Si quieres ver o seguir una muestra completa integrada, descarga el archivo BasicExample de GitHub.
Descripción general de IMA de DAI
La implementación de la DAI de IMA incluye cuatro componentes principales del SDK, como se demuestra en este guía:
StreamDisplayContainer
: Es un objeto contenedor que se ubica encima del elemento de reproducción de video y aloja los elementos de la IU del anuncio.AdsLoader
: Un objeto que solicita transmisiones y controla eventos activados por objetos de respuesta a solicitudes de transmisión. Solo deberías crear una instancia de un cargador de anuncios, que puede reutilizarse durante el ciclo de vida de la y mantener la integridad de su aplicación.StreamRequest
: Un objeto que define una solicitud de transmisión. Las solicitudes de transmisión pueden ser de video on demand o en vivo. transmisiones continuas. 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 administra interacciones y transmisiones de inserción de anuncios dinámicos con el backend de DAI. El Además, administra el seguimiento de los pings y reenvía la transmisión y los eventos de anuncios al publicador.
Requisitos previos
- Android Studio
- App de reproducción de video de muestra para la integración del SDK
Descarga y ejecuta la app de ejemplo del reproductor de video
La app de ejemplo proporciona un reproductor de video que funciona y que reproduce video HLS. Usar esto como un punto de partida para integrar las funciones de DAI del SDK de IMA,
Descarga el reproductor de video de muestra. app y extraerlo.
Inicia Android Studio y selecciona Open an existing Android Studio project. o, si Android Studio ya se está ejecutando, selecciona File > Nuevo > Importar Proyecto. Luego, elige
SampleVideoPlayer/build.gradle
.Ejecuta una sincronización de Gradle seleccionando Tools > Android > Sincroniza el proyecto con archivos de Gradle.
Asegúrate de que la app del reproductor se compile y se ejecute en un dispositivo Android físico. un dispositivo virtual de Android usando Run > Ejecuta “app”. Es normal que el video para que se cargue unos minutos antes de reproducir el contenido.
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 DAI de IMA. La app de ejemplo consta de dos partes principales:
samplevideoplayer/SampleVideoPlayer.java
: Un reproductor HLS basado en ExoPlayer que funciona como la base de la integración de IMA de DAI.videoplayerapp/MyActivity.java
: Esta actividad crea el reproductor de video y le pasa unContext
y unSimpleExoPlayerView
.
Agregue el SDK de IMA de DAI a la aplicación del reproductor
También debe incluir una referencia al SDK de IMA de DAI. En Android Studio, agrega
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.35.0'
}
Integre el SDK de IMA de DAI
Crea una clase nueva llamada
SampleAdsWrapper
en el paquetevideoplayerapp
. (enapp/java/com.google.ads.interactivemedia.v3.samples/videoplayerapp/
) para une elSampleVideoPlayer
existente y agrega lógica con la implementación de la DAI de IMA. Para Para ello, primero debes crear unAdsLoader
que se usará para solicitar anuncios desde 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 un elemento. con anuncios. Puede ser una transmisión en vivo con anuncios (configuración predeterminada) o una transmisión de video on demand(VOD) que reproduce contenido pregrabado con anuncios. Para habilitar la transmisión de VOD, marcar como comentario la solicitud de transmisión en vivo y quitar el comentario de Solicitud de transmisión de VOD.Para trabajar con la DAI, un jugador debe pasar eventos del ID3 para transmisiones en vivo a la DAI de IMA. SDK. En el siguiente código de muestra, esto lo realiza el
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 un elemento
VideoStreamPlayer
para reproducir la transmisión, así que agregacreateVideoStreamPlayer()
, 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()); } @Override public int getVolume() { return videoPlayer.getVolume(); } }; return player; }
Implementa los objetos de escucha requeridos y agrega compatibilidad con el manejo de errores.
Observa la implementación de
AdErrorListener
, ya que llama a una URL de resguardo si la no se reproducen los anuncios. Debido a que el contenido y los anuncios están en una sola transmisión, debes 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 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 llamarSampleAdsWrapper
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 de la actividad
activity_my.xml
para agregar elementos de la IU para de los datos.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 estás solicitando y mostrando anuncios de video en tu dispositivo Android . Para optimizar tu implementación, consulta Favoritos, restablecimiento automático, y la API documentación.
Soluciona problemas
Si tienes problemas para reproducir un anuncio de video, prueba descargar el BasicExample. Si funciona correctamente en BasicExample, es probable que haya un problema con tu de integración de IMA de tu app.
Si los problemas persisten, visite el SDK de IMA foro.