Возможно, сейчас вы задумались над тем, зачем вообще нужен какой-то другой плеер? Ответ на этот вопрос довольно прост: Lightning по умолчанию поставляется с поддержкой обычного воспроизведения HTML5. Это означает, что у вас есть возможность воспроизводить, например, простые файлы mp4. Однако, если предстоит более сложная задача воспроизведения видео с применением технологий HLS, MPEG-Dash и, конечно же, DRM, потребуется другой плеер. Lightning просто использует тег видео для воспроизведения, поэтому в текущем состоянии он не сможет поддерживать подобные сценарии использования.
Чтобы успешно справляться с такими случаями, придется интегрировать внешний плеер. Я рекомендую ShakaPlayer, который хорошо зарекомендовал себя на SmartTV и обладает широким диапазоном настроек.
Шаг 1. Начальная настройка
Для начала понадобится готовый проект Lightning, в котором можно писать код. Если у вас уже есть готовый проект, можете перейти к шагу 2.
Чтобы создать проект Lightning, нужно сначала установить Lightning CLI:
npm install -g @lightningjs/cli
После установки Lightning CLI создадим проект с помощью следующей команды:
lng create
Вы можете пройтись по опциям, предоставляемым CLI, и определить, какие настройки вам больше нравится. Данное руководство не предписывает, какие именно опции нужно выбрать. Я выбрал Typescript, но вы решайте сами, что вам подходит.
После создания проекта установите модули node
, запустив npm i
в командной строке.
Теперь, когда проект настроен, перейдем к следующему шагу по запуску ShakaPlayer в приложении Lightning.
Шаг 2. Создание страницы Player
Поскольку плееры обычно не запускаются на главной странице приложений, необходимо создать специальную страницу для плеера и включить в приложение маршрутизацию, используя встроенный в Lightning маршрутизатор (Router). Мы не будем рассматривать все шаги по созданию маршрутизатора. Рекомендую следовать шагам, определенным в документации Lightning.
Итак, создаем страницу Player. Она должна быть заполнена всеми компонентами пользовательского интерфейса. Мы же ограничимся двумя простыми элементами.
- Элемент-обертка, содержащим все элементы UI. Мы будем использовать этот элемент для плавного показа и скрытия интерфейса.
- Кнопка Play/Pause, которая будет реализована внутри обертки. Она нужна для переключения состояния воспроизведения.
В обертку должны быть помещены и другие UI-элементы, но в данной статье мы ограничимся тем, что указано выше.
import {Lightning} from "@lightningjs/sdk";
import {RouterPage} from "./RouterPage"; // Определяет isPage:true в TypeConfig.
export default class Player extends Lightning.Component<Lightning.Component.TemplateSpecLoose, RouterPage> {
static override _template(): Lightning.Component.Template<Lightning.Component.TemplateSpecLoose> {
return {
Wrapper: {
alpha: 1
PlayPause: {
mount: 0.5,
x: 1920 / 2,
y: 1080 / 2,
rect: true,
w: 250,
h: 250,
color: 0x00000000,
Background: {
rect: true,
w: 250,
h: 250,
color: 0xffababab,
shader: {
type: Lightning.shaders.RoundedRectangle,
radius: 125
},
},
Text: {
mount: 0.5,
x: 125,
y: 125,
text: {
textColor: 0xffffffff,
text: 'Pause'
}
}
}
}
}
}
}
Шаг 3. Установка и импортирование ShakaPlayer
Это довольно простой шаг. Есть несколько способов получить ссылку на ShakaPlayer в проекте.
- Использовать ссылку на CDN и включить этот скрипт в
index.html
(но в контексте Metrological Appstore у нас не будет доступа к этому индексу). - Внедрить код, вручную создав тег
script
с помощью JavaScript (это также не лучший вариант для Metrological). - Включить в виде пакета NPM, который будет встроен в файлы приложения.
Последний метод предпочтительнее первых двух, поскольку позволит Metrological лучше управлять ресурсами, используемыми приложением в контексте их Appstore.
Начнем с установки пакета из NPM (вы можете применить любой менеджер пакетов):
npm i shaka-player
Затем импортируем ссылку ShakaPlayer в верхней части страницы Player:
import shaka from 'shaka-player';
Шаг 4. Подключение Lightning к ShakaPlayer
Lightning имеет собственную интеграцию с воспроизведением видео, так что стоит воспользоваться этой особенностью. К счастью, с Lightning сделать это очень просто. Начнем с настройки элемента VideoPlayer для работы со страницей Player:
import {VideoPlayer} from "@lightningjs/sdk";
override _firstActive() {
VideoPlayer.consumer(this);
VideoPlayer.loader(this._loadPlayback);
VideoPlayer.unloader(this._unloadPlayback);
}
Приведенный выше код выполняет три функции для VideoPlayer. Первая, consumer
, предназначена для того, чтобы позволить странице Player обрабатывать события воспроизведения (описание можно найти здесь, в рамках туториала мы не будем это реализовывать). Функции loader
и unloader
используются для обработки воспроизведения с помощью ShakaPlayer. Реализуем их прямо сейчас. Приведенный ниже пример показывает пример простых настроек.
_setupShakaPlayer (videoEl: HTMLVideoElement) {
videoEl.autoplay = true;
this._player = new shaka.Player(videoEl);
}
async _loadPlayback (url: string, videoEl: HTMLVideoElement) {
this._setupShakaPlayer(videoEl);
await this._player.load(url);
}
async _unloadPlayback () {
await this._player.unload();
}
Мы просто передаем элемент видео и URL воспроизведения вновь созданному экземпляру ShakaPlayer. Как видите, мы установили videoEl.autoplay = true
для немедленного запуска воспроизведения. Если вам не нужна эта функция, можно убрать autoplay
. Когда видео выгружается, просим ShakaPlayer выгрузиться тоже.
Шаг 5. Запуск воспроизведения
Мы почти у цели! Следующий шаг очень прост. Поскольку ShakaPlayer настроен для работы с объектом VideoPlayer программы Lightning, дальше нужно лишь отдать команду VideoPlayer, чтобы он начал воспроизводить видео. Для этого воспользуемся функцией open
, которую можно вызвать, например, из метода жизненного цикла _active
:
override _active() {
VideoPlayer.open('https://demo.unified-streaming.com/k8s/features/stable/video/tears-of-steel/tears-of-steel.ism/.mpd')
}
В этом примере я использовал поток MPEG-Dash без DRM, который взял со страницы демонстрационных URL на платформе Unified Streaming. Если вы применили тот же код и открыли страницу Player в своем браузере, у вас должно начаться воспроизведение!
Шаг 6. Воспроизведение и пауза
Часть работы, посвященная воспроизведению видео, завершена. Это означает, что можно приступать к дальнейшей реализации. Хочу привести небольшой пример того, как можно реализовать рабочую кнопку Play/Pause.
В настройках страницы Player уже создан элемент пользовательского интерфейса для кнопки Play/Pause. Теперь надо подключить к нему обработчики событий, чтобы нажатие на кнопку взаимодействовало с плеером. Начнем с выделения кнопки Play/Pause в отдельный компонент Lightning, чтобы она смогла принимать фокус, и добавим несколько методов для изменения состояния кнопки:
// Компонент страницы Player. static override _template(): Lightning.Component.Template<Lightning.Component.TemplateSpecLoose> { return { Wrapper: { alpha: 1, PlayPause: { type: PlayPause } } } } override _getFocused(): Lightning.Component { return this.tag('PlayPause'); } // Новый компонент PlayPause. import {Lightning} from "@lightningjs/sdk"; export default class PlayPause extends Lightning.Component { // @ts-ignore _isPlaying: boolean override _setup() { this._isPlaying = true; } static override _template () { return { mount: 0.5, x: 1920 / 2, y: 1080 / 2, rect: true, w: 250, h: 250, color: 0x00000000, Background: { rect: true, w: 250, h: 250, color: 0xffababab, shader: { type: Lightning.shaders.RoundedRectangle, radius: 125 }, }, Text: { mount: 0.5, x: 125, y: 125, text: { textColor: 0xffffffff, text: 'Pause' } } } } set isPlaying(isPlaying: boolean) { this._isPlaying = isPlaying; this.tag('Text').patch({ text: { text: isPlaying ? 'Pause' : 'Play' } }); } get isPlaying(): boolean { return this._isPlaying; } }
Приведенный выше код выделяет кнопку в отдельный компонент и добавляет метод isPlaying
. Мы будем использовать его для обозначения состояния воспроизведения и паузы, что обеспечит смену текста кнопки с “Play” на “Pause” и наоборот. В реальном сценарии использования вы, скорее всего, замените эти слова иконками воспроизведения и паузы.
Теперь, когда кнопка настроена, можно прикрепить ее к обработчику события для кнопки “Enter”. Затем в зависимости от состояния кнопки мы будем либо приостанавливать, либо возобновлять воспроизведение видео:
override _handleEnter () {
const button = this.tag('PlayPause');
button.isPlaying = !button.isPlaying;
button.isPlaying ? VideoPlayer.play() : VideoPlayer.pause();
}
Мы стремительно приближаемся к завершению! После добавления вышеописанной реализации нажатие кнопки “OK” на TV-Remote (или “Enter” на клавиатуре) обеспечивает переключение между состояниями воспроизведения и паузы. Плеер готов к работе.
Шаг 7. Следующие этапы реализации
Здесь была описана лишь минимальная часть реализации того, что необходимо для плеера. Вам понадобится полноценный пользовательский интерфейс, который можно показывать и скрывать, элементы управления перемоткой назад и вперед и, возможно, DRM. Но основа у вас уже есть — вы научились использовать ShakaPlayer с Lightning.
Для совершения следующих шагов стоит ознакомиться с документацией ShakaPlayer. Это даст более четкое понимание того, как работать с различными событиями, поступающими от плеера (например, с обновлением времени и ошибками).
Использованный здесь код доступен на Github.
Читайте также:
- Как создать многопользовательский чат с помощью WebSocket за 10 минут
- Повышение дизайнерских навыков: советы и упражнения
- Как сократить время начальной загрузки веб-приложения
Читайте нас в Telegram, VK и Дзен
Перевод статьи Matthijs Langendijk: Using ShakaPlayer with LightningJS