Configura el SDK de IMA para la DAI

Los SDKs de IMA facilitan la integración de anuncios multimedia en tus sitios web y aplicaciones. Los SDKs de IMA pueden solicitar anuncios de cualquier servidor de anuncios compatible con VAST y administrar la reproducción de anuncios en tus aplicaciones. Con los SDKs de IMA DAI, las apps realizan una solicitud de transmisión para el video del anuncio y el contenido, ya sea VOD o contenido en vivo. Luego, el SDK devuelve una transmisión de video combinada, de modo que no tengas que administrar el cambio entre el anuncio y el video de contenido en tu 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 DAI en una app de reproductor de video simple. Si deseas ver o seguir una integración de ejemplo completa, descarga BasicExample desde GitHub.

Descripción general de IMA DAI

La implementación de la DAI de IMA implica cuatro componentes principales del SDK, como se muestra en esta guía:

  • IMAAdDisplayContainer: Es un objeto contenedor que se encuentra en la parte superior del elemento de reproducción de video y aloja los elementos de la IU del anuncio.
  • IMAAdsLoader: Es un objeto que solicita transmisiones y controla los eventos activados por los objetos de respuesta de solicitud de transmisión. Solo debes crear una instancia del cargador de anuncios, que se puede reutilizar durante la vida útil de la aplicación.
  • IMAStreamRequest: Puede ser un IMAVODStreamRequest o un IMALiveStreamRequest. Es un objeto que define una solicitud de transmisión. Las solicitudes de transmisión pueden ser para videos on demand o transmisiones en vivo. Las solicitudes de transmisión en vivo especifican una clave de recurso, mientras que las solicitudes de VOD especifican un ID de CMS y un ID de video. Ambos tipos de solicitudes pueden incluir, de forma opcional, una clave de API necesaria para acceder a las transmisiones especificadas y un código de red de Google Ad Manager para que el SDK de IMA controle los identificadores de anuncios según se especifica en la configuración de Google Ad Manager.
  • IMAStreamManager: Es un objeto que controla las transmisiones de inserción de anuncios dinámicos y las interacciones con el backend de la DAI. El administrador de transmisiones también controla los pings de seguimiento y reenvía los eventos de transmisiones y anuncios al publicador.

Requisitos previos

Antes de comenzar, necesitas lo siguiente:

También necesitas los parámetros que se usan para solicitar tu transmisión desde el SDK de IMA. Para ver ejemplos de parámetros de solicitud, consulta Sample Streams.

Parámetros de transmisión en vivo
Clave del activo La clave del recurso que identifica tu transmisión en vivo en Google Ad Manager.
Ejemplo: c-rArva4ShKVIAkNfy6HUQ
Parámetros de transmisión de VOD
ID de la fuente de contenido Es el ID de la fuente de contenido de Google Ad Manager.
Ejemplo: 2548831
ID de video Es el ID de video de Google Ad Manager.
Ejemplo: tears-of-steel
Parámetros comunes (VOD y transmisión en vivo)
Código de red Tu código de red de Google Ad Manager
Ejemplo: 21775744923

Crea un proyecto nuevo de Xcode

En Xcode, crea un proyecto nuevo para iOS con Objective-C llamado "BasicExample".

Agrega el SDK de IMA DAI al proyecto de Xcode

Usa uno de estos tres métodos para instalar el SDK de IMA DAI.

Instala el SDK con CocoaPods (opción preferida)

CocoaPods es un administrador de dependencias para proyectos de Xcode y es el método recomendado para instalar el SDK de DAI de IMA. Para obtener más información sobre la instalación o el uso de CocoaPods, consulta la documentación de CocoaPods. Después de instalar CocoaPods, sigue estas instrucciones para instalar el SDK de IMA DAI:

  1. En el mismo directorio que tu archivo BasicExample.xcodeproj, crea un archivo de texto llamado Podfile y agrega la siguiente configuración:

    source 'https://github.com/CocoaPods/Specs.git'
    
    platform :ios, '14'
    
    target 'BasicExample' do
      pod 'GoogleAds-IMA-iOS-SDK', '~> 3.26.1'
    end
    

  2. Desde el directorio que contiene el Podfile, ejecuta el siguiente comando:

    pod install --repo-update

Instala el SDK con Swift Package Manager

El SDK de anuncios multimedia interactivos admite Swift Package Manager a partir de la versión 3.18.4. Sigue estos pasos para importar el paquete de Swift.

  1. En Xcode, instala el paquete Swift del SDK de IMA DAI. Para ello, navega a File > Add Packages.

  2. En el mensaje que aparece, busca el repositorio de GitHub del paquete de Swift del SDK de IMA DAI:

    https://github.com/googleads/swift-package-manager-google-interactive-media-ads-ios
    
  3. Selecciona la versión del paquete Swift del SDK de IMA DAI que deseas usar. Para los proyectos nuevos, recomendamos usar la opción Up to Next Major Version.

Cuando termines, Xcode resolverá las dependencias de tu paquete y las descargará en segundo plano. Para obtener más detalles sobre cómo agregar dependencias de paquetes, consulta el artículo de Apple.

Descarga e instala el SDK de forma manual

Si no quieres usar Swift Package Manager ni CocoaPods, puedes descargar el SDK de IMA DAI y agregarlo manualmente a tu proyecto.

Crea un reproductor de video simple

Implementa un reproductor de video en tu controlador de vista principal con un reproductor de AV encapsulado en una vista de IU. El SDK de IMA usa la vista de la IU para mostrar los elementos de la IU de los anuncios.

Objective-C

#import "ViewController.h"

#import <AVKit/AVKit.h>

/// Content URL.
static NSString *const kBackupContentUrl =
    @"http://devimages.apple.com/iphone/samples/bipbop/bipbopall.m3u8";

@interface ViewController ()
/// Play button.
@property(nonatomic, weak) IBOutlet UIButton *playButton;

@property(nonatomic, weak) IBOutlet UIView *videoView;
/// Video player.
@property(nonatomic, strong) AVPlayer *videoPlayer;
@end

@implementation ViewController

- (void)viewDidLoad {
  [super viewDidLoad];
  self.view.backgroundColor = [UIColor blackColor];

  // Load AVPlayer with the path to your content.
  NSURL *contentURL = [NSURL URLWithString:kBackupContentUrl];
  self.videoPlayer = [AVPlayer playerWithURL:contentURL];

  // Create a player layer for the player.
  AVPlayerLayer *playerLayer = [AVPlayerLayer playerLayerWithPlayer:self.videoPlayer];

  // Size, position, and display the AVPlayer.
  playerLayer.frame = self.videoView.layer.bounds;
  [self.videoView.layer addSublayer:playerLayer];
}

- (IBAction)onPlayButtonTouch:(id)sender {
  [self.videoPlayer play];
  self.playButton.hidden = YES;
}

@end

Swift

// Copyright 2024 Google LLC. All rights reserved.
//
//
// Licensed under the Apache License, Version 2.0 (the "License"); you may not use this
// file except in compliance with the License. You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software distributed under
// the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF
// ANY KIND, either express or implied. See the License for the specific language governing
// permissions and limitations under the License.

import AVFoundation
import UIKit

class ViewController: UIViewController {

  /// Content URL.
  static let backupStreamURLString =
    "http://devimages.apple.com/iphone/samples/bipbop/bipbopall.m3u8"

  /// Play button.
  @IBOutlet private weak var playButton: UIButton!

  @IBOutlet private weak var videoView: UIView!
  /// Video player.
  private var videoPlayer: AVPlayer?

  override func viewDidLoad() {
    super.viewDidLoad()

    playButton.layer.zPosition = CGFloat(MAXFLOAT)

    // Load AVPlayer with path to our content.
    // note: this unwrap is safe because the URL is a constant string.
    let contentURL = URL(string: ViewController.backupStreamURLString)!
    videoPlayer = AVPlayer(url: contentURL)

    // Create a player layer for the player.
    let playerLayer = AVPlayerLayer(player: videoPlayer)

    // Size, position, and display the AVPlayer.
    playerLayer.frame = videoView.layer.bounds
    videoView.layer.addSublayer(playerLayer)
  }

  @IBAction func onPlayButtonTouch(_ sender: Any) {
    videoPlayer?.play()
    playButton.isHidden = true
  }
}

Inicializa el cargador de anuncios

Importa el SDK de IMA en tu controlador de vistas y adopta los protocolos IMAAdsLoaderDelegate y IMAStreamManagerDelegate para controlar los eventos del cargador de anuncios y del administrador de transmisiones.

Agrega estas propiedades privadas para almacenar los componentes clave del SDK de IMA:

  • IMAAdsLoader: Administra las solicitudes de transmisión durante el ciclo de vida de tu app.
  • IMAAdDisplayContainer: Controla la inserción y la administración de los elementos de la interfaz de usuario de anuncios.
  • IMAAVPlayerVideoDisplay: Se comunica entre el SDK de IMA y tu reproductor multimedia, y controla los metadatos cronometrados.
  • IMAStreamManager: Administra la reproducción de la transmisión y activa eventos relacionados con los anuncios.

Inicializa el cargador de anuncios, el contenedor de visualización de anuncios y la visualización de video después de que se cargue la vista.

Objective-C

@import GoogleInteractiveMediaAds;

// ...

@interface ViewController () <IMAAdsLoaderDelegate, IMAStreamManagerDelegate>
/// The entry point for the IMA DAI SDK to make DAI stream requests.
@property(nonatomic, strong) IMAAdsLoader *adsLoader;
/// The container where the SDK renders each ad's user interface elements and companion slots.
@property(nonatomic, strong) IMAAdDisplayContainer *adDisplayContainer;
/// The reference of your video player for the IMA DAI SDK to monitor playback and handle timed
/// metadata.
@property(nonatomic, strong) IMAAVPlayerVideoDisplay *imaVideoDisplay;
/// References the stream manager from the IMA DAI SDK after successful stream loading.
@property(nonatomic, strong) IMAStreamManager *streamManager;

// ...

@end

@implementation ViewController

- (void)viewDidLoad {
  [super viewDidLoad];

  // ...

  self.adsLoader = [[IMAAdsLoader alloc] initWithSettings:nil];
  self.adsLoader.delegate = self;

  // Create an ad display container for rendering each ad's user interface elements and companion
  // slots.
  self.adDisplayContainer =
      [[IMAAdDisplayContainer alloc] initWithAdContainer:self.videoView
                                          viewController:self
                                          companionSlots:nil];

  // Create an IMAAVPlayerVideoDisplay to give the SDK access to your video player.
  self.imaVideoDisplay = [[IMAAVPlayerVideoDisplay alloc] initWithAVPlayer:self.videoPlayer];
}

Swift

import GoogleInteractiveMediaAds
// ...

class ViewController: UIViewController, IMAAdsLoaderDelegate, IMAStreamManagerDelegate {
  // ...

  /// The entry point for the IMA DAI SDK to make DAI stream requests.
  private var adsLoader: IMAAdsLoader?
  /// The container where the SDK renders each ad's user interface elements and companion slots.
  private var adDisplayContainer: IMAAdDisplayContainer?
  /// The reference of your video player for the IMA DAI SDK to monitor playback and handle timed
  /// metadata.
  private var imaVideoDisplay: IMAAVPlayerVideoDisplay!
  /// References the stream manager from the IMA DAI SDK after successfully loading the DAI stream.
  private var streamManager: IMAStreamManager?

  // ...

  override func viewDidLoad() {
    super.viewDidLoad()

    // ...

    adsLoader = IMAAdsLoader(settings: nil)
    adsLoader?.delegate = self

    // Create an ad display container for rendering ad UI elements and the companion ad.
    adDisplayContainer = IMAAdDisplayContainer(
      adContainer: videoView,
      viewController: self,
      companionSlots: nil)

    // Create an IMAAVPlayerVideoDisplay to give the SDK access to your video player.
    imaVideoDisplay = IMAAVPlayerVideoDisplay(avPlayer: videoPlayer)
  }

Realiza una solicitud de transmisión

Cuando un usuario presione el botón de reproducción, realiza una nueva solicitud de transmisión. Usa la clase IMALiveStreamRequest para las transmisiones en vivo. Para las transmisiones de VOD, usa la clase IMAVODStreamRequest.

La solicitud de transmisión requiere tus parámetros de transmisión, así como una referencia a tu contenedor de visualización de anuncios y a la visualización de video.

Objective-C

- (IBAction)onPlayButtonTouch:(id)sender {
  [self requestStream];
  self.playButton.hidden = YES;
}

- (void)requestStream {
  // Create a stream request. Use one of "Live stream request" or "VOD request", depending on your
  // type of stream.
  IMAStreamRequest *request;
  if (kStreamType == StreamTypeLive) {
    // Live stream request. Replace the asset key with your value.
    request = [[IMALiveStreamRequest alloc] initWithAssetKey:kLiveStreamAssetKey
                                                 networkCode:kNetworkCode
                                          adDisplayContainer:self.adDisplayContainer
                                                videoDisplay:self.imaVideoDisplay
                                                 userContext:nil];
  } else {
    // VOD request. Replace the content source ID and video ID with your values.
    request = [[IMAVODStreamRequest alloc] initWithContentSourceID:kVODContentSourceID
                                                           videoID:kVODVideoID
                                                       networkCode:kNetworkCode
                                                adDisplayContainer:self.adDisplayContainer
                                                      videoDisplay:self.imaVideoDisplay
                                                       userContext:nil];
  }
  [self.adsLoader requestStreamWithRequest:request];
}

Swift

@IBAction func onPlayButtonTouch(_ sender: Any) {
  requestStream()
  playButton.isHidden = true
}

func requestStream() {
  // Create a stream request. Use one of "Livestream request" or "VOD request".
  if ViewController.requestType == StreamType.live {
    // Livestream request.
    let request = IMALiveStreamRequest(
      assetKey: ViewController.assetKey,
      networkCode: ViewController.networkCode,
      adDisplayContainer: adDisplayContainer!,
      videoDisplay: imaVideoDisplay,
      userContext: nil)
    adsLoader?.requestStream(with: request)
  } else {
    // VOD stream request.
    let request = IMAVODStreamRequest(
      contentSourceID: ViewController.contentSourceID,
      videoID: ViewController.videoID,
      networkCode: ViewController.networkCode,
      adDisplayContainer: adDisplayContainer!,
      videoDisplay: imaVideoDisplay,
      userContext: nil)
    adsLoader?.requestStream(with: request)
  }
}

Cómo detectar eventos de carga de transmisión

La clase IMAAdsLoader llama a los métodos IMAAdsLoaderDelegate cuando se inicializa correctamente o falla la solicitud de transmisión.

En el método de delegado adsLoadedWithData, configura tu IMAStreamManagerDelegate. Inicializa el administrador de transmisiones. Durante la inicialización, el administrador de transmisiones comienza la reproducción.

En el método delegado failedWithErrorData, registra el error. De manera opcional, reproduce la transmisión de respaldo. Consulta las prácticas recomendadas de la DAI.

Objective-C

- (void)adsLoader:(IMAAdsLoader *)loader adsLoadedWithData:(IMAAdsLoadedData *)adsLoadedData {
  NSLog(@"Stream created with: %@.", adsLoadedData.streamManager.streamId);
  self.streamManager = adsLoadedData.streamManager;
  self.streamManager.delegate = self;
  [self.streamManager initializeWithAdsRenderingSettings:nil];
}

- (void)adsLoader:(IMAAdsLoader *)loader failedWithErrorData:(IMAAdLoadingErrorData *)adErrorData {
  // Log the error and play the content.
  NSLog(@"AdsLoader error, code:%ld, message: %@", adErrorData.adError.code,
        adErrorData.adError.message);
  [self.videoPlayer play];
}

Swift

func adsLoader(_ loader: IMAAdsLoader, adsLoadedWith adsLoadedData: IMAAdsLoadedData) {
  print("DAI stream loaded. Stream session ID: \(adsLoadedData.streamManager!.streamId!)")
  streamManager = adsLoadedData.streamManager!
  streamManager!.delegate = self
  streamManager!.initialize(with: nil)
}

func adsLoader(_ loader: IMAAdsLoader, failedWith adErrorData: IMAAdLoadingErrorData) {
  print("Error loading DAI stream. Error message: \(adErrorData.adError.message!)")
  // Play the backup stream.
  videoPlayer.play()
}

Cómo detectar eventos de anuncios

El IMAStreamManager llama a los métodos IMAStreamManagerDelegate para pasar eventos y errores de transmisión a tu aplicación.

En este ejemplo, registra los eventos de anuncios principales en la consola:

Objective-C

- (void)streamManager:(IMAStreamManager *)streamManager didReceiveAdEvent:(IMAAdEvent *)event {
  NSLog(@"Ad event (%@).", event.typeString);
  switch (event.type) {
    case kIMAAdEvent_STARTED: {
      // Log extended data.
      NSString *extendedAdPodInfo = [[NSString alloc]
          initWithFormat:@"Showing ad %ld/%ld, bumper: %@, title: %@, description: %@, contentType:"
                         @"%@, pod index: %ld, time offset: %lf, max duration: %lf.",
                         (long)event.ad.adPodInfo.adPosition, (long)event.ad.adPodInfo.totalAds,
                         event.ad.adPodInfo.isBumper ? @"YES" : @"NO", event.ad.adTitle,
                         event.ad.adDescription, event.ad.contentType,
                         (long)event.ad.adPodInfo.podIndex, event.ad.adPodInfo.timeOffset,
                         event.ad.adPodInfo.maxDuration];

      NSLog(@"%@", extendedAdPodInfo);
      break;
    }
    case kIMAAdEvent_AD_BREAK_STARTED: {
      NSLog(@"Ad break started");
      break;
    }
    case kIMAAdEvent_AD_BREAK_ENDED: {
      NSLog(@"Ad break ended");
      break;
    }
    case kIMAAdEvent_AD_PERIOD_STARTED: {
      NSLog(@"Ad period started");
      break;
    }
    case kIMAAdEvent_AD_PERIOD_ENDED: {
      NSLog(@"Ad period ended");
      break;
    }
    default:
      break;
  }
}

- (void)streamManager:(IMAStreamManager *)streamManager didReceiveAdError:(IMAAdError *)error {
  NSLog(@"StreamManager error with type: %ld\ncode: %ld\nmessage: %@", error.type, error.code,
        error.message);
  [self.videoPlayer play];
}

Swift

func streamManager(_ streamManager: IMAStreamManager, didReceive event: IMAAdEvent) {
  print("Ad event \(event.typeString).")
  switch event.type {
  case IMAAdEventType.STARTED:
    // Log extended data.
    if let ad = event.ad {
      let extendedAdPodInfo = String(
        format: "Showing ad %zd/%zd, bumper: %@, title: %@, "
          + "description: %@, contentType:%@, pod index: %zd, "
          + "time offset: %lf, max duration: %lf.",
        ad.adPodInfo.adPosition,
        ad.adPodInfo.totalAds,
        ad.adPodInfo.isBumper ? "YES" : "NO",
        ad.adTitle,
        ad.adDescription,
        ad.contentType,
        ad.adPodInfo.podIndex,
        ad.adPodInfo.timeOffset,
        ad.adPodInfo.maxDuration)

      print("\(extendedAdPodInfo)")
    }
    break
  case IMAAdEventType.AD_BREAK_STARTED:
    print("Ad break started.")
    break
  case IMAAdEventType.AD_BREAK_ENDED:
    print("Ad break ended.")
    break
  case IMAAdEventType.AD_PERIOD_STARTED:
    print("Ad period started.")
    break
  case IMAAdEventType.AD_PERIOD_ENDED:
    print("Ad period ended.")
    break
  default:
    break
  }
}

func streamManager(_ streamManager: IMAStreamManager, didReceive error: IMAAdError) {
  print("StreamManager error with type: \(error.type)")
  print("code: \(error.code)")
  print("message: \(error.message ?? "Unknown Error")")
}

Ejecuta tu app y, si todo sale bien, podrás solicitar y reproducir transmisiones de DAI de Google con el SDK de IMA. Para obtener información sobre las funciones más avanzadas del SDK, consulta otras guías que se enumeran en la barra lateral izquierda o las muestras en GitHub.