באמצעות ערכות ה-IMA SDK קל לשלב מודעות מולטימדיה באתרים ובאפליקציות שלכם. ערכות IMA SDK יכולות לבקש מודעות מכל שרת מודעות שתואם ל-VAST ולנהל את הפעלת המודעות באפליקציות שלך. באמצעות ערכות SDK בצד הלקוח של IMA יש לך שליטה על הפעלת תוכן וידאו, ו-SDK מטפלת בהפעלת מודעות. המודעות מופעלות בנגן וידאו נפרד שממוקם מעל נגן הווידאו של האפליקציה.
המדריך הזה מראה איך לשלב את IMA SDK באפליקציה פשוטה של נגן וידאו. אם אתם רוצים להציג שילוב לדוגמה לדוגמה או לעקוב אחריו, תוכלו להוריד את BasicExample מ-GitHub.
סקירה כללית על IMA בצד הלקוח
ההטמעה של בצד הלקוח ב-IMA כוללת ארבעה רכיבים עיקריים של SDK, שמודגמים במדריך הזה:
IMAAdDisplayContainer
: אובייקט של מאגר שבו מתבצע עיבוד של מודעות.IMAAdsLoader
: אובייקט שמבקש מודעות ומטפל באירועים מתגובות לבקשות להצגת מודעות. עליכם ליצור מודעה רק בכלי טעינה אחד של מודעות, שניתן לעשות בו שימוש חוזר במהלך השימוש באפליקציה.IMAAdsRequest
: אובייקט המגדיר בקשה להצגת מודעה. בקשות להצגת מודעות מציינות את כתובת ה-URL של תג המודעה מסוג VAST, וגם פרמטרים נוספים, כמו מאפיינים של מודעות.IMAAdsManager
: אובייקט שמכיל את התגובה לבקשה להצגת מודעות, שולט בהפעלה של מודעות ומאזין לאירועים של מודעות שמופעלים על ידי ה-SDK.
דרישות מוקדמות
לפני שמתחילים, צריך:
- Xcode 9.2 ואילך
- CocoaPods (מועדף) או עותק של ה-IMA SDK ל-tvOS שהורד
1. יצירת פרויקט Xcode חדש
ב-Xcode, יוצרים פרויקט tvOS חדש באמצעות Objective-C או Swift. שם הפרויקט צריך להיות BasicExample.
2. הוספת ה-IMA SDK לפרויקט Xcode
התקנת ה-SDK באמצעות CocoaPods (מועדף)
CocoaPods הוא מנהל יחסי תלות בפרויקטים של Xcode, והוא השיטה המומלצת להתקנת ה-IMA SDK. מידע נוסף על ההתקנה או השימוש ב-CocoaPods זמין במסמכי התיעוד של CocoaPods. אחרי שמתקינים את CocoaPods, פועלים לפי ההוראות הבאות כדי להתקין את IMA SDK:
באותה ספרייה שבה נמצא הקובץ BasicExample.xcodeproj, יוצרים קובץ טקסט בשם Podfile ומוסיפים את ההגדרות הבאות:
source 'https://github.com/CocoaPods/Specs.git' platform :tvos, '10' target "BasicExample" do pod 'GoogleAds-IMA-tvOS-SDK', '~> 4.2' end
מהספרייה שמכילה את ה-Podfile, מריצים את
pod install --repo-update
מוודאים שההתקנה הצליחה. לשם כך, פותחים את הקובץ BasicExample.xcworkspace ומוודאים שהוא מכיל שני פרויקטים: BasicExample ו-Pods (יחסי התלות שהותקנו על ידי CocoaPods).
הורדה והתקנה של ה-SDK באופן ידני
אם אתם לא רוצים להשתמש ב-CocoaPods, אתם יכולים להוריד את ה-IMA SDK ולהוסיף אותו ידנית לפרויקט.
3. יצירת נגן וידאו פשוט
תחילה, מטמיעים נגן וידאו בסיסי. בהתחלה, הנגן הזה לא משתמש ב-IMA SDK והוא עדיין לא מכיל שיטה להפעלת ההפעלה.
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. ייבוא IMA SDK
בשלב הבא, יש להוסיף את מסגרת ה-IMA באמצעות הצהרת ייבוא מתחת לייבוא הקיים.
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. הטמעה של מעקב אחר סמן המיקום של התוכן ושל צופים בסוף השידור
כדי להפעיל מודעות באמצע הסרטון, ב-IMA SDK צריך לעקוב אחר המיקום הנוכחי של תוכן הווידאו. כדי לעשות זאת, צריך ליצור כיתה שמשתמשת ב-IMAContentPlayhead
. אם אתם משתמשים ב-AVPlayer
, כפי שמתואר בדוגמה הזו, ה-SDK מספק את הסיווג IMAAVPlayerContentPlayhead
שמאפשר לכם לעשות זאת.
אם אתם לא משתמשים ב-AVPlayer
, עליכם להטמיע את IMAContentPlayhead
בכיתה משלכם.
עליך גם להודיע ל-SDK בסיום הפעלת התוכן כדי שניתן יהיה להציג מודעות בסוף הסרטון. כדי לעשות זאת, צריך להפעיל את contentComplete
ב-IMAAdsLoader
באמצעות 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. מפעילים את הכלי לטעינת מודעות ושולחים בקשה להצגת מודעות
כדי לבקש קבוצת מודעות, צריך ליצור מופע של IMAAdsLoader
.
הכלי הזה יכול לשמש לעיבוד IMAAdsRequest
אובייקטים שמשויכים לכתובת URL של תג מודעה שצוין.
מומלץ לשמור רק מופע אחד של IMAAdsLoader
בכל מחזור החיים של האפליקציה. כדי לשלוח בקשות נוספות להצגת מודעות, צריך ליצור אובייקט IMAAdsRequest
חדש אבל להשתמש שוב באותו IMAAdsLoader
. מידע נוסף זמין בשאלות הנפוצות בנושא 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. הגדרת הענקת גישה לכלי לטעינת מודעות
באירוע טעינה מוצלח, הפונקציה IMAAdsLoader
מפעילה את השיטה adsLoadedWithData
של בעל הגישה שהוקצתה לו, ומעבירה אותה למכונה של IMAAdsManager
. לאחר מכן תוכלו להפעיל את מנהל המודעות כדי לטעון את המודעות השונות, כפי שמוגדר בתגובה לכתובת ה-URL של תג המודעה.
בנוסף, ודאו שאתם מטפלים בשגיאות שעשויות להתרחש בתהליך הטעינה. אם מודעות לא נטענות, חשוב לוודא שהפעלה המדיה ממשיכה ללא מודעות כדי שלא תפריע לחוויית המשתמש.
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. הגדרה של בעל הרשאות לניהול מודעות
לבסוף, כדי לנהל אירועים ושינויים במצב, מנהל המודעות צריך להעניק גישה משלו. ב-IMAAdManagerDelegate
יש שיטות לטיפול באירועים ובשגיאות של מודעות, וגם שיטות להפעלה ולהשהיה של התוכן בסרטון.
ההפעלה מתחילה
יש אירועים רבים שבהם אפשר להשתמש בשיטה didReceiveAdEvent
כדי לטפל, אבל בדוגמה הבסיסית הזו צריך פשוט להאזין לאירוע LOADED
ולהורות למנהל המודעות להתחיל להפעיל תוכן ומודעות.
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() } } ...
טיפול בשגיאות
הוספת גורם מטפל גם עבור שגיאות במודעות. אם מתרחשת שגיאה, כמו בשלב הקודם, מפעילים מחדש את הפעלת התוכן.
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() }
הפעלה של אירועי הפעלה והשהיה
שתי שיטות ההענקת הגישה האחרונות שאתם צריכים להטמיע משמשות להפעלה ולהשהיה של אירועים בתוכן הווידאו המקורי, בהתאם לבקשת ה-IMA SDK. הפעלת האפשרות 'הפעלה והשהיה' לפי בקשה מונעת מהמשתמש להחמיץ חלקים מתוכן הסרטון כאשר מוצגות מודעות.
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() } }
זהו! הבקשה להצגת מודעות באמצעות ה-IMA SDK מוצגת עכשיו. תוכלו לקרוא מידע נוסף על הפיצ'רים הנוספים של SDK או דוגמאות ב-GitHub.
השלבים הבאים
כדי למקסם את ההכנסות מפרסום בפלטפורמת tvOS, יש לבקש הרשאת שקיפות ומעקב אחר אפליקציות לשימוש ב-IDFA.