Personaliza las notificaciones multimedia y los controles de reproducción con la API de Media Session

Cómo realizar la integración con las teclas multimedia de hardware, personalizar las notificaciones multimedia y mucho más

François Beaufort
François Beaufort

Se introdujo la API de Media Session para que los usuarios sepan qué se está reproduciendo en ese momento en su navegador y lo controlen sin regresar a la página que lo inició. Permite que los desarrolladores web personalicen esta experiencia a través de metadatos en notificaciones multimedia personalizadas, eventos multimedia como reproducir, pausar, buscar, cambiar de pista y eventos de videoconferencia, como silenciar/activar el sonido del micrófono, encender o apagar la cámara, y colgar. Estas personalizaciones están disponibles en varios contextos, incluidos los centros de medios para computadoras, las notificaciones multimedia en dispositivos móviles y también en dispositivos wearable. Describiré estas personalizaciones en este artículo.

Capturas de pantalla de los contextos de las sesiones multimedia
Centro de contenido multimedia en computadoras, notificaciones multimedia en dispositivos móviles y dispositivos wearable.

Información acerca de la API de Media Session

La API de Media session ofrece varios beneficios y funciones:

  • Se admiten las teclas multimedia de hardware.
  • Las notificaciones de contenido multimedia se personalizan en dispositivos móviles, computadoras de escritorio y dispositivos wearable vinculados.
  • El centro de contenido multimedia está disponible para computadoras de escritorio.
  • Los controles multimedia de la pantalla de bloqueo están disponibles en ChromeOS y dispositivos móviles.
  • Los controles de la ventana de pantalla en pantalla están disponibles para la reproducción de audio, videoconferencias y presentación de diapositivas.
  • Está disponible la integración del Asistente en dispositivos móviles.

Navegadores compatibles

  • 73
  • 79
  • 82
  • 15

Origen

Algunos ejemplos ilustrarán algunos de estos puntos.

Ejemplo 1: Si los usuarios presionan la tecla multimedia "pista siguiente" del teclado, los desarrolladores web pueden controlar esta acción del usuario independientemente de que el navegador esté en primer plano o en segundo plano.

Ejemplo 2: Si los usuarios escuchan un podcast en la Web mientras la pantalla del dispositivo está bloqueada, pueden presionar el ícono de "retroceder" en los controles multimedia de la pantalla de bloqueo para que los desarrolladores web retrocedan el tiempo de reproducción unos segundos.

Ejemplo 3: Si los usuarios tienen pestañas que reproducen audio, pueden detener fácilmente la reproducción desde el centro de contenido multimedia en el escritorio para que los desarrolladores web tengan la oportunidad de borrar su estado.

Ejemplo 4: Si los usuarios están en una videollamada, pueden presionar el control para activar o desactivar el micrófono en la ventana Pantalla en pantalla para evitar que el sitio web reciba datos del micrófono.

Todo esto se realiza a través de dos interfaces diferentes: la interfaz MediaSession y la interfaz MediaMetadata. El primero permite a los usuarios controlar lo que se está reproduciendo. La segunda es la forma en que le indicas a MediaSession qué debe controlarse.

A modo de ejemplo, la siguiente imagen muestra cómo se relacionan estas interfaces con controles multimedia específicos, en este caso, una notificación multimedia en dispositivos móviles.

Ilustración de interfaces de sesiones multimedia.
Anatomía de una notificación de contenido multimedia en dispositivos móviles.

Permite que los usuarios sepan qué se está reproduciendo

Cuando un sitio web reproduce audio o video, los usuarios reciben automáticamente notificaciones multimedia, ya sea en la bandeja de notificaciones de un dispositivo móvil o en el centro de contenido multimedia para computadoras de escritorio. El navegador hace todo lo posible para mostrar la información adecuada mediante el título del documento y la imagen de ícono más grande que pueda encontrar. Con la API de Media Session, es posible personalizar la notificación multimedia con algunos metadatos de contenido multimedia más completos, como el título, el nombre del artista, el nombre del álbum y el material gráfico, como se muestra a continuación.

Chrome solicita el foco de audio "completo" para mostrar notificaciones multimedia solo cuando la duración del contenido multimedia es de al menos 5 segundos. Esto garantiza que los sonidos imprevistos, como los golpes, no muestren notificaciones.

// 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.
}

Cuando finalice la reproducción, no es necesario "liberar" la sesión multimedia, ya que la notificación desaparecerá automáticamente. Ten en cuenta que se usará navigator.mediaSession.metadata cuando se inicie la próxima reproducción. Por eso, es importante actualizarla cuando cambie la fuente de reproducción de contenido multimedia para asegurarte de que se muestre información relevante en la notificación multimedia.

Debes tener en cuenta algunos aspectos sobre los metadatos de contenido multimedia.

  • El array de material gráfico de la notificación admite URLs de BLOB y URLs de datos.
  • Si no se define ningún material gráfico y hay una imagen de ícono (especificada con <link rel=icon>) con un tamaño deseable, las notificaciones multimedia la usarán.
  • El tamaño del material gráfico de las notificaciones en Chrome para Android es 512x512. Para dispositivos de baja gama, es 256x256.
  • El atributo title del elemento HTML multimedia se usa en el widget de macOS "Está sonando".
  • Si el recurso multimedia está incorporado (por ejemplo, en un iframe), la información de la API de Media Session debe configurarse desde el contexto incorporado. Consulta el fragmento que aparece a continuación.
<iframe id="iframe">
  <video>...</video>
</iframe>
<script>
  iframe.contentWindow.navigator.mediaSession.metadata = new MediaMetadata({
    title: 'Never Gonna Give You Up',
    ...
  });
</script>

También puedes agregar información individual del capítulo, como el título de la sección, su marca de tiempo y una imagen de captura de pantalla a los metadatos de contenido multimedia. De esta manera, los usuarios pueden navegar por el contenido de ese contenido multimedia.

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' },
    ]
  }]
});
Información del capítulo que se muestra en una notificación multimedia de ChromeOS.
Notificación multimedia con capítulos en ChromeOS.

Permitir que los usuarios controlen lo que se está reproduciendo

Una acción de sesión multimedia es una acción (por ejemplo, "reproducir" o "pausar") que un sitio web puede controlar para los usuarios cuando interactúan con la reproducción de contenido multimedia actual. Las acciones son análogas a los eventos y funcionan de la misma manera. Al igual que los eventos, las acciones se implementan configurando controladores en un objeto apropiado, en este caso, una instancia de MediaSession. Algunas acciones se activan cuando los usuarios presionan botones de auriculares, otro dispositivo remoto, un teclado o interactúan con una notificación multimedia.

Captura de pantalla de una notificación multimedia en Windows 10.
Notificación multimedia personalizada en Windows 10.

Debido a que es posible que no se admitan algunas acciones de la sesión multimedia, se recomienda usar un bloque try…catch cuando las configures.

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.`);
  }
}

Desconfigurar un controlador de acciones de la sesión multimedia es tan fácil como configurarlo como 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.`);
}

Una vez configurados, se conservarán los controladores de acciones de la sesión multimedia durante las reproducciones de contenido multimedia. Esto es similar al patrón del objeto de escucha de eventos, con la excepción de que controlar un evento significa que el navegador deja de realizar cualquier comportamiento predeterminado y lo usa como un indicador de que el sitio web admite la acción multimedia. Por lo tanto, no se mostrarán los controles de acciones multimedia, a menos que se configure el controlador de acciones adecuado.

Captura de pantalla del widget Está sonando en macOS Big Sur.
Widget de Está sonando en macOS Big Sur.

Reproducir / pausar

La acción "play" indica que el usuario quiere reanudar la reproducción de contenido multimedia, mientras que "pause" indica un deseo de detenerla temporalmente.

El ícono de "reproducir/pausar" siempre se muestra en una notificación multimedia, y el navegador controla automáticamente los eventos multimedia relacionados. Para anular su comportamiento predeterminado, controla las acciones multimedia "reproducir" y "pausar" como se muestra a continuación.

El navegador puede considerar que un sitio web no está reproduciendo contenido multimedia cuando, por ejemplo, lo busca o carga. En este caso, anula este comportamiento configurando navigator.mediaSession.playbackState en "playing" o "paused" para asegurarte de que la IU del sitio web permanezca sincronizada con los controles de notificaciones multimedia.

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';
});

Pista anterior

La acción "previoustrack" indica que el usuario quiere iniciar la reproducción de contenido multimedia actual desde el principio si esta tiene una noción de principio, o bien pasar al elemento anterior de la lista de reproducción si la reproducción de contenido multimedia tiene una noción de lista de reproducción.

navigator.mediaSession.setActionHandler('previoustrack', () => {
  // Play previous track.
});

Pista siguiente

La acción "nexttrack" indica que el usuario quiere mover la reproducción de contenido multimedia al siguiente elemento de la playlist si esta tiene una noción de una playlist.

navigator.mediaSession.setActionHandler('nexttrack', () => {
  // Play next track.
});

Detener

La acción "stop" indica que el usuario desea detener la reproducción de contenido multimedia y borrar el estado si corresponde.

navigator.mediaSession.setActionHandler('stop', () => {
  // Stop playback and clear state if appropriate.
});

Retroceder / adelante

La acción "seekbackward" indica que el usuario quiere retroceder el tiempo de reproducción de contenido multimedia un corto período, mientras que "seekforward" indica que desea avanzar un período breve. En ambos casos, un período corto significa unos pocos segundos.

El valor seekOffset que se proporciona en el controlador de acciones es el tiempo en segundos en el que se mueve el tiempo de reproducción de contenido multimedia. Si no se proporciona (por ejemplo, undefined), debes usar un tiempo razonable (por ejemplo, de 10 a 30 segundos).

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.
});

Ir a una hora específica

La acción "seekto" indica que el usuario quiere mover el tiempo de reproducción de contenido multimedia a un momento específico.

El valor seekTime que se proporciona en el controlador de acciones es el tiempo en segundos al que se debe mover el tiempo de reproducción de contenido multimedia.

El valor booleano fastSeek que se proporciona en el controlador de acciones es verdadero si se llama varias veces a la acción como parte de una secuencia y esta no es la última llamada de esa secuencia.

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.
});

Cómo configurar la posición de reproducción

Mostrar con precisión la posición de reproducción de contenido multimedia en una notificación es tan simple como configurar el estado de la posición en un momento adecuado, como se muestra a continuación. El estado de posición es una combinación de la velocidad de reproducción de contenido multimedia, la duración y la hora actual.

Captura de pantalla de los controles multimedia de la pantalla de bloqueo en ChromeOS.
Controles multimedia de la pantalla de bloqueo en ChromeOS.

Se debe proporcionar la duración, que debe ser positiva. La posición debe ser positiva y menor que la duración. La velocidad de reproducción debe ser superior a 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();
});

Restablecer el estado de la posición es tan fácil como configurarlo en null.

// Reset position state when media is reset.
navigator.mediaSession.setPositionState(null);

Acciones de videoconferencia

Cuando el usuario coloca la videollamada en una ventana de pantalla en pantalla, el navegador puede mostrar controles para el micrófono y la cámara, y para colgar. Cuando el usuario hace clic en ellas, el sitio web las administra mediante las acciones de videoconferencia que aparecen a continuación. Para ver un ejemplo, consulta el ejemplo de videoconferencia.

Captura de pantalla de los controles de videoconferencia en una ventana pantalla en pantalla
Controles de videoconferencia en una ventana pantalla en pantalla.

Activar o desactivar micrófono

La acción "togglemicrophone" indica que el usuario desea silenciar o activar el sonido del micrófono. El método setMicrophoneActive(isActive) le indica al navegador si el sitio web actualmente considera que el micrófono está activo.

let isMicrophoneActive = false;

navigator.mediaSession.setActionHandler('togglemicrophone', () => {
  if (isMicrophoneActive) {
    // Mute the microphone.
  } else {
    // Unmute the microphone.
  }
  isMicrophoneActive = !isMicrophoneActive;
  navigator.mediaSession.setMicrophoneActive(isMicrophoneActive);
});

Alternar cámaras

La acción "togglecamera" indica que el usuario desea activar o desactivar la cámara activa. El método setCameraActive(isActive) indica si el navegador considera que el sitio web está activo.

let isCameraActive = false;

navigator.mediaSession.setActionHandler('togglecamera', () => {
  if (isCameraActive) {
    // Disable the camera.
  } else {
    // Enable the camera.
  }
  isCameraActive = !isCameraActive;
  navigator.mediaSession.setCameraActive(isCameraActive);
});

Colgar

La acción "hangup" indica que el usuario desea finalizar una llamada.

navigator.mediaSession.setActionHandler('hangup', () => {
  // End the call.
});

Acciones de presentación de diapositivas

Cuando el usuario coloca su presentación de diapositivas en una ventana de pantalla en pantalla, el navegador puede mostrar los controles para navegar por las diapositivas. Cuando el usuario hace clic en ellas, el sitio web las controla a través de la API de Media Session. Para ver un ejemplo, consulta la muestra de presentación de diapositivas.

Diapositiva anterior

La acción "previousslide" indica que el usuario quiere volver a la diapositiva anterior cuando presenta diapositivas.

navigator.mediaSession.setActionHandler('previousslide', () => {
  // Show previous slide.
});

Navegadores compatibles

  • 111
  • 111
  • x
  • x

Siguiente diapositiva

La acción "nextslide" indica que el usuario quiere ir a la siguiente diapositiva cuando presenta las diapositivas.

navigator.mediaSession.setActionHandler('nextslide', () => {
  // Show next slide.
});

Navegadores compatibles

  • 111
  • 111
  • x
  • x

Ejemplos

Consulta algunas muestras de sesiones multimedia en las que aparecen Blender Foundation y el trabajo de Jan Morgenstern.

Una presentación en pantalla sobre la API de Media Session

Recursos