IMA SDK позволяет легко интегрировать мультимедийные объявления на сайты и в приложения. IMA SDK может запрашивать объявления с любого сервера, совместимого с VAST, и управлять воспроизведением рекламы в ваших приложениях. Клиентские IMA SDK позволяют управлять воспроизведением видеоконтента, а воспроизведение рекламы берет на себя SDK. Объявления воспроизводятся в отдельном видеопроигрывателе, который расположен поверх проигрывателя видеоконтента в приложении.
В этом руководстве рассказывается, как интегрировать IMA SDK в приложение с видеопроигрывателем. Чтобы посмотреть или использовать готовый пример интеграции, скачайте BasicExample с GitHub.
Общие сведения о IMA на стороне клиента
При реализации IMA на стороне клиента используются четыре основных компонента SDK. В этом руководстве рассматриваются следующие компоненты:
IMAAdDisplayContainer– объект-контейнер, который указывает, где IMA отображает элементы интерфейса объявления и измеряет видимость, включая Active View и Open Measurement.IMAAdsLoader– объект, который запрашивает объявления и обрабатывает события, связанные с ответами на запросы объявлений. Вам нужно создать только один экземпляр загрузчика объявлений, который можно использовать в течение всего жизненного цикла приложения.IMAAdsRequest: Объект, определяющий запрос объявления. В запросах объявлений указывается URL тега объявления VAST, а также дополнительные параметры, например размеры объявления.IMAAdsManager: Объект, который содержит ответ на запрос объявления, управляет воспроизведением объявления и отслеживает события, связанные с объявлением и инициированные SDK.
Требования
Прежде чем начать, вам понадобится следующее:
- Xcode 13 или более поздней версии;
- Способ установки IMA SDK:
- Рекомендуемый вариант: Swift Package Manager.
- Скачайте копию IMA SDK для tvOS.
1. Создайте проект Xcode
В Xcode создайте проект tvOS на Objective-C или Swift. В качестве названия проекта укажите BasicExample.
2. Добавьте IMA SDK в проект Xcode
Выберите способ установки IMA SDK.
Рекомендуемый способ: установить IMA SDK с помощью Swift Package Manager
Interactive Media Ads SDK поддерживает Swift Package Manager начиная с версии 4.8.2. Чтобы импортировать пакет Swift, выполните следующие действия:
В Xcode установите пакет IMA SDK Swift, выбрав File (Файл) > Add Packages (Добавить пакеты).
В появившемся окне найдите хранилище IMA SDK Swift Package на GitHub:
https://github.com/googleads/swift-package-manager-google-interactive-media-ads-tvosВыберите версию IMA SDK Swift Package, которую хотите использовать. Для новых проектов рекомендуется использовать Up to Next Major Version.
Когда все будет готово, Xcode распознает зависимости пакета и скачает их в фоновом режиме. Подробнее о том, как добавлять зависимости пакетов, читайте в статье Apple.
Как скачать и установить IMA SDK вручную
Если вы не хотите использовать Swift Package Manager, скачайте IMA SDK и добавьте его в проект вручную.
3. Импорт IMA SDK
Добавьте фреймворк IMA с помощью оператора импорта.
Objective-C
#import "ViewController.h"
#import <AVKit/AVKit.h>
@import GoogleInteractiveMediaAds;
Swift
import AVFoundation
import GoogleInteractiveMediaAds
import UIKit
4. Как создать видеопроигрыватель и интегрировать IMA SDK
Ниже приведен пример инициализации IMA SDK.
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&cmsid=496&vid=short_onecue&correlator=";
@interface ViewController () <IMAAdsLoaderDelegate, IMAAdsManagerDelegate>
@property(nonatomic) IMAAdsLoader *adsLoader;
@property(nonatomic) IMAAdDisplayContainer *adDisplayContainer;
@property(nonatomic) IMAAdsManager *adsManager;
@property(nonatomic) IMAAVPlayerContentPlayhead *contentPlayhead;
@property(nonatomic) AVPlayerViewController *contentPlayerViewController;
@property(nonatomic, getter=isAdBreakActive) BOOL adBreakActive;
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
self.view.backgroundColor = [UIColor blackColor];
[self setupAdsLoader];
[self setupContentPlayer];
}
- (void)viewDidAppear:(BOOL)animated {
[super viewDidAppear:animated];
[self requestAds];
}
// 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 resume events from the
// remote and play content underneath the ad.
[self.contentPlayerViewController willMoveToParentViewController:nil];
[self.contentPlayerViewController.view removeFromSuperview];
[self.contentPlayerViewController removeFromParentViewController];
}
Swift
class ViewController: UIViewController, IMAAdsLoaderDelegate, IMAAdsManagerDelegate {
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&correlator="
var adsLoader: IMAAdsLoader!
var adDisplayContainer: IMAAdDisplayContainer!
var adsManager: IMAAdsManager!
var contentPlayhead: IMAAVPlayerContentPlayhead?
var playerViewController: AVPlayerViewController!
var adBreakActive = false
deinit {
NotificationCenter.default.removeObserver(self)
}
override func viewDidLoad() {
super.viewDidLoad()
self.view.backgroundColor = UIColor.black
setUpContentPlayer()
setUpAdsLoader()
}
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
requestAds()
}
В этом примере viewDidLoad() инициализирует IMAAdsLoader, а viewDidAppear() запрашивает объявления, когда область просмотра становится видимой. Вспомогательные методы
showContentPlayer() и hideContentPlayer() переключают видимость контента во время воспроизведения объявления.
В этом примере используется постоянная переменная adTagURLString, которая определяет тег объявления VAST для запроса объявления, и следующие компоненты для управления IMA SDK:
adsLoader– обрабатывает запросы объявлений и ответы на них. Рекомендуем использовать один экземпляр для жизненного цикла приложения.adDisplayContainer– определяет представление для показа объявлений.adsManagerуправляет воспроизведением объявлений и отслеживает события, связанные с ними.contentPlayhead– отслеживает ход воспроизведения контента, чтобы запускать рекламные паузы в середине ролика.adBreakActive– указывает, воспроизводится ли рекламная пауза, чтобы предотвратить перемотку рекламы.
5. Реализуйте отслеживание указателя воспроизведения контента и наблюдатель за окончанием трансляции
Чтобы показывать рекламу в середине видео, IMA SDK должен отслеживать текущую позицию воспроизведения видеоконтента. Чтобы передать текущую позицию в IMA, создайте класс, который реализует IMAContentPlayhead. Если вы используете AVPlayer, как показано в этом примере, IMA SDK предоставляет класс IMAAVPlayerContentPlayhead для передачи информации о текущей позиции. Если вы не используете AVPlayer, реализуйте IMAContentPlayhead в собственном классе.
Objective-C
- (void)setupContentPlayer {
// Create a content video player. Create a playhead to track content progress so the SDK knows
// when to play ads in a VMAP playlist.
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];
}
Swift
func setUpContentPlayer() {
// Load AVPlayer with path to our content.
let contentURL = URL(string: ViewController.contentURLString)!
let player = AVPlayer(url: contentURL)
playerViewController = AVPlayerViewController()
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)
showContentPlayer()
}
Настройте прослушиватель, который будет вызывать contentComplete для IMAAdsLoader, когда контент заканчивается, с помощью AVPlayerItemDidPlayToEndTimeNotification. Вызов contentComplete сообщает IMA SDK, что воспроизведение контента завершено и можно показывать рекламу в конце видео.
Objective-C
- (void)contentDidFinishPlaying:(NSNotification *)notification {
// Notify the SDK that the postrolls should be played.
[self.adsLoader contentComplete];
}
- (void)dealloc {
[[NSNotificationCenter defaultCenter] removeObserver:self];
}
Swift
@objc func contentDidFinishPlaying(_ notification: Notification) {
adsLoader.contentComplete()
}
6. Инициализируйте загрузчик объявлений и отправьте запрос объявлений
Чтобы запросить набор объявлений, создайте экземпляр IMAAdsLoader.
Этот загрузчик обрабатывает объекты IMAAdsRequest, связанные с указанным URL тега объявления.
Рекомендуется использовать только один экземпляр IMAAdsLoader на протяжении всего жизненного цикла приложения. Чтобы отправлять дополнительные запросы объявлений, создайте новый объект IMAAdsRequest, но используйте тот же экземпляр IMAAdsLoader. Дополнительную информацию можно найти в разделе часто задаваемых вопросов об IMA SDK.
Objective-C
- (void)setupAdsLoader {
self.adsLoader = [[IMAAdsLoader alloc] init];
self.adsLoader.delegate = self;
}
- (void)requestAds {
// Pass the main view as the container for ad display.
self.adDisplayContainer = [[IMAAdDisplayContainer alloc] initWithAdContainer:self.view
viewController:self];
IMAAdsRequest *request = [[IMAAdsRequest alloc] initWithAdTagUrl:kAdTagURLString
adDisplayContainer:self.adDisplayContainer
contentPlayhead:self.contentPlayhead
userContext:nil];
[self.adsLoader requestAdsWithRequest:request];
}
Swift
func setUpAdsLoader() {
adsLoader = IMAAdsLoader(settings: nil)
adsLoader.delegate = self
}
func requestAds() {
// Create ad display container for ad rendering.
adDisplayContainer = IMAAdDisplayContainer(adContainer: self.view, viewController: self)
// Create an ad request with our ad tag, display container, and optional user context.
let request = IMAAdsRequest(
adTagUrl: ViewController.adTagURLString,
adDisplayContainer: adDisplayContainer,
contentPlayhead: contentPlayhead,
userContext: nil)
adsLoader.requestAds(with: request)
}
7. Как настроить делегат загрузчика объявлений
При успешной загрузке IMAAdsLoader вызывает метод adsLoadedWithData назначенного делегата, передавая ему экземпляр IMAAdsManager.
Получив экземпляр IMAAdsManager, инициализируйте менеджер объявлений, который загружает отдельные объявления на основе ответа URL тега объявления.
Для событий неудачной загрузки настройте делегат IMAAdsLoader, который будет обрабатывать ошибки, возникающие в процессе загрузки. Если объявления не загружаются, убедитесь, что воспроизведение медиаконтента продолжается без рекламы.
Objective-C
#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.delegate = self;
[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];
}
Swift
func adsLoader(_ loader: IMAAdsLoader, adsLoadedWith adsLoadedData: IMAAdsLoadedData) {
// Grab the instance of the IMAAdsManager and set ourselves as the delegate.
adsManager = adsLoadedData.adsManager
adsManager.delegate = self
adsManager.initialize(with: nil)
}
func adsLoader(_ loader: IMAAdsLoader, failedWith adErrorData: IMAAdLoadingErrorData) {
print("Error loading ads: \(adErrorData.adError.message ?? "No error message available.")")
showContentPlayer()
playerViewController.player?.play()
}
8. Как настроить делегирование управляющего аккаунта
Наконец, для управления событиями и изменениями состояния менеджеру рекламы требуется собственный делегат. В IMAAdManagerDelegate есть методы для обработки событий и ошибок, связанных с объявлениями, а также методы для запуска и приостановки воспроизведения видеоконтента.
Начинается воспроизведение
Метод didReceiveAdEvent обрабатывает все события IMAAdEvent.
В этом простом примере прослушивается событие LOADED, которое сообщает менеджеру рекламы о необходимости начать воспроизведение контента и объявлений. IMA SDK активирует событие ICON_FALLBACK_IMAGE_CLOSED, когда пользователь закрывает резервное диалоговое окно после нажатия на значок. После этого воспроизведение объявления возобновляется.
Objective-C
#pragma mark - IMAAdsManagerDelegate
- (void)adsManager:(IMAAdsManager *)adsManager didReceiveAdEvent:(IMAAdEvent *)event {
switch (event.type) {
case kIMAAdEvent_LOADED: {
// Play each ad once it has loaded.
[adsManager start];
break;
}
case kIMAAdEvent_ICON_FALLBACK_IMAGE_CLOSED: {
// Resume ad after user has closed dialog.
[adsManager resume];
break;
}
default:
break;
}
}
Swift
func adsManager(_ adsManager: IMAAdsManager, didReceive event: IMAAdEvent) {
switch event.type {
case IMAAdEventType.LOADED:
// Play each ad once it has been loaded.
adsManager.start()
case IMAAdEventType.ICON_FALLBACK_IMAGE_CLOSED:
// Resume playback after the user has closed the dialog.
adsManager.resume()
default:
break
}
}
Исправление ошибок
Также добавьте обработчик ошибок, связанных с объявлениями. Если возникнет ошибка, как на предыдущем шаге, возобновите воспроизведение контента.
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];
}
Swift
func adsManager(_ adsManager: IMAAdsManager, didReceive error: IMAAdError) {
// Fall back to playing content
print("AdsManager error: \(error.message ?? "No error message available.")")
showContentPlayer()
playerViewController.player?.play()
}
Активация событий воспроизведения и паузы
Последние два метода делегата, которые вы реализуете, запускают события воспроизведения и паузы в базовом видеоконтенте, когда IMA SDK запрашивает их. Если вы настроите приостановку и возобновление воспроизведения по запросу IMA SDK, пользователи не будут пропускать фрагменты видеоконтента во время показа рекламы.
Objective-C
- (void)adsManagerDidRequestContentPause:(IMAAdsManager *)adsManager {
// Pause the content for the SDK to play ads.
[self.contentPlayerViewController.player pause];
[self hideContentPlayer];
// Trigger an update to send focus to the ad display container.
self.adBreakActive = YES;
[self setNeedsFocusUpdate];
}
- (void)adsManagerDidRequestContentResume:(IMAAdsManager *)adsManager {
// Resume the content since the SDK is done playing ads (at least for now).
[self showContentPlayer];
[self.contentPlayerViewController.player play];
// Trigger an update to send focus to the content player.
self.adBreakActive = NO;
[self setNeedsFocusUpdate];
}
Swift
func adsManagerDidRequestContentPause(_ adsManager: IMAAdsManager) {
// Pause the content for the SDK to play ads.
playerViewController.player?.pause()
hideContentPlayer()
// Trigger an update to send focus to the ad display container.
adBreakActive = true
setNeedsFocusUpdate()
}
func adsManagerDidRequestContentResume(_ adsManager: IMAAdsManager) {
// Resume the content since the SDK is done playing ads (at least for now).
showContentPlayer()
playerViewController.player?.play()
// Trigger an update to send focus to the content player.
adBreakActive = false
setNeedsFocusUpdate()
}
Готово! Теперь вы запрашиваете и показываете объявления с помощью IMA SDK. Чтобы узнать о дополнительных функциях SDK, ознакомьтесь с другими руководствами или примерами на GitHub.
Дальнейшие действия
Чтобы максимально увеличить доход от рекламы на платформе tvOS, запросите разрешение на использование IDFA в соответствии с правилами App Tracking Transparency.