عرض محتوى الصوت والفيديو المخزنَين مؤقتًا

هناك بعض المشاكل في طريقة تعامل بعض المتصفّحات مع طلبات مواد عرض الوسائط، أي عنوان URL المحدّد في السمة src للعنصرَين <video> و<audio>، ما يمكن أن يؤدي إلى سلوك عرض غير صحيح ما لم تتخذ خطوات محدّدة عند إعداد Workbox.

المشكلة

في مناقشة مشكلة GitHub هذه، يتم شرح التفاصيل المعقدة للمشاكل التي تواجهها المتصفّحات بشأن عرض أصول الصوت والفيديو. الصورة الكاملة معقدة، لكن النقاط الرئيسية هي:

  • يجب أن يتم إخبار إطار العمل باحترام عناوين طلبات Range باستخدام وحدة workbox-range-requests للاستراتيجية المستخدَمة كمعالج.
  • يجب تفعيل وضع سياسة مشاركة الموارد المتعددة المصادر (CORS) من خلال السمة crossorigin مع عناصر <video> أو <audio>
  • إذا أردت عرض الوسائط من ذاكرة التخزين المؤقت، يجب إضافتها بشكل صريح إلى ذاكرة التخزين المؤقت مسبقًا. ويمكنك إجراء ذلك عن طريق التخزين المؤقت مسبقًا، أو باستخدام cache.add()، أو باستخدام طريقة drawStrategyCache في وصفات مربع العمل. ولن ينجح التخزين المؤقت لمادة عرض الوسائط أثناء بثها في وقت التشغيل، إذ يتم جلب محتوى جزئي فقط من الشبكة أثناء التشغيل.

إليك كيفية تلبية هذه المتطلبات في Workbox، بدءًا من الترميز الصحيح لمادة عرض الوسائط:

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

وبعد ذلك، في مشغّل الخدمات، استخدِم المكوِّن الإضافي workbox-range-request للتعامل مع مواد عرض الوسائط وفقًا لذلك:

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

وباستخدام هذا النهج، يمكنك التأكد من أن مشغّل الخدمات لديك يجلب مواد عرض الوسائط الخاصة بموقعك الإلكتروني وتخزينها مؤقتًا بشكل صحيح، مع الأخذ في الاعتبار طلبات النطاق والمخاطر المحتملة الأخرى المتعلقة بطلبات الوسائط.