이 페이지에는 커스텀 웹 수신기 앱에서 사용할 수 있는 기능에 관한 코드 스니펫과 설명이 포함되어 있습니다.
- 웹 수신기와 함께 제공된 내장 플레이어 UI를 나타내는
cast-media-player
요소입니다. background-image
,splash-image
,font-family
와 같은 다양한 UI 요소의 스타일을 지정할 수 있도록cast-media-player
요소의 맞춤 CSS와 유사한 스타일 지정.- 웹 수신기 프레임워크를 로드하는 스크립트 요소.
- 메시지를 가로채고 이벤트를 처리하는 자바스크립트 코드
- 자동재생 대기열
- 재생 구성 옵션입니다.
- 웹 수신자 컨텍스트를 설정하는 옵션
- 웹 수신기 앱에서 지원하는 명령어를 설정하는 옵션입니다.
- 웹 수신기 애플리케이션을 시작하기 위한 자바스크립트 호출입니다.
애플리케이션 구성 및 옵션
CastReceiverContext
는 개발자에게 노출되는 가장 바깥쪽 클래스이며 기본 라이브러리의 로드를 관리하고 웹 수신기 SDK의 초기화를 처리합니다.
Web Receiver API에서 발신자가 연결 해제되었음을 감지하면 SENDER_DISCONNECTED
이벤트를 발생시킵니다. 웹 수신기가 maxInactivity
초에 설명된 대로 발신자와 통신할 수 없으면 SENDER_DISCONNECTED
이벤트도 발생합니다. 개발 중에는 Chrome 원격 디버그로 앱을 디버깅할 때 웹 수신기 앱이 닫히지 않도록 maxInactivity
를 높은 값으로 설정하는 것이 좋습니다.
const context = cast.framework.CastReceiverContext.getInstance();
const options = new cast.framework.CastReceiverOptions();
options.maxInactivity = 3600; //Development only
context.start(options);
하지만 게시된 웹 수신기 애플리케이션의 경우 maxInactivity
를 설정하지 않고 기본값을 사용하는 것이 더 좋습니다. 웹 수신자 옵션은 애플리케이션에서 한 번만 설정됩니다.
다른 구성은 cast.framework.PlaybackConfig
입니다.
다음과 같이 설정할 수 있습니다.
const playbackConfig = new cast.framework.PlaybackConfig();
playbackConfig.manifestRequestHandler = requestInfo => {
requestInfo.withCredentials = true;
};
context.start({playbackConfig: playbackConfig});
이 구성은 각 콘텐츠 재생에 영향을 미치며 기본적으로 재정의 동작을 제공합니다. 개발자가 재정의할 수 있는 동작 목록은 cast.framework.PlaybackConfig
의 정의를 참고하세요. 콘텐츠 간에 구성을 변경하려면 PlayerManager
를 사용하여 현재 playbackConfig
를 가져오고 재정의를 수정 또는 추가하고 playbackConfig
을 다음과 같이 재설정하면 됩니다.
const playerManager =
cast.framework.CastReceiverContext.getInstance().getPlayerManager();
const playbackConfig = (Object.assign(
new cast.framework.PlaybackConfig(), playerManager.getPlaybackConfig()));
playbackConfig.autoResumeNumberOfSegments = 1;
playerManager.setPlaybackConfig(playbackConfig);
PlaybackConfig
가 재정의되지 않은 경우 getPlaybackConfig()
는 null 객체를 반환합니다. 또한 PlaybackConfig that
의 모든 속성이 undefined
입니다.
기본값이 사용됩니다.
이벤트 리스너
웹 수신기 SDK를 사용하면 웹 수신기 앱이 플레이어 이벤트를 처리할 수 있습니다. 이벤트 리스너는 리스너를 트리거해야 하는 이벤트를 지정하는 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
});
메시지 가로채기
웹 수신기 SDK를 사용하면 웹 수신기 앱이 메시지를 가로채고 이러한 메시지에 커스텀 코드를 실행할 수 있습니다. 메시지 인터셉터는 가로채야 하는 메시지 유형을 지정하는 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();
오류 처리
메시지 가로채기에서 오류가 발생하면 웹 수신기 앱이 적절한 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;
});
});
메시지 가로채기 및 이벤트 리스너
메시지 가로채기와 이벤트 리스너 간의 주요 차이점은 다음과 같습니다.
- 이벤트 리스너로는 요청 데이터를 수정할 수 없습니다.
- 이벤트 리스너는 분석 또는 맞춤 함수를 트리거하는 데 가장 적합합니다.
playerManager.addEventListener(cast.framework.events.category.CORE,
event => {
console.log(event);
});
- 메시지 가로채기를 사용하면 메시지를 수신 대기하고 가로채고 요청 데이터 자체를 수정할 수 있습니다.
- 메시지 가로채기는 요청 데이터와 관련하여 맞춤 로직을 처리하는 데 가장 적합합니다.
미디어 로드
MediaInformation
는 entity
, contentUrl
, contentId
등 cast.framework.messages.MessageType.LOAD
메시지에 미디어를 로드하는 다양한 속성을 제공합니다.
entity
는 발신 앱과 수신자 앱 구현 시 사용할 수 있는 추천 속성입니다. 이 속성은 재생목록이나 특정 미디어 콘텐츠일 수 있는 딥 링크 URL입니다.
contentUrl
는 재생 가능한 URL용으로 설계되었으며 사용할 수 있게 되면 사용할 수 있습니다.
값이 미디어 URL, 실제 ID 또는 맞춤 조회용 키 매개변수인지 명확하지 않아 contentId
가 지원 중단되었습니다.
entity
를 사용하여 실제 ID 또는 키 매개변수를 저장하고 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
메서드는 연결된 Cast 기기 및 연결된 동영상/오디오 기기의 기기 정보를 제공합니다. getDeviceCapabilities
메서드는 Google 어시스턴트, 블루투스, 연결된 디스플레이 및 오디오 기기의 지원 정보를 제공합니다.
이 메서드는 지정된 enum 중 하나를 전달하여 enum의 기기 기능을 가져와 쿼리할 수 있는 객체를 반환합니다. enum은 cast.framework.system.DeviceCapabilities
에 정의되어 있습니다.
이 예에서는 웹 수신기 기기가 각각 IS_HDR_SUPPORTED
및 IS_DV_SUPPORTED
키를 사용하여 HDR 및 DolbyVision (DV)을 재생할 수 있는지 확인합니다.
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();
사용자 상호작용 처리
사용자는 발신기 애플리케이션 (웹, Android, iOS), 어시스턴트 지원 기기의 음성 명령, 스마트 디스플레이의 터치 컨트롤, Android TV 기기의 리모컨을 통해 웹 수신기 애플리케이션과 상호작용할 수 있습니다. Cast SDK는 웹 수신기 앱이 이러한 상호작용을 처리하고 사용자 작업 상태를 통해 애플리케이션 UI를 업데이트하며 원하는 경우 변경사항을 전송하여 백엔드 서비스를 업데이트할 수 있는 다양한 API를 제공합니다.
지원되는 미디어 명령어
UI 제어 상태는 iOS 및 Android 발신기 확장 컨트롤러, 터치 기기에서 실행되는 수신기 및 리모컨 앱, Android TV 기기의 수신기 앱에 의해 MediaStatus.supportedMediaCommands
에 의해 구동됩니다. 속성에서 특정 비트 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를 제공합니다. 이러한 요청을 지원하려면 다음을 완료해야 합니다.
USER_ACTION
메시지를 가로채고 요청된 작업을 결정합니다.MediaInformation
UserActionState
를 업데이트하여 UI를 업데이트합니다.
아래 스니펫은 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
을 사용하고 MediaInformation
에서 UserActionState
를 추가하거나 삭제합니다. MediaInformation
의 UserActionState
를 업데이트하면 요청된 작업과 연결된 버튼의 상태가 변경됩니다. 이 변경사항은 스마트 디스플레이 컨트롤 UI, 리모컨 앱, Android TV UI에 반영됩니다. 또한 iOS 및 Android 발신자를 위해 확장된 컨트롤러의 UI를 업데이트하기 위해 발신 MediaStatus
메시지를 통해 브로드캐스트됩니다.
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에서 지원됩니다. 이러한 명령어의 기본 구현은 cast.framework.PlayerManager
에서 확인할 수 있습니다.
명령어 | 설명 |
---|---|
재생 | 일시중지 상태에서 재생을 재생하거나 다시 시작합니다. |
일시중지 | 현재 재생 중인 콘텐츠를 일시중지합니다. |
이전 | 미디어 큐의 이전 미디어 항목으로 건너뜁니다. |
다음 | 미디어 큐의 다음 미디어 항목으로 건너뜁니다. |
중지 | 현재 재생 중인 미디어를 중지합니다. |
반복 안함 | 대기열의 마지막 항목 재생이 완료되면 대기열의 미디어 항목 반복을 사용 중지합니다. |
반복 싱글 | 현재 재생 중인 미디어를 무제한으로 반복합니다. |
모두 반복 | 큐의 마지막 항목이 재생되면 큐의 모든 항목을 반복합니다. |
모두 반복 및 셔플 | 큐의 마지막 항목이 재생되면 큐를 셔플하고 큐에 있는 모든 항목을 반복합니다. |
셔플 | 미디어 대기열에서 미디어 항목을 셔플합니다. |
자막 사용 / 사용 중지 | 미디어의 자막 사용 / 사용 중지 사용 / 사용 중지는 언어별로도 지원됩니다. |
탐색을 절대 시간으로 | 지정된 절대 시간으로 이동합니다. |
탐색: 현재 시간과 비교하여 시간 기준 | 현재 재생 시간을 기준으로 지정된 기간만큼 앞뒤로 이동합니다. |
다시 플레이하기 | 현재 재생 중인 미디어를 다시 시작하거나, 현재 재생되고 있지 않은 경우 마지막으로 재생한 미디어 항목을 재생합니다. |
재생 속도 설정하기 | 미디어 재생 속도에 차이가 있습니다. 이 작업은 기본적으로 처리되어야 합니다. SET_PLAYBACK_RATE 메시지 가로채기를 사용하여 수신 속도 요청을 재정의할 수 있습니다. |
음성이 포함된 지원되는 미디어 명령어
어시스턴트 지원 기기에서 음성 명령어가 미디어 명령어를 트리거하지 못하게 하려면 먼저 지원하려는 지원되는 미디어 명령어를 설정해야 합니다. 그런 다음 CastReceiverOptions.enforceSupportedCommands
속성을 사용 설정하여 이러한 명령어를 적용해야 합니다. Cast SDK 발신자 및 터치 지원 기기의 UI가 이러한 구성을 반영하도록 변경됩니다. 이 플래그를 사용 설정하지 않으면 수신 음성 명령어가 실행됩니다.
예를 들어 발신기 애플리케이션 및 터치 지원 기기에서 PAUSE
를 허용하는 경우 이러한 설정을 반영하도록 수신기도 구성해야 합니다. 이 옵션이 구성되면 지원되는 명령어 목록에 포함되지 않은 모든 수신 음성 명령어가 삭제됩니다.
아래 예에서는 CastReceiverContext
를 시작할 때 CastReceiverOptions
를 제공합니다. PAUSE
명령어 지원을 추가하고 플레이어가 이 명령어만 지원하도록 시행했습니다. 이제 음성 명령어가 SEEK
와 같은 다른 작업을 요청하면 거부됩니다. 이 명령어는 아직 지원되지 않는다는 사실을 사용자에게 알립니다.
const context = cast.framework.CastReceiverContext.getInstance();
context.start({
enforceSupportedCommands: true,
supportedCommands: cast.framework.messages.Command.PAUSE
});
제한하려는 각 명령어에 별도의 로직을 적용할 수 있습니다. enforceSupportedCommands
플래그를 삭제하고 제한하려는 각 명령어에 대해 수신 메시지를 가로챌 수 있습니다. 여기서는 SDK가 제공하는 요청을 가로채서 어시스턴트 지원 기기에 실행된 SEEK
명령어가 웹 수신기 애플리케이션에서 탐색을 트리거하지 않도록 합니다.
애플리케이션에서 지원하지 않는 미디어 명령어의 경우 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 플랫폼이 사용자 음성 듣기 또는 말하기와 같은 어시스턴트 활동으로 인해 애플리케이션의 사운드를 백그라운드로 전송하는 경우 활동이 시작될 때 NOT_IN_FOCUS
의 FocusState
메시지가 웹 수신기 애플리케이션에 전송됩니다. 활동이 종료되면 IN_FOCUS
가 포함된 다른 메시지가 전송됩니다.
애플리케이션과 재생 중인 미디어에 따라 FocusState
가 NOT_IN_FOCUS
일 때 메시지 유형 FOCUS_STATE
를 가로채서 미디어를 일시중지할 수 있습니다.
예를 들어 어시스턴트가 사용자 쿼리에 응답하면 오디오북 재생을 일시중지하는 것이 좋습니다.
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
매개변수는 연결된 언어가 추천되었는지 또는 사용자가 명시적으로 요청했는지를 나타냅니다.
예를 들어 'OK Google, 자막 켜기' 명령어는 isSuggestedLanguage
가 true
로 설정됩니다. 언어가 사용된 언어에서 추론되었기 때문입니다. 'Hey Google, 영어 자막 켜 줘'와 같이 언어가 명시적으로 요청된 경우 isSuggestedLanguage
가 false
로 설정됩니다.
메타데이터 및 음성 전송
음성 명령은 기본적으로 웹 수신기에서 처리되지만 콘텐츠의 메타데이터가 완전하고 정확한지 확인해야 합니다. 이렇게 하면 음성 명령이 어시스턴트에 의해 제대로 처리되고 메타데이터가 Google Home 앱과 같은 새로운 유형의 인터페이스와 Google Home Hub와 같은 스마트 디스플레이에 표시됩니다.
스트림 이전
세션 상태 유지는 스트림 전송의 기초로, 사용자는 음성 명령, Google Home 앱 또는 스마트 디스플레이를 사용하여 기기 간에 기존 오디오 및 동영상 스트림을 이동할 수 있습니다. 미디어가 한 기기 (소스)에서 재생을 중지하고 다른 기기 (대상)에서 계속 재생됩니다. 최신 펌웨어가 있는 모든 Cast 기기는 스트림 전송에서 소스 또는 대상의 역할을 할 수 있습니다.
스트림 전송을 위한 이벤트 흐름은 다음과 같습니다.
- 원본 기기에서:
- 미디어 재생이 중지됩니다.
- 웹 수신기 애플리케이션은 현재 미디어 상태를 저장하는 명령어를 수신합니다.
- 웹 수신기 애플리케이션이 종료되었습니다.
- 대상 기기에서 다음을 실행합니다.
- 웹 수신기 애플리케이션이 로드됩니다.
- 웹 수신기 애플리케이션은 저장된 미디어 상태를 복원하는 명령어를 수신합니다.
- 미디어 재생이 다시 시작됩니다.
미디어 상태의 요소는 다음과 같습니다.
- 노래, 동영상, 미디어 항목의 특정 위치 또는 타임스탬프
- 더 넓은 대기열 (예: 재생목록 또는 아티스트 라디오)에 배치됩니다.
- 인증된 사용자입니다.
- 재생 상태 (예: 재생 또는 일시중지)
스트림 이전 사용 설정
웹 수신기에 스트림 전송을 구현하려면 다음 단계를 따르세요.
STREAM_TRANSFER
명령어로supportedMediaCommands
를 업데이트합니다.playerManager.addSupportedMediaCommands( cast.framework.messages.Command.STREAM_TRANSFER, true);
- 원하는 경우 세션 상태 보존에 설명된 대로
SESSION_STATE
및RESUME_SESSION
메시지 인터셉터를 재정의합니다. 커스텀 데이터를 세션 스냅샷의 일부로 저장해야 하는 경우에만 이를 재정의하세요. 그렇지 않으면 세션 상태를 보존하는 기본 구현이 스트림 전송을 지원합니다.
세션 상태 보존
웹 수신기 SDK는 웹 수신기 앱이 현재 미디어 상태의 스냅샷을 촬영하고 상태를 로드 요청으로 변환하고 로드 요청으로 세션을 재개하여 세션 상태를 보존할 수 있는 기본 구현을 제공합니다.
필요한 경우 웹 수신기에 의해 생성된 로드 요청을 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;
});
맞춤 데이터는 RESUME_SESSION
메시지 인터셉터의 loadRequestData.customData
에서 검색할 수 있습니다.
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;
});
콘텐츠 미리 로드
웹 수신기는 대기열의 현재 재생 항목 이후 미디어 항목 미리 로드를 지원합니다.
미리 로드 작업은 예정된 항목의 여러 세그먼트를 미리 다운로드합니다. 사양은 QueueItem 객체의 preloadTime 값에서 제공됩니다(제공되지 않은 경우 기본값은 20초). 시간은 현재 재생 중인 항목의 끝을 기준으로 초 단위로 표시됩니다 . 양수 값만 유효합니다. 예를 들어 값이 10초인 경우 이전 항목이 완료되기 10초 전에 이 항목이 미리 로드됩니다. 미리 로드 시간이 currentItem에 남은 시간보다 길면 미리 로드를 최대한 빨리 수행합니다. 따라서 매우 큰 값을 미리 로드하기 위해 큐 항목에 지정하면 현재 항목을 재생 중일 때 이미 다음 항목을 미리 로드하는 효과를 얻을 수 있습니다. 그러나 이 값은 현재 재생 항목의 대역폭 및 스트리밍 성능에 영향을 미칠 수 있으므로 개발자에게 설정과 선택은 그대로 둡니다.
미리 로드는 기본적으로 HLS, DASH, 스무스 스트리밍 콘텐츠에 적용됩니다.
Cast 기기가 단일 미디어 요소만 지원하며 기존 콘텐츠 항목이 재생되는 동안에는 미리 로드에 사용할 수 없으므로 일반 MP4 동영상 및 오디오 파일은 미리 로드되지 않습니다.
맞춤 메시지
메시지 교환은 웹 수신기 애플리케이션의 주요 상호작용 방법입니다.
발신자는 Android, iOS, 웹 등 실행 중인 플랫폼의 발신자 API를 사용하여 웹 수신자에게 메시지를 보냅니다. 이벤트 리스너에 전달되는 이벤트 객체 (메시지의 표현)에는 데이터가 특정 이벤트 유형의 속성을 갖는 데이터 요소(event.data
)가 있습니다.
웹 수신기 애플리케이션은 지정된 네임스페이스에서 메시지를 수신 대기하도록 선택할 수 있습니다. 이렇게 하면 웹 수신자 애플리케이션이 해당 네임스페이스 프로토콜을 지원한다고 표시됩니다. 그런 다음 해당 프로토콜과 통신하기를 원하는 연결된 발신자는 적절한 프로토콜을 사용합니다.
모든 네임스페이스는 문자열로 정의되며 '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();
마찬가지로 웹 수신기 애플리케이션은 연결된 발신자에게 메시지를 전송하여 웹 수신자의 상태에 대한 정보를 발신자에게 보낼 수 있습니다. 웹 수신기 애플리케이션은 CastReceiverContext
에서 sendCustomMessage(namespace, senderId, message)
를 사용하여 메시지를 보낼 수 있습니다.
웹 수신기는 수신된 메시지에 응답하거나 애플리케이션 상태 변경으로 인해 개별 발신자에게 메시지를 보낼 수 있습니다. 웹 수신자는 지점 간 메시지 (64KB 한도) 외에도 모든 연결된 발신자에게 메시지를 브로드캐스트할 수 있습니다.
오디오 기기용 전송
오디오 전용 재생에 관한 지원은 오디오 기기용 Google Cast 가이드를 참고하세요.
Android TV
이 섹션에서는 Google Web Receiver가 입력을 재생으로 사용하는 방법과 Android TV 호환성을 설명합니다.
애플리케이션을 리모컨과 통합
Android TV 기기에서 실행되는 Google 웹 수신기는 미디어 재생 메시지에 설명된 대로 기기의 컨트롤 입력 (예: 휴대기기 원격 제어) 입력을 urn:x-cast:com.google.cast.media
네임스페이스에 정의된 미디어 재생 메시지로 변환합니다. Android TV의 컨트롤 입력에서 기본 재생 컨트롤을 허용하려면 애플리케이션이 이러한 메시지를 지원하여 애플리케이션 미디어 재생을 제어해야 합니다.
Android TV 호환성 가이드라인
다음은 애플리케이션이 Android TV와 호환되도록 하기 위해 피해야 할 일반적인 실수입니다.
- 사용자 에이전트 문자열에 'Android' 및 'C eCPC'가 모두 포함되어 있습니다. 일부 사이트는 'Android' 라벨을 감지하므로 모바일 전용 사이트로 리디렉션될 수 있습니다. 사용자 에이전트 문자열의 'Android'가 항상 모바일 사용자를 나타낸다고 가정하지 마세요.
- Android의 미디어 스택은 데이터를 가져오는 데 투명한 GZIP을 사용할 수 있습니다. 미디어 데이터가
Accept-Encoding: gzip
에 응답할 수 있는지 확인합니다. - Android TV HTML5 미디어 이벤트는 Chromecast와 다른 시점에 트리거될 수 있으므로 Chromecast에 숨겨진 문제가 드러날 수 있습니다.
- 미디어를 업데이트할 때
timeupdate
,pause
,waiting
와 같은<audio>/<video>
요소에서 실행된 미디어 관련 이벤트를 사용합니다.progress
,suspend
,stalled
와 같은 네트워킹 관련 이벤트는 플랫폼에 종속되는 경향이 있으므로 사용하지 마세요. 수신기에서 미디어 이벤트를 처리하는 방법에 관한 자세한 내용은 미디어 이벤트를 참고하세요. - 수신기 사이트의 HTTPS 인증서를 구성할 때 중간 CA 인증서를 포함해야 합니다. Qualsys SSL 테스트 페이지를 참고하여 확인할 수 있습니다. 사이트의 신뢰할 수 있는 인증 경로에 '추가 다운로드'라고 표시된 CA 인증서가 포함되어 있으면 Android 기반 플랫폼에서 로드되지 않을 수 있습니다.
- Chromecast가 720p 그래픽 평면에 수신기 페이지를 표시하는 동안, Android TV를 비롯한 다른 Cast 플랫폼은 페이지를 최대 1080p로 표시할 수 있습니다. 수신기 페이지가 다양한 해상도에서 적절하게 확장되도록 합니다.