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

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

المشكلة

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

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

إليك كيفية تلبية هذه المتطلبات في 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(),
    ],
  }),
);

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