Commencer

Les SDK IMA permettent d'intégrer facilement des annonces multimédias à vos sites Web et applications. Les SDK IMA peuvent demander des annonces à n'importe quel ad server compatible VAST et gérer la lecture des annonces dans vos applications. Avec les SDK IMA côté client, vous contrôlez la lecture des contenus vidéo, tandis que le SDK gère la lecture des annonces. Les annonces sont diffusées dans un lecteur vidéo distinct, placé sur le lecteur vidéo de l'application.

Ce guide explique comment intégrer le SDK IMA à une application de lecteur vidéo simple. Si vous souhaitez afficher ou suivre un exemple d'intégration terminé, téléchargez BasicExample à partir de GitHub.

Présentation côté client IMA

L'implémentation côté client IMA implique quatre composants SDK principaux, décrits dans ce guide:

  • IMAAdDisplayContainer : objet de conteneur dans lequel les annonces sont affichées.
  • IMAAdsLoader : objet qui demande des annonces et gère les événements à partir des réponses de demande d'annonce. Vous ne devez instancier qu'un seul chargeur d'annonces, qui peut être réutilisé tout au long de la durée de vie de l'application.
  • IMAAdsRequest : objet qui définit une demande d'annonce. Les demandes d'annonces spécifient l'URL du tag d'emplacement publicitaire VAST, ainsi que des paramètres supplémentaires tels que les dimensions de l'annonce.
  • IMAAdsManager : objet qui contient la réponse à la demande d'annonce, contrôle la lecture de l'annonce et écoute les événements d'annonce déclenchés par le SDK.

Prérequis

Avant de commencer, vous avez besoin des éléments suivants :

1. Créer un projet Xcode

Dans Xcode, créez un projet tvOS à l'aide d'Objective-C ou de Swift. Utilisez BasicExample comme nom de projet.

2. Ajouter le SDK IMA au projet Xcode

Installer le SDK à l'aide de CocoaPods (recommandé)

CocoaPods est un gestionnaire de dépendances pour les projets Xcode. Il s'agit de la méthode recommandée pour installer le SDK IMA. Pour en savoir plus sur l'installation ou l'utilisation de CocoaPods, consultez la documentation de CocoaPods. Une fois que CocoaPods est installé, procédez comme suit pour installer le SDK IMA:

  1. Dans le même répertoire que votre fichier BasicExample.xcodeproj, créez un fichier texte nommé Podfile et ajoutez la configuration suivante:

    source 'https://github.com/CocoaPods/Specs.git'
    platform :tvos, '10'
    target "BasicExample" do
      pod 'GoogleAds-IMA-tvOS-SDK', '~> 4.2'
    end
    
  2. À partir du répertoire contenant le Podfile, exécutez pod install --repo-update.

  3. Vérifiez que l'installation a réussi en ouvrant le fichier BasicExample.xcworkspace et en vérifiant qu'il contient deux projets : BasicExample et Pods (les dépendances installées par CocoaPods).

Télécharger et installer manuellement le SDK

Si vous ne souhaitez pas utiliser CocoaPods, vous pouvez télécharger le SDK IMA et l'ajouter manuellement à votre projet.

3. Créer un lecteur vidéo simple

Commencez par implémenter un lecteur vidéo de base. Dans un premier temps, ce lecteur n'utilise pas le SDK IMA et ne contient aucune méthode pour déclencher la lecture pour le moment.

ViewController.m

Objective-C

#import "ViewController.h"

#import <AVKit/AVKit.h>

NSString *const kContentURLString =
    @"https://storage.googleapis.com/interactive-media-ads/media/bipbop.m3u8";

@interface ViewController ()
@property(nonatomic) AVPlayerViewController *contentPlayerViewController;
@end

@implementation ViewController

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

- (void)setupContentPlayer {
  // Create a content video player.
  NSURL *contentURL = [NSURL URLWithString:kContentURLString];
  AVPlayer *player = [AVPlayer playerWithURL:contentURL];
  self.contentPlayerViewController = [[AVPlayerViewController alloc] init];
  self.contentPlayerViewController.player = player;
  self.contentPlayerViewController.view.frame = self.view.bounds;

  // Attach content video player to view hierarchy.
  [self showContentPlayer];
}

// Add the content video player as a child view controller.
- (void)showContentPlayer {
  [self addChildViewController:self.contentPlayerViewController];
  self.contentPlayerViewController.view.frame = self.view.bounds;
  [self.view insertSubview:self.contentPlayerViewController.view atIndex:0];
  [self.contentPlayerViewController didMoveToParentViewController:self];
}

// Remove and detach the content video player.
- (void)hideContentPlayer {
  // The whole controller needs to be detached so that it doesn't capture events from the remote.
  [self.contentPlayerViewController willMoveToParentViewController:nil];
  [self.contentPlayerViewController.view removeFromSuperview];
  [self.contentPlayerViewController removeFromParentViewController];
}

@end
      

Swift

import AVFoundation
import UIKit

class ViewController: UIViewController {
  static let ContentURLString = "https://storage.googleapis.com/interactive-media-ads/media/bipbop.m3u8"

  var playerViewController: AVPlayerViewController!

  override func viewDidLoad() {
    super.viewDidLoad()
    self.view.backgroundColor = UIColor.black;
    setUpContentPlayer()
  }

  func setUpContentPlayer() {
    // Load AVPlayer with path to your content.
    let contentURL! = URL(string: ViewController.ContentURLString)
    let player = AVPlayer(url: contentURL)
    playerViewController = AVPlayerViewController()
    playerViewController.player = player

    showContentPlayer()
  }

  func showContentPlayer() {
    self.addChild(playerViewController)
    playerViewController.view.frame = self.view.bounds
    self.view.insertSubview(playerViewController.view, at: 0)
    playerViewController.didMove(toParent:self)
  }

  func hideContentPlayer() {
    // The whole controller needs to be detached so that it doesn't capture  events from the remote.
    playerViewController.willMove(toParent:nil)
    playerViewController.view.removeFromSuperview()
    playerViewController.removeFromParent()
  }
}
      

4. Importer le SDK IMA

Ajoutez ensuite le framework IMA à l'aide d'une instruction d'importation, sous les importations existantes.

ViewController.m

Objective-C

#import "ViewController.h"

#import <AVKit/AVKit.h>
#import <GoogleInteractiveMediaAds/GoogleInteractiveMediaAds.h>
NSString *const kContentURLString =
    @"https://storage.googleapis.com/interactive-media-ads/media/bipbop.m3u8";
      

Swift

import AVFoundation
import GoogleInteractiveMediaAds
import UIKit

class ViewController: UIViewController {
  static let ContentURLString = "https://devstreaming-cdn.apple.com/videos/streaming/examples/img_bipbop_adv_example_fmp4/master.m3u8"
      

5. Implémenter le suivi de la tête de lecture de contenu et un observateur de fin de flux

Pour pouvoir lire les annonces mid-roll, le SDK IMA doit suivre la position actuelle de votre contenu vidéo. Pour ce faire, créez une classe qui implémente IMAContentPlayhead. Si vous utilisez un AVPlayer, comme illustré dans cet exemple, le SDK fournit la classe IMAAVPlayerContentPlayhead qui s'en charge pour vous. Si vous n'utilisez pas AVPlayer, vous devez implémenter IMAContentPlayhead sur votre propre classe.

Vous devez également indiquer au SDK la fin de la lecture de votre contenu pour qu'il puisse afficher des annonces post-roll. Pour ce faire, appelez contentComplete sur IMAAdsLoader à l'aide de AVPlayerItemDidPlayToEndTimeNotification.

ViewController.m

Objective-C

...

@interface ViewController ()
@property(nonatomic) IMAAVPlayerContentPlayhead *contentPlayhead;
@property(nonatomic) AVPlayerViewController *contentPlayerViewController;
@end

...

- (void)setupContentPlayer {
  // Create a content video player.
  NSURL *contentURL = [NSURL URLWithString:kContentURLString];
  AVPlayer *player = [AVPlayer playerWithURL:contentURL];
  self.contentPlayerViewController = [[AVPlayerViewController alloc] init];
  self.contentPlayerViewController.player = player;
  self.contentPlayerViewController.view.frame = self.view.bounds;
  self.contentPlayhead =
      [[IMAAVPlayerContentPlayhead alloc] initWithAVPlayer:self.contentPlayerViewController.player];

  // Track end of content.
  AVPlayerItem *contentPlayerItem = self.contentPlayerViewController.player.currentItem;
  [NSNotificationCenter.defaultCenter addObserver:self
                                         selector:@selector(contentDidFinishPlaying:)
                                             name:AVPlayerItemDidPlayToEndTimeNotification
                                           object:contentPlayerItem];

  // Attach content video player to view hierarchy.
  [self showContentPlayer];
}

...

- (void)contentDidFinishPlaying:(NSNotification *)notification {}

- (void)dealloc {
  [NSNotificationCenter.defaultCenter removeObserver:self];
}

@end
      

Swift

...

class ViewController: UIViewController {
  static let ContentURLString = "https://devstreaming-cdn.apple.com/videos/streaming/examples/img_bipbop_adv_example_fmp4/master.m3u8"

  var contentPlayhead: IMAAVPlayerContentPlayhead?
  var playerViewController: AVPlayerViewController!

  deinit {
    NotificationCenter.default.removeObserver(self)
  }

...

  func setUpContentPlayer() {
    // Load AVPlayer with path to your content.
    let contentURL! = URL(string: ViewController.ContentURLString)
    let player = AVPlayer(url: contentURL)
    playerViewController = AVPlayerViewController()
    playerViewController.player = player

    // Set up your content playhead and contentComplete callback.
    contentPlayhead = IMAAVPlayerContentPlayhead(avPlayer: player)
    NotificationCenter.default.addObserver(
      self,
      selector: #selector(ViewController.contentDidFinishPlaying(_:)),
      name: NSNotification.Name.AVPlayerItemDidPlayToEndTime,
      object: player.currentItem);

    showContentPlayer()
  }

...

  @objc func contentDidFinishPlaying(_ notification: Notification) {
    adsLoader.contentComplete()
  }
}
      

6. Initialiser le chargeur d'annonces et effectuer une demande d'annonce

Pour demander un ensemble d'annonces, vous devez créer une instance IMAAdsLoader. Ce chargeur permet de traiter des objets IMAAdsRequest associés à une URL de tag d'emplacement publicitaire spécifiée.

Nous vous recommandons de ne conserver qu'une seule instance de IMAAdsLoader pour l'ensemble du cycle de vie de votre application. Pour envoyer des demandes d'annonces supplémentaires, créez un objet IMAAdsRequest, mais réutilisez le même IMAAdsLoader. Pour en savoir plus, consultez les questions fréquentes concernant le SDK IMA.

ViewController.m

Objective-C

...

NSString *const kContentURLString =
    @"https://devstreaming-cdn.apple.com/videos/streaming/examples/img_bipbop_adv_example_fmp4/"
    @"master.m3u8";
NSString *const kAdTagURLString = @"https://pubads.g.doubleclick.net/gampad/ads?"
    @"iu=/21775744923/external/vmap_ad_samples&sz=640x480&"
    @"cust_params=sample_ar%3Dpremidpostlongpod&"
    @"ciu_szs=300x250&gdfp_req=1&ad_rule=1&output=vmap&unviewed_position_start=1&"
    @"env=vp&impl=s&cmsid=496&vid=short_onecue&correlator=";

@interface ViewController ()
@property(nonatomic) IMAAdsLoader *adsLoader;
@property(nonatomic) IMAAVPlayerContentPlayhead *contentPlayhead;
@property(nonatomic) AVPlayerViewController *contentPlayerViewController;
@end

@implementation ViewController

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

- (void)viewDidAppear:(BOOL)animated {
  [super viewDidAppear:animated];
  [self requestAds];
}

- (void)setupAdsLoader {
  self.adsLoader = [[IMAAdsLoader alloc] init];
}

- (void)requestAds {
  // Pass the main view as the container for ad display.
  IMAAdDisplayContainer *adDisplayContainer =
      [[IMAAdDisplayContainer alloc] initWithAdContainer:self.view];
  IMAAdsRequest *request = [[IMAAdsRequest alloc] initWithAdTagUrl:kAdTagURLString
                                                adDisplayContainer:adDisplayContainer
                                                   contentPlayhead:self.contentPlayhead
                                                       userContext:nil];
  [self.adsLoader requestAdsWithRequest:request];
}

...

- (void)contentDidFinishPlaying:(NSNotification *)notification {
  // Notify the SDK that the postrolls should be played.
  [self.adsLoader contentComplete];
}

...

@end
      

Swift

...

class ViewController: UIViewController {
  static let ContentURLString = "https://devstreaming-cdn.apple.com/videos/streaming/examples/img_bipbop_adv_example_fmp4/master.m3u8"
  static let AdTagURLString = "https://pubads.g.doubleclick.net/gampad/ads?iu=/21775744923/external/single_ad_samples&sz=640x480&cust_params=sample_ct%3Dlinear&ciu_szs=300x250%2C728x90&gdfp_req=1&output=vast&unviewed_position_start=1&env=vp&impl=s&correlator="

  var adsLoader: IMAAdsLoader!
  var contentPlayhead: IMAAVPlayerContentPlayhead?
  var playerViewController: AVPlayerViewController!

...

  override func viewDidLoad() {
    super.viewDidLoad()
    self.view.backgroundColor = UIColor.black;
    setUpContentPlayer()
    setUpAdsLoader()
  }

  override func viewDidAppear(_ animated: Bool) {
    super.viewDidAppear(animated);
    requestAds()
  }

...

  func setUpAdsLoader() {
    adsLoader = IMAAdsLoader(settings: nil)
  }

  func requestAds() {
    // Create ad display container for ad rendering.
    let adDisplayContainer = IMAAdDisplayContainer(adContainer: self.view)
    // Create an ad request with your ad tag, display container, and optional user context.
    let request = IMAAdsRequest(
        adTagUrl: ViewController.AdTagURLString,
        adDisplayContainer: adDisplayContainer,
        contentPlayhead: contentPlayhead,
        userContext: nil)

    adsLoader.requestAds(with: request)
  }

  @objc func contentDidFinishPlaying(_ notification: Notification) {
    adsLoader.contentComplete()
  }
}
      

7. Configurer un délégué de chargeur d'annonces

Lors d'un événement de chargement réussi, IMAAdsLoader appelle la méthode adsLoadedWithData du délégué qui lui a été attribué, en lui transmettant une instance de IMAAdsManager. Vous pouvez ensuite initialiser le gestionnaire d'annonces, qui charge les annonces individuelles, comme défini par la réponse à l'URL du tag d'emplacement publicitaire.

Veillez également à gérer les erreurs susceptibles de se produire lors du processus de chargement. Si les annonces ne se chargent pas, assurez-vous que la lecture de contenus multimédias se poursuit sans publicité, afin de ne pas perturber l'expérience utilisateur.

ViewController.m

Objective-C

...

@interface ViewController () <IMAAdsLoaderDelegate>
@property(nonatomic) IMAAdsLoader *adsLoader;
@property(nonatomic) IMAAdsManager *adsManager;
@property(nonatomic) IMAAVPlayerContentPlayhead *contentPlayhead;
@property(nonatomic) AVPlayerViewController *contentPlayerViewController;
@end

@implementation ViewController

...

- (void)setupAdsLoader {
  self.adsLoader = [[IMAAdsLoader alloc] init];
  self.adsLoader.delegate = self;
}

...

#pragma mark - IMAAdsLoaderDelegate

- (void)adsLoader:(IMAAdsLoader *)loader adsLoadedWithData:(IMAAdsLoadedData *)adsLoadedData {
  // Initialize and listen to the ads manager loaded for this request.
  self.adsManager = adsLoadedData.adsManager;
  [self.adsManager initializeWithAdsRenderingSettings:nil];
}

- (void)adsLoader:(IMAAdsLoader *)loader failedWithErrorData:(IMAAdLoadingErrorData *)adErrorData {
  // Fall back to playing content.
  NSLog(@"Error loading ads: %@", adErrorData.adError.message);
  [self.contentPlayerViewController.player play];
}

@end
      

Swift

...

class ViewController: UIViewController, IMAAdsLoaderDelegate {

...

  var adsLoader: IMAAdsLoader!
  var adsManager: IMAAdsManager!
  var contentPlayhead: IMAAVPlayerContentPlayhead?
  var playerViewController: AVPlayerViewController!

...

  func setUpAdsLoader() {
    adsLoader = IMAAdsLoader(settings: nil)
    adsLoader.delegate = self
  }

...

  // MARK: - IMAAdsLoaderDelegate

  func adsLoader(_ loader: IMAAdsLoader!, adsLoadedWith adsLoadedData: IMAAdsLoadedData!) {
    adsManager = adsLoadedData.adsManager
    adsManager.initialize(with: nil)
  }

  func adsLoader(_ loader: IMAAdsLoader!, failedWith adErrorData: IMAAdLoadingErrorData!) {
    print("Error loading ads: " + adErrorData.adError.message)
    showContentPlayer()
    playerViewController.player?.play()
  }
}
      

8. Configurer un délégué pour le gestionnaire des annonces

Enfin, pour gérer les événements et les changements d'état, le gestionnaire des annonces a besoin d'un délégué. IMAAdManagerDelegate propose des méthodes pour gérer les erreurs et les événements d'annonce, ainsi que pour déclencher la lecture et la mise en pause de votre contenu vidéo.

Démarrage de la lecture

La méthode didReceiveAdEvent permet de gérer de nombreux événements. Toutefois, pour cet exemple de base, il suffit d'écouter l'événement LOADED pour indiquer au gestionnaire d'annonces de lancer la lecture du contenu et des annonces.

ViewController.m

Objective-C

@interface ViewController () <IMAAdsLoaderDelegate, IMAAdsManagerDelegate>

...

- (void)adsLoader:(IMAAdsLoader *)loader adsLoadedWithData:(IMAAdsLoadedData *)adsLoadedData {
  // Initialize and listen to the ads manager loaded for this request.
  self.adsManager = adsLoadedData.adsManager;
  self.adsManager.delegate = self;
  [self.adsManager initializeWithAdsRenderingSettings:nil];
}

...

#pragma mark - IMAAdsManagerDelegate

- (void)adsManager:(IMAAdsManager *)adsManager didReceiveAdEvent:(IMAAdEvent *)event {
  // Play each ad once it has loaded.
  if (event.type == kIMAAdEvent_LOADED) {
    [adsManager start];
  }
}

...
      

Swift

...

class ViewController: UIViewController, IMAAdsLoaderDelegate, IMAAdsManagerDelegate {

...

  func adsLoader(_ loader: IMAAdsLoader!, adsLoadedWith adsLoadedData: IMAAdsLoadedData!) {
    // Grab the instance of the IMAAdsManager and set yourself as the delegate.
    adsManager = adsLoadedData.adsManager
    adsManager.delegate = self
    adsManager.initialize(with: nil)
  }

...

  // MARK: - IMAAdsManagerDelegate

  func adsManager(_ adsManager: IMAAdsManager!, didReceive event: IMAAdEvent!) {
    // Play each ad once it has been loaded
    if event.type == IMAAdEventType.LOADED {
      adsManager.start()
    }
  }

...
      

Traiter les erreurs

Ajouter un gestionnaire pour les erreurs liées aux annonces Si une erreur se produit, comme lors de l'étape précédente, reprenez la lecture du contenu.

ViewController.m

Objective-C


...

- (void)adsManager:(IMAAdsManager *)adsManager didReceiveAdError:(IMAAdError *)error {
  // Fall back to playing content.
  NSLog(@"AdsManager error: %@", error.message);
  [self showContentPlayer];
  [self.contentPlayerViewController.player play];
}
@end
      

Swift

...

  func adsManager(_ adsManager: IMAAdsManager!, didReceive error: IMAAdError!) {
    // Fall back to playing content
    print("AdsManager error: " + error.message)
    showContentPlayer()
    playerViewController.player?.play()
  }
      

Déclencher des événements de lecture et de mise en pause

Les deux dernières méthodes déléguées que vous devez implémenter sont utilisées pour déclencher des événements de lecture et de mise en pause sur le contenu vidéo sous-jacent, à la demande du SDK IMA. Le déclenchement de la mise en pause et de la lecture lorsque cela est demandé empêche l'utilisateur de lire des portions manquantes du contenu vidéo lors de l'affichage des annonces.

ViewController.m

Objective-C

...

- (void)adsManagerDidRequestContentPause:(IMAAdsManager *)adsManager {
  // Pause the content for the SDK to play ads.
  [self.contentPlayerViewController.player pause];
  [self hideContentPlayer];
}

- (void)adsManagerDidRequestContentResume:(IMAAdsManager *)adsManager {
  // Resume the content since the SDK is done playing ads (at least for now).
  [self showContentPlayer];
  [self.contentPlayerViewController.player play];
}

@end
      

Swift

...

  func adsManagerDidRequestContentPause(_ adsManager: IMAAdsManager!) {
    // Pause the content for the SDK to play ads.
    playerViewController.player?.pause()
    hideContentPlayer()
  }

  func adsManagerDidRequestContentResume(_ adsManager: IMAAdsManager!) {
    // Resume the content since the SDK is done playing ads (at least for now).
    showContentPlayer()
    playerViewController.player?.play()
  }
}
      

Et voilà ! Vous demandez et affichez les annonces via le SDK IMA. Pour en savoir plus sur les fonctionnalités supplémentaires du SDK, consultez les autres guides ou les exemples sur GitHub.

Étapes suivantes

Afin de maximiser les revenus publicitaires sur la plate-forme tvOS, demandez l'autorisation du suivi des applications et de la transparence des applications pour utiliser l'IDFA.