Vamos começar

Os SDKs do IMA facilitam a integração de anúncios multimídia nos seus sites e apps. Os SDKs do IMA podem solicitar anúncios de qualquer servidor compatível com VAST e gerenciar a exibição de anúncios nos seus apps. Com os SDKs da DAI do IMA, os apps fazem uma solicitação de stream de vídeo e conteúdo de vídeo, seja VOD ou de conteúdo ao vivo. Em seguida, o SDK retorna um stream de vídeo combinado para que você não precise gerenciar a alternância entre anúncios em vídeo e de conteúdo no seu app.

Este guia demonstra como integrar o SDK do IMA a um app de player de vídeo simples. Se você quiser ver ou acompanhar um exemplo de integração concluída, faça o download do BasicExample no GitHub.

Visão geral da DAI do IMA

A implementação da DAI do IMA envolve três componentes principais do SDK, demonstrados neste guia:

  • IMAAdDisplayContainer: um objeto contêiner que fica sobre o elemento de reprodução de vídeo e hospeda os elementos da IU do anúncio.
  • IMAAdsLoader: um objeto que solicita streams e processa eventos acionados por objetos de resposta de solicitação de stream. Só é possível instanciar um carregador de anúncios, que pode ser reutilizado ao longo da vida útil do aplicativo.
  • IMAStreamRequest: um IMAVODStreamRequest ou um IMALiveStreamRequest: um objeto que define uma solicitação de stream. As solicitações de stream podem ser para transmissões ao vivo ou de vídeo on demand. As solicitações especificam um ID de conteúdo, uma chave de API ou um token de autenticação, além de outros parâmetros.
  • IMAStreamManager: é um objeto que processa interações e fluxos de inserção de anúncios dinâmicos com o back-end da DAI. O gerenciador de stream também processa pings de rastreamento e encaminha eventos de stream e de anúncio para o editor.

Pré-requisitos

Antes de começar, os seguintes itens são necessários:

1. Criar um novo projeto do Xcode

No Xcode, crie um novo projeto tvOS usando o Objective-C. Use BasicExample como o nome do projeto.

2. Adicionar o SDK do IMA ao projeto Xcode

Como instalar o SDK usando o CocoaPods (preferencial)

O CocoaPods é um gerenciador de dependências para projetos do Xcode e é o método recomendado para instalar o SDK do IMA. Para mais informações sobre como instalar ou usar o CocoaPods, consulte a documentação do CocoaPods. Depois de instalar o CocoaPods, use as seguintes instruções para instalar o SDK do IMA:

  1. No mesmo diretório do arquivo BasicExample.xcodeproj, crie um arquivo de texto chamado Podfile e adicione a seguinte configuração:

    source 'https://github.com/CocoaPods/Specs.git'
    platform :tvos, '10'
    target "BasicExample" do
      pod 'GoogleAds-IMA-tvOS-SDK', '~> 4.2'
    end
    
  2. No diretório que contém o Podfile, execute pod install --repo-update.

  3. Para verificar se a instalação foi bem-sucedida, abra o arquivo BasicExample.xcworkspace e confirme que ele contém dois projetos: BasicExample e Pods (as dependências instaladas pelo CocoaPods).

Como fazer o download e instalar o SDK manualmente

Se você não quiser usar o CocoaPods, faça o download do SDK do IMA e o adicione manualmente ao seu projeto.

3. Criar um player de vídeo simples

Primeiro, implemente um player de vídeo básico. Inicialmente, esse player não usa o SDK do IMA e ainda não contém nenhum método para acionar a reprodução.

ViewController.m

#import "ViewController.h"

#import <AVKit/AVKit.h>

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

@implementation ViewController

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

  // Create a stream video player.
  AVPlayer *player = [[AVPlayer alloc] init];
  self.playerViewController = [[AVPlayerViewController alloc] init];
  self.playerViewController.player = player;

  // Attach the video player to the view hierarchy.
  [self addChildViewController:self.playerViewController];
  self.playerViewController.view.frame = self.view.bounds;
  [self.view addSubview:self.playerViewController.view];
  [self.playerViewController didMoveToParentViewController:self];
}

@end

4. Importar o SDK e adicionar stubs para a interação do IMA

Depois de adicionar o SDK do IMA ao seu projeto, importe o SDK e adicione stubs para os principais pontos de interação do IMA.

ViewController.m

#import "ViewController.h"

#import <AVKit/AVKit.h>
#import <GoogleInteractiveMediaAds/GoogleInteractiveMediaAds.h>

@interface ViewController ()
@property(nonatomic) IMAAdsLoader *adsLoader;
@property(nonatomic) UIView *adContainerView;
@property(nonatomic) IMAStreamManager *streamManager;
@property(nonatomic) AVPlayerViewController *playerViewController;
@end

@implementation ViewController

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

  [self setupAdsLoader];

  // Create a stream video player.
  AVPlayer *player = [[AVPlayer alloc] init];
  self.playerViewController = [[AVPlayerViewController alloc] init];
  self.playerViewController.player = player;

  // Attach the video player to the view hierarchy.
  [self addChildViewController:self.playerViewController];
  self.playerViewController.view.frame = self.view.bounds;
  [self.view addSubview:self.playerViewController.view];
  [self.playerViewController didMoveToParentViewController:self];

  [self attachAdContainer];
}

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

- (void)setupAdsLoader {}

- (void)attachAdContainer {}

- (void)requestStream {}

@end

5. Implementar o IMAAdsLoader

Em seguida, instancie o IMAAdsLoader e anexe a visualização do contêiner de anúncios à hierarquia de visualização.

ViewController.m

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

- (void)attachAdContainer {
  self.adContainerView = [[UIView alloc] init];
  [self.view addSubview:self.adContainerView];
  self.adContainerView.frame = self.view.bounds;
}
...

6. Fazer uma solicitação de stream

Crie algumas constantes para armazenar as informações do stream e implemente a função de solicitação de stream para fazer a solicitação.

ViewController.m

...
#import <GoogleInteractiveMediaAds/GoogleInteractiveMediaAds.h>

static NSString *const kAssetKey = @"sN_IYUG8STe1ZzhIIE_ksA";
static NSString *const kContentSourceID = @"2528370";
static NSString *const kVideoID = @"tears-of-steel";

@interface ViewController ()
...

- (void)requestStream {
  IMAAVPlayerVideoDisplay *videoDisplay =
      [[IMAAVPlayerVideoDisplay alloc] initWithAVPlayer:self.playerViewController.player];
  IMAAdDisplayContainer *adDisplayContainer =
      [[IMAAdDisplayContainer alloc] initWithAdContainer:self.adContainerView];
  IMALiveStreamRequest *request = [[IMALiveStreamRequest alloc] initWithAssetKey:kAssetKey
                                                              adDisplayContainer:adDisplayContainer
                                                                    videoDisplay:videoDisplay];
  // VOD request. Comment out the IMALiveStreamRequest above and uncomment this IMAVODStreamRequest
  // to switch from a livestream to a VOD stream.
  // IMAVODStreamRequest *request =
  //     [[IMAVODStreamRequest alloc] initWithContentSourceId:kContentSourceID
  //                                                  videoId:kVideoID
  //                                       adDisplayContainer:adDisplayContainer
  //                                             videoDisplay:videoDisplay];
  [self.adsLoader requestStreamWithRequest:request];
}
...

7. Processar eventos de stream

Os eventos IMAAdsLoader e IMAStreamManager são usados para processar a inicialização, os erros e as alterações no estado do stream. Esses eventos são acionados nos protocolos IMAAdsLoaderDelegate e IMAStreamManagerDelegate. Detecte um evento de anúncio carregado e inicialize o stream. Se um anúncio não for carregado, reproduza um stream de backup.

ViewController.m

...
static NSString *const kAssetKey = @"sN_IYUG8STe1ZzhIIE_ksA";
static NSString *const kContentSourceID = @"2528370";
static NSString *const kVideoID = @"tears-of-steel";
static NSString *const kBackupStreamURLString =
    @"https://storage.googleapis.com/interactive-media-ads/media/bbb.m3u8";

@interface ViewController () <IMAAdsLoaderDelegate, IMAStreamManagerDelegate>

...
  [self.adsLoader requestStreamWithRequest:request];
}

- (void)playBackupStream {
  NSURL *backupStreamURL = [NSURL URLWithString:kBackupStreamURLString];
  AVPlayerItem *backupStreamItem = [AVPlayerItem playerItemWithURL:backupStreamURL];
  [self.playerViewController.player replaceCurrentItemWithPlayerItem:backupStreamItem];
  [self.playerViewController.player play];
}


#pragma mark - IMAAdsLoaderDelegate

- (void)adsLoader:(IMAAdsLoader *)loader adsLoadedWithData:(IMAAdsLoadedData *)adsLoadedData {
  // Initialize and listen to stream manager's events.
  self.streamManager = adsLoadedData.streamManager;
  self.streamManager.delegate = self;
  [self.streamManager initializeWithAdsRenderingSettings:nil];
  NSLog(@"Stream created with: %@.", self.streamManager.streamId);
}

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


#pragma mark - IMAStreamManagerDelegate

- (void)streamManager:(IMAStreamManager *)streamManager didReceiveAdEvent:(IMAAdEvent *)event {}

- (void)streamManager:(IMAStreamManager *)streamManager didReceiveAdError:(IMAAdError *)error {}

- (void)streamManager:(IMAStreamManager *)streamManager
  adDidProgressToTime:(NSTimeInterval)time
           adDuration:(NSTimeInterval)adDuration
           adPosition:(NSInteger)adPosition
             totalAds:(NSInteger)totalAds
      adBreakDuration:(NSTimeInterval)adBreakDuration {}

@end

8. Processar eventos de registro e erro

Há vários eventos que podem ser tratados pelo delegado do gerenciador de stream, mas, para implementações básicas, os usos mais importantes são realizar a geração de registros de eventos, para evitar ações de busca enquanto os anúncios são reproduzidos e lidar com erros.

ViewController.m

...
#pragma mark - IMAStreamManagerDelegate

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

      NSLog(@"%@", extendedAdPodInfo);
      break;
    }
    case kIMAAdEvent_AD_BREAK_STARTED: {
      // Prevent user seek through when an ad starts.
      self.playerViewController.requiresLinearPlayback = YES;
      break;
    }
    case kIMAAdEvent_AD_BREAK_ENDED: {
      // Allow users to seek through after an ad ends.
      self.playerViewController.requiresLinearPlayback = NO;
      break;
    }
    default:
      break;
  }
}

- (void)streamManager:(IMAStreamManager *)streamManager didReceiveAdError:(IMAAdError *)error {
  // Fall back to playing the backup stream.
  NSLog(@"StreamManager error: %@", error.message);
  [self playBackupStream];
}

@end

Pronto! Agora você está solicitando e exibindo anúncios com o SDK do IMA. Para saber mais sobre recursos mais avançados do SDK, consulte os outros guias ou as amostras no GitHub.

Próximas etapas

Para maximizar a receita de publicidade na plataforma tvOS, solicite a permissão de transparência e rastreamento do app para usar o IDFA.