หน้านี้มีตัวอย่างโค้ดและคำอธิบายฟีเจอร์ที่ใช้ได้กับ แอปตัวรับสัญญาณเว็บแบบกำหนดเอง
- องค์ประกอบ
cast-media-player
ที่แสดงถึง UI ของเพลเยอร์ในตัว ที่มาพร้อมกับ Web Receiver - การจัดรูปแบบที่กำหนดเองคล้าย CSS สำหรับองค์ประกอบ
cast-media-player
เพื่อจัดรูปแบบองค์ประกอบ UI ต่างๆ เช่นbackground-image
,splash-image
และfont-family
- องค์ประกอบสคริปต์เพื่อโหลดเฟรมเวิร์ก Web Receiver
- โค้ด JavaScript เพื่อสกัดกั้นข้อความและจัดการเหตุการณ์
- คิวสำหรับการเล่นอัตโนมัติ
- ตัวเลือกในการกำหนดค่าการเล่น
- ตัวเลือกในการตั้งค่าบริบทของ Web Receiver
- ตัวเลือกในการตั้งค่าคำสั่งที่แอป Web Receiver รองรับ
- การเรียก JavaScript เพื่อเริ่มแอปพลิเคชัน Web Receiver
การกำหนดค่าและตัวเลือกของแอปพลิเคชัน
กำหนดค่าแอปพลิเคชัน
CastReceiverContext
เป็นคลาสที่อยู่นอกสุดซึ่งแสดงต่อนักพัฒนาซอฟต์แวร์ และจะจัดการการโหลด
ไลบรารีพื้นฐานและจัดการการเริ่มต้น SDK ของ Web Receiver SDK
มี API ที่ช่วยให้นักพัฒนาแอปพลิเคชันกำหนดค่า SDK ผ่าน
CastReceiverOptions
ได้
ระบบจะประเมินการกำหนดค่าเหล่านี้ 1 ครั้งต่อการเปิดแอปพลิเคชัน และจะส่งไปยัง
SDK เมื่อตั้งค่าพารามิเตอร์ที่ไม่บังคับในการเรียกใช้
start
ตัวอย่างด้านล่างแสดงวิธีลบล้างลักษณะการทำงานเริ่มต้นสำหรับการตรวจหาว่าการเชื่อมต่อผู้ส่งยังคงเชื่อมต่ออยู่หรือไม่ เมื่อ Web Receiver สื่อสารกับผู้ส่งไม่ได้เป็นเวลา maxInactivity
วินาที ระบบจะส่งเหตุการณ์ SENDER_DISCONNECTED
การกำหนดค่าด้านล่าง
จะลบล้างการหมดเวลานี้ ซึ่งจะมีประโยชน์เมื่อแก้ไขข้อบกพร่องเนื่องจากจะป้องกันไม่ให้
แอป Web Receiver ปิดเซสชัน Chrome Remote Debugger เมื่อไม่มี
ผู้ส่งที่เชื่อมต่อในสถานะ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
และจะได้รับการประเมินเมื่อสร้างผู้เล่น ระบบจะสร้างเพลเยอร์
ทุกครั้งที่มีการส่งการโหลดใหม่ไปยัง Web Receiver SDK การแก้ไข
PlaybackConfig
หลังจากสร้างเพลเยอร์แล้วจะได้รับการประเมินในการโหลดเนื้อหาครั้งถัดไป SDK มีเมธอดต่อไปนี้สำหรับการแก้ไข
PlaybackConfig
CastReceiverOptions.playbackConfig
เพื่อลบล้างตัวเลือกการกำหนดค่าเริ่มต้นเมื่อเริ่มต้นCastReceiverContext
PlayerManager.getPlaybackConfig()
เพื่อรับการกำหนดค่าปัจจุบันPlayerManager.setPlaybackConfig()
เพื่อลบล้างการกำหนดค่าปัจจุบัน การตั้งค่านี้จะมีผลกับการโหลดครั้งต่อๆ ไปทั้งหมด หรือจนกว่าจะมีการลบล้างอีกครั้งPlayerManager.setMediaPlaybackInfoHandler()
เพื่อใช้การกำหนดค่าเพิ่มเติมเฉพาะกับรายการสื่อที่โหลดอยู่ นอกเหนือจากการกำหนดค่าปัจจุบัน ระบบจะเรียกตัวแฮนเดิลเลอร์ก่อนสร้างเพลเยอร์ การเปลี่ยนแปลงที่ทำที่นี่จะไม่ถาวรและจะไม่รวมอยู่ในการค้นหาไปยังgetPlaybackConfig()
เมื่อโหลดรายการสื่อถัดไป ระบบจะเรียกใช้แฮนเดิลนี้ อีกครั้ง
ตัวอย่างด้านล่างแสดงวิธีตั้งค่า PlaybackConfig
เมื่อเริ่มต้น CastReceiverContext
การกำหนดค่าจะลบล้างคำขอขาออกสำหรับ
การขอไฟล์ Manifest ตัวแฮนเดิลระบุว่าควรส่งคำขอ Access-Control ของ 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 จัดการเหตุการณ์ของเพลเยอร์ได้ ตัวตรวจหาเหตุการณ์จะใช้พารามิเตอร์
cast.framework.events.EventType
(หรืออาร์เรย์ของพารามิเตอร์เหล่านี้) ที่ระบุเหตุการณ์ที่ควรทริกเกอร์ตัวตรวจหา อาร์เรย์ที่กำหนดค่าไว้ล่วงหน้าของ
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
ที่ระบุประเภทข้อความที่ควรสกัดกั้น
อินเทอร์เซ็ปเตอร์ควรแสดงผลคำขอที่แก้ไขแล้วหรือ Promise ที่แก้ไขแล้ว
พร้อมค่าคำขอที่แก้ไขแล้ว การส่งคืน 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();
การจัดการข้อผิดพลาด
เมื่อเกิดข้อผิดพลาดในตัวสกัดกั้นข้อความ แอปตัวรับสัญญาณเว็บควรแสดง
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 เหตุการณ์เพื่อทริกเกอร์ Analytics หรือฟังก์ชันที่กำหนดเอง
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
บิตไวส์ที่เฉพาะเจาะจงในพร็อพเพอร์ตี้ ระบบจะเปิดใช้ปุ่มที่เกี่ยวข้องกับการดำเนินการนั้น หากไม่ได้ตั้งค่าไว้ ปุ่มจะถูกปิดใช้
คุณเปลี่ยนแปลงค่าเหล่านี้ได้ใน Web Receiver โดยทำดังนี้
- การใช้
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
และพิจารณาการดำเนินการที่ขอ - อัปเดต
MediaInformation
UserActionState
เพื่ออัปเดต 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;
}
คำสั่งเสียง
ปัจจุบัน Web Receiver 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
ไม่ทริกเกอร์การค้นหาในแอปพลิเคชัน Web Receiver
สำหรับคำสั่งสื่อที่แอปพลิเคชันไม่รองรับ ให้แสดงเหตุผลข้อผิดพลาดที่เหมาะสม เช่น
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
ข้อมูลเมตาและการพากย์เสียง
แม้ว่า Web Receiver จะจัดการคำสั่งเสียงโดยค่าเริ่มต้น แต่คุณควรตรวจสอบว่าข้อมูลเมตาของเนื้อหานั้นสมบูรณ์และถูกต้อง วิธีนี้ช่วยให้ Assistant จัดการคำสั่งเสียงได้อย่างถูกต้องและข้อมูลเมตาแสดงอย่างถูกต้องในอินเทอร์เฟซประเภทใหม่ๆ เช่น แอป Google Home และจออัจฉริยะอย่าง Google Home Hub
การถ่ายโอนสตรีม
การรักษาสถานะเซสชันเป็นพื้นฐานของการโอนสตรีม ซึ่งผู้ใช้สามารถย้ายสตรีมเสียงและวิดีโอที่มีอยู่ไปยังอุปกรณ์ต่างๆ ได้โดยใช้คำสั่งเสียง, แอป Google Home หรือจออัจฉริยะ สื่อจะหยุดเล่นในอุปกรณ์หนึ่ง (แหล่งที่มา) และเล่นต่อในอีกอุปกรณ์หนึ่ง (ปลายทาง) อุปกรณ์ Cast ที่มีเฟิร์มแวร์ล่าสุดสามารถใช้เป็นแหล่งที่มาหรือปลายทางในการ โอนสตรีมได้
ขั้นตอนการโอนสตรีมมีดังนี้
- ในอุปกรณ์ต้นทาง ให้ทำดังนี้
- สื่อหยุดเล่น
- แอปพลิเคชัน 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
ก็ได้ตามที่อธิบายไว้ในการรักษาสถานะเซสชัน คุณจะลบล้างได้ก็ต่อเมื่อต้องจัดเก็บข้อมูลที่กำหนดเองเป็นส่วนหนึ่งของสแนปชอตเซสชันเท่านั้น ไม่เช่นนั้น การใช้งานเริ่มต้น สำหรับการรักษาสถานะเซสชันจะรองรับการโอนสตรีม
การคงสถานะเซสชันไว้
Web Receiver 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;
});
การโหลดเนื้อหาล่วงหน้า
Web Receiver รองรับการโหลดรายการสื่อล่วงหน้าหลังจากรายการที่กำลังเล่น อยู่ในคิว
การดำเนินการโหลดล่วงหน้าจะดาวน์โหลดล่วงหน้าหลายส่วนของ รายการที่กำลังจะมา การระบุจะทำในค่า preloadTime ในออบเจ็กต์ QueueItem (ค่าเริ่มต้นคือ 20 วินาทีหากไม่ได้ระบุ) เวลาจะแสดงเป็นวินาที โดยอิงตามตอนจบของรายการที่กำลังเล่น ใช้ได้เฉพาะค่าบวกเท่านั้น เช่น หากค่าเป็น 10 วินาที ระบบจะโหลดรายการนี้ล่วงหน้า 10 วินาทีก่อนที่รายการก่อนหน้าจะเล่นจบ หากเวลาในการโหลดล่วงหน้าสูงกว่า เวลาที่เหลือใน currentItem ระบบจะโหลดล่วงหน้าทันที ที่ทำได้ ดังนั้นหากระบุค่าการโหลดล่วงหน้าขนาดใหญ่มากใน queueItem คุณจะได้รับผลลัพธ์ที่ว่าเมื่อใดก็ตามที่เราเล่นรายการปัจจุบัน เราจะโหลดรายการถัดไปไว้ล่วงหน้าแล้ว อย่างไรก็ตาม เราจะปล่อยให้การตั้งค่าและการเลือก นี้เป็นหน้าที่ของนักพัฒนาแอป เนื่องจากค่านี้อาจส่งผลต่อแบนด์วิดท์และประสิทธิภาพการสตรีม ของรายการที่กำลังเล่นอยู่
การโหลดล่วงหน้าจะใช้ได้กับเนื้อหา HLS, DASH และ Smooth Streaming โดยค่าเริ่มต้น
ระบบจะไม่โหลดไฟล์วิดีโอและเสียง MP4 ปกติ เช่น MP3 ไว้ล่วงหน้า เนื่องจากอุปกรณ์ Cast รองรับองค์ประกอบสื่อเพียงรายการเดียว และไม่สามารถใช้เพื่อโหลดล่วงหน้าในขณะที่รายการเนื้อหาที่มีอยู่ยังเล่นอยู่
ข้อความที่กำหนดเอง
การแลกเปลี่ยนข้อความคือวิธีการโต้ตอบหลักสำหรับแอปพลิเคชัน Web Receiver
ผู้ส่งจะส่งข้อความไปยัง Web Receiver โดยใช้ Sender API สำหรับ
แพลตฟอร์มที่ผู้ส่งใช้งาน (Android, iOS, เว็บ) ออบเจ็กต์เหตุการณ์ (ซึ่งเป็นรูปแบบของข้อความ) ที่ส่งไปยังเครื่องมือฟังเหตุการณ์มีองค์ประกอบข้อมูล (event.data
) ซึ่งข้อมูลจะใช้คุณสมบัติของประเภทเหตุการณ์ที่เฉพาะเจาะจง
แอปพลิเคชัน Web Receiver อาจเลือกรับฟังข้อความในเนมสเปซที่ระบุ การดำเนินการดังกล่าวทำให้แอปพลิเคชัน Web Receiver รองรับโปรโตคอลเนมสเปซนั้น จากนั้นผู้ส่งที่เชื่อมต่อซึ่งต้องการสื่อสารในเนมสเปซนั้นจะต้องใช้โปรโตคอลที่เหมาะสม
เนมสเปซทั้งหมดกำหนดโดยสตริงและต้องขึ้นต้นด้วย "urn:x-cast:
"
ตามด้วยสตริงใดก็ได้ เช่น "urn:x-cast:com.example.cast.mynamespace
"
ต่อไปนี้คือข้อมูลโค้ดสำหรับ Web Receiver เพื่อรับฟังข้อความที่กำหนดเองจากผู้ส่งที่เชื่อมต่อ
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
Web Receiver สามารถส่งข้อความไปยังผู้ส่งแต่ละรายได้ ไม่ว่าจะตอบกลับ
ข้อความที่ได้รับหรือเนื่องจากการเปลี่ยนแปลงสถานะแอปพลิเคชัน นอกเหนือจากการรับส่งข้อความแบบจุดต่อจุด (จำกัดขนาด 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 จะบ่งบอกถึงผู้ใช้ อุปกรณ์เคลื่อนที่เสมอ
- Media Stack ของ Android อาจใช้ GZIP แบบโปร่งใสในการดึงข้อมูล ตรวจสอบว่าข้อมูลสื่อตอบสนองต่อ
Accept-Encoding: gzip
ได้ - เหตุการณ์สื่อ HTML5 ของ Android TV อาจทริกเกอร์ในเวลาที่ต่างจาก Chromecast ซึ่งอาจเผยให้เห็นปัญหาที่ซ่อนอยู่ใน Chromecast
- เมื่ออัปเดตสื่อ ให้ใช้เหตุการณ์ที่เกี่ยวข้องกับสื่อซึ่งทริกเกอร์โดยองค์ประกอบ
<audio>/<video>
เช่นtimeupdate
,pause
และwaiting
หลีกเลี่ยงการใช้เหตุการณ์ที่เกี่ยวข้องกับเครือข่าย เช่นprogress
,suspend
และstalled
เนื่องจากเหตุการณ์เหล่านี้มักจะขึ้นอยู่กับแพลตฟอร์ม ดูข้อมูลเพิ่มเติมเกี่ยวกับการจัดการเหตุการณ์สื่อในตัวรับได้ที่เหตุการณ์สื่อ - เมื่อกำหนดค่าใบรับรอง HTTPS ของเว็บไซต์ผู้รับ ให้ตรวจสอบว่าได้รวม ใบรับรอง CA ระดับกลางแล้ว ดูหน้าทดสอบ SSL ของ Qualsys เพื่อ ตรวจสอบว่าเส้นทางการรับรองที่เชื่อถือได้สำหรับเว็บไซต์ของคุณมีใบรับรอง CA ที่มีป้ายกำกับว่า "ดาวน์โหลดเพิ่มเติม" หรือไม่ หากมี ระบบอาจโหลดไม่ได้ในแพลตฟอร์มที่ใช้ Android
- ขณะที่ Chromecast แสดงหน้าผู้รับบนระนาบกราฟิก 720p แพลตฟอร์ม Cast อื่นๆ รวมถึง Android TV อาจแสดงหน้าเว็บได้สูงสุด 1080p ตรวจสอบว่าหน้าตัวรับสัญญาณปรับขนาดได้อย่างเหมาะสมที่ความละเอียดต่างๆ