Phân phát âm thanh và video được lưu vào bộ nhớ đệm

Có một vài điểm khác biệt trong cách một số trình duyệt xử lý yêu cầu cho thành phần nội dung đa phương tiện, chẳng hạn như URL được chỉ định trong thuộc tính src của các phần tử <video><audio>. Điều này có thể dẫn đến hành vi phân phát không chính xác, trừ phi bạn thực hiện các bước cụ thể khi định cấu hình Workbox.

Vấn đề

Sự phức tạp của các trình duyệt gặp vấn đề trong việc phân phát tài sản âm thanh và video được giải thích chi tiết trong cuộc thảo luận về vấn đề trên GitHub. Thông tin tổng quan rất phức tạp, nhưng các điểm chính là:

  • Hộp làm việc phải được yêu cầu tuân thủ tiêu đề của yêu cầu Range bằng cách sử dụng mô-đun workbox-range-requests cho chiến lược được dùng làm trình xử lý.
  • Các phần tử <video> hoặc <audio> cần chọn sử dụng chế độ CORS với thuộc tính crossorigin.
  • Nếu muốn phân phát nội dung nghe nhìn từ bộ nhớ đệm, trước tiên, bạn nên thêm nội dung đó vào bộ nhớ đệm một cách rõ ràng. Bạn có thể thực hiện việc này bằng cách lưu trước vào bộ nhớ đệm hoặc thông qua cache.add(), hoặc sử dụng phương thức smoothStrategyCache trong công thức hộp làm việc. Bạn sẽ không thể lưu nội dung nghe nhìn vào bộ nhớ đệm khi phát trực tuyến trong thời gian chạy vì chỉ một phần nội dung được tìm nạp từ mạng trong quá trình phát.

Sau đây là cách đáp ứng các yêu cầu này trong Workbox, bắt đầu bằng phần đánh dấu phù hợp cho một nội dung nghe nhìn:

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

Sau đó, trong trình chạy dịch vụ, hãy sử dụng trình bổ trợ workbox-range-request để xử lý các thành phần nội dung nghe nhìn cho phù hợp:

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

Với phương pháp này, bạn có thể đảm bảo rằng thành phần nội dung đa phương tiện trên trang web của bạn được trình chạy dịch vụ tìm nạp và lưu vào bộ nhớ đệm đúng cách, đồng thời tính đến yêu cầu theo phạm vi và các sai lầm tiềm ẩn khác liên quan đến yêu cầu nội dung đa phương tiện.