ตั้งค่า IMA SDK สําหรับ DAI

เลือกแพลตฟอร์ม: HTML5 Android iOS tvOS Cast Roku

IMA SDK ช่วยให้ผสานรวมโฆษณามัลติมีเดียเข้ากับเว็บไซต์และแอปได้อย่างง่ายดาย IMA SDK สามารถ ขอโฆษณาจากเซิร์ฟเวอร์โฆษณา ที่รองรับ VAST และจัดการการเล่นโฆษณาในแอปได้ เมื่อใช้ IMA DAI SDK แอปจะส่งคำขอสตรีมสำหรับโฆษณาและเนื้อหาวิดีโอ ไม่ว่าจะเป็นเนื้อหา VOD หรือเนื้อหาสด จากนั้น SDK จะแสดงสตรีมวิดีโอที่รวมกัน เพื่อให้คุณไม่ต้องจัดการการสลับระหว่างโฆษณาและวิดีโอเนื้อหา ภายในแอป

เลือกโซลูชัน DAI ที่คุณสนใจ

DAI แบบบริการเต็มรูปแบบ

คู่มือนี้แสดงวิธีผสานรวม IMA DAI SDK เข้ากับแอปโปรแกรมเล่นวิดีโออย่างง่าย หากต้องการดูหรือทำตามตัวอย่างการผสานรวมที่เสร็จสมบูรณ์แล้ว ให้ดาวน์โหลด BasicExample จาก GitHub

ภาพรวม DAI ของ IMA

การติดตั้งใช้งาน IMA DAI มีองค์ประกอบ SDK หลัก 3 อย่างดังที่แสดงในคำแนะนำนี้

  • IMAAdDisplayContainer: ออบเจ็กต์คอนเทนเนอร์ที่อยู่เหนือองค์ประกอบการเล่นวิดีโอและมีองค์ประกอบ UI ของโฆษณา
  • IMAAdsLoader: ออบเจ็กต์ที่ขอสตรีมและจัดการเหตุการณ์ที่ทริกเกอร์โดยออบเจ็กต์การตอบกลับคำขอสตรีม คุณควรสร้างอินสแตนซ์ของ AdsLoader เพียงรายการเดียว ซึ่งสามารถนำกลับมาใช้ใหม่ได้ตลอดอายุการใช้งานของแอปพลิเคชัน
  • IMAStreamRequest – either a IMAVODStreamRequest or a IMALiveStreamRequest: ออบเจ็กต์ที่กำหนดคำขอสตรีม คำขอสตรีมอาจเป็นคำขอสำหรับวิดีโอออนดีมานด์หรือไลฟ์สด คำขอไลฟ์สดจะระบุคีย์เนื้อหา ส่วนคำขอ VOD จะระบุรหัส CMS และรหัสวิดีโอ คำขอทั้ง 2 ประเภทอาจมีคีย์ API ที่จำเป็นต่อการเข้าถึงสตรีมที่ระบุ และรหัสเครือข่าย Google Ad Manager สำหรับ IMA SDK เพื่อจัดการตัวระบุโฆษณาตามที่ระบุในการตั้งค่า Google Ad Manager
  • IMAStreamManager: ออบเจ็กต์ที่จัดการสตรีมการแทรกโฆษณาแบบไดนามิกและการโต้ตอบกับแบ็กเอนด์ DAI นอกจากนี้ ตัวจัดการสตรีมยังจัดการการติดตาม Ping และส่งต่อเหตุการณ์สตรีมและโฆษณาไปยัง ผู้เผยแพร่โฆษณาด้วย

ข้อกำหนดเบื้องต้น

ก่อนเริ่มต้น คุณต้องมีสิ่งต่อไปนี้

สร้างโปรเจ็กต์ Xcode ใหม่

ใน Xcode ให้สร้างโปรเจ็กต์ tvOS ใหม่โดยใช้ Objective-C ใช้ BasicExample เป็น ชื่อโปรเจ็กต์

เพิ่ม IMA DAI SDK ลงในโปรเจ็กต์ Xcode

ใช้วิธีใดวิธีหนึ่งต่อไปนี้เพื่อติดตั้ง IMA DAI SDK

ติดตั้ง SDK โดยใช้ Swift Package Manager

SDK โฆษณาสื่ออินเทอร์แอกทีฟรองรับ Swift Package Manager ตั้งแต่เวอร์ชัน 4.8.2 เป็นต้นไป ทำตาม ขั้นตอนต่อไปนี้เพื่อนำเข้าแพ็กเกจ Swift

  1. ใน Xcode ให้ติดตั้งแพ็กเกจ Swift ของ GoogleInteractiveMediaAds โดยไปที่File > Add Packages

  2. ในพรอมต์ที่ปรากฏขึ้น ให้ค้นหาที่เก็บ GitHub ของ GoogleInteractiveMediaAds Swift Package

    https://github.com/googleads/swift-package-manager-google-interactive-media-ads-tvos
    
  3. เลือกเวอร์ชันของแพ็กเกจ Swift ของ GoogleInteractiveMediaAds ที่ต้องการใช้ สำหรับโปรเจ็กต์ใหม่ เราขอแนะนำให้ใช้อัปเดตเป็นเวอร์ชันหลักถัดไป

เมื่อดำเนินการเสร็จแล้ว Xcode จะแก้ไขการขึ้นต่อกันของแพ็กเกจและดาวน์โหลดไว้ในเบื้องหลัง ดูรายละเอียดเพิ่มเติมเกี่ยวกับวิธีเพิ่มการอ้างอิงแพ็กเกจได้ที่ บทความของ Apple

ติดตั้ง SDK โดยใช้ CocoaPods

CocoaPods เป็นเครื่องมือจัดการทรัพยากร Dependency สำหรับโปรเจ็กต์ Xcode และเป็นวิธีที่แนะนำในการติดตั้ง IMA DAI SDK ดูข้อมูลเพิ่มเติมเกี่ยวกับการติดตั้งหรือการใช้ CocoaPods ได้ที่เอกสารประกอบของ CocoaPods เมื่อติดตั้ง CocoaPods แล้ว ให้ใช้วิธีการต่อไปนี้เพื่อติดตั้ง IMA DAI SDK

  1. ในไดเรกทอรีเดียวกับไฟล์ BasicExample.xcodeproj ให้สร้างไฟล์ข้อความ ชื่อ Podfile แล้วเพิ่มการกำหนดค่าต่อไปนี้

    source 'https://github.com/CocoaPods/Specs.git'
    platform :tvos, '15'
    target "BasicExample" do
      pod 'GoogleAds-IMA-tvOS-SDK', '~> 4.16.0'
    end
    
  2. จากไดเรกทอรีที่มี Podfile ให้เรียกใช้คำสั่งต่อไปนี้

    pod install --repo-update
  3. ยืนยันว่าการติดตั้งสำเร็จโดยเปิดไฟล์ BasicExample.xcworkspace แล้วตรวจสอบว่ามี 2 โปรเจ็กต์ ได้แก่ BasicExample และ Pods (ทรัพยากร Dependency ที่ติดตั้งโดย CocoaPods)

การดาวน์โหลดและติดตั้ง SDK ด้วยตนเอง

หากไม่ต้องการใช้ Swift Package Manager หรือ CocoaPods คุณสามารถดาวน์โหลด IMA DAI SDK และเพิ่มลงในโปรเจ็กต์ด้วยตนเองได้

นำเข้า IMA SDK

เพิ่มเฟรมเวิร์ก IMA โดยใช้คำสั่งนำเข้า

Objective-C

#import "ViewController.h"
#import <AVKit/AVKit.h>

@import GoogleInteractiveMediaAds;

Swift

import AVFoundation
import GoogleInteractiveMediaAds
import UIKit

สร้างวิดีโอเพลเยอร์และผสานรวม IMA SDK

ตัวอย่างต่อไปนี้เริ่มต้น IMA SDK

Objective-C

// Live stream asset key, VOD content source and video IDs, and backup content URL.
static NSString *const kAssetKey = @"c-rArva4ShKVIAkNfy6HUQ";
static NSString *const kContentSourceID = @"2548831";
static NSString *const kVideoID = @"tears-of-steel";
static NSString *const kNetworkCode = @"21775744923";
static NSString *const kBackupStreamURLString =
    @"http://googleimadev-vh.akamaihd.net/i/big_buck_bunny/bbb-,480p,720p,1080p,.mov.csmil/"
    @"master.m3u8";
static const StreamType kDefaultStreamType = StreamTypeLive;

@interface ViewController () <IMAAdsLoaderDelegate,
                              IMAStreamManagerDelegate,
                              AVPlayerViewControllerDelegate>
@property(nonatomic) IMAAdsLoader *adsLoader;
@property(nonatomic) IMAAdDisplayContainer *adDisplayContainer;
@property(nonatomic) UIView *adContainerView;
@property(nonatomic) id<IMAVideoDisplay> videoDisplay;
@property(nonatomic) IMAStreamManager *streamManager;
@property(nonatomic) AVPlayerViewController *playerViewController;
@property(nonatomic, getter=isAdBreakActive) BOOL adBreakActive;
@end

@implementation ViewController

- (void)viewDidLoad {
  [super viewDidLoad];
  self.view.backgroundColor = [UIColor blackColor];
  self.streamType = kDefaultStreamType;
  [self setupAdsLoader];
  [self setupPlayer];
  [self setupAdContainer];
}

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

- (void)setupPlayer {
  // Create a stream video player.
  AVPlayer *player = [[AVPlayer alloc] init];
  self.playerViewController = [[AVPlayerViewController alloc] init];
  self.playerViewController.player = player;

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

Swift

class ViewController:
  UIViewController,
  IMAAdsLoaderDelegate,
  IMAStreamManagerDelegate,
  AVPlayerViewControllerDelegate
{
  // Live stream asset key, VOD content source and video IDs, Google Ad Manager network code, and
  // backup content URL.
  static let assetKey = "c-rArva4ShKVIAkNfy6HUQ"
  static let contentSourceID = "2548831"
  static let videoID = "tears-of-steel"
  static let networkCode = "21775744923"
  static let backupStreamURLString =
    "http://googleimadev-vh.akamaihd.net/i/big_buck_bunny/bbb-,480p,720p,1080p,.mov.csmil/master.m3u8"

  var adsLoader: IMAAdsLoader?
  var videoDisplay: IMAAVPlayerVideoDisplay!
  var adDisplayContainer: IMAAdDisplayContainer?
  var adContainerView: UIView?
  private var streamManager: IMAStreamManager?
  private var contentPlayhead: IMAAVPlayerContentPlayhead?
  private var playerViewController: AVPlayerViewController!
  private var userSeekTime = 0.0
  private var adBreakActive = false

  private enum StreamType {
    case live
    /// Video on demand.
    case vod
  }

  /// Set the stream type here.
  private let currentStreamType: StreamType = .live

  deinit {
    NotificationCenter.default.removeObserver(self)
  }

  override func viewDidLoad() {
    super.viewDidLoad()
    self.view.backgroundColor = UIColor.black

    setupAdsLoader()
    setupPlayer()
    setupAdContainer()
  }

  override func viewDidAppear(_ animated: Bool) {
    super.viewDidAppear(animated)
    requestStream()
  }

  func setupPlayer() {
    let player = AVPlayer()
    let playerViewController = AVPlayerViewController()
    playerViewController.delegate = self
    playerViewController.player = player

    // Set up our content playhead and contentComplete callback.
    contentPlayhead = IMAAVPlayerContentPlayhead(avPlayer: player)
    NotificationCenter.default.addObserver(
      self,
      selector: #selector(ViewController.contentDidFinishPlaying(_:)),
      name: NSNotification.Name.AVPlayerItemDidPlayToEndTime,
      object: player.currentItem)

    self.addChild(playerViewController)
    playerViewController.view.frame = self.view.bounds
    self.view.insertSubview(playerViewController.view, at: 0)
    playerViewController.didMove(toParent: self)
    self.playerViewController = playerViewController
  }

ใน viewDidLoad() setupAdsLoader() จะสร้าง IMAAdsLoader setupPlayer() จะสร้าง AVPlayerViewController และ setupAdContainer() จะเตรียม UIView เพื่อแสดงโฆษณา เมื่อมุมมองปรากฏขึ้น viewDidAppear() จะเรียกใช้ requestStream() เพื่อขอสตรีม DAI

ตัวอย่างนี้ใช้ค่าคงที่ เช่น asset key สำหรับไลฟ์สด หรือ content source ID และ video ID สำหรับสตรีม VOD เพื่อกำหนดพารามิเตอร์คำขอสตรีม นอกจากนี้ ตัวอย่างยังใช้คอมโพเนนต์ต่อไปนี้เพื่อจัดการ IMA SDK

  • adsLoader: จัดการคำขอสตรีมไปยัง Google Ad Manager เราขอแนะนำให้ใช้ อินสแตนซ์เดียวสำหรับวงจรของแอป
  • videoDisplay: การติดตั้งใช้งาน IMAVideoDisplay ที่อนุญาตให้ IMA ควบคุม การเล่นวิดีโอและติดตามเหตุการณ์การเล่นโดยใช้ AVPlayer
  • adDisplayContainer: จัดการมุมมองที่ใช้ในการแสดงผลองค์ประกอบ UI ของโฆษณาและ จัดการโฟกัส UI ระหว่างช่วงพักโฆษณา
  • streamManager: จัดการการเล่นสตรีมโฆษณาและเนื้อหารวมกัน และ ส่งเหตุการณ์วงจรโฆษณาโดยใช้ผู้มอบสิทธิ์
  • playerViewController: เพลเยอร์ tvOS ที่ใช้เพื่อนำเสนอวิดีโอ สตรีมที่จัดการโดย IMA SDK
  • adBreakActive: แฟล็กบูลีนที่ระบุว่าช่วงพักโฆษณากำลังเล่นอยู่หรือไม่ ใช้เพื่อ ป้องกันการกรอโฆษณาและจัดการโฟกัส UI

ติดตั้งใช้งาน IMAAdsLoader

จากนั้นสร้างอินสแตนซ์ของ IMAAdsLoader และแนบมุมมองคอนเทนเนอร์โฆษณากับลำดับชั้นของ View

Objective-C

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

- (void)setupAdContainer {
  // Attach the ad container to the view hierarchy on top of the player.
  self.adContainerView = [[UIView alloc] init];
  [self.view addSubview:self.adContainerView];
  self.adContainerView.frame = self.view.bounds;
  // Keep hidden initially, until an ad break.
  self.adContainerView.hidden = YES;
}

Swift

func setupAdsLoader() {
  let adsLoader = IMAAdsLoader(settings: nil)
  adsLoader.delegate = self
  self.adsLoader = adsLoader
}

func setupAdContainer() {
  // Attach the ad container to the view hierarchy on top of the player.
  let adContainerView = UIView()
  self.view.addSubview(adContainerView)
  adContainerView.frame = self.view.bounds
  // Keep hidden initially, until an ad break.
  adContainerView.isHidden = true
  self.adContainerView = adContainerView
}

ส่งคำขอสตรีม

สร้างค่าคงที่ 2-3 รายการเพื่อเก็บข้อมูลสตรีม แล้วใช้ฟังก์ชันคำขอสตรีมเพื่อส่งคำขอ

Objective-C

- (void)requestStream {
  self.videoDisplay =
      [[IMAAVPlayerVideoDisplay alloc] initWithAVPlayer:self.playerViewController.player];
  self.adDisplayContainer = [[IMAAdDisplayContainer alloc] initWithAdContainer:self.adContainerView
                                                                viewController:self];

  // Use the streamType property to determine which request to create.
  IMAStreamRequest *request;

  switch (self.streamType) {
    case StreamTypeLive: {
      request = [[IMALiveStreamRequest alloc] initWithAssetKey:kAssetKey
                                                   networkCode:kNetworkCode
                                            adDisplayContainer:self.adDisplayContainer
                                                  videoDisplay:self.videoDisplay
                                                   userContext:nil];
      NSLog(@"IMA: Requesting Live Stream with Asset Key: %@.", kAssetKey);
      break;
    }
    case StreamTypeVOD: {
      request = [[IMAVODStreamRequest alloc] initWithContentSourceID:kContentSourceID
                                                             videoID:kVideoID
                                                         networkCode:kNetworkCode
                                                  adDisplayContainer:self.adDisplayContainer
                                                        videoDisplay:self.videoDisplay
                                                         userContext:nil];
      NSLog(@"IMA: Requesting VOD Stream with Video ID: %@.", kVideoID);
      break;
    }
  }

  if (request) {
    [self.adsLoader requestStreamWithRequest:request];
  } else {
    // Fallback or error handling if no request object was created
    NSLog(@"IMA Error: Could not create stream request for unknown type.");
    [self playBackupStream];
  }
}

Swift

func requestStream() {
  guard let playerViewController = self.playerViewController else { return }
  guard let adContainerView = self.adContainerView else { return }
  guard let adsLoader = self.adsLoader else { return }

  self.videoDisplay = IMAAVPlayerVideoDisplay(avPlayer: playerViewController.player!)
  let adDisplayContainer = IMAAdDisplayContainer(
    adContainer: adContainerView, viewController: self)
  self.adDisplayContainer = adDisplayContainer

  // Variable to hold the specific stream request object.
  let request: IMAStreamRequest

  switch self.currentStreamType {
  case .live:
    // Create a live stream request.
    request = IMALiveStreamRequest(
      assetKey: ViewController.assetKey,
      networkCode: ViewController.networkCode,
      adDisplayContainer: adDisplayContainer,
      videoDisplay: self.videoDisplay,
      pictureInPictureProxy: nil,
      userContext: nil)
    print("IMA: Requesting Live Stream with asset key \(ViewController.assetKey)")

  case .vod:
    // Create a VOD stream request.
    request = IMAVODStreamRequest(
      contentSourceID: ViewController.contentSourceID,
      videoID: ViewController.videoID,
      networkCode: ViewController.networkCode,
      adDisplayContainer: adDisplayContainer,
      videoDisplay: self.videoDisplay,
      pictureInPictureProxy: nil,
      userContext: nil)
    print(
      "IMA: Requesting VOD Stream with content source ID \(ViewController.contentSourceID) and "
        + "video ID \(ViewController.videoID)")
  }

  adsLoader.requestStream(with: request)
}

จัดการเหตุการณ์สตรีม

IMAAdsLoader และ IMAStreamManager จะทริกเกอร์เหตุการณ์ที่ใช้เพื่อจัดการการเริ่มต้น ข้อผิดพลาด และการเปลี่ยนแปลงสถานะสตรีม เหตุการณ์เหล่านี้จะทริกเกอร์ผ่านโปรโตคอล IMAAdsLoaderDelegate และ IMAStreamManagerDelegate รอ เหตุการณ์โฆษณาที่โหลดแล้วและเริ่มต้นสตรีม หากโฆษณาโหลดไม่สำเร็จ ให้เล่นสตรีมสำรองแทน

Objective-C

- (void)playBackupStream {
  NSURL *backupStreamURL = [NSURL URLWithString:kBackupStreamURLString];
  [self.videoDisplay loadStream:backupStreamURL withSubtitles:@[]];
  [self.videoDisplay play];
  [self startMediaSession];
}

- (void)startMediaSession {
  [[AVAudioSession sharedInstance] setActive:YES error:nil];
  [[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategoryPlayback error:nil];
}

#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];
}

Swift

@objc func contentDidFinishPlaying(_ notification: Notification) {
  guard let adsLoader = self.adsLoader else { return }
  adsLoader.contentComplete()
}

func startMediaSession() {
  try? AVAudioSession.sharedInstance().setActive(true, options: [])
  try? AVAudioSession.sharedInstance().setCategory(.playback)
}

// MARK: - IMAAdsLoaderDelegate

func adsLoader(_ loader: IMAAdsLoader, adsLoadedWith adsLoadedData: IMAAdsLoadedData) {
  let streamManager = adsLoadedData.streamManager!
  streamManager.delegate = self
  streamManager.initialize(with: nil)
  self.streamManager = streamManager
}

func adsLoader(_ loader: IMAAdsLoader, failedWith adErrorData: IMAAdLoadingErrorData) {
  print("Error loading ads: \(adErrorData.adError.message)")
  let streamUrl = URL(string: ViewController.backupStreamURLString)
  self.videoDisplay.loadStream(streamUrl!, withSubtitles: [])
  self.videoDisplay.play()
  playerViewController.player?.play()
}

จัดการเหตุการณ์การบันทึกและข้อผิดพลาด

มีเหตุการณ์หลายอย่างที่ตัวแทน Stream Manager จัดการได้ แต่ สำหรับการติดตั้งใช้งานขั้นพื้นฐาน การใช้งานที่สำคัญที่สุดคือการบันทึกเหตุการณ์ เพื่อป้องกันการดำเนินการค้นหาขณะที่โฆษณากำลังเล่น และเพื่อจัดการข้อผิดพลาด

Objective-C

#pragma mark - IMAStreamManagerDelegate

- (void)streamManager:(IMAStreamManager *)streamManager didReceiveAdEvent:(IMAAdEvent *)event {
  NSLog(@"StreamManager event (%@).", event.typeString);
  switch (event.type) {
    case kIMAAdEvent_STREAM_STARTED: {
      [self startMediaSession];
      break;
    }
    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: {
      self.adContainerView.hidden = NO;
      // Trigger an update to send focus to the ad display container.
      self.adBreakActive = YES;
      [self setNeedsFocusUpdate];
      break;
    }
    case kIMAAdEvent_AD_BREAK_ENDED: {
      self.adContainerView.hidden = YES;
      // Trigger an update to send focus to the content player.
      self.adBreakActive = NO;
      [self setNeedsFocusUpdate];
      break;
    }
    case kIMAAdEvent_ICON_FALLBACK_IMAGE_CLOSED: {
      // Resume playback after the user has closed the dialog.
      [self.videoDisplay play];
      break;
    }
    default:
      break;
  }
}

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

Swift

// MARK: - IMAStreamManagerDelegate
func streamManager(_ streamManager: IMAStreamManager, didReceive event: IMAAdEvent) {
  print("StreamManager event \(event.typeString).")
  switch event.type {
  case IMAAdEventType.STREAM_STARTED:
    self.startMediaSession()
  case IMAAdEventType.STARTED:
    // Log extended data.
    if let ad = event.ad {
      let extendedAdPodInfo = String(
        format: "Showing ad %zd/%zd, bumper: %@, title: %@, "
          + "description: %@, contentType:%@, pod index: %zd, "
          + "time offset: %lf, max duration: %lf.",
        ad.adPodInfo.adPosition,
        ad.adPodInfo.totalAds,
        ad.adPodInfo.isBumper ? "YES" : "NO",
        ad.adTitle,
        ad.adDescription,
        ad.contentType,
        ad.adPodInfo.podIndex,
        ad.adPodInfo.timeOffset,
        ad.adPodInfo.maxDuration)

      print("\(extendedAdPodInfo)")
    }
    break
  case IMAAdEventType.AD_BREAK_STARTED:
    if let adContainerView = self.adContainerView {
      adContainerView.isHidden = false
    }
    // Trigger an update to send focus to the ad display container.
    adBreakActive = true
    setNeedsFocusUpdate()
    break
  case IMAAdEventType.AD_BREAK_ENDED:
    if let adContainerView = self.adContainerView {
      adContainerView.isHidden = true
    }
    // Trigger an update to send focus to the content player.
    adBreakActive = false
    setNeedsFocusUpdate()
    break
  case IMAAdEventType.ICON_FALLBACK_IMAGE_CLOSED:
    // Resume playback after the user has closed the dialog.
    self.videoDisplay.play()
    break
  default:
    break
  }
}

func streamManager(_ streamManager: IMAStreamManager, didReceive error: IMAAdError) {
  print("StreamManager error: \(error.message ?? "Unknown Error")")
}

เท่านี้ก็เรียบร้อย ตอนนี้คุณขอและแสดงโฆษณาด้วย IMA DAI SDK แล้ว หากต้องการดูข้อมูลเพิ่มเติมเกี่ยวกับฟีเจอร์ SDK ขั้นสูงอื่นๆ โปรดดูคำแนะนำอื่นๆ หรือตัวอย่างใน GitHub