Configurare l'SDK IMA per DAI

Gli SDK IMA semplificano l'integrazione di annunci multimediali nei tuoi siti web e nelle tue app. Gli SDK IMA possono richiedere annunci da qualsiasi ad server compatibile con VAST e gestire la riproduzione degli annunci nelle tue app. Con gli SDK IMA DAI, le app effettuano una richiesta di streaming per l'annuncio e il video dei contenuti, che possono essere VOD o live. L'SDK restituisce quindi uno stream video combinato, in modo da non dover gestire il passaggio tra l'annuncio e il video di contenuti all'interno dell'app.

Seleziona la soluzione DAI che ti interessa

DAI con servizio completo

Questa guida mostra come integrare l'SDK IMA DAI in una semplice app video player. Se vuoi visualizzare o seguire un'integrazione di esempio completata, scarica BasicExample da GitHub.

Panoramica di IMA DAI

L'implementazione di IMA DAI prevede quattro componenti principali dell'SDK, come illustrato in questa guida:

  • IMAAdDisplayContainer - Un oggetto contenitore che si trova sopra l'elemento di riproduzione video e contiene gli elementi dell'interfaccia utente dell'annuncio.
  • IMAAdsLoader – Un oggetto che richiede stream e gestisce gli eventi attivati dagli oggetti di risposta alla richiesta di stream. Devi creare un solo caricatore di annunci, che può essere riutilizzato per tutta la durata dell'applicazione.
  • IMAStreamRequest IMAVODStreamRequest o IMALiveStreamRequest. Un oggetto che definisce una richiesta di stream. Le richieste di stream possono riguardare video on demand o live streaming. Le richieste di live streaming specificano una chiave asset, mentre le richieste VOD specificano un ID CMS e un ID video. Entrambi i tipi di richiesta possono includere facoltativamente una chiave API necessaria per accedere agli stream specificati e un codice di rete Google Ad Manager per l'SDK IMA per gestire gli identificatori pubblicità come specificato nelle impostazioni di Google Ad Manager.
  • IMAStreamManager – Un oggetto che gestisce i flussi di inserimento di annunci dinamici e le interazioni con il backend DAI. Lo stream manager gestisce anche i ping di monitoraggio e inoltra gli eventi di stream e annunci al publisher.

Prerequisiti

Prima di iniziare, devi disporre di quanto segue:

Devi anche disporre dei parametri utilizzati per richiedere lo stream dall'SDK IMA. Per esempi di parametri di richiesta, vedi Sample Streams.

Parametri di live streaming
Chiave asset La chiave asset che identifica il tuo live streaming in Google Ad Manager.
Esempio: c-rArva4ShKVIAkNfy6HUQ
Parametri di stream VOD
ID origine di contenuto L'ID della fonte di contenuto di Google Ad Manager.
Esempio: 2548831
ID video L'ID video di Google Ad Manager.
Esempio: tears-of-steel
Parametri comuni (VOD e live streaming)
Codice rete Il tuo codice di rete Google Ad Manager.
Esempio: 21775744923

Crea un nuovo progetto Xcode

In Xcode, crea un nuovo progetto iOS utilizzando Objective-C denominato "BasicExample".

Aggiungi l'SDK IMA DAI al progetto Xcode

Utilizza uno di questi tre metodi per installare l'SDK IMA DAI.

Installa l'SDK utilizzando CocoaPods (opzione preferita)

CocoaPods è un gestore delle dipendenze per i progetti Xcode ed è il metodo consigliato per installare l'SDK IMA DAI. Per ulteriori informazioni sull'installazione o sull'utilizzo di CocoaPods, consulta la documentazione di CocoaPods. Dopo aver installato CocoaPods, utilizza le seguenti istruzioni per installare l'SDK IMA DAI:

  1. Nella stessa directory del file BasicExample.xcodeproj, crea un file di testo denominato Podfile e aggiungi la seguente configurazione:

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

  2. Dalla directory che contiene il Podfile, esegui:

    pod install --repo-update

Installa l'SDK utilizzando Swift Package Manager

L'SDK Interactive Media Ads supporta Swift Package Manager a partire dalla versione 3.18.4. Segui i passaggi riportati di seguito per importare il pacchetto Swift.

  1. In Xcode, installa il pacchetto Swift dell'SDK IMA DAI andando a File > Add Packages (File > Aggiungi pacchetti).

  2. Nel prompt visualizzato, cerca il repository GitHub del pacchetto Swift dell'SDK IMA DAI:

    https://github.com/googleads/swift-package-manager-google-interactive-media-ads-ios
    
  3. Seleziona la versione del pacchetto Swift dell'SDK IMA DAI che vuoi utilizzare. Per i nuovi progetti, ti consigliamo di utilizzare l'opzione Fino alla prossima versione principale.

Al termine, Xcode risolve le dipendenze del pacchetto e le scarica in background. Per maggiori dettagli su come aggiungere le dipendenze dei pacchetti, consulta l'articolo di Apple.

Scaricare e installare manualmente l'SDK

Se non vuoi utilizzare Swift Package Manager o CocoaPods, puoi scaricare l'SDK IMA DAI e aggiungerlo manualmente al tuo progetto.

Creare un semplice video player

Implementa un video player nel controller di visualizzazione principale utilizzando un player AV racchiuso in una visualizzazione UI. L'SDK IMA utilizza la visualizzazione UI per mostrare gli elementi dell'interfaccia utente dell'annuncio.

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

Inizializza il caricatore di annunci

Importa l'SDK IMA nel controller di visualizzazione e adotta i protocolli IMAAdsLoaderDelegate e IMAStreamManagerDelegate per gestire gli eventi del caricatore di annunci e dello stream manager.

Aggiungi queste proprietà private per archiviare i componenti chiave dell'SDK IMA:

  • IMAAdsLoader - Gestisce le richieste di stream per l'intera durata dell'app.
  • IMAAdDisplayContainer - Gestisce l'inserimento e la gestione degli elementi dell'interfaccia utente degli annunci.
  • IMAAVPlayerVideoDisplay - Comunica tra l'SDK IMA e il tuo media player e gestisce i metadati temporizzati.
  • IMAStreamManager - Gestisce la riproduzione dello stream e attiva gli eventi correlati agli annunci.

Inizializza il caricatore di annunci, il contenitore di visualizzazione degli annunci e la visualizzazione dei video dopo il caricamento della visualizzazione.

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

Effettuare una richiesta di stream

Quando un utente preme il pulsante di riproduzione, invia una nuova richiesta di stream. Utilizza la classe IMALiveStreamRequest per i live streaming. Per gli stream VOD, utilizza la classe IMAVODStreamRequest.

La richiesta di stream richiede i parametri dello stream, nonché un riferimento al contenitore di visualizzazione dell'annuncio e alla visualizzazione del 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)
  }
}

Ascolta gli eventi di caricamento dello stream

La classe IMAAdsLoader chiama i metodi IMAAdsLoaderDelegate in caso di inizializzazione riuscita o non riuscita della richiesta di flusso.

Nel metodo delegato adsLoadedWithData, imposta IMAStreamManagerDelegate. Inizializza lo stream manager. All'inizializzazione, lo stream manager avvia la riproduzione.

Nel metodo delegato failedWithErrorData, registra l'errore. (Facoltativo) Riproduci lo stream di backup. Consulta le best practice per l'inserimento dinamico degli annunci.

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

Ascolta gli eventi degli annunci

IMAStreamManager chiama i metodi IMAStreamManagerDelegate per trasmettere eventi ed errori di streaming alla tua applicazione.

Per questo esempio, registra gli eventi relativi all'annuncio principale nella console:

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

Esegui l'app e, se l'operazione va a buon fine, puoi richiedere e riprodurre stream DAI di Google con l'SDK IMA. Per scoprire di più sulle funzionalità avanzate dell'SDK, consulta le altre guide elencate nella barra laterale a sinistra o gli esempi su GitHub.