หน้านี้มีข้อมูลโค้ดและคำอธิบายฟีเจอร์ที่พร้อมใช้งานสำหรับ แอป Custom Web Receiver
- องค์ประกอบ
cast-media-player
ที่แสดงถึง UI ของโปรแกรมเล่นวิดีโอในตัวที่มาพร้อมกับ Web Receiver - การจัดรูปแบบที่เหมือน CSS ที่กำหนดเองสำหรับองค์ประกอบ
cast-media-player
เพื่อจัดรูปแบบองค์ประกอบ UI ต่างๆ เช่นbackground-image
,splash-image
และfont-family
- องค์ประกอบของสคริปต์สำหรับโหลดเฟรมเวิร์กตัวรับเว็บ
- โค้ด JavaScript เพื่อสกัดกั้นข้อความและจัดการกับเหตุการณ์
- จัดคิวเล่นอัตโนมัติ
- ตัวเลือกเพื่อกำหนดค่าการเล่น
- ตัวเลือกในการตั้งค่าบริบทของตัวรับเว็บ
- ตัวเลือกในการตั้งค่าคำสั่งที่แอป Web Receiver รองรับ
- การเรียกใช้ JavaScript เพื่อเริ่มแอปพลิเคชัน Web Receiver
การกำหนดค่าและตัวเลือกแอปพลิเคชัน
กำหนดค่าแอปพลิเคชัน
CastReceiverContext
เป็นคลาสนอกสุดที่นักพัฒนาซอฟต์แวร์เห็น และจัดการการโหลดไลบรารีพื้นฐานและจัดการการเริ่มต้น Web Receiver SDK SDK
มี API ที่อนุญาตให้นักพัฒนาแอปพลิเคชันกำหนดค่า SDK ผ่าน CastReceiverOptions
การกำหนดค่าเหล่านี้จะได้รับการประเมินครั้งเดียวต่อการเปิดใช้แอปพลิเคชัน และจะส่งไปยัง SDK เมื่อตั้งค่าพารามิเตอร์ที่ไม่บังคับในการเรียกไปยัง start
ตัวอย่างด้านล่างแสดงวิธีลบล้างลักษณะการทำงานเริ่มต้นในการตรวจสอบว่าการเชื่อมต่อของผู้ส่งยังคงเชื่อมต่ออยู่หรือไม่ เมื่อเว็บรีซีฟเวอร์ไม่สามารถสื่อสารกับผู้ส่งเป็นเวลา maxInactivity
วินาที ระบบจะส่งออกเหตุการณ์ SENDER_DISCONNECTED
การกำหนดค่าด้านล่างจะลบล้างระยะหมดเวลานี้ การดำเนินการนี้จะเป็นประโยชน์เมื่อแก้ไขข้อบกพร่องเนื่องจากจะป้องกันแอป Web Receiver ไม่ให้ปิดเซสชันโปรแกรมแก้ไขข้อบกพร่องระยะไกลของ Chrome เมื่อไม่มีผู้ส่งที่เชื่อมต่อไว้ในสถานะ IDLE
const context = cast.framework.CastReceiverContext.getInstance();
const options = new cast.framework.CastReceiverOptions();
options.maxInactivity = 3600; // Development only
context.start(options);
กำหนดค่าโปรแกรมเล่น
เมื่อโหลดเนื้อหา Web Receiver SDK มอบวิธีในการกำหนดค่าตัวแปรการเล่น เช่น ข้อมูล DRM ลองกำหนดค่าอีกครั้ง และตัวแฮนเดิลคำขอโดยใช้ cast.framework.PlaybackConfig
ข้อมูลนี้จะจัดการโดย
PlayerManager
และประเมิน ณ เวลาที่สร้างโปรแกรมเล่น ระบบจะสร้างโปรแกรมเล่นทุกครั้ง
เมื่อมีการส่งโหลดใหม่ไปยัง SDK ของ Web Receiver ระบบจะประเมินการแก้ไข PlaybackConfig
หลังจากสร้างโปรแกรมเล่นวิดีโอในการโหลดเนื้อหาครั้งถัดไป SDK มีวิธีการแก้ไข PlaybackConfig
ดังต่อไปนี้
CastReceiverOptions.playbackConfig
เพื่อลบล้างตัวเลือกการกำหนดค่าเริ่มต้นเมื่อเริ่มต้นCastReceiverContext
PlayerManager.getPlaybackConfig()
เพื่อรับการกำหนดค่าปัจจุบันPlayerManager.setPlaybackConfig()
เพื่อลบล้างการกำหนดค่าปัจจุบัน การตั้งค่านี้จะใช้กับการโหลดครั้งต่อๆ ไปทั้งหมด หรือจนกว่าจะมีการลบล้างอีกครั้งPlayerManager.setMediaPlaybackInfoHandler()
เพื่อใช้การกำหนดค่าเพิ่มเติมเฉพาะสำหรับรายการสื่อที่โหลดจากการกำหนดค่าปัจจุบัน โดยจะมีการเรียกใช้เครื่องจัดการ ก่อนการสร้างโปรแกรมเล่น การเปลี่ยนแปลงที่ทำที่นี่ไม่ใช่แบบถาวรและจะไม่รวมอยู่ในการค้นหาgetPlaybackConfig()
เมื่อรายการสื่อถัดไปโหลดขึ้นมา จะมีการเรียกเครื่องจัดการนี้อีกครั้ง
ตัวอย่างด้านล่างแสดงวิธีตั้งค่า PlaybackConfig
เมื่อเริ่มต้น CastReceiverContext
การกำหนดค่าจะลบล้างคำขอขาออกสำหรับการรับไฟล์ Manifest ตัวแฮนเดิลระบุว่าควรสร้างคำขอควบคุมการเข้าถึง CORS โดยใช้ข้อมูลเข้าสู่ระบบ เช่น คุกกี้หรือส่วนหัวการให้สิทธิ์
const playbackConfig = new cast.framework.PlaybackConfig();
playbackConfig.manifestRequestHandler = requestInfo => {
requestInfo.withCredentials = true;
};
context.start({playbackConfig: playbackConfig});
ตัวอย่างด้านล่างแสดงวิธีลบล้าง PlaybackConfig
โดยใช้ Getter และ setter ที่ให้ไว้ใน PlayerManager
การตั้งค่านี้จะกำหนดค่าโปรแกรมเล่นให้เล่นเนื้อหาต่อหลังจากโหลด 1 ส่วนแล้ว
const playerManager =
cast.framework.CastReceiverContext.getInstance().getPlayerManager();
const playbackConfig = (Object.assign(
new cast.framework.PlaybackConfig(), playerManager.getPlaybackConfig()));
playbackConfig.autoResumeNumberOfSegments = 1;
playerManager.setPlaybackConfig(playbackConfig);
ตัวอย่างด้านล่างแสดงวิธีลบล้าง PlaybackConfig
สำหรับคำขอโหลดที่เจาะจงโดยใช้เครื่องจัดการข้อมูลการเล่นสื่อ ตัวแฮนเดิลจะเรียกใช้เมธอด getLicenseUrlForMedia
ที่แอปพลิเคชันใช้งานเพื่อรับ licenseUrl
จาก contentId
ของรายการปัจจุบัน
playerManager.setMediaPlaybackInfoHandler((loadRequestData, playbackConfig) => {
const mediaInformation = loadRequestData.media;
playbackConfig.licenseUrl = getLicenseUrlForMedia(mediaInformation.contentId);
return playbackConfig;
});
Listener เหตุการณ์
Web Receiver SDK ทำให้แอป Web Receiver ของคุณจัดการเหตุการณ์ของโปรแกรมเล่นได้ Listener เหตุการณ์จะใช้พารามิเตอร์ cast.framework.events.EventType
(หรืออาร์เรย์ของพารามิเตอร์เหล่านี้) ซึ่งระบุเหตุการณ์ที่ควรทริกเกอร์ Listener คุณดูอาร์เรย์ cast.framework.events.EventType
ที่กำหนดค่าไว้ล่วงหน้าซึ่งมีประโยชน์สำหรับการแก้ไขข้อบกพร่องได้ใน cast.framework.events.category
พารามิเตอร์เหตุการณ์ให้ข้อมูลเพิ่มเติมเกี่ยวกับเหตุการณ์
ตัวอย่างเช่น หากต้องการทราบว่าจะมีการเผยแพร่การเปลี่ยนแปลง mediaStatus
เมื่อใด คุณสามารถใช้ตรรกะต่อไปนี้ในการจัดการเหตุการณ์ได้
const playerManager =
cast.framework.CastReceiverContext.getInstance().getPlayerManager();
playerManager.addEventListener(
cast.framework.events.EventType.MEDIA_STATUS, (event) => {
// Write your own event handling code, for example
// using the event.mediaStatus value
});
การดักฟังข้อความ
Web Receiver SDK ทำให้แอป Web Receiver ของคุณสกัดกั้นข้อความและรันโค้ดที่กำหนดเองกับข้อความเหล่านั้นได้ เครื่องมือดักจับข้อความจะใช้พารามิเตอร์ cast.framework.messages.MessageType
ที่ระบุประเภทของข้อความที่ควรสกัดกั้น
เครื่องมือแทรกแซงควรแสดงผลคำขอที่แก้ไขหรือคำสัญญาที่แก้ไขด้วยค่าคำขอที่แก้ไขแล้ว การแสดง null
จะป้องกันไม่ให้เรียกใช้เครื่องจัดการข้อความเริ่มต้น ดูรายละเอียดเพิ่มเติมได้ที่การโหลดสื่อ
ตัวอย่างเช่น หากต้องการเปลี่ยนข้อมูลคำขอโหลด คุณสามารถใช้ตรรกะต่อไปนี้สกัดกั้นและแก้ไขได้
const context = cast.framework.CastReceiverContext.getInstance();
const playerManager = context.getPlayerManager();
playerManager.setMessageInterceptor(
cast.framework.messages.MessageType.LOAD, loadRequestData => {
const error = new cast.framework.messages.ErrorData(
cast.framework.messages.ErrorType.LOAD_FAILED);
if (!loadRequestData.media) {
error.reason = cast.framework.messages.ErrorReason.INVALID_PARAM;
return error;
}
if (!loadRequestData.media.entity) {
return loadRequestData;
}
return thirdparty.fetchAssetAndAuth(loadRequestData.media.entity,
loadRequestData.credentials)
.then(asset => {
if (!asset) {
throw cast.framework.messages.ErrorReason.INVALID_REQUEST;
}
loadRequestData.media.contentUrl = asset.url;
loadRequestData.media.metadata = asset.metadata;
loadRequestData.media.tracks = asset.tracks;
return loadRequestData;
}).catch(reason => {
error.reason = reason; // cast.framework.messages.ErrorReason
return error;
});
});
context.start();
การจัดการข้อผิดพลาด
เมื่อเกิดข้อผิดพลาดในตัวดักจับข้อความ แอป Web Receiver ควรแสดงผล cast.framework.messages.ErrorType
และ cast.framework.messages.ErrorReason
ที่เหมาะสม
playerManager.setMessageInterceptor(
cast.framework.messages.MessageType.LOAD, loadRequestData => {
const error = new cast.framework.messages.ErrorData(
cast.framework.messages.ErrorType.LOAD_CANCELLED);
if (!loadRequestData.media) {
error.reason = cast.framework.messages.ErrorReason.INVALID_PARAM;
return error;
}
...
return fetchAssetAndAuth(loadRequestData.media.entity,
loadRequestData.credentials)
.then(asset => {
...
return loadRequestData;
}).catch(reason => {
error.reason = reason; // cast.framework.messages.ErrorReason
return error;
});
});
การดักจับข้อความเทียบกับ Listener เหตุการณ์
ความแตกต่างหลักๆ ระหว่างการดักรับข้อความและ Listener เหตุการณ์มีดังนี้
- Listener เหตุการณ์ไม่อนุญาตให้คุณแก้ไขข้อมูลคำขอ
- Listener เหตุการณ์จะใช้เพื่อทริกเกอร์การวิเคราะห์หรือฟังก์ชันที่กำหนดเองได้ดีที่สุด
playerManager.addEventListener(cast.framework.events.category.CORE,
event => {
console.log(event);
});
- การสกัดกั้นข้อความช่วยให้คุณฟังข้อความ ดักจับข้อความ และแก้ไขข้อมูลคำขอได้
- การดักจับข้อความเป็นวิธีที่ดีที่สุดในการจัดการกับตรรกะที่กำหนดเองเกี่ยวกับคำขอข้อมูล
กำลังโหลดสื่อ
MediaInformation
มีพร็อพเพอร์ตี้มากมายสำหรับโหลดสื่อในข้อความ
cast.framework.messages.MessageType.LOAD
ซึ่งรวมถึง entity
,
contentUrl
และ contentId
entity
เป็นพร็อพเพอร์ตี้ที่แนะนำสำหรับใช้ในการใช้งานสำหรับทั้งแอปผู้ส่งและผู้รับ พร็อพเพอร์ตี้เป็น URL ของ Deep Link ที่เป็นได้ทั้งเพลย์ลิสต์หรือเนื้อหาสื่อ แอปพลิเคชันคุณควรแยกวิเคราะห์ URL นี้และ ป้อนข้อมูลอย่างน้อย 1 ใน 2 ช่องที่เหลือcontentUrl
สอดคล้องกับ URL ที่เล่นได้ซึ่งโปรแกรมเล่นจะใช้โหลดเนื้อหา เช่น URL นี้อาจชี้ไปยังไฟล์ Manifest ของ DASHcontentId
อาจเป็น URL เนื้อหาที่เล่นได้ (คล้ายกับของพร็อพเพอร์ตี้contentUrl
) หรือตัวระบุที่ไม่ซ้ำกันสำหรับเนื้อหาหรือเพลย์ลิสต์ที่โหลด หากใช้พร็อพเพอร์ตี้นี้เป็นตัวระบุ แอปพลิเคชันควรป้อนข้อมูล URL ที่เล่นได้ในcontentUrl
ขอแนะนำให้ใช้ entity
เพื่อจัดเก็บรหัสจริงหรือพารามิเตอร์คีย์ และใช้ contentUrl
สำหรับ URL ของสื่อ ตัวอย่างจะแสดงในตัวอย่างต่อไปนี้ซึ่งมี entity
อยู่ในคำขอ LOAD
และมีการดึงข้อมูล contentUrl
ที่เล่นได้
playerManager.setMessageInterceptor(
cast.framework.messages.MessageType.LOAD, loadRequestData => {
...
if (!loadRequestData.media.entity) {
// Copy the value from contentId for legacy reasons if needed
loadRequestData.media.entity = loadRequestData.media.contentId;
}
return thirdparty.fetchAssetAndAuth(loadRequestData.media.entity,
loadRequestData.credentials)
.then(asset => {
loadRequestData.media.contentUrl = asset.url;
...
return loadRequestData;
});
});
ความสามารถของอุปกรณ์
เมธอด getDeviceCapabilities
จะให้ข้อมูลอุปกรณ์ในอุปกรณ์แคสต์ที่เชื่อมต่อและอุปกรณ์วิดีโอหรือเสียงที่ต่อเชื่อมอยู่ เมธอด getDeviceCapabilities
จะให้ข้อมูลการสนับสนุนสําหรับ Google Assistant, บลูทูธ รวมถึงอุปกรณ์จอแสดงผลและอุปกรณ์เสียงที่เชื่อมต่อ
วิธีนี้จะส่งคืนออบเจ็กต์ที่คุณค้นหาได้โดยการส่งผ่าน enum ที่ระบุรายการหนึ่งเพื่อรับความสามารถของอุปกรณ์สำหรับ enum นั้น โดย Enum จะกำหนดไว้ใน cast.framework.system.DeviceCapabilities
ตัวอย่างนี้ตรวจสอบว่าอุปกรณ์ Web Receiver เล่น HDR และDolbyVision (DV) ด้วยคีย์ IS_HDR_SUPPORTED
และ IS_DV_SUPPORTED
ตามลำดับได้หรือไม่
const context = cast.framework.CastReceiverContext.getInstance();
context.addEventListener(cast.framework.system.EventType.READY, () => {
const deviceCapabilities = context.getDeviceCapabilities();
if (deviceCapabilities &&
deviceCapabilities[cast.framework.system.DeviceCapabilities.IS_HDR_SUPPORTED]) {
// Write your own event handling code, for example
// using the deviceCapabilities[cast.framework.system.DeviceCapabilities.IS_HDR_SUPPORTED] value
}
if (deviceCapabilities &&
deviceCapabilities[cast.framework.system.DeviceCapabilities.IS_DV_SUPPORTED]) {
// Write your own event handling code, for example
// using the deviceCapabilities[cast.framework.system.DeviceCapabilities.IS_DV_SUPPORTED] value
}
});
context.start();
การจัดการการโต้ตอบของผู้ใช้
ผู้ใช้สามารถโต้ตอบกับแอปพลิเคชัน Web Receiver ผ่านแอปพลิเคชันของผู้ส่ง (เว็บ, Android และ iOS), คำสั่งเสียงในอุปกรณ์ที่พร้อมใช้งาน Assistant, การควบคุมด้วยการสัมผัสบนจออัจฉริยะ และรีโมตคอนโทรลในอุปกรณ์ Android TV Cast SDK มี API มากมายเพื่อให้แอป Web Receiver จัดการการโต้ตอบเหล่านี้ อัปเดต UI ของแอปพลิเคชันผ่านสถานะการดำเนินการของผู้ใช้ และเลือกที่จะส่งการเปลี่ยนแปลงเพื่ออัปเดตบริการแบ็กเอนด์ทั้งหมดก็ได้
คำสั่งสื่อที่รองรับ
สถานะการควบคุม UI จะเป็นไปตาม
MediaStatus.supportedMediaCommands
ตัวควบคุมแบบขยาย ตัวรับสัญญาณและรีโมตคอนโทรลสำหรับผู้ส่ง iOS และ Android ที่ทำงานในอุปกรณ์ระบบสัมผัส และแอปตัวรับสัญญาณในอุปกรณ์ Android TV เมื่อเปิดใช้บิตไวส์ Command
โดยเฉพาะในพร็อพเพอร์ตี้ ระบบจะเปิดใช้ปุ่มที่เกี่ยวข้องกับการดำเนินการดังกล่าว หากไม่ได้ตั้งค่าไว้ ปุ่มนี้จะปิดใช้งาน ค่าเหล่านี้สามารถเปลี่ยนแปลงได้ในเว็บรีซีฟเวอร์โดยทำดังนี้
- การใช้
PlayerManager.setSupportedMediaCommands
เพื่อตั้งค่าCommands
- การเพิ่มคำสั่งใหม่โดยใช้
addSupportedMediaCommands
- การนำคำสั่งที่มีอยู่ออกโดยใช้
removeSupportedMediaCommands
playerManager.setSupportedMediaCommands(cast.framework.messages.Command.SEEK |
cast.framework.messages.Command.PAUSE);
เมื่อผู้รับเตรียม MediaStatus
ที่อัปเดตแล้ว ก็จะรวมการเปลี่ยนแปลงไว้ในพร็อพเพอร์ตี้ supportedMediaCommands
ด้วย เมื่อมีการประกาศสถานะ แอปผู้ส่งที่เชื่อมต่อจะอัปเดตปุ่มใน UI ของตนตามความเหมาะสม
ดูข้อมูลเพิ่มเติมเกี่ยวกับคำสั่งสื่อและอุปกรณ์ระบบสัมผัสที่รองรับได้ที่คู่มือ Accessing UI controls
การจัดการสถานะการดำเนินการของผู้ใช้
เมื่อโต้ตอบกับ UI หรือส่งคำสั่งเสียง ผู้ใช้จะควบคุมการเล่นเนื้อหาและคุณสมบัติที่เกี่ยวข้องกับรายการที่กำลังเล่นได้ SDK จะจัดการคำขอที่ควบคุมการเล่นโดยอัตโนมัติ คำขอที่แก้ไขคุณสมบัติของรายการปัจจุบันที่เล่น เช่น คำสั่ง LIKE
กำหนดให้แอปพลิเคชันของผู้รับจัดการ SDK มีชุด API เพื่อจัดการคำขอประเภทนี้ ในการรองรับคำขอเหล่านี้ คุณต้องดำเนินการต่อไปนี้
- ตั้งค่า
MediaInformation
userActionStates
ด้วยค่ากำหนดของผู้ใช้เมื่อโหลดรายการสื่อ - สกัดกั้นข้อความ
USER_ACTION
รายการและระบุการดำเนินการที่ขอ - อัปเดต
UserActionState
ของMediaInformation
เพื่ออัปเดต UI
ข้อมูลโค้ดต่อไปนี้จะสกัดกั้นคำขอ LOAD
และป้อนข้อมูล MediaInformation
ของ LoadRequestData
ในกรณีนี้ ผู้ใช้ชอบเนื้อหา
ที่กำลังโหลดอยู่
playerManager.setMessageInterceptor(
cast.framework.messages.MessageType.LOAD, (loadRequestData) => {
const userActionLike = new cast.framework.messages.UserActionState(
cast.framework.messages.UserAction.LIKE);
loadRequestData.media.userActionStates = [userActionLike];
return loadRequestData;
});
ข้อมูลโค้ดต่อไปนี้จะสกัดกั้นข้อความ USER_ACTION
และจัดการการเรียกแบ็กเอนด์ด้วยการเปลี่ยนแปลงที่ขอ จากนั้นระบบจะทำการโทรเพื่ออัปเดต UserActionState
บนตัวรับสัญญาณ
playerManager.setMessageInterceptor(cast.framework.messages.MessageType.USER_ACTION,
(userActionRequestData) => {
// Obtain the media information of the current content to associate the action to.
let mediaInfo = playerManager.getMediaInformation();
// If there is no media info return an error and ignore the request.
if (!mediaInfo) {
console.error('Not playing media, user action is not supported');
return new cast.framework.messages.ErrorData(messages.ErrorType.BAD_REQUEST);
}
// Reach out to backend services to store user action modifications. See sample below.
return sendUserAction(userActionRequestData, mediaInfo)
// Upon response from the backend, update the client's UserActionState.
.then(backendResponse => updateUserActionStates(backendResponse))
// If any errors occurred in the backend return them to the cast receiver.
.catch((error) => {
console.error(error);
return error;
});
});
ข้อมูลโค้ดต่อไปนี้จำลองการเรียกบริการแบ็กเอนด์ ฟังก์ชันจะตรวจสอบ UserActionRequestData
เพื่อดูประเภทการเปลี่ยนแปลงที่ผู้ใช้ขอ และจะทำการเรียกเครือข่ายก็ต่อเมื่อแบ็กเอนด์รองรับการดำเนินการนี้เท่านั้น
function sendUserAction(userActionRequestData, mediaInfo) {
return new Promise((resolve, reject) => {
switch (userActionRequestData.userAction) {
// Handle user action changes supported by the backend.
case cast.framework.messages.UserAction.LIKE:
case cast.framework.messages.UserAction.DISLIKE:
case cast.framework.messages.UserAction.FOLLOW:
case cast.framework.messages.UserAction.UNFOLLOW:
case cast.framework.messages.UserAction.FLAG:
case cast.framework.messages.UserAction.SKIP_AD:
let backendResponse = {userActionRequestData: userActionRequestData, mediaInfo: mediaInfo};
setTimeout(() => {resolve(backendResponse)}, 1000);
break;
// Reject all other user action changes.
default:
reject(
new cast.framework.messages.ErrorData(cast.framework.messages.ErrorType.INVALID_REQUEST));
}
});
}
ข้อมูลโค้ดต่อไปนี้ใช้ UserActionRequestData
และเพิ่มหรือนำ UserActionState
ออกจาก MediaInformation
การอัปเดต UserActionState
ของ MediaInformation
จะเปลี่ยนสถานะของปุ่มที่เชื่อมโยงกับการดำเนินการที่ขอ การเปลี่ยนแปลงนี้แสดงอยู่ใน UI ของตัวควบคุมจออัจฉริยะ แอปรีโมตคอนโทรล และ UI ของ Android TV ระบบจะกระจายผ่านข้อความขาออกด้วย MediaStatus
เพื่ออัปเดต UI ของตัวควบคุมแบบขยายสำหรับผู้ส่งใน iOS และ Android
function updateUserActionStates(backendResponse) {
// Unwrap the backend response.
let mediaInfo = backendResponse.mediaInfo;
let userActionRequestData = backendResponse.userActionRequestData;
// If the current item playing has changed, don't update the UserActionState for the current item.
if (playerManager.getMediaInformation().entity !== mediaInfo.entity) {
return;
}
// Check for existing userActionStates in the MediaInformation.
// If none, initialize a new array to populate states with.
let userActionStates = mediaInfo.userActionStates || [];
// Locate the index of the UserActionState that will be updated in the userActionStates array.
let index = userActionStates.findIndex((currUserActionState) => {
return currUserActionState.userAction == userActionRequestData.userAction;
});
if (userActionRequestData.clear) {
// Remove the user action state from the array if cleared.
if (index >= 0) {
userActionStates.splice(index, 1);
}
else {
console.warn("Could not find UserActionState to remove in MediaInformation");
}
} else {
// Add the UserActionState to the array if enabled.
userActionStates.push(
new cast.framework.messages.UserActionState(userActionRequestData.userAction));
}
// Update the UserActionState array and set the new MediaInformation
mediaInfo.userActionStates = userActionStates;
playerManager.setMediaInformation(mediaInfo, true);
return;
}
คำสั่งเสียง
ปัจจุบัน SDK ตัวรับเว็บรองรับคำสั่งสื่อต่อไปนี้สำหรับอุปกรณ์ที่พร้อมใช้งาน Assistant การใช้งานเริ่มต้นของคำสั่งเหล่านี้จะอยู่ใน cast.framework.PlayerManager
คำสั่ง | คำอธิบาย |
---|---|
เล่น | เล่นหรือเล่นต่อจากสถานะหยุดชั่วคราว |
หยุดชั่วคราว | หยุดเนื้อหาที่เล่นอยู่ชั่วคราว |
ก่อนหน้า | ข้ามไปยังรายการสื่อก่อนหน้าในคิวสื่อ |
ถัดไป | ข้ามไปยังรายการสื่อถัดไปในคิวสื่อ |
หยุด | หยุดสื่อที่เล่นอยู่ในปัจจุบัน |
ไม่เล่นซ้ำ | ปิดใช้การทำซ้ำรายการสื่อในคิวเมื่อเล่นรายการสุดท้ายในคิวเสร็จแล้ว |
เล่นซิงเกิลซ้ำ | เล่นสื่อที่เล่นอยู่ซ้ำไปเรื่อยๆ ไม่สิ้นสุด |
เล่นซ้ำทั้งหมด | เล่นรายการทั้งหมดในคิวซ้ำเมื่อมีการเล่นรายการสุดท้ายในคิว |
เล่นซ้ำทั้งหมดและสุ่มเพลง | เมื่อเล่นรายการสุดท้ายในคิวเสร็จแล้ว ให้สับเปลี่ยนคิวและทำซ้ำรายการทั้งหมดในคิว |
สุ่มเพลง | สุ่มรายการสื่อในคิวสื่อ |
เปิด / ปิดคำบรรยาย | เปิด / ปิดคำบรรยายแทนเสียงสำหรับสื่อ ตัวเลือก "เปิดใช้ / ปิดใช้" มีให้ใช้งานตามภาษาด้วย |
กรอไปยังเวลาสัมบูรณ์ | ข้ามไปยังเวลาสัมบูรณ์ที่ระบุ |
กรอไปยังเวลาที่เกี่ยวข้องกับเวลาปัจจุบัน | ข้ามไปข้างหน้าหรือถอยหลังตามระยะเวลาที่ระบุซึ่งสัมพันธ์กับเวลาการเล่นปัจจุบัน |
เล่นอีกครั้ง | รีสตาร์ทสื่อที่เล่นอยู่ในปัจจุบัน หรือเล่นรายการสื่อที่เล่นล่าสุดหากไม่มีรายการใดเล่นอยู่ |
กำหนดอัตราการเล่น | เปลี่ยนแปลงอัตราการเล่นสื่อ ซึ่งควรได้รับการจัดการโดยค่าเริ่มต้น คุณสามารถใช้เครื่องมือดักจับข้อความ SET_PLAYBACK_RATE เพื่อลบล้างคำขออัตราที่เข้ามาใหม่ได้ |
คำสั่งเสียงที่รองรับสำหรับสื่อ
หากต้องการป้องกันไม่ให้คำสั่งเสียงทริกเกอร์คำสั่งสื่อในอุปกรณ์ที่พร้อมใช้งาน Assistant คุณต้องตั้งค่าคำสั่งสื่อที่รองรับซึ่งคุณวางแผนจะรองรับก่อน จากนั้นคุณต้องบังคับใช้คำสั่งเหล่านั้นโดยการเปิดใช้พร็อพเพอร์ตี้ CastReceiverOptions.enforceSupportedCommands
UI ของผู้ส่ง Cast SDK และอุปกรณ์ที่พร้อมใช้งานระบบสัมผัสจะเปลี่ยนไปตามการกำหนดค่าเหล่านี้ หากไม่ได้เปิดใช้การทำเครื่องหมายไว้
คำสั่งเสียงที่เข้ามาใหม่จะทำงาน
เช่น หากอนุญาต PAUSE
จากแอปพลิเคชันผู้ส่งและอุปกรณ์ที่พร้อมใช้งานระบบสัมผัส คุณต้องกำหนดค่าผู้รับให้ตรงกับการตั้งค่าเหล่านั้นด้วย เมื่อกำหนดค่าแล้ว คำสั่งเสียงที่เข้ามาจะหายไปหากไม่อยู่ในรายการคำสั่งที่รองรับ
ในตัวอย่างด้านล่าง เราได้ให้ CastReceiverOptions
เมื่อเริ่มต้น CastReceiverContext
เราเพิ่มการรองรับคำสั่ง PAUSE
และบังคับให้โปรแกรมเล่นรองรับเฉพาะคำสั่งนั้นแล้ว ตอนนี้หากคำสั่งเสียงขอให้ดำเนินการอื่น เช่น SEEK
ก็จะถูกปฏิเสธ ผู้ใช้จะได้รับแจ้งว่า
ยังไม่มีการรองรับคำสั่งนี้
const context = cast.framework.CastReceiverContext.getInstance();
context.start({
enforceSupportedCommands: true,
supportedCommands: cast.framework.messages.Command.PAUSE
});
คุณสามารถใช้ตรรกะแยกกันสำหรับแต่ละคำสั่งที่ต้องการจำกัดได้ นำแฟล็ก enforceSupportedCommands
ออกและสกัดกั้นข้อความขาเข้าสำหรับแต่ละคำสั่งที่ต้องการจำกัดได้ ในส่วนนี้เราจะสกัดกั้นคำขอที่ได้รับจาก SDK เพื่อให้คำสั่ง SEEK
ที่ออกให้กับอุปกรณ์ที่พร้อมใช้งาน Assistant ไม่ทริกเกอร์การค้นหาในแอปพลิเคชันเว็บรีซีฟเวอร์ของคุณ
สำหรับคำสั่งสื่อที่แอปพลิเคชันไม่รองรับ ให้ส่งเหตุผลข้อผิดพลาดที่เหมาะสม เช่น NOT_SUPPORTED
playerManager.setMessageInterceptor(cast.framework.messages.MessageType.SEEK,
seekData => {
// Block seeking if the SEEK supported media command is disabled
if (!(playerManager.getSupportedMediaCommands() & cast.framework.messages.Command.SEEK)) {
let e = new cast.framework.messages.ErrorData(cast.framework.messages.ErrorType
.INVALID_REQUEST);
e.reason = cast.framework.messages.ErrorReason.NOT_SUPPORTED;
return e;
}
return seekData;
});
เบื้องหลังจากกิจกรรมเสียง
หากแพลตฟอร์ม Cast ใช้พื้นหลังของเสียงแอปพลิเคชันเนื่องจากกิจกรรม Assistant เช่น การฟังคำพูดของผู้ใช้หรือพูดตอบ จะมีการส่งข้อความ FocusState
ถึง NOT_IN_FOCUS
ไปยังแอปพลิเคชัน Web Receiver เมื่อกิจกรรมเริ่มขึ้น ระบบจะส่งข้อความอีกฉบับกับ IN_FOCUS
เมื่อกิจกรรมสิ้นสุดลง
คุณอาจต้องการหยุดสื่อชั่วคราวเมื่อ FocusState
มีสถานะเป็น NOT_IN_FOCUS
โดยการสกัดกั้นข้อความประเภท FOCUS_STATE
ทั้งนี้ขึ้นอยู่กับแอปพลิเคชันและสื่อที่เล่นอยู่
เช่น การหยุดเล่นหนังสือเสียงชั่วคราวจะทำให้ผู้ใช้ได้รับประสบการณ์การใช้งานที่ดีหาก Assistant ตอบสนองต่อคำถามของผู้ใช้
playerManager.setMessageInterceptor(cast.framework.messages.MessageType.FOCUS_STATE,
focusStateRequestData => {
// Pause content when the app is out of focus. Resume when focus is restored.
if (focusStateRequestData.state == cast.framework.messages.FocusState.NOT_IN_FOCUS) {
playerManager.pause();
} else {
playerManager.play();
}
return focusStateRequestData;
});
ภาษาของคำบรรยายแทนเสียงที่ระบุเสียง
เมื่อผู้ใช้ไม่ได้ระบุภาษาของคำบรรยายอย่างชัดเจน ภาษาที่ใช้สำหรับคำบรรยายจะเป็นภาษาเดียวกับที่พูดคำสั่ง
ในสถานการณ์เหล่านี้ พารามิเตอร์ isSuggestedLanguage
ของข้อความขาเข้าจะระบุว่าผู้ใช้แนะนำหรือขอภาษาที่เกี่ยวข้องอย่างชัดแจ้งหรือไม่
ตัวอย่างเช่น isSuggestedLanguage
ได้รับการตั้งค่าเป็น true
สำหรับคำสั่ง "Ok Google เปิดคำบรรยาย" เนื่องจากภาษาดังกล่าวอนุมานโดยภาษาที่พูดในคำสั่ง หากมีการร้องขอภาษาอย่างชัดเจน เช่น "Ok Google เปิดคำบรรยายภาษาอังกฤษ" isSuggestedLanguage
จะตั้งค่าเป็นfalse
การแคสต์ข้อมูลเมตาและการแคสต์เสียง
แม้ว่าเว็บรีซีฟเวอร์จะจัดการคำสั่งเสียงโดยค่าเริ่มต้น แต่คุณก็ควรตรวจสอบว่าข้อมูลเมตาสำหรับเนื้อหาครบถ้วนและถูกต้อง การดำเนินการนี้ช่วยให้ Assistant จัดการคำสั่งเสียงได้อย่างเหมาะสมและข้อมูลเมตาแสดงอย่างถูกต้องในอินเทอร์เฟซประเภทใหม่ๆ เช่น แอป Google Home และจออัจฉริยะ เช่น Google Home Hub
การโอนสตรีม
การรักษาสถานะเซสชันเป็นพื้นฐานของการโอนสตรีม ซึ่งผู้ใช้สามารถย้ายสตรีมเสียงและวิดีโอที่มีอยู่ในอุปกรณ์ต่างๆ โดยใช้คำสั่งเสียง, แอป Google Home หรือจออัจฉริยะ สื่อจะหยุดเล่นบนอุปกรณ์หนึ่ง (ต้นทาง) และจะเล่นต่อในอุปกรณ์อื่น (ปลายทาง) อุปกรณ์แคสต์ทุกเครื่องที่มีเฟิร์มแวร์เวอร์ชันล่าสุดจะใช้เป็นแหล่งที่มาหรือปลายทางในการโอนสตรีมได้
โฟลว์เหตุการณ์สำหรับการโอนสตรีมคือ
- ในอุปกรณ์ต้นทาง ให้ทำดังนี้
- สื่อหยุดเล่น
- แอปพลิเคชัน Web Receiver ได้รับคำสั่งเพื่อบันทึกสถานะของสื่อปัจจุบัน
- แอปพลิเคชัน Web Receiver ถูกปิด
- ในอุปกรณ์ปลายทาง ให้ทำดังนี้
- โหลดแอปพลิเคชัน Web Receiver แล้ว
- แอปพลิเคชัน Web Receiver จะได้รับคำสั่งเพื่อคืนค่าสถานะสื่อที่บันทึกไว้
- สื่อเล่นต่อ
องค์ประกอบของสถานะสื่อมีดังนี้
- ตำแหน่งหรือการประทับเวลาที่เจาะจงของเพลง วิดีโอ หรือรายการสื่อ
- อยู่ในคิวที่กว้างกว่า (เช่น เพลย์ลิสต์หรือสถานีวิทยุของศิลปิน)
- ผู้ใช้ที่ตรวจสอบสิทธิ์แล้ว
- สถานะการเล่น (เช่น กำลังเล่นหรือหยุดชั่วคราว)
การเปิดใช้การโอนสตรีม
วิธีใช้การโอนสตรีมสำหรับ Web Receiver
- อัปเดต
supportedMediaCommands
ด้วยคำสั่งSTREAM_TRANSFER
ดังนี้playerManager.addSupportedMediaCommands( cast.framework.messages.Command.STREAM_TRANSFER, true);
- (ไม่บังคับ) ลบล้างตัวตัดข้อความ
SESSION_STATE
และRESUME_SESSION
ตามที่อธิบายไว้ในสถานะการรักษาเซสชัน ลบล้างค่าเหล่านี้เฉพาะเมื่อจำเป็นต้องจัดเก็บข้อมูลที่กำหนดเองให้เป็นส่วนหนึ่งของสแนปชอตเซสชัน ไม่เช่นนั้น การใช้งานเริ่มต้นสำหรับการรักษาสถานะเซสชันจะรองรับการโอนสตรีม
การรักษาสถานะเซสชัน
SDK ของตัวรับเว็บมีการติดตั้งใช้งานเริ่มต้นสำหรับแอปตัวรับเว็บเพื่อคงสถานะของเซสชันด้วยการบันทึกสแนปชอตสถานะสื่อปัจจุบัน แปลงสถานะเป็นคำขอโหลด และทำให้เซสชันกลับมาทำงานอีกครั้งพร้อมด้วยคำขอโหลด
สามารถลบล้างคำขอโหลดที่ Web Receiver สร้างขึ้นได้ในตัวดักจับข้อความ SESSION_STATE
หากจำเป็น หากต้องการเพิ่มข้อมูลที่กำหนดเองลงในคำขอโหลด เราขอแนะนำให้ใส่ข้อมูลเหล่านั้นไว้ใน loadRequestData.customData
playerManager.setMessageInterceptor(
cast.framework.messages.MessageType.SESSION_STATE,
function (sessionState) {
// Override sessionState.loadRequestData if needed.
const newCredentials = updateCredentials_(sessionState.loadRequestData.credentials);
sessionState.loadRequestData.credentials = newCredentials;
// Add custom data if needed.
sessionState.loadRequestData.customData = {
'membership': 'PREMIUM'
};
return sessionState;
});
คุณดึงข้อมูลที่กำหนดเองได้จาก loadRequestData.customData
ในเครื่องมือดักจับข้อความ RESUME_SESSION
let cred_ = null;
let membership_ = null;
playerManager.setMessageInterceptor(
cast.framework.messages.MessageType.RESUME_SESSION,
function (resumeSessionRequest) {
let sessionState = resumeSessionRequest.sessionState;
// Modify sessionState.loadRequestData if needed.
cred_ = sessionState.loadRequestData.credentials;
// Retrieve custom data.
membership_ = sessionState.loadRequestData.customData.membership;
return resumeSessionRequest;
});
การโหลดเนื้อหาล่วงหน้า
ตัวรับเว็บรองรับการโหลดรายการสื่อล่วงหน้าหลังจากรายการเล่นปัจจุบันในคิว
การดำเนินการโหลดล่วงหน้าจะดาวน์โหลดกลุ่มต่างๆ ที่กำลังจะมีขึ้นล่วงหน้า ข้อมูลจำเพาะจะทำกับค่า preloadTime ในออบเจ็กต์ QueueItem (ค่าเริ่มต้นคือ 20 วินาที หากไม่ได้ระบุ) เวลาจะแสดงเป็นวินาที ซึ่งสัมพันธ์กับจุดสิ้นสุดของรายการที่กำลังเล่น ใช้ได้เฉพาะค่าบวกเท่านั้น ตัวอย่างเช่น หากค่าเป็น 10 วินาที รายการนี้จะถูกโหลดล่วงหน้า 10 วินาทีก่อนที่รายการก่อนหน้าจะจบลง หากเวลาในการโหลดล่วงหน้าสูงกว่าเวลาที่เหลืออยู่ในรายการ Currents การโหลดล่วงหน้าจะเกิดขึ้นทันทีที่เป็นไปได้ ดังนั้น หากมีการระบุค่าการโหลดล่วงหน้าที่สูงมากใน identifierItem ค่าหนึ่งอาจมีผลทุกครั้งที่เรากำลังเล่นรายการปัจจุบันอยู่ เราก็โหลดรายการถัดไปไว้ล่วงหน้าแล้ว อย่างไรก็ตาม เราปล่อยการตั้งค่าและตัวเลือกนี้ให้กับนักพัฒนาซอฟต์แวร์เนื่องจากค่านี้อาจส่งผลต่อแบนด์วิดท์และประสิทธิภาพการสตรีมรายการที่เล่นอยู่
โดยค่าเริ่มต้น การโหลดล่วงหน้าจะใช้ได้กับเนื้อหา HLS, DASH และ Smooth Streaming
ไฟล์วิดีโอและไฟล์เสียง MP4 ทั่วไป เช่น MP3 จะไม่มีการโหลดล่วงหน้าเนื่องจากอุปกรณ์แคสต์รองรับองค์ประกอบสื่อเพียงองค์ประกอบเดียวเท่านั้นและไม่สามารถใช้เพื่อโหลดล่วงหน้าขณะที่รายการเนื้อหาที่มีอยู่ยังเล่นอยู่ได้
ข้อความที่กำหนดเอง
การแลกเปลี่ยนข้อความเป็นวิธีการโต้ตอบที่สำคัญสำหรับแอปพลิเคชันตัวรับเว็บ
ผู้ส่งส่งข้อความไปที่ Web Receiver โดยใช้ API ผู้ส่งสำหรับแพลตฟอร์มที่ผู้ส่งใช้อยู่ (Android, iOS, เว็บ) ออบเจ็กต์เหตุการณ์ (ซึ่งเป็นการแสดงข้อความ) ที่ส่งไปยัง Listener เหตุการณ์มีองค์ประกอบข้อมูล (event.data
) ที่ข้อมูลต้องใช้ในพร็อพเพอร์ตี้ของประเภทเหตุการณ์ที่เจาะจง
แอปพลิเคชัน Web Receiver อาจเลือกฟังข้อความบนเนมสเปซที่ระบุ จากการดำเนินการดังกล่าว แอปพลิเคชันตัวรับเว็บจะรองรับโปรโตคอลเนมสเปซดังกล่าว จากนั้นจะขึ้นอยู่กับผู้ส่งที่เชื่อมต่อที่ต้องการสื่อสารในเนมสเปซนั้นเพื่อใช้โปรโตคอลที่เหมาะสม
เนมสเปซทั้งหมดกำหนดโดยสตริงและต้องขึ้นต้นด้วย "urn:x-cast:
" ตามด้วยสตริงใดก็ได้ เช่น "urn:x-cast:com.example.cast.mynamespace
"
นี่คือข้อมูลโค้ดสำหรับตัวรับเว็บเพื่อฟังข้อความที่กำหนดเองจากผู้ส่งที่เชื่อมต่อ
const context = cast.framework.CastReceiverContext.getInstance();
const CUSTOM_CHANNEL = 'urn:x-cast:com.example.cast.mynamespace';
context.addCustomMessageListener(CUSTOM_CHANNEL, function(customEvent) {
// handle customEvent.
});
context.start();
ในทางเดียวกัน แอปพลิเคชัน Web Receiver ก็ช่วยให้ผู้ส่งทราบเกี่ยวกับสถานะของ Web Receiver ได้โดยส่งข้อความถึงผู้ส่งที่เชื่อมต่อ แอปพลิเคชัน Web Receiver ส่งข้อความได้โดยใช้ sendCustomMessage(namespace, senderId, message)
บน CastReceiverContext
ตัวรับเว็บสามารถส่งข้อความถึงผู้ส่งแต่ละรายได้ ไม่ว่าจะเป็นการตอบกลับข้อความที่ได้รับหรือเนื่องจากการเปลี่ยนแปลงสถานะของแอปพลิเคชัน นอกเหนือจากการรับส่งข้อความแบบจุดต่อจุด (จำกัดที่ 64 KB) ตัวรับเว็บยังอาจประกาศข้อความไปยังผู้ส่งที่เชื่อมต่อทั้งหมดได้ด้วย
แคสต์สำหรับอุปกรณ์เสียง
ดูคู่มือ Google Cast สำหรับอุปกรณ์เสียงเพื่อรับการสนับสนุนเกี่ยวกับการเล่นเฉพาะเสียง
Android TV
ส่วนนี้จะกล่าวถึงวิธีที่ Google Web Receiver ใช้ข้อมูลที่คุณป้อนในการเล่น รวมถึงความเข้ากันได้ของ Android TV
การผสานรวมแอปพลิเคชันของคุณกับรีโมตคอนโทรล
Google Web Receiver ที่ทำงานในอุปกรณ์ Android TV จะแปลอินพุตจากอินพุตตัวควบคุมของอุปกรณ์ (เช่น รีโมตคอนโทรลแบบมือถือ) เป็นข้อความการเล่นสื่อที่กำหนดไว้สำหรับเนมสเปซ urn:x-cast:com.google.cast.media
ตามที่อธิบายไว้ในข้อความการเล่นสื่อ แอปพลิเคชันของคุณต้องรองรับข้อความเหล่านี้เพื่อควบคุมการเล่นสื่อของแอปพลิเคชันเพื่ออนุญาตการควบคุมการเล่นขั้นพื้นฐานจากอินพุตควบคุมของ Android TV
หลักเกณฑ์สำหรับความเข้ากันได้กับ Android TV
คำแนะนำและข้อผิดพลาดทั่วไปที่ควรหลีกเลี่ยงเพื่อให้แน่ใจว่าแอปพลิเคชันของคุณเข้ากันได้กับ Android TV มีดังนี้
- โปรดทราบว่าสตริง User Agent มีทั้ง "Android" และ "CrKey" บางเว็บไซต์อาจเปลี่ยนเส้นทางไปยังเว็บไซต์สำหรับอุปกรณ์เคลื่อนที่เท่านั้นเนื่องจากตรวจพบป้ายกำกับ "Android" อย่าคิดเอาเองว่า "Android" ในสตริง User Agent จะระบุผู้ใช้อุปกรณ์เคลื่อนที่เสมอ
- สแต็กสื่อของ Android อาจใช้ GZIP แบบโปร่งใสสำหรับการดึงข้อมูล ตรวจสอบว่าข้อมูลสื่อของคุณตอบสนองต่อ
Accept-Encoding: gzip
ได้ - ระบบอาจทริกเกอร์เหตุการณ์สื่อ HTML5 ของ Android TV ในเวลาที่แตกต่างจาก Chromecast ซึ่งอาจเปิดเผยปัญหาที่ซ่อนอยู่ใน Chromecast
- เมื่ออัปเดตสื่อ ให้ใช้เหตุการณ์ที่เกี่ยวข้องกับสื่อที่องค์ประกอบ
<audio>/<video>
เริ่มทำงาน เช่นtimeupdate
,pause
และwaiting
หลีกเลี่ยงการใช้เหตุการณ์ที่เกี่ยวข้องกับเครือข่าย เช่นprogress
,suspend
และstalled
เนื่องจากเหตุการณ์เหล่านี้มักอิงตามแพลตฟอร์ม ดูข้อมูลเพิ่มเติมเกี่ยวกับการจัดการเหตุการณ์สื่อในตัวรับได้ที่เหตุการณ์สื่อ - เมื่อกำหนดค่าใบรับรอง HTTPS ของเว็บไซต์ผู้รับ อย่าลืมรวมใบรับรอง CA ระดับกลางด้วย โปรดดูหน้าทดสอบ Qualsys SSL เพื่อตรวจสอบความถูกต้อง หากเส้นทางการรับรองที่เชื่อถือได้สำหรับเว็บไซต์ของคุณมีใบรับรองของ CA ที่มีป้ายกำกับว่า "extra Download" เส้นทางดังกล่าวก็จะไม่สามารถโหลดบนแพลตฟอร์มที่ใช้ Android ได้
- แม้ว่า Chromecast จะแสดงหน้าตัวรับสัญญาณบนระนาบกราฟิก 720p แต่แพลตฟอร์มแคสต์อื่นๆ รวมถึง Android TV อาจแสดงหน้าที่มีความละเอียดสูงสุด 1080p ตรวจสอบให้แน่ใจว่าหน้าตัวรับสัญญาณปรับขนาดได้อย่างดีที่ความละเอียดต่างๆ