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

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

คำศัพท์

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

SDK ของ Web Sender ประกอบด้วย 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 ได้นั้น แอปจำเป็นต้องทราบตำแหน่งของ SDK Web Sender ของ 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 ของผู้ส่งเว็บใช้ Namespace cast.framework.* Namespace แสดงถึงสิ่งต่อไปนี้:

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

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

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

ตรวจสอบเอกสารอ้างอิง API ของ Google Cast Web Sender เพื่อดูคำอธิบายเนมสเปซทั้งหมด

ปุ่ม "แคสต์"

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

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

หรือคุณอาจสร้างปุ่มโดยใช้โปรแกรมโดยทำตามขั้นตอนต่อไปนี้

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

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

การเริ่มต้น

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

ภายในเครื่องจัดการนี้ คุณเริ่มต้นการโต้ตอบกับการแคสต์ด้วยการเรียกใช้เมธอด 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

หากคุณใช้ตัวรับสื่อเริ่มต้นซึ่งไม่ต้องมีการลงทะเบียน คุณจะใช้ SDK ของ Web Sender ที่กำหนดไว้ล่วงหน้าตามที่แสดงด้านล่างแทน 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 ช่วยให้แอปควบคุมสื่อได้อย่างเต็มรูปแบบ ไม่ว่าจะเป็น PLAY, หยุดชั่วคราว, หยุด และ "ดู" สำหรับสื่อที่โหลด

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

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

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

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

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

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

ดูข้อมูลเพิ่มเติมได้ที่การโอนสตรีมบนเว็บรีซีฟเวอร์