Im Cache gespeicherte Audio- und Videoinhalte bereitstellen

Es gibt einige Schwachstellen in der Art und Weise, wie Browser mit Anfragen nach Medien-Assets – d. h. der im Attribut src der Elemente <video> und <audio> angegebenen URL – umgehen. Dies kann zu einem falschen Auslieferungsverhalten führen, wenn Sie bei der Konfiguration von Workbox keine speziellen Schritte ausführen.

Das Problem

Die Funktionsweise der Browser bei der Auslieferung von Audio- und Video-Assets ist in der GitHub-Diskussion zu Problemen ausführlich erläutert. Das Gesamtbild ist kompliziert, aber die wichtigsten Punkte sind:

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

Gehen Sie wie folgt vor, um diese Anforderungen in Workbox zu erfüllen, angefangen 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 Plug-in workbox-range-request, 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 Medieninhalte Ihrer Website von Ihrem Service Worker ordnungsgemäß abgerufen und im Cache gespeichert werden. Gleichzeitig können Sie Bereichsanfragen und andere potenzielle Fallstricke im Zusammenhang mit Medienanfragen berücksichtigen.