Автоопределение или отклонение загрузок видео VP9, несовместимых с iOS Safari

Недавно я обнаружил, что несколько видео на моём самостоятельно размещённом форуме Discourse незаметно перестали воспроизводиться на iPhone и iPad. После расследования выяснилось, что корень проблемы заключается в том, что видео были закодированы с использованием кодека VP9 внутри контейнера MP4 — комбинация, которую iOS Safari не поддерживает.

Как это происходит

Facebook (и, возможно, другие платформы) иногда доставляет видео в кодировке VP9, когда пользователи скачивают свой контент. Когда эти файлы загружаются в Discourse, они принимаются без проблем — расширение .mp4 не даёт никаких указаний на используемый внутри кодек. На настольных браузерах и Android видео воспроизводятся нормально, поэтому проблема остаётся незамеченной. В iOS Safari видео показывает миниатюру и кнопку воспроизведения, но при нажатии появляется только вращающийся индикатор. Пользователи обычно полагают, что это проблема сети, и продолжают работу, не сообщая о ней.

Почему это трудно обнаружить

  • Расширение файла (.mp4) идентично рабочему файлу с кодеком H.264
  • Настольные браузеры поддерживают VP9, поэтому администраторы, тестирующие на десктопе, не видят проблем
  • Пользователи iOS часто не сообщают об отдельных сбоях медиа, особенно когда другой контент в том же сообщении виден и воспроизводится
  • Нет предупреждения или ошибки для администратора

Предлагаемое решение

При загрузке видео Discourse мог бы проверять кодек видео (ffprobe уже доступен в Docker-контейнере) и либо:

  1. Отклонить загрузку с чётким сообщением, объясняющим, что VP9 не поддерживается на iOS, и просьбой перекодировать видео в H.264, или
  2. Автоматически перекодировать видео в H.264 при загрузке (аналогично тому, как некоторые платформы нормализуют загрузки)

Вариант 1 менее сложен в реализации и уже стал бы значительным улучшением. Вариант 2 был бы идеален для обеспечения безупречного пользовательского опыта.

Окружение

  • Самостоятельно размещённый Discourse в Docker, локальное хранилище (без S3)
  • Версия Discourse: 2026.4.0-latest
  • Обратный прокси Apache перед nginx Discourse

Обходное решение

Для администраторов, столкнувшихся с этой проблемой, исправление включает:

  1. Идентификацию файлов VP9 с помощью ffprobe
  2. Перекодирование в H.264 с помощью ffmpeg -c:v libx264 -profile:v main -level 3.1 -r 30 -movflags +faststart
  3. Обновление полей sha1, url, filesize в таблице uploads
  4. Обновление коротких URL-токенов upload:// в сыром markdown затронутых сообщений
  5. Пересборку затронутых сообщений

Это нетривиальный ручной процесс, который большинство администраторов форумов не смогут выполнить самостоятельно.

1 лайк

Для автоматического перекодирования вы можете ознакомиться с Discourse Video Stream :movie_camera:.

Автоматическое локальное перекодирование работает, но основной проблемой является безопасная доставка для большинства конфигураций.

3 лайка

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

Ваше замечание о локальном транскодировании интересно. В процессе исправления я вручную запустил ffmpeg на 9 затронутых файлах на своём VPS, и сервер справился с этим без проблем. Я понимаю опасения относительно синхронного выполнения транскодирования во время загрузки: скачки нагрузки на процессор, таймауты и нагрузка на диск — всё это реальные риски. Но разве асинхронный подход с фоновыми задачами не решил бы большинство этих проблем? Загрузка завершалась бы нормально, а транскодирование выполнялось бы в очереди фоновых задач, как это уже делает Discourse при создании миниатюр изображений. Видео просто не было бы воспроизводимо на iOS до завершения задачи, что, по-видимому, является приемлемым компромиссом.

Даже без полноценного транскодирования более лёгкий вариант — обнаружение VP9 при загрузке и либо отказ с чётким сообщением об ошибке, либо пометка в панели администратора — значительно помог бы администраторам с самостоятельным размещением, у которых может не быть технической подготовки для диагностики тихих сбоев воспроизведения на iOS.

1 лайк

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

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

4 лайка