Diffuser des contenus audio et vidéo mis en cache

Certains navigateurs traitent les requêtes d'éléments multimédias (c'est-à-dire l'URL spécifiée dans l'attribut src des éléments <video> et <audio>) qui peut entraîner un comportement de diffusion incorrect, sauf si vous suivez des étapes spécifiques lors de la configuration de Workbox.

Problème

Les subtilités des navigateurs problématiques concernant la diffusion d'éléments audio et vidéo sont expliquées en détail dans cette discussion sur GitHub. La vue d'ensemble est complexe, mais voici les points clés à retenir:

  • Vous devez indiquer à la boîte de travail de respecter les en-têtes de requête Range en utilisant le module workbox-range-requests pour la stratégie utilisée en tant que gestionnaire.
  • Les éléments <video> ou <audio> doivent être activés en mode CORS avec l'attribut crossorigin.
  • Si vous souhaitez diffuser du contenu multimédia à partir du cache, vous devez l'ajouter explicitement au cache à l'avance. Pour ce faire, vous pouvez effectuer une mise en cache préalable, utiliser cache.add(), ou encore utiliser la méthode "heatStrategyCache" dans des recettes de boîte de travail. La mise en cache de l'élément multimédia lors de sa diffusion au moment de l'exécution ne fonctionne pas, car seule une partie du contenu est extraite du réseau pendant la lecture.

Voici comment respecter ces exigences dans Workbox, en commençant par le balisage approprié d'un élément multimédia:

<!-- 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>

Ensuite, dans votre service worker, utilisez le plug-in workbox-range-request pour gérer les éléments multimédias en conséquence:

// 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(),
    ],
  }),
);

Cette approche vous permet de vous assurer que les éléments multimédias de votre site Web sont correctement récupérés et mis en cache par votre service worker, tout en prenant en compte les demandes de plages et les autres pièges éventuels liés aux demandes de médias.