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

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

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

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

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

ในเว็บ ให้ระบุช่วงพักโฆษณาในคำสั่งโหลดโดยใช้ 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)

การใช้ 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);

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

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

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

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

ตัวอย่างเช่น ตั้งค่าสีข้อความเป็นสีแดงที่มีความทึบแสง 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 ของผู้ส่งรายงานระดับเสียงตามตัวรับเสมอ ใช้ Callback 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 จะส่งไปยังผู้ส่งใน Callback ในกรณีนี้ 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) หรือ สร้างแอปตัวรับสัญญาณได้แล้ว