С помощью 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
Начиная с версии 4.8.2, Interactive Media Ads SDK поддерживает Swift Package Manager. Чтобы импортировать пакет 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, которую хотите использовать. Для новых проектов мы рекомендуем использовать вариант До следующей основной версии.
Когда все будет готово, Xcode начнет распознавать зависимости пакета и скачивать их в фоновом режиме. Подробнее о том, как добавить зависимости пакетов, можно узнать из статьи Apple.
Как вручную скачать и установить IMA SDK
Если вы не хотите использовать Swift Package Manager, скачайте и вручную добавьте IMA SDK в свой проект.
3. Импорт IMA SDK
Добавьте фреймворк IMA, используя оператор import.
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.