開始使用 IMA DAI SDK

您可以使用 IMA SDK 輕鬆將多媒體廣告整合至網站和應用程式。IMA SDK 可向任何 符合 VAST 規定的廣告伺服器要求廣告,並管理應用程式中的廣告播放作業。透過 IMA DAI SDK,應用程式會針對廣告和內容影片 (隨選影片或直播內容) 提出串流要求。接著,SDK 會傳回合併的影片串流,因此您不必在應用程式中管理廣告和內容影片之間的切換。

選取感興趣的動態廣告解決方案

DAI 廣告連播放送

本指南將說明如何將 IMA DAI SDK 整合至簡單的影片播放器應用程式。如要查看或瞭解整合完成的範例,請從 GitHub 下載 PodServingExample

IMA DAI 總覽

實作 IMA DAI 時,需要使用四個主要 SDK 元件,如本指南所示:

此外,如要播放 Pod 服務串流,您必須實作自訂 VTP 處理常式。這個自訂 VTP 處理程序會將串流 ID 傳送給影片技術合作夥伴 (VTP),以及傳回包含內容和拼接廣告的串流資訊所需的任何其他資訊。VTP 會提供如何實作自訂 VTP 處理常式的操作說明。

必要條件

開始之前,請先準備下列項目:

您也需要用來從 IMA SDK 要求串流的參數。

直播參數
聯播網代碼 Ad Manager 360 帳戶的聯播網代碼。
範例:51636543
自訂素材資源金鑰 在 Ad Manager 360 中識別廣告單元放送事件的自訂素材資源鍵。資訊清單操控工具或第三方 Pod 放送合作夥伴可以建立這個資訊清單。
Example: google-sample
VOD 串流參數
聯播網代碼 Ad Manager 360 帳戶的聯播網代碼。
範例:51636543

建立新的 Xcode 專案

在 Xcode 中,使用 Objective-C 建立名為「PodServingExample」的新 iOS 專案。

將 IMA DAI SDK 新增至 Xcode 專案

請使用下列三種方法之一安裝 IMA DAI SDK。

使用 CocoaPods 安裝 SDK (建議)

CocoaPods 是 Xcode 專案的依附元件管理員,也是安裝 IMA DAI SDK 的建議方法。如要進一步瞭解如何安裝或使用 CocoaPods,請參閱 CocoaPods 說明文件。安裝 CocoaPods 後,請按照下列操作說明安裝 IMA DAI SDK:

  1. PodServingExample.xcodeproj 檔案所在的目錄中,建立名為 Podfile 的文字檔案,然後加入下列設定:

    source 'https://github.com/CocoaPods/Specs.git'
    
    platform :ios, '14'
    
    target 'PodServingExample' do
      pod 'GoogleAds-IMA-iOS-SDK'
    end
    

  2. 在包含 Podfile 的目錄中執行以下指令:

    pod install --repo-update

使用 Swift Package Manager 安裝 SDK

自 3.18.4 版起,互動式媒體廣告 SDK 支援 Swift Package Manager。請按照下列步驟匯入 Swift 套件。

  1. 在 Xcode 中,依序點選「File」>「Add Packages」,安裝 IMA DAI SDK Swift Package。

  2. 在出現的提示中,搜尋 IMA DAI SDK Swift Package GitHub 存放區:

    https://github.com/googleads/swift-package-manager-google-interactive-media-ads-ios
    
  3. 選取要使用的 IMA DAI SDK Swift 套件版本。對於新專案,建議您使用升級至下一個主要版本

完成後,Xcode 會解析套件依附元件,並在背景下載這些依附元件。如要進一步瞭解如何新增套件依附元件,請參閱 Apple 的文章

手動下載及安裝 SDK

如果您不想使用 Swift Package Manager 或 CocoaPods,可以下載 IMA DAI SDK,然後手動將其新增至專案。

建立簡單的影片播放器

在主要 View Controller 中實作影片播放器,使用包裝在 UI 檢視畫面中的 AV 播放器。IMA SDK 會使用 UI 檢視畫面顯示廣告 UI 元素。

#import "ViewController.h"

#import <AVKit/AVKit.h>

/// Content URL.
static NSString *const kBackupContentUrl =
    @"http://devimages.apple.com/iphone/samples/bipbop/bipbopall.m3u8";

@interface ViewController ()
/// Play button.
@property(nonatomic, weak) IBOutlet UIButton *playButton;

@property(nonatomic, weak) IBOutlet UIView *videoView;
/// Video player.
@property(nonatomic, strong) AVPlayer *videoPlayer;
@end

@implementation ViewController

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

  // Load AVPlayer with the path to your content.
  NSURL *contentURL = [NSURL URLWithString:kBackupContentUrl];
  self.videoPlayer = [AVPlayer playerWithURL:contentURL];

  // Create a player layer for the player.
  AVPlayerLayer *playerLayer = [AVPlayerLayer playerLayerWithPlayer:self.videoPlayer];

  // Size, position, and display the AVPlayer.
  playerLayer.frame = self.videoView.layer.bounds;
  [self.videoView.layer addSublayer:playerLayer];
}

- (IBAction)onPlayButtonTouch:(id)sender {
  [self.videoPlayer play];
  self.playButton.hidden = YES;
}

@end

初始化廣告載入器

將 IMA SDK 匯入至 View Controller,並採用 IMAAdsLoaderDelegateIMAStreamManagerDelegate 協定,以便處理廣告載入器和串流管理器事件。

新增下列私人屬性,以便儲存重要 IMA SDK 元件:

在檢視區載入後,初始化廣告載入器、廣告顯示容器和影片顯示功能。

@import GoogleInteractiveMediaAds;

// ...

@interface ViewController () <IMAAdsLoaderDelegate, IMAStreamManagerDelegate>
/// The entry point for the IMA DAI SDK to make DAI stream requests.
@property(nonatomic, strong) IMAAdsLoader *adsLoader;
/// The container where the SDK renders each ad's user interface elements and companion slots.
@property(nonatomic, strong) IMAAdDisplayContainer *adDisplayContainer;
/// The reference of your video player for the IMA DAI SDK to monitor playback and handle timed
/// metadata.
@property(nonatomic, strong) IMAAVPlayerVideoDisplay *imaVideoDisplay;
/// References the stream manager from the IMA DAI SDK after successful stream loading.
@property(nonatomic, strong) IMAStreamManager *streamManager;

// ...

@end

@implementation ViewController

- (void)viewDidLoad {
  [super viewDidLoad];

  // ...

  self.adsLoader = [[IMAAdsLoader alloc] initWithSettings:nil];
  self.adsLoader.delegate = self;

  // Create an ad display container for rendering each ad's user interface elements and companion
  // slots.
  self.adDisplayContainer =
      [[IMAAdDisplayContainer alloc] initWithAdContainer:self.videoView
                                          viewController:self
                                          companionSlots:nil];

  // Create an IMAAVPlayerVideoDisplay to give the SDK access to your video player.
  self.imaVideoDisplay = [[IMAAVPlayerVideoDisplay alloc] initWithAVPlayer:self.videoPlayer];
}

提出串流要求

當使用者按下播放按鈕時,請提出新的串流要求。將 IMAPodStreamRequest 類別用於直播。如為 VOD 串流,請使用 IMAPodVODStreamRequest 類別。

串流要求需要串流參數,以及廣告顯示容器和影片顯示的參照。

- (IBAction)onPlayButtonTouch:(id)sender {
  [self requestStream];
  self.playButton.hidden = YES;
}

- (void)requestStream {
  // Create a stream request.
  IMAStreamRequest *request;
  if (kStreamType == StreamTypeLive) {
    // Live stream request. Replace the network code and custom asset key with your values.
    request = [[IMAPodStreamRequest alloc] initWithNetworkCode:kNetworkCode
                                                customAssetKey:kCustomAssetKey
                                            adDisplayContainer:adDisplayContainer
                                                  videoDisplay:self.videoDisplay
                                         pictureInPictureProxy:nil
                                                   userContext:nil];
  } else {
    // VOD request. Replace the network code with your value.
    request = [[IMAPodVODStreamRequest alloc] initWithNetworkCode:@kNetworkCode
                                               adDisplayContainer:adDisplayContainer
                                                     videoDisplay:self.videoDisplay
                                            pictureInPictureProxy:nil
                                                      userContext:nil];
  }
  [self.adsLoader requestStreamWithRequest:request];
}

監聽串流載入事件

當串流要求初始化成功或失敗時,IMAAdsLoader 類別會呼叫 IMAAdsLoaderDelegate 方法。

adsLoadedWithData 委派方法中,設定 IMAStreamManagerDelegate。將串流 ID 傳遞至自訂 VTP 處理常式,並擷取串流資訊清單網址。針對直播,請將資訊清單網址載入至影片顯示畫面,並開始播放。如果是 VOD 串流,請將資訊清單網址傳遞至串流管理員的 loadThirdPartyStream 方法。這個方法會向 Ad Manager 360 要求廣告事件資料,然後載入資訊清單網址並開始播放。

failedWithErrorData 委派方法中記錄錯誤。視需要播放備用串流。請參閱 DAI 最佳做法

- (void)adsLoader:(IMAAdsLoader *)loader adsLoadedWithData:(IMAAdsLoadedData *)adsLoadedData {
  NSLog(@"Stream created with: %@.", adsLoadedData.streamManager.streamId);
  self.streamManager = adsLoadedData.streamManager;
  self.streamManager.delegate = self;

  // Build the Pod serving Stream URL.
  NSString *streamID = adsLoadedData.streamManager.streamId;
  // Your custom VTP handler takes the stream ID and returns the stream manifest URL.
  NSString *urlString = gCustomVTPHandler(streamID);
  NSURL *streamUrl = [NSURL URLWithString:urlString];
  if (kStreamType == StreamTypeLive) {
    // Load live streams directly into the AVPlayer.
    [self.videoDisplay loadStream:streamUrl withSubtitles:@[]];
    [self.videoDisplay play];
  } else {
    // Load VOD streams using the `loadThirdPartyStream` method in IMA SDK's stream manager.
    // The stream manager loads the stream, requests metadata, and starts playback.
    [self.streamManager loadThirdPartyStream:streamUrl streamSubtitles:@[]];
  }
}

- (void)adsLoader:(IMAAdsLoader *)loader failedWithErrorData:(IMAAdLoadingErrorData *)adErrorData {
  // Log the error and play the backup content.
  NSLog(@"AdsLoader error, code:%ld, message: %@", adErrorData.adError.code,
        adErrorData.adError.message);
  [self.videoPlayer play];
}

實作自訂 VTP 處理常式

自訂 VTP 處理程序會將觀眾的串流 ID 傳送給影片技術合作夥伴 (VTP),以及 VTP 需要傳回包含內容和拼接廣告的串流資訊。VTP 會提供具體操作說明,說明如何實作自訂 VTP 處理常式。

舉例來說,VTP 可能包含資訊清單範本網址,其中包含巨集 [[STREAMID]]。在這個範例中,處理程序會在巨集的位置插入串流 ID,並傳回產生的資訊清單網址。

/// Custom VTP Handler.
///
/// Returns the stream manifest URL from the video technical partner or manifest manipulator.
static NSString *(^gCustomVTPHandler)(NSString *) = ^(NSString *streamID) {
  // Insert synchronous code here to retrieve a stream manifest URL from your video tech partner
  // or manifest manipulation server.
  // This example uses a hardcoded URL template, containing a placeholder for the stream
  // ID and replaces the placeholder with the stream ID.
  NSString *manifestUrl = @"YOUR_MANIFEST_URL_TEMPLATE";
  return [manifestUrl stringByReplacingOccurrencesOfString:@"[[STREAMID]]"
                                                withString:streamID];
};

監聽廣告事件

IMAStreamManager 會呼叫 IMAStreamManagerDelegate 方法,將串流事件和錯誤傳遞至應用程式。

在本例中,請將主要廣告事件記錄到控制台:

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

      NSLog(@"%@", extendedAdPodInfo);
      break;
    }
    case kIMAAdEvent_AD_BREAK_STARTED: {
      NSLog(@"Ad break started");
      break;
    }
    case kIMAAdEvent_AD_BREAK_ENDED: {
      NSLog(@"Ad break ended");
      break;
    }
    case kIMAAdEvent_AD_PERIOD_STARTED: {
      NSLog(@"Ad period started");
      break;
    }
    case kIMAAdEvent_AD_PERIOD_ENDED: {
      NSLog(@"Ad period ended");
      break;
    }
    default:
      break;
  }
}

- (void)streamManager:(IMAStreamManager *)streamManager didReceiveAdError:(IMAAdError *)error {
  NSLog(@"StreamManager error with type: %ld\ncode: %ld\nmessage: %@", error.type, error.code,
        error.message);
  [self.videoPlayer play];
}

清理 IMA DAI 素材資源

如要停止串流播放、停止所有廣告追蹤,並釋放所有已載入的串流資產,請呼叫 IMAStreamManager.destroy()

執行應用程式,如果成功,您就可以使用 IMA SDK 要求及播放 Google DAI 串流。如要進一步瞭解更進階的 SDK 功能,請參閱左側邊欄列出的其他指南,或參閱 GitHub 上的範例