เพิ่มฟีเจอร์ขั้นสูงลงในแอป Web Sender

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

Web Sender SDK รองรับช่วงพักโฆษณาและโฆษณาที่แสดงร่วมกันภายในสตรีมสื่อที่ระบุ

ดูข้อมูลเพิ่มเติมเกี่ยวกับวิธีการทำงานของช่วงพักโฆษณาได้ที่ภาพรวมช่วงพักโฆษณาของ Web Receiver

แม้ว่าคุณจะระบุช่วงพักได้ทั้งในส่วนผู้ส่งและผู้รับ แต่เราขอแนะนำให้ระบุในตัวรับบนเว็บและตัวรับ Android TV เพื่อให้ลักษณะการทำงานมีความสอดคล้องกันในทุกแพลตฟอร์ม

บนเว็บ ให้ระบุช่วงพักโฆษณาในคําสั่งโหลดโดยใช้ BreakClip และ Break

let breakClip1 = new BreakClip('bc0');
breakClip1.title = 'Clip title'
breakClip1.posterUrl = 'https://www.some.url';
breakClip1.duration = 60;
breakClip.whenSKippable = 5;

let breakClip2 = ...
let breakClip3 = ...

let break1 = new Break('b0', ['bc0', 'bc1', 'bc2'], 10);

let mediaInfo = new chrome.cast.media.MediaInfo(<contentId>, '<contentType');
...
mediaInfo.breakClips = [breakClip1, breakClip2, breakClip3];
mediaInfo.breaks = [break1];

let request = new chrome.cast.media.LoadRequest(mediaInfo);

cast.framework.CastContext.getInstance().getCurrentSession().loadMedia(request)

การใช้ Tracks API

แทร็กอาจเป็นออบเจ็กต์ข้อความ (คำบรรยายหรือคำบรรยายแทนเสียง) หรือออบเจ็กต์สตรีมเสียงหรือวิดีโอก็ได้ Tracks API ช่วยให้คุณทำงานกับออบเจ็กต์เหล่านี้ในแอปพลิเคชันได้

ออบเจ็กต์ Track แสดงถึงแทร็กใน SDK คุณกําหนดค่าแทร็กและกําหนดรหัสที่ไม่ซ้ำกันให้กับแทร็กได้ดังนี้

var englishSubtitle = new chrome.cast.media.Track(1, // track ID
  chrome.cast.media.TrackType.TEXT);
englishSubtitle.trackContentId = 'https://some-url/caption_en.vtt';
englishSubtitle.trackContentType = 'text/vtt';
englishSubtitle.subtype = chrome.cast.media.TextTrackType.SUBTITLES;
englishSubtitle.name = 'English Subtitles';
englishSubtitle.language = 'en-US';
englishSubtitle.customData = null;

var frenchSubtitle = new chrome.cast.media.Track(2, // track ID
  chrome.cast.media.TrackType.TEXT);
frenchSubtitle.trackContentId = 'https://some-url/caption_fr.vtt';
frenchSubtitle.trackContentType = 'text/vtt';
frenchSubtitle.subtype = chrome.cast.media.TextTrackType.SUBTITLES;
frenchSubtitle.name = 'French Subtitles';
frenchSubtitle.language = 'fr';
frenchSubtitle.customData = null;

var frenchAudio = new chrome.cast.media.Track(3, // track ID
  chrome.cast.media.TrackType.AUDIO);
frenchAudio.trackContentId = 'trk0001';
frenchAudio.trackContentType = 'audio/mp3';
frenchAudio.subtype = null;
frenchAudio.name = 'French Audio';
frenchAudio.language = 'fr';
frenchAudio.customData = null;

รายการสื่ออาจมีหลายแทร็ก เช่น อาจมีคำบรรยายหลายรายการ (แต่ละรายการเป็นภาษาที่แตกต่างกัน) หรือสตรีมเสียงสำรองหลายรายการ (สำหรับภาษาที่แตกต่างกัน)

MediaInfo คือคลาสที่จำลองรายการสื่อ หากต้องการเชื่อมโยงคอลเล็กชันของวัตถุ Track กับรายการสื่อ ให้อัปเดตพร็อพเพอร์ตี้ tracks ของรายการนั้น คุณต้องทำการเชื่อมโยงนี้ก่อนจึงจะอัปโหลดสื่อไปยังผู้รับได้

var tracks = [englishSubtitle, frenchSubtitle, frenchAudio];
var mediaInfo = new chrome.cast.media.MediaInfo(mediaURL);
mediaInfo.contentType = 'video/mp4';
mediaInfo.metadata = new chrome.cast.media.GenericMediaMetadata();
mediaInfo.customData = null;
mediaInfo.streamType = chrome.cast.media.StreamType.BUFFERED;
mediaInfo.textTrackStyle = new chrome.cast.media.TextTrackStyle();
mediaInfo.duration = null;
mediaInfo.tracks = tracks;

คุณสามารถตั้งค่าแทร็กที่กำลังใช้งานในคำขอสื่อ activeTrackIds ได้

นอกจากนี้ คุณยังเปิดใช้งานแทร็กอย่างน้อย 1 แทร็กที่เชื่อมโยงกับรายการสื่อได้หลังจากโหลดสื่อแล้ว โดยเรียกใช้ EditTracksInfoRequest(opt_activeTrackIds, opt_textTrackStyle) และส่งรหัสของแทร็กที่จะเปิดใช้งานใน opt_activeTrackIds โปรดทราบว่าพารามิเตอร์ทั้ง 2 รายการนี้ไม่บังคับ และคุณเลือกแทร็กหรือสไตล์ที่ใช้งานอยู่ได้ ตัวอย่างเช่น วิธีเปิดใช้งานคำบรรยายภาษาฝรั่งเศส (2) และเสียงภาษาฝรั่งเศส (3) มีดังนี้

var activeTrackIds = [2, 3];
var tracksInfoRequest = new chrome.cast.media.EditTracksInfoRequest(activeTrackIds);
media.editTracksInfo(tracksInfoRequest, successCallback, errorCallback);

หากต้องการนำแทร็กเสียงหรือวิดีโอทั้งหมดออกจากสื่อปัจจุบัน เพียงตั้งค่า mediaInfo.tracks=null (อาร์เรย์ว่าง) แล้วโหลดสื่ออีกครั้ง

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

  • อัปเดต var activeTrackIds = [2, 3]; (แสดงก่อนหน้านี้) ให้รวมเฉพาะ [3] ซึ่งเป็นแทร็กเสียง
  • ตั้งค่า mediaInfo.tracks=null โปรดทราบว่าคุณไม่จำเป็นต้องโหลดสื่อซ้ำเพื่อปิดคำบรรยายแทนเสียง (track.hidden) การส่งอาร์เรย์ activeTracksId ที่ไม่มี trackId ที่เปิดใช้ไว้ก่อนหน้านี้จะเป็นการปิดแทร็กข้อความ

การจัดรูปแบบแทร็กข้อความ

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

var textTrackStyle = new chrome.cast.media.TextTrackStyle();
var tracksInfoRequest = new chrome.cast.media.EditTracksInfoRequest(textTrackStyle);
media.editTracksInfo(tracksInfoRequest, successCallback, errorCallback);

คุณสามารถติดตามสถานะของคําขอด้วยผลลัพธ์ของการติดต่อกลับ ไม่ว่าจะเป็นความสําเร็จหรือข้อผิดพลาด และอัปเดตผู้ส่งต้นทางตามความเหมาะสม

แอปพลิเคชันควรอนุญาตให้ผู้ใช้อัปเดตสไตล์สำหรับแทร็กข้อความได้ โดยใช้การตั้งค่าที่ระบบหรือแอปพลิเคชันเองมีให้

คุณจัดรูปแบบองค์ประกอบสไตล์แทร็กข้อความต่อไปนี้ได้

  • สีและความทึบแสงของพื้นหน้า (ข้อความ)
  • สีและความโปร่งแสงของพื้นหลัง
  • ชนิดขอบ
  • สีขอบ
  • ขนาดแบบอักษร
  • ชุดแบบอักษร
  • รูปแบบตัวอักษร

เช่น กำหนดสีข้อความเป็นสีแดงที่มีความทึบแสง 75% ดังนี้

var textTrackStyle = new chrome.cast.media.TextTrackStyle();
textTrackStyle.foregroundColor = '#80FF0000';

การควบคุมระดับเสียง

คุณใช้ปุ่ม RemotePlayer และ RemotePlayerController เพื่อตั้งค่าระดับเสียงของรีซีฟเวอร์ได้

function changeVolume(newVolume) {
  player.volumeLevel = newVolume;
  playerController.setVolumeLevel();
  // Update sender UI to reflect change
}

แอปของผู้ส่งควรปฏิบัติตามหลักเกณฑ์ต่อไปนี้ในการควบคุมระดับเสียง

  • แอปพลิเคชันของผู้ส่งต้องซิงค์กับผู้รับเพื่อให้ UI ของผู้ส่งรายงานระดับเสียงตามผู้รับเสมอ ใช้การเรียกกลับ RemotePlayerEventType.VOLUME_LEVEL_CHANGED และ RemotePlayerEventType.IS_MUTED_CHANGED เพื่อคงระดับเสียงของผู้ส่งไว้ ดูข้อมูลเพิ่มเติมได้ที่การอัปเดตสถานะ
  • แอปฝั่งผู้ส่งต้องไม่ตั้งค่าระดับเสียงเป็นระดับที่เจาะจงซึ่งกำหนดไว้ล่วงหน้า หรือตั้งค่าระดับเสียงเป็นระดับเสียงปลุก/สื่อของอุปกรณ์ฝั่งผู้ส่งเมื่อแอปโหลดในอุปกรณ์ฝั่งผู้รับ

ดูตัวควบคุมระดับเสียงของผู้ส่งในรายการตรวจสอบการออกแบบ

การส่งข้อความสื่อไปยังผู้รับ

Media Messages ส่งจากผู้ส่งไปยังผู้รับได้ ตัวอย่างเช่น หากต้องการส่งข้อความ SKIP_AD ไปยังผู้รับ ให้ทำดังนี้

// Get a handle to the skip button element
const skipButton = document.getElementById('skip');
skipButton.addEventListener("click", function() {
  if (castSession) {
    const media = castSession.getMediaSession();
    castSession.sendMessage('urn:x-cast:com.google.cast.media', {
      type: 'SKIP_AD',
      requestId: 1,
      mediaSessionId: media.mediaSessionId
    });
  }
});

การอัปเดตสถานะ

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

ด้วยเหตุนี้ แอปพลิเคชันของคุณจึงควรลงทะเบียน Listener ที่จำเป็นทั้งหมดใน RemotePlayerController หากมีการเปลี่ยนแปลง TextTrackStyle ของสื่อปัจจุบัน ผู้ส่งที่เชื่อมต่อทั้งหมดจะได้รับการแจ้งเตือน และระบบจะส่งพร็อพเพอร์ตี้ที่เกี่ยวข้องของเซสชันสื่อปัจจุบัน เช่น activeTrackIds และ textTrackStyle ของช่อง MediaInfo ไปยังผู้ส่งในการเรียกกลับ ในกรณีนี้ SDK ของผู้รับจะไม่ยืนยันว่ารูปแบบใหม่แตกต่างจากรูปแบบก่อนหน้าหรือไม่ และจะแจ้งให้ผู้ส่งที่เชื่อมต่อทั้งหมดทราบโดยไม่คำนึงถึง

สัญญาณบอกสถานะความคืบหน้า

การแสดงตำแหน่งการเล่นพร้อมตัวบ่งบอกความคืบหน้าในฝั่งผู้ส่งเป็นข้อกำหนดสำหรับแอปส่วนใหญ่ Cast API ใช้โปรโตคอลสื่อ Cast ซึ่งจะเพิ่มประสิทธิภาพการใช้แบนด์วิดท์สำหรับสถานการณ์นี้และสถานการณ์อื่นๆ คุณจึงไม่จำเป็นต้องใช้การซิงค์สถานะของคุณเอง ดูการใช้งานตัวบ่งชี้ความคืบหน้าในการเล่นสื่อโดยใช้ API อย่างถูกต้องได้ที่แอปตัวอย่าง CastVideos-chrome

ข้อกำหนด CORS

สําหรับสตรีมมิงสื่อแบบปรับเปลี่ยนได้ Google Cast ต้องมีส่วนหัว CORS แต่สตรีมสื่อ mp4 ธรรมดาก็ต้องใช้ CORS ด้วยหากมีแทร็ก หากต้องการเปิดใช้แทร็กสำหรับสื่อใดก็ตาม คุณต้องเปิดใช้ CORS สำหรับทั้งสตรีมแทร็กและสตรีมสื่อ ดังนั้น หากคุณไม่มีส่วนหัว CORS สำหรับสื่อ mp4 ธรรมดาในเซิร์ฟเวอร์ และเพิ่มแทร็กคำบรรยายธรรมดา คุณจะสตรีมสื่อไม่ได้ เว้นแต่คุณจะอัปเดตเซิร์ฟเวอร์ให้รวมส่วนหัว CORS ที่เหมาะสม

คุณต้องมีส่วนหัวต่อไปนี้ Content-Type,Accept-Encoding และ Range โปรดทราบว่าส่วนหัว 2 รายการสุดท้าย Accept-Encoding และ Range เป็นส่วนหัวเพิ่มเติมที่คุณอาจไม่จําเป็นต้องใช้ก่อนหน้านี้

ใช้ไวลด์การ์ด "*" กับส่วนหัว Access-Control-Allow-Origin ไม่ได้ หากหน้าเว็บมีเนื้อหาสื่อที่ได้รับการคุ้มครอง หน้าเว็บนั้นต้องใช้โดเมนแทนไวลด์การ์ด

ดำเนินเซสชันต่อโดยไม่ต้องโหลดหน้าเว็บซ้ำ

หากต้องการกลับมาใช้ CastSession ที่มีอยู่ ให้ใช้ requestSessionById(sessionId) กับ sessionId ของเซสชันที่พยายามเข้าร่วม

sessionId จะอยู่ใน CastSession ที่ใช้งานอยู่โดยใช้ getSessionId() หลังจากเรียกใช้ loadMedia()

แนวทางที่แนะนำคือ

  1. โทรหา loadMedia() เพื่อเริ่มเซสชัน
  2. จัดเก็บ sessionId ไว้ในเครื่อง
  3. เข้าร่วมเซสชันอีกครั้งโดยใช้ requestSessionById(sessionId) เมื่อจำเป็น
let sessionId;

function rejoinCastSession() {
  chrome.cast.requestSessionById(sessionId);

  // Add any business logic to load new content or only resume the session
}

document.getElementById('play-button').addEventListener(("click"), function() {
  if (sessionId == null) {
    let castSession = cast.framework.CastContext.getInstance().getCurrentSession();
    if (castSession) {
      let mediaInfo = createMediaInfo();
      let request = new chrome.cast.media.LoadRequest(mediaInfo);
      castSession.loadMedia(request)

      sessionId = CastSession.getSessionId();
    } else {
      console.log("Error: Attempting to play media without a Cast Session");
    }
  } else {
    rejoinCastSession();
  }
});

ขั้นตอนถัดไป

นี่เป็นฟีเจอร์ทั้งหมดที่คุณเพิ่มลงในแอปส่งทางเว็บได้ ตอนนี้คุณสร้างแอปส่งสำหรับแพลตฟอร์มอื่น (Android หรือ iOS) หรือสร้างแอปผู้รับได้แล้ว