На этой странице представлены фрагменты кода и описания функций, доступных для приложения, созданного на основе пользовательского веб-приемника.
- Элемент
cast-media-player, представляющий собой встроенный пользовательский интерфейс проигрывателя, предоставляемый Web Receiver. - Настройка стилей, аналогичных CSS, для элемента
cast-media-playerпозволяющая стилизовать различные элементы пользовательского интерфейса, такие какbackground-image,splash-imageиfont-family. - Элемент скрипта для загрузки фреймворка Web Receiver.
- JavaScript-код для перехвата сообщений и обработки событий.
- Поставить в очередь на автовоспроизведение.
- Параметры для настройки воспроизведения.
- Параметры для настройки контекста веб-приемника.
- Параметры для настройки команд, поддерживаемых приложением Web Receiver.
- Вызов JavaScript для запуска приложения Web Receiver.
Настройки и параметры приложения
Настройте приложение
Класс CastReceiverContext является самым внешним классом, доступным разработчику, и он управляет загрузкой базовых библиотек и инициализацией SDK Web Receiver. SDK предоставляет API, позволяющие разработчикам приложений настраивать SDK через CastReceiverOptions . Эти конфигурации оцениваются один раз при каждом запуске приложения и передаются в SDK при установке необязательного параметра в вызове метода start .
В приведенном ниже примере показано, как переопределить поведение по умолчанию для определения того, активно ли установлено соединение с отправителем. Когда Web Receiver не может связаться с отправителем в течение maxInactivity секунд, отправляется событие SENDER_DISCONNECTED . Приведенная ниже конфигурация переопределяет этот тайм-аут. Это может быть полезно при отладке проблем, поскольку предотвращает закрытие сеанса удаленного отладчика Chrome приложением Web Receiver, когда в состоянии IDLE нет подключенных отправителей.
const context = cast.framework.CastReceiverContext.getInstance();
const options = new cast.framework.CastReceiverOptions();
options.maxInactivity = 3600; // Development only
context.start(options);
Настройте плеер
При загрузке контента SDK Web Receiver предоставляет возможность настройки переменных воспроизведения, таких как информация о DRM , конфигурации повторных попыток и обработчики запросов, с помощью cast.framework.PlaybackConfig . Эта информация обрабатывается PlayerManager и оценивается в момент создания плееров. Плееры создаются каждый раз, когда в SDK Web Receiver передается новая загрузка. Изменения в 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;
});
обработчик событий
SDK Web Receiver позволяет вашему приложению Web Receiver обрабатывать события проигрывателя. Слушатель событий принимает параметр cast.framework.events.EventType (или массив таких параметров), который указывает событие (или события), которые должны запускать слушатель. Предварительно настроенные массивы cast.framework.events.EventType , полезные для отладки, можно найти в cast.framework.events.category . Параметр event предоставляет дополнительную информацию о событии.
Например, если вы хотите узнать, когда транслируется изменение 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 Web Receiver позволяет вашему приложению 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();
Обработка ошибок
При возникновении ошибок в перехватчике сообщений ваше приложение 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;
});
});
Перехват сообщений против прослушивания событий
Ниже приведены некоторые ключевые различия между перехватом сообщений и обработчиком событий:
- Обработчик событий не позволяет изменять данные запроса.
- Обработчик событий лучше всего использовать для запуска аналитики или пользовательской функции.
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), либо уникальный идентификатор загружаемого контента или плейлиста. Если вы используете это свойство в качестве идентификатора, ваше приложение должно заполнить поле 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 Assistant, 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), голосовые команды на устройствах с поддержкой Google Assistant, сенсорное управление на смарт-дисплеях и пульты дистанционного управления на устройствах Android TV. SDK Cast предоставляет различные API, позволяющие приложению Web Receiver обрабатывать эти взаимодействия, обновлять пользовательский интерфейс приложения в зависимости от состояния действий пользователя и, при необходимости, отправлять изменения для обновления любых серверных служб.
Поддерживаемые команды мультимедиа
Состояния элементов управления пользовательского интерфейса определяются свойством 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и определяйте запрошенное действие. - Обновите значение
UserActionStateобъектаMediaInformation, чтобы обновить пользовательский интерфейс.
Следующий фрагмент кода перехватывает запрос 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;
}
Голосовые команды
В настоящее время в SDK Web Receiver для устройств с поддержкой Google Assistant поддерживаются следующие команды работы с мультимедиа. Реализации этих команд по умолчанию находятся в cast.framework.PlayerManager .
| Командование | Описание |
|---|---|
| Играть | Воспроизвести или возобновить воспроизведение с паузы. |
| Пауза | Приостановить воспроизведение текущего контента. |
| Предыдущий | Перейти к предыдущему медиафайлу в очереди воспроизведения. |
| Следующий | Перейти к следующему медиафайлу в очереди воспроизведения. |
| Останавливаться | Остановить воспроизведение текущего медиафайла. |
| Повторить Нет | Отключить повтор воспроизведения медиафайлов в очереди после завершения воспроизведения последнего файла в очереди. |
| Повторить одиночный | Воспроизводимый в данный момент медиафайл можно повторять бесконечно. |
| Повторить все | Повторите все элементы в очереди после того, как будет воспроизведен последний элемент в очереди. |
| Повторить все и перемешать | После того, как последний элемент в очереди проиграется, перемешайте очередь и повторите воспроизведение всех элементов в очереди. |
| Перетасовка | Перемешивайте медиафайлы в очереди воспроизведения. |
| Субтитры Вкл. / Выкл. | Включение/отключение субтитров для ваших медиафайлов. Также можно выбрать язык субтитров. |
| Стремитесь к абсолютному времени. | Переход к указанному абсолютному времени. |
| Стремитесь соотносить время с текущим временем. | Перемещается вперед или назад на указанный промежуток времени относительно текущего времени воспроизведения. |
| Сыграть снова | Если в данный момент ничего не воспроизводится, перезапустите воспроизводимый в данный момент медиафайл или воспроизведите последний воспроизведенный медиафайл. |
| Установить скорость воспроизведения | Изменяйте скорость воспроизведения мультимедиа. Это должно обрабатываться по умолчанию. Вы можете использовать перехватчик сообщений SET_PLAYBACK_RATE для переопределения входящих запросов на изменение скорости. |
Поддерживаются голосовые команды управления мультимедиа.
Чтобы предотвратить запуск команды воспроизведения мультимедиа голосовой командой на устройстве с поддержкой Google Assistant, необходимо сначала указать поддерживаемые команды воспроизведения мультимедиа , которые вы планируете поддерживать. Затем необходимо обеспечить выполнение этих команд, включив свойство 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 , отправленные устройствам с поддержкой Google 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 переводит звук вашего приложения в фоновый режим из-за активности Ассистента, например, прослушивания речи пользователя или ответа на её реплики, то при начале активности в приложение 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 входящего сообщения указывает, был ли соответствующий язык предложен или явно запрошен пользователем.
Например, для команды «OK Google, включи субтитры» параметр isSuggestedLanguage устанавливается в true , поскольку язык определяется на основе языка, на котором была произнесена команда. Если язык запрашивается явно, например, в команде «OK Google, включи английские субтитры», isSuggestedLanguage устанавливается в false .
Метаданные и подбор голоса
Хотя голосовые команды по умолчанию обрабатываются веб-приемником, следует убедиться, что метаданные для вашего контента являются полными и точными. Это гарантирует правильную обработку голосовых команд Ассистентом и корректное отображение метаданных на новых типах интерфейсов, таких как приложение Google Home и умные дисплеи, например, Google Home Hub.
Передача потока
Сохранение состояния сессии является основой потоковой передачи, позволяющей пользователям перемещать существующие аудио- и видеопотоки между устройствами с помощью голосовых команд, приложения Google Home или умных дисплеев. Воспроизведение медиафайлов прекращается на одном устройстве (источнике) и продолжается на другом (получателе). Любое устройство Cast с последней версией прошивки может выступать в качестве источника или получателя при потоковой передаче.
Последовательность событий для потоковой передачи данных выглядит следующим образом:
- На исходном устройстве:
- Медиа прекращают трансляцию.
- Приложение 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 предоставляет реализацию по умолчанию для приложений 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 секунд до завершения предыдущего элемента. Если время предварительной загрузки больше, чем оставшееся время текущего элемента, предварительная загрузка произойдет как можно скорее. Таким образом, если в объекте QueueItem указано очень большое значение preloadTime, можно добиться эффекта предварительной загрузки следующего элемента во время воспроизведения текущего элемента. Однако мы оставляем настройку и выбор этого параметра на усмотрение разработчика, поскольку это значение может влиять на пропускную способность и производительность потоковой передачи текущего воспроизводимого элемента.
Предварительная загрузка по умолчанию будет работать для потокового контента HLS, DASH и Smooth.
Обычные видео- и аудиофайлы в формате MP4, такие как MP3, не будут предварительно загружены, поскольку устройства Cast поддерживают только один медиаэлемент и не могут использоваться для предварительной загрузки, пока воспроизводится уже существующий контент.
Пользовательские сообщения
Обмен сообщениями является ключевым методом взаимодействия для приложений Web Receiver.
Отправитель передает сообщения веб-приемнику, используя API отправителя для платформы, на которой он работает (Android, iOS, Web). Объект события (который является проявлением сообщения), передаваемый обработчикам событий, содержит элемент данных ( event.data ), где данные принимают свойства конкретного типа события.
Приложение Web Receiver может выбрать прослушивание сообщений в указанном пространстве имен. Благодаря этому приложение 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 . Web Receiver может отправлять сообщения отдельному отправителю либо в ответ на полученное сообщение, либо в связи с изменением состояния приложения. Помимо обмена сообщениями между двумя точками (с ограничением в 64 КБ), Web Receiver также может транслировать сообщения всем подключенным отправителям.
Трансляция для аудиоустройств
Информацию о поддержке воспроизведения только звука см. в руководстве по Google Cast для аудиоустройств .
Android TV
В этом разделе обсуждается, как Google Web Receiver использует ваши входные данные для воспроизведения, а также совместимость с Android TV.
Интеграция вашего приложения с пультом дистанционного управления.
Веб-приемник Google, работающий на устройстве 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 с пометкой «дополнительная загрузка», то он может не загрузиться на платформах Android.
- В то время как Chromecast отображает страницу приемника в графическом формате 720p, другие платформы Cast, включая Android TV, могут отображать страницу в формате до 1080p. Убедитесь, что страница вашего приемника корректно масштабируется при разных разрешениях.