إعداد حزمة تطوير البرامج لإعلانات الوسائط التفاعلية لعرض الإعلانات أثناء التشغيل

تسهّل حِزم تطوير البرامج (SDK) لإعلانات الوسائط التفاعلية دمج إعلانات الوسائط المتعددة في مواقعك الإلكترونية وتطبيقاتك. يمكن لحِزم تطوير البرامج لإعلانات الوسائط التفاعلية طلب الإعلانات من أي خادم إعلانات متوافق مع VAST وإدارة تشغيل الإعلانات في تطبيقاتك. باستخدام حِزم تطوير البرامج لإدراج الإعلانات الديناميكي في "إعلانات الوسائط التفاعلية"، تقدّم التطبيقات طلب بث لإعلان وفيديو محتوى، سواء كان فيديو عند الطلب أو محتوى مباشرًا. بعد ذلك، تعرض حزمة SDK بث فيديو مدمجًا، ما يغنيك عن إدارة التبديل بين الفيديو الإعلاني وفيديو المحتوى داخل تطبيقك.

اختيار حلّ "الإعلانات الديناميكية أثناء عرض الفيديو" الذي يهمّك

إدراج إعلان ديناميكي شامل

يوضّح هذا الدليل كيفية دمج حزمة تطوير البرامج (SDK) الخاصة بـ "إعلانات البث المباشر" في "إعلانات الوسائط التفاعلية" في تطبيق بسيط لمشغّل فيديو. إذا أردت الاطّلاع على نموذج تكامل مكتمل أو اتّباعه، يمكنك تنزيل BasicExample من GitHub.

نظرة عامة على IMA DAI

يتضمّن تنفيذ "إعلانات الوسائط التفاعلية" (IMA) في "الإعلانات الديناميكية أثناء البث" ثلاثة مكوّنات رئيسية في حزمة SDK، كما هو موضّح في هذا الدليل:

  • IMAAdDisplayContainer: هو عنصر حاوٍ يظهر فوق عنصر تشغيل الفيديو ويحتوي على عناصر واجهة مستخدم الإعلان.
  • IMAAdsLoader: كائن يطلب عمليات بث ويتعامل مع الأحداث التي يتم تشغيلها بواسطة كائنات الرد على طلب البث. يجب إنشاء أداة تحميل إعلانات واحدة فقط، ويمكن إعادة استخدامها طوال مدة تشغيل التطبيق.
  • IMAStreamRequest – إما IMAVODStreamRequest أو IMALiveStreamRequest: كائن يحدّد طلب بث. يمكن أن تكون طلبات البث المباشر لفيديوهات عند الطلب أو أحداث بث مباشر. تحدّد طلبات البث المباشر مفتاح مادة عرض، بينما تحدّد طلبات الفيديو عند الطلب معرّفًا في "نظام إدارة المحتوى" ومعرّف فيديو. يمكن أن يتضمّن كلا نوعَي الطلبات اختياريًا مفتاح واجهة برمجة التطبيقات اللازم للوصول إلى عمليات البث المحدّدة، ورمز شبكة "مدير إعلانات Google" لكي تتعامل أداة تطوير البرامج لإعلانات الوسائط التفاعلية (IMA) مع معرّفات الإعلانات على النحو المحدّد في إعدادات "مدير إعلانات Google".
  • IMAStreamManager: عنصر يعالج عمليات بث "إدراج الإعلان الديناميكي" والتفاعلات مع الخلفية البرمجية لميزة "إدراج الإعلان الديناميكي". يتولّى مدير البث أيضًا معالجة طلبات اختبار الاتصال الخاصة بالتتبُّع وإعادة توجيه أحداث البث والإعلانات إلى الناشر.

المتطلبات الأساسية

قبل البدء، يجب أن يتوفّر لديك ما يلي:

إنشاء مشروع Xcode جديد

في Xcode، أنشئ مشروعًا جديدًا لتطبيق tvOS باستخدام Objective-C. استخدِم BasicExample كاسم للمشروع.

إضافة حزمة تطوير البرامج (SDK) لميزة "الإعلانات الديناميكية أثناء البث" من "إعلانات الوسائط التفاعلية" إلى مشروع Xcode

استخدِم إحدى الطرق الثلاث التالية لتثبيت حزمة تطوير البرامج (SDK) الخاصة بميزة "الإعلانات الديناميكية أثناء عرض الفيديو" في "إعلانات الوسائط التفاعلية".

تثبيت حزمة تطوير البرامج (SDK) باستخدام CocoaPods (الطريقة المفضّلة)

‫CocoaPods هي أداة لإدارة الملحقات في مشاريع Xcode، وهي الطريقة المقترَحة لتثبيت حزمة تطوير البرامج (SDK) الخاصة بـ "الإعلانات الديناميكية أثناء عرض الفيديو" من "إعلانات الوسائط التفاعلية". لمزيد من المعلومات حول تثبيت CocoaPods أو استخدامه، يُرجى الاطّلاع على مستندات CocoaPods. بعد تثبيت CocoaPods، اتّبِع التعليمات التالية لتثبيت حزمة تطوير البرامج (SDK) الخاصة بـ "إعلانات الوسائط التفاعلية" (IMA) في البث المباشر:

  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

تتيح "حزمة تطوير البرامج لإعلانات الوسائط التفاعلية" استخدام Swift Package Manager بدءًا من الإصدار 4.8.2. اتّبِع الخطوات التالية لاستيراد حزمة Swift.

  1. في Xcode، ثبِّت حزمة GoogleInteractiveMediaAds Swift Package من خلال الانتقال إلى ملف > إضافة حِزم.

  2. في الطلب الذي يظهر، ابحث عن مستودع GoogleInteractiveMediaAds Swift Package على GitHub:

    https://github.com/googleads/swift-package-manager-google-interactive-media-ads-tvos
    
  3. اختَر إصدار حزمة GoogleInteractiveMediaAds Swift الذي تريد استخدامه. بالنسبة إلى المشاريع الجديدة، ننصحك باستخدام الترقية إلى الإصدار الرئيسي التالي.

بعد الانتهاء، يحلّ Xcode التبعيات المرتبطة بحِزمك وينزّلها في الخلفية. لمزيد من التفاصيل حول كيفية إضافة تبعيات الحزمة، يُرجى الاطّلاع على مقالة Apple.

تنزيل حزمة تطوير البرامج (SDK) وتثبيتها يدويًا

إذا كنت لا تريد استخدام Swift Package Manager أو CocoaPods، يمكنك تنزيل حزمة تطوير البرامج (SDK) الخاصة بـ "إعلانات الوسائط التفاعلية" (DAI) وإضافتها يدويًا إلى مشروعك.

إنشاء مُشغّل فيديو بسيط

أولاً، عليك تنفيذ مشغّل فيديو أساسي. في البداية، لا يستخدم مشغّل الفيديو هذا حزمة تطوير البرامج (SDK) الخاصة بالإعلانات الديناميكية أثناء عرض الفيديو من "IMA"، كما أنّه لا يتضمّن أي طريقة لتشغيل الفيديو.

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) و"إدخال الإعلانات الديناميكي" (DAI) إلى مشروعك، استورِد حزمة تطوير البرامج وأضِف رموزًا بديلة للنقاط الأساسية للتفاعل مع "إعلانات الوسائط التفاعلية".

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) في "الإعلانات الديناميكية أثناء عرض الفيديو". لمزيد من المعلومات حول ميزات حزمة SDK المتقدّمة، يُرجى الاطّلاع على الأدلة الأخرى أو الأمثلة على GitHub.