使用 IMA SDK,即可輕鬆將多媒體廣告整合至網站和應用程式。IMA SDK 可向任何 符合 VAST 規定的廣告伺服器請求廣告,並在應用程式中管理廣告播放。應用程式可透過 IMA DAI SDK,對廣告和內容影片 (隨選影片或直播內容) 提出串流請求。SDK 接著會傳回合併的影片串流,因此您不必在應用程式中管理廣告和內容影片之間的切換。
選取您感興趣的 DAI 解決方案
全方位服務 DAI
本指南說明如何將 IMA DAI SDK 整合至簡易影片播放器應用程式。如要查看或跟著完成範例整合,請從 GitHub 下載 BasicExample。
IMA DAI 總覽
如本指南所示,導入 IMA DAI 需使用三個主要 SDK 元件:
IMAAdDisplayContainer
: 位於影片播放元素頂端的容器物件,用於存放廣告 UI 元素。IMAAdsLoader
: 這個物件會要求串流,並處理串流要求回應物件觸發的事件。 您應該只例項化一個廣告載入器,這個載入器可在應用程式的整個生命週期中重複使用。IMAStreamRequest
:IMAVODStreamRequest
或IMALiveStreamRequest
:定義串流要求的物件。串流要求可以是隨選影片或直播串流。直播串流請求會指定素材資源金鑰,而 VOD 請求則會指定 CMS ID 和影片 ID。這兩種要求類型都可以選擇性地加入存取指定串流所需的 API 金鑰,以及 Google Ad Manager 聯播網代碼,供 IMA SDK 處理廣告 ID,如 Google Ad Manager 設定中所指定。IMAStreamManager
: 這個物件會處理動態廣告插播串流,以及與 DAI 後端的互動。串流管理工具也會處理追蹤 Ping,並將串流和廣告事件轉送給發布商。
必要條件
開始之前,請先備妥下列項目:
- Xcode 13 以上版本
- CocoaPods (建議使用)、Swift Package Manager,或下載的 tvOS 適用的 IMA DAI SDK 副本
建立新的 Xcode 專案
在 Xcode 中,使用 Objective-C 建立新的 tvOS 專案。使用 BasicExample 做為專案名稱。
將 IMA DAI SDK 新增至 Xcode 專案
請使用下列三種方法之一安裝 IMA DAI SDK。
使用 CocoaPods 安裝 SDK (建議)
CocoaPods 是 Xcode 專案的依附元件管理工具,建議您使用這個工具安裝 IMA DAI SDK。如要進一步瞭解如何安裝或使用 CocoaPods,請參閱 CocoaPods 說明文件。安裝 CocoaPods 後,請按照下列操作說明安裝 IMA DAI SDK:
在 BasicExample.xcodeproj 檔案所在的目錄中,建立名為 Podfile 的文字檔案,並新增下列設定:
source 'https://github.com/CocoaPods/Specs.git' platform :tvos, '14' target "BasicExample" do pod 'GoogleAds-IMA-tvOS-SDK', '~> 4.15.1' end
在包含 Podfile 的目錄中執行下列指令:
pod install --repo-update`
開啟 BasicExample.xcworkspace 檔案,確認其中包含兩個專案:BasicExample 和 Pods (CocoaPods 安裝的依附元件),藉此確認安裝是否成功。
使用 Swift Package Manager 安裝 SDK
自 4.8.2 版起,互動式媒體廣告 SDK 支援 Swift Package Manager。請按照下列步驟匯入 Swift 套件。
在 Xcode 中,依序前往「File」>「Add Packages」,安裝 GoogleInteractiveMediaAds Swift Package。
在顯示的提示中,搜尋 GoogleInteractiveMediaAds Swift Package GitHub 存放區:
https://github.com/googleads/swift-package-manager-google-interactive-media-ads-tvos
選取要使用的 GoogleInteractiveMediaAds Swift 套件版本。對於新專案,建議使用「Up to Next Major Version」。
完成後,Xcode 會解析套件依附元件,並在背景下載。如要進一步瞭解如何新增套件依附元件,請參閱 Apple 的文章。
手動下載及安裝 SDK
如果不想使用 Swift Package Manager 或 CocoaPods,可以下載 IMA DAI SDK,然後手動新增至專案。
建立簡易影片播放器
首先,請導入基本影片播放器。一開始,這個播放器不會使用 IMA DAI 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
匯入 SDK 並新增 IMA 互動的虛設常式
將 IMA DAI 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
實作 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;
}
提出串流要求
建立幾個常數來保存串流資訊,然後實作串流要求函式來提出要求。
ViewController.m
#import <GoogleInteractiveMediaAds/GoogleInteractiveMediaAds.h>
static NSString *const kAssetKey = @"sN_IYUG8STe1ZzhIIE_ksA";
static NSString *const kContentSourceID = @"2548831";
static NSString *const kVideoID = @"tears-of-steel";
static NSString *const kNetworkCode = @"21775744923";
@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
networkCode:kNetworkCode
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
// networkCode:kNetworkCode
// adDisplayContainer:adDisplayContainer
// videoDisplay:videoDisplay];
[self.adsLoader requestStreamWithRequest:request];
}
處理串流事件
IMAAdsLoader
和 IMAStreamManager
會觸發事件,用於處理初始化、錯誤和串流狀態變化。這些事件會透過 IMAAdsLoaderDelegate
和 IMAStreamManagerDelegate
協定觸發。監聽廣告載入事件,並初始化串流。如果廣告無法載入,請改為播放備用串流。
ViewController.m
static NSString *const kAssetKey = @"sN_IYUG8STe1ZzhIIE_ksA";
static NSString *const kContentSourceID = @"2548831";
static NSString *const kVideoID = @"tears-of-steel";
static NSString *const kNetworkCode = @"21775744923";
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
處理記錄和錯誤事件
串流管理員委派可處理多種事件,但對於基本實作,最重要的用途是執行事件記錄、在廣告播放期間防止搜尋動作,以及處理錯誤。
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 and show the ad controls.
self.adContainerView.hidden = NO;
break;
}
case kIMAAdEvent_AD_BREAK_ENDED: {
// Allow user seek through after an ad ends and hide the ad controls.
self.adContainerView.hidden = YES;
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 DAI SDK 請求及顯示廣告。如要瞭解更多進階 SDK 功能,請參閱其他指南或 GitHub 上的範例。