OpenTranscode/README.md

183 lines
8.3 KiB
Markdown
Executable File
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# OpenTranscode
A single-file, batch transcoding GUI for Linux built with PySide6. Wraps **av1an** for chunk-parallel AV1/VP9/x265 encoding with a retro-futuristic MMD3 media console aesthetic.
![Python 3.12+](https://img.shields.io/badge/Python-3.12%2B-blue)
![PySide6](https://img.shields.io/badge/PySide6-6.6%2B-green)
![Linux](https://img.shields.io/badge/Platform-Linux-orange)
![License: AGPL-3.0](https://img.shields.io/badge/License-AGPL--3.0-yellow)
![OpenTranscode](./OpenTranscode.png)
## Features
- **Batch encoding** — Drop a source folder, pick settings, hit encode. Processes every matching file recursively.
- **Three open codecs** — AV1 (SVT-AV1), VP9 (libvpx), x265 (HEVC) with per-codec preset selection.
- **Config-driven profiles** — Codecs, audio, containers, and resolutions defined as dataclass tables — no nested if/else chains.
- **av1an chunk-parallel encoding** — Scene-based chunking with multi-worker parallelism. Automatically detects `--chunk-method` support and scales workers to physical CPU cores minus one.
- **Lossless intermediate pipeline** — Resolution changes use a lossless libx264 ultrafast CRF 0 pre-scale pass (yuv420p10le) with duration integrity verification before the final encode.
- **Forced subtitle muxing** — Optional soft-subtitle remux post-encode. Prefers forced-disposition tracks. Container-aware: WebVTT for WebM, stream copy for MKV.
- **Audio normalization** — Rotary volume knob (-20 dB to +6 dB gain).
- **Real-time FFmpeg library probing** — Greys out audio codecs whose underlying FFmpeg libraries are missing.
- **Distro-aware dependency management** — Auto-detects Arch, Debian/Ubuntu, Fedora/RHEL/Rocky/Alma, openSUSE, and NixOS. Installs packages, handles av1an version conflicts, and builds from source when repos are stale.
- **Post-encode integrity checks** — Verifies output file size (≥ 5% of source) and duration (≥ 95% of source) before accepting. Failed outputs are deleted automatically.
- **Batch delete with confirmation** — Single pre-flight prompt showing file count and total size. Sources deleted only after individual verification passes.
- **Custom radio-knob widgets** — Retro rotary controls for CRF and audio normalization with snap-to-tick, glow indicators, and mouse/scroll interaction.
- **MMD3 theme** — Brushed aluminum, amber/green LED displays, beveled metallic panels via QSS.
## Requirements
| Dependency | Minimum Version | Purpose |
|---|---|---|
| Python | 3.12+ | Runtime |
| PySide6 | 6.6+ | Qt6 GUI framework |
| av1an | 0.4.0+ | Chunk-parallel encoder frontend |
| FFmpeg | 5.0+ (with libsvtav1, libvpx, libx265, libopus, libvorbis, flac) | Encoding, probing, remuxing |
| ffprobe | (bundled with FFmpeg) | Stream analysis and validation |
| mkvtoolnix | any | MKV container support |
| Rust/Cargo | latest stable | Building av1an from source (if repo version is stale) |
### Per-Distro Package Lists
**Arch / Manjaro / Endeavouros / Garuda / CachyOS:**
`ffmpeg mkvtoolnix-cli nasm cython gcc cmake git ninja python-pip svt-av1 rav1e aom libvpx x265 libopus libvorbis flac`
**Debian / Ubuntu / Linux Mint / Pop!_OS:**
`ffmpeg av1an mkvtoolnix svt-av1 rav1e aom-tools libvpx-tools x265 nasm gcc cmake git cargo rustc`
**Fedora:**
`ffmpeg mkvtoolnix svt-av1 rav1e aom libvpx x265 nasm gcc cmake git ninja-build cargo rustc` (requires RPM Fusion)
**RHEL / CentOS / Rocky / Alma:**
Same as Fedora, plus `epel-release` and RPM Fusion.
**openSUSE (Tumbleweed/Leap):**
`ffmpeg av1an mkvtoolnix svt-av1 rav1e aom-tools libvpx-tools x265 nasm gcc cmake git ninja cargo rustc` (requires Packman repo)
**NixOS:**
Manual configuration required — see quickstart.
> All distros: if the packaged av1an is below 0.4.0, the app automatically builds from git.
## Install & Run
```bash
# Clone the repo
git clone https://github.com/YOUR_USER/open-transcode.git
cd open-transcode
# Install Python dependency
pip install PySide6
# Run — dependency auto-install triggers on first launch
python open-transcode-master.py
```
On first launch, if av1an or FFmpeg is missing, the app detects your distro and offers to install everything automatically (Arch, Debian, Fedora, openSUSE). NixOS users will see a config snippet to paste into their configuration.
## Project Structure
```
open-transcode/
├── open-transcode-master.py # Single-file application (~2800 lines)
├── README.md # This file
├── quickstart.md # Setup & first-encode walkthrough
├── LICENSE # AGPL-3.0
└── .gitignore # Python/Qt/OS artifacts
```
## How It Works
### Encoding Pipeline
```
Source file
├─ ffprobe pre-validation (skip if no video stream or < 0.5s)
├─ [If resolution != Original]
│ └─ Lossless pre-scale → {file}.scaled_tmp.mkv
│ (libx264 ultrafast CRF 0, yuv420p10le, scale+pad filter)
│ └─ Duration integrity check (≥ 95% of source)
├─ av1an encode (chunk-parallel, scene-based splitting)
│ └─ Workers: physical_cores - 1
├─ Post-encode verification
│ ├─ Size check: output ≥ 5% of source
│ └─ Duration check: output ≥ 95% of source
├─ [If subtitle language selected]
│ └─ Soft subtitle remux (forced track preferred)
│ ├─ MKV: -c:s copy (any codec)
│ └─ WebM: -c:s webvtt (container requirement)
└─ [If delete-source enabled]
└─ Delete source (only after verification passes)
```
### Distro Auto-Detection
On startup, reads `/etc/os-release` and matches against known distro families. Each family has:
- Package manager and install command template
- Extra binary search paths (e.g. `~/.cargo/bin` for Rust-built tools)
- Distro-specific av1an encoder name quirks
- A dedicated `*_prep_deps()` function with fine-grained package installation
### Config-Driven Profiles
All codec/container/audio/resolution options are defined as `@dataclass` tables:
- `VIDEO_CODECS` — Label, av1an encoder name, CRF range, default CRF, params function, preset map
- `AUDIO_PROFILES` — Label + FFmpeg parameter tokens
- `CONTAINER_PROFILES` — Label + file extension
- `RESOLUTION_PRESETS` — Label, category (standard/wide/ultrawide/original), dimensions
- `SUBTITLE_OPTIONS` — Label + ISO 639-2 language code (or None)
The UI indexes into these tables — zero conditional logic for profile selection.
## Supported Input Formats
Default: `.mp4 .mkv .avi .mov .ts .m4v .flv .wmv .webm .mpg .mpeg`
Configurable at runtime via the FILTER field in the UI (comma-separated extensions).
## Supported Output Formats
| Container | Video Codecs | Audio Codecs | Subtitles |
|---|---|---|---|
| MKV (.mkv) | AV1, VP9, x265 | Opus, Vorbis, FLAC | Any (stream copy) |
| WebM (.webm) | AV1, VP9 | Opus, Vorbis, FLAC | WebVTT only |
## UI Controls
| Control | Type | Range / Options |
|---|---|---|
| SOURCE / SINK | Path fields + browse | Any directory |
| VIDEO | Combo | AV1 (SVT-AV1), VP9, x265 (HEVC) |
| PRESET | Combo | 4 per codec (e.g. Slow/Medium/Fast/Faster) |
| AUDIO | Combo | Opus 96k/128k/64k, Vorbis 128k/192k, FLAC |
| CONTAINER | Combo | MKV, WebM |
| RESOLUTION | Combo | Original, 720p4K (16:9 / 21:9 / 32:9) |
| SUBS | Combo | None, English (forced track preferred) |
| CRF | Rotary knob | 1852 (codec-dependent range) |
| AUDIO NORM | Rotary knob | -20 dB to +6 dB (0 = off) |
| DELETE SOURCE | Checkbox | Per-batch confirmation prompt |
## Troubleshooting
**av1an build fails:** Ensure Rust is installed (`rustup`) and you have ~2 GB of free disk space in `/tmp`. The build takes 515 minutes depending on hardware.
**Codec greyed out:** The corresponding FFmpeg library is missing. Install it via your package manager or re-run the auto-prep.
**"chunk-method not recognized":** Your av1an is below 0.4.0. The auto-prep should handle this by building from git. If it doesn't, manually remove the packaged av1an and rebuild.
**WebM + non-WebVTT subtitles fail:** WebM only supports WebVTT subtitles. The app auto-converts during remux. If the source subtitle codec can't be converted, the mux is silently skipped.
**Permission denied on av1an install:** The git build attempts `sudo cp` to `/usr/local/bin`. Ensure your user has sudo access, or manually copy the binary from `/tmp/av1an-build/target/release/av1an`.
## License
AGPL-3.0 — see [LICENSE](LICENSE).