1. Обзор
В этой лаборатории кода вы узнаете, как создать приложение Custom Web Receiver для воспроизведения контента на устройствах с поддержкой Cast .
Что такое Google Cast?
Google Cast позволяет пользователям транслировать контент с мобильного устройства на телевизор. Затем пользователи могут использовать свое мобильное устройство или браузер Chrome на настольном компьютере в качестве пульта дистанционного управления для воспроизведения мультимедиа на телевизоре.
Google Cast SDK позволяет вашему приложению управлять устройствами с поддержкой Google Cast (например, телевизором или аудиосистемой). Cast SDK предоставляет необходимые компоненты пользовательского интерфейса на основе контрольного списка Google Cast Design .
Контрольный список Google Cast Design предназначен для того, чтобы сделать использование Cast простым и предсказуемым на всех поддерживаемых платформах. Подробнее см. здесь.
Что мы собираемся строить?
После завершения этой лабораторной работы у вас будет приложение HTML5, которое действует как ваш собственный пользовательский приемник, способный отображать видеоконтент на устройствах с поддержкой Cast.
Что вы узнаете
- Как подготовиться к разработке приемника.
- Основные сведения о приемнике с поддержкой Cast на основе платформы Cast Application Framework.
- Как получить кастинговое видео.
- Как интегрировать Debug Logger.
- Как оптимизировать приемник для умных дисплеев.
Что вам понадобится
- Новейший браузер Google Chrome .
- Служба хостинга HTTPS, например Firebase Hosting или ngrok .
- Устройство Google Cast, например Chromecast или Android TV, с доступом в Интернет.
- Телевизор или монитор с входом HDMI.
Опыт
- Вам потребуются предыдущие знания веб-разработки.
- Вам также потребуются предварительные знания о просмотре телевизора :)
Как вы будете использовать этот урок?
Как бы вы оценили свой опыт создания веб-приложений?
Как бы вы оценили свои впечатления от просмотра телевидения?
2. Получите пример кода
Вы можете загрузить весь пример кода на свой компьютер...
и распакуйте загруженный zip-файл.
3. Развертывание приемника локально
Чтобы иметь возможность использовать веб-приемник с устройством Cast, он должен быть размещен где-то, где ваше устройство Cast сможет его достичь. Если у вас уже есть доступный сервер, поддерживающий https, пропустите следующие инструкции и запишите URL-адрес , так как он понадобится вам в следующем разделе.
Если у вас нет доступного сервера, вы можете использовать хостинг Firebase или ngrok .
Запустить сервер
После того, как вы настроите выбранную вами службу, перейдите к app-start
и запустите свой сервер.
Запишите URL-адрес вашего размещенного приемника. Вы будете использовать его в следующем разделе.
4. Зарегистрируйте приложение в консоли разработчика Cast.
Вам необходимо зарегистрировать свое приложение , чтобы иметь возможность запускать собственный приемник, встроенный в эту кодовую лабораторию, на устройствах Chromecast. После регистрации приложения вы получите идентификатор приложения, который ваше приложение-отправитель должно использовать для выполнения вызовов API, например для запуска приложения-получателя.
Нажмите «Добавить новое приложение»
Выберите «Пользовательский приемник», это то, что мы создаем.
Введите данные вашего нового получателя, обязательно используйте URL-адрес, который вы получили в итоге.
в последнем разделе. Запишите идентификатор приложения, присвоенный вашему новому приемнику.
Вы также должны зарегистрировать свое устройство Google Cast , чтобы оно могло получить доступ к вашему приложению-приемнику перед его публикацией. После публикации приложения-приемника оно станет доступно для всех устройств Google Cast. Для целей этой лаборатории рекомендуется работать с неопубликованным приложением-приемником.
Нажмите «Добавить новое устройство».
Введите серийный номер, напечатанный на задней панели устройства Cast, и дайте ему описательное имя. Вы также можете узнать свой серийный номер, транслируя экран в Chrome при доступе к консоли разработчика Google Cast SDK.
Пройдет 5–15 минут, прежде чем ваш приемник и устройство будут готовы к тестированию. Подождав 5–15 минут, необходимо перезагрузить устройство Cast.
5. Запустите пример приложения.
Пока мы ждем, пока наше новое приложение-приемник будет готово к тестированию, давайте посмотрим, как выглядит образец готового приложения-приемника. Ресивер, который мы собираемся построить, будет способен воспроизводить мультимедиа с использованием потоковой передачи с адаптивным битрейтом (мы будем использовать образец контента, закодированный для динамической адаптивной потоковой передачи через HTTP (DASH)).
В браузере откройте инструмент управления и контроля (CaC) .
- Вы должны увидеть наш инструмент CaC.
- Используйте образец идентификатора приемника по умолчанию «CC1AD845» и нажмите кнопку «Установить идентификатор приложения».
- Нажмите кнопку Cast в левом верхнем углу и выберите свое устройство Google Cast.
- Перейдите на вкладку «Загрузить носитель» вверху.
- Нажмите кнопку «Загрузить по содержимому», чтобы воспроизвести образец видео.
- Видео начнет воспроизводиться на вашем устройстве Google Cast, чтобы показать, как выглядят основные функции приемника с использованием приемника по умолчанию.
6. Подготовьте стартовый проект
Нам нужно добавить поддержку Google Cast в загруженное вами стартовое приложение. Вот некоторая терминология Google Cast, которую мы будем использовать в этой лаборатории кода:
- приложение- отправитель работает на мобильном устройстве или ноутбуке,
- приложение- приемник работает на устройстве Google Cast.
Теперь вы готовы работать над исходным проектом, используя свой любимый текстовый редактор:
- Выберите каталог
app-start
из загруженного примера кода. - Откройте
js/receiver.js
иindex.html
Обратите внимание: пока вы работаете над этой лабораторией кода, http-server
должен улавливать внесенные вами изменения. Если вы заметили, что это не так, попробуйте убить и перезапустить http-server
.
Дизайн приложения
Приложение-получатель инициализирует сеанс Cast и будет находиться в режиме ожидания до тех пор, пока не поступит запрос LOAD (другими словами, команда на воспроизведение фрагмента мультимедиа) от отправителя.
Приложение состоит из одного основного представления, определенного в index.html
, и одного файла JavaScript с именем js/receiver.js
содержащего всю логику, необходимую для работы нашего приемника.
index.html
Этот html-файл будет содержать пользовательский интерфейс нашего приложения-приемника. На данный момент он пуст, и мы будем дополнять его в лаборатории кода.
приемник.js
Этот скрипт будет управлять всей логикой нашего приложения-приемника. Сейчас это всего лишь пустой файл, но мы собираемся превратить его в полностью функционирующий приемник Cast с помощью всего лишь нескольких строк кода в следующем разделе.
7. Базовый приемник Cast
Базовый приемник Cast инициализирует сеанс Cast при запуске. Это необходимо, чтобы сообщить всем подключенным приложениям-отправителям, что подключение получателя прошло успешно. Кроме того, новый SDK предварительно настроен для обработки потокового мультимедиа с адаптивным битрейтом (с использованием DASH, HLS и Smooth Streaming) и простых файлов MP4. Давайте попробуем это.
Инициализация
Добавьте следующий код в index.html
в заголовке:
<head>
...
<script src="//www.gstatic.com/cast/sdk/libs/caf_receiver/v3/cast_receiver_framework.js"></script>
</head>
Добавьте следующий код в index.html
<body>
перед < footer>
загрузкой файла receiver.js,
чтобы предоставить SDK приемника достаточно места для вызова пользовательского интерфейса приемника по умолчанию, который поставляется вместе со сценарием, который вы только что добавили.
<cast-media-player></cast-media-player>
Теперь нам нужно инициализировать SDK в js/receiver.js
, состоящий из:
- получение ссылки на
CastReceiverContext
, вашу основную точку входа во весь Receiver SDK. - сохранение ссылки на
PlayerManager
, объект, обрабатывающий воспроизведение, и предоставление вам всех хуков, необходимых для подключения вашей собственной пользовательской логики. - инициализация SDK путем вызова
start()
вCastReceiverContext
Добавьте следующее в js/receiver.js
.
const context = cast.framework.CastReceiverContext.getInstance();
const playerManager = context.getPlayerManager();
context.start();
8. Кастинг «базового» видеоконтента
Для целей этой лаборатории кода используйте CaC Tool, чтобы опробовать свой новый приемник.
Направьте свой веб-браузер на инструмент управления и контроля (CaC) .
Обязательно замените в поле свой собственный идентификатор приложения , зарегистрированный ранее, и нажмите «Установить идентификатор приложения». Это указывает инструменту использовать ваш приемник при запуске сеанса трансляции.
Кастинг СМИ
На высоком уровне для воспроизведения мультимедиа на устройстве Cast должно произойти следующее:
- Отправитель создает объект
MediaInfo
JSON
из Cast SDK, который моделирует элемент мультимедиа. - Отправитель подключается к устройству Cast для запуска приложения-получателя.
- Получатель загружает объект
MediaInfo
с помощью запросаLOAD
для воспроизведения содержимого. - Ресивер контролирует и отслеживает состояние носителя.
- Отправитель отправляет получателю команды воспроизведения для управления воспроизведением на основе взаимодействия пользователя с приложением отправителя.
В этой первой базовой попытке мы собираемся заполнить MediaInfo
URL-адресом воспроизводимого ресурса (хранящимся в MediaInfo.contentUrl
).
Реальный отправитель использует идентификатор мультимедиа, специфичный для приложения, в MediaInfo.contentId
. Получатель использует contentId
в качестве идентификатора для выполнения соответствующих вызовов серверного API для разрешения фактического URL-адреса ресурса и установки для него значения MediaInfo.contentUrl.
Ресивер также будет выполнять такие задачи, как получение лицензии DRM или вставка информации о рекламных паузах.
В следующем разделе мы собираемся расширить возможности вашего приемника, чтобы он мог делать что-то подобное. А пока нажмите значок Cast и выберите свое устройство, чтобы открыть ресивер.
Перейдите на вкладку «Загрузить медиафайл» и нажмите кнопку «Загрузить по содержимому». Ваш ресивер должен начать воспроизведение образца контента.
Итак, в стандартной комплектации Receiver SDK обрабатывает:
- Инициализация сеанса трансляции
- Обработка входящих запросов
LOAD
от отправителей, содержащих игровые ресурсы. - Предоставьте базовый пользовательский интерфейс проигрывателя, готовый к отображению на большом экране.
Не стесняйтесь изучить инструмент CaC и его код, прежде чем перейти к следующему разделу, где мы собираемся расширить наш приемник, чтобы он мог взаимодействовать с простым примером API для выполнения входящих запросов LOAD
от отправителей.
9. Интеграция с внешним API
В соответствии с тем, как большинство разработчиков взаимодействуют со своими приемниками Cast в реальных приложениях, мы собираемся модифицировать наш приемник для обработки запросов LOAD
, которые ссылаются на предполагаемый медиаконтент по его ключу API вместо отправки URL-адреса воспроизводимого ресурса.
Приложения обычно делают это, потому что:
- Отправитель может не знать URL-адрес содержимого.
- Приложение Cast предназначено для обработки аутентификации, другой бизнес-логики или вызовов API непосредственно на получателе.
Эта функциональность в основном реализована в методе PlayerManager
setMessageInterceptor()
. Это позволяет перехватывать входящие сообщения по типу и изменять их до того, как они достигнут внутреннего обработчика сообщений SDK. В этом разделе мы имеем дело с запросами LOAD
, где мы будем делать следующее:
- Прочтите входящий запрос
LOAD
и его пользовательскийcontentId
. - Выполните
GET
вызов нашего API, чтобы найти потоковый ресурс по егоcontentId
. - Измените запрос
LOAD
, указав URL-адрес потока. - Измените объект
MediaInformation
чтобы задать параметры типа потока. - Передайте запрос SDK на воспроизведение или отклоните команду, если мы не можем найти запрошенный носитель.
Предоставленный пример API демонстрирует приемы SDK для настройки общих задач приемника, при этом по-прежнему полагаясь в основном на готовый интерфейс.
Пример API
Откройте в браузере https://storage.googleapis.com/cpe-sample-media/content.json и просмотрите наш образец каталога видео. Содержимое включает URL-адреса изображений плакатов в формате PNG, а также потоки DASH и HLS. Потоки DASH и HLS указывают на демультиплексированные источники видео и аудио, хранящиеся во фрагментированных контейнерах mp4.
{
"bbb": {
"author": "The Blender Project",
"description": "Grumpy Bunny is grumpy",
"poster": "https://[...]/[...]/BigBuckBunny/images/screenshot1.png",
"stream": {
"dash": "https://[...]/[...]/BigBuckBunny/BigBuckBunny_master.mpd",
"hls": "https://[...]/[...]/BigBuckBunny/BigBuckBunny_master.m3u8",
"title": "Big Buck Bunny"
},
"fbb_ad": {
"author": "Google Inc.",
"description": "Introducing Chromecast. The easiest way to enjoy [...]",
"poster": "https://[...]/[...]/ForBiggerBlazes/images/screenshot8.png",
"stream": {
"dash": "https://[...]/[...]/ForBiggerBlazes/ForBiggerBlazes.mpd",
"hls": "https://[...]/[...]/ForBiggerBlazes/ForBiggerBlazes.m3u8",
"title": "For Bigger Blazes"
},
[...]
}
На следующем шаге мы сопоставим ключ каждой записи (например, bbb, fbb_ad
) с URL-адресом потока после вызова получателя с запросом LOAD
.
Перехватить запрос LOAD
На этом этапе мы создадим перехватчик нагрузки с функцией, которая выполняет запрос XHR
к размещенному файлу JSON
. Как только файл JSON
будет получен, мы проанализируем его содержимое и установим метаданные. В следующих разделах мы настроим параметры MediaInformation
, чтобы указать тип контента.
Добавьте следующий код в файл js/receiver.js
непосредственно перед вызовом context.start()
.
function makeRequest (method, url) {
return new Promise(function (resolve, reject) {
let xhr = new XMLHttpRequest();
xhr.open(method, url);
xhr.onload = function () {
if (this.status >= 200 && this.status < 300) {
resolve(JSON.parse(xhr.response));
} else {
reject({
status: this.status,
statusText: xhr.statusText
});
}
};
xhr.onerror = function () {
reject({
status: this.status,
statusText: xhr.statusText
});
};
xhr.send();
});
}
playerManager.setMessageInterceptor(
cast.framework.messages.MessageType.LOAD,
request => {
return new Promise((resolve, reject) => {
// Fetch content repository by requested contentId
makeRequest('GET', 'https://storage.googleapis.com/cpe-sample-media/content.json').then(function (data) {
let item = data[request.media.contentId];
if(!item) {
// Content could not be found in repository
reject();
} else {
// Add metadata
let metadata = new
cast.framework.messages.GenericMediaMetadata();
metadata.title = item.title;
metadata.subtitle = item.author;
request.media.metadata = metadata;
// Resolve request
resolve(request);
}
});
});
});
В следующем разделе будет описано, как настроить media
свойство запроса на загрузку для контента DASH.
Использование примера содержимого API DASH
Теперь, когда мы подготовили перехватчик нагрузки, мы укажем тип контента получателю. Эта информация предоставит получателю URL-адрес основного списка воспроизведения и тип MIME потока. Добавьте следующий код в файл js/receiver.js в Promise()
перехватчика LOAD
:
...
playerManager.setMessageInterceptor(
cast.framework.messages.MessageType.LOAD,
request => {
return new Promise((resolve, reject) => {
...
} else {
// Adjusting request to make requested content playable
request.media.contentUrl = item.stream.dash;
request.media.contentType = 'application/dash+xml';
...
}
});
});
});
После завершения этого шага вы можете перейти к тестированию и попробовать загрузить контент DASH. Если вы хотите вместо этого протестировать загрузку содержимого HLS, перейдите к следующему шагу.
Использование примера содержимого API HLS
Пример API включает в себя контент HLS, а также DASH. Помимо установки contentType
, как мы это делали на предыдущем шаге, запросу загрузки потребуются некоторые дополнительные свойства, чтобы использовать URL-адреса HLS примера API. Если получатель настроен для воспроизведения потоков HLS, ожидаемым типом контейнера по умолчанию является транспортный поток (TS). В результате получатель попытается открыть примеры потоков MP4 в формате TS, если будет изменено только свойство contentUrl
. В запросе на загрузку объект MediaInformation
должен быть изменен с помощью дополнительных свойств, чтобы получатель знал, что контент имеет тип MP4, а не TS. Добавьте следующий код в файл js/receiver.js в перехватчике нагрузки, чтобы изменить свойства contentUrl
и contentType
. Дополнительно добавьте свойства HlsSegmentFormat
и HlsVideoSegmentFormat
.
...
playerManager.setMessageInterceptor(
cast.framework.messages.MessageType.LOAD,
request => {
return new Promise((resolve, reject) => {
...
} else {
// Adjusting request to make requested content playable
request.media.contentUrl = item.stream.hls;
request.media.contentType = 'application/x-mpegurl';
request.media.hlsSegmentFormat = cast.framework.messages.HlsSegmentFormat.FMP4;
request.media.hlsVideoSegmentFormat = cast.framework.messages.HlsVideoSegmentFormat.FMP4;
...
}
});
});
});
Тестирование
Снова откройте инструмент управления и контроля (CaC) и установите идентификатор приложения на идентификатор приложения вашего ресивера. Выберите свое устройство с помощью кнопки Cast.
Перейдите на вкладку «Загрузить носитель». На этот раз удалите текст в поле «URL-адрес контента» рядом с кнопкой «Загрузить по контенту», что заставит наше приложение отправить запрос LOAD
, содержащий только ссылку contentId
на наши медиафайлы.
Предполагая, что с вашими изменениями в приемнике все работает нормально, перехватчик должен позаботиться о преобразовании объекта MediaInfo
во что-то, что SDK может воспроизводить на экране.
Нажмите кнопку «Загрузить по содержимому», чтобы проверить, правильно ли воспроизводится ваш медиафайл. Не стесняйтесь менять идентификатор контента на другой идентификатор в файле content.json .
10. Оптимизация для умных дисплеев
Интеллектуальные дисплеи — это устройства с сенсорными функциями, которые позволяют приложениям-приемникам поддерживать сенсорное управление.
В этом разделе объясняется, как оптимизировать приложение-приемник при запуске на интеллектуальных дисплеях и как настроить элементы управления проигрывателем.
Доступ к элементам управления пользовательского интерфейса
Доступ к объекту элементов управления пользовательского интерфейса для интеллектуальных дисплеев можно получить с помощью cast.framework.ui.Controls.GetInstance()
. Добавьте следующий код в файл js/receiver.js
над context.start()
:
...
// Optimizing for smart displays
const touchControls = cast.framework.ui.Controls.getInstance();
context.start();
Если вы не используете элемент <cast-media-player>, вам нужно будет установить touchScreenOptimizedApp
в CastReceiverOptions
. В этой кодовой лаборатории мы используем элемент <cast-media-player>.
context.start({ touchScreenOptimizedApp: true });
Кнопки управления по умолчанию назначаются каждому слоту на основе MetadataType
и MediaStatus.supportedMediaCommands
.
Управление видео
Для MetadataType.MOVIE
, MetadataType.TV_SHOW
и MetadataType.GENERIC
объект элементов управления пользовательского интерфейса для интеллектуальных дисплеев будет отображаться, как показано в примере ниже.
-
--playback-logo-image
-
MediaMetadata.subtitle
-
MediaMetadata.title
-
MediaStatus.currentTime
-
MediaInformation.duration
-
ControlsSlot.SLOT_SECONDARY_1
:ControlsButton.QUEUE_PREV
-
ControlsSlot.SLOT_PRIMARY_1
:ControlsButton.SEEK_BACKWARD_30
-
PLAY/PAUSE
-
ControlsSlot.SLOT_PRIMARY_2
:ControlsButton.SEEK_FORWARD_30
-
ControlsSlot.SLOT_SECONDARY_2
:ControlsButton.QUEUE_NEXT
Управление звуком
Для MetadataType.MUSIC_TRACK
объект элементов управления пользовательского интерфейса для интеллектуальных дисплеев будет отображаться, как показано ниже:
-
--playback-logo-image
-
MusicTrackMediaMetadata.albumName
-
MusicTrackMediaMetadata.title
-
MusicTrackMediaMetadata.albumArtist
-
MusicTrackMediaMetadata.images[0]
-
MediaStatus.currentTime
-
MediaInformation.duration
-
ControlsSlot.SLOT_SECONDARY_1
:ControlsButton.NO_BUTTON
-
ControlsSlot.SLOT_PRIMARY_1
:ControlsButton.QUEUE_PREV
-
PLAY/PAUSE
-
ControlsSlot.SLOT_PRIMARY_2
:ControlsButton.QUEUE_NEXT
-
ControlsSlot.SLOT_SECONDARY_2
:ControlsButton.NO_BUTTON
Обновление поддерживаемых мультимедийных команд
Объект UI Controls также определяет, отображается ли ControlsButton
на основе MediaStatus.supportedMediaCommands
.
Когда значение supportedMediaCommands
равно ALL_BASIC_MEDIA
, макет элемента управления по умолчанию будет отображаться, как показано ниже:
Когда значение supportedMediaCommands
равно ALL_BASIC_MEDIA | QUEUE_PREV | QUEUE_NEXT
, макет элемента управления по умолчанию будет отображаться, как показано ниже:
Когда значение supportMediaCommands равно PAUSE | QUEUE_PREV | QUEUE_NEXT
, макет элемента управления по умолчанию будет отображаться, как показано ниже:
Если текстовые дорожки доступны, кнопка субтитров всегда будет отображаться в SLOT_1
.
Чтобы динамически изменить значение supportedMediaCommands
после запуска контекста получателя, вы можете вызвать PlayerManager.setSupportedMediaCommands
, чтобы переопределить значение. Кроме того, вы можете добавить новую команду с помощью addSupportedMediaCommands
или удалить существующую команду с помощью removeSupportedMediaCommands
.
Настройка кнопок управления
Вы можете настроить элементы управления с помощью PlayerDataBinder
. Добавьте следующий код в файл js/receiver.js
под элементом touchControls, чтобы установить первый слот для элементов управления:
...
// Optimizing for smart displays
const touchControls = cast.framework.ui.Controls.getInstance();
const playerData = new cast.framework.ui.PlayerData();
const playerDataBinder = new cast.framework.ui.PlayerDataBinder(playerData);
playerDataBinder.addEventListener(
cast.framework.ui.PlayerDataEventType.MEDIA_CHANGED,
(e) => {
if (!e.value) return;
// Clear default buttons and re-assign
touchControls.clearDefaultSlotAssignments();
touchControls.assignButton(
cast.framework.ui.ControlsSlot.SLOT_PRIMARY_1,
cast.framework.ui.ControlsButton.SEEK_BACKWARD_30
);
});
context.start();
11. Реализация просмотра мультимедиа на умных дисплеях
Media Browse — это функция CAF Receiver, которая позволяет пользователям просматривать дополнительный контент на сенсорных устройствах. Чтобы реализовать это, вы будете использовать PlayerDataBinder
для установки пользовательского интерфейса BrowseContent
. Затем вы можете заполнить его с помощью BrowseItems
на основе содержимого, которое вы хотите отобразить.
Просмотр содержания
Ниже приведен пример пользовательского интерфейса BrowseContent
и его свойств:
-
BrowseContent.title
-
BrowseContent.items
Соотношение сторон
Используйте targetAspectRatio property
, чтобы выбрать наилучшее соотношение сторон для ваших изображений. SDK CAF Receiver SDK поддерживает три соотношения сторон: SQUARE_1_TO_1
, PORTRAIT_2_TO_3
, LANDSCAPE_16_TO_9
.
ОбзорЭлемент
Используйте BrowseItem
для отображения заголовка, подзаголовка, продолжительности и изображения для каждого элемента:
-
BrowseItem.image
-
BrowseItem.duration
-
BrowseItem.title
-
BrowseItem.subtitle
Установить данные просмотра мультимедиа
Вы можете предоставить список медиаконтента для просмотра, вызвав setBrowseContent
. Добавьте следующий код в файл js/receiver.js
под playerDataBinder
и в прослушиватель событий MEDIA_CHANGED
чтобы установить элементы просмотра с заголовком «Далее».
// Optimizing for smart displays
const touchControls = cast.framework.ui.Controls.getInstance();
const playerData = new cast.framework.ui.PlayerData();
const playerDataBinder = new cast.framework.ui.PlayerDataBinder(playerData);
...
let browseItems = getBrowseItems();
function getBrowseItems() {
let browseItems = [];
makeRequest('GET', 'https://storage.googleapis.com/cpe-sample-media/content.json')
.then(function (data) {
for (let key in data) {
let item = new cast.framework.ui.BrowseItem();
item.entity = key;
item.title = data[key].title;
item.subtitle = data[key].description;
item.image = new cast.framework.messages.Image(data[key].poster);
item.imageType = cast.framework.ui.BrowseImageType.MOVIE;
browseItems.push(item);
}
});
return browseItems;
}
let browseContent = new cast.framework.ui.BrowseContent();
browseContent.title = 'Up Next';
browseContent.items = browseItems;
browseContent.targetAspectRatio = cast.framework.ui.BrowseImageAspectRatio.LANDSCAPE_16_TO_9;
playerDataBinder.addEventListener(
cast.framework.ui.PlayerDataEventType.MEDIA_CHANGED,
(e) => {
if (!e.value) return;
....
// Media browse
touchControls.setBrowseContent(browseContent);
});
Нажатие на элемент просмотра мультимедиа активирует перехватчик LOAD
. Добавьте следующий код в перехватчик LOAD
, чтобы сопоставить request.media.contentId
с request.media.entity
из элемента просмотра мультимедиа:
playerManager.setMessageInterceptor(
cast.framework.messages.MessageType.LOAD,
request => {
...
// Map contentId to entity
if (request.media && request.media.entity) {
request.media.contentId = request.media.entity;
}
return new Promise((resolve, reject) => {
...
});
});
Вы также можете установить для объекта BrowseContent
значение null
, чтобы удалить пользовательский интерфейс просмотра мультимедиа.
12. Отладка приложений-приемников
Пакет Cast Receiver SDK предоставляет разработчикам еще один вариант простой отладки приложений-приемников с помощью API CastDebugLogger и сопутствующего инструмента управления и контроля (CaC) для сбора журналов.
Инициализация
Чтобы включить API, добавьте исходный сценарий CastDebugLogger
в файл index.html. Источник должен быть объявлен в теге <head> после объявления Cast Receiver SDK.
<head>
...
<script src="//www.gstatic.com/cast/sdk/libs/caf_receiver/v3/cast_receiver_framework.js"></script>
<!-- Cast Debug Logger -->
<script src="//www.gstatic.com/cast/sdk/libs/devtools/debug_layer/caf_receiver_logger.js"></script>
</head>
В js/receiver.js
вверху файла и под playerManager
добавьте следующий код, чтобы получить экземпляр CastDebugLogger
и включить регистратор:
const context = cast.framework.CastReceiverContext.getInstance();
const playerManager = context.getPlayerManager();
// Debug Logger
const castDebugLogger = cast.debug.CastDebugLogger.getInstance();
const LOG_TAG = 'MyAPP.LOG';
// Enable debug logger and show a 'DEBUG MODE' overlay at top left corner.
context.addEventListener(cast.framework.system.EventType.READY, () => {
if (!castDebugLogger.debugOverlayElement_) {
castDebugLogger.setEnabled(true);
}
});
Когда журнал отладки включен, на приемнике будет отображаться надпись DEBUG MODE
.
Записывать события игрока
Используя CastDebugLogger
вы можете легко регистрировать события игрока, которые запускаются CAF Receiver SDK, и использовать разные уровни регистрации для регистрации данных событий. Конфигурация loggerLevelByEvents
использует cast.framework.events.EventType
и cast.framework.events.category
, чтобы указать, какие события будут регистрироваться.
Добавьте следующий код под объявлением castDebugLogger
для регистрации событий CORE
проигрывателя или трансляции изменения mediaStatus
:
// Debug Logger
const castDebugLogger = cast.debug.CastDebugLogger.getInstance();
// Enable debug logger and show a 'DEBUG MODE' overlay at top left corner.
context.addEventListener(cast.framework.system.EventType.READY, () => {
if (!castDebugLogger.debugOverlayElement_) {
castDebugLogger.setEnabled(true);
}
});
// Set verbosity level for Core events.
castDebugLogger.loggerLevelByEvents = {
'cast.framework.events.category.CORE': cast.framework.LoggerLevel.INFO,
'cast.framework.events.EventType.MEDIA_STATUS': cast.framework.LoggerLevel.DEBUG
}
Сообщения журнала и пользовательские теги
API CastDebugLogger позволяет создавать сообщения журнала, которые отображаются на наложении отладки получателя разными цветами. Доступны следующие методы журналирования, перечисленные в порядке от высшего к низшему приоритету:
-
castDebugLogger.error(custom_tag, message);
-
castDebugLogger.warn(custom_tag, message);
-
castDebugLogger.info(custom_tag, message);
-
castDebugLogger.debug(custom_tag, message);
Для каждого метода журнала первым параметром является пользовательский тег. Это может быть любая идентифицирующая строка, которую вы считаете значимой. CastDebugLogger
использует теги для фильтрации журналов. Использование тегов подробно описано ниже. Второй параметр — это сообщение журнала .
Чтобы показать журналы в действии, добавьте журналы в перехватчик LOAD
.
playerManager.setMessageInterceptor(
cast.framework.messages.MessageType.LOAD,
request => {
castDebugLogger.info(LOG_TAG, 'Intercepting LOAD request');
// Map contentId to entity
if (request.media && request.media.entity) {
request.media.contentId = request.media.entity;
}
return new Promise((resolve, reject) => {
// Fetch content repository by requested contentId
makeRequest('GET', 'https://storage.googleapis.com/cpe-sample-media/content.json')
.then(function (data) {
let item = data[request.media.contentId];
if(!item) {
// Content could not be found in repository
castDebugLogger.error(LOG_TAG, 'Content not found');
reject();
} else {
// Adjusting request to make requested content playable
request.media.contentUrl = item.stream.dash;
request.media.contentType = 'application/dash+xml';
castDebugLogger.warn(LOG_TAG, 'Playable URL:', request.media.contentUrl);
// Add metadata
let metadata = new cast.framework.messages.MovieMediaMetadata();
metadata.metadataType = cast.framework.messages.MetadataType.MOVIE;
metadata.title = item.title;
metadata.subtitle = item.author;
request.media.metadata = metadata;
// Resolve request
resolve(request);
}
});
});
});
Вы можете контролировать, какие сообщения будут отображаться в наложении отладки, задав уровень журнала в loggerLevelByTags
для каждого настраиваемого тега. Например, включение пользовательского тега с уровнем журнала cast.framework.LoggerLevel.DEBUG
будет отображать все сообщения, добавленные с сообщениями об ошибках, предупреждениями, информацией и отладкой. Включение пользовательского тега с уровнем WARNING
будет отображать только сообщения об ошибках и предупреждения.
Конфигурация loggerLevelByTags
не является обязательной. Если пользовательский тег не настроен для его уровня ведения журнала, все сообщения журнала будут отображаться в наложении отладки.
Добавьте следующий код под регистратором событий CORE
:
// Set verbosity level for Core events.
castDebugLogger.loggerLevelByEvents = {
'cast.framework.events.category.CORE': cast.framework.LoggerLevel.INFO,
'cast.framework.events.EventType.MEDIA_STATUS': cast.framework.LoggerLevel.DEBUG
}
// Set verbosity level for custom tags.
castDebugLogger.loggerLevelByTags = {
[LOG_TAG]: cast.framework.LoggerLevel.DEBUG,
};
Наложение отладки
Cast Debug Logger обеспечивает наложение отладки на приемнике для отображения ваших пользовательских сообщений журнала на устройстве трансляции. Используйте showDebugLogs
для переключения наложения отладки и clearDebugLogs
для очистки сообщений журнала в наложении.
Добавьте следующий код, чтобы просмотреть наложение отладки на вашем приемнике.
context.addEventListener(cast.framework.system.EventType.READY, () => {
if (!castDebugLogger.debugOverlayElement_) {
// Enable debug logger and show a 'DEBUG MODE' overlay at top left corner.
castDebugLogger.setEnabled(true);
// Show debug overlay
castDebugLogger.showDebugLogs(true);
// Clear log messages on debug overlay
castDebugLogger.clearDebugLogs();
}
});
13. Поздравления
Теперь вы знаете, как создать собственное приложение веб-приемника с помощью Cast Web Receiver SDK.
Более подробную информацию см. в руководстве разработчика веб-приемника .