Add video as a media kind in photos: streaming upload with per-kind limits, ffprobe metadata, poster frame reusing the image variant pipeline, and a playback object (remux when web-compatible, else h264/yuv420p/aac transcode). Video jobs run on a separate pool with a long lease. Frontend gains a video viewer, grid badge/duration and video upload.
112 lines
7.3 KiB
Markdown
112 lines
7.3 KiB
Markdown
# Spec Delta
|
||
|
||
## Purpose
|
||
|
||
Поддержка видео в альбомах: приём файла, фоновая подготовка web-совместимого варианта,
|
||
постер-кадр и воспроизведение в браузере.
|
||
|
||
## ADDED Requirements
|
||
|
||
### Requirement: Приём видео
|
||
Участник с правом загрузки SHALL загружать видео в альбом; система SHALL принимать ввод
|
||
`video/*` и SHALL отклонять файлы сверх лимита видео понятной ошибкой о превышении размера.
|
||
|
||
#### Scenario: Успешная загрузка видео
|
||
- **WHEN** участник с правом загрузки отправляет видеофайл в пределах лимита
|
||
- **THEN** система сохраняет оригинал и создаёт медиа-запись с признаком видео
|
||
|
||
#### Scenario: Превышение лимита видео
|
||
- **WHEN** загружается файл больше лимита видео
|
||
- **THEN** система отклоняет загрузку с явной ошибкой о превышении размера
|
||
|
||
#### Scenario: Не медиафайл
|
||
- **WHEN** загружается файл, не являющийся изображением или видео
|
||
- **THEN** система отклоняет загрузку
|
||
|
||
### Requirement: Метаданные видео
|
||
При обработке система SHALL извлекать длительность, размеры кадра и поворот и SHALL
|
||
возвращать длительность в данных медиа.
|
||
|
||
#### Scenario: Длительность доступна
|
||
- **WHEN** видео успешно обработано
|
||
- **THEN** данные медиа содержат длительность видео
|
||
|
||
#### Scenario: Метаданные недоступны
|
||
- **WHEN** из видео не удаётся извлечь метаданные
|
||
- **THEN** запись сохраняется, а длительность пуста
|
||
|
||
### Requirement: Постер видео
|
||
Система SHALL извлекать кадр-постер и SHALL генерировать из него варианты thumb, medium и
|
||
preview тем же способом, что для изображений, чтобы сетка и обложка отображали видео постером.
|
||
|
||
#### Scenario: Генерация постера
|
||
- **WHEN** видео обработано
|
||
- **THEN** система создаёт варианты thumb, medium и preview из кадра-постера
|
||
|
||
#### Scenario: Обложка из видео
|
||
- **WHEN** видео становится обложкой альбома
|
||
- **THEN** альбом отображает постер видео
|
||
|
||
### Requirement: Гарантированное воспроизведение
|
||
Система SHALL готовить воспроизводимый вариант видео: SHALL выполнять remux без
|
||
перекодирования, когда источник web-совместим, и SHALL транскодировать в h264/yuv420p/aac
|
||
с faststart иначе; система SHALL NOT увеличивать разрешение и SHALL ограничивать длинную
|
||
сторону 1080p.
|
||
|
||
#### Scenario: Совместимый источник
|
||
- **WHEN** источник — h264/yuv420p с совместимым профилем, звуком aac или без звука, в подходящем контейнере и в пределах разрешения
|
||
- **THEN** система подготавливает вариант remux без перекодирования
|
||
|
||
#### Scenario: Несовместимый источник
|
||
- **WHEN** источник не является web-совместимым (например, hevc, 10-bit или yuv444)
|
||
- **THEN** система транскодирует видео в h264/yuv420p/aac
|
||
|
||
#### Scenario: Разрешение выше предела
|
||
- **WHEN** длинная сторона источника превышает 1080p
|
||
- **THEN** система масштабирует видео до 1080p, не увеличивая меньший источник
|
||
|
||
### Requirement: Готовность и воспроизведение видео
|
||
Данные медиа SHALL содержать адрес воспроизводимого варианта, когда он готов; клиент SHALL
|
||
воспроизводить его с перемоткой; до готовности система SHALL отдавать постер и признак
|
||
обработки, а обновление о готовности SHALL транслироваться подписчикам.
|
||
|
||
#### Scenario: Вариант не готов
|
||
- **WHEN** видео ещё обрабатывается
|
||
- **THEN** данные медиа содержат постер и не содержат адрес воспроизведения
|
||
|
||
#### Scenario: Вариант готов
|
||
- **WHEN** обработка завершена
|
||
- **THEN** данные медиа содержат адрес воспроизведения, а подписчики получают обновление
|
||
|
||
#### Scenario: Перемотка
|
||
- **WHEN** клиент перематывает воспроизведение
|
||
- **THEN** система отдаёт запрошенный диапазон байт
|
||
|
||
### Requirement: Фоновая подготовка видео
|
||
Задание подготовки видео SHALL выполняться в фоне с длительным лизингом, таймаутом и
|
||
повторами при сбое и SHALL NOT вытеснять генерацию вариантов изображений.
|
||
|
||
#### Scenario: Повтор при сбое
|
||
- **WHEN** подготовка видео завершается ошибкой
|
||
- **THEN** задание повторяется с задержкой до достижения предела попыток
|
||
|
||
#### Scenario: Изоляция от картинок
|
||
- **WHEN** длительное видео обрабатывается
|
||
- **THEN** генерация вариантов изображений продолжает выполняться
|
||
|
||
### Requirement: Оригинал видео
|
||
Система SHALL сохранять исходный видеофайл и SHALL использовать его для скачивания
|
||
независимо от подготовленного варианта.
|
||
|
||
#### Scenario: Скачивание оригинала
|
||
- **WHEN** участник скачивает видео
|
||
- **THEN** система возвращает адрес исходного файла
|
||
|
||
### Requirement: Отсутствие видео-инструментов
|
||
При отсутствии `ffmpeg`/`ffprobe` система SHALL отключать приём видео и SHALL отражать
|
||
недоступность видео-обработки в состоянии здоровья.
|
||
|
||
#### Scenario: Инструменты отсутствуют
|
||
- **WHEN** видео-инструменты недоступны
|
||
- **THEN** приём видео отклоняется, а health сообщает о недоступности видео
|