feat: Обновленая реализация CLI

This commit is contained in:
2026-01-20 00:25:55 +03:00
commit b93554f0cd
25 changed files with 4618 additions and 0 deletions

404
docs/CLI_REFERENCE.md Normal file
View File

@@ -0,0 +1,404 @@
# CLI Reference — Справочник команд
Полное руководство по использованию DASH Video Converter CLI.
---
## Синтаксис
```bash
create-vod <input-video> [output-dir] [options]
```
## Позиционные аргументы
| Аргумент | Описание | По умолчанию |
|----------|----------|--------------|
| `input-video` | Путь к входному видео файлу | **Обязательный** |
| `output-dir` | Директория для сохранения результата | `.` (текущая папка) |
---
## Опции
### `-r, --resolutions` — Профили разрешений
Задает список профилей для генерации. Можно указывать разрешение и FPS.
**Формат:**
- `<resolution>` — только разрешение (FPS = 30)
- `<resolution>@<fps>` — разрешение с FPS (разделитель `@`)
- `<resolution>-<fps>` — разрешение с FPS (разделитель `-`)
**Поддерживаемые разрешения:**
- `360p` (640×360)
- `480p` (854×480)
- `720p` (1280×720)
- `1080p` (1920×1080)
- `1440p` (2560×1440)
- `2160p` (3840×2160)
**Примеры:**
```bash
# Базовые разрешения (30 FPS)
create-vod video.mp4 -r 360,720,1080
# С указанием FPS
create-vod video.mp4 -r 720@60,1080@60
# Смешанный формат
create-vod video.mp4 -r 360 720@60 1080 1440@120
```
**Автоматическая коррекция FPS:**
- Если запрошенный FPS > FPS источника → используется FPS источника
- Максимальный FPS: **120** (ограничение системы)
- Система выведет предупреждение при коррекции
**По умолчанию:** Автоматический выбор всех подходящих разрешений (≤ разрешения источника) с 30 FPS.
---
### `-c, --codec` — Видео кодек
Выбор видео кодека для кодирования.
**Значения:**
- `h264` — только H.264 (максимальная совместимость)
- `av1` — только AV1 (лучшее сжатие, новые браузеры)
- `dual`оба кодека (рекомендуется)
**Примеры:**
```bash
# Только H.264 (быстрее, больше места)
create-vod video.mp4 -c h264
# Только AV1 (медленнее, меньше места)
create-vod video.mp4 -c av1
# Оба кодека (максимальная совместимость)
create-vod video.mp4 -c dual
```
**GPU ускорение:**
- H.264: `h264_nvenc` (NVIDIA), fallback → `libx264` (CPU)
- AV1: `av1_nvenc` (NVIDIA), `av1_qsv` (Intel), `av1_amf` (AMD), fallback → `libsvtav1` (CPU)
**По умолчанию:** `dual`
---
### `--accel` — Аппаратный ускоритель
Выбор приоритетного ускорителя. По умолчанию выбирается лучший из доступных.
**Значения:**
- `auto` — автоопределение по приоритету (NVENC → QSV → AMF → CPU)
- `nvenc` — NVIDIA NVENC
- `qsv` — Intel Quick Sync
- `amf` — AMD AMF
- `cpu` — принудительно без GPU
**Примеры:**
```bash
create-vod video.mp4 --accel nvenc
create-vod video.mp4 --accel qsv
create-vod video.mp4 --accel cpu # отключить GPU
```
---
### `-f, --format` — Формат стриминга
Выбор формата адаптивного стриминга.
**Значения:**
- `dash` — только DASH (MPEG-DASH)
- `hls` — только HLS (HTTP Live Streaming)
- `both`оба формата
**Примеры:**
```bash
# Только DASH
create-vod video.mp4 -f dash
# Только HLS (для Safari/iOS)
create-vod video.mp4 -f hls
# Оба формата (максимальная совместимость)
create-vod video.mp4 -f both
```
**Особенности:**
| Формат | Кодеки | Совместимость | Примечание |
|--------|--------|---------------|------------|
| DASH | H.264 + AV1 | Chrome, Firefox, Edge, Safari (с dash.js) | Стандарт индустрии |
| HLS | H.264 только | Safari, iOS, все браузеры | Требует H.264 |
| both | H.264 + AV1 (DASH), H.264 (HLS) | Максимальная | Рекомендуется |
**Ограничения:**
- HLS требует `--codec h264` или `--codec dual`
- AV1 не поддерживается в HLS (Safari не поддерживает AV1)
**Файловая структура:**
```
output/
└── video_name/
├── 720p-h264/ ← Сегменты H.264 720p
│ ├── 720p-h264_.mp4
│ ├── 720p-h264_1.m4s
│ └── playlist.m3u8 ← HLS медиа плейлист
├── 720p-av1/ ← Сегменты AV1 720p (только для DASH)
│ ├── 720p-av1_.mp4
│ └── 720p-av1_1.m4s
├── audio/ ← Аудио сегменты
│ ├── audio_.mp4
│ ├── audio_1.m4s
│ └── playlist.m3u8
├── manifest.mpd ← DASH манифест (корень)
├── master.m3u8 ← HLS мастер плейлист (корень)
├── poster.jpg ← Общие файлы
├── thumbnails.jpg
└── thumbnails.vtt
```
**Преимущества структуры:**
- Сегменты хранятся один раз (нет дублирования)
- DASH и HLS используют одни и те же .m4s файлы
- Экономия 50% места при `format=both`
**По умолчанию:** `both` (максимальная совместимость)
---
### `-p, --poster` — Тайм-код постера
Время, с которого извлечь кадр для постера.
**Формат:**
- Секунды: `5`, `10.5`
- Тайм-код: `00:00:05`, `00:01:30`
**Примеры:**
```bash
# 5 секунд от начала
create-vod video.mp4 -p 5
# 1 минута 30 секунд
create-vod video.mp4 -p 00:01:30
```
**По умолчанию:** `00:00:00` (первый кадр)
---
## Примеры использования
### Базовое использование
```bash
# Простейший запуск (оба формата, dual codec, автопрофили)
create-vod video.mp4
# С указанием выходной директории
create-vod video.mp4 ./output
```
### Кастомные профили
```bash
# Только 720p и 1080p
create-vod video.mp4 -r 720,1080
# High FPS профили
create-vod video.mp4 -r 720@60,1080@60,1440@120
# Один профиль 4K
create-vod video.mp4 -r 2160
```
### Выбор кодека
```bash
# Быстрое кодирование (только H.264)
create-vod video.mp4 -c h264
# Лучшее сжатие (только AV1)
create-vod video.mp4 -c av1
# Максимальная совместимость
create-vod video.mp4 -c dual
```
### Выбор формата
```bash
# DASH для современных браузеров
create-vod video.mp4 -f dash
# HLS для Safari/iOS
create-vod video.mp4 -f hls -c h264
# Оба формата для всех устройств
create-vod video.mp4 -f both -c dual
```
### Комбинированные примеры
```bash
# Производственная конфигурация
create-vod video.mp4 ./cdn/videos -r 360,720,1080 -c dual -f both
# High-end конфигурация (4K, high FPS)
create-vod video.mp4 -r 720@60,1080@60,1440@120,2160@60 -c dual -f both
# Быстрая конвертация для тестов
create-vod video.mp4 -r 720 -c h264 -f dash
# Mobile-first (низкие разрешения, HLS)
create-vod video.mp4 -r 360,480,720 -c h264 -f hls
# Кастомный постер
create-vod video.mp4 -r 720,1080 -p 00:02:30
```
---
## Системные требования
### Обязательные зависимости
- **FFmpeg** — кодирование видео
- **MP4Box (GPAC)** — упаковка DASH/HLS
Установка:
```bash
# Arch Linux
sudo pacman -S ffmpeg gpac
# Ubuntu/Debian
sudo apt install ffmpeg gpac
# macOS
brew install ffmpeg gpac
```
### Опциональные (для GPU ускорения)
- **NVIDIA GPU** — для H.264/AV1 кодирования через NVENC
- **Intel GPU** — для AV1 через QSV
- **AMD GPU** — для AV1 через AMF
---
## Производительность
### CPU vs GPU
| Кодек | CPU | GPU (NVENC) | Ускорение |
|-------|-----|-------------|-----------|
| H.264 | libx264 | h264_nvenc | ~10-20x |
| AV1 | libsvtav1 | av1_nvenc | ~15-30x |
### Параллельное кодирование
- **GPU**: до 3 профилей одновременно
- **CPU**: до 2 профилей одновременно
### Время конвертации (примерные данные)
Видео 4K, 10 секунд, dual codec, 3 профиля:
| Конфигурация | Время |
|--------------|-------|
| CPU (libx264 + libsvtav1) | ~5-10 минут |
| GPU (NVENC) | ~30-60 секунд |
---
## Рекомендации
### Для максимальной совместимости
```bash
create-vod video.mp4 -c dual -f both
```
Генерирует:
- DASH с H.264 + AV1 (Chrome, Firefox, Edge)
- HLS с H.264 (Safari, iOS)
- Все современные устройства поддерживаются
### Для быстрой разработки
```bash
create-vod video.mp4 -r 720 -c h264 -f dash
```
Быстрое кодирование одного профиля.
### Для продакшена
```bash
create-vod video.mp4 -r 360,480,720,1080,1440 -c dual -f both
```
Широкий диапазон профилей для всех устройств.
### Для 4K контента
```bash
create-vod video.mp4 -r 720,1080,1440,2160 -c dual -f both
```
От HD до 4K для премиум контента.
---
## Устранение проблем
### HLS требует H.264
**Ошибка:**
```
❌ Error: HLS format requires H.264 codec
```
**Решение:**
```bash
# Используйте h264 или dual
create-vod video.mp4 -f hls -c h264
# или
create-vod video.mp4 -f hls -c dual
```
### FPS источника ниже запрошенного
**Предупреждение:**
```
⚠️ Requested 120 FPS, but source is 60 FPS. Using 60 FPS instead
```
Это нормально! Система автоматически ограничивает FPS до максимума источника.
### MP4Box не найден
**Ошибка:**
```
❌ MP4Box not found
```
**Решение:**
```bash
sudo pacman -S gpac # Arch
sudo apt install gpac # Ubuntu
```
---
## См. также
- [FEATURES.md](./FEATURES.md) — Возможности и технические детали
- [PUBLISHING.md](./PUBLISHING.md) — Публикация пакета в npm
- [README.md](../README.md) — Быстрый старт

213
docs/FEATURES.md Normal file
View File

@@ -0,0 +1,213 @@
# Возможности DASH Video Converter
## Архитектура
Конвертация выполняется в два этапа для обеспечения стабильности и максимальной производительности:
**Этап 1: Кодирование** - тяжелая работа по перекодированию видео во все профили качества с использованием FFmpeg и NVENC.
**Этап 2: Упаковка DASH** - быстрая упаковка готовых MP4 файлов в DASH формат через MP4Box с генерацией манифеста.
Преимущества подхода:
- Стабильность: MP4Box специализируется на DASH, FFmpeg - на кодирование
- Параллелизм: все профили кодируются одновременно на GPU
- Надежность: разделение ответственности между инструментами
## Этап 1: Оптимизация и кодирование
### Стандартные профили разрешений
Автоматически создаются профили с частотой 30 FPS:
- 360p (640x360) - 800 kbps
- 480p (854x480) - 1200 kbps
- 720p (1280x720) - 2800 kbps
- 1080p (1920x1080) - 5000 kbps
### Опциональные профили высокого разрешения
Создаются только если исходное видео имеет соответствующее или более высокое разрешение:
- 2K (2560x1440) - если исходное >= 1440p
- 4K (3840x2160) - если исходное >= 2160p
Система автоматически определяет разрешение исходного видео и создает только применимые профили без upscaling.
### Высокочастотные профили
Система автоматически определяет частоту кадров исходного видео и создает дополнительные высокочастотные профили только если это поддерживается оригиналом:
- **Оригинал >= 45 FPS**: создаются профили @ 60 FPS для всех разрешений
- **Оригинал >= 75 FPS**: создаются профили @ 90 FPS для всех разрешений
- **Оригинал >= 95 FPS**: создаются профили @ 120 FPS для всех разрешений
Стандартные 30 FPS профили создаются всегда.
Пример: если исходное видео 60 FPS, будут созданы:
- 360p @ 30fps, 360p @ 60fps
- 480p @ 30fps, 480p @ 60fps
- 720p @ 30fps, 720p @ 60fps
- 1080p @ 30fps, 1080p @ 60fps
Интерполяция кадров не применяется - создаются только те частоты, которые нативно поддерживаются исходным материалом.
### Технические особенности
- **NVENC GPU ускорение**: аппаратное кодирование на видеокарте NVIDIA
- **GOP size выравнивание**: keyframe каждые N кадров для точной сегментации (N = FPS × segment_duration)
- **VBR режим**: переменный битрейт для оптимального качества
- **Умное кодирование аудио**: автоматический выбор оптимального битрейта без upscaling
- Целевой максимум: 256 kbps AAC стерео
- Фактический битрейт: `min(source_bitrate, 256 kbps)`
- Округление до стандартных значений: 64k, 96k, 128k, 192k, 256k
- Примеры: исходник 64 kbps → выход 64 kbps | исходник 320 kbps → выход 256 kbps
## Этап 2: Создание DASH
### Упаковка через MP4Box
- Создание фрагментированных MP4 сегментов длительностью 2 секунды
- Генерация единого MPD манифеста для всех профилей
- Выравнивание сегментов по Random Access Points (RAP)
### Организация файловой структуры
После упаковки файлы автоматически организуются в подпапки:
- Видео сегменты: `{resolution}/`
- Аудио сегменты: `audio/`
- Манифест: корень директории
Пути в MPD манифесте обновляются для соответствия структуре подпапок.
## Множественные аудио дорожки
### Поддержка озвучек и языков
Система поддерживает несколько аудио дорожек с различными источниками:
**Извлечение из видео**:
- Автоматическое извлечение всех аудио дорожек из входного файла
- Выбор конкретных дорожек по индексу
**Внешние файлы**:
- Добавление аудио из отдельных файлов (MP3, AAC, M4A)
- Синхронизация с видео
### Метаданные аудио дорожек
Каждая дорожка содержит метаданные для правильного отображения в плеере:
- **language**: код языка (ru, en, ja)
- **label**: название озвучки ("Кубик в кубе", "LostFilm", "Original")
- **role**: тип озвучки
- `main` - основная
- `dub` - дубляж
- `commentary` - комментарии
Пример структуры в MPD:
```xml
<AdaptationSet lang="ru" label="Кубик в кубе">
<Role schemeIdUri="urn:mpeg:dash:role:2011" value="dub"/>
<Representation id="audio_kubik" .../>
</AdaptationSet>
```
## Генерация постера
### Автоматический режим
По умолчанию постер создается из первого кадра видео (00:00:00).
### Указание таймкода
Возможно указание конкретного времени для извлечения постера:
Формат:
- `MM:SS` - минуты:секунды (например, `06:32`)
- `HH:MM:SS` - часы:минуты:секунды (например, `01:23:45`)
Команда:
```bash
--poster-time 06:32
```
Постер сохраняется в формате JPEG с оптимизированным качеством.
## Превью спрайты
### Thumbnail спрайты
Автоматическая генерация спрайта с миниатюрами для навигации по видео:
- **Интервал**: 1 секунда (по умолчанию)
- **Размер миниатюры**: 160x90 пикселей
- **Сетка**: 10 колонок, динамическое количество строк
- **Формат**: JPEG sprite
### WebVTT файл
Генерируется VTT файл с координатами каждой миниатюры:
```vtt
WEBVTT
00:00:00.000 --> 00:00:01.000
thumbnails.jpg#xywh=0,0,160,90
00:00:01.000 --> 00:00:02.000
thumbnails.jpg#xywh=160,0,160,90
```
Плееры используют VTT для отображения превью при наведении на timeline.
## Выходная структура файлов
### Организация директорий
```
output/
└── video-name/
├── manifest.mpd # Главный DASH манифест
├── poster.jpg # Постер видео
├── thumbnails.jpg # Спрайт превью
├── thumbnails.vtt # WebVTT для превью
├── audio/ # Аудио дорожки
│ ├── audio_init.m4s # Инициализационный сегмент
│ ├── audio_1.m4s # Сегмент #1
│ └── audio_N.m4s # Сегмент #N
├── 1080p/ # Профиль 1080p @ 30fps
│ ├── 1080p_init.m4s
│ ├── 1080p_1.m4s
│ └── 1080p_N.m4s
├── 1080p-60/ # Профиль 1080p @ 60fps (если применимо)
│ └── ...
├── 720p/ # Профиль 720p @ 30fps
│ └── ...
├── 480p/ # Профиль 480p @ 30fps
│ └── ...
└── 360p/ # Профиль 360p @ 30fps
└── ...
```
### Именование файлов
**Инициализационные сегменты**: `{profile}_init.m4s` или `{profile}_.mp4`
**Медиа сегменты**: `{profile}_{number}.m4s`
**Аудио**: `audio_{number}.m4s` или `audio_{lang}_{number}.m4s` для множественных дорожек
Имя выходной директории всегда соответствует имени входного видео файла (без расширения).
## Производительность
- Параллельное кодирование до 3 профилей одновременно (с NVENC)
- GOP size точно соответствует длительности сегмента для быстрой упаковки
- Временные файлы в `/tmp/` с автоочисткой
- Прогресс-бары в реальном времени для каждого профиля
## Требования
- **FFmpeg**: с поддержкой h264_nvenc (опционально), aac, scale
- **MP4Box** (GPAC): для DASH упаковки
- **NVIDIA GPU**: для NVENC ускорения (опционально, fallback на CPU)
- **Bun**: runtime окружение

135
docs/PUBLISHING.md Normal file
View File

@@ -0,0 +1,135 @@
# 📦 Инструкция по публикации в NPM
## Подготовка к публикации
### Шаг 1: Авторизация в NPM
```bash
npm login
```
Введите credentials для аккаунта с доступом к организации `@grom13`.
### Шаг 2: Сборка проекта
```bash
cd /home/gromov/projects/my/create-vod
npm run build
```
Эта команда выполнит:
- Сборку библиотеки в `dist/`
- Генерацию TypeScript деклараций (`.d.ts`)
- Сборку CLI бинарника в `bin/cli.js`
### Шаг 3: Проверка перед публикацией (опционально)
```bash
# Посмотреть какие файлы будут опубликованы
npm pack --dry-run
# Или создать тестовый архив для проверки
npm pack
# Это создаст файл gromlab-create-vod-0.1.0.tgz
```
## Публикация
### Шаг 4: Публикация в NPM
```bash
npm publish --access public
```
⚠️ **Важно:** Флаг `--access public` обязателен для scoped пакетов (`@grom13/...`), иначе NPM попытается опубликовать как приватный пакет (требует платную подписку).
### Шаг 5: Проверка публикации
```bash
# Проверить что пакет доступен
npm view @gromlab/create-vod
# Протестировать установку через npx
npx @gromlab/create-vod --help
# Или установить глобально и протестировать
npm install -g @gromlab/create-vod
dvc --help
```
## Обновление версии
Для будущих релизов используйте команды версионирования:
```bash
# Patch версия (0.1.0 → 0.1.1) - исправления багов
npm version patch
# Minor версия (0.1.0 → 0.2.0) - новые функции
npm version minor
# Major версия (0.1.0 → 1.0.0) - breaking changes
npm version major
```
После обновления версии:
```bash
npm publish --access public
```
## Откат публикации (если нужно)
```bash
# Удалить конкретную версию (в течение 72 часов)
npm unpublish @gromlab/create-vod@0.1.0
# Удалить весь пакет (использовать осторожно!)
npm unpublish @gromlab/create-vod --force
```
⚠️ **Внимание:** После unpublish нельзя повторно опубликовать ту же версию. Нужно увеличить версию.
## Использование после публикации
Пакет будет доступен для использования:
```bash
# Через npx (без установки)
npx @gromlab/create-vod video.mp4 ./output
# Глобальная установка
npm install -g @gromlab/create-vod
dvc video.mp4 ./output
# Локальная установка в проект
npm install @gromlab/create-vod
```
## Troubleshooting
### Ошибка: "You must sign up for private packages"
Решение: Добавьте флаг `--access public` при публикации.
### Ошибка: "You do not have permission to publish"
Решение: Убедитесь что вы авторизованы (`npm whoami`) и имеете доступ к организации `@grom13`.
### Ошибка при сборке
Решение: Убедитесь что установлены все зависимости:
```bash
npm install
# или
bun install
```
## Checklist перед публикацией
- [ ] Обновлена версия в `package.json`
- [ ] Обновлен `README.md` с актуальной информацией
- [ ] Проект успешно собирается (`npm run build`)
- [ ] Протестирован CLI локально
- [ ] Авторизованы в NPM (`npm whoami`)
- [ ] Проверены файлы для публикации (`npm pack --dry-run`)

View File

@@ -0,0 +1,558 @@
# Тестирование качества видео и сравнение кодеков
Руководство по анализу качества видео, сравнению кодеков и измерению эффективности сжатия.
## 📋 Содержание
1. [Метрики качества](#метрики-качества)
2. [Протестированные кодеки](#протестированные-кодеки)
3. [Результаты тестирования](#результаты-тестирования)
4. [Команды для тестирования](#команды-для-тестирования)
5. [Интерпретация результатов](#интерпретация-результатов)
6. [Рекомендации](#рекомендации)
---
## Метрики качества
### PSNR (Peak Signal-to-Noise Ratio)
**Что измеряет:** Отношение сигнал/шум в децибелах (dB). Показывает математическое отличие между оригиналом и сжатым видео.
**Интерпретация:**
- `> 45 dB` - Отличное качество (практически неразличимо)
- `40-45 dB` - Очень хорошее качество
- `35-40 dB` - Хорошее качество
- `30-35 dB` - Приемлемое качество
- `< 30 dB` - Плохое качество (видимые артефакты)
**Формула расчета:**
```
PSNR = 10 × log₁₀(MAX²/MSE)
```
где MAX - максимальное значение пикселя (255 для 8-bit), MSE - средняя квадратичная ошибка.
### SSIM (Structural Similarity Index)
**Что измеряет:** Структурное сходство изображений. Более точно отражает восприятие человеческим глазом.
**Интерпретация:**
- `1.0` - Идентичные изображения (100%)
- `> 0.99` - Отличное качество (99%+ схожести)
- `0.95-0.99` - Хорошее качество
- `0.90-0.95` - Приемлемое качество
- `< 0.90` - Заметная потеря качества
**Преимущества SSIM:**
- Учитывает яркость, контраст и структуру
- Лучше коррелирует с субъективной оценкой качества
- Более устойчива к локальным искажениям
---
## Протестированные кодеки
### 1. H.264 / AVC
**Описание:** Широко распространенный кодек, поддерживается всеми устройствами.
**Энкодеры:**
- `libx264` - CPU энкодер (отличное качество/размер)
- `h264_nvenc` - NVIDIA GPU энкодер (быстрее, но менее эффективен)
**Параметры качества:**
- CRF: 0-51 (меньше = лучше качество)
- Рекомендуемый диапазон: 18-28
- Пресеты: ultrafast, fast, medium, slow, slower, veryslow
### 2. VP9
**Описание:** Открытый кодек от Google, часть WebM. На 20-50% эффективнее H.264.
**Энкодеры:**
- `libvpx-vp9` - CPU энкодер
- `vp9_vaapi` - аппаратное ускорение (Intel/AMD)
**Параметры качества:**
- CRF: 0-63 (меньше = лучше качество)
- Рекомендуемый диапазон: 28-35
- cpu-used: 0-5 (меньше = лучше качество, медленнее)
### 3. AV1
**Описание:** Современный кодек, следующее поколение после VP9. На 30-50% эффективнее H.264.
**Энкодеры:**
- `libsvtav1` - CPU энкодер (быстрый, хорошее качество)
- `libaom-av1` - CPU энкодер (лучшее качество, очень медленный)
- `av1_nvenc` - NVIDIA GPU энкодер (быстро, но менее эффективен)
- `av1_amf` - AMD GPU энкодер
- `av1_qsv` - Intel GPU энкодер
**Параметры качества:**
- CRF (libsvtav1): 0-63 (меньше = лучше качество)
- CQ (av1_nvenc): 0-51 (меньше = лучше качество)
- Рекомендуемый диапазон: 30-40
---
## Результаты тестирования
### Тестовое видео
**Параметры:**
- Файл: `tenexia.mp4`
- Разрешение: 1920×1080 (Full HD)
- FPS: 25
- Длительность: 135 секунд (2:15)
- Оригинальный размер: 167 MB
- Оригинальный кодек: H.264 (битрейт ~10 Mbps)
### Сводная таблица результатов
| Кодек | Энкодер | Параметр | Размер | PSNR | SSIM | Сжатие | Скорость |
|-------|---------|----------|--------|------|------|--------|----------|
| **Оригинал** | - | - | 167 MB | - | - | 1.0x | - |
| **VP9** | libvpx-vp9 | CRF 32 | 13 MB | 47.42 dB | 0.9917 | 12.8x | ~5-10 мин |
| **AV1** | libsvtav1 | CRF 35 | 9.5 MB | 48.01 dB | 0.9921 | 17.6x | ~10-15 мин |
| **AV1** | av1_nvenc | CQ 32 | 20 MB | N/A | N/A | 8.3x | ~10 сек |
| **AV1** | av1_nvenc | CQ 40 | 9.3 MB | 47.13 dB | 0.9914 | 18.0x | ~10 сек |
| **AV1** | av1_nvenc | CQ 45 | 7.1 MB | 45.49 dB | 0.9899 | 23.5x | ~10 сек |
| **H.264** | libx264 | CRF 28 | 9.7 MB | 44.85 dB | 0.9904 | 17.2x | ~3-5 мин |
| **H.264** | h264_nvenc | CQ 28 | 20 MB | 47.88 dB | 0.9922 | 8.4x | ~10 сек |
| **H.264** | h264_nvenc | CQ 32 | 12 MB | N/A | N/A | 14.0x | ~10 сек |
| **H.264** | h264_nvenc | CQ 35 | 7.9 MB | 44.48 dB | 0.9891 | 21.1x | ~10 сек |
### Победители по категориям
🥇 **Лучшее качество:** AV1 CPU (CRF 35) - PSNR 48.01 dB, SSIM 0.9921
🥇 **Лучшее сжатие при сохранении качества:** AV1 GPU (CQ 40) - 9.3 MB, PSNR 47.13 dB
🥇 **Максимальное сжатие:** AV1 GPU (CQ 45) - 7.1 MB, PSNR 45.49 dB (всё ещё отличное)
**Лучший баланс скорость/качество:** AV1 GPU (CQ 40) - быстро + малый размер + хорошее качество
---
## Команды для тестирования
### 1. Анализ исходного видео
#### Получить метаданные с помощью ffprobe
```bash
# Полная информация в JSON формате
ffprobe -v error -show_format -show_streams -print_format json input.mp4
# Краткая информация о видео
ffprobe -v error -select_streams v:0 -show_entries stream=codec_name,width,height,r_frame_rate,bit_rate -of default=noprint_wrappers=1 input.mp4
# Информация об аудио
ffprobe -v error -select_streams a:0 -show_entries stream=codec_name,sample_rate,bit_rate,channels -of default=noprint_wrappers=1 input.mp4
# Размер файла и битрейт
ffprobe -v error -show_entries format=size,duration,bit_rate -of default=noprint_wrappers=1:nokey=1 input.mp4
```
### 2. Конвертация видео
#### VP9 (CPU)
```bash
# Базовая конвертация
ffmpeg -i input.mp4 \
-c:v libvpx-vp9 \
-crf 32 \
-b:v 0 \
-row-mt 1 \
-cpu-used 2 \
-c:a libopus \
-b:a 128k \
output_vp9.webm
# Параметры:
# -crf 32 - качество (18-40, меньше = лучше)
# -b:v 0 - режим постоянного качества
# -row-mt 1 - многопоточность
# -cpu-used 2 - скорость кодирования (0-5)
```
#### AV1 (CPU) - libsvtav1
```bash
# Рекомендуемая конфигурация
ffmpeg -i input.mp4 \
-c:v libsvtav1 \
-crf 35 \
-preset 6 \
-svtav1-params tune=0 \
-c:a libopus \
-b:a 128k \
output_av1_cpu.mp4
# Параметры:
# -crf 35 - качество (0-63, меньше = лучше)
# -preset 6 - скорость (0-13, 6 = средняя)
# -svtav1-params tune=0 - оптимизация под PSNR
```
#### AV1 (GPU) - NVIDIA
```bash
# Оптимальный баланс качество/размер
ffmpeg -i input.mp4 \
-c:v av1_nvenc \
-preset p7 \
-cq 40 \
-b:v 0 \
-c:a libopus \
-b:a 128k \
output_av1_gpu.mp4
# Параметры:
# -preset p7 - качество пресета (p1-p7, p7 = лучшее)
# -cq 40 - constant quality (0-51, меньше = лучше)
# -b:v 0 - без ограничения битрейта
# Максимальное сжатие (хорошее качество)
ffmpeg -i input.mp4 -c:v av1_nvenc -preset p7 -cq 45 -b:v 0 -c:a libopus -b:a 128k output_av1_small.mp4
```
#### AV1 (GPU) - AMD
```bash
ffmpeg -i input.mp4 \
-c:v av1_amf \
-quality quality \
-qp_i 40 -qp_p 40 \
-c:a libopus \
-b:a 128k \
output_av1_amd.mp4
```
#### AV1 (GPU) - Intel
```bash
ffmpeg -i input.mp4 \
-c:v av1_qsv \
-preset veryslow \
-global_quality 40 \
-c:a libopus \
-b:a 128k \
output_av1_intel.mp4
```
#### H.264 (CPU)
```bash
# Лучшее качество/размер
ffmpeg -i input.mp4 \
-c:v libx264 \
-crf 28 \
-preset slow \
-c:a aac \
-b:a 128k \
output_h264_cpu.mp4
# Параметры:
# -crf 28 - качество (18-28, меньше = лучше)
# -preset slow - компромисс скорость/качество
# (ultrafast, fast, medium, slow, slower, veryslow)
```
#### H.264 (GPU) - NVIDIA
```bash
# Баланс качество/размер
ffmpeg -i input.mp4 \
-c:v h264_nvenc \
-preset p7 \
-cq 33 \
-b:v 0 \
-c:a aac \
-b:a 128k \
output_h264_gpu.mp4
# Параметры:
# -preset p7 - качество (p1-p7)
# -cq 33 - constant quality (0-51)
```
### 3. Измерение качества
#### PSNR (Peak Signal-to-Noise Ratio)
```bash
# Базовый расчет PSNR
ffmpeg -i encoded.mp4 -i original.mp4 \
-lavfi "[0:v][1:v]psnr" \
-f null - 2>&1 | grep "PSNR"
# С сохранением детальной статистики в файл
ffmpeg -i encoded.mp4 -i original.mp4 \
-lavfi "[0:v][1:v]psnr=stats_file=psnr_stats.log" \
-f null -
# Просмотр статистики
head -5 psnr_stats.log && echo "..." && tail -5 psnr_stats.log
```
**Формат вывода:**
```
PSNR y:46.02 u:53.92 v:53.54 average:47.42 min:41.20 max:52.27
```
- `y` - яркость (luminance)
- `u`, `v` - цветовые каналы (chrominance)
- `average` - средний PSNR
- `min`, `max` - минимальный и максимальный PSNR по кадрам
#### SSIM (Structural Similarity Index)
```bash
# Базовый расчет SSIM
ffmpeg -i encoded.mp4 -i original.mp4 \
-lavfi "[0:v][1:v]ssim" \
-f null - 2>&1 | grep "SSIM"
# С сохранением детальной статистики
ffmpeg -i encoded.mp4 -i original.mp4 \
-lavfi "[0:v][1:v]ssim=stats_file=ssim_stats.log" \
-f null -
# Просмотр статистики
head -5 ssim_stats.log && echo "..." && tail -5 ssim_stats.log
```
**Формат вывода:**
```
SSIM Y:0.9887 (19.46 dB) U:0.9979 (26.70 dB) V:0.9979 (26.75 dB) All:0.9917 (20.83 dB)
```
- Значения 0.0-1.0 (1.0 = идентичные изображения)
- dB - SSIM в децибелах (для удобства сравнения)
#### VMAF (Video Multimethod Assessment Fusion)
VMAF - современная метрика от Netflix, лучше всего коррелирует с человеческим восприятием.
```bash
# Установка модели VMAF (один раз)
# Скачать модель с https://github.com/Netflix/vmaf/tree/master/model
# Расчет VMAF
ffmpeg -i encoded.mp4 -i original.mp4 \
-lavfi "[0:v][1:v]libvmaf=model_path=/path/to/vmaf_v0.6.1.json:log_path=vmaf.json" \
-f null -
# Интерпретация VMAF:
# 90-100 - Отличное качество
# 75-90 - Хорошее качество
# 50-75 - Приемлемое качество
# < 50 - Плохое качество
```
### 4. Полный скрипт для тестирования
Создайте файл `test_codec.sh`:
```bash
#!/bin/bash
# Использование: ./test_codec.sh input.mp4 encoded.mp4 output_dir
INPUT="$1"
ENCODED="$2"
OUTPUT_DIR="${3:-.}"
mkdir -p "$OUTPUT_DIR"
echo "=== Анализ размеров файлов ==="
echo "Оригинал:"
ls -lh "$INPUT" | awk '{print $5, $9}'
echo "Сжатый:"
ls -lh "$ENCODED" | awk '{print $5, $9}'
echo ""
# Рассчет сжатия
ORIG_SIZE=$(stat -f%z "$INPUT" 2>/dev/null || stat -c%s "$INPUT")
ENC_SIZE=$(stat -f%z "$ENCODED" 2>/dev/null || stat -c%s "$ENCODED")
RATIO=$(echo "scale=2; $ORIG_SIZE / $ENC_SIZE" | bc)
echo "Сжатие: ${RATIO}x"
echo ""
echo "=== Метаданные закодированного видео ==="
ffprobe -v error -show_format -show_streams -print_format json "$ENCODED" | \
grep -E "(codec_name|width|height|bit_rate|size)" | head -10
echo ""
echo "=== Расчет PSNR ==="
ffmpeg -i "$ENCODED" -i "$INPUT" \
-lavfi "[0:v][1:v]psnr=stats_file=$OUTPUT_DIR/psnr_stats.log" \
-f null - 2>&1 | grep "PSNR"
echo ""
echo "=== Расчет SSIM ==="
ffmpeg -i "$ENCODED" -i "$INPUT" \
-lavfi "[0:v][1:v]ssim=stats_file=$OUTPUT_DIR/ssim_stats.log" \
-f null - 2>&1 | grep "SSIM"
echo ""
echo "Детальная статистика сохранена в $OUTPUT_DIR/"
```
**Использование:**
```bash
chmod +x test_codec.sh
./test_codec.sh original.mp4 encoded.mp4 ./test_results
```
---
## Интерпретация результатов
### Матрица принятия решений
| Сценарий | Рекомендуемый кодек | Параметры | Ожидаемый результат |
|----------|---------------------|-----------|---------------------|
| Максимальное качество | AV1 CPU | CRF 30-35 | Лучшее качество, малый размер |
| Быстрое кодирование | AV1 GPU | CQ 38-42 | Быстро, хорошее качество |
| Совместимость | H.264 CPU | CRF 23-28 | Работает везде |
| Веб-стриминг | VP9 | CRF 30-35 | Хороший баланс |
| Архивирование | AV1 CPU | CRF 25-30 | Лучшее качество |
### Соответствие метрик и визуального качества
| PSNR | SSIM | Визуальная оценка |
|------|------|-------------------|
| > 45 dB | > 0.99 | Практически неотличимо от оригинала |
| 40-45 dB | 0.98-0.99 | Отличное качество, артефакты незаметны |
| 35-40 dB | 0.95-0.98 | Хорошее качество, артефакты видны при внимательном просмотре |
| 30-35 dB | 0.90-0.95 | Приемлемое качество, видимые артефакты |
| < 30 dB | < 0.90 | Плохое качество, явные артефакты |
### Факторы, влияющие на результаты
1. **Контент видео:**
- Статичные сцены сжимаются лучше
- Быстрое движение требует больше битрейта
- Детализированные текстуры сложнее сжать
- Темные сцены могут показывать бандинг
2. **Разрешение:**
- Высокие разрешения требуют более высокого битрейта
- При одинаковом CRF, 4K будет весить больше чем 1080p
3. **Частота кадров:**
- 60 FPS требует ~1.5-2x больше битрейта чем 30 FPS
- Высокий FPS важнее для игрового контента
4. **Цветовое пространство:**
- HDR (10-bit) требует ~20-30% больше битрейта
- Широкий цветовой охват увеличивает размер
---
## Рекомендации
### Для продакшена
**Adaptive Streaming (DASH/HLS):**
```bash
# Используйте несколько профилей качества
# 360p, 480p, 720p, 1080p, 1440p, 2160p
# Dual codec для максимальной совместимости:
# - AV1 для современных браузеров
# - H.264 для старых устройств (iOS < 14)
# Пример: create-vod уже реализует это
create-vod input.mp4 output/ -c dual -f both -r 360,720,1080
```
### Для архивирования
```bash
# Используйте AV1 CPU с низким CRF
ffmpeg -i input.mp4 \
-c:v libsvtav1 -crf 25 -preset 4 \
-c:a libopus -b:a 192k \
archive.mp4
```
### Для быстрой обработки
```bash
# Используйте GPU кодирование
ffmpeg -i input.mp4 \
-c:v av1_nvenc -preset p7 -cq 35 \
-c:a aac -b:a 128k \
quick_encode.mp4
```
### Подбор оптимального CRF/CQ
**Метод бинарного поиска:**
1. Начните с среднего значения (CRF 28 для H.264, 32 для VP9, 35 для AV1)
2. Закодируйте короткий фрагмент (30-60 сек)
3. Проверьте качество (PSNR > 45, SSIM > 0.99 для отличного качества)
4. Если качество избыточное - увеличьте CRF на 2-3
5. Если качество недостаточное - уменьшите CRF на 2-3
6. Повторяйте до достижения баланса
**Быстрый тест:**
```bash
# Извлечь 60 секунд с 30-й секунды
ffmpeg -ss 30 -i input.mp4 -t 60 -c copy sample.mp4
# Протестировать разные CRF
for crf in 30 32 35 38 40; do
ffmpeg -i sample.mp4 -c:v libsvtav1 -crf $crf -preset 8 -c:a copy test_crf${crf}.mp4
# Измерить качество
ffmpeg -i test_crf${crf}.mp4 -i sample.mp4 -lavfi "[0:v][1:v]psnr" -f null - 2>&1 | grep "PSNR"
# Размер файла
ls -lh test_crf${crf}.mp4
done
```
---
## Дополнительные ресурсы
### Инструменты
- **FFmpeg** - https://ffmpeg.org/
- **ffprobe** - анализ медиа файлов
- **MediaInfo** - GUI инструмент для анализа
- **Handbrake** - GUI для кодирования
- **ab-av1** - инструмент для подбора оптимальных параметров AV1
### Документация
- [FFmpeg Encoding Guide](https://trac.ffmpeg.org/wiki/Encode)
- [x264 Settings](https://trac.ffmpeg.org/wiki/Encode/H.264)
- [VP9 Encoding Guide](https://trac.ffmpeg.org/wiki/Encode/VP9)
- [SVT-AV1 Documentation](https://gitlab.com/AOMediaCodec/SVT-AV1)
- [NVIDIA Video Codec SDK](https://developer.nvidia.com/video-codec-sdk)
### Научные статьи
- "The Netflix Tech Blog: Per-Title Encode Optimization"
- "VMAF: The Journey Continues" - Netflix
- "AV1 Performance vs x265 and libvpx" - Facebook Engineering
---
## Changelog
**2025-11-12** - Создан документ на основе реальных тестов
- Протестированы кодеки: VP9, AV1 (CPU/GPU), H.264 (CPU/GPU)
- Добавлены все команды для тестирования
- Добавлены результаты сравнения на видео 1920×1080, 135 сек