เริ่มต้น

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

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

ภาพรวมของ IMA DAI

การใช้ IMA DAI ประกอบด้วยคอมโพเนนต์ SDK หลัก 3 ส่วนซึ่งแสดงในคู่มือนี้

  • IMAAdDisplayContainer: ออบเจ็กต์คอนเทนเนอร์ที่ตั้งอยู่บนองค์ประกอบการเล่นวิดีโอและเก็บองค์ประกอบ UI ของโฆษณา
  • IMAAdsLoader: ออบเจ็กต์ที่ขอสตรีมและจัดการเหตุการณ์ที่ทริกเกอร์โดยคําขอการตอบกลับของสตรีม คุณควรสร้างอินสแตนซ์ตัวโหลดโฆษณาเพียงรายการเดียว ซึ่งสามารถนํากลับมาใช้ใหม่ได้ตลอดอายุการใช้งานของแอปพลิเคชัน
  • IMAStreamRequest IMAVODStreamRequest หรือ IMALiveStreamRequest: ออบเจ็กต์ที่กําหนดคําขอสตรีม คําขอสตรีมอาจเป็นได้ทั้งวิดีโอออนดีมานด์หรือสตรีมแบบสด คําขอจะระบุรหัสเนื้อหา รวมถึงคีย์ API หรือโทเค็นการตรวจสอบสิทธิ์และพารามิเตอร์อื่นๆ
  • IMAStreamManager: ออบเจ็กต์ที่จัดการสตรีมการแทรกโฆษณาแบบไดนามิกและการโต้ตอบกับแบ็กเอนด์ DAI ผู้จัดการสตรีมยังจัดการคําสั่ง ping สําหรับการติดตามและส่งต่อสตรีมและเหตุการณ์โฆษณาไปยังผู้เผยแพร่โฆษณาอีกด้วย

สิ่งที่ต้องดำเนินการก่อน

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

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

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

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

การติดตั้ง SDK โดยใช้ CocoaPods (แนะนํา)

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

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

    source 'https://github.com/CocoaPods/Specs.git'
    platform :tvos, '10'
    target "BasicExample" do
      pod 'GoogleAds-IMA-tvOS-SDK', '~> 4.2'
    end
    
  2. จากไดเรกทอรีที่มี Podfile ให้เรียกใช้ pod install --repo-update

  3. ยืนยันว่าการติดตั้งสําเร็จโดยเปิดไฟล์ BasicExample.xcworkspace และยืนยันว่ามี 2 โปรเจ็กต์ ได้แก่ BasicExample และ พ็อด (ทรัพยากร Dependency ที่ติดตั้งโดย 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. สร้างคําขอสตรีม

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

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 สูงสุด ให้ขอสิทธิ์ด้านความโปร่งใสและการติดตามแอปเพื่อใช้ IDFA