ผสานรวม 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 ได้ แอปจะต้องทราบ ตำแหน่งของ Google Cast Web Sender SDK ดังที่แสดงด้านล่าง เพิ่มพารามิเตอร์การค้นหา URL ของ loadCastFramework เพื่อโหลด API ของ Web Sender Framework ด้วย ทุกหน้าของแอปต้องอ้างอิงถึงไลบรารีดังนี้

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

เฟรมเวิร์ก

Web Sender SDK ใช้เนมสเปซ 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 เพื่อ เลือกสีสำหรับสถานะ Web Receiver ที่เชื่อมต่อ และ --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 ที่ใช้เพื่อดำเนินการที่จำเป็นเพื่อให้ได้ผลลัพธ์ที่ต้องการ หาก Promise ถูกปฏิเสธ อาร์กิวเมนต์ของฟังก์ชันจะเป็น chrome.cast.ErrorCode

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

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

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

  • เล่น/หยุดชั่วคราว: playerController.playOrPause();
  • หยุด: 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>

สถานะสื่อ

ในระหว่างการเล่นสื่อ จะเกิดเหตุการณ์ต่างๆ ขึ้น ซึ่งคุณสามารถบันทึกได้โดยการตั้งค่า เครื่องมือฟังสำหรับ 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 ดูข้อมูลเพิ่มเติมได้ที่การอัปเดตสถานะ

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

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

เซสชันได้รับการจัดการโดยชั้นเรียน CastContext ซึ่งแอปของคุณสามารถเรียกข้อมูลผ่าน cast.framework.CastContext.getInstance() ได้ เซสชันแต่ละรายการจะแสดงด้วยคลาสย่อยของคลาส Session เช่น CastSession แสดงเซสชันที่มีอุปกรณ์แคสต์ แอปของคุณสามารถเข้าถึงเซสชัน 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
    }
  });

แม้ว่าผู้ใช้จะควบคุมการสิ้นสุดการแคสต์ได้โดยตรงผ่านปุ่ม Cast ของเฟรมเวิร์ก แต่ผู้ส่งเองก็หยุดการแคสต์ได้โดยใช้ออบเจ็กต์ current 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 หรือจออัจฉริยะ สื่อจะหยุดเล่นในอุปกรณ์หนึ่ง (แหล่งที่มา) และเล่นต่อในอีกอุปกรณ์หนึ่ง (ปลายทาง) อุปกรณ์ Cast ที่มีเฟิร์มแวร์ล่าสุดสามารถใช้เป็นแหล่งที่มาหรือปลายทางในการ โอนสตรีมได้

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

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