시작하기

IMA SDK를 사용하면 멀티미디어 광고를 웹사이트와 앱에 쉽게 통합할 수 있습니다. IMA SDK는 원하는 형식에서 광고를 <ph type="x-smartling-placeholder"></ph> VAST 호환 광고 서버를 사용하고 앱에서 광고 재생을 관리할 수 있습니다. IMA 클라이언트 측 SDK를 사용하면 SDK는 광고 재생을 처리하는 동안 콘텐츠 동영상 재생은 계속 제어할 수 있습니다. 다음 시간 동안 광고 재생 앱의 콘텐츠 동영상 플레이어 위에 배치된 별도의 동영상 플레이어입니다.

이 가이드에서는 IMA SDK를 간단한 동영상 플레이어에 통합하는 방법을 보여줍니다. 있습니다. 완성된 샘플을 보거나 함께 보고 싶다면 통합하려면 BasicExample GitHub를 참고하세요.

IMA 클라이언트 측 개요

IMA 클라이언트 측 구현에는 네 가지 주요 SDK 구성요소가 필요하며, 다음 사항을 참조하세요.

  • IMAAdDisplayContainer: 광고가 렌더링되는 컨테이너 객체입니다.
  • IMAAdsLoader: 광고를 요청하고 광고 요청 응답의 이벤트를 처리하는 객체입니다. 다음과 같은 경우에만 하나의 광고 로더를 인스턴스화할 수 있습니다. 이는 애플리케이션의 수명 주기 동안 재사용될 수 있습니다.
  • IMAAdsRequest: 광고 요청을 정의하는 객체입니다. 광고 요청은 VAST 광고 태그의 URL뿐 아니라 광고 크기와 같은 추가 매개변수
  • IMAAdsManager: 광고 요청에 대한 응답을 포함하고, 광고 재생을 제어하며, 광고를 리슨하는 객체입니다. SDK에 의해 발생한 이벤트

기본 요건

시작하기 전에 다음이 필요합니다.

1. 새 Xcode 프로젝트 만들기

Xcode에서 Objective-C 또는 Swift를 사용하여 새 tvOS 프로젝트를 만듭니다. 사용 BasicExample을 프로젝트 이름으로 사용합니다.

2. Xcode 프로젝트에 IMA SDK 추가

CocoaPods를 사용하여 SDK 설치 (권장)

CocoaPods는 Xcode 프로젝트의 종속 항목 관리자이며 메서드를 참조하세요. 설치 또는 사용에 대한 자세한 내용은 CocoaPods는 CocoaPods 문서를 참고하세요. 작업한 후에는 CocoaPods가 설치되어 있는 경우 다음 안내에 따라 IMA SDK를 설치하세요.

  1. BasicExample.xcodeproj 파일과 동일한 디렉터리에 텍스트를 만듭니다. Podfile 파일을 만들고 다음 구성을 추가합니다.

    source 'https://github.com/CocoaPods/Specs.git'
    platform :tvos, '14'
    target "BasicExample" do
      pod 'GoogleAds-IMA-tvOS-SDK', '~> 4.13.0'
    end
    
  2. Podfile이 있는 디렉터리에서 pod install --repo-update를 실행합니다.

  3. 다음 명령어를 열어 설치가 완료되었는지 확인합니다. BasicExample.xcworkspace 파일을 열고 다음 두 프로젝트가 포함되어 있는지 확인합니다. BasicExamplePods (CocoaPods에서 설치한 종속 항목).

Swift Package Manager를 사용하여 SDK 설치

양방향 미디어 광고 SDK에서 지원하는 Swift 패키지 Manager를 사용할 수 있습니다. Swift 패키지를 가져오려면 아래 단계를 따르세요.

  1. Xcode에서 파일 > 패키지 추가...를 클릭합니다.

  2. 메시지가 표시되면 IMA SDK Swift Package GitHub를 검색합니다. 저장소:

    https://github.com/googleads/swift-package-manager-google-interactive-media-ads-tvos
    
  3. 사용할 IMA SDK Swift 패키지의 버전을 선택합니다. 새 프로젝트의 경우 Up to Next Major Version(최대 다음 메이저 버전)을 사용하는 것이 좋습니다.

완료되면 Xcode가 패키지 종속 항목을 확인하고 백그라운드에서 다운로드됩니다. 패키지 추가 방법에 관한 자세한 내용은 자세한 내용은 Apple의 도움말

수동으로 SDK 다운로드 및 설치

CocoaPods를 사용하지 않으려면 IMA SDK를 다운로드하여 프로젝트에 추가합니다

3. 간단한 동영상 플레이어 만들기

먼저 기본 동영상 플레이어를 구현합니다. 처음에 이 플레이어는 아직 재생을 트리거하는 메서드가 포함되어 있지 않습니다.

ViewController.m

Objective-C

#import "ViewController.h"

#import <AVKit/AVKit.h>

NSString *const kContentURLString =
    @"https://storage.googleapis.com/interactive-media-ads/media/stock.mp4";

@interface ViewController ()
@property(nonatomic) AVPlayerViewController *contentPlayerViewController;
@end

@implementation ViewController

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

- (void)setupContentPlayer {
  // Create a content video player.
  NSURL *contentURL = [NSURL URLWithString:kContentURLString];
  AVPlayer *player = [AVPlayer playerWithURL:contentURL];
  self.contentPlayerViewController = [[AVPlayerViewController alloc] init];
  self.contentPlayerViewController.player = player;
  self.contentPlayerViewController.view.frame = self.view.bounds;

  // Attach content video player to view hierarchy.
  [self showContentPlayer];
}

// Add the content video player as a child view controller.
- (void)showContentPlayer {
  [self addChildViewController:self.contentPlayerViewController];
  self.contentPlayerViewController.view.frame = self.view.bounds;
  [self.view insertSubview:self.contentPlayerViewController.view atIndex:0];
  [self.contentPlayerViewController didMoveToParentViewController:self];
}

// Remove and detach the content video player.
- (void)hideContentPlayer {
  // The whole controller needs to be detached so that it doesn't capture events from the remote.
  [self.contentPlayerViewController willMoveToParentViewController:nil];
  [self.contentPlayerViewController.view removeFromSuperview];
  [self.contentPlayerViewController removeFromParentViewController];
}

@end
      

Swift

import AVFoundation
import UIKit

class ViewController: UIViewController {
  static let ContentURLString = "https://storage.googleapis.com/interactive-media-ads/media/stock.mp4"

  var playerViewController: AVPlayerViewController!

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

  func setUpContentPlayer() {
    // Load AVPlayer with path to your content.
    let contentURL! = URL(string: ViewController.ContentURLString)
    let player = AVPlayer(url: contentURL)
    playerViewController = AVPlayerViewController()
    playerViewController.player = player

    showContentPlayer()
  }

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

  func hideContentPlayer() {
    // The whole controller needs to be detached so that it doesn't capture  events from the remote.
    playerViewController.willMove(toParent:nil)
    playerViewController.view.removeFromSuperview()
    playerViewController.removeFromParent()
  }
}
      

4. IMA SDK 가져오기

그런 다음 기존 가져올 수 있습니다

ViewController.m

Objective-C

#import "ViewController.h"

#import <AVKit/AVKit.h>
#import <GoogleInteractiveMediaAds/GoogleInteractiveMediaAds.h>
NSString *const kContentURLString =
    @"https://storage.googleapis.com/interactive-media-ads/media/stock.mp4";
      

Swift

import AVFoundation
import GoogleInteractiveMediaAds
import UIKit

class ViewController: UIViewController {
  static let ContentURLString = "https://storage.googleapis.com/interactive-media-ads/media/stock.mp4"
      

5. 콘텐츠 플레이헤드 추적기 및 스트림 종료 관찰자 구현

미드롤 광고를 재생하려면 IMA SDK가 현재 위치를 추적해야 합니다. 도움이 될 수 있습니다 이렇게 하려면 IMAContentPlayhead 이 예와 같이 AVPlayer를 사용하는 경우 SDK는 이 작업을 실행하는 IMAAVPlayerContentPlayhead 클래스를 제공합니다. AVPlayer을(를) 사용하지 않는 경우 IMAContentPlayhead 자체 클래스를 만들 수 있습니다.

또한 콘텐츠 재생이 완료되면 SDK에 알려주어야 표시할 수 있습니다. 이 작업은 contentComplete AVPlayerItemDidPlayToEndTimeNotification를 사용하는 IMAAdsLoader

ViewController.m

Objective-C

...

@interface ViewController ()
@property(nonatomic) IMAAVPlayerContentPlayhead *contentPlayhead;
@property(nonatomic) AVPlayerViewController *contentPlayerViewController;
@end

...

- (void)setupContentPlayer {
  // Create a content video player.
  NSURL *contentURL = [NSURL URLWithString:kContentURLString];
  AVPlayer *player = [AVPlayer playerWithURL:contentURL];
  self.contentPlayerViewController = [[AVPlayerViewController alloc] init];
  self.contentPlayerViewController.player = player;
  self.contentPlayerViewController.view.frame = self.view.bounds;
  self.contentPlayhead =
      [[IMAAVPlayerContentPlayhead alloc] initWithAVPlayer:self.contentPlayerViewController.player];

  // Track end of content.
  AVPlayerItem *contentPlayerItem = self.contentPlayerViewController.player.currentItem;
  [NSNotificationCenter.defaultCenter addObserver:self
                                         selector:@selector(contentDidFinishPlaying:)
                                             name:AVPlayerItemDidPlayToEndTimeNotification
                                           object:contentPlayerItem];

  // Attach content video player to view hierarchy.
  [self showContentPlayer];
}

...

- (void)contentDidFinishPlaying:(NSNotification *)notification {}

- (void)dealloc {
  [NSNotificationCenter.defaultCenter removeObserver:self];
}

@end
      

Swift

...

class ViewController: UIViewController {
  static let ContentURLString = "https://storage.googleapis.com/interactive-media-ads/media/stock.mp4"

  var contentPlayhead: IMAAVPlayerContentPlayhead?
  var playerViewController: AVPlayerViewController!

  deinit {
    NotificationCenter.default.removeObserver(self)
  }

...

  func setUpContentPlayer() {
    // Load AVPlayer with path to your content.
    let contentURL! = URL(string: ViewController.ContentURLString)
    let player = AVPlayer(url: contentURL)
    playerViewController = AVPlayerViewController()
    playerViewController.player = player

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

    showContentPlayer()
  }

...

  @objc func contentDidFinishPlaying(_ notification: Notification) {
    adsLoader.contentComplete()
  }
}
      

6. 광고 로더 초기화 및 광고 요청

광고 세트를 요청하려면 IMAAdsLoader 인스턴스를 만들어야 합니다. 이 로더는 다음 항목과 관련된 IMAAdsRequest 객체를 처리하는 데 사용할 수 있습니다. 지정할 수 있습니다.

전체 기간에 IMAAdsLoader 인스턴스를 하나만 유지하는 것이 좋습니다. 수명 주기를 나타냅니다 추가 광고 요청을 하려면 IMAAdsRequest 객체와 유사하지만 동일한 IMAAdsLoader를 재사용합니다. 자세히 알아보기 IMA SDK FAQ를 참조하세요.

ViewController.m

Objective-C

...

NSString *const kContentURLString =
    @"https://storage.googleapis.com/interactive-media-ads/media/stock.mp4";
NSString *const kAdTagURLString = @"https://pubads.g.doubleclick.net/gampad/ads?"
    @"iu=/21775744923/external/vmap_ad_samples&sz=640x480&"
    @"cust_params=sample_ar%3Dpremidpostlongpod&"
    @"ciu_szs=300x250&gdfp_req=1&ad_rule=1&output=vmap&unviewed_position_start=1&"
    @"env=vp&impl=s&cmsid=496&vid=short_onecue&correlator=";

@interface ViewController ()
@property(nonatomic) IMAAdsLoader *adsLoader;
@property(nonatomic) IMAAVPlayerContentPlayhead *contentPlayhead;
@property(nonatomic) AVPlayerViewController *contentPlayerViewController;
@end

@implementation ViewController

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

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

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

- (void)requestAds {
  // Pass the main view as the container for ad display.
  IMAAdDisplayContainer *adDisplayContainer =
      [[IMAAdDisplayContainer alloc] initWithAdContainer:self.view];
  IMAAdsRequest *request = [[IMAAdsRequest alloc] initWithAdTagUrl:kAdTagURLString
                                                adDisplayContainer:adDisplayContainer
                                                   contentPlayhead:self.contentPlayhead
                                                       userContext:nil];
  [self.adsLoader requestAdsWithRequest:request];
}

...

- (void)contentDidFinishPlaying:(NSNotification *)notification {
  // Notify the SDK that the postrolls should be played.
  [self.adsLoader contentComplete];
}

...

@end
      

Swift

...

class ViewController: UIViewController {
  static let ContentURLString = "https://storage.googleapis.com/interactive-media-ads/media/stock.mp4"
  static let AdTagURLString = "https://pubads.g.doubleclick.net/gampad/ads?iu=/21775744923/external/single_ad_samples&sz=640x480&cust_params=sample_ct%3Dlinear&ciu_szs=300x250%2C728x90&gdfp_req=1&output=vast&unviewed_position_start=1&env=vp&impl=s&correlator="

  var adsLoader: IMAAdsLoader!
  var contentPlayhead: IMAAVPlayerContentPlayhead?
  var playerViewController: AVPlayerViewController!

...

  override func viewDidLoad() {
    super.viewDidLoad()
    self.view.backgroundColor = UIColor.black;
    setUpContentPlayer()
    setUpAdsLoader()
  }

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

...

  func setUpAdsLoader() {
    adsLoader = IMAAdsLoader(settings: nil)
  }

  func requestAds() {
    // Create ad display container for ad rendering.
    let adDisplayContainer = IMAAdDisplayContainer(adContainer: self.view)
    // Create an ad request with your ad tag, display container, and optional user context.
    let request = IMAAdsRequest(
        adTagUrl: ViewController.AdTagURLString,
        adDisplayContainer: adDisplayContainer,
        contentPlayhead: contentPlayhead,
        userContext: nil)

    adsLoader.requestAds(with: request)
  }

  @objc func contentDidFinishPlaying(_ notification: Notification) {
    adsLoader.contentComplete()
  }
}
      

7. 광고 로더 대리자 설정

로드에 성공하면 IMAAdsLoaderadsLoadedWithData를 호출합니다. 메서드를 사용하여 IMAAdsManager의 인스턴스를 전달합니다. 나 그런 다음 정의된 대로 개별 광고를 로드하는 광고 관리자를 초기화할 수 있습니다. 광고 태그 URL에 대한 응답으로 발생합니다.

또한 로드하는 동안 발생할 수 있는 모든 오류를 처리해야 합니다. 프로세스입니다 광고가 로드되지 않는 경우 사용자의 이용 경험을 방해하지 않아야 합니다.

ViewController.m

Objective-C

...

@interface ViewController () <IMAAdsLoaderDelegate>
@property(nonatomic) IMAAdsLoader *adsLoader;
@property(nonatomic) IMAAdsManager *adsManager;
@property(nonatomic) IMAAVPlayerContentPlayhead *contentPlayhead;
@property(nonatomic) AVPlayerViewController *contentPlayerViewController;
@end

@implementation ViewController

...

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

...

#pragma mark - IMAAdsLoaderDelegate

- (void)adsLoader:(IMAAdsLoader *)loader adsLoadedWithData:(IMAAdsLoadedData *)adsLoadedData {
  // Initialize and listen to the ads manager loaded for this request.
  self.adsManager = adsLoadedData.adsManager;
  [self.adsManager initializeWithAdsRenderingSettings:nil];
}

- (void)adsLoader:(IMAAdsLoader *)loader failedWithErrorData:(IMAAdLoadingErrorData *)adErrorData {
  // Fall back to playing content.
  NSLog(@"Error loading ads: %@", adErrorData.adError.message);
  [self.contentPlayerViewController.player play];
}

@end
      

Swift

...

class ViewController: UIViewController, IMAAdsLoaderDelegate {

...

  var adsLoader: IMAAdsLoader!
  var adsManager: IMAAdsManager!
  var contentPlayhead: IMAAVPlayerContentPlayhead?
  var playerViewController: AVPlayerViewController!

...

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

...

  // MARK: - IMAAdsLoaderDelegate

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

  func adsLoader(_ loader: IMAAdsLoader!, failedWith adErrorData: IMAAdLoadingErrorData!) {
    print("Error loading ads: " + adErrorData.adError.message)
    showContentPlayer()
    playerViewController.player?.play()
  }
}
      

8. 광고 관리자 위임 설정

마지막으로, 이벤트 및 상태 변경을 관리하려면 광고 관리자가 있습니다. IMAAdManagerDelegate에는 광고 이벤트와 오류를 처리하는 메서드가 있습니다. 동영상 콘텐츠의 재생 및 일시중지를 트리거하는 방법도 있습니다.

재생 시작

didReceiveAdEvent 메서드를 사용하여 처리할 수 있는 이벤트가 많이 있습니다. 이 기본 예에서는 단순히 LOADED 이벤트를 수신 대기하여 광고에 콘텐츠 및 광고 재생을 시작할 수 있습니다.

ViewController.m

Objective-C

@interface ViewController () <IMAAdsLoaderDelegate, IMAAdsManagerDelegate>

...

- (void)adsLoader:(IMAAdsLoader *)loader adsLoadedWithData:(IMAAdsLoadedData *)adsLoadedData {
  // Initialize and listen to the ads manager loaded for this request.
  self.adsManager = adsLoadedData.adsManager;
  self.adsManager.delegate = self;
  [self.adsManager initializeWithAdsRenderingSettings:nil];
}

...

#pragma mark - IMAAdsManagerDelegate

- (void)adsManager:(IMAAdsManager *)adsManager didReceiveAdEvent:(IMAAdEvent *)event {
  // Play each ad once it has loaded.
  if (event.type == kIMAAdEvent_LOADED) {
    [adsManager start];
  }
}

...
      

Swift

...

class ViewController: UIViewController, IMAAdsLoaderDelegate, IMAAdsManagerDelegate {

...

  func adsLoader(_ loader: IMAAdsLoader!, adsLoadedWith adsLoadedData: IMAAdsLoadedData!) {
    // Grab the instance of the IMAAdsManager and set yourself as the delegate.
    adsManager = adsLoadedData.adsManager
    adsManager.delegate = self
    adsManager.initialize(with: nil)
  }

...

  // MARK: - IMAAdsManagerDelegate

  func adsManager(_ adsManager: IMAAdsManager!, didReceive event: IMAAdEvent!) {
    // Play each ad once it has been loaded
    if event.type == IMAAdEventType.LOADED {
      adsManager.start()
    }
  }

...
      

오류 처리

광고 오류에 대한 핸들러도 추가합니다. 앞서 설명한 바와 같이 오류가 발생하면 콘텐츠 재생을 재개합니다.

ViewController.m

Objective-C


...

- (void)adsManager:(IMAAdsManager *)adsManager didReceiveAdError:(IMAAdError *)error {
  // Fall back to playing content.
  NSLog(@"AdsManager error: %@", error.message);
  [self showContentPlayer];
  [self.contentPlayerViewController.player play];
}
@end
      

Swift

...

  func adsManager(_ adsManager: IMAAdsManager!, didReceive error: IMAAdError!) {
    // Fall back to playing content
    print("AdsManager error: " + error.message)
    showContentPlayer()
    playerViewController.player?.play()
  }
      

재생 및 일시중지 이벤트 트리거

구현해야 하는 마지막 두 가지 대리자 메서드는 재생과 일시중지 이벤트를 요청할 수 있습니다. 요청이 있을 때 일시중지 및 재생을 트리거하여 사용자가 일부를 빠뜨리는 것을 방지 동영상 콘텐츠의 총조회수를 측정합니다.

ViewController.m

Objective-C

...

- (void)adsManagerDidRequestContentPause:(IMAAdsManager *)adsManager {
  // Pause the content for the SDK to play ads.
  [self.contentPlayerViewController.player pause];
  [self hideContentPlayer];
}

- (void)adsManagerDidRequestContentResume:(IMAAdsManager *)adsManager {
  // Resume the content since the SDK is done playing ads (at least for now).
  [self showContentPlayer];
  [self.contentPlayerViewController.player play];
}

@end
      

Swift

...

  func adsManagerDidRequestContentPause(_ adsManager: IMAAdsManager!) {
    // Pause the content for the SDK to play ads.
    playerViewController.player?.pause()
    hideContentPlayer()
  }

  func adsManagerDidRequestContentResume(_ adsManager: IMAAdsManager!) {
    // Resume the content since the SDK is done playing ads (at least for now).
    showContentPlayer()
    playerViewController.player?.play()
  }
}
      

작업이 끝났습니다. 이제 IMA SDK를 사용하여 광고를 요청하고 표시합니다. 배우기 위해 자세한 내용은 다른 가이드 또는 GitHub의 샘플

다음 단계

tvOS 플랫폼에서 광고 수익을 극대화하려면 IDFA 사용을 위한 앱 투명성 및 추적 권한을 요청하세요.