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.
58 lines
4.4 KiB
Markdown
58 lines
4.4 KiB
Markdown
# Proposal
|
||
|
||
## Why
|
||
|
||
Альбом задуман как общее пространство для медиа семьи или команды, но сегодня принимает
|
||
только изображения: загрузка отклоняет всё, что не `image/*`, генерация вариантов и
|
||
вьюер работают исключительно с картинками. Видео с телефонов и камер остаётся вне
|
||
системы — теряется в мессенджерах и разрывает контекст альбома. Пользователю нужно
|
||
загружать видео в те же альбомы и гарантированно воспроизводить его в браузере.
|
||
|
||
## What Changes
|
||
|
||
- Загрузка видео в альбом наравне с фото: стриминг multipart, отдельный лимит 2 ГБ
|
||
(картинки остаются 100 МБ).
|
||
- Сущность фото становится медиа-записью: `kind` (`image` | `video`), `duration_ms`,
|
||
`playback_url`; набор ролей объекта пополняется ролью `playback`.
|
||
- Асинхронная подготовка видео в фоне: извлечение метаданных (ffprobe), постер-кадр
|
||
(переиспользует существующую генерацию WebP-вариантов thumb/medium/preview) и
|
||
воспроизводимый mp4 — remux без перекодирования для web-совместимых источников,
|
||
иначе транскод в h264/yuv420p/aac с `faststart`.
|
||
- Очередь заданий различает вид задачи и отделяет длительные (транскод) задания от
|
||
коротких (картинки): длительный лизинг, таймаут и отдельный малый пул, чтобы
|
||
транскод не вытеснял генерацию вариантов изображений.
|
||
- Внешняя зависимость `ffmpeg`/`ffprobe` (без Docker — бинарник на хосте): путь
|
||
конфигурируется, доступность отражается в health, при отсутствии видео-функции
|
||
отключаются.
|
||
- UI: плеер `<video>` во вьюере, постер и признак видео с длительностью в сетке,
|
||
приём видео в загрузчике.
|
||
- **BREAKING**: изменяются схема `photos` и ограничение ролей `photo_objects` на обоих
|
||
бэкендах метаданных (PostgreSQL и SQLite), с пересборкой таблицы в SQLite.
|
||
|
||
## Capabilities
|
||
|
||
### New Capabilities
|
||
|
||
- `videos`: обработка и воспроизведение видео в альбоме — приём файла, извлечение
|
||
метаданных, постер-кадр, remux/транскод в web-формат, контракт воспроизведения и
|
||
готовности.
|
||
|
||
### Modified Capabilities
|
||
|
||
- `photos`: сущность фото становится медиа-записью (`kind`, `duration_ms`,
|
||
`playback_url`); расширяется допустимый ввод и лимиты размера.
|
||
- `media-objects`: набор ролей объекта включает `playback`; очередь заданий различает
|
||
виды и поддерживает длительные задания с длительным лизингом.
|
||
- `ui-workspace`: вьюер, сетка и загрузчик получают поддержку видео.
|
||
- `dev-seed-data`: набор seed-данных включает видео-фикстуры.
|
||
|
||
## Impact
|
||
|
||
- **Backend**: `photos` (service, handlers, pipeline, worker, objects, keys), новые
|
||
миграции PostgreSQL и SQLite, `storage` (стриминговое чтение больших объектов),
|
||
`app` (роуты/health), `config` (VIDEO-*, FFMPEG_PATH, лимиты).
|
||
- **Frontend**: `types.ts`, `Viewer.svelte`, `PhotoGrid.svelte`, `Uploader.svelte`.
|
||
- **Зависимости**: `ffmpeg`/`ffprobe` на хосте; целевой remux/транскод в mp4 h264/aac.
|
||
- **Без изменений**: `albums`, `share-links`, `social`, `realtime` — работают через
|
||
роль `playback` и постер-картинку без правок поведения.
|