使用 IMA SDK 即可輕鬆將互動式多媒體廣告整合至您的網站和應用程式。IMA SDK 能向任何 符合 VAST 規定的廣告伺服器請求廣告,並管理您應用程式中的廣告播放。使用 IMA DAI SDK,應用程式會對廣告與內容影片發出串流要求 (VOD 或直播內容)。接著,SDK 會傳回合併的影片串流,因此您不必管理應用程式中的廣告和內容影片之間切換。
本指南會說明如何將 IMA SDK 整合到簡單的影片播放器應用程式中。如果您想查看或遵循完成的範例整合,請從 GitHub 下載 BasicExample。
IMA 動態廣告插播總覽
導入 IMA DAI 會涉及三個主要的 SDK 元件,詳情請參閱本指南:
IMAAdDisplayContainer
: 位於影片播放元素頂端的容器物件,並保存廣告 UI 元素。IMAAdsLoader
:要求要求及處理串流要求回應物件觸發的事件的物件。您只能在一個廣告載入器中執行個體化,並在應用程式的整個生命週期中重複使用。IMAStreamRequest
:IMAVODStreamRequest
或IMALiveStreamRequest
:定義串流要求的物件。串流要求可以是隨選影片或直播活動。要求會指定內容 ID、API 金鑰或驗證權杖,以及其他參數。IMAStreamManager
: 處理動態廣告插播串流和 DAI 後端互動的物件。串流管理員也會處理追蹤連線偵測 (ping),並將串流和廣告事件轉送給發布商。
必要條件
開始操作前,您必須符合以下條件:
- Xcode 9.2 以上版本
- CocoaPods (建議) 或適用於 tvOS 的 IMA SDK 副本
1. 建立新的 Xcode 專案
在 Xcode 中,使用 Objective-C 建立新的 tvOS 專案。使用 BasicExample 做為專案名稱。
2. 將 IMA SDK 加入 Xcode 專案
使用 CocoaPods 安裝 SDK (建議)
CocoaPods 是 Xcode 專案的依附元件管理工具,也是安裝 IMA SDK 的建議方法。如要進一步瞭解如何安裝或使用 CocoaPods,請參閱 CocoaPods 說明文件。安裝 CocoaPods 後,請按照下列操作說明安裝 IMA SDK:
在與 BasicExample.xcodeproj 檔案相同的目錄中,建立名為 Podfile 的文字檔案,並新增下列設定:
source 'https://github.com/CocoaPods/Specs.git' platform :tvos, '10' target "BasicExample" do pod 'GoogleAds-IMA-tvOS-SDK', '~> 4.2' end
從包含 Podfile 的目錄中執行
pod install --repo-update
開啟 BasicExample.xcworkspace 檔案並確認其中含有兩個專案,分別是 BasicExample 和 Pods (由 CocoaPods 安裝的依附元件)。
手動下載並安裝 SDK
如果您不想使用 CocoaPods,您可以下載 IMA SDK,然後手動加進專案。
3. 建立簡單的影片播放器
首先,請實作基本影片播放器。這個播放器一開始未使用 IMA SDK,目前還沒有任何會觸發播放方法的方法。
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. 匯入 SDK 並新增 IMA 互動虛設常式
在專案中加入 IMA SDK 後,請匯入 SDK,並為 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. 導入 IMAAdsLoader
接著,請將 IMAAdsLoader
執行個體化,並將廣告容器檢視畫面附加至檢視區塊階層。
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. 提出直播要求
建立一些常數來保留串流資訊,然後實作串流要求函式來提出要求。
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. 處理串流事件
IMAAdsLoader
和 IMAStreamManager
會觸發事件,用於處理串流狀態的初始化、錯誤和變更。這些事件會透過 IMAAdsLoaderDelegate
和 IMAStreamManagerDelegate
通訊協定觸發。監聽廣告載入事件並初始化串流。如果廣告無法載入,請改為播放備份串流。
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. 處理記錄和錯誤事件
可由串流管理員委任的某些事件處理,但如果是基本導入,最重要的用途是執行事件記錄、避免廣告播放時執行搜尋動作,以及處理錯誤。
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
大功告成!您現在正在使用 IMA SDK 請求及顯示廣告。如要進一步瞭解進階 SDK 功能,請參閱其他指南或 GitHub 範例。
後續步驟
如要提高 tvOS 平台的廣告收益,請要求應用程式資訊公開和追蹤權限即可使用廣告識別碼。