Cómo entregar audio y video almacenados en caché

Hay algunas diferencias en la forma en que algunos navegadores manejan las solicitudes de elementos multimedia, es decir, la URL especificada en el atributo src de los elementos <video> y <audio>, lo que puede generar un comportamiento de publicación incorrecto, a menos que sigas pasos específicos cuando configures Workbox.

El problema

Las complejidades de los problemas que tienen los navegadores con respecto a la entrega de elementos de audio y video se explican en detalle en este debate sobre problemas de GitHub. El panorama completo es complicado, pero los puntos clave son los siguientes:

  • Se debe indicar a la caja de trabajo que respete los encabezados de solicitud Range mediante el módulo workbox-range-requests con la estrategia que se usa como controlador.
  • Los elementos <video> o <audio> deben habilitar el modo CORS con el atributo crossorigin.
  • Si deseas entregar contenido multimedia desde la caché, debes agregarlo explícitamente a la caché con anticipación. Puedes hacerlo con el almacenamiento previo en caché, con cache.add(), o con el método WarmStrategyCache en recetas de la caja de trabajo. El almacenamiento en caché del elemento multimedia mientras se transmite durante el tiempo de ejecución no funcionará, ya que solo se recupera contenido parcial de la red durante la reproducción.

Aquí te mostramos cómo cumplir con estos requisitos en Workbox, comenzando con el lenguaje de marcado adecuado para un recurso multimedia:

<!-- In your page: -->

<!-- You need to set `crossorigin`, even for same-origin URLs! -->
<video src="movie.mp4" crossorigin="anonymous"></video>
<audio src="song.mp3" crossorigin="anonymous"></audio>

Luego, en tu service worker, usa el complemento workbox-range-request para controlar los elementos multimedia según corresponda:

// sw.js
import {registerRoute} from 'workbox-routing';
import {CacheFirst} from 'workbox-strategies';
import {CacheableResponsePlugin} from 'workbox-cacheable-response';
import {RangeRequestsPlugin} from 'workbox-range-requests';

// In your service worker:
// It's up to you to either precache, use warmRuntimeCache, or
// explicitly call cache.add() to populate the cache with media assets.
// If you choose to cache media assets up front, do so with care,
// as they can be quite large and exceed storage quotas.
//
// This route will go to the network if there isn't a cache match,
// but it won't populate the cache at runtime because the response for
// the media asset will be a partial 206 response. If there is a cache
// match, then it will properly serve partial responses.
registerRoute(
  ({request}) => {
    const {destination} = request;

    return destination === 'video' || destination === 'audio'
  },
  new CacheFirst({
    cacheName: 'your-cache-name-here',
    plugins: [
      new CacheableResponsePlugin({
        statuses: [200]
      }),
      new RangeRequestsPlugin(),
    ],
  }),
);

Con este enfoque, puedes asegurarte de que el service worker recupere y almacene en caché los recursos multimedia de tu sitio web de manera adecuada, teniendo en cuenta las solicitudes de rango y otros errores potenciales relacionados con las solicitudes de medios.