Как интегрироваться с аппаратными мультимедийными клавишами, настроить мультимедийные уведомления и многое другое.
Чтобы пользователи знали, что в данный момент воспроизводится в их браузере, и управляли этим, не возвращаясь на страницу, на которой оно было запущено, был введен API сеанса мультимедиа. Это позволяет веб-разработчикам настраивать этот опыт с помощью метаданных в пользовательских медиа-уведомлениях, медиа-событиях, таких как воспроизведение, пауза, поиск, отслеживание изменений, а также событиях видеоконференций, таких как отключение/включение звука микрофона, включение/выключение камеры и завершение разговора. Эти настройки доступны в нескольких контекстах, включая медиацентры на настольных компьютерах, мультимедийные уведомления на мобильных устройствах и даже на носимых устройствах. Я опишу эти настройки в этой статье.
Об API медиасеанса
API сеанса мультимедиа предоставляет несколько преимуществ и возможностей:
- Поддерживаются аппаратные медиа-ключи.
- Мультимедийные уведомления настраиваются на мобильном устройстве, настольном компьютере и подключенном носимом устройстве.
- Медиа-хаб доступен на рабочем столе.
- Элементы управления мультимедиа на экране блокировки доступны на ChromeOS и мобильных устройствах.
- Элементы управления окном «картинка в картинке» доступны для воспроизведения звука , видеоконференций и презентации слайдов .
- Доступна интеграция помощника на мобильном телефоне.
Несколько примеров проиллюстрируют некоторые из этих положений.
Пример 1. Если пользователи нажимают мультимедийную клавишу «Следующая дорожка» на своей клавиатуре, веб-разработчики могут обрабатывать это действие пользователя независимо от того, находится ли браузер на переднем плане или на заднем плане.
Пример 2. Если пользователи слушают подкаст в Интернете, когда экран их устройства заблокирован, они все равно могут нажать значок «перейти назад» на элементах управления мультимедиа на экране блокировки, чтобы веб-разработчики переместили время воспроизведения назад на несколько секунд.
Пример 3. Если у пользователей есть вкладки, воспроизводящие звук, они могут легко остановить воспроизведение из медиа-концентратора на рабочем столе, чтобы веб-разработчики имели возможность очистить свое состояние.
Пример 4. Если пользователи участвуют в видеозвонке, они могут нажать кнопку «переключить микрофон» в окне «Картинка в картинке», чтобы запретить веб-сайту получать данные с микрофона.
Все это делается через два разных интерфейса: интерфейс MediaSession
и интерфейс MediaMetadata
. Первый позволяет пользователям контролировать все, что воспроизводится. Во-вторых, как вы сообщаете MediaSession
, чем нужно управлять.
Для иллюстрации на изображении ниже показано, как эти интерфейсы связаны с конкретными элементами управления мультимедиа, в данном случае с медиа-уведомлением на мобильном устройстве.
Сообщите пользователям, что воспроизводится
Когда веб-сайт воспроизводит аудио или видео, пользователи автоматически получают мультимедийные уведомления либо в области уведомлений на мобильном телефоне, либо в медиа-центре на настольном компьютере. Браузер делает все возможное, чтобы отобразить соответствующую информацию, используя заголовок документа и самое большое изображение значка, которое он может найти. С помощью API сеанса мультимедиа можно настроить медиа-уведомление с использованием более обширных метаданных мультимедиа, таких как заголовок, имя исполнителя, название альбома и обложка, как показано ниже.
Chrome запрашивает «полный» фокус звука, чтобы отображать мультимедийные уведомления только в том случае, если продолжительность мультимедиа составляет не менее 5 секунд . Это гарантирует, что случайные звуки, такие как звон, не будут отображаться в уведомлениях.
// After media (video or audio) starts playing
await document.querySelector("video").play();
if ("mediaSession" in navigator) {
navigator.mediaSession.metadata = new MediaMetadata({
title: 'Never Gonna Give You Up',
artist: 'Rick Astley',
album: 'Whenever You Need Somebody',
artwork: [
{ src: 'https://via.placeholder.com/96', sizes: '96x96', type: 'image/png' },
{ src: 'https://via.placeholder.com/128', sizes: '128x128', type: 'image/png' },
{ src: 'https://via.placeholder.com/192', sizes: '192x192', type: 'image/png' },
{ src: 'https://via.placeholder.com/256', sizes: '256x256', type: 'image/png' },
{ src: 'https://via.placeholder.com/384', sizes: '384x384', type: 'image/png' },
{ src: 'https://via.placeholder.com/512', sizes: '512x512', type: 'image/png' },
]
});
// TODO: Update playback state.
}
Когда воспроизведение закончится, нет необходимости «освобождать» медиа-сессию, поскольку уведомление автоматически исчезнет. Имейте в виду, что navigator.mediaSession.metadata
будет использоваться при следующем запуске воспроизведения. Вот почему важно обновлять его при изменении источника воспроизведения мультимедиа, чтобы в медиа-уведомлении отображалась соответствующая информация.
Есть несколько вещей, которые следует отметить относительно метаданных мультимедиа.
- Массив изображений уведомлений поддерживает URL-адреса больших двоичных объектов и URL-адреса данных.
- Если обложка не определена и имеется изображение значка (указанное с помощью
<link rel=icon>
) желаемого размера, мультимедийные уведомления будут использовать его. - Целевой размер изображения уведомления в Chrome для Android —
512x512
. Для бюджетных устройств это256x256
. - Атрибут
title
HTML-элемента мультимедиа используется в виджете «Сейчас играет» macOS. - Если медиа-ресурс встроен (например, в iframe), информация API сеанса мультимедиа должна быть установлена из встроенного контекста. См. фрагмент ниже.
<iframe id="iframe">
<video>...</video>
</iframe>
<script>
iframe.contentWindow.navigator.mediaSession.metadata = new MediaMetadata({
title: 'Never Gonna Give You Up',
...
});
</script>
Вы также можете добавить в метаданные мультимедиа информацию об отдельных главах, например название раздела, его временную метку и изображение снимка экрана. Это позволяет пользователям перемещаться по содержимому мультимедиа.
navigator.mediaSession.metadata = new MediaMetadata({
// title, artist, album, artwork, ...
chapterInfo: [{
title: 'Chapter 1',
startTime: 0,
artwork: [
{ src: 'https://via.placeholder.com/128', sizes: '128x128', type: 'image/png' },
{ src: 'https://via.placeholder.com/512', sizes: '512x512', type: 'image/png' },
]
}, {
title: 'Chapter 2',
startTime: 42,
artwork: [
{ src: 'https://via.placeholder.com/128', sizes: '128x128', type: 'image/png' },
{ src: 'https://via.placeholder.com/512', sizes: '512x512', type: 'image/png' },
]
}]
});
Позвольте пользователям контролировать, что воспроизводится
Действие медиа-сеанса — это действие (например, «воспроизведение» или «пауза»), которое веб-сайт может обрабатывать для пользователей, когда они взаимодействуют с текущим воспроизведением мультимедиа. Действия аналогичны событиям и работают так же. Как и события, действия реализуются путем установки обработчиков соответствующего объекта, в данном случае экземпляра MediaSession
. Некоторые действия запускаются, когда пользователи нажимают кнопки на гарнитуре, другом удаленном устройстве, клавиатуре или взаимодействуют с мультимедийным уведомлением.
Поскольку некоторые действия медиа-сеанса могут не поддерживаться, при их настройке рекомендуется использовать блок try…catch
.
const actionHandlers = [
['play', () => { /* ... */ }],
['pause', () => { /* ... */ }],
['previoustrack', () => { /* ... */ }],
['nexttrack', () => { /* ... */ }],
['stop', () => { /* ... */ }],
['seekbackward', (details) => { /* ... */ }],
['seekforward', (details) => { /* ... */ }],
['seekto', (details) => { /* ... */ }],
/* Video conferencing actions */
['togglemicrophone', () => { /* ... */ }],
['togglecamera', () => { /* ... */ }],
['hangup', () => { /* ... */ }],
/* Presenting slides actions */
['previousslide', () => { /* ... */ }],
['nextslide', () => { /* ... */ }],
];
for (const [action, handler] of actionHandlers) {
try {
navigator.mediaSession.setActionHandler(action, handler);
} catch (error) {
console.log(`The media session action "${action}" is not supported yet.`);
}
}
Отключить обработчик действий медиа-сеанса так же просто, как установить для него значение null
.
try {
// Unset the "nexttrack" action handler at the end of a playlist.
navigator.mediaSession.setActionHandler('nexttrack', null);
} catch (error) {
console.log(`The media session action "nexttrack" is not supported yet.`);
}
После установки обработчики действий медиа-сеанса будут сохраняться во время воспроизведения мультимедиа. Это похоже на шаблон прослушивателя событий, за исключением того, что обработка события означает, что браузер прекращает выполнять какое-либо поведение по умолчанию и использует это как сигнал о том, что веб-сайт поддерживает мультимедийное действие. Следовательно, элементы управления действиями мультимедиа не будут отображаться, если не установлен правильный обработчик действий.
Воспроизведение / пауза
Действие "play"
указывает, что пользователь хочет возобновить воспроизведение мультимедиа, а "pause"
указывает на желание временно остановить его.
Значок «воспроизведение/пауза» всегда отображается в медиа-уведомлении, а соответствующие медиа-события обрабатываются браузером автоматически. Чтобы переопределить их поведение по умолчанию, обработайте действия мультимедиа «воспроизведение» и «пауза», как показано ниже.
Браузер может считать, что веб-сайт не воспроизводит мультимедиа, например, при поиске или загрузке. В этом случае переопределите это поведение, установив для navigator.mediaSession.playbackState
значение "playing"
или "paused"
чтобы обеспечить синхронизацию пользовательского интерфейса веб-сайта с элементами управления мультимедийными уведомлениями.
const video = document.querySelector('video');
navigator.mediaSession.setActionHandler('play', async () => {
// Resume playback
await video.play();
});
navigator.mediaSession.setActionHandler('pause', () => {
// Pause active playback
video.pause();
});
video.addEventListener('play', () => {
navigator.mediaSession.playbackState = 'playing';
});
video.addEventListener('pause', () => {
navigator.mediaSession.playbackState = 'paused';
});
Предыдущий трек
Действие "previoustrack"
указывает, что пользователь хочет либо начать текущее воспроизведение мультимедиа с начала, если воспроизведение мультимедиа имеет понятие начала, либо перейти к предыдущему элементу в списке воспроизведения, если воспроизведение мультимедиа имеет понятие списка воспроизведения.
navigator.mediaSession.setActionHandler('previoustrack', () => {
// Play previous track.
});
Следующий трек
Действие "nexttrack"
указывает, что пользователь хочет переместить воспроизведение мультимедиа к следующему элементу в списке воспроизведения, если воспроизведение мультимедиа имеет понятие списка воспроизведения.
navigator.mediaSession.setActionHandler('nexttrack', () => {
// Play next track.
});
Останавливаться
Действие "stop"
указывает, что пользователь хочет остановить воспроизведение мультимедиа и при необходимости очистить состояние.
navigator.mediaSession.setActionHandler('stop', () => {
// Stop playback and clear state if appropriate.
});
Искать назад/вперед
Действие "seekbackward"
указывает, что пользователь хочет переместить время воспроизведения мультимедиа назад на короткий период, тогда как "seekforward"
указывает на желание переместить время воспроизведения мультимедиа вперед на короткий период. В обоих случаях короткий период означает несколько секунд.
Значение seekOffset
, предоставленное в обработчике действий, представляет собой время в секундах, на которое нужно переместить время воспроизведения мультимедиа. Если оно не предусмотрено (например, undefined
), то следует использовать разумное время (например, 10-30 секунд).
const video = document.querySelector('video');
const defaultSkipTime = 10; /* Time to skip in seconds by default */
navigator.mediaSession.setActionHandler('seekbackward', (details) => {
const skipTime = details.seekOffset || defaultSkipTime;
video.currentTime = Math.max(video.currentTime - skipTime, 0);
// TODO: Update playback state.
});
navigator.mediaSession.setActionHandler('seekforward', (details) => {
const skipTime = details.seekOffset || defaultSkipTime;
video.currentTime = Math.min(video.currentTime + skipTime, video.duration);
// TODO: Update playback state.
});
Ищите определенное время
Действие "seekto"
указывает, что пользователь хочет переместить время воспроизведения мультимедиа на определенное время.
Значение seekTime
, указанное в обработчике действий, представляет собой время в секундах, на которое необходимо переместить время воспроизведения мультимедиа.
Логическое значение fastSeek
, предоставленное в обработчике действия, истинно, если действие вызывается несколько раз как часть последовательности и это не последний вызов в этой последовательности.
const video = document.querySelector('video');
navigator.mediaSession.setActionHandler('seekto', (details) => {
if (details.fastSeek && 'fastSeek' in video) {
// Only use fast seek if supported.
video.fastSeek(details.seekTime);
return;
}
video.currentTime = details.seekTime;
// TODO: Update playback state.
});
Установить позицию воспроизведения
Точное отображение позиции воспроизведения мультимедиа в уведомлении так же просто, как установка состояния позиции в подходящее время, как показано ниже. Состояние позиции представляет собой комбинацию скорости воспроизведения мультимедиа, продолжительности и текущего времени.
Продолжительность должна быть предусмотрена и положительна. Позиция должна быть положительной и меньше продолжительности. Скорость воспроизведения должна быть больше 0.
const video = document.querySelector('video');
function updatePositionState() {
if ('setPositionState' in navigator.mediaSession) {
navigator.mediaSession.setPositionState({
duration: video.duration,
playbackRate: video.playbackRate,
position: video.currentTime,
});
}
}
// When video starts playing, update duration.
await video.play();
updatePositionState();
// When user wants to seek backward, update position.
navigator.mediaSession.setActionHandler('seekbackward', (details) => {
/* ... */
updatePositionState();
});
// When user wants to seek forward, update position.
navigator.mediaSession.setActionHandler('seekforward', (details) => {
/* ... */
updatePositionState();
});
// When user wants to seek to a specific time, update position.
navigator.mediaSession.setActionHandler('seekto', (details) => {
/* ... */
updatePositionState();
});
// When video playback rate changes, update position state.
video.addEventListener('ratechange', (event) => {
updatePositionState();
});
Сбросить состояние позиции так же просто, как установить его на null
.
// Reset position state when media is reset.
navigator.mediaSession.setPositionState(null);
Действия видеоконференции
Когда пользователь помещает свой видеовызов в окно «Картинка в картинке», браузер может отображать элементы управления микрофоном и камерой, а также для завершения вызова. Когда пользователь нажимает на них, веб-сайт обрабатывает их с помощью действий видеоконференции, описанных ниже. Пример см. в примере видеоконференции .
Переключить микрофон
Действие "togglemicrophone"
указывает, что пользователь хочет отключить или включить микрофон. Метод setMicrophoneActive(isActive)
сообщает браузеру, считает ли веб-сайт в данный момент микрофон активным.
let isMicrophoneActive = false;
navigator.mediaSession.setActionHandler('togglemicrophone', () => {
if (isMicrophoneActive) {
// Mute the microphone.
} else {
// Unmute the microphone.
}
isMicrophoneActive = !isMicrophoneActive;
navigator.mediaSession.setMicrophoneActive(isMicrophoneActive);
});
Переключить камеру
Действие "togglecamera"
указывает, что пользователь хочет включить или выключить активную камеру. Метод setCameraActive(isActive)
указывает, считает ли браузер веб-сайт активным.
let isCameraActive = false;
navigator.mediaSession.setActionHandler('togglecamera', () => {
if (isCameraActive) {
// Disable the camera.
} else {
// Enable the camera.
}
isCameraActive = !isCameraActive;
navigator.mediaSession.setCameraActive(isCameraActive);
});
Вешать трубку
Действие "hangup"
указывает на то, что пользователь хочет завершить вызов.
navigator.mediaSession.setActionHandler('hangup', () => {
// End the call.
});
Демонстрация действий со слайдами
Когда пользователь помещает презентацию своих слайдов в окно «Картинка в картинке», браузер может отображать элементы управления для навигации по слайдам. Когда пользователь нажимает на них, веб-сайт обрабатывает их через API сеанса мультимедиа. Пример см. в примере «Представление слайдов» .
Предыдущий слайд
Действие "previousslide"
указывает, что пользователь хочет вернуться к предыдущему слайду при представлении слайдов.
navigator.mediaSession.setActionHandler('previousslide', () => {
// Show previous slide.
});
Поддержка браузера
Следующий слайд
Действие "nextslide"
указывает, что пользователь хочет перейти к следующему слайду при представлении слайдов.
navigator.mediaSession.setActionHandler('nextslide', () => {
// Show next slide.
});
Поддержка браузера
Образцы
Ознакомьтесь с некоторыми образцами Media Session, в которых представлены работы Blender Foundation и Яна Моргенштерна .
Ресурсы
- Спецификация медиа-сессии: wicg.github.io/mediasession
- Проблемы со спецификациями: github.com/WICG/mediasession/issues .
- Ошибки Chrome: crbug.com