Настройка IMA SDK для DAI

Пакеты IMA SDK упрощают интеграцию мультимедийной рекламы в ваши веб-сайты и приложения. Пакеты IMA SDK могут запрашивать рекламу с любого рекламного сервера , совместимого с VAST, и управлять её воспроизведением в ваших приложениях. С помощью пакетов IMA DAI SDK приложения запрашивают потоковое видео для рекламы и контента — как VOD, так и прямой трансляции. Затем SDK возвращает объединённый видеопоток, поэтому вам не придётся переключаться между рекламой и контентом в приложении.

Выберите интересующее вас решение DAI

Полный комплекс услуг DAI

В этом руководстве показано, как интегрировать IMA DAI SDK в простое приложение видеоплеера. Если вы хотите просмотреть готовый пример интеграции или следовать ему, скачайте BasicExample с GitHub.

Обзор IMA DAI

Реализация IMA DAI включает три основных компонента SDK, как показано в этом руководстве:

  • IMAAdDisplayContainer : объект-контейнер, который располагается поверх элемента воспроизведения видео и содержит элементы пользовательского интерфейса рекламы.
  • IMAAdsLoader — объект, который запрашивает потоки и обрабатывает события, вызванные объектами ответа на запрос потока. Следует создать только один экземпляр загрузчика рекламы, который можно использовать повторно на протяжении всего жизненного цикла приложения.
  • IMAStreamRequestIMAVODStreamRequest или IMALiveStreamRequest : объект, определяющий запрос потока. Запросы потока могут быть предназначены как для видео по запросу, так и для прямых трансляций. В запросах прямых трансляций указывается ключ ресурса, а в запросах VOD – идентификатор CMS и идентификатор видео. Оба типа запросов могут дополнительно включать ключ API, необходимый для доступа к указанным потокам, и сетевой код Google Ad Manager для IMA SDK для обработки идентификаторов объявлений, указанных в настройках Google Ad Manager.
  • IMAStreamManager : объект, который обрабатывает потоки динамической вставки рекламы и взаимодействует с бэкендом DAI. Менеджер потоков также обрабатывает запросы отслеживания и пересылает события потоков и рекламы издателю.

Предпосылки

Прежде чем начать, вам понадобится следующее:

  • Xcode 13 или более поздняя версия
  • CocoaPods (предпочтительно), Swift Package Manager или загруженная копия IMA DAI SDK для tvOS

Создать новый проект Xcode

В Xcode создайте новый проект tvOS на Objective-C. Используйте BasicExample в качестве имени проекта.

Добавьте IMA DAI SDK в проект Xcode

Для установки IMA DAI SDK используйте один из этих трех методов.

Установить SDK с помощью CocoaPods (предпочтительно)

CocoaPods — это менеджер зависимостей для проектов Xcode, рекомендуемый метод установки IMA DAI SDK. Подробнее об установке и использовании CocoaPods см. в документации CocoaPods . После установки CocoaPods следуйте следующим инструкциям для установки IMA DAI SDK:

  1. В том же каталоге, где находится файл BasicExample.xcodeproj , создайте текстовый файл с именем Podfile и добавьте следующую конфигурацию:

    source 'https://github.com/CocoaPods/Specs.git'
    platform :tvos, '14'
    target "BasicExample" do
      pod 'GoogleAds-IMA-tvOS-SDK', '~> 4.15.1'
    end
    
  2. Из каталога, содержащего Podfile, запустите:

    pod install --repo-update`
  3. Убедитесь, что установка прошла успешно, открыв файл BasicExample.xcworkspace и убедившись, что он содержит два проекта: BasicExample и Pods (зависимости, установленные CocoaPods).

Установите SDK с помощью Swift Package Manager

Interactive Media Ads SDK поддерживает Swift Package Manager, начиная с версии 4.8.2. Чтобы импортировать пакет Swift, выполните следующие действия.

  1. В Xcode установите пакет GoogleInteractiveMediaAds Swift, перейдя в Файл > Добавить пакеты .

  2. В появившемся окне найдите репозиторий GitHub GoogleInteractiveMediaAds Swift Package:

    https://github.com/googleads/swift-package-manager-google-interactive-media-ads-tvos
    
  3. Выберите нужную версию пакета GoogleInteractiveMediaAds Swift. Для новых проектов мы рекомендуем использовать версию Up to Next Major Version .

После завершения Xcode определит зависимости пакетов и загрузит их в фоновом режиме. Подробнее о добавлении зависимостей пакетов см. в статье Apple .

Загрузка и установка SDK вручную

Если вы не хотите использовать Swift Package Manager или CocoaPods, вы можете загрузить IMA DAI SDK и вручную добавить его в свой проект.

Создайте простой видеоплеер

Для начала реализуем базовый видеоплеер. Изначально этот плеер не использует IMA DAI 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

Импортируйте SDK и добавьте заглушки для взаимодействия с IMA.

После добавления IMA DAI 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

Реализуйте 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;
}

Подать заявку на трансляцию

Создайте несколько констант для хранения информации о потоке, а затем реализуйте функцию запроса потока для выполнения запроса.

ViewController.m

#import <GoogleInteractiveMediaAds/GoogleInteractiveMediaAds.h>

static NSString *const kAssetKey = @"sN_IYUG8STe1ZzhIIE_ksA";
static NSString *const kContentSourceID = @"2548831";
static NSString *const kVideoID = @"tears-of-steel";
static NSString *const kNetworkCode = @"21775744923";

@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
                                                                     networkCode:kNetworkCode
                                                              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
  //                                              networkCode:kNetworkCode
  //                                       adDisplayContainer:adDisplayContainer
  //                                             videoDisplay:videoDisplay];
  [self.adsLoader requestStreamWithRequest:request];
}

Обработка событий потока

События IMAAdsLoader и IMAStreamManager инициируют события, используемые для обработки инициализации, ошибок и изменений состояния потока. Эти события инициируются по протоколам IMAAdsLoaderDelegate и IMAStreamManagerDelegate . Отслеживайте событие загрузки рекламы и инициализируйте поток. Если реклама не загружается, воспроизводите резервный поток.

ViewController.m

static NSString *const kAssetKey = @"sN_IYUG8STe1ZzhIIE_ksA";
static NSString *const kContentSourceID = @"2548831";
static NSString *const kVideoID = @"tears-of-steel";
static NSString *const kNetworkCode = @"21775744923";
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

Обработка событий регистрации и ошибок

Есть несколько событий, которые могут быть обработаны делегатом менеджера потоков, но для базовых реализаций наиболее важными являются ведение журнала событий, предотвращение действий поиска во время воспроизведения рекламы и обработка ошибок.

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 and show the ad controls.
      self.adContainerView.hidden = NO;
      break;
    }
    case kIMAAdEvent_AD_BREAK_ENDED: {
      // Allow user seek through after an ad ends and hide the ad controls.
      self.adContainerView.hidden = YES;
      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 DAI SDK. Чтобы узнать о более продвинутых функциях SDK, ознакомьтесь с другими руководствами или примерами на GitHub .