ผสานรวม SDK ของ Cast ลงในแอป Web Sender

คู่มือนักพัฒนาแอปนี้อธิบายวิธีเพิ่มการรองรับ Google Cast ลงในแอป Web Sender โดยใช้ Cast SDK

คำศัพท์

อุปกรณ์เคลื่อนที่หรือเบราว์เซอร์คือผู้ส่ง ซึ่งควบคุมการเล่น ส่วนอุปกรณ์ Google Cast คือผู้รับ ซึ่งจะแสดงเนื้อหาบนหน้าจอเพื่อเล่น

Web Sender SDK ประกอบด้วย 2 ส่วน ได้แก่ Framework API (cast.framework) และ Base API (chrome.cast) โดยทั่วไปแล้ว คุณจะต้องเรียกใช้ Framework API ที่ง่ายกว่าและอยู่ในระดับที่สูงขึ้น ซึ่ง Base API ในระดับที่ต่ำกว่าจะประมวลผล

เฟรมเวิร์กของผู้ส่งหมายถึง Framework API, โมดูล และทรัพยากรที่เกี่ยวข้องซึ่งให้บริการ Wrapper เกี่ยวกับฟังก์ชันระดับล่าง แอปผู้ส่งหรือแอป Google Cast ใน Chrome หมายถึงแอปเว็บ (HTML/JavaScript) ที่ทำงานภายในเบราว์เซอร์ Chrome บนอุปกรณ์ของผู้ส่ง แอปตัวรับสัญญาณบนเว็บหมายถึงแอป HTML/JavaScript ที่ทำงานบน Chromecast หรืออุปกรณ์ Google Cast

เฟรมเวิร์กผู้ส่งใช้การออกแบบการเรียกกลับแบบอะซิงโครนัสเพื่อแจ้งเหตุการณ์ให้แอปผู้ส่งทราบและเพื่อเปลี่ยนสถานะต่างๆ ของวงจรชีวิตของแอป Cast

โหลดไลบรารี

แอปของคุณจะต้องทราบตำแหน่งของ Google Cast Web Sender SDK ดังที่แสดงด้านล่างเพื่อให้ใช้ฟีเจอร์ของ Google Cast ได้ เพิ่มพารามิเตอร์การค้นหาของ URL loadCastFramework เพื่อโหลด Web Sender Framework API ด้วย หน้าทั้งหมดของแอปต้องอ้างอิงคลังดังต่อไปนี้

<script src="https://www.gstatic.com/cv/js/sender/v1/cast_sender.js?loadCastFramework=1"></script>

เฟรมเวิร์ก

SDK ของ Web Sender ใช้เนมสเปซ cast.framework* เนมสเปซแสดงถึงสิ่งต่อไปนี้

  • เมธอดหรือฟังก์ชันที่เรียกใช้การดำเนินการใน API
  • Listener เหตุการณ์สําหรับฟังก์ชัน Listener ใน API

เฟรมเวิร์กประกอบด้วยองค์ประกอบหลักต่อไปนี้

  • CastContext เป็นออบเจ็กต์แบบ Singleton ที่ให้ข้อมูลเกี่ยวกับสถานะ Cast ปัจจุบัน และทริกเกอร์เหตุการณ์สำหรับสถานะ Cast และการเปลี่ยนแปลงสถานะเซสชัน Cast
  • ออบเจ็กต์ CastSession จะจัดการเซสชัน โดยให้ข้อมูลสถานะและทริกเกอร์เหตุการณ์ เช่น การเปลี่ยนแปลงระดับเสียงของอุปกรณ์ สถานะปิดเสียง และข้อมูลเมตาของแอป
  • องค์ประกอบปุ่มแคสต์ ซึ่งเป็นองค์ประกอบ HTML ที่กําหนดเองแบบง่ายที่ขยายปุ่ม HTML หากปุ่มแคสต์ที่ให้มาไม่เพียงพอ คุณสามารถใช้สถานะแคสต์เพื่อติดตั้งใช้งานปุ่มแคสต์ได้
  • RemotePlayerController ให้การเชื่อมโยงข้อมูลเพื่อลดความซับซ้อนในการใช้งานโปรแกรมเล่นระยะไกล

อ่านข้อมูลอ้างอิง Google Cast Web Sender API เพื่อดูคำอธิบายที่สมบูรณ์ของเนมสเปซ

ปุ่ม "แคสต์"

เฟรมเวิร์กจะจัดการคอมโพเนนต์ปุ่มแคสต์ในแอปของคุณโดยสมบูรณ์ ซึ่งรวมถึงการจัดการการแสดงผลและการจัดการเหตุการณ์คลิก

<google-cast-launcher></google-cast-launcher>

หรือจะสร้างปุ่มแบบเป็นโปรแกรมก็ได้ โดยทำดังนี้

document.createElement("google-cast-launcher");

คุณใช้การจัดรูปแบบเพิ่มเติม เช่น ขนาดหรือตำแหน่ง กับองค์ประกอบได้ตามต้องการ ใช้แอตทริบิวต์ --connected-color เพื่อเลือกสีสำหรับสถานะเว็บรีซีฟเวอร์ที่เชื่อมต่อ และ --disconnected-color สำหรับสถานะไม่ได้เชื่อมต่อ

การเริ่มต้น

หลังจากโหลด API เฟรมเวิร์กแล้ว แอปจะเรียกใช้ตัวแฮนเดิล window.__onGCastApiAvailable คุณควรตรวจสอบว่าแอปตั้งค่าตัวแฮนเดิลนี้ใน window ก่อนโหลดไลบรารีผู้ส่ง

ภายในตัวแฮนเดิลนี้ คุณจะเริ่มต้นการโต้ตอบของ Cast โดยการเรียกใช้เมธอด setOptions(options) ของ CastContext

เช่น

<script>
window['__onGCastApiAvailable'] = function(isAvailable) {
  if (isAvailable) {
    initializeCastApi();
  }
};
</script>

จากนั้นให้เริ่มต้น API ดังนี้

initializeCastApi = function() {
  cast.framework.CastContext.getInstance().setOptions({
    receiverApplicationId: applicationId,
    autoJoinPolicy: chrome.cast.AutoJoinPolicy.ORIGIN_SCOPED
  });
};

ก่อนอื่น แอปจะดึงข้อมูลอินสแตนซ์แบบ Singleton ของออบเจ็กต์ CastContext ที่เฟรมเวิร์กให้มา จากนั้นจะใช้ setOptions(options) โดยใช้ออบเจ็กต์ CastOptions เพื่อตั้งค่า applicationID

หากคุณใช้ตัวรับสื่อเริ่มต้นซึ่งไม่ต้องลงทะเบียน คุณจะใช้ค่าคงที่ที่ Web Sender SDK กำหนดไว้ล่วงหน้าดังที่แสดงด้านล่างแทน applicationID

cast.framework.CastContext.getInstance().setOptions({
  receiverApplicationId: chrome.cast.media.DEFAULT_MEDIA_RECEIVER_APP_ID
});

ส่วนควบคุมสื่อ

เมื่อเริ่มต้นCastContextแล้ว แอปจะดึงข้อมูลCastSessionปัจจุบันได้ทุกเมื่อโดยใช้getCurrentSession()

var castSession = cast.framework.CastContext.getInstance().getCurrentSession();

CastSession ใช้โหลดสื่อไปยังอุปกรณ์แคสต์ที่เชื่อมต่อได้โดยใช้ loadMedia(loadRequest) ขั้นแรก ให้สร้างMediaInfo โดยใช้ contentId และ contentType รวมถึงข้อมูลอื่นๆ ที่เกี่ยวข้องกับเนื้อหา จากนั้นสร้าง LoadRequest จากคำขอดังกล่าว โดยตั้งค่าข้อมูลที่เกี่ยวข้องทั้งหมดสำหรับคำขอ สุดท้าย ให้โทรหา loadMedia(loadRequest) บน CastSession

var mediaInfo = new chrome.cast.media.MediaInfo(currentMediaURL, contentType);
var request = new chrome.cast.media.LoadRequest(mediaInfo);
castSession.loadMedia(request).then(
  function() { console.log('Load succeed'); },
  function(errorCode) { console.log('Error code: ' + errorCode); });

เมธอด loadMedia จะแสดงผลสัญญาที่ใช้ดำเนินการที่จำเป็นเพื่อให้ได้ผลลัพธ์ที่ต้องการ หาก Promise ถูกปฏิเสธ อาร์กิวเมนต์ของฟังก์ชันจะเป็น chrome.cast.ErrorCode

คุณเข้าถึงตัวแปรสถานะโปรแกรมเล่นได้ใน RemotePlayer การโต้ตอบทั้งหมดกับ RemotePlayer รวมถึงการเรียกกลับเหตุการณ์สื่อและคำสั่งต่างๆ จะจัดการด้วย RemotePlayerController

var player = new cast.framework.RemotePlayer();
var playerController = new cast.framework.RemotePlayerController(player);

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

  • เล่น/หยุดชั่วคราว: playerController.playOrPause();
  • STOP: playerController.stop();
  • SEEK: playerController.seek();

คุณสามารถใช้ RemotePlayer และ RemotePlayerController กับเฟรมเวิร์กการเชื่อมโยงข้อมูล เช่น Polymer หรือ Angular เพื่อติดตั้งใช้งานเพลเยอร์ระยะไกลได้

ข้อมูลโค้ดสําหรับ Angular มีดังนี้

<button id="playPauseButton" class="playerButton"
  ng-disabled="!player.canPause"
  ng-click="controller.playOrPause()">
    {{player.isPaused ? 'Play' : 'Pause'}}
</button>
<script>
var player = new cast.framework.RemotePlayer();
var controller = new cast.framework.RemotePlayerController(player);
// Listen to any player update, and trigger angular data binding
update.controller.addEventListener(
  cast.framework.RemotePlayerEventType.ANY_CHANGE,
  function(event) {
    if (!$scope.$$phase) $scope.$apply();
  });
</script>

สถานะสื่อ

ระหว่างการเล่นสื่อ จะเกิดเหตุการณ์ต่างๆ ขึ้น ซึ่งสามารถบันทึกได้โดยการตั้งค่า Listeners สําหรับเหตุการณ์ cast.framework.RemotePlayerEventType ต่างๆ ในออบเจ็กต์ RemotePlayerController

หากต้องการทราบข้อมูลสถานะสื่อ ให้ใช้เหตุการณ์ cast.framework.RemotePlayerEventType.MEDIA_INFO_CHANGED ซึ่งจะทริกเกอร์เมื่อการเล่นมีการเปลี่ยนแปลงและเมื่อ CastSession.getMediaSession().media มีการเปลี่ยนแปลง

playerController.addEventListener(
  cast.framework.RemotePlayerEventType.MEDIA_INFO_CHANGED, function() {
    // Use the current session to get an up to date media status.
    let session = cast.framework.CastContext.getInstance().getCurrentSession();

    if (!session) {
        return;
    }

    // Contains information about the playing media including currentTime.
    let mediaStatus = session.getMediaSession();
    if (!mediaStatus) {
        return;
    }

    // mediaStatus also contains the mediaInfo containing metadata and other
    // information about the in progress content.
    let mediaInfo = mediaStatus.media;
  });

เมื่อเกิดเหตุการณ์ต่างๆ เช่น หยุดชั่วคราว เล่น เล่นต่อ หรือกรอไปข้างหน้า แอปจะต้องดำเนินการกับเหตุการณ์เหล่านั้นและซิงค์ระหว่างแอปกับแอป Web Receiver บนอุปกรณ์แคสต์ ดูข้อมูลเพิ่มเติมได้ที่การอัปเดตสถานะ

วิธีการทํางานของการจัดการเซสชัน

Cast SDK นำเสนอแนวคิดเซสชัน Cast ซึ่งการสร้างเซสชันนี้รวมขั้นตอนการเชื่อมต่อกับอุปกรณ์ การเปิด (หรือเข้าร่วม) แอป Web Receiver การเชื่อมต่อกับแอปนั้น และเริ่มต้นช่องการควบคุมสื่อ ดูข้อมูลเพิ่มเติมเกี่ยวกับเซสชันแคสต์และวงจรชีวิตของ Web Receiver ได้ในคู่มือวงจรชีวิตของแอปพลิเคชันของ Web Receiver

เซสชันจะจัดการโดยคลาส CastContext ซึ่งแอปของคุณเรียกดูได้ผ่าน cast.framework.CastContext.getInstance() เซสชันแต่ละรายการแสดงโดยคลาสย่อยของคลาส Session เช่น CastSession represent sessions with Cast devices แอปของคุณเข้าถึงเซสชัน Cast ที่ใช้งานอยู่ในปัจจุบันได้ผ่าน CastContext.getCurrentSession()

หากต้องการตรวจสอบสถานะเซสชัน ให้เพิ่ม Listener ลงใน CastContext สําหรับประเภทเหตุการณ์ CastContextEventType.SESSION_STATE_CHANGED

var context = cast.framework.CastContext.getInstance();
context.addEventListener(
  cast.framework.CastContextEventType.SESSION_STATE_CHANGED,
  function(event) {
    switch (event.sessionState) {
      case cast.framework.SessionState.SESSION_STARTED:
      case cast.framework.SessionState.SESSION_RESUMED:
        break;
      case cast.framework.SessionState.SESSION_ENDED:
        console.log('CastContext: CastSession disconnected');
        // Update locally as necessary
        break;
    }
  })

สําหรับการยกเลิกการเชื่อมต่อ เช่น เมื่อผู้ใช้คลิกปุ่ม "หยุดแคสต์" จากกล่องโต้ตอบแคสต์ คุณสามารถเพิ่ม Listener สําหรับประเภทเหตุการณ์ RemotePlayerEventType.IS_CONNECTED_CHANGED ใน Listener ในโปรแกรมฟัง ให้ตรวจสอบว่า RemotePlayer ตัดการเชื่อมต่อหรือไม่ หากใช่ ให้อัปเดตสถานะโปรแกรมเล่นในเครื่องตามที่จำเป็น เช่น

playerController.addEventListener(
  cast.framework.RemotePlayerEventType.IS_CONNECTED_CHANGED, function() {
    if (!player.isConnected) {
      console.log('RemotePlayerController: Player disconnected');
      // Update local player to disconnected state
    }
  });

แม้ว่าผู้ใช้จะควบคุมการสิ้นสุดการแคสต์ได้โดยตรงผ่านปุ่มแคสต์ของเฟรมเวิร์ก แต่ผู้ส่งเองก็หยุดการแคสต์ได้โดยใช้ออบเจ็กต์ CastSession ในปัจจุบัน

function stopCasting() {
  var castSession = cast.framework.CastContext.getInstance().getCurrentSession();
  // End the session and pass 'true' to indicate
  // that Web Receiver app should be stopped.
  castSession.endSession(true);
}

การโอนสตรีม

การรักษาสถานะเซสชันเป็นพื้นฐานของการโอนสตรีม ซึ่งผู้ใช้สามารถย้ายสตรีมเสียงและวิดีโอที่มีอยู่ไปยังอุปกรณ์ต่างๆ ได้โดยใช้คำสั่งเสียง แอป Google Home หรือจออัจฉริยะ สื่อจะหยุดเล่นในอุปกรณ์หนึ่ง (แหล่งที่มา) และเล่นต่อในอีกอุปกรณ์หนึ่ง (ปลายทาง) อุปกรณ์แคสต์ทุกรุ่นที่ใช้เฟิร์มแวร์ล่าสุดสามารถทำหน้าที่เป็นแหล่งที่มาหรือปลายทางในการโอนสตรีม

หากต้องการรับอุปกรณ์ปลายทางเครื่องใหม่ในระหว่างการโอนสตรีม ให้เรียกใช้ CastSession#getCastDevice() เมื่อมีการเรียกใช้เหตุการณ์ cast.framework.SessionState.SESSION_RESUMED

ดูข้อมูลเพิ่มเติมได้ในหัวข้อการโอนสตรีมใน Web Receiver