Im Cache gespeicherte Audio- und Videoinhalte bereitstellen

Bei der Verarbeitung von Anfragen nach Media-Assets, d. h. der URL, die im Attribut src der Elemente <video> und <audio> angegeben ist, gibt es einige Stolperfallen. Diese können zu Fehlern bei der Auslieferung führen, wenn Sie keine speziellen Schritte bei der Workbox-Konfiguration ausführen.

Das Problem

Die Komplexität der Browser bei der Bereitstellung von Audio- und Video-Assets wird in dieser GitHub-Problemdiskussion ausführlich erläutert. Der Gesamtüberblick ist kompliziert, aber die wichtigsten Punkte sind:

  • Die Workbox muss angewiesen werden, Range-Anfrageheader zu berücksichtigen. Dazu wird das workbox-range-requests-Modul für die als Handler verwendete Strategie verwendet.
  • Für <video>- oder <audio>-Elemente muss der CORS-Modus mit dem Attribut crossorigin aktiviert werden.
  • Wenn Sie Medien aus dem Cache bereitstellen möchten, sollten Sie sie vorab explizit dem Cache hinzufügen. Dazu können Sie das Pre-Caching, cache.add() oder die warmStrategyCache-Methode in Workbox-Rezepten verwenden. Das Media-Asset kann nicht während der Laufzeit im Cache gespeichert werden, da während der Wiedergabe nur ein Teil des Inhalts aus dem Netzwerk abgerufen wird.

So erfüllen Sie diese Anforderungen in Workbox, beginnend mit dem richtigen Markup für ein Medien-Asset:

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

Verwenden Sie dann in Ihrem Service Worker das workbox-range-request-Plug-in, um die Medien-Assets entsprechend zu verarbeiten:

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

Mit diesem Ansatz können Sie sicherstellen, dass die Medien-Assets Ihrer Website ordnungsgemäß von Ihrem Service Worker abgerufen und im Cache gespeichert werden. Dabei werden Bereichsanfragen und andere mögliche Fallstricke im Zusammenhang mit Medienanfragen berücksichtigt.