สร้างเว็บรีซีฟเวอร์ที่กำหนดเอง

1. ภาพรวม

โลโก้ Google Cast

Codelab นี้จะสอนวิธีสร้างแอป Web Receiver แบบกำหนดเองเพื่อเล่นเนื้อหาบนอุปกรณ์ที่พร้อมใช้งาน Cast

Google Cast คืออะไร

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

Google Cast SDK ช่วยให้แอปของคุณควบคุมอุปกรณ์ที่พร้อมใช้งาน Google Cast ได้ (เช่น ทีวีหรือระบบเสียง) Cast SDK มีคอมโพเนนต์ UI ที่จำเป็นตามรายการตรวจสอบการออกแบบ Google Cast

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

เราจะสร้างอะไร

เมื่อทำ Codelab นี้เสร็จแล้ว คุณจะมีแอป HTML5 ที่ทำหน้าที่เป็นตัวรับสัญญาณที่กำหนดเองของคุณเอง ซึ่งสามารถแสดงเนื้อหาวิดีโอบนอุปกรณ์ที่พร้อมใช้งาน Cast

สิ่งที่คุณจะได้เรียนรู้

  • วิธีตั้งค่าสำหรับการพัฒนาตัวรับ
  • ข้อมูลพื้นฐานของตัวรับที่พร้อมใช้งาน Cast โดยอิงตามเฟรมเวิร์กแอปพลิเคชัน Cast
  • วิธีรับวิดีโอที่แคสต์
  • วิธีผสานรวมเครื่องบันทึกการแก้ไขข้อบกพร่อง
  • วิธีเพิ่มประสิทธิภาพเครื่องรับสำหรับจออัจฉริยะ

สิ่งที่คุณต้องมี

  • เบราว์เซอร์ Google Chrome เวอร์ชันล่าสุด
  • บริการโฮสติ้ง HTTPS เช่น Firebase Hosting หรือ ngrok
  • อุปกรณ์ Google Cast เช่น Chromecast หรือ Android TV ที่กำหนดค่าให้เข้าถึงอินเทอร์เน็ตได้
  • ทีวีหรือจอภาพที่มีอินพุต HDMI

ประสบการณ์

  • คุณจะต้องมีความรู้ด้านการพัฒนาเว็บมาก่อน
  • นอกจากนี้ คุณยังต้องมีความรู้พื้นฐานเกี่ยวกับการดูทีวีด้วย :)

คุณจะใช้บทแนะนำนี้อย่างไร

อ่านอย่างเดียว อ่านและทำแบบฝึกหัด

คุณจะให้คะแนนประสบการณ์ในการสร้างเว็บแอปเท่าใด

ผู้ฝึกหัด ขั้นกลาง ผู้ชำนาญ

คุณจะให้คะแนนประสบการณ์การดูทีวีเท่าใด

ผู้ฝึกหัด ขั้นกลาง ผู้ชำนาญ

2. รับโค้ดตัวอย่าง

คุณดาวน์โหลดโค้ดตัวอย่างทั้งหมดลงในคอมพิวเตอร์ได้...

และแตกไฟล์ ZIP ที่ดาวน์โหลด

3. การติดตั้งใช้งานตัวรับสัญญาณในเครื่อง

หากต้องการใช้ตัวรับเว็บกับอุปกรณ์ Cast คุณต้องโฮสต์ตัวรับเว็บในที่ที่อุปกรณ์ Cast เข้าถึงได้ หากคุณมีเซิร์ฟเวอร์ที่รองรับ HTTPS อยู่แล้ว ให้ข้ามวิธีการต่อไปนี้และจด URL ไว้ เนื่องจากคุณจะต้องใช้ในส่วนถัดไป

หากไม่มีเซิร์ฟเวอร์ให้ใช้งาน คุณสามารถใช้ Firebase Hosting หรือ ngrok

เรียกใช้เซิร์ฟเวอร์

เมื่อตั้งค่าบริการที่ต้องการแล้ว ให้ไปที่ app-start แล้วเริ่มเซิร์ฟเวอร์

จดบันทึก URL ของตัวรับที่โฮสต์ คุณจะต้องใช้ในส่วนถัดไป

4. ลงทะเบียนแอปพลิเคชันใน Cast Developer Console

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

รูปภาพของแผงควบคุมสำหรับนักพัฒนาซอฟต์แวร์ Google Cast SDK โดยไฮไลต์ปุ่ม "เพิ่มแอปพลิเคชันใหม่"

คลิก "เพิ่มแอปพลิเคชันใหม่"

รูปภาพหน้าจอ "แอปพลิเคชันตัวรับสัญญาณใหม่" ที่ไฮไลต์ตัวเลือก "ตัวรับสัญญาณที่กำหนดเอง"

เลือก "Custom Receiver" ซึ่งเป็นสิ่งที่เรากำลังสร้าง

รูปภาพหน้าจอ "ตัวรับสัญญาณที่กำหนดเองใหม่" ซึ่งแสดง URL ที่มีคนกำลังพิมพ์ลงในช่อง "URL ของแอปพลิเคชันตัวรับสัญญาณ"

ป้อนรายละเอียดผู้รับใหม่ โดยตรวจสอบว่าใช้ URL ที่คุณได้รับ

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

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

รูปภาพของแผงควบคุมสำหรับนักพัฒนาซอฟต์แวร์ Google Cast SDK โดยไฮไลต์ปุ่ม "เพิ่มอุปกรณ์ใหม่"

คลิก "เพิ่มอุปกรณ์ใหม่"

รูปภาพของกล่องโต้ตอบ "เพิ่มอุปกรณ์รับการแคสต์"

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

ระบบจะใช้เวลา 5-15 นาทีก่อนที่เครื่องรับและอุปกรณ์จะพร้อมสำหรับการทดสอบ หลังจากรอ 5-15 นาที คุณต้องรีบูตอุปกรณ์ Cast

5. เรียกใช้แอปตัวอย่าง

โลโก้ Google Chrome

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

เปิดเครื่องมือคำสั่งและการควบคุม (CaC) ในเบราว์เซอร์

รูปภาพแท็บ "Cast Connect & Logger Controls" ของเครื่องมือ Command and Control (CaC)

  1. คุณควรเห็นเครื่องมือ CaC
  2. ใช้รหัสตัวรับสัญญาณตัวอย่างเริ่มต้น "CC1AD845" แล้วคลิกปุ่ม "ตั้งค่ารหัสแอป"
  3. คลิกปุ่มแคสต์ที่ด้านซ้ายบน แล้วเลือกอุปกรณ์ Google Cast

รูปภาพแท็บ "การควบคุมการเชื่อมต่อและบันทึกการแคสต์" ของเครื่องมือ Command and Control (CaC) ที่ระบุว่าเชื่อมต่อกับแอปตัวรับ

  1. ไปที่แท็บ "โหลดสื่อ" ที่ด้านบน

รูปภาพแท็บ "โหลดสื่อ" ของเครื่องมือ Command and Control (CaC)

  1. คลิกปุ่ม "โหลดตามเนื้อหา" เพื่อเล่นวิดีโอตัวอย่าง
  2. วิดีโอจะเริ่มเล่นบนอุปกรณ์ Google Cast เพื่อแสดงให้เห็นว่าฟังก์ชันการทำงานของเครื่องรับพื้นฐานมีลักษณะอย่างไรเมื่อใช้เครื่องรับเริ่มต้น

6. เตรียมโปรเจ็กต์เริ่มต้น

เราต้องเพิ่มการรองรับ Google Cast ลงในแอปเริ่มต้นที่คุณดาวน์โหลด คำศัพท์บางคำที่เกี่ยวข้องกับ Google Cast ซึ่งเราจะใช้ใน Codelab นี้มีดังนี้

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

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

  1. เลือกไดเรกทอรี ไอคอนโฟลเดอร์app-start จากการดาวน์โหลดโค้ดตัวอย่าง
  2. เปิด js/receiver.js และ index.html

โปรดทราบว่าขณะที่คุณทำตาม Codelab นี้ http-server ควรจะตรวจพบการเปลี่ยนแปลงที่คุณทำ หากพบว่าไม่เป็นเช่นนั้น ให้ลองปิดและรีสตาร์ท http-server

การออกแบบแอป

แอปตัวรับจะเริ่มต้นเซสชัน Cast และจะอยู่ในโหมดสแตนด์บายจนกว่าจะได้รับคำขอ LOAD (หรือก็คือคำสั่งให้เล่นสื่อ) จากผู้ส่ง

แอปประกอบด้วยมุมมองหลัก 1 มุมมองที่กำหนดไว้ใน index.html และไฟล์ JavaScript 1 ไฟล์ชื่อ js/receiver.js ซึ่งมีตรรกะทั้งหมดที่ทำให้ตัวรับทำงานได้

index.html

ไฟล์ HTML นี้จะมี UI สำหรับแอปตัวรับสัญญาณของเรา ตอนนี้ไฟล์นี้ว่างเปล่า และเราจะเพิ่มเนื้อหาลงในไฟล์นี้ตลอดทั้งโค้ดแล็บ

receiver.js

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

7. อุปกรณ์รับการแคสต์พื้นฐาน

เครื่องรับ Cast พื้นฐานจะเริ่มต้นเซสชัน Cast เมื่อเริ่มต้นระบบ ซึ่งจำเป็นต่อการแจ้งให้แอปพลิเคชันของผู้ส่งที่เชื่อมต่อทั้งหมดทราบว่าการเปิดเครื่องรับสำเร็จ นอกจากนี้ SDK ใหม่ยังได้รับการกำหนดค่าล่วงหน้าให้จัดการสื่อสตรีมมิงที่ปรับอัตราบิตได้ (ใช้ DASH, HLS และ Smooth Streaming) และไฟล์ MP4 ธรรมดาได้ทันที มาลองกันเลย

การเริ่มต้น

เพิ่มโค้ดต่อไปนี้ลงใน index.html ในส่วนหัว

<head>
  ...

  <script src="//www.gstatic.com/cast/sdk/libs/caf_receiver/v3/cast_receiver_framework.js"></script>
</head>

เพิ่มโค้ดต่อไปนี้ลงใน index.html <body> ก่อน <footer> loading receiver.js, เพื่อให้ SDK ของตัวรับมีพื้นที่ในการแสดง UI ของตัวรับเริ่มต้นที่มาพร้อมกับสคริปต์ที่คุณเพิ่งเพิ่ม

<cast-media-player></cast-media-player>

ตอนนี้เราต้องเริ่มต้น SDK ใน js/receiver.js ซึ่งประกอบด้วย

  • การรับการอ้างอิงถึง CastReceiverContext ซึ่งเป็นจุดแรกเข้าหลักของ Receiver SDK ทั้งหมด
  • จัดเก็บการอ้างอิงถึง PlayerManager ซึ่งเป็นออบเจ็กต์ที่จัดการการเล่นและให้ฮุกทั้งหมดที่คุณต้องการเพื่อเสียบตรรกะที่กำหนดเองของคุณเอง
  • เริ่มต้น SDK โดยการเรียกใช้ start() ใน CastReceiverContext

เพิ่มรายการต่อไปนี้ไปยัง js/receiver.js

const context = cast.framework.CastReceiverContext.getInstance();
const playerManager = context.getPlayerManager();

context.start();

8. การแคสต์เนื้อหาวิดีโอ "พื้นฐาน"

สำหรับ Codelab นี้ ให้ใช้เครื่องมือ CaC เพื่อลองใช้ตัวรับสัญญาณใหม่ของคุณ

ชี้เว็บเบราว์เซอร์ไปที่เครื่องมือคำสั่งและการควบคุม (CaC)

รูปภาพแท็บ &quot;Cast Connect & Logger Controls&quot; ของเครื่องมือ Command and Control (CaC)

อย่าลืมแทนที่รหัสแอปของคุณเองตามที่ลงทะเบียนไว้ก่อนหน้านี้ในช่อง แล้วคลิก "ตั้งรหัสแอป" ซึ่งจะสั่งให้เครื่องมือใช้ตัวรับสัญญาณเมื่อเริ่มเซสชันการแคสต์

การแคสต์สื่อ

ในระดับสูง หากต้องการเล่นสื่อบนอุปกรณ์แคสต์ จะต้องดำเนินการต่อไปนี้

  1. ผู้ส่งสร้างออบเจ็กต์ MediaInfo JSON จาก Cast SDK ที่จำลองรายการสื่อ
  2. ผู้ส่งจะเชื่อมต่อกับอุปกรณ์แคสต์เพื่อเปิดแอปพลิเคชันตัวรับ
  3. ผู้รับจะโหลดออบเจ็กต์ MediaInfo ผ่านคำขอ LOAD เพื่อเล่นเนื้อหา
  4. ตัวรับจะตรวจสอบและติดตามสถานะสื่อ
  5. ผู้ส่งจะส่งคำสั่งการเล่นไปยังผู้รับเพื่อควบคุมการเล่นตามการโต้ตอบของผู้ใช้กับแอปผู้ส่ง

ในความพยายามขั้นพื้นฐานครั้งแรกนี้ เราจะป้อนข้อมูล MediaInfo ด้วย URL ของชิ้นงานที่เล่นได้ (จัดเก็บไว้ใน MediaInfo.contentUrl)

ผู้ส่งในโลกแห่งความเป็นจริงใช้ตัวระบุสื่อเฉพาะแอปพลิเคชันใน MediaInfo.contentId เครื่องรับใช้ contentId เป็นตัวระบุเพื่อทำการเรียก API แบ็กเอนด์ที่เหมาะสมเพื่อแก้ไข URL ของชิ้นงานจริงและตั้งค่าเป็น MediaInfo.contentUrl. เครื่องรับจะจัดการงานต่างๆ เช่น การขอรับใบอนุญาต DRM หรือการแทรกข้อมูลเกี่ยวกับช่วงพักโฆษณาด้วย

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

รูปภาพแท็บ &quot;การควบคุมการเชื่อมต่อและบันทึกการแคสต์&quot; ของเครื่องมือ Command and Control (CaC) ที่ระบุว่าเชื่อมต่อกับแอปตัวรับ

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

รูปภาพแท็บ &quot;โหลดสื่อ&quot; ของเครื่องมือ Command and Control (CaC)

ดังนั้น Receiver SDK จึงจัดการสิ่งต่อไปนี้ได้ทันที

  • กำลังเริ่มต้นเซสชันการแคสต์
  • จัดการLOADคำขอที่เข้ามาจากผู้ส่งที่มีเนื้อหาที่เล่นได้
  • มี UI ของเพลเยอร์พื้นฐานที่พร้อมแสดงบนหน้าจอขนาดใหญ่

คุณสามารถสำรวจเครื่องมือ CaC และโค้ดของเครื่องมือก่อนที่จะไปยังส่วนถัดไป ซึ่งเราจะขยายตัวรับเพื่อสื่อสารกับ API ตัวอย่างแบบง่ายเพื่อตอบสนองLOADคำขอจากผู้ส่ง

9. ผสานรวมกับ API ภายนอก

เราจะแก้ไขตัวรับเพื่อจัดการLOADคำขอที่อ้างอิงเนื้อหาสื่อที่ต้องการด้วยคีย์ API แทนที่จะส่ง URL ของชิ้นงานที่เล่นได้ ซึ่งสอดคล้องกับวิธีที่นักพัฒนาแอปส่วนใหญ่โต้ตอบกับตัวรับ Cast ในแอปพลิเคชันในโลกแห่งความเป็นจริง

โดยปกติแล้ว แอปพลิเคชันจะทำเช่นนี้เนื่องจากสาเหตุต่อไปนี้

  • ผู้ส่งอาจไม่ทราบ URL ของเนื้อหา
  • แอปพลิเคชัน Cast ออกแบบมาเพื่อจัดการการตรวจสอบสิทธิ์ ตรรกะทางธุรกิจอื่นๆ หรือการเรียก API โดยตรงบนตัวรับ

ฟังก์ชันนี้จะใช้งานในวิธี PlayerManager setMessageInterceptor() เป็นหลัก ซึ่งจะช่วยให้คุณสกัดกั้นข้อความขาเข้าตามประเภทและแก้ไขข้อความเหล่านั้นได้ก่อนที่จะไปถึงตัวแฮนเดิลข้อความภายในของ SDK ในส่วนนี้ เราจะจัดการกับLOADคำขอโดยจะดำเนินการต่อไปนี้

  • อ่านLOADคำขอที่เข้ามาและcontentIdที่กำหนดเอง
  • GETเรียกใช้ API ของเราเพื่อค้นหาเนื้อหาที่สตรีมได้ตาม contentId
  • แก้ไขLOADคำขอด้วย URL ของสตรีม
  • แก้ไขออบเจ็กต์ MediaInformation เพื่อตั้งค่าพารามิเตอร์ประเภทสตรีม
  • ส่งคำขอไปยัง SDK เพื่อเล่น หรือปฏิเสธคำสั่งหากเราค้นหาสื่อที่ขอไม่ได้

API ตัวอย่างที่ให้มาจะแสดงฮุกของ SDK สำหรับการปรับแต่งงานทั่วไปของตัวรับสัญญาณ ในขณะที่ยังคงอาศัยประสบการณ์การใช้งานที่พร้อมใช้งานเป็นส่วนใหญ่

ตัวอย่าง API

เปิดเบราว์เซอร์ไปที่ https://storage.googleapis.com/cpe-sample-media/content.json แล้วดูแคตตาล็อกวิดีโอตัวอย่างของเรา เนื้อหาประกอบด้วย URL สำหรับภาพโปสเตอร์ในรูปแบบ PNG รวมถึงสตรีมทั้ง DASH และ HLS สตรีม DASH และ HLS จะชี้ไปยังแหล่งที่มาของวิดีโอและเสียงที่แยกมัลติเพล็กซ์แล้วซึ่งจัดเก็บไว้ในคอนเทนเนอร์ MP4 ที่มีการแบ่งส่วน

{
  "bbb": {
    "author": "The Blender Project",
    "description": "Grumpy Bunny is grumpy",
    "poster": "https://[...]/[...]/BigBuckBunny/images/screenshot1.png",
    "stream": {
      "dash": "https://[...]/[...]/BigBuckBunny/BigBuckBunny_master.mpd",
      "hls": "https://[...]/[...]/BigBuckBunny/BigBuckBunny_master.m3u8",
    "title": "Big Buck Bunny"
  },
  "fbb_ad": {
    "author": "Google Inc.",
    "description": "Introducing Chromecast. The easiest way to enjoy [...]",
    "poster": "https://[...]/[...]/ForBiggerBlazes/images/screenshot8.png",
    "stream": {
      "dash": "https://[...]/[...]/ForBiggerBlazes/ForBiggerBlazes.mpd",
      "hls": "https://[...]/[...]/ForBiggerBlazes/ForBiggerBlazes.m3u8",
    "title": "For Bigger Blazes"
  },

  [...]

}

ในขั้นตอนถัดไป เราจะแมปคีย์ของแต่ละรายการ (เช่น bbb, fbb_ad ) กับ URL ของสตรีมหลังจากที่เรียกใช้ตัวรับด้วยคำขอ LOAD

สกัดกั้นคำขอ LOAD

ในขั้นตอนนี้ เราจะสร้างตัวสกัดกั้นการโหลดด้วยฟังก์ชันที่ส่งคำขอ XHR ไปยังไฟล์ JSON ที่โฮสต์ เมื่อได้รับJSONไฟล์แล้ว เราจะแยกวิเคราะห์เนื้อหาและตั้งค่าข้อมูลเมตา ในส่วนต่อไปนี้ เราจะปรับแต่งพารามิเตอร์ MediaInformation เพื่อระบุประเภทเนื้อหา

เพิ่มโค้ดต่อไปนี้ลงในไฟล์ js/receiver.js ก่อนการเรียกใช้ context.start()

function makeRequest (method, url) {
  return new Promise(function (resolve, reject) {
    let xhr = new XMLHttpRequest();
    xhr.open(method, url);
    xhr.onload = function () {
      if (this.status >= 200 && this.status < 300) {
        resolve(JSON.parse(xhr.response));
      } else {
        reject({
          status: this.status,
          statusText: xhr.statusText
        });
      }
    };
    xhr.onerror = function () {
      reject({
        status: this.status,
        statusText: xhr.statusText
      });
    };
    xhr.send();
  });
}

playerManager.setMessageInterceptor(
    cast.framework.messages.MessageType.LOAD,
    request => {
      return new Promise((resolve, reject) => {
        // Fetch content repository by requested contentId
        makeRequest('GET', 'https://storage.googleapis.com/cpe-sample-media/content.json').then(function (data) {
          let item = data[request.media.contentId];
          if(!item) {
            // Content could not be found in repository
            reject();
          } else {
            // Add metadata
            let metadata = new
               cast.framework.messages.GenericMediaMetadata();
            metadata.title = item.title;
            metadata.subtitle = item.author;

            request.media.metadata = metadata;

            // Resolve request
            resolve(request);
          }
        });
      });
    });

ส่วนถัดไปจะอธิบายวิธีกำหนดค่าพร็อพเพอร์ตี้ media ของคำขอโหลดสำหรับเนื้อหา DASH

การใช้เนื้อหา DASH ของ API ตัวอย่าง

ตอนนี้เราได้เตรียมตัวสกัดกั้นการโหลดแล้ว เราจะระบุประเภทเนื้อหาให้กับผู้รับ ข้อมูลนี้จะให้ URL เพลย์ลิสต์หลักและประเภท MIME ของสตรีมแก่ผู้รับ เพิ่มโค้ดต่อไปนี้ลงในไฟล์ js/receiver.js ใน LOAD interceptor's Promise()

...
playerManager.setMessageInterceptor(
    cast.framework.messages.MessageType.LOAD,
    request => {
      return new Promise((resolve, reject) => {
          ...
          } else {
            // Adjusting request to make requested content playable
            request.media.contentUrl = item.stream.dash;
            request.media.contentType = 'application/dash+xml';
            ...
          }
        });
      });
    });

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

การใช้เนื้อหา HLS ของ API ตัวอย่าง

API ตัวอย่างมีทั้งเนื้อหา HLS และ DASH นอกเหนือจากการตั้งค่า contentType เหมือนที่เราทำในขั้นตอนก่อนหน้าแล้ว คำขอโหลดจะต้องมีพร็อพเพอร์ตี้เพิ่มเติมบางอย่างเพื่อใช้ URL ของ HLS ของ API ตัวอย่าง เมื่อกำหนดค่าตัวรับให้เล่นสตรีม HLS ประเภทคอนเทนเนอร์เริ่มต้นที่คาดไว้คือสตรีมการขนส่ง (TS) ด้วยเหตุนี้ ผู้รับจึงจะพยายามเปิดสตรีม MP4 ตัวอย่างในรูปแบบ TS หากมีการแก้ไขเฉพาะพร็อพเพอร์ตี้ contentUrl ในคำขอโหลด คุณควรแก้ไขออบเจ็กต์ MediaInformation ด้วยพร็อพเพอร์ตี้เพิ่มเติมเพื่อให้ตัวรับทราบว่าเนื้อหามีประเภทเป็น MP4 ไม่ใช่ TS เพิ่มโค้ดต่อไปนี้ลงในไฟล์ js/receiver.js ในตัวสกัดกั้นการโหลดเพื่อแก้ไขพร็อพเพอร์ตี้ contentUrl และ contentType นอกจากนี้ ให้เพิ่มพร็อพเพอร์ตี้ HlsSegmentFormat และ HlsVideoSegmentFormat ด้วย

...
playerManager.setMessageInterceptor(
    cast.framework.messages.MessageType.LOAD,
    request => {
      return new Promise((resolve, reject) => {
          ...
          } else {
            // Adjusting request to make requested content playable
            request.media.contentUrl = item.stream.hls;
            request.media.contentType = 'application/x-mpegurl';
            request.media.hlsSegmentFormat = cast.framework.messages.HlsSegmentFormat.FMP4;
            request.media.hlsVideoSegmentFormat = cast.framework.messages.HlsVideoSegmentFormat.FMP4;
            ...
          }
        });
      });
    });

การทดสอบ

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

ไปที่แท็บ "โหลดสื่อ" คราวนี้ให้ลบข้อความในช่อง "URL ของเนื้อหา" ข้างปุ่ม "โหลดตามเนื้อหา" ซึ่งจะบังคับให้แอปพลิเคชันของเราส่งLOADคำขอที่มีเฉพาะcontentIdการอ้างอิงถึงสื่อของเรา

รูปภาพแท็บ &quot;โหลดสื่อ&quot; ของเครื่องมือ Command and Control (CaC)

หากการแก้ไขตัวรับทำงานได้ดี ตัวสกัดกั้นควรจัดการการสร้างออบเจ็กต์ MediaInfo ให้เป็นสิ่งที่ SDK เล่นบนหน้าจอได้

คลิกปุ่ม "โหลดตามเนื้อหา" เพื่อดูว่าสื่อเล่นอย่างถูกต้องหรือไม่ คุณสามารถเปลี่ยน Content ID เป็นรหัสอื่นในไฟล์ content.json ได้

10. การเพิ่มประสิทธิภาพสำหรับจออัจฉริยะ

จออัจฉริยะคืออุปกรณ์ที่มีฟังก์ชันการสัมผัสซึ่งช่วยให้แอปพลิเคชันตัวรับสัญญาณรองรับการควบคุมที่เปิดใช้การสัมผัสได้

ส่วนนี้จะอธิบายวิธีเพิ่มประสิทธิภาพแอปพลิเคชันตัวรับเมื่อเปิดใช้บนจออัจฉริยะ และวิธีปรับแต่งตัวควบคุมเพลเยอร์

การเข้าถึงตัวควบคุม UI

คุณเข้าถึงออบเจ็กต์การควบคุม UI สำหรับจออัจฉริยะได้โดยใช้ cast.framework.ui.Controls.GetInstance() เพิ่มโค้ดต่อไปนี้ลงในไฟล์ js/receiver.js เหนือ context.start()

...

// Optimizing for smart displays
const touchControls = cast.framework.ui.Controls.getInstance();

context.start();

หากไม่ได้ใช้องค์ประกอบ <cast-media-player> คุณจะต้องตั้งค่า touchScreenOptimizedApp ใน CastReceiverOptions ใน Codelab นี้ เราจะใช้องค์ประกอบ <cast-media-player>

context.start({ touchScreenOptimizedApp: true });

ระบบจะกำหนดปุ่มควบคุมเริ่มต้นให้กับแต่ละช่องตาม MetadataType และ MediaStatus.supportedMediaCommands

การควบคุมวิดีโอ

สำหรับ MetadataType.MOVIE, MetadataType.TV_SHOW และ MetadataType.GENERIC ระบบจะแสดงออบเจ็กต์การควบคุม UI สำหรับจออัจฉริยะตามตัวอย่างด้านล่าง

รูปภาพวิดีโอที่กำลังเล่นพร้อมตัวควบคุม UI ที่ซ้อนทับอยู่ด้านบน

  1. --playback-logo-image
  2. MediaMetadata.subtitle
  3. MediaMetadata.title
  4. MediaStatus.currentTime
  5. MediaInformation.duration
  6. ControlsSlot.SLOT_SECONDARY_1: ControlsButton.QUEUE_PREV
  7. ControlsSlot.SLOT_PRIMARY_1: ControlsButton.SEEK_BACKWARD_30
  8. PLAY/PAUSE
  9. ControlsSlot.SLOT_PRIMARY_2: ControlsButton.SEEK_FORWARD_30
  10. ControlsSlot.SLOT_SECONDARY_2: ControlsButton.QUEUE_NEXT

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

สำหรับ MetadataType.MUSIC_TRACK ออบเจ็กต์การควบคุม UI สำหรับจออัจฉริยะจะแสดงดังนี้

รูปภาพเพลงที่กำลังเล่นพร้อมปุ่มควบคุม UI ที่ซ้อนทับอยู่ด้านบน

  1. --playback-logo-image
  2. MusicTrackMediaMetadata.albumName
  3. MusicTrackMediaMetadata.title
  4. MusicTrackMediaMetadata.albumArtist
  5. MusicTrackMediaMetadata.images[0]
  6. MediaStatus.currentTime
  7. MediaInformation.duration
  8. ControlsSlot.SLOT_SECONDARY_1: ControlsButton.NO_BUTTON
  9. ControlsSlot.SLOT_PRIMARY_1: ControlsButton.QUEUE_PREV
  10. PLAY/PAUSE
  11. ControlsSlot.SLOT_PRIMARY_2: ControlsButton.QUEUE_NEXT
  12. ControlsSlot.SLOT_SECONDARY_2: ControlsButton.NO_BUTTON

การอัปเดตคำสั่งสื่อที่รองรับ

ออบเจ็กต์การควบคุม UI ยังกำหนดด้วยว่าจะแสดง ControlsButton หรือไม่โดยอิงตาม MediaStatus.supportedMediaCommands

เมื่อค่าของ supportedMediaCommands เท่ากับ ALL_BASIC_MEDIA เลย์เอาต์การควบคุมเริ่มต้นจะแสดงดังนี้

รูปภาพของตัวควบคุมมีเดียเพลเยอร์: แถบความคืบหน้า ปุ่ม &quot;เล่น&quot; ปุ่ม &quot;ข้ามไปข้างหน้า&quot; และปุ่ม &quot;ข้ามไปข้างหลัง&quot; ที่เปิดใช้

เมื่อค่าของ supportedMediaCommands เท่ากับ ALL_BASIC_MEDIA | QUEUE_PREV | QUEUE_NEXT เลย์เอาต์การควบคุมเริ่มต้นจะแสดงดังนี้

รูปภาพของตัวควบคุมมีเดียเพลเยอร์: แถบความคืบหน้า ปุ่ม &quot;เล่น&quot; ปุ่ม &quot;ข้ามไปข้างหน้า&quot; และ &quot;ข้ามไปข้างหลัง&quot; รวมถึงปุ่ม &quot;จัดคิวเพลงก่อนหน้า&quot; และ &quot;จัดคิวเพลงถัดไป&quot; ที่เปิดใช้

เมื่อค่าของ supportedMediaCommands เท่ากับ PAUSE | QUEUE_PREV | QUEUE_NEXT เลย์เอาต์การควบคุมเริ่มต้นจะแสดงดังนี้

รูปภาพของตัวควบคุมมีเดียเพลเยอร์: แถบความคืบหน้า ปุ่ม &quot;เล่น&quot; และปุ่ม &quot;คิวเพลงก่อนหน้า&quot; และ &quot;คิวเพลงถัดไป&quot; ที่เปิดใช้

เมื่อมีแทร็กข้อความ ปุ่มคำบรรยายแทนเสียงจะแสดงที่ SLOT_1 เสมอ

รูปภาพของตัวควบคุมมีเดียเพลเยอร์: แถบความคืบหน้า ปุ่ม &quot;เล่น&quot; ปุ่ม &quot;ข้ามไปข้างหน้า&quot; และ &quot;ข้ามไปข้างหลัง&quot; ปุ่ม &quot;คิวเพลงก่อนหน้า&quot; และ &quot;คิวเพลงถัดไป&quot; และปุ่ม &quot;คำบรรยายแทนเสียง&quot; ที่เปิดใช้

หากต้องการเปลี่ยนค่าของ supportedMediaCommands แบบไดนามิกหลังจากเริ่มบริบทผู้รับ คุณสามารถเรียกใช้ PlayerManager.setSupportedMediaCommands เพื่อลบล้างค่าได้ นอกจากนี้ คุณยังเพิ่มคำสั่งใหม่ได้โดยใช้ addSupportedMediaCommands หรือนำคำสั่งที่มีอยู่ออกได้โดยใช้ removeSupportedMediaCommands

การปรับแต่งปุ่มควบคุม

คุณปรับแต่งตัวควบคุมได้โดยใช้ PlayerDataBinder เพิ่มโค้ดต่อไปนี้ลงในไฟล์ js/receiver.js ใต้ touchControls เพื่อตั้งค่าช่องแรกของตัวควบคุม

...

// Optimizing for smart displays
const touchControls = cast.framework.ui.Controls.getInstance();
const playerData = new cast.framework.ui.PlayerData();
const playerDataBinder = new cast.framework.ui.PlayerDataBinder(playerData);

playerDataBinder.addEventListener(
  cast.framework.ui.PlayerDataEventType.MEDIA_CHANGED,
  (e) => {
    if (!e.value) return;

    // Clear default buttons and re-assign
    touchControls.clearDefaultSlotAssignments();
    touchControls.assignButton(
      cast.framework.ui.ControlsSlot.SLOT_PRIMARY_1,
      cast.framework.ui.ControlsButton.SEEK_BACKWARD_30
    );
  });

context.start();

11. การติดตั้งใช้งานการเรียกดูสื่อในจออัจฉริยะ

การเรียกดูสื่อเป็นฟีเจอร์ของตัวรับ CAF ที่ช่วยให้ผู้ใช้สำรวจเนื้อหาเพิ่มเติมในอุปกรณ์ระบบสัมผัสได้ หากต้องการใช้ฟีเจอร์นี้ คุณจะต้องใช้ PlayerDataBinder เพื่อตั้งค่า UI ของ BrowseContent จากนั้นคุณจะป้อนข้อมูลใน BrowseItems ตามเนื้อหาที่ต้องการแสดงได้

BrowseContent

ตัวอย่าง UI ของ BrowseContent และพร็อพเพอร์ตี้มีดังนี้

รูปภาพของ UI BrowseContent ที่แสดงภาพปกวิดีโอ 2 รายการและส่วนหนึ่งของวิดีโอที่ 3

  1. BrowseContent.title
  2. BrowseContent.items

สัดส่วนภาพ

ใช้ targetAspectRatio property เพื่อเลือกสัดส่วนภาพที่ดีที่สุดสำหรับชิ้นงานรูปภาพ CAF Receiver SDK รองรับสัดส่วนภาพ 3 แบบ ได้แก่ SQUARE_1_TO_1, PORTRAIT_2_TO_3 และ LANDSCAPE_16_TO_9

BrowseItem

ใช้ BrowseItem เพื่อแสดงชื่อ คำบรรยายแทนเสียง ระยะเวลา และรูปภาพของแต่ละรายการ

รูปภาพของ UI BrowseContent ที่แสดงภาพปกวิดีโอ 2 รายการและส่วนหนึ่งของวิดีโอที่ 3

  1. BrowseItem.image
  2. BrowseItem.duration
  3. BrowseItem.title
  4. BrowseItem.subtitle

ตั้งค่าข้อมูลการเรียกดูสื่อ

คุณระบุรายการเนื้อหาสื่อสำหรับการเรียกดูได้โดยการเรียกใช้ setBrowseContent เพิ่มโค้ดต่อไปนี้ลงในไฟล์ js/receiver.js ใต้ playerDataBinder และในเครื่องมือฟังเหตุการณ์ MEDIA_CHANGED เพื่อตั้งค่ารายการที่เรียกดูโดยมีชื่อว่า "ถัดไป"

// Optimizing for smart displays
const touchControls = cast.framework.ui.Controls.getInstance();
const playerData = new cast.framework.ui.PlayerData();
const playerDataBinder = new cast.framework.ui.PlayerDataBinder(playerData);

...

let browseItems = getBrowseItems();

function getBrowseItems() {
  let browseItems = [];
  makeRequest('GET', 'https://storage.googleapis.com/cpe-sample-media/content.json')
  .then(function (data) {
    for (let key in data) {
      let item = new cast.framework.ui.BrowseItem();
      item.entity = key;
      item.title = data[key].title;
      item.subtitle = data[key].description;
      item.image = new cast.framework.messages.Image(data[key].poster);
      item.imageType = cast.framework.ui.BrowseImageType.MOVIE;
      browseItems.push(item);
    }
  });
  return browseItems;
}

let browseContent = new cast.framework.ui.BrowseContent();
browseContent.title = 'Up Next';
browseContent.items = browseItems;
browseContent.targetAspectRatio = cast.framework.ui.BrowseImageAspectRatio.LANDSCAPE_16_TO_9;

playerDataBinder.addEventListener(
  cast.framework.ui.PlayerDataEventType.MEDIA_CHANGED,
  (e) => {
    if (!e.value) return;

    ....

    // Media browse
    touchControls.setBrowseContent(browseContent);
  });

การคลิกรายการเรียกดูสื่อจะทริกเกอร์LOADอินเทอร์เซ็ปเตอร์ เพิ่มโค้ดต่อไปนี้ลงในอินเทอร์เซ็ปเตอร์ LOAD เพื่อแมป request.media.contentId กับ request.media.entity จากรายการการเรียกดูสื่อ

playerManager.setMessageInterceptor(
    cast.framework.messages.MessageType.LOAD,
    request => {
      ...

      // Map contentId to entity
      if (request.media && request.media.entity) {
        request.media.contentId = request.media.entity;
      }

      return new Promise((resolve, reject) => {
            ...
        });
    });

นอกจากนี้ คุณยังตั้งค่า BrowseContent object เป็น null เพื่อนำ UI การเรียกดูสื่อออกได้ด้วย

12. การแก้ไขข้อบกพร่องของแอปตัวรับสัญญาณ

Cast Receiver SDK เป็นอีกตัวเลือกหนึ่งสำหรับนักพัฒนาแอปในการแก้ไขข้อบกพร่องของแอปตัวรับได้อย่างง่ายดายโดยใช้ CastDebugLogger API และเครื่องมือคำสั่งและการควบคุม (CaC) ที่ใช้ร่วมกันเพื่อบันทึก

การเริ่มต้น

หากต้องการรวม API ให้เพิ่มสคริปต์แหล่งที่มา CastDebugLogger ในไฟล์ index.html ควรประกาศแหล่งที่มาในแท็ก <head> หลังการประกาศ Cast Receiver SDK

<head>
  ...
  <script src="//www.gstatic.com/cast/sdk/libs/caf_receiver/v3/cast_receiver_framework.js"></script>
  <!-- Cast Debug Logger -->
  <script src="//www.gstatic.com/cast/sdk/libs/devtools/debug_layer/caf_receiver_logger.js"></script>
</head>

ใน js/receiver.js ที่ด้านบนของไฟล์และด้านล่าง playerManager ให้เพิ่มโค้ดต่อไปนี้เพื่อเรียกอินสแตนซ์ CastDebugLogger และเปิดใช้เครื่องบันทึก

const context = cast.framework.CastReceiverContext.getInstance();
const playerManager = context.getPlayerManager();

// Debug Logger
const castDebugLogger = cast.debug.CastDebugLogger.getInstance();
const LOG_TAG = 'MyAPP.LOG';

// Enable debug logger and show a 'DEBUG MODE' overlay at top left corner.
context.addEventListener(cast.framework.system.EventType.READY, () => {
  if (!castDebugLogger.debugOverlayElement_) {
      castDebugLogger.setEnabled(true);
  }
});

เมื่อเปิดใช้เครื่องมือบันทึกการแก้ไขข้อบกพร่องแล้ว การซ้อนทับที่แสดง DEBUG MODE จะปรากฏบนเครื่องรับ

รูปภาพวิดีโอที่กำลังเล่นพร้อมข้อความ &quot;DEBUG MODE&quot; ปรากฏบนพื้นหลังสีแดงที่มุมซ้ายบนของเฟรม

บันทึกเหตุการณ์ของเพลเยอร์

การใช้ CastDebugLogger คุณจะบันทึกเหตุการณ์ของผู้เล่นที่ SDK ของตัวรับ CAF เรียกใช้ และใช้ระดับเครื่องบันทึกที่แตกต่างกันเพื่อบันทึกข้อมูลเหตุการณ์ได้อย่างง่ายดาย Config loggerLevelByEvents ใช้ cast.framework.events.EventType และ cast.framework.events.category เพื่อระบุเหตุการณ์ที่จะบันทึก

เพิ่มโค้ดต่อไปนี้ใต้ประกาศ castDebugLogger เพื่อบันทึกเมื่อมีการทริกเกอร์เหตุการณ์ CORE ของเพลเยอร์หรือมีการออกอากาศการเปลี่ยนแปลง mediaStatus

// Debug Logger
const castDebugLogger = cast.debug.CastDebugLogger.getInstance();

// Enable debug logger and show a 'DEBUG MODE' overlay at top left corner.
context.addEventListener(cast.framework.system.EventType.READY, () => {
  if (!castDebugLogger.debugOverlayElement_) {
      castDebugLogger.setEnabled(true);
  }
});

// Set verbosity level for Core events.
castDebugLogger.loggerLevelByEvents = {
  'cast.framework.events.category.CORE': cast.framework.LoggerLevel.INFO,
  'cast.framework.events.EventType.MEDIA_STATUS': cast.framework.LoggerLevel.DEBUG
}

ข้อความในบันทึกและแท็กที่กำหนดเอง

CastDebugLogger API ช่วยให้คุณสร้างข้อความบันทึกที่จะปรากฏในการวางซ้อนการแก้ไขข้อบกพร่องของตัวรับสัญญาณด้วยสีต่างๆ ได้ วิธีการบันทึกต่อไปนี้พร้อมใช้งาน โดยเรียงตามลำดับความสำคัญจากสูงสุดไปต่ำสุด

  • castDebugLogger.error(custom_tag, message);
  • castDebugLogger.warn(custom_tag, message);
  • castDebugLogger.info(custom_tag, message);
  • castDebugLogger.debug(custom_tag, message);

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

หากต้องการแสดงบันทึกใน Action ให้เพิ่มบันทึกลงในอินเทอร์เซ็ปเตอร์ LOAD

playerManager.setMessageInterceptor(
  cast.framework.messages.MessageType.LOAD,
  request => {
    castDebugLogger.info(LOG_TAG, 'Intercepting LOAD request');

    // Map contentId to entity
    if (request.media && request.media.entity) {
      request.media.contentId = request.media.entity;
    }

    return new Promise((resolve, reject) => {
      // Fetch content repository by requested contentId
      makeRequest('GET', 'https://storage.googleapis.com/cpe-sample-media/content.json')
        .then(function (data) {
          let item = data[request.media.contentId];
          if(!item) {
            // Content could not be found in repository
            castDebugLogger.error(LOG_TAG, 'Content not found');
            reject();
          } else {
            // Adjusting request to make requested content playable
            request.media.contentUrl = item.stream.dash;
            request.media.contentType = 'application/dash+xml';
            castDebugLogger.warn(LOG_TAG, 'Playable URL:', request.media.contentUrl);

            // Add metadata
            let metadata = new cast.framework.messages.MovieMediaMetadata();
            metadata.metadataType = cast.framework.messages.MetadataType.MOVIE;
            metadata.title = item.title;
            metadata.subtitle = item.author;

            request.media.metadata = metadata;

            // Resolve request
            resolve(request);
          }
      });
    });
  });

คุณสามารถควบคุมข้อความที่จะปรากฏในการวางซ้อนการแก้ไขข้อบกพร่องได้โดยการตั้งค่าระดับบันทึกใน loggerLevelByTags สำหรับแท็กที่กำหนดเองแต่ละรายการ เช่น การเปิดใช้แท็กที่กำหนดเองที่มีระดับบันทึก cast.framework.LoggerLevel.DEBUG จะแสดงข้อความทั้งหมดที่เพิ่มพร้อมกับข้อความบันทึกข้อผิดพลาด คำเตือน ข้อมูล และการแก้ไขข้อบกพร่อง การเปิดใช้แท็กที่กำหนดเองที่มีระดับ WARNING จะแสดงเฉพาะข้อความบันทึกข้อผิดพลาดและคำเตือน

การกำหนดค่า loggerLevelByTags เป็นค่าที่ไม่บังคับ หากไม่ได้กำหนดค่าแท็กที่กำหนดเองสำหรับระดับ Logger ข้อความบันทึกทั้งหมดจะแสดงในการวางซ้อนการแก้ไขข้อบกพร่อง

เพิ่มโค้ดต่อไปนี้ใต้เครื่องบันทึกเหตุการณ์ CORE

// Set verbosity level for Core events.
castDebugLogger.loggerLevelByEvents = {
  'cast.framework.events.category.CORE': cast.framework.LoggerLevel.INFO,
  'cast.framework.events.EventType.MEDIA_STATUS': cast.framework.LoggerLevel.DEBUG
}

// Set verbosity level for custom tags.
castDebugLogger.loggerLevelByTags = {
    [LOG_TAG]: cast.framework.LoggerLevel.DEBUG,
};

การวางซ้อนการแก้ไขข้อบกพร่อง

Cast Debug Logger มีการวางซ้อนการแก้ไขข้อบกพร่องในตัวรับเพื่อแสดงข้อความบันทึกที่กำหนดเองในอุปกรณ์ที่แคสต์ ใช้ showDebugLogs เพื่อเปิด/ปิดการวางซ้อนการแก้ไขข้อบกพร่อง และ clearDebugLogs เพื่อล้างข้อความบันทึกในการวางซ้อน

เพิ่มโค้ดต่อไปนี้เพื่อแสดงตัวอย่างการซ้อนทับการแก้ไขข้อบกพร่องในตัวรับ

context.addEventListener(cast.framework.system.EventType.READY, () => {
  if (!castDebugLogger.debugOverlayElement_) {
      // Enable debug logger and show a 'DEBUG MODE' overlay at top left corner.
      castDebugLogger.setEnabled(true);

      // Show debug overlay
      castDebugLogger.showDebugLogs(true);

      // Clear log messages on debug overlay
      castDebugLogger.clearDebugLogs();
  }
});

รูปภาพแสดงการวางซ้อนการแก้ไขข้อบกพร่อง รายการข้อความบันทึกการแก้ไขข้อบกพร่องบนพื้นหลังโปร่งแสงที่ด้านบนของเฟรมวิดีโอ

13. ขอแสดงความยินดี

ตอนนี้คุณทราบวิธีสร้างแอปพลิเคชันตัวรับเว็บที่กำหนดเองโดยใช้ Cast Web Receiver SDK แล้ว

ดูรายละเอียดเพิ่มเติมได้ในคู่มือนักพัฒนาซอฟต์แวร์ Web Receiver