ช่วงพักโฆษณา

จัดทุกอย่างให้เป็นระเบียบอยู่เสมอด้วยคอลเล็กชัน บันทึกและจัดหมวดหมู่เนื้อหาตามค่ากำหนดของคุณ

ภาพรวม

Web Receiver SDK มีการรองรับโฆษณาเนทีฟสําหรับช่วงพักโฆษณาและโฆษณาที่แสดงร่วมภายในสตรีมสื่อหนึ่งๆ โดยจะมี 2 วิธีในการรวมช่วงพักโฆษณาในฝั่งผู้รับ ได้แก่ การต่อฝั่งไคลเอ็นต์และฝั่งเซิร์ฟเวอร์โดยใช้ช่วงพักโฆษณาและคลิปช่วงพักโฆษณา

ก่อนที่จะเริ่มการพัฒนาช่วงพักโฆษณา ให้ทําความคุ้นเคยกับการตั้งค่า Custom Web Receiver Cast SDK Ad Breaks API ช่วยดูแลให้ผู้ใช้ได้รับประสบการณ์ที่สอดคล้องกันบนอุปกรณ์ที่พร้อมใช้งาน Cast ทั้งหมด เมื่อโฆษณาเป็นส่วนหนึ่งของการเล่น

ในคู่มือนี้ ช่วงพักหมายถึงช่วงเวลาของการเล่นที่มีโฆษณาหรือบัมเปอร์อย่างน้อย 1 รายการ และโฆษณาหรือบัมเปอร์แต่ละรายการจะเรียกว่าคลิปช่วงพักโฆษณา

แผนภาพนี้แสดงช่วงพักโฆษณา 2 รายการ โดยแต่ละรายการมีโฆษณา 2 รายการ

กิจกรรม

ตารางต่อไปนี้อธิบายเหตุการณ์ที่ระบบเรียกให้แสดงเมื่อมีการพบช่วงพักระหว่างการเล่น

กิจกรรมพัก คำอธิบาย
เปิดอยู่ เริ่มทํางานเมื่อคลิปหนีบแรกในช่วงพักเริ่มโหลด กิจกรรมคือ cast.framework.events.BreaksEvent
BREAK_END สิ้นสุดแล้ว เริ่มทํางานเมื่อคลิปช่วงพักสุดท้ายของช่วงพักโฆษณาสิ้นสุดลง เหตุการณ์คือ cast.framework.events.BreaksEvent
หมายเหตุ: เหตุการณ์นี้จะเริ่มทํางานแม้ว่าผู้ใช้ข้ามคลิปช่วงพักโฆษณาในช่วงพักเพื่อสิ้นสุดช่วงพัก
การละเมิดรายละเอียด เริ่มทํางานเมื่อคลิปพักเริ่มโหลด กิจกรรมคือ cast.framework.events.BreaksEvent
เริ่มใช้ iOS เริ่มทํางานเมื่อคลิปพักเริ่มทํางาน กิจกรรมคือ cast.framework.events.BreaksEvent
BREAK_CLIP_END เริ่มทํางานเมื่อคลิปพักสิ้นสุดลง เหตุการณ์คือ cast.framework.events.BreaksEvent
หมายเหตุ: เหตุการณ์นี้จะเริ่มทํางานแม้ว่าผู้ใช้จะข้ามช่วงพักก็ตาม โปรดตรวจสอบพร็อพเพอร์ตี้ endedReason ของ BreaksEvent หากต้องการทราบระยะเวลาที่มีคนดูคลิปช่วงพักโฆษณา โปรดดู getBreakClipCurrentTimeSec และ getBreakClipDurationSec จาก PlayerManager

เหตุการณ์เหล่านี้จะใช้เพื่อการวิเคราะห์และการติดตามการเล่นโฆษณาได้ เมื่อมีการใช้ VMAP (เพลย์ลิสต์โฆษณาหลายรายการสําหรับวิดีโอ) และ VAST (เทมเพลตการแสดงโฆษณาวิดีโอ) SDK จะส่งเหตุการณ์การติดตามมาตรฐานใดๆ ในการตอบกลับมาโดยอัตโนมัติ

ขณะพักกําลังเล่น SDK ผู้รับเว็บจะออกอากาศ MediaStatus กับ breakStatus ไปยังผู้ส่งที่เชื่อมต่อทั้งหมด ผู้ส่งสามารถใช้ข้อมูลนี้เพื่ออัปเดต UI และระงับการดําเนินการค้นหาได้

SDK ผู้รับเว็บมี 2 วิธีในการรวมช่วงพักโฆษณาไปยังผู้รับ ได้แก่ การต่อวิดีโอฝั่งไคลเอ็นต์และฝั่งเซิร์ฟเวอร์

การต่อโฆษณาฝั่งไคลเอ็นต์

สําหรับการต่อโฆษณาฝั่งไคลเอ็นต์ หรือที่เรียกว่า "ไม่ได้ฝัง" ข้อมูลโฆษณาที่จําเป็นควรระบุด้วย Break และออบเจ็กต์ BreakClip เมื่อโหลดสื่อ ข้อมูลโค้ดต่อไปนี้เป็นตัวอย่างของฟังก์ชันการเพิ่มช่วงพักโฆษณาตอนต้น ตอนกลาง และตอนท้าย โดยการอ้างอิงไปยัง third_party และวิธีการของฟังก์ชันเหล่านี้คือตัวอย่างของฟังก์ชันตัวช่วยที่นักพัฒนาแอปอาจมีในแอป ตัวอย่างนี้ยังแสดงให้เห็นว่าสามารถเริ่มการทํางานของการติดตามเหตุการณ์อย่างไรเมื่อฟังเหตุการณ์ BREAK_CLIP_ENDED จนจบ และตรวจสอบค่าของ endedReason

/**
 * @param {!cast.framework.messages.MediaInformation} mediaInformation
 */
function addBreakToMedia(mediaInformation) {
  mediaInformation.breakClips = [
  {
    id: 'bc1',
    title: third_party.getBreakClipTitle('bc1'),
    contentId: third_party.getBreakClipUrl('bc1'),
    contentType: third_party.getBreakClipContentType('bc1'),
    posterUrl: third_party.getBreakClipPosterUrl('bc1')
  },
  {
    id: 'bc2'
    ...
  },
  {
    id: 'bc3'
    ...
  },
  {
    id: 'bc4'
    ...
  }];
  mediaInformation.breaks = [
  {
    id: 'b1',
    breakClipIds: ['bc1', 'bc2'],
    position: 0  //pre-roll position
  },
  {
    id: 'b2',
    breakClipIds: ['bc3'],
    position: 10*60 //ten minutes
  },{
    id: 'b3',
    breakClipIds: ['bc4'],
    position: -1  //post-roll position (-1 is only valid client stitching; for server-side ad stitching, exact position is required)
  }];
}

const context = cast.framework.CastReceiverContext.getInstance();
const playerManager = context.getPlayerManager();

playerManager.addEventListener(cast.framework.events.EventType.BREAK_CLIP_ENDED, function(event){
  if(event.endedReason === cast.framework.events.EndedReason.END_OF_STREAM){
    //call your ad tracking code here for break clip watched to completion
  }
});


playerManager.setMessageInterceptor(
    cast.framework.messages.MessageType.LOAD,
    loadRequestData => {
      addBreakToMedia(loadRequestData.media);
      return loadRequestData;
    });
context.start();

โฆษณา VAST

SDK ผู้รับเว็บรองรับโฆษณา VAST มาตรฐาน IAB หากต้องการรวมโฆษณา VAST ไว้ในสื่อ ให้สร้างออบเจ็กต์ vastAdsRequest แล้วกําหนดให้กับพร็อพเพอร์ตี้ vastAdsRequest ของ BreakClip ออบเจ็กต์ vastAdsRequest ต้องมีการกําหนดพร็อพเพอร์ตี้ adsResponse หรือพร็อพเพอร์ตี้ adTagUrl

/**
 * @param {!cast.framework.messages.MediaInformation} mediaInformation
 */
function addBreakToMedia(mediaInformation) {
  mediaInformation.breakClips = [
  {
    id: 'bc1',
    vastAdsRequest:{
      adTagUrl: 'https://castsample.com/vast?rand=' + Math.floor(Math.random()* 10000)
    }
  }];
}

SDK ผู้รับเว็บจะส่งคําขอไปยัง adTagUrl ที่ระบุ และแยกวิเคราะห์การตอบกลับ XML เพื่อสร้างออบเจ็กต์ BreakClip ด้านล่างเป็นตัวอย่างของออบเจ็กต์ BreakClip ที่ SDK ของเราสร้างขึ้น

{
  "id": "GENERATED:0",
  "contentId": "https://file.mp4",
  "contentType": "video/mp4",
  "title": "Preroll",
  "duration": 10,
  "clickThroughUrl": "https://click"
}

โฆษณา VMAP

SDK ตัวรับเว็บยังรองรับมาตรฐาน VMAP ของ IAB ด้วย เมื่อมี VMAP แล้ว Cast SDK จะแยกวิเคราะห์การตอบสนองของ VMAP และสร้างออบเจ็กต์ Break สําหรับรายการ <AdBreak> ที่ระบุในการตอบกลับ นอกจากนี้ ยังสร้างBreakClipsที่เหมาะสมด้วยออบเจ็กต์ vastAdsRequest สําหรับแต่ละรายการ <AdSource> ที่มีอยู่ใน VMAP หากต้องการใช้ VMAP ในการแทรกโฆษณาลงในเนื้อหา ให้สร้างออบเจ็กต์ vastAdsRequest และกําหนดไปยังพร็อพเพอร์ตี้ vmapAdsRequest ของออบเจ็กต์ MediaInformation อันเป็นส่วนหนึ่งของคําขอโหลด

/**
 * @param {!cast.framework.messages.MediaInformation} mediaInformation
 */
function addBreakToMedia(mediaInformation) {
  mediaInformation.vmapAdsRequest = {
    adTagUrl: 'https://castsample.com/vmap?rand=' + Math.floor(Math.random()* 10000)
  };
}

การต่อโฆษณาฝั่งเซิร์ฟเวอร์

สําหรับการต่อวิดีโอฝั่งเซิร์ฟเวอร์ หรือที่เรียกว่าโฆษณาที่ฝัง เซิร์ฟเวอร์คาดว่าจะให้สตรีมเดี่ยวที่มีทั้งสื่อหลักและโฆษณา ในกรณีนี้ นักพัฒนาแอปจะต้องระบุ duration และ contentType ของ BreakClip ข้าม contentUrl ไป นอกจากนี้ ต้องตั้งค่า isEmbedded เป็น "จริง"

/**
 * @param {!cast.framework.messages.MediaInformation} mediaInformation
 */
function addBreakToMedia(mediaInformation) {
  mediaInformation.breakClips = [
  {
    id: 'bc1',
    title: third_party.getBreakClipTitle('bc1'),
    posterUrl: third_party.getBreakClipPosterUrl('bc1'),
    duration: third_party.getBreakClipDuration('bc1')
  },
  {
    id: 'bc2'
    ...
  },
  {
    id: 'bc3'
    ...
  },
  {
    id: 'bc4'
    ...
  }];
  mediaInformation.breaks = [
  {
    id: 'b1',
    breakClipIds: ['bc1', 'bc2'],
    position: 0,
    isEmbedded: true
  },
  {
    id: 'b2',
    breakClipIds: ['bc3', 'bc4'],
    position: 10*60,
    isEmbedded: true
  }];
}

const context = cast.framework.CastReceiverContext.getInstance();
const playerManager = context.getPlayerManager();
playerManager.setMessageInterceptor(
    cast.framework.messages.MessageType.LOAD,
    loadRequestData => {
      addBreakToMedia(loadRequestData.media);
      return loadRequestData;
    });
context.start();

ลักษณะการทํางานของช่วงพัก

ลักษณะการทํางานเริ่มต้นของช่วงพักโฆษณา

  1. เมื่อเริ่มต้นช่วงพัก จะมีเครื่องหมายเป็น isWatched หากผู้ใช้สครับไปยังจุดก่อนหน้าช่วงพักโฆษณา
  2. หากผู้ใช้สครับผ่านทางช่วงพักโดยไม่มีการดูช่วงพัก การเล่นช่วงพักสุดท้ายระหว่าง seekFrom กับ seekTo จะเล่นก่อนที่เนื้อหาจะเริ่มเล่น

ลักษณะการทํางานของช่วงพักโฆษณาที่กําหนดเอง

คุณแก้ไขdefault behaviorสําหรับตัวแบ่งและคลิปช่วงพักโฆษณาได้โดยใช้เมธอด setBreakClipLoadInterceptor และ setBreakSeekInterceptor ในออบเจ็กต์ BreakManager

setBreakClipLoadInterceptor

ระบบจะเรียก setBreakClipLoadInterceptor ก่อนที่จะถึงช่วงพัก มีการเรียกใช้ฟังก์ชันนี้เพียงครั้งเดียวต่อคลิปช่วงพักโฆษณา แต่จะส่งออบเจ็กต์ BreakClip ไปยังฟังก์ชันเรียกกลับ

เช่น หากมีช่วงพักโฆษณาล่วงหน้า ระบบจะเรียก setBreakClipLoadInterceptor สําหรับช่วงพักโฆษณานั้นทันทีที่วิดีโอเริ่มเล่น ทันทีที่โฆษณาตอนต้นจบลง ระบบจะเรียก setBreakClipLoadInterceptor สําหรับช่วงพักถัดไป

หาก Null หรือไม่มีฟังก์ชันใดในฟังก์ชันเรียกกลับไปยัง setBreakClipLoadInterceptor ระบบจะข้ามคลิปช่วงพักโฆษณา ระบบจะสกัดกั้น สําหรับช่วงพักทั้งหมดทันที

เมื่อใช้ setBreakClipLoadInterceptor ออบเจ็กต์ BreakClip จะแก้ไขได้ก่อนการเล่นจะเริ่มต้นขึ้น

setBreakSeekInterceptor

setBreakSeekInterceptor จะทริกเกอร์หลังจากการดําเนินการค้นหาและส่งออบเจ็กต์ BreakSeekData ไปยังฟังก์ชันเรียกกลับ ออบเจ็กต์ BreakSeekData มีอาร์เรย์ของช่วงพักโฆษณาที่มีการกําหนดตําแหน่งระหว่างเวลาส่วนหัวของตัวควบคุมการเล่นปัจจุบันและเวลาในการค้นหาปลายทาง (เช่น seekFrom กับ seekTo) หลังจากการกรอไปข้างหน้า ลักษณะการทํางานเริ่มต้นคือการเล่นช่วงพักโฆษณาที่ยังไม่ได้เล่นครั้งล่าสุดก่อนเวลา seekTo เมื่อเล่นเสร็จแล้ว การเล่นเนื้อหาจะกลับมาทํางานอีกครั้งจากตําแหน่ง seekTo

ตัวสับเปลี่ยนนี้อนุญาตให้แก้ไขออบเจ็กต์ BreakClip ในช่วงพักโฆษณาที่เกี่ยวข้อง

หากต้องการปรับแต่งลักษณะการทํางาน ให้ใช้setBreakSeekInterceptorเพื่อลบล้าง default behavior หากนํา setBreakSeekInterceptor มาใช้ คุณต้องระบุช่วงพักโฆษณาที่แน่ชัดอย่างชัดเจน

  • หากค่าเป็น Null หรือไม่แสดงผลจาก setBreakSeekInterceptor ระบบจะข้ามตัวแบ่งดังกล่าว
  • หากมีการส่งออบเจ็กต์เดียวกันที่ส่งไปยังฟังก์ชันเรียกกลับ ระบบจะลบล้าง default behavior และช่วงพักโฆษณาทั้งหมดจะเล่น นอกจากนี้ หากผู้ใช้สครับไปยังจุดก่อนหน้า พวกเขาจะเห็นช่วงพักแม้ว่าจะดูช่วงพักเหล่านั้นแล้วก็ตาม หากไม่ได้ใช้ setBreakSeekInterceptor ระบบจะข้ามช่วงพักที่ดูไปแล้ว

การทําให้คลิปช่วงพักโฆษณาเป็นแบบข้ามได้

หากต้องการทําให้คลิปช่วงพักโฆษณาเป็นแบบข้ามได้ ให้ระบุจํานวนวินาทีที่ต้องรอก่อนคลิปคลิปจะข้ามได้ในออบเจ็กต์ BreakClip

/**
 * @param {!cast.framework.messages.MediaInformation} mediaInformation
 */
function addBreakToMedia(media) {
  media.breakClips = [
  {
    id: 'bc1',
    ...
    whenSkippable: 10 //to allow user to skip break clip from sender after 10 seconds
  }];
}

โฆษณาที่ข้ามโดยอัตโนมัติ

ระบบจะข้ามโฆษณาโดยอัตโนมัติโดยไม่ต้องโต้ตอบกับผู้ใช้ การข้ามโฆษณามี 2 วิธีดังนี้

  1. การตั้งค่าพร็อพเพอร์ตี้ isWatched ของช่วงพักเป็น "จริง" จะข้ามช่วงพักโดยอัตโนมัติ
    playerManager.addEventListener(cast.framework.events.category.CORE, function(event){
      if(event.type === cast.framework.events.EventType.PLAYER_LOADING){
        let breaks = playerManager.getBreaks();
        for(let i in breaks){
          breaks[i].isWatched = true;
        }
      }
    });
  2. ข้าม BreakClip ได้โดยการแสดงผลค่าว่างใน setBreakClipLoadInterceptor การเรียกกลับ
    playerManager.getBreakManager().setBreakClipLoadInterceptor(breakClip => {
      return null;
    });