diff --git a/README.md b/README.md index d1e6915..85a5c8d 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@ 🇷🇺 Russian README: https://gromlab.ru/vod/create-vod/src/branch/master/README_RU.md -CLI tool to convert videos to DASH and HLS with hardware acceleration (NVENC / Intel QSV / AMD AMF / VAAPI), adaptive streaming, and automatic thumbnails/poster. Formats are always DASH + HLS. +CLI tool to convert videos to DASH and HLS with hardware acceleration (NVENC / Intel QSV / AMD AMF / VAAPI), adaptive streaming, and automatic thumbnails/poster. **Features:** - ⚡ Hardware acceleration: auto-detect encoder/decoder (NVENC / Intel QSV / AMD AMF / VAAPI / CPU) @@ -11,18 +11,8 @@ CLI tool to convert videos to DASH and HLS with hardware acceleration (NVENC / I - 🖼️ Preview: thumbnail sprite + VTT, poster from the first frame - ⏱️ Progress: per-profile and overall CLI progress bars -## Quick Start - -```bash -# Run via npx (no install) -npx @gromlab/create-vod video.mp4 - -# Or install globally -npm install -g @gromlab/create-vod -create-vod video.mp4 -``` - -**System requirements:** +## Install +For the CLI to work correctly, FFmpeg and MP4Box must be installed in the system. ```bash # Arch Linux sudo pacman -S ffmpeg gpac @@ -34,12 +24,24 @@ sudo apt install ffmpeg gpac brew install ffmpeg gpac ``` +## Quick Start +Before running, make sure `FFmpeg` and `MP4Box` are installed (see Install). + +```bash +# Run via npx (no install) +npx @gromlab/create-vod video.mp4 + +# Or install globally +npm install -g @gromlab/create-vod +create-vod video.mp4 +``` + **Output:** A folder `video/` in the current directory with segments under `{profile}-{codec}/`, DASH/HLS manifests in the root, poster, and thumbnail sprite/VTT (both DASH and HLS are always generated). ## CLI Usage ```bash -create-vod [output-dir] [-r resolutions] [-c codec] [-p poster-timecode] +create-vod [output-dir] [-r resolutions] [-c codec] [-p poster-timecode] [-e encoder] [-d decoder] ``` ### Main arguments @@ -109,6 +111,6 @@ High FPS (60/90/120) are generated only if the source supports that FPS. - Thumbnails: auto sprite (160×90, 1s interval) + VTT - Poster: first frame (0:00:00, configurable via `-p`) - Parallel encoding: enabled -- AV1: enabled only if hardware AV1 encoder detected (in auto mode); otherwise остаётся H.264 +- AV1: enabled only if hardware AV1 encoder detected (in auto mode); otherwise stays on H.264 **Requirements:** Node.js ≥18.0.0, FFmpeg, MP4Box (gpac), optional NVIDIA/Intel/AMD GPU for acceleration diff --git a/docs/QUALITY.md b/docs/QUALITY.md new file mode 100644 index 0000000..5c32d2b --- /dev/null +++ b/docs/QUALITY.md @@ -0,0 +1,40 @@ +# Регулировка качества и измерение + +## Целевое качество +- Ориентир: средний VMAF ≥ 93 для кодированного видео. + +## Что регулируем +- GPU-энкодеры используют CQ (Constant Quality). +- CPU-энкодеры используют CRF (Constant Rate Factor). +- Значения по умолчанию взяты из текущей логики кодирования (см. `src/core/encoding.ts`) и могут быть переопределены через CLI (`--h264-cq`, `--h264-crf`, `--av1-cq`, `--av1-crf`). + +## Дефолтные CQ/CRF + +| Энкодер | H.264 | AV1 | +|------------------|-----------------|----------------| +| NVENC | CQ 32 | CQ 42 | +| QSV | CQ 32 | CQ 42 | +| AMF | CQ 32 | CQ 42 | +| VAAPI | CQ 32 | CQ 42 | +| videotoolbox | CQ 32 | CQ 42 | +| v4l2 | CQ 32 | CQ 42 | +| CPU (libx264 / libsvtav1) | CRF 25→20* | CRF 40→28* | + +\* CPU значения зависят от целевого разрешения: +- 360p: H.264 CRF 25, AV1 CRF 40 +- 480p: H.264 CRF 24, AV1 CRF 38 +- 720p: H.264 CRF 23, AV1 CRF 35 +- 1080p: H.264 CRF 22, AV1 CRF 32 +- 1440p: H.264 CRF 21, AV1 CRF 30 +- 2160p: H.264 CRF 20, AV1 CRF 28 + +## Как мерить качество (VMAF) +1. Закодируйте тестовый ролик с нужными параметрами (CQ/CRF). +2. Сравните с исходником по VMAF (разрешения должны совпадать, при необходимости приведите к одному размеру). +3. Пример команды FFmpeg c libvmaf: + ```bash + ffmpeg -i encoded.mp4 -i source.mp4 \ + -lavfi "[0:v]setpts=PTS-STARTPTS[enc];[1:v]setpts=PTS-STARTPTS[ref];[enc][ref]libvmaf=log_path=vmaf.json:log_fmt=json" \ + -f null - + ``` + В логах ищите `VMAF score`; если < 93 — увеличьте качество (понизьте CQ/CRF), если > 95 и нужен меньший битрейт — можно чуть поднять CQ/CRF. diff --git a/package.json b/package.json index 16d3ec1..c0ba7e1 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "@gromlab/create-vod", "author": "Gromov Sergei", - "version": "0.1.8", + "version": "0.1.9", "description": "DASH/HLS video converter with hardware acceleration (NVENC/QSV/AMF/VAAPI), thumbnails and poster generation", "type": "module", "main": "./dist/index.js", diff --git a/src/config/profiles.ts b/src/config/profiles.ts index 3190df1..84a2dc4 100644 --- a/src/config/profiles.ts +++ b/src/config/profiles.ts @@ -87,7 +87,7 @@ export const DEFAULT_PROFILES: VideoProfile[] = [ /** * Select appropriate profiles based on input video resolution - * Only creates profiles that are equal to or smaller than input resolution + * Oriented by height: only profiles with height <= source height * Always generates 30 FPS profiles by default * For high FPS (>30), user must explicitly specify in customProfiles */ @@ -101,7 +101,7 @@ export function selectProfiles( // Standard 30 FPS profiles (always created) const baseProfiles = DEFAULT_PROFILES.filter(profile => { - return profile.width <= inputWidth && profile.height <= inputHeight; + return profile.height <= inputHeight; }); // Add standard 30fps profiles with bitrate limit @@ -206,8 +206,8 @@ export function validateProfile( } // Check if source supports this resolution - if (profile.width > sourceWidth || profile.height > sourceHeight) { - return { error: `Source resolution (${sourceWidth}x${sourceHeight}) is lower than ${profileStr} (${profile.width}x${profile.height})` }; + if (profile.height > sourceHeight) { + return { error: `Source height (${sourceHeight}px) is lower than requested ${profileStr} height (${profile.height}px)` }; } // Check if requested FPS exceeds source FPS @@ -271,4 +271,3 @@ export function createProfilesFromStrings( return { profiles, errors, warnings }; } -