Skip to content
🚧 These docs are a work in progress and may contain inaccuracies. Content is being actively reviewed and validated.

Transcoding

Dubby transcodes media on-the-fly when your device doesn’t natively support the source format. These settings control how transcoding behaves.

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.

VariableDefaultDescription
DUBBY_GPU_ENABLEDtrueUse hardware-accelerated encoding when available
DUBBY_MULTI_QUALITYfalseEnable multi-quality adaptive bitrate (ABR)
DUBBY_MAX_QUALITY_TIERS4Maximum quality tiers for ABR (1–6)
DUBBY_TRANSCODING_DEFAULT_CRF23Constant rate factor (0–51, lower = better quality)
DUBBY_TRANSCODING_DEFAULT_PRESETfastFFmpeg encoding preset (ultrafast–veryslow)
DUBBY_TRANSCODING_HLS_SEGMENT_DURATION4HLS segment length in seconds (2–10)
DUBBY_TRANSCODING_DISK_WARNING_THRESHOLD_GB10Warn when free disk drops below this (GB)
DUBBY_TRANSCODING_DISK_CRITICAL_THRESHOLD_GB2Stop new transcodes below this (GB)
DUBBY_TRANSCODING_MAX_CACHE_SIZE_PER_USER_GB20Max transcode cache per user (GB)
DUBBY_TRANSCODING_MAX_TOTAL_CACHE_SIZE_GB100Max total transcode cache (GB)

When DUBBY_GPU_ENABLED=true (the default), the server probes for available hardware encoders at startup and selects the best one:

  1. NVIDIA NVENC — Dedicated GPU encoder (fastest, best quality)
  2. Apple VideoToolbox — macOS/Apple Silicon hardware encoder
  3. Intel Quick Sync (QSV) — Integrated GPU on 6th-gen Intel and newer
  4. AMD VAAPI — GPU encoder on Linux with proper kernel driver
  5. AMD AMF — GPU encoder on Windows
  6. 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 is transcoded when the client doesn’t support the source codec. The server selects the best codec each client supports:

PlatformSupported codecsMax channelsCodec preference
WebAAC2 (stereo)AAC
Apple TVAAC, AC3, EAC38 (7.1)EAC3 → AC3 → AAC
Android TVAAC, AC3, EAC36 (5.1)EAC3 → AC3 → AAC
Shield ProAAC, AC3, EAC38 (7.1)EAC3 → AC3 → AAC

Audio bitrate scales with the video quality tier:

QualityAudio bitrate
4K384 kbps
1080p256 kbps
720p192 kbps
480p128 kbps

Lossless formats (TrueHD, DTS-HD MA) are always transcoded except on devices that support HDMI passthrough.

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:/cache

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)
Terminal window
# Follow transcode logs in real-time
docker logs -f dubby 2>&1 | grep -i "transcode\|ffmpeg\|session"

Active sessions and their transcoding status are also visible in the admin dashboard.