Управление хранением видеофайлов в интернете.

Управление видеоконтентом — сложная задача; потоковая передача требует большой пропускной способности, а кэширование — непростая. Эти проблемы усугубляются, когда видео воспроизводится в цикле, например, на экране киоска . Если, к примеру, у компании сотни устройств, воспроизводящих 30 видеороликов подряд весь день, каждый день, это может быстро перегрузить сеть. Используя кэширование вместо потоковой передачи, вы тратите на загрузку только один раз, ускоряете последующие воспроизведения и делаете видео доступным для просмотра в автономном режиме. Для этого можно воспользоваться возможностями хранения данных браузера , среди которых API кэширования и IndexedDB наиболее подходят для хранения видеофайлов. Хотя оба варианта хороши, мы сосредоточимся на API кэширования из-за его интеграции с популярной библиотекой сервис-воркеров Workbox .

Кэширование видео от сервисного работника

Поскольку загрузка и кэширование больших файлов, таких как видео, может быть особенно ресурсоемкой задачей, требующей значительных временных и вычислительных ресурсов, ее следует выполнять в фоновом режиме вне основного потока. Сервис-воркеры особенно полезны для разгрузки задач кэширования. Они выступают в качестве посредника между страницей и сетью, позволяя перехватывать запросы и применять дополнительную логику к сетевому ответу, например, стратегию кэширования .

Существует множество различных стратегий кэширования, и каждая из них предназначена для решения разных задач. Например, чтобы обслуживать файл из кэша, если он доступен, или использовать сеть в качестве резервного варианта, если кэш недоступен, можно написать следующий код.

self.addEventListener('fetch', function (event) {
  event.respondWith(
    caches.match(event.request).then(function (response) {
      return response || fetch(event.request);
    }),
  );
});

Управление этим процессом для различных типов ресурсов или URL-адресов, требующих разных стратегий кэширования, может быть повторяющимся и чреватым ошибками. Workbox предоставляет набор инструментов, включая вспомогательные функции маршрутизации и стратегии кэширования , которые позволяют писать код сервис-воркера более декларативным и многократно используемым способом.

Предыдущая стратегия называется «кэширование в первую очередь» . Чтобы написать то же самое с использованием Workbox, вам нужно будет добавить следующее:

registerRoute(
  ({ request }) => request.destination === 'video',
  new CacheFirst()
);

Workbox предоставляет аналогичные рецепты для других стратегий кэширования и распространенных задач сервис-воркеров, включая интеграцию с инструментами сборки, такими как Webpack и Rollup .

После настройки Workbox вам нужно выбрать, когда вы будете кэшировать свои видео. Здесь есть два подхода: кэширование при загрузке страницы или отложенное кэширование при запросе видео.

Настойчивый подход

Предварительное кэширование — это метод, при котором файлы сохраняются в кэше во время установки сервис-воркера, делая их доступными сразу после завершения работы сервиса. Workbox может автоматически настроить предварительное кэширование для файлов, к которым он имеет доступ в процессе сборки.

Следующий код Workbox можно использовать в вашем сервис-воркере для предварительного кэширования файлов:

import { addPlugins, precacheAndRoute } from 'workbox-precaching';
import { RangeRequestsPlugin } from 'workbox-range-requests';

addPlugins([new RangeRequestsPlugin()]);
precacheAndRoute(self.__WB_MANIFEST);
  • import (s) - Загрузка необходимых привязок из соответствующих модулей Workbox . Поскольку сервис-воркеры пока не поддерживают ESModules повсеместно, ваш сервис-воркер на базе Workbox необходимо будет обработать с помощью сборщика, чтобы он работал в производственной среде.
  • RangeRequestsPlugin — позволяет обрабатывать запросы с заголовком Range с помощью кэшированного ответа. Это необходимо, поскольку браузеры обычно используют заголовок Range для медиаконтента.
  • addPlugins — позволяет добавлять плагины Workbox к каждому запросу Workbox.
  • precacheAndRoute — Добавляет записи в список предварительного кэширования и создает маршрут для обработки соответствующих запросов на выборку.
  • __WB_MANIFEST — Заполнитель, который Workbox CLI (или плагины инструментов сборки) заменяет манифестом предварительного кэширования.

Передайте свой сервис-воркер либо в Workbox CLI, либо в выбранный вами инструмент сборки и настройте способ генерации предварительного кэша; файл workbox-config.js , подобный приведенному ниже, укажет CLI, как следует отображать ваш сервис-воркер:

module.exports = {
  globDirectory: '.',
  globPatterns: ['**/*.{html,mp4}'],
  maximumFileSizeToCacheInBytes: 5000000,
  swSrc: 'sw.js',
  swDest: 'sw.js',
};
  • globDirectory — корневая папка, из которой начинается поиск файлов предварительного кэша.
  • globPatterns — шаблоны файлов ( «globs» ), которые должны быть предварительно кэшированы.
  • maximumFileSizeToCacheInBytes — Верхний предел размера файла, который может быть предварительно кэширован, в байтах.
  • swSrc — путь к файлу, который будет использоваться для генерации вашего сервис-воркера.
  • swDest — место назначения сгенерированного сервисного воркера (оно может совпадать с исходным файлом, но убедитесь, self.__WB_MANIFEST присутствует при каждом запуске).

При запуске процесса сборки генерируется новая версия сервисного работника, а self.__WB_MANIFEST заменяется списком файлов, каждый из которых имеет хеш, обозначающий его ревизию:

precacheAndRoute([
  {
    revision: '524ac4b453c83f76eb9caeec11854ca5',
    url: 'ny.mp4',
  },
]);

При каждом запуске процесса сборки этот список перезаписывается текущим набором соответствующих файлов и их текущими хэшами ревизий. Это гарантирует, что при добавлении, удалении или изменении файла сервис-воркер обновит кэш при следующей установке.

Ленивый подход

Если у вас нет всех видеофайлов, доступных на этапе сборки, или вы хотите кэшировать видео только тогда, когда они необходимы, следует использовать отложенный подход. Этот подход требует разделения кэширования и предоставления контента; поскольку во время воспроизведения видео из сети загружается только часть контента, кэширование файлов по мере их потоковой передачи не сработает.

Кэширование файлов

Кэши можно создавать с помощью метода `Cache.open()` , а затем добавлять файлы в кэш с помощью методов `Cache.add()` или `Cache.addAll()` . Если ваше приложение получает JSON-список видео для кэширования, их можно добавить в видеокэш следующим образом:

// Open video cache
const cache = await caches.open('video-cache');
// Fetch list of videos
const videos = await (await fetch('/video-list.json')).json();
// Add videos to cache
await cache.addAll(videos);

Преимущество такого подхода заключается в возможности независимого управления этапом кэширования от жизненного цикла сервис-воркера , даже от других веб-воркеров . Недостаток же состоит в том, что управление хранилищем ложится на разработчика: необходимо написать собственный алгоритм для отслеживания изменений файлов, отслеживания кэшированных в браузере файлов и управления обновлениями файлов, чтобы гарантировать обновление только измененных файлов.

Предоставление доступа к кэшированным видеофайлам

Стратегия кэширования во время выполнения сервис-воркера, например, «кэшировать первым», может быть использована для предоставления доступа к ранее кэшированным видеофайлам:

import { registerRoute } from 'workbox-routing';
import { CacheFirst } from 'workbox-strategies';
import { CacheableResponsePlugin } from 'workbox-cacheable-response';
import { RangeRequestsPlugin } from 'workbox-range-requests';

registerRoute(
  ({ request }) => request.destination === 'video',
  new CacheFirst({
    cacheName: 'video-cache',
    plugins: [
      new CacheableResponsePlugin({
        statuses: [200],
      }),
      new RangeRequestsPlugin(),
    ],
  }),
);
  • import (s) - Загружает необходимые привязки из соответствующих модулей рабочей области .
  • registerRoute — Направляет запросы к функциям (стратегиям кэширования и плагинам), которые предоставляют ответы.
  • CacheFirst — стратегия кэширования, которая выполняет запрос из кэша, если он доступен, в противном случае извлекает его из сети и обновляет кэш.
  • CacheableResponsePlugin — используется для указания того, какие заголовки должны присутствовать, чтобы ответ можно было кэшировать. Убедитесь, что для маршрутов, кэширующих видео, указаны только заголовки со статусом 200, чтобы избежать кэширования ответов с частичным содержимым (206) во время потоковой передачи видео.
  • RangeRequestsPlugin — плагин, позволяющий обрабатывать запросы с заголовком Range с помощью кэшированного ответа. Это необходимо, поскольку браузеры обычно используют заголовок Range для медиаконтента.

Оптимизация загрузки видео — важная задача для приложений, интенсивно использующих потоковую передачу. Используя API кэширования браузера и Workbox, вы можете сделать эту сложную задачу управляемой, экономя трафик пользователей, снижая нагрузку на сервер, обеспечивая более быстрое воспроизведение видео и позволяя воспроизводить видео даже в автономном режиме.