Transcoding
Dubby transcodes media on-the-fly when your device doesn’t natively support the source format. These settings control how transcoding behaves.
Environment variables
Section titled “Environment variables”All transcoding settings can be set via environment variables, the YAML config file (dubby.yaml), or the admin UI. See Configuration for details on precedence and the full YAML reference.
| Variable | Default | Description |
|---|---|---|
DUBBY_GPU_ENABLED | true | Use hardware-accelerated encoding when available |
DUBBY_MULTI_QUALITY | false | Enable multi-quality adaptive bitrate (ABR) |
DUBBY_MAX_QUALITY_TIERS | 4 | Maximum quality tiers for ABR (1–6) |
DUBBY_TRANSCODING_DEFAULT_CRF | 23 | Constant rate factor (0–51, lower = better quality) |
DUBBY_TRANSCODING_DEFAULT_PRESET | fast | FFmpeg encoding preset (ultrafast–veryslow) |
DUBBY_TRANSCODING_HLS_SEGMENT_DURATION | 4 | HLS segment length in seconds (2–10) |
DUBBY_TRANSCODING_DISK_WARNING_THRESHOLD_GB | 10 | Warn when free disk drops below this (GB) |
DUBBY_TRANSCODING_DISK_CRITICAL_THRESHOLD_GB | 2 | Stop new transcodes below this (GB) |
DUBBY_TRANSCODING_MAX_CACHE_SIZE_PER_USER_GB | 20 | Max transcode cache per user (GB) |
DUBBY_TRANSCODING_MAX_TOTAL_CACHE_SIZE_GB | 100 | Max total transcode cache (GB) |
GPU transcoding
Section titled “GPU transcoding”When DUBBY_GPU_ENABLED=true (the default), the server probes for available hardware encoders at startup and selects the best one:
- NVIDIA NVENC — Dedicated GPU encoder (fastest, best quality)
- Apple VideoToolbox — macOS/Apple Silicon hardware encoder
- Intel Quick Sync (QSV) — Integrated GPU on 6th-gen Intel and newer
- AMD VAAPI — GPU encoder on Linux with proper kernel driver
- AMD AMF — GPU encoder on Windows
- Software (libx264/libx265) — CPU fallback, always available
If no GPU is detected, the server falls back to software encoding automatically. You can force software-only transcoding by setting DUBBY_GPU_ENABLED=false.
For GPU setup instructions, see Hardware Acceleration.
Audio transcoding
Section titled “Audio transcoding”Audio is transcoded when the client doesn’t support the source codec. The server selects the best codec each client supports:
| Platform | Supported codecs | Max channels | Codec preference |
|---|---|---|---|
| Web | AAC | 2 (stereo) | AAC |
| Apple TV | AAC, AC3, EAC3 | 8 (7.1) | EAC3 → AC3 → AAC |
| Android TV | AAC, AC3, EAC3 | 6 (5.1) | EAC3 → AC3 → AAC |
| Shield Pro | AAC, AC3, EAC3 | 8 (7.1) | EAC3 → AC3 → AAC |
Audio bitrate scales with the video quality tier:
| Quality | Audio bitrate |
|---|---|
| 4K | 384 kbps |
| 1080p | 256 kbps |
| 720p | 192 kbps |
| 480p | 128 kbps |
Lossless formats (TrueHD, DTS-HD MA) are always transcoded except on devices that support HDMI passthrough.
Transcode cache
Section titled “Transcode cache”Active transcodes write HLS segments to a temporary directory. These files are cleaned up automatically when a session ends (after 2 minutes of inactivity).
For best performance, ensure the transcode cache directory is on an SSD. In Docker, this is typically the /cache volume:
volumes: - dubby-cache:/cacheMonitoring transcodes
Section titled “Monitoring transcodes”With LOG_LEVEL=debug, the server logs the full playback plan for each session, including:
- Which tier of the playback hierarchy was selected
- Which codecs are being transcoded (and which are being copied)
- The FFmpeg command being used
- Encoder performance (fps, bitrate)
# Follow transcode logs in real-timedocker logs -f dubby 2>&1 | grep -i "transcode\|ffmpeg\|session"Active sessions and their transcoding status are also visible in the admin dashboard.