Wypróbuj

Pakiety IMA SDK ułatwiają integrację reklam multimedialnych w witrynach i aplikacjach. Pakiety IMA SDK mogą żądać reklam z dowolnego serwera reklam zgodnego z VAST i zarządzać odtwarzaniem reklam w aplikacjach. Korzystając z pakietów SDK po stronie klienta IMA, zachowujesz kontrolę nad odtwarzaniem filmów, a pakiet SDK obsługuje odtwarzanie reklam. Reklamy są wyświetlane w oddzielnym odtwarzaczu umieszczonym na odtwarzaczu wideo w aplikacji.

Z tego przewodnika dowiesz się, jak zintegrować pakiet IMA SDK z prostą aplikacją do odtwarzaczy wideo. Jeśli chcesz wyświetlić lub przeprowadzić przykładową integrację, pobierz BasicExample z GitHuba.

Omówienie po stronie klienta IMA

Implementacja po stronie klienta obejmuje 4 główne komponenty SDK. Omówiono to w tym przewodniku:

  • IMAAdDisplayContainer: obiekt kontenera, w którym są renderowane reklamy.
  • IMAAdsLoader: obiekt, który żąda reklam i obsługuje zdarzenia z odpowiedzi na żądania reklam. Należy zainicjować tylko jeden program wczytujący reklamy, którego można używać wielokrotnie w trakcie działania aplikacji.
  • IMAAdsRequest: obiekt, który definiuje żądanie reklamy. Żądania reklam określają adres URL tagu reklamy VAST oraz dodatkowe parametry, np. wymiary reklamy.
  • IMAAdsManager: obiekt zawierający odpowiedź na żądanie reklamy, kontrolujący odtwarzanie reklam i nasłuchujący zdarzeń reklamowych wywoływanych przez pakiet SDK.

Wymagania wstępne

Zanim zaczniesz, musisz mieć:

1. Utwórz nowy projekt Xcode

W Xcode utwórz nowy projekt tvOS, korzystając z celu C lub Swift. Użyj nazwy BasicExample jako nazwy projektu.

2. Dodawanie pakietu IMA SDK do projektu Xcode

Instalowanie pakietu SDK za pomocą CocoaPods (zalecane)

CocoaPods to menedżer zależności projektów Xcode i zalecana metoda instalacji pakietu IMA SDK. Więcej informacji na temat instalowania i używania CocoaPods znajdziesz w dokumentacji CocoaPods. Po zainstalowaniu CocoaPods IMA SDK możesz wykonać te czynności:

  1. W tym samym katalogu, w którym znajduje się plik BasicExample.xcodeproj, utwórz plik tekstowy o nazwie Podfile i dodaj do niego tę konfigurację:

    source 'https://github.com/CocoaPods/Specs.git'
    platform :tvos, '14'
    target "BasicExample" do
      pod 'GoogleAds-IMA-tvOS-SDK', '~> 4.9.2'
    end
    
  2. W katalogu zawierającym plik Podfile uruchom polecenie pod install --repo-update

  3. Sprawdź, czy instalacja się powiodła. Otwórz plik BasicExample.xcworkspace i upewnij się, że zawiera on 2 projekty: BasicExample i Pods (zależności zainstalowane przez CocoaPods).

Ręczne pobieranie i instalowanie pakietu SDK

Jeśli nie chcesz używać CocoaPods, możesz pobrać pakiet IMA SDK i dodać go ręcznie do projektu.

3. Utwórz prosty odtwarzacz wideo

Najpierw zaimplementuj podstawowy odtwarzacz wideo. Początkowo ten odtwarzacz nie korzysta z pakietu IMA SDK i nie zawiera jeszcze żadnej metody uruchomienia odtwarzania.

ViewController.m

Objective-C

#import "ViewController.h"

#import <AVKit/AVKit.h>

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

@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/bipbop.m3u8"

  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. Importowanie pakietu IMA SDK

Następnie dodaj platformę IMA, używając dotychczasowych instrukcji importu.

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/bipbop.m3u8";
      

Swift

import AVFoundation
import GoogleInteractiveMediaAds
import UIKit

class ViewController: UIViewController {
  static let ContentURLString = "https://devstreaming-cdn.apple.com/videos/streaming/examples/img_bipbop_adv_example_fmp4/master.m3u8"
      

5. Zaimplementuj narzędzie do śledzenia suwaków treści i obserwatora końca strumienia

Aby odtwarzać reklamy w trakcie filmu, pakiet IMA SDK musi śledzić bieżącą pozycję Twoich treści wideo. Aby to zrobić, utwórz klasę, która korzysta z klasy IMAContentPlayhead. Jeśli używasz AVPlayer w sposób przedstawiony w tym przykładzie, SDK udostępni klasę IMAAVPlayerContentPlayhead, która zrobi to za Ciebie. Jeśli nie korzystasz z klasy AVPlayer, musisz wdrożyć IMAContentPlayhead na swoich zajęciach.

Musisz też poinformować SDK o zakończeniu odtwarzania treści, aby umożliwić wyświetlanie reklam po filmie. W tym celu należy wywołać metodę contentComplete na platformie IMAAdsLoader, używając metody AVPlayerItemDidPlayToEndTimeNotification.

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://devstreaming-cdn.apple.com/videos/streaming/examples/img_bipbop_adv_example_fmp4/master.m3u8"

  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. Inicjowanie programu wczytującego reklamy i wysyłanie żądania reklam

Aby wysłać żądanie reklamy, musisz utworzyć wystąpienie IMAAdsLoader. Ten program do wczytywania może przetwarzać obiekty IMAAdsRequest powiązane z określonym adresem URL tagu reklamy.

Zalecaną metodą jest zachowanie tylko jednego wystąpienia IMAAdsLoader przez cały cykl życia aplikacji. Aby utworzyć dodatkowe żądania reklamy, utwórz nowy obiekt IMAAdsRequest, ale użyj tego samego obiektu IMAAdsLoader. Więcej informacji znajdziesz w najczęstszych pytaniach o pakiet IMA SDK.

ViewController.m

Objective-C

...

NSString *const kContentURLString =
    @"https://devstreaming-cdn.apple.com/videos/streaming/examples/img_bipbop_adv_example_fmp4/"
    @"master.m3u8";
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://devstreaming-cdn.apple.com/videos/streaming/examples/img_bipbop_adv_example_fmp4/master.m3u8"
  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. Konfigurowanie przedstawiciela wczytującego reklamy

Po pomyślnym wywołaniu zdarzenia IMAAdsLoader wywołuje metodę adsLoadedWithData przypisanego przedstawiciela, przekazując mu wystąpienie IMAAdsManager. Następnie możesz zainicjować menedżera reklam, który wczytuje poszczególne reklamy, zgodnie z odpowiedzią na adres URL tagu reklamy.

Pamiętaj też, aby naprawiać błędy, które mogą wystąpić podczas wczytywania strony. Jeśli reklamy się nie ładują, zadbaj o to, aby odtwarzanie multimediów przebiegało bez reklam, aby nie zakłócały korzystania z witryny przez użytkownika.

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. Konfigurowanie przedstawicieli zarządzających reklamami

Na koniec, aby zarządzać zdarzeniami i zmianami stanu, menedżer reklam musi mieć własnego przedstawiciela. IMAAdManagerDelegate obejmuje metody obsługi zdarzeń reklamowych i błędów, a także metody odtwarzania i wstrzymywania odtwarzania treści wideo.

Rozpoczynam odtwarzanie

Metoda didReceiveAdEvent może służyć do obsługi wielu zdarzeń, ale w podstawowym przykładzie wystarczy użyć zdarzenia LOADED, aby poprosić menedżera reklam o rozpoczęcie odtwarzania treści i reklam.

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()
    }
  }

...
      

Obsługa błędów

Dodaj również moduł obsługi błędów reklamy. Jeśli wystąpi błąd, np. w poprzednim kroku, wznów odtwarzanie treści.

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()
  }
      

Aktywowanie zdarzeń wstrzymania i wstrzymania

Ostatnie 2 metody przekazywania dostępu, które musisz wdrożyć, służą do uruchamiania i wstrzymywania zdarzeń w przypadku bazowej treści wideo na żądanie pakietu IMA SDK. Aktywowanie wstrzymywania i odtwarzania na żądanie uniemożliwia użytkownikom pominięcie części treści wideo, gdy są one wyświetlane.

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()
  }
}
      

Znakomicie. Teraz wysyłasz żądanie i wyświetlasz reklamy za pomocą pakietu IMA SDK. Aby dowiedzieć się więcej o dodatkowych funkcjach pakietu SDK, zapoznaj się z innymi przewodnikami lub przykładami na GitHubie.

Następne kroki

Aby zmaksymalizować przychody z reklam na platformie tvOS, poproś o uprawnienia do przejrzystości i śledzenia aplikacji, aby korzystać z IDFA.