بدء استخدام حزمة تطوير البرامج لإدراج إعلان ديناميكي لإعلانات الوسائط التفاعلية

اختيار حلّ DAI الذي يهمّك

إدراج إعلان ديناميكي في مجموعات الإعلانات

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

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

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

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

قبل استخدام هذا الدليل، تعرَّف على بروتوكول Web Receiver في إطار عمل تطبيقات Chromecast. يفترض هذا الدليل فهمًا أساسيًا لمفاهيم أجهزة استقبال CAF، مثل أدوات اعتراض الرسائل ومواد mediaInformation ، والتعرّف على استخدام أداة التحكّم والتوجيه في البث، لمحاكاة جهاز إرسال CAF.

لاستخدام ميزة عرض مجموعات الإعلانات المتسلسلة في "الإعلانات الديناميكية على شبكة البحث"، يجب أن تعمل مع شريك عرض مجموعات الإعلانات المتسلسلة ويجب أن يكون لديك حساب على "مدير إعلانات 360" المتقدّم. إذا كان لديك حساب على "مدير إعلانات Google"، يُرجى التواصل مع مدير حسابك للحصول على مزيد من التفاصيل. للحصول على معلومات عن الاشتراك في "مدير إعلانات Google"، يُرجى الانتقال إلى مركز مساعدة "مدير إعلانات Google".

للحصول على معلومات عن الدمج مع الأنظمة الأساسية الأخرى أو استخدام حِزم تطوير البرامج (SDK) من جهة العميل لإعلانات الوسائط التفاعلية، يُرجى الاطّلاع على حِزم تطوير البرامج (SDK) لإعلانات الوسائط التفاعلية.

نظرة عامة على عرض مجموعات الإعلانات الديناميكية في IMA

يتضمّن تنفيذ ميزة عرض المجموعات باستخدام حزمة تطوير البرامج IMA CAF DAI SDK مكوّنَين رئيسيَّين، يتم توضيحهما في هذا الدليل:

  • StreamRequest: عنصر يحدّد طلب بث إلى خوادم Google الإعلانية. تحدّد الطلبات رمز الشبكة ومفتاح مادة العرض المخصّصة ومفتاح واجهة برمجة التطبيقات الاختياري، بالإضافة إلى مَعلمات اختيارية أخرى.
  • StreamManager: عنصر يعالج الاتصال بين بث الفيديو وحزمة تطوير البرامج (SDK) لميزة DAI في IMA، مثل تنشيط إشارات التتبّع وإعادة توجيه أحداث البث إلى الناشر.

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

ضبط كائنات MediaInfo للمُرسِل

أولاً، عليك ضبط كائن MediaInfo في تطبيق المُرسِل لتضمين الحقول التالية:

الحقل المحتويات
contentId معرّف فريد لعنصر الوسائط هذا

CONTENT_ID

contentUrl اختيارية: عنوان URL للبث الاحتياطي الذي يتم تشغيله في حال تعذّر تحميل بث الإعلانات أثناء عرض الفيديو

BACKUP_STREAM_URL

contentType اختيارية: نوع Mime لمجموعات بث المحتوى الاحتياطية لا يلزم استخدام هذه السمة إلا في عمليات بث DASH.

CONTENT_STREAM_MIMETYPE

streamType تختلف السلسلة الثابتة أو الثابتة المستخدَمة لهذه القيمة حسب منصة المُرسِل.
customData يحتوي الحقل customData على قاعدة بيانات للمفاتيح والقيم الخاصة بالحقول المطلوبة الإضافية. في هذا العيّنة، يحتوي على مَعلمات بث الإعلانات أثناء التشغيل. في التطبيق العلني، يمكنك بدلاً من ذلك تمرير معرّف سيستخدمه تطبيق تلقي البث لاسترداد هذه المَعلمات من خلال طلب من جهة الخادم.
الحقل المحتويات
daiStreamType نوع بث الإعلانات أثناء التشغيل، إما "LIVE" أو "VOD"

DAI_STREAM_TYPE

networkCode رمز الشبكة لحسابك على "مدير إعلانات Google‏ 360".

NETWORK_CODE

customAssetKey هذا الحقل مطلوب لأحداث البث المباشر فقط. مفتاح مادة العرض المخصّصة الذي يحدِّد حدث عرض المجموعة الإعلانية في "مدير إعلانات Google‏ 360".

CUSTOM_ASSET_KEY

apiKey مفتاح اختياري لواجهة برمجة التطبيقات لاسترداد معرّف مصدر بيانات من حزمة تطوير البرامج لإعلانات الوسائط التفاعلية (IMA DAI SDK)

API_KEY

في ما يلي بعض نماذج الرموز البرمجية لمساعدتك في البدء:

الويب

لضبط هذه القيم في أداة إرسال الويب في Cast، عليك أولاً إنشاء عنصر MediaInfo يحتوي على البيانات المطلوبة، ثم تقديم طلب تحميل إلى أداة استقبال الويب.

// Create mediaInfo object
const mediaInfo = new chrome.cast.media.MediaInfo("CONTENT_ID");
mediaInfo.contentUrl = "BACKUP_STREAM_URL";
mediaInfo.contentType = "CONTENT_STREAM_MIMETYPE";
mediaInfo.streamType = chrome.cast.media.StreamType.LIVE;
mediaInfo.customData = {
  daiStreamType: "DAI_STREAM_TYPE",
  networkCode: "NETWORK-CODE",
  customAssetKey: "CUSTOM_ASSET_KEY",
  apiKey: "API_KEY"
};

// Make load request to cast web receiver
const castSession = cast.framework.CastContext.getInstance().getCurrentSession();
const request = new chrome.cast.media.LoadRequest(mediaInfo);
castSession.loadMedia(request).then(
  () => { console.log('Load succeed'); },
  (errorCode) => { console.log('Error code: ' + errorCode); });

Android

لضبط هذه القيم في أداة إرسال الويب في Cast، عليك أولاً إنشاء عنصر MediaInfo بالبيانات المطلوبة، ثم تقديم طلب تحميل إلى عنصر مستلِم الويب.

JSONObject customData = new JSONObject()?
  .put("daiStreamType", "DAI_STREAM_TYPE")
  .put("networkCode", "NETWORK-CODE")
  .put("customAssetKey", "CUSTOM_ASSET_KEY")
  .put("apiKey", "API_KEY");
MediaInfo mediaInfo = MediaInfo.Builder("CONTENT_ID")
  .setContentUrl("BACKUP_STREAM_URL")
  .setContentType("CONTENT_STREAM_MIMETYPE")
  .setStreamType(MediaInfo.STREAM_TYPE_LIVE)
  .setCustomData(customData)
  .build();

RemoteMediaClient remoteMediaClient = mCastSession.getRemoteMediaClient();
remoteMediaClient.load(new MediaLoadRequestData.Builder().setMediaInfo(mediaInfo).build());

iOS (Obj-C)

لضبط هذه القيم في أداة إرسال الويب في Cast، عليك أولاً إنشاء عنصر GCKMediaInformation يحتوي على البيانات المطلوبة، ثم تقديم طلب تحميل إلى أداة استقبال الويب.

NSURL url = [NSURL URLWithString:@"BACKUP_STREAM_URL"];
NSDictionary *customData = @{
  @"daiStreamType": @"DAI_STREAM_TYPE",
  @"networkCode": @"NETWORK-CODE",
  @"customAssetKey": @"CUSTOM_ASSET_KEY",
  @"apiKey": @"API_KEY"};
mediaInfoBuilder.customData = customData;

GCKMediaInformationBuilder *mediaInfoBuilder =
  [[GCKMediaInformationBuilder alloc] initWithContentID: @"CONTENT_ID"];
mediaInfoBuilder.contentURL = url;
mediaInfoBuilder.contentType = @"CONTENT_STREAM_MIMETYPE";
mediaInfoBuilder.streamType = GCKMediaStreamTypeLive;
mediaInfoBuilder.customData = customData;
self.mediaInformation = [mediaInfoBuilder build];

GCKRequest *request = [self.sessionManager.currentSession.remoteMediaClient loadMedia:self.mediaInformation];
if (request != nil) {
  request.delegate = self;
}

iOS (Swift)

لضبط هذه القيم في أداة إرسال الويب في Cast، عليك أولاً إنشاء عنصر GCKMediaInformation يحتوي على البيانات المطلوبة، ثم تقديم طلب تحميل إلى أداة استقبال الويب.

let url = URL.init(string: "BACKUP_STREAM_URL")
guard let mediaURL = url else {
  print("invalid mediaURL")
  return
}

let customData = [
  "daiStreamType": "DAI_STREAM_TYPE",
  "networkCode": "NETWORK-CODE",
  "customAssetKey": "CUSTOM_ASSET_KEY",
  "region": "API_KEY"
]

let mediaInfoBuilder = GCKMediaInformationBuilder.init(contentId: "CONTENT_ID")
mediaInfoBuilder.contentURL = mediaUrl
mediaInfoBuilder.contentType = @"CONTENT_STREAM_MIMETYPE"
mediaInfoBuilder.streamType = GCKMediaStreamType.Live
mediaInfoBuilder.customData = customData
mediaInformation = mediaInfoBuilder.build()

guard let mediaInfo = mediaInformation else {
  print("invalid mediaInformation")
  return
}

if let request = sessionManager.currentSession?.remoteMediaClient?.loadMedia
(mediaInfo) {
  request.delegate = self
}

أداة تكلفة اكتساب العملاء

لضبط هذه القيم في أداة التحكّم والتوجيه في البث، انقر على علامة التبويب "تحميل الوسائط"، واضبط نوع طلب التحميل المخصّص على LOAD. بعد ذلك، استبدِل بيانات JSON في مربّع النص ببيانات JSON التالية:

{
  "media": {
    "contentId": "CONTENT_ID",
    "contentUrl": "BACKUP_STREAM_URL",
    "contentType": ""CONTENT_STREAM_MIMETYPE"",
    "streamType": "LIVE",
    "customData": {
      "daiStreamType": "DAI_STREAM_TYPE",
      "networkCode": "NETWORK-CODE",
      "customAssetKey": "CUSTOM_ASSET_KEY",
      "oAuthToken": "API_KEY"
    }
  }
}

يمكن إرسال طلب التحميل المخصّص هذا إلى المستلِم لاختبار بقية الخطوات.

إنشاء جهاز استقبال CAF أساسي

أنشئ مستقبل ويب مخصّصًا، كما هو موضّح في دليل مستقبل الويب المخصّص في حزمة تطوير البرامج (CAF SDK).

يجب أن يظهر رمز جهاز الاستقبال على النحو التالي:

<html>
<head>
  <script
      src="//www.gstatic.com/cast/sdk/libs/caf_receiver/v3/cast_receiver_framework.js">
  </script>
</head>
<body>
  <cast-media-player></cast-media-player>
  <script>
    // ...
  </script>
</body>
</html>

استيراد حزمة تطوير البرامج (SDK) لعرض الإعلانات الديناميكية في الفيديو من IMA والحصول على أداة إدارة المشغّل

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

<html>
<head>
  <script
      src="//www.gstatic.com/cast/sdk/libs/caf_receiver/v3/cast_receiver_framework.js"></script>
  <script src="//imasdk.googleapis.com/js/sdkloader/cast_dai.js"></script>
</head>
<body>
  <cast-media-player></cast-media-player>
  <script>
    const castContext = cast.framework.CastReceiverContext.getInstance();
    const playerManager = castContext.getPlayerManager();

    castContext.start();
  </script>
</body>
</html>

بدء تشغيل IMA Stream Manager

شغِّل IMA Stream Manager.

<html>
<head>
  <script type="text/javascript"
      src="//www.gstatic.com/cast/sdk/libs/caf_receiver/v3/cast_receiver_framework.js"></script>
  <script src="//imasdk.googleapis.com/js/sdkloader/cast_dai.js"></script>
</head>
<body>
  <cast-media-player></cast-media-player>
  <script>
    const castContext = cast.framework.CastReceiverContext.getInstance();
    const playerManager = castContext.getPlayerManager();
    const streamManager = new google.ima.cast.dai.api.StreamManager();

    castContext.start();
  </script>
</body>
</html>

إنشاء أداة اعتراض تحميل Stream Manager

قبل تمرير عناصر الوسائط إلى CAF، أنشئ طلب البث في اعتراض رسائل LOAD.

    const castContext = cast.framework.CastReceiverContext.getInstance();
    const playerManager = castContext.getPlayerManager();
    const streamManager = new google.ima.cast.dai.api.StreamManager();

    /**
     * Creates a livestream request object for a Pod Serving stream.
     * @param {!LoadRequestData} castRequest The request object from the cast sender
     * @return {StreamRequest} an IMA stream request
     */
    const createStreamRequest = (castRequest) => { /* ... */};

    /**
     * Initates a DAI stream request for the final stream manifest.
     * @param {!LoadRequestData} castRequest The request object from the cast sender
     * @return {Promise<LoadRequestData>} a promise that resolves to an updated castRequest, containing the DAI stream manifest
     */
    const createDAICastRequest = (castRequest) => {
        return streamManager.requestStream(castRequest, createStreamRequest(castRequest))
          .then((castRequestWithPodStreamData) => {
            console.log('Successfully made DAI stream request.');
            // ...
            return castRequestWithPodStreamData;
          })
          .catch((error) => {
            console.log('Failed to make DAI stream request.');
            // CAF will automatically fallback to the content URL
            // that it can read from the castRequest object.
            return castRequest;
          });
    };

    playerManager.setMessageInterceptor(
        cast.framework.messages.MessageType.LOAD, createDAICastRequest);

    castContext.start();

إنشاء طلب البث

أكمِل الدالة createStreamRequest لإنشاء بثّ لعرض مجموعة وحدات معالجة رسومات (Pod) استنادًا إلى طلب تحميل CAF.

    /**
     * Creates a livestream request object for a Pod Serving stream.
     * @param {!LoadRequestData} castRequest The request object from the cast sender
     * @return {StreamRequest} an IMA stream request
     */
    const createStreamRequest = (castRequest) => {
      const customData = castRequest.media.customData;
      let streamRequest;
      if (customData.daiStreamType == "LIVE") {
        streamRequest = new google.ima.cast.dai.api.PodStreamRequest();
        streamRequest.customAssetKey = customData.customAssetKey;
        streamRequest.networkCode = customData.networkCode;
        streamRequest.apiKey = customData.apiKey;
      } else if (customData.daiStreamType == "VOD") {
        streamRequest = new google.ima.cast.dai.api.PodVodStreamRequest();
        streamRequest.networkCode = customData.networkCode;
        streamRequest.apiKey = customData.apiKey;
      }
      return streamRequest;
    };

استرداد بيان التجميع من VTP

إذا تم قبول طلب البث، استخدِم streamManager.getStreamId() ل retrieving the stream's ID. سيقدّم شريكك التقني المختص بالفيديوهات (VTP) أو مُشغّل ملف البيان المخصّص تعليمات لاسترداد عنوان URL لملف البيان باستخدام معرّف البث هذا.

بعد استرداد عنوان URL لملف البيان، استبدِل القيمة الحالية contentUrl بالقيمة الجديدة manifestUrl.

أخيرًا، قبل عرض بيان البث المعدَّل، استخدِم الأسلوب loadStreamMetadata في streamManager لإعلام حزمة IMA SDK بأنّه يمكنها طلب البيانات الوصفية للبث بأمان. هذه المكالمة ضرورية فقط لأحداث الفيديوهات المسجّلة.

    /**
     * Initates a DAI stream request for the final stream manifest.
     * @param {!LoadRequestData} castRequest The request object from the cast sender
     * @return {Promise<LoadRequestData>} a promise that resolves to an updated castRequest, containing the DAI stream manifest
     */
    const createDAICastRequest = (castRequest) => {
        return streamManager.requestStream(castRequest, createStreamRequest(castRequest))
          .then((castRequestWithPodStreamData) => {
            console.log('Successfully made DAI stream request.');

            // This is a sample VTP integration. Consult your VTP documentation
            // for how to retrieve an ad-stitched stream manifest URL.
            const manifestTemplate = "https://.../manifest.m3u8?gam_stream_id=[[STREAMID]]";
            const streamId = streamManager.getStreamId();
            const manifestUrl = manifestTemplate.replace('[[STREAMID]]', streamId)
            // Assign your manifestUrl to the request's content URL.
            castRequestWithPodStreamData.media.contentUrl = manifestUrl;

            // After generating the manifest URL, VOD streams must notify the
            // IMA SDK that it is safe to request ad pod metadata.
            // This is only necessary for VOD streams. It is a no-op for
            // livestreams, so no conditional is needed.
            streamManager.loadStreamMetadata();

            return castRequestWithPodStreamData;
          })
          .catch((error) => {
            console.log('Failed to make DAI stream request.');
            // CAF will automatically fallback to the content URL
            // that it can read from the castRequest object.
            return castRequest;
          });
    };

تنظيف مواد عرض "الإعلانات الديناميكية أثناء عرض الفيديو" في IMA

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