Pliki audio i wideo przechowywane w pamięci podręcznej

Występują pewne niedociągnięcia w sposobie obsługi żądań zasobów medialnych przez niektóre przeglądarki, czyli adres URL podany w atrybucie src elementów <video> i <audio>. Może to prowadzić do nieprawidłowego działania wyświetlania, chyba że wykonasz odpowiednie czynności podczas konfigurowania pola Workbox.

Problem

Problemy, które występują w przeglądarkach w związku z wyświetlaniem zasobów audio i wideo, zostały szczegółowo wyjaśnione w tym artykule na GitHubie. Pełny obraz sytuacji jest skomplikowany, ale najważniejsze kwestie:

  • Pole robocze musi respektować nagłówki żądań Range przez wykorzystanie modułu workbox-range-requests w strategii wykorzystywanej jako moduł obsługi.
  • Elementy <video> lub <audio> muszą aktywować tryb CORS za pomocą atrybutu crossorigin.
  • Jeśli chcesz udostępniać multimedia z pamięci podręcznej, dodaj do niej pliki z wyprzedzeniem. Możesz to zrobić, używając wstępnego buforowania, korzystając z metody cache.add() lub korzystając z metody fireStrategyCache w polach roboczych. Zapisywanie zasobu multimedialnego w pamięci podręcznej podczas transmisji w czasie działania nie zadziała, ponieważ podczas odtwarzania zostaną pobrane tylko części treści z sieci.

Oto jak spełnić te wymagania w polu Workbox, zaczynając od odpowiednich znaczników dla zasobu multimedialnego:

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

Następnie w skrypcie service worker użyj wtyczki workbox-range-request, aby odpowiednio obsłużyć zasoby multimedialne:

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

Dzięki temu możesz mieć pewność, że zasoby multimedialne Twojej witryny będą prawidłowo pobierane i zapisywane w pamięci podręcznej przez skrypt service worker, przy uwzględnieniu żądań zakresu i innych potencjalnych problemów związanych z żądaniami mediów.