На этой странице приведены фрагменты кода и описания функций, доступных для приложения Custom Web Receiver.
- Элемент
cast-media-player, представляющий встроенный интерфейс проигрывателя, который предоставляется вместе с веб-приемником. - Специальный стиль, похожий на CSS, для элемента
cast-media-player, который позволяет оформлять различные элементы интерфейса, такие какbackground-image,splash-imageиfont-family. - Элемент скрипта для загрузки фреймворка Web Receiver.
- Код JavaScript для перехвата сообщений и обработки событий.
- Очередь для автовоспроизведения.
- Параметры воспроизведения.
- Параметры для настройки контекста веб-приемника.
- Параметры для настройки команд, поддерживаемых приложением веб-приемника.
- Вызов JavaScript для запуска приложения веб-приемника.
Конфигурация и параметры приложения
Настройте приложение.
CastReceiverContext – это внешний класс, доступный разработчику. Он управляет загрузкой базовых библиотек и инициализацией Web Receiver SDK. SDK предоставляет API, которые позволяют разработчикам приложений настраивать SDK с помощью CastReceiverOptions.
Эти конфигурации оцениваются один раз при запуске приложения и передаются в SDK при задании необязательного параметра в вызове start.
В примере ниже показано, как переопределить режим работы по умолчанию для определения того, активно ли подключение отправителя. Если веб-приемник не может связаться с отправителем в течение maxInactivity секунд, отправляется событие SENDER_DISCONNECTED. Указанная ниже конфигурация переопределяет это время ожидания. Это может быть полезно при отладке, так как не позволяет веб-приемнику закрывать сеанс удаленного отладчика 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 и оценивается при создании игроков. Проигрыватели создаются каждый раз, когда в Web Receiver SDK передается новая загрузка. Изменения, внесенные в PlaybackConfig после создания проигрывателя, будут учтены при следующей загрузке контента. SDK предоставляет следующие методы для изменения PlaybackConfig:
CastReceiverOptions.playbackConfig, чтобы переопределить параметры конфигурации по умолчанию при инициализацииCastReceiverContext.PlayerManager.getPlaybackConfig(), чтобы получить текущую конфигурацию.PlayerManager.setPlaybackConfig(), чтобы переопределить текущую конфигурацию. Эта настройка применяется ко всем последующим загрузкам или до тех пор, пока не будет переопределена.PlayerManager.setMediaPlaybackInfoHandler()чтобы применить дополнительные конфигурации только к мультимедийному объекту, загружаемому поверх текущих конфигураций. Обработчик вызывается непосредственно перед созданием проигрывателя. Изменения, внесенные здесь, не сохраняются и не учитываются в запросах кgetPlaybackConfig(). Когда загружается следующий мультимедийный объект, этот обработчик вызывается снова.
В примере ниже показано, как задать PlaybackConfig при инициализации CastReceiverContext. Конфигурация переопределяет исходящие запросы на получение манифестов. Обработчик указывает, что запросы CORS Access-Control должны выполняться с использованием учетных данных, таких как файлы cookie или заголовки авторизации.
const playbackConfig = new cast.framework.PlaybackConfig();
playbackConfig.manifestRequestHandler = requestInfo => {
requestInfo.withCredentials = true;
};
context.start({playbackConfig: playbackConfig});
В примере ниже показано, как переопределить PlaybackConfig с помощью геттера и сеттера, предоставленных в PlayerManager. Эта настройка позволяет возобновить воспроизведение контента после загрузки одного сегмента.
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;
});
Прослушиватель событий
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;
});
});
Перехват сообщений и прослушиватель событий
Ниже перечислены основные различия между перехватом сообщений и прослушивателем событий.
- Прослушиватель событий не позволяет изменять данные запроса.
- Прослушиватель событий лучше всего использовать для запуска аналитики или специальной функции.
playerManager.addEventListener(cast.framework.events.category.CORE,
event => {
console.log(event);
});
- Перехват сообщений позволяет прослушивать сообщения, перехватывать их и изменять данные запроса.
- Перехват сообщений лучше всего подходит для обработки данных запросов с помощью специальной логики.
Загрузка медиаконтента
MediaInformation
предоставляет множество свойств для загрузки медиаконтента в сообщение cast.framework.messages.MessageType.LOAD, включая entity, contentUrl и contentId.
- Рекомендуем использовать в реализации для приложений отправителя и получателя ресурс
entity. Свойство представляет собой URL ссылки на контент, который может быть плейлистом или медиаконтентом. Ваше приложение должно проанализировать этот URL и заполнить хотя бы одно из двух других полей. contentUrl– это воспроизводимый URL, который проигрыватель будет использовать для загрузки контента. Например, этот URL может указывать на манифест DASH.contentIdможет быть 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 предоставляет информацию о подключенном Cast-устройстве и подключенном к нему видео- или аудиоустройстве. Метод getDeviceCapabilities предоставляет информацию о поддержке Google Ассистента, Bluetooth, подключенного дисплея и аудиоустройств.
Этот метод возвращает объект, который можно запросить, передав одно из указанных перечислений, чтобы получить возможность устройства для этого перечисления. Перечисления определены в файле 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), голосовые команды на устройствах с поддержкой Ассистента, сенсорное управление на умных дисплеях и пульты дистанционного управления на устройствах Android TV. Cast SDK предоставляет различные API, позволяющие веб-приложению-приемнику обрабатывать эти взаимодействия, обновлять пользовательский интерфейс приложения через состояния действий пользователя и при необходимости отправлять изменения для обновления любых серверных служб.
Поддерживаемые команды для управления мультимедиа
Состояния элементов управления пользовательского интерфейса определяются 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. Когда статус транслируется, подключенные приложения-отправители обновляют кнопки в своем интерфейсе.
Подробнее о поддерживаемых командах управления мультимедиа и сенсорных устройствах можно узнать в Accessing UI controls.
Управление состояниями действий пользователей
Когда пользователи взаимодействуют с интерфейсом или отправляют голосовые команды, они могут управлять воспроизведением контента и свойствами, связанными с воспроизводимым элементом. Запросы, управляющие воспроизведением, обрабатываются SDK автоматически. Запросы, которые изменяют свойства текущего воспроизводимого объекта, например команда LIKE, должны обрабатываться приложением-получателем. В SDK есть ряд API для обработки таких запросов. Чтобы поддерживать такие запросы, необходимо выполнить следующие действия:
- Установите значение
MediaInformationuserActionStatesв соответствии с предпочтениями пользователя при загрузке мультимедийного объекта. - Перехватывать сообщения
USER_ACTIONи определять запрошенное действие. - Обновите
MediaInformationUserActionState, чтобы обновить интерфейс.
В приведенном ниже фрагменте кода перехватывается запрос 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 меняет состояние кнопки, связанной с запрошенным действием. Это изменение отражено в интерфейсе управления умным дисплеем, приложении для дистанционного управления и интерфейсе Android TV. Кроме того, он передается через исходящие сообщения MediaStatus, чтобы обновить интерфейс развернутого контроллера для отправителей на 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 для устройств с поддержкой Ассистента поддерживаются следующие команды мультимедиа. Реализации этих команд по умолчанию можно найти в файле cast.framework.PlayerManager.
| Команда | Описание |
|---|---|
| Воспроизвести | Воспроизвести или возобновить воспроизведение после паузы. |
| Приостановка комментариев | Приостановить воспроизведение контента. |
| Назад | Перейти к предыдущему медиафайлу в очереди. |
| Далее | Перейти к следующему мультимедийному объекту в очереди. |
| Остановить | Остановить воспроизведение. |
| Не повторять | Отключить повтор воспроизведения мультимедийных объектов в очереди после того, как будет воспроизведен последний объект. |
| Повторять один трек | Повторять текущий медиафайл бесконечно. |
| Повторять все | Повторять все треки в очереди после воспроизведения последнего. |
| Повтор всех треков и перемешивание | Когда последний трек в очереди закончится, очередь перемешается и все треки будут воспроизведены снова. |
| Перемешать | Перемешать мультимедийные объекты в очереди воспроизведения. |
| Субтитры (вкл./выкл.) | Включить или отключить субтитры для медиаконтента. Включить или отключить функцию можно для каждого языка отдельно. |
| Перемотка к абсолютному времени | Переход к указанному абсолютному времени. |
| Перейти к времени относительно текущего | Перематывает видео вперед или назад на указанный промежуток времени относительно текущего времени воспроизведения. |
| Сыграть ещё раз | Перезапустить воспроизведение текущего медиаконтента или воспроизвести последний воспроизведенный мультимедийный объект, если сейчас ничего не проигрывается. |
| Как задать скорость воспроизведения | Изменять скорость воспроизведения медиаконтента. Это должно быть настроено по умолчанию. Вы можете использовать перехватчик сообщений SET_PLAYBACK_RATE, чтобы переопределять входящие запросы на ограничение частоты. |
Поддерживаемые голосовые команды для управления медиаконтентом
Чтобы голосовая команда не запускала команду медиа на устройстве с поддержкой Ассистента, сначала задайте поддерживаемые команды медиа. Затем вам нужно применить эти команды, включив свойство CastReceiverOptions.enforceSupportedCommands. Интерфейс отправителей 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, отправленные на устройства с поддержкой Ассистента,
не запускали поиск в вашем приложении веб-приемника.
Если ваше приложение не поддерживает определенные команды для мультимедиа, возвращайте подходящую причину ошибки, например 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 переводит звук вашего приложения в фоновый режим из-за действий Ассистента, например когда он слушает речь пользователя или отвечает ему, то при начале этих действий в приложение Web Receiver отправляется сообщение FocusState
NOT_IN_FOCUS. Когда действие завершится, будет отправлено ещё одно сообщение с 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 входящего сообщения указывает, был ли связанный язык предложен или явно запрошен пользователем.
Например, для команды "Окей, Google, включи субтитры" значение isSuggestedLanguage будет true, поскольку язык был определен по языку команды. Если язык указан в запросе, например "Окей, Google, включи субтитры на английском", для параметра isSuggestedLanguage задается значение false.
Метаданные и голосовое управление
По умолчанию голосовые команды обрабатываются веб-приемником, но вам следует убедиться, что метаданные вашего контента полные и точные. Это позволяет Ассистенту правильно обрабатывать голосовые команды, а метаданным – корректно отображаться в новых типах интерфейсов, например в приложении Google Home и на умных дисплеях, таких как Google Home Hub.
Перенос трансляции
Сохранение состояния сеанса – основа передачи потока, при которой пользователи могут переключать аудио- и видеопотоки между устройствами с помощью голосовых команд, приложения Google Home или умных дисплеев. Воспроизведение медиаконтента останавливается на одном устройстве (источнике) и продолжается на другом (целевом). Любое устройство для трансляции [контента] : Cast-устройство : [*] с последней версией встроенного ПО может быть источником или получателем при переносе трансляции.
Последовательность событий при переносе трансляции:
- На исходном устройстве:
- Воспроизведение медиаконтента останавливается.
- Веб-приложение-получатель получает команду сохранить текущее состояние медиаконтента.
- Приложение 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;
});
Предзагрузка контента
Веб-приемник поддерживает предварительную загрузку объектов мультимедиа после текущего воспроизведения. элемент в очереди.
При предварительной загрузке скачиваются несколько сегментов предстоящих объектов. Значение указывается в объекте QueueItem в поле preloadTime (если оно не задано, по умолчанию используется значение 20 секунд). Время указывается в секундах относительно конца текущего воспроизводимого объекта . Допустимы только положительные значения. Например, если значение равно 10 секундам, этот объект будет предварительно загружен за 10 секунд до того, как закончится предыдущий объект. Если время предварительной загрузки больше, чем время, оставшееся до конца текущего элемента, предварительная загрузка начнется как можно скорее. Таким образом, если для queueItem указано очень большое значение preload, то во время воспроизведения текущего элемента будет выполняться предварительная загрузка следующего. Однако мы оставляем настройку и выбор этого параметра на усмотрение разработчика, поскольку это значение может повлиять на пропускную способность и производительность потоковой передачи текущего воспроизводимого элемента.
Предзагрузка по умолчанию работает с контентом, передаваемым по протоколам HLS, DASH и Smooth Streaming.
Обычные видеофайлы MP4 и аудиофайлы MP3 не будут предварительно загружаться, поскольку устройства Cast поддерживают только один медиаэлемент и не могут использоваться для предварительной загрузки, пока воспроизводится существующий контент.
Специальные сообщения
Обмен сообщениями – основной способ взаимодействия для приложений Web Receiver.
Отправитель передает сообщения веб-приемнику, используя API отправителя для платформы, на которой он работает (Android, iOS, веб). Объект события (который является проявлением сообщения), передаваемый прослушивателям событий, содержит элемент данных (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();
Аналогичным образом приложения веб-приемника могут сообщать отправителям о своем состоянии, отправляя им сообщения. Приложение веб-приемника может отправлять сообщения с помощью sendCustomMessage(namespace, senderId, message) на CastReceiverContext.
Веб-приемник может отправлять сообщения отдельному отправителю либо в ответ на полученное сообщение, либо в связи с изменением состояния приложения. Помимо обмена сообщениями между двумя устройствами (с ограничением в 64 КБ), веб-приемник может также транслировать сообщения всем подключенным отправителям.
Трансляция на аудиоустройства
Информацию о воспроизведении только аудиоконтента можно найти в руководстве по Google Cast для аудиоустройств.
Android TV
В этом разделе рассказывается, как веб-приемник Google использует ваши входные данные для воспроизведения и как он совместим с Android TV.
Интеграция приложения с пультом ДУ
Google Web Receiver, запущенный на устройстве Android TV, преобразует входные данные от элементов управления устройства (например, от пульта ДУ) в сообщения о воспроизведении медиаконтента, определенные для пространства имен urn:x-cast:com.google.cast.media, как описано в разделе Сообщения о воспроизведении медиаконтента. Чтобы пользователи могли управлять воспроизведением медиаконтента в приложении с помощью элементов управления Android TV, ваше приложение должно поддерживать эти сообщения.
Требования к совместимости с Android TV
Ниже приведены рекомендации и распространенные ошибки, которые следует учитывать, чтобы ваше приложение было совместимо с Android TV.
- Учитывайте, что строка агента пользователя содержит как "Android", так и "CrKey". Некоторые сайты могут перенаправлять на мобильную версию, поскольку обнаруживают ярлык "Android". Не предполагайте, что строка User-Agent, содержащая слово "Android", всегда указывает на мобильного пользователя.
- Медиастек Android может использовать прозрачное сжатие GZIP для получения данных. Убедитесь, что ваши медиаданные могут отвечать на запросы
Accept-Encoding: gzip. - События мультимедиа HTML5 на Android TV могут запускаться в другое время, чем на Chromecast, и это может выявить проблемы, которые были скрыты на Chromecast.
- При обновлении медиаконтента используйте события, связанные с медиаконтентом, которые активируются элементами
<audio>/<video>, напримерtimeupdate,pauseиwaiting. Не используйте события, связанные с сетью, напримерprogress,suspendиstalled, поскольку они зависят от платформы. Подробнее о том, как обрабатывать медиасобытия в получателе… - При настройке сертификатов HTTPS для сайта-получателя обязательно включите сертификаты промежуточного центра сертификации. Проверьте это на странице тестирования Qualsys SSL. Если доверенный путь сертификации для вашего сайта включает сертификат ЦС с пометкой "дополнительное скачивание", то он может не загружаться на платформах Android.
- Хотя Chromecast отображает страницу получателя на графическом уровне 720p, другие платформы Cast, в том числе Android TV, могут отображать страницу с разрешением до 1080p. Убедитесь, что страница получателя корректно масштабируется при разных разрешениях.