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 do lado do cliente do IMA, você mantém o controle da reprodução de vídeo do conteúdo, enquanto o SDK gerencia a reprodução do anúncio. Os anúncios são reproduzidos em um player de vídeo separado posicionado no player de vídeo do 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 do lado do cliente do IMA
A implementação do lado do cliente do IMA envolve quatro componentes principais do SDK, que são demonstrados neste guia:
IMAAdDisplayContainer
: é um objeto contêiner em que os anúncios são renderizados.IMAAdsLoader
: um objeto que solicita anúncios e processa eventos de respostas de solicitações de anúncios. Só é possível instanciar um carregador de anúncios, que pode ser reutilizado ao longo da vida útil do aplicativo.IMAAdsRequest
: um objeto que define uma solicitação de anúncios. As solicitações de anúncios especificam o URL da tag de anúncio VAST, bem como parâmetros adicionais, como dimensões de anúncio.IMAAdsManager
: um objeto que contém a resposta à solicitação de anúncios, controla a reprodução dos anúncios e detecta os eventos de anúncios disparados pelo SDK.
Pré-requisitos
Antes de começar, os seguintes itens são necessários:
- Xcode 9.2 ou posterior
- CocoaPods (preferencial) ou uma cópia do SDK do IMA para tvOS disponível para download
1. Criar um novo projeto do Xcode
No Xcode, crie um novo projeto tvOS usando Objective-C ou Swift. 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:
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
No diretório que contém o Podfile, execute
pod install --repo-update
.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
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. Importar o SDK do IMA
Em seguida, adicione o framework do IMA usando uma instrução de importação abaixo das importações existentes.
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. Implementar o tracker de reprodução do conteúdo e o observador no fim da transmissão
Para reproduzir anúncios intermediários, o SDK do IMA precisa rastrear a posição atual
do conteúdo em vídeo. Para fazer isso, crie uma classe que implemente
IMAContentPlayhead
. Se você estiver usando um AVPlayer
, como mostrado neste exemplo,
o SDK fornecerá a classe IMAAVPlayerContentPlayhead
que fará isso por você.
Se você não estiver usando AVPlayer
, vai precisar implementar IMAContentPlayhead
em
uma classe própria.
Também é necessário informar o SDK quando o conteúdo for reproduzido para
exibir anúncios finais. Para isso, chame contentComplete
no
IMAAdsLoader
usando 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. Inicializar o carregador de anúncios e fazer uma solicitação de anúncios
Para solicitar um conjunto de anúncios, você precisa criar uma instância de IMAAdsLoader
.
Esse carregador pode ser usado para processar objetos IMAAdsRequest
associados a um URL de tag de anúncio especificado.
Como prática recomendada, mantenha apenas uma instância de IMAAdsLoader
durante todo o
ciclo de vida do app. Para fazer outras solicitações de anúncios, crie um novo
objeto IMAAdsRequest
, mas reutilize o mesmo IMAAdsLoader
. Para mais
informações, consulte as Perguntas frequentes sobre o SDK do 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. Configurar um delegado do carregador de anúncios
Em um evento de carregamento bem-sucedido, o IMAAdsLoader
chama o método adsLoadedWithData
do delegado atribuído, transmitindo uma instância de IMAAdsManager
. Em seguida, você pode inicializar o gerenciador de anúncios, que carrega os anúncios individuais, conforme definido pela resposta ao URL da tag de anúncio.
Além disso, processe todos os erros que podem ocorrer durante o processo de carregamento. Caso os anúncios não sejam carregados, a reprodução de mídia precisa continuar sem anúncios para não interferir na experiência do usuário.
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. Configurar um delegado do gerenciador de anúncios
Por fim, para gerenciar eventos e mudanças de estado, o gerenciador de anúncios precisa de um delegado. O IMAAdManagerDelegate
tem métodos para processar erros e eventos de anúncios,
além de métodos para acionar a reprodução e pausar no conteúdo de vídeo.
Iniciando reprodução
Há muitos eventos que o método didReceiveAdEvent
pode usar para processar, mas, neste exemplo básico, basta detectar o evento LOADED
para dizer ao gerenciador de anúncios para iniciar a reprodução do conteúdo e dos anúncios.
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() } } ...
Como processar os erros
Adicione também um gerenciador para erros de anúncios. Se ocorrer um erro, como na etapa anterior, retome a reprodução do conteúdo.
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() }
Como acionar eventos de reprodução e pausa
Os dois últimos métodos delegados que você precisa implementar são usados para acionar eventos de reprodução e pausação no conteúdo de vídeo subjacente, quando solicitado pelo SDK do IMA. O acionamento da pausa e da exibição quando solicitado impede que o usuário perca partes do conteúdo de vídeo quando os anúncios são exibidos.
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() } }
Pronto! Agora você está solicitando e exibindo anúncios com o SDK do IMA. Para saber mais sobre outros recursos 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.