IMA SDK を使用すると、ウェブサイトやアプリにマルチメディア広告を簡単に統合できます。IMA SDK は、 VAST 準拠のあらゆる広告サーバーから広告をリクエストし、アプリでの広告再生を管理できます。IMA クライアントサイド SDK を使用すると、コンテンツ動画の再生を制御しながら、SDK で広告の再生を処理できます。広告は、アプリのコンテンツ動画プレーヤーの上に配置された別の動画プレーヤーで再生されます。
このガイドでは、IMA SDK を動画プレーヤー アプリに統合する方法について説明します。統合済みのサンプルを表示または実行するには、GitHub から BasicExample をダウンロードしてください。
IMA クライアントサイドの概要
IMA クライアントサイドの実装には、4 つの主要な SDK コンポーネントが関与します。このガイドでは、次のコンポーネントについて説明します。
IMAAdDisplayContainer: IMA が広告の UI 要素をレンダリングし、アクティブ ビューやオープン測定などの視認性を測定する場所を指定するコンテナ オブジェクト。IMAAdsLoader: 広告をリクエストし、広告リクエスト レスポンスからイベントを処理するオブジェクト。広告ローダは 1 つだけインスタンス化し、アプリのライフサイクル全体で再利用する必要があります。IMAAdsRequest: 広告リクエストを定義するオブジェクト。広告リクエストでは、VAST 広告タグの URL と、広告のサイズなどの追加パラメータを指定します。IMAAdsManager: 広告リクエストに対するレスポンスを含み、広告の再生を制御し、SDK によって発生した広告イベントをリッスンするオブジェクト。
前提条件
始める前に、次のものが必要になります。
- Xcode 13 以降
- IMA SDK のインストール方法:
- 推奨: Swift Package Manager
- CocoaPods
- tvOS 向け IMA SDK のダウンロード コピー
1. 新しい Xcode プロジェクトを作成する
Xcode で、Objective-C または Swift を使用して新しい tvOS プロジェクトを作成します。プロジェクト名として BasicExample を使用します。
2. Xcode プロジェクトに IMA SDK を追加する
IMA SDK をインストールするには、ご希望の方法を選択してください。
推奨: Swift Package Manager を使用して IMA SDK をインストールする
Interactive Media Ads SDK はバージョン 4.8.2 から Swift Package Manager に対応しています。Swift パッケージをインポートする手順は次のとおりです。
Xcode で File > Add Packages... を開き、IMA SDK の Swift パッケージをインストールします。
表示されたプロンプトで、IMA SDK Swift パッケージの GitHub リポジトリ(下記)を検索します。
https://github.com/googleads/swift-package-manager-google-interactive-media-ads-tvos使用する IMA SDK Swift パッケージのバージョンを選択します。新しいプロジェクトの場合は [Up to Next Major Version] を選択することをおすすめします。
完了すると、Xcode はパッケージの依存関係を解決し、バックグラウンドでダウンロードします。パッケージの依存関係の追加について詳しくは、Apple の記事を参照してください。
CocoaPods を使用して IMA SDK をインストールする
IMA SDK をインストールするには、CocoaPods を使用します。CocoaPods のインストールと使用の詳細については、CocoaPods のドキュメントをご覧ください。CocoaPods をインストールしたら、次の操作を行います。
BasicExample.xcodeproj ファイルと同じディレクトリに、Podfile という名前のテキスト ファイルを作成し、次の構成を追加します。
source 'https://github.com/CocoaPods/Specs.git' platform :tvos, '15' target "BasicExample" do pod 'GoogleAds-IMA-tvOS-SDK', '~> 4.16.0' endPodfile が含まれているディレクトリから、
pod install --repo-updateを実行します。BasicExample.xcworkspace ファイルを開き、BasicExample と Pods(CocoaPods によってインストールされた依存関係)の 2 つのプロジェクトが含まれていることを確認して、インストールが正常に完了したことを確認します。
IMA SDK を手動でダウンロードしてインストールする
Swift パッケージ マネージャーを使用しない場合は、IMA SDK をダウンロードして、プロジェクトに手動で追加します。
3. IMA SDK をインポートする
import ステートメントを使用して 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()
}
AVPlayerItemDidPlayToEndTimeNotification を使用して、コンテンツの終了時に IMAAdsLoader の contentComplete を呼び出すリスナーを設定します。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 インスタンスを作成します。このローダーは、指定された広告タグ URL に関連付けられた IMAAdsRequest オブジェクトを処理します。
ベスト プラクティスとして、アプリのライフサイクル全体で IMAAdsLoader のインスタンスを 1 つだけ維持します。追加の広告リクエストを行うには、新しい 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()
}
再生イベントと一時停止イベントをトリガーする
実装する最後の 2 つのデリゲート メソッドは、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 Transparency and Tracking の権限をリクエストします。