При добавлении сервис-воркеров на сайт видео в Safari и на устройствах iOS прерывается.

Я делал сайт, где в компонентах героя есть видео, и до добавления gatsby-plugin-offline все работало нормально. Я провел некоторое тестирование браузера, и все браузеры казались оштрафованными, видео было в порядке. Тогда я решил, что пора добавить сервис-воркера и сделать сайт доступным для установки и работать в автономном режиме. Я добавил плагин и все протестировал с Chrome и Android. Все как должно быть! Но потом я открыл его на своем iPad и увидел, что видео вообще не воспроизводятся, даже не загружаются.

Это выглядело странно, поскольку видео были реализованы с помощью HTML-тега <video> и были стандартными файлами MP4. К счастью, я добавил только сервис-воркера, поэтому я начал подозревать, что это как-то связано с этим.

Я наткнулся на статью Джереми Кейтса, где он описывает, как у него была такая же проблема. Он ссылается на решение и более подробное объяснение в посте Фила Нэша. Похоже, Safari нужны сервисные работники для поддержки запросов байтового диапазона для воспроизведения мультимедиа. Как сказано в документации для Safari:

«HTTP-серверы, на которых размещены медиафайлы для iOS, должны поддерживать запросы байтового диапазона, которые iOS использует для выполнения произвольного доступа при воспроизведении мультимедиа».

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

Я покажу вам, как реализовать оба решения с gatsby-plugin-offline.

Получить видео из кеша

gatsby-plugin-offline использует Workbox для генерации сервис-воркеров. К счастью, в Workbox уже есть продвинутый рецепт работы с видео и аудио. Именно так мы и будем это реализовывать. Нам просто нужно добавить его к сервис-воркеру, созданному Гэтсби.

Во-первых, нам нужно добавить атрибут crossOrigin="anonymous" в наш HTML-тег <video>:

<video src="movie.mp4" crossOrigin="anonymous"></video>

Во-вторых, мы создаем файл, который будет добавлен к сгенерированному файлу сервис-воркера. Назовем его sw-range-request-handler.js. Мы поместим это в корневую папку нашего проекта.

Содержимое этого файла будет:

Мы сопоставляем все запрошенные файлы MP4 и используем стратегию CacheFirst для поиска видеофайлов в кеше. Если совпадений в кэше нет, файл будет обслуживаться из сети.

Если вы посмотрите на пример из Расширенных рецептов Workbox, то увидите, что использование функций плагина немного отличается. Это потому, что на данный момент gatsby-plugin-offline использует Workbox v.4, но пример для v.5.

Вы увидите, что мы также не импортировали какие-либо функции из Workbox. Это потому, что мы только добавляем содержимое нашего файла в сгенерированный файл сервис-воркера, где все эти плагины уже добавлены к объекту workbox.

Когда gatsby-plugin-offline обновится до версии 5 Workbox, нам нужно будет обновить, как мы используем плагины:

Теперь нам нужно использовать параметр appendScript в конфигурации gatsby-plugin-offline, чтобы добавить наш файл в сервис-воркер. Добавьте объект options в gatsby-config.js:

{
  resolve: `gatsby-plugin-offline`,
  options: {
    appendScript: require.resolve(`./sw-range-request-handler.js`),
  },
},

Теперь, запустив команду gatsby build и просмотрев файл public/sw.js, вы увидите, что в самом конце находится наш код. Отображение видео на устройствах Safari и iOS снова будет работать после обновления сервис-воркера.

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

Получить видео из сети

Чтобы никогда не кэшировать видео в хранилище и получать их только из сети, вам необходимо перезаписать конфигурацию Workbox. Это можно сделать, перезаписав объект workboxConfig внутри объекта options.

Во-первых, мы все равно должны добавить атрибут crossOrigin="anonymous" в наш HTML-тег <video>:

<video src="movie.mp4" crossOrigin="anonymous"></video>

Во-вторых, мы модифицируем gatsby-config.js файл, чтобы перезаписать существующий workboxConfig:

Мы используем стратегию NetworkOnly, чтобы получить наш файл MP4. Его никогда не будут искать в кеше.

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

Заключение

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

Если вы используете Workbox, то посмотрите их продвинутые рецепты. Если вы используете чистую реализацию сервис-воркеров, то посмотрите статью Джереми Кейта Сервис-воркеры и видео в Safari или сообщение Фила Нэша Сервис-воркеры: Остерегайтесь запроса диапазона Safari. Они дают более подробное объяснение этой проблемы.

Спасибо.