Dar control a los usuarios: la API de sesión multimedia
He aquí un escenario. Comienzas una canción de Kendrick Lamar en una de las muchas pestañas abiertas de tu navegador. Te encanta, pero alguien entra en tu espacio y necesitas pausarlo. ¿Qué pestaña es? Los navegadores intentan ayudar un poco con eso. Probablemente puedas silenciar todo el audio del sistema. ¿Pero no sería bueno tener control sobre la reproducción de audio sin necesariamente tener que encontrar el camino de regreso a esa pestaña?
La API Media Session lo hace posible. Proporciona acceso de reproducción multimedia al usuario fuera de la pestaña del navegador donde se está reproduciendo. Si se implementa, estará disponible en varios lugares del dispositivo, incluidos:
- el área de notificaciones en muchos dispositivos móviles,
- en otros dispositivos portátiles, y
- el área del centro multimedia de muchos dispositivos de escritorio.
Además, la API Media Session nos permite controlar la reproducción multimedia con teclas multimedia y asistentes de voz como Siri, Google Assistant, Bixby o Alexa.
La API de sesión de medios
La API Media Session consta principalmente de las dos interfaces siguientes:
MediaMetadata
MediaSession
La MediaMetadata
interfaz es lo que proporciona datos sobre los medios de reproducción. Es responsable de informarnos el título, el álbum, la obra de arte y el artista del medio (que es Kendrick Lamar en este ejemplo). La MediaSession
interfaz es la responsable de la funcionalidad de reproducción multimedia.
Antes de profundizar en el tema, deberíamos tomar nota de la detección de funciones. Es una buena práctica comprobar si un navegador admite una función antes de implementarla. Para comprobar si un navegador admite la API de sesión multimedia, tendríamos que incluir lo siguiente en nuestro archivo JavaScript:
if ('mediaSession' in navigator) { // Our media session api that lets us seek to the beginning of Kendrick Lamar's quot;Alrightquot;}
La interfaz MediaMetadata
El constructor MediaMetadata.MediaMetadata()
crea un nuevo MediaMetadata
objeto. Después de crearlo, podemos agregar las siguientes propiedades:
MediaMetadata.title
establece u obtiene el título del medio que se reproduce.MediaMetadata.artist
establece u obtiene el nombre del artista o grupo del medio que se reproduce.MediaMetadata.album
establece u obtiene el nombre del álbum que contiene el medio en reproducción.MediaMetadata.artwork
establece u obtiene la variedad de imágenes relacionadas con el medio en reproducción.
El valor de la artwork
propiedad del MediaMetadata
objeto es una matriz de MediaImage
objetos. Un MediaImage
objeto contiene detalles que describen una imagen asociada con los medios. Los objetos tienen las tres propiedades siguientes:
src
: la URL de la imagensizes
: indica el tamaño de la imagen, por lo que no es necesario escalar una imagentype
: el tipo MIME de la imagen
Creemos un MediaMetadata
objeto para “Alright” de Kendrick Lamar de su álbum To Pimp a Butterfly.
if ('mediaSession' in navigator) { navigator.mediaSession.metadata = new MediaMetadata({ title: 'Alright', artist: 'Kendrick Lamar', album: 'To Pimp A Butterfly', artwork: [ { src: 'https://mytechnicalarticle/kendrick-lamar/to-pimp-a-butterfly/alright/96x96', sizes: '96x96', type: 'image/png' }, { src: 'https://mytechnicalarticle/kendrick-lamar/to-pimp-a-butterfly/alright/128x128', sizes: '128x128', type: 'image/png' }, // More sizes, like 192x192, 256x256, 384x384, and 512x512 ] });}
La interfaz MediaSession
Como se indicó anteriormente, esto es lo que permite al usuario controlar la reproducción de los medios. Podemos realizar las siguientes acciones en el medio de reproducción a través de esta interfaz:
play
: reproducir los mediospause
: pausar los mediosprevioustrack
: cambia a la pista anteriornexttrack
: cambia a la siguiente pistaseekbackward
: busca hacia atrás desde la posición actual, unos segundosseekforward
: busca hacia adelante desde la posición actual, unos segundosseekto
: busca a un tiempo específico desde la posición actualstop
: detener la reproducción multimediaskipad
: pasa por alto el anuncio que se reproduce, si lo hay
El MediaSessionAction
tipo enumerado hace que estas acciones estén disponibles como tipos de cadena. Para admitir cualquiera de estas acciones, tenemos que usar el MediaSession
método setActionHandler()
para definir un controlador para esa acción. El método realiza la acción y una devolución de llamada que se llama cuando el usuario invoca la acción. Profundicemos un poco más para comprenderlo mejor.
Para configurar controladores para las acciones play
y pause
, incluimos lo siguiente en nuestro archivo JavaScript:
let alright = new HTMLAudioElement();if ('mediaSession' in navigator) { navigator.mediaSession.setActionHandler('play', () = { alright.play(); }); navigator.mediaSession.setActionHandler('pause', () = { alright.pause(); });}
Aquí configuramos la pista para que se reproduzca cuando el usuario la reproduzca y se detenga cuando el usuario la pausa a través de la interfaz multimedia.
Para las acciones previoustrack
y nexttrack
, incluimos lo siguiente:
let u = new HTMLAudioElement();let forSaleInterlude = new HTMLAudioElement();if ('mediaSession' in navigator) { navigator.mediaSession.setActionHandler('previoustrack', () = { u.play(); }); navigator.mediaSession.setActionHandler('nexttrack', () = { forSaleInterlude.play(); });}
Puede que esto no se explique por sí solo si no eres un gran fanático de Kendrick Lamar, pero con suerte entenderás lo esencial. Cuando el usuario quiera reproducir la pista anterior, configuramos la pista anterior para que se reproduzca. Cuando es la siguiente pista, es la siguiente pista.
Para implementar las acciones seekbackward
y seekforward
, incluimos lo siguiente:
if ('mediaSession' in navigator) { navigator.mediaSession.setActionHandler('seekbackward', (details) = { alright.currentTime = alright.currentTime - (details.seekOffset || 10); }); navigator.mediaSession.setActionHandler('seekforward', (details) = { alright.currentTime = alright.currentTime + (details.seekOffset || 10); });}
Dado que no consideramos que nada de esto se explique por sí solo, me gustaría dar una explicación concisa sobre las acciones seekbackward
y . seekforward
Los controladores para ambas acciones, seekbackward
y seekforward
, se activan, como sus nombres lo indican, cuando el usuario quiere buscar hacia atrás o hacia adelante unos pocos segundos. El MediaSessionActionDetails
diccionario nos proporciona los “pocos segundos” en una propiedad seekOffset
. Sin embargo, la seekOffset
propiedad no siempre está presente porque no todos los agentes de usuario actúan de la misma manera. Cuando no esté presente, debemos configurar la pista para que busque hacia atrás o hacia adelante “unos cuantos segundos” que tenga sentido para nosotros. Por eso usamos 10 segundos porque son bastantes. En pocas palabras, configuramos la pista para que se busque por seekOffset
segundos si se proporciona. Si no se proporciona, buscamos por 10 segundos.
Para agregar la seekto
funcionalidad a nuestra API de sesión de medios, incluimos el siguiente fragmento:
if ('mediaSession' in navigator) { navigator.mediaSession.setActionHandler('seekto', (details) = { if (details.fastSeek 'fastSeek' in alright) { alright.fastSeek(details.seekTime); return; } alright.currentTime = details.seekTime; });}
Aquí, el MediaSessionActionDetails
diccionario proporciona las propiedades fastSeek
y seekTime
. fastSeek
Básicamente, la búsqueda se realiza rápidamente (como avance rápido o rebobinado), mientras que seekTime
es el momento en que la pista debe buscar. Si bien fastSeek
es una propiedad opcional, el MediaSessionActionDetails
diccionario siempre proporciona la seekTime
propiedad para el seekto
controlador de acciones. Básicamente, configuramos el seguimiento fastSeek
cuando seekTime
la propiedad está disponible y el usuario busca rápidamente, mientras que simplemente lo configuramos seekTime
cuando el usuario solo busca en un tiempo específico.
Aunque no sé por qué uno querría detener una canción de Kendrick, no estaría más describir el stop
controlador de acciones de la MediaSession
interfaz:
if ('mediaSession' in navigator) { navigator.mediaSession.setActionHandler('stop', () = { alright.pause(); alright.currentTime = 0; });}
El usuario invoca el skipad
controlador de acción (como en “omitir anuncio” en lugar de “ski pad”) cuando se reproduce un anuncio y quiere omitirlo para poder continuar escuchando la pista “A lright” de Kendrick Lamar. Si soy honesto, los detalles completos del skipad
controlador de están fuera del alcance de mi comprensión de “API de sesión de medios”. Por lo tanto, probablemente deberías buscarlo por tu cuenta después de leer este artículo, si realmente quieres implementarlo.
terminando
Deberíamos tomar nota de algo. Siempre que el usuario reproduzca la pista, busque o cambie la velocidad de reproducción, se supone que debemos actualizar el estado de posición en la interfaz proporcionada por la API de sesión de medios. Lo que usamos para implementar esto es el setPositionState()
método del mediaSession
objeto, como se muestra a continuación:
if ('mediaSession' in navigator) { navigator.mediaSession.setPositionState({ duration: alright.duration, playbackRate: alright.playbackRate, position: alright.currentTime });}
Además, me gustaría recordarles que no todos los navegadores de los usuarios soportan todas las acciones. Por lo tanto, se recomienda configurar los controladores de acciones en un try...catch
bloque, como se muestra a continuación:
const actionsAndHandlers = [ ['play', () = { /*...*/ }], ['pause', () = { /*...*/ }], ['previoustrack', () = { /*...*/ }], ['nexttrack', () = { /*...*/ }], ['seekbackward', (details) = { /*...*/ }], ['seekforward', (details) = { /*...*/ }], ['seekto', (details) = { /*...*/ }], ['stop', () = { /*...*/ }]] for (const [action, handler] of actionsAndHandlers) { try { navigator.mediaSession.setActionHandler(action, handler); } catch (error) { console.log(`The media session action, ${action}, is not supported`); }}
Poniendo todo lo que hemos hecho, tendríamos lo siguiente:
let alright = new HTMLAudioElement();let u = new HTMLAudioElement();let forSaleInterlude = new HTMLAudioElement();const updatePositionState = () = { navigator.mediaSession.setPositionState({ duration: alright.duration, playbackRate: alright.playbackRate, position: alright.currentTime });} const actionsAndHandlers = [ ['play', () = { alright.play(); updatePositionState(); }], ['pause', () = { alright.pause(); }], ['previoustrack', () = { u.play(); }], ['nexttrack', () = { forSaleInterlude.play(); }], ['seekbackward', (details) = { alright.currentTime = alright.currentTime - (details.seekOffset || 10); updatePositionState(); }], ['seekforward', (details) = { alright.currentTime = alright.currentTime + (details.seekOffset || 10); updatePositionState(); }], ['seekto', (details) = { if (details.fastSeek 'fastSeek' in alright) { alright.fastSeek(details.seekTime); updatePositionState(); return; } alright.currentTime = details.seekTime; updatePositionState(); }], ['stop', () = { alright.pause(); alright.currentTime = 0; }],] if ( 'mediaSession' in navigator ) { navigator.mediaSession.metadata = new MediaMetadata({ title: 'Alright', artist: 'Kendrick Lamar', album: 'To Pimp A Butterfly', artwork: [ { src: 'https://mytechnicalarticle/kendrick-lamar/to-pimp-a-butterfly/alright/96x96', sizes: '96x96', type: 'image/png' }, { src: 'https://mytechnicalarticle/kendrick-lamar/to-pimp-a-butterfly/alright/128x128', sizes: '128x128', type: 'image/png' }, // More sizes, like 192x192, 256x256, 384x384, and 512x512 ] }); for (const [action, handler] of actionsAndHandlers) { try { navigator.mediaSession.setActionHandler(action, handler); } catch (error) { console.log(`The media session action, ${action}, is not supported`); } }}
Aquí hay una demostración de la API:
Implementé seis de las acciones. No dudes en probar el resto durante tu tiempo libre.
Si ve el Pen en su dispositivo móvil, observe cómo aparece en su área de notificación.
Si su reloj inteligente está emparejado con su dispositivo, eche un vistazo.
Si tiene el P en Chrome en el escritorio, navegue hasta el centro de medios y juegue con los botones multimedia allí. La demostración incluso tiene varias pistas, por lo que puedes experimentar avanzando y retrocediendo entre las pistas.
Si llegué hasta aquí (o no), gracias por leer y, por favor, en la próxima aplicación que cree con funcionalidad multimedia, implemente esta API.
Deja un comentario