docs: add MkDocs site

14-page documentation site covering installation, quick start,
full config reference, Sonarr/Radarr/qBittorrent/Tdarr integrations,
ffmpeg/HandBrake transcoder setup, SSH transcode workers, disc format
reference, and troubleshooting.

Stack: mkdocs-material 9.x (MIT), pinned <10 to avoid 2.0 licence wall.
This commit is contained in:
pyr0ball 2026-05-27 09:45:29 -07:00
parent 49f4a48fda
commit dc768a8dbb
16 changed files with 986 additions and 0 deletions

103
docs/config.md Normal file
View file

@ -0,0 +1,103 @@
# Configuration Reference
All configuration lives in `~/.config/media-postprocessor/api-keys.conf`.
Every key can also be set as an environment variable — **env vars take precedence over the config file**.
---
## Sonarr
```bash
SONARR_URL=http://your-sonarr-host:8989/sonarr
SONARR_API_KEY=your-sonarr-api-key
```
Find your API key in Sonarr under **Settings → General → Security → API Key**.
---
## Radarr
```bash
RADARR_URL=http://your-radarr-host:7878/radarr
RADARR_API_KEY=your-radarr-api-key
```
Find your API key in Radarr under **Settings → General → Security → API Key**.
---
## Encode settings
```bash
# Transcoder to use: ffmpeg (default) or handbrake
DISCARR_TRANSCODER=ffmpeg
# ffmpeg encode preset (used when DISCARR_TRANSCODER=ffmpeg)
# Default produces a reasonable HEVC/H.265 encode at CRF 22
FFMPEG_ARGS=-c:v libx265 -crf 22 -preset medium -c:a aac -b:a 192k
# HandBrake preset name (used when DISCARR_TRANSCODER=handbrake)
HANDBRAKE_PRESET=H.265 MKV 1080p30
```
---
## SSH transcode worker
When set, Discarr sends encode jobs to a remote host over SSH instead of running them locally.
```bash
SSH_TRANSCODE_HOST=strahl
SSH_TRANSCODE_USER=alan
SSH_TRANSCODE_MEDIA_ROOT=/media
# Optional: override SSH key path (defaults to ~/.ssh/id_rsa)
SSH_TRANSCODE_KEY=~/.ssh/id_ed25519
```
See [SSH Transcode Workers](transcoders/ssh-workers.md) for setup instructions.
---
## Discarr runtime
```bash
# Web UI port (default: 8603)
PORT=8603
# Config file path (default: ~/.config/media-postprocessor/api-keys.conf)
DISCARR_CONFIG=~/.config/media-postprocessor/api-keys.conf
# Job log path
DISCARR_LOG=~/.local/share/discarr/jobs.log
# Pending queue path
DISCARR_QUEUE=~/.local/share/discarr/pending-queue.json
# Discarr's own URL (used by notification hook scripts)
DISCARR_URL=http://127.0.0.1:8603
```
---
## qBittorrent integration
```bash
# qBittorrent Web UI URL
QBIT_URL=http://your-qbit-host:8080
QBIT_USER=admin
QBIT_PASS=your-password
```
See [qBittorrent integration](integrations/qbittorrent.md).
---
## Tdarr integration
```bash
TDARR_URL=http://your-tdarr-host:8265
```
See [Tdarr integration](integrations/tdarr.md).

26
docs/env.md Normal file
View file

@ -0,0 +1,26 @@
# Environment Variables
All variables can be set in the config file (`api-keys.conf`) or as environment variables. Environment variables take precedence.
| Variable | Default | Description |
|---|---|---|
| `PORT` | `8603` | Web UI port |
| `DISCARR_CONFIG` | `~/.config/media-postprocessor/api-keys.conf` | Config file path |
| `DISCARR_LOG` | `~/.local/share/discarr/jobs.log` | Job log file |
| `DISCARR_QUEUE` | `~/.local/share/discarr/pending-queue.json` | Persistent queue file |
| `DISCARR_URL` | `http://127.0.0.1:8603` | Discarr's own URL (used by hook scripts) |
| `SONARR_URL` | — | Sonarr base URL |
| `SONARR_API_KEY` | — | Sonarr API key |
| `RADARR_URL` | — | Radarr base URL |
| `RADARR_API_KEY` | — | Radarr API key |
| `DISCARR_TRANSCODER` | `ffmpeg` | Transcoder: `ffmpeg` or `handbrake` |
| `FFMPEG_ARGS` | see config | ffmpeg encode arguments |
| `HANDBRAKE_PRESET` | `H.265 MKV 1080p30` | HandBrake preset name |
| `SSH_TRANSCODE_HOST` | — | Remote SSH encode host |
| `SSH_TRANSCODE_USER` | — | SSH user on remote host |
| `SSH_TRANSCODE_MEDIA_ROOT` | — | Media root path on remote host |
| `SSH_TRANSCODE_KEY` | `~/.ssh/id_rsa` | SSH private key path |
| `QBIT_URL` | — | qBittorrent Web UI URL |
| `QBIT_USER` | — | qBittorrent username |
| `QBIT_PASS` | — | qBittorrent password |
| `TDARR_URL` | — | Tdarr Web UI URL |

59
docs/index.md Normal file
View file

@ -0,0 +1,59 @@
# Discarr
**Scan disc rips. Map titles. Queue HEVC encodes. Notify Sonarr and Radarr when done.**
Discarr is a self-hosted web UI that bridges disc ripping (VIDEO_TS / BDMV / ISO) into Sonarr and Radarr. Point it at a disc directory, map each title to the right episode or movie, and it handles the encode queue and arr notification.
---
## How it works
```
Disc rip (MakeMKV / HandBrake)
Discarr web UI
┌─────────────────────────────┐
│ 1. Scan disc structure │
│ 2. Map titles → arr items │
│ 3. Queue HEVC encode │
│ 4. Notify Sonarr / Radarr │
└─────────────────────────────┘
Sonarr / Radarr import
```
## Features
- **Disc scanning** — detects VIDEO_TS, BDMV, multi-disc, and ISO structures automatically
- **IFO chapter extraction** — reads DVD structure to split multi-episode discs correctly
- **Episode/movie mapping** — browser UI maps disc titles to Sonarr episodes or Radarr movies
- **HEVC encode queue** — dispatches ffmpeg or HandBrake jobs locally or over SSH
- **Arr notification** — custom script hooks notify on import, file delete, or completion
- **qBittorrent integration** — optional hook triggers a scan on torrent completion
- **Tdarr integration** — optional ping to Tdarr after encode completes
- **Persistent job queue** — survives restarts; jobs resume automatically
- **No npm dependencies** — pure Node.js built-ins only
## Requirements
| Dependency | Required | Notes |
|---|---|---|
| Node.js 18+ | Yes | Runtime |
| ffmpeg + ffprobe | Yes | Disc scanning, encode dispatch |
| HandBrake CLI | Recommended | HEVC encoding (falls back to ffmpeg) |
| libdvdcss | Recommended | CSS-encrypted DVD decryption |
| libdvdread + libdvdnav | Yes (DVD) | DVD structure reading |
## Quick links
- [Installation guide](install.md)
- [Quick start](quickstart.md)
- [Configuration reference](config.md)
- [Sonarr integration](integrations/sonarr.md)
- [SSH transcode workers](transcoders/ssh-workers.md)
## License
GPL-3.0. Source on [Forgejo](https://git.opensourcesolarpunk.com/Circuit-Forge/discarr) and [GitHub](https://github.com/pyr0ball/discarr).

110
docs/install.md Normal file
View file

@ -0,0 +1,110 @@
# Installation
## Native installer (recommended)
The installer handles Node.js, ffmpeg, HandBrake CLI, and DVD libraries automatically.
**Supported platforms:** Ubuntu/Debian (apt), Fedora/RHEL (dnf), Arch Linux (pacman), macOS (brew)
```bash
git clone https://git.opensourcesolarpunk.com/Circuit-Forge/discarr
cd discarr
sudo bash install.sh
```
The installer will ask whether to register a systemd service.
### Installer options
Override defaults with environment variables:
```bash
sudo DISCARR_INSTALL_DIR=/opt/discarr \
DISCARR_PORT=8603 \
REGISTER_SERVICE=yes \
bash install.sh
```
| Variable | Default | Description |
|---|---|---|
| `DISCARR_INSTALL_DIR` | `/opt/discarr` | Where to install app files |
| `DISCARR_USER` | `discarr` | System user for the service |
| `DISCARR_PORT` | `8603` | Web UI port |
| `REGISTER_SERVICE` | `ask` | `ask`, `yes`, or `no` |
| `SKIP_DEPS` | `0` | Set to `1` to skip system dep installation |
### What gets installed
| Dependency | apt | dnf | pacman | brew |
|---|---|---|---|---|
| Node.js 20 LTS | NodeSource | NodeSource | nodejs | node@20 |
| ffmpeg + ffprobe | ffmpeg | ffmpeg (RPM Fusion) | ffmpeg | ffmpeg |
| HandBrake CLI | handbrake-cli | HandBrake-cli | handbrake-cli | handbrake |
| libdvdcss | libdvd-pkg | libdvdcss (RPM Fusion) | libdvdcss | libdvdcss |
| libdvdread | libdvdread8 | libdvdread | libdvdread | — |
| libdvdnav | libdvdnav4 | libdvdnav | libdvdnav | — |
!!! note "libdvdcss on Ubuntu"
Ubuntu's `libdvd-pkg` builds libdvdcss from source using `dpkg-reconfigure`. The installer handles this automatically. Legal in most jurisdictions for personal use.
!!! note "HandBrake on Fedora"
Requires RPM Fusion. The installer enables it automatically when installing ffmpeg — HandBrake installs from the same repo.
---
## Docker
Pre-built image — includes ffmpeg, ffprobe, HandBrake CLI, libdvd* libraries, and openssh-client:
```bash
docker run -d \
--name discarr \
-p 8603:8603 \
-v ~/.config/media-postprocessor:/root/.config/media-postprocessor:ro \
-v ~/.local/share/discarr:/root/.local/share/discarr \
-v /path/to/media:/media \
pyr0ball/discarr:latest
```
### Docker Compose
```yaml
services:
discarr:
image: pyr0ball/discarr:latest
container_name: discarr
ports:
- "8603:8603"
volumes:
- ~/.config/media-postprocessor:/root/.config/media-postprocessor:ro
- discarr-data:/root/.local/share/discarr
- /path/to/media:/media
restart: unless-stopped
environment:
- PORT=8603
volumes:
discarr-data:
```
!!! warning "Media path"
The `/media` mount must be the same path that Sonarr/Radarr can also see. If your arr apps run in Docker, make sure they share the same media volume or NFS mount.
---
## Manual (from source)
Install system dependencies yourself (see table above), then:
```bash
git clone https://git.opensourcesolarpunk.com/Circuit-Forge/discarr
cd discarr
# Configure
mkdir -p ~/.config/media-postprocessor
cp api-keys.conf.example ~/.config/media-postprocessor/api-keys.conf
$EDITOR ~/.config/media-postprocessor/api-keys.conf
# Run
node server.js
```

View file

@ -0,0 +1,48 @@
# qBittorrent Integration
Configure qBittorrent to notify Discarr when a torrent finishes downloading, so disc rips downloaded as torrents are scanned automatically.
## 1. Add the run-on-completion script
In qBittorrent, go to **Tools → Options → Downloads**.
Under **Run external program on torrent completion**, enter:
```
/opt/discarr/scripts/qbittorrent-notify.sh "%D"
```
`%D` passes the save path of the completed torrent to the script.
## 2. Configure qBittorrent credentials
In `~/.config/media-postprocessor/api-keys.conf`:
```bash
QBIT_URL=http://your-qbit-host:8080
QBIT_USER=admin
QBIT_PASS=your-password
```
## 3. How it works
When a torrent completes, qBittorrent runs the script with the download directory. The script checks if the directory contains a disc structure (VIDEO_TS, BDMV, or ISO) and, if so, submits it to Discarr's scan queue automatically.
```
Torrent completes
qbittorrent-notify.sh "%D"
│ checks for disc structure
│ POST /api/scan {"path": "/media/downloads/..."}
Discarr scan queue
```
## 4. DISCARR_URL
The script uses `DISCARR_URL` to find the Discarr instance. If qBittorrent and Discarr are not on the same host, set this in the config file:
```bash
DISCARR_URL=http://discarr-host:8603
```

View file

@ -0,0 +1,42 @@
# Radarr Integration
Discarr notifies Radarr when a movie encode completes so it can trigger an import scan automatically.
## 1. Add the notification hook
In Radarr, go to **Settings → Connect → Add Connection → Custom Script**.
| Field | Value |
|---|---|
| Name | `Discarr` |
| Path | `/opt/discarr/scripts/radarr-notify.sh` |
| On Import | ✓ |
| On Movie File Delete | ✓ |
## 2. Configure the API key
In `~/.config/media-postprocessor/api-keys.conf`:
```bash
RADARR_URL=http://your-radarr-host:7878/radarr
RADARR_API_KEY=your-radarr-api-key
```
Find your API key in Radarr under **Settings → General → Security → API Key**.
## 3. How it works
```
Encode completes
radarr-notify.sh
│ POST /api/v3/command
│ {"name": "RescanMovie", "movieId": <id>}
Radarr imports file
```
## 4. Test the connection
Click **Test** on the connection in Radarr. To test end-to-end, queue a movie encode in Discarr and watch **Activity → Queue** in Radarr for the import.

View file

@ -0,0 +1,49 @@
# Sonarr Integration
Discarr notifies Sonarr when an encode completes so it can trigger an import scan automatically.
## 1. Add the notification hook
In Sonarr, go to **Settings → Connect → Add Connection → Custom Script**.
| Field | Value |
|---|---|
| Name | `Discarr` |
| Path | `/opt/discarr/scripts/sonarr-notify.sh` |
| On Import | ✓ |
| On Episode File Delete | ✓ |
!!! note "Docker installs"
If Sonarr runs in Docker, the script path must be accessible inside the Sonarr container. Mount the Discarr scripts directory as a volume, or copy the script into a shared config directory.
## 2. Configure the API key
In `~/.config/media-postprocessor/api-keys.conf`:
```bash
SONARR_URL=http://your-sonarr-host:8989/sonarr
SONARR_API_KEY=your-sonarr-api-key
```
Find your API key in Sonarr under **Settings → General → Security → API Key**.
## 3. How it works
When Discarr finishes an encode, it calls the Sonarr API to trigger a rescan on the target path. Sonarr picks up the new file and handles the rename and library update.
```
Encode completes
sonarr-notify.sh
│ POST /api/v3/command
│ {"name": "RescanSeries", "seriesId": <id>}
Sonarr imports file
```
## 4. Test the connection
In Sonarr, click **Test** on the connection you just added. You should see a success notification.
To test end-to-end, queue a small encode in Discarr and watch **Activity → Queue** in Sonarr for the import.

View file

@ -0,0 +1,26 @@
# Tdarr Integration
Discarr can notify Tdarr after an encode completes, triggering a library scan so Tdarr picks up the new file for any further processing (remux, subtitle extraction, quality checks).
## Configuration
In `~/.config/media-postprocessor/api-keys.conf`:
```bash
TDARR_URL=http://your-tdarr-host:8265
```
## How it works
After the encode finishes and the arr notification fires, Discarr sends a scan request to Tdarr's API pointing at the output directory. Tdarr adds the new file to its processing queue.
!!! note "Optional integration"
If `TDARR_URL` is not set, Discarr skips the Tdarr notification silently.
## When to use this
Useful if you run Tdarr for:
- Re-encoding to a specific codec/quality after Discarr's initial HEVC pass
- Subtitle extraction and burn-in
- Health checks on the output file before arr import

80
docs/quickstart.md Normal file
View file

@ -0,0 +1,80 @@
# Quick Start
## 1. Install Discarr
Follow the [installation guide](install.md). For the fastest path:
```bash
git clone https://git.opensourcesolarpunk.com/Circuit-Forge/discarr
cd discarr
sudo bash install.sh
```
## 2. Configure API keys
```bash
mkdir -p ~/.config/media-postprocessor
cp api-keys.conf.example ~/.config/media-postprocessor/api-keys.conf
$EDITOR ~/.config/media-postprocessor/api-keys.conf
```
Minimum config:
```bash
SONARR_URL=http://your-sonarr-host:8989/sonarr
SONARR_API_KEY=your-sonarr-api-key
RADARR_URL=http://your-radarr-host:7878/radarr
RADARR_API_KEY=your-radarr-api-key
```
Find your API keys in Sonarr/Radarr under **Settings → General → Security → API Key**.
## 3. Start Discarr
```bash
# If installed as a service:
systemctl start discarr
# Or run directly:
node /opt/discarr/server.js
# Or with Docker:
docker run -d -p 8603:8603 \
-v ~/.config/media-postprocessor:/root/.config/media-postprocessor:ro \
-v /path/to/media:/media \
pyr0ball/discarr:latest
```
Open **http://localhost:8603**.
## 4. Scan a disc
1. Paste the path to a disc directory or ISO (e.g. `/media/disc/VIDEO_TS`) into the **Path** field
2. Click **Scan**
3. Discarr lists the disc titles with duration and chapter count
## 5. Map titles to arr items
For each title:
1. Choose **TV (Sonarr)** or **Movie (Radarr)**
2. Search for the series or movie name
3. For TV: select the season and episode(s) the title maps to
4. Click **Queue**
## 6. Monitor the encode
The **Queue** tab shows running and pending encode jobs. Each job shows:
- Input file and mapped target
- Encode progress (% and ETA)
- Status: `pending``encoding``notifying``done`
Once encoding finishes, Discarr fires the notification hook and Sonarr/Radarr picks up the import automatically.
## Next steps
- [Set up notification hooks](integrations/sonarr.md) so Sonarr/Radarr trigger scans automatically
- [Configure SSH transcode workers](transcoders/ssh-workers.md) to offload encoding to a dedicated machine
- [Full configuration reference](config.md)

View file

@ -0,0 +1,55 @@
# Disc Formats
Discarr supports the following input formats:
## VIDEO_TS (DVD)
Standard DVD file structure. Discarr reads IFO files to extract title, chapter, and duration information.
```
/media/disc/
└── VIDEO_TS/
├── VIDEO_TS.IFO
├── VTS_01_0.IFO
├── VTS_01_0.VOB
├── VTS_01_1.VOB
└── ...
```
**Multi-episode discs:** Discarr reads chapter boundaries from IFO data to identify individual episodes within a single title. You can split a title into multiple episodes during the mapping step.
## BDMV (Blu-ray)
Standard Blu-ray structure. Discarr reads CLPI (clip info) and MPLS (playlist) files for title enumeration.
```
/media/disc/
└── BDMV/
├── BACKUP/
├── CERTIFICATE/
├── CLIPINF/
├── MOVIEOBJ.BDM
├── STREAM/
└── ...
```
## ISO
Disc image files. Discarr mounts the ISO in memory and scans the inner structure (VIDEO_TS or BDMV).
```
/media/disc.iso
```
!!! note "libdvdcss for encrypted DVDs"
CSS-encrypted DVD ISOs require libdvdcss to be installed. The native installer handles this. The Docker image includes libdvdcss.
## Multi-disc sets
Discarr handles multi-disc sets by scanning each disc directory separately. Map each disc in sequence — the episode counter picks up where the previous disc left off.
## Scan path tips
- Pass the directory containing `VIDEO_TS` or `BDMV`, not the inner directory itself
- For ISOs, pass the full `.iso` file path
- Symlinks are followed

View file

@ -0,0 +1,142 @@
# Troubleshooting
## Discarr won't start
**Check Node.js version:**
```bash
node --version # must be 18+
```
**Check for port conflict:**
```bash
ss -tlnp | grep 8603
# Change port with: PORT=8604 node server.js
```
**Check logs (if running as a service):**
```bash
journalctl -u discarr -f
```
---
## Scan returns no titles
**ffprobe not found:**
```bash
which ffprobe # must be in PATH
ffprobe -version
```
**Disc structure not recognised:**
- Ensure the path points to the directory containing `VIDEO_TS` or `BDMV`, not inside it
- For ISOs, pass the full path including the `.iso` extension
- Check read permissions: `ls -la /path/to/disc`
**Encrypted DVD:**
```bash
dpkg -l libdvd-pkg 2>/dev/null || rpm -q libdvdcss 2>/dev/null
# Reinstall if missing — see Installation guide
```
---
## Encode fails immediately
**ffmpeg not found:**
```bash
which ffmpeg && ffmpeg -version
```
**HandBrake preset not found:**
```bash
HandBrakeCLI --preset-list | grep "H.265"
```
Check `HANDBRAKE_PRESET` matches exactly (case-sensitive).
**Disk space:**
```bash
df -h /tmp ~/.local/share/discarr
# Full HEVC encodes need 50100 GB of temp space for large discs
```
---
## Sonarr/Radarr not importing after encode
**Check hook scripts are executable:**
```bash
ls -la /opt/discarr/scripts/
chmod +x /opt/discarr/scripts/*.sh
```
**Test the hook manually:**
```bash
DISCARR_URL=http://127.0.0.1:8603 /opt/discarr/scripts/sonarr-notify.sh
```
**Check API key:**
```bash
curl -s "http://your-sonarr-host:8989/sonarr/api/v3/system/status" \
-H "X-Api-Key: your-api-key" | python3 -m json.tool | head -5
```
**Check Sonarr logs:**
Sonarr: **System → Logs** — look for connection errors from the Custom Script hook.
---
## SSH transcode not working
**Test SSH connection:**
```bash
ssh -i ~/.ssh/id_ed25519 user@remote-host echo "OK"
```
**Check ffmpeg on remote:**
```bash
ssh user@remote-host which ffmpeg
```
**Check disk space on remote:**
```bash
ssh user@remote-host df -h /media
```
---
## Jobs stuck in queue after restart
The queue file persists across restarts at `~/.local/share/discarr/pending-queue.json`.
To clear a stuck job:
```bash
# Edit the queue file and remove the stuck entry
$EDITOR ~/.local/share/discarr/pending-queue.json
systemctl restart discarr
```
Or clear the whole queue:
```bash
echo '[]' > ~/.local/share/discarr/pending-queue.json
systemctl restart discarr
```

2
docs/requirements.txt Normal file
View file

@ -0,0 +1,2 @@
mkdocs>=1.5,<2
mkdocs-material>=9.5,<10

View file

@ -0,0 +1,49 @@
# ffmpeg
ffmpeg is the default transcoder in Discarr. It handles HEVC encoding and is required for disc metadata scanning regardless of which transcoder you use for encoding.
## Requirements
- `ffmpeg` — encoder
- `ffprobe` — disc metadata scanning (required even if using HandBrake for encoding)
Both are installed by `install.sh` or bundled in the Docker image.
## Encode arguments
Control encode quality and speed with `FFMPEG_ARGS`:
```bash
# Default (CRF 22, medium preset — good quality/size balance)
FFMPEG_ARGS=-c:v libx265 -crf 22 -preset medium -c:a aac -b:a 192k
# Faster encode, slightly larger file
FFMPEG_ARGS=-c:v libx265 -crf 22 -preset fast -c:a aac -b:a 192k
# Smaller file, slower encode
FFMPEG_ARGS=-c:v libx265 -crf 24 -preset slow -c:a aac -b:a 192k
# Hardware-accelerated (NVIDIA NVENC)
FFMPEG_ARGS=-c:v hevc_nvenc -preset p4 -cq 22 -c:a aac -b:a 192k
# Keep all audio tracks (useful for multi-language discs)
FFMPEG_ARGS=-c:v libx265 -crf 22 -preset medium -c:a copy -map 0
```
!!! tip "CRF values"
Lower CRF = better quality, larger file. For HEVC (`libx265`):
| CRF | Quality | Typical use |
|---|---|---|
| 1820 | Near-lossless | Archival |
| 2224 | High quality | Standard library |
| 2628 | Good quality | Space-constrained |
## Checking ffmpeg capabilities
```bash
ffmpeg -codecs | grep hevc
ffmpeg -hwaccels
```
If hardware acceleration is available (NVENC, VAAPI, QSV), you can set it in `FFMPEG_ARGS` for significantly faster encodes.

View file

@ -0,0 +1,49 @@
# HandBrake
HandBrake is an optional transcoder. Use it instead of ffmpeg when you want to use HandBrake's preset system or its more aggressive subtitle/chapter handling.
## Enable HandBrake
```bash
DISCARR_TRANSCODER=handbrake
```
## Preset
Specify any preset available in your HandBrake installation:
```bash
HANDBRAKE_PRESET=H.265 MKV 1080p30
```
### Common presets
| Preset | Resolution | Notes |
|---|---|---|
| `H.265 MKV 1080p30` | 1080p | Default — good balance |
| `H.265 MKV 720p30` | 720p | Smaller files |
| `H.265 MKV 576p25` | 576p | PAL DVD native |
| `H.265 MKV 480p30` | 480p | NTSC DVD native |
| `Production Max` | Source | Near-lossless, large files |
List all available presets on your system:
```bash
HandBrakeCLI --preset-list
```
## Custom presets
Export a preset from HandBrake's GUI, save it to a JSON file, and reference it:
```bash
HANDBRAKE_PRESET_FILE=/home/alan/.config/handbrake/my-preset.json
HANDBRAKE_PRESET=My Custom Preset
```
## Subtitle handling
HandBrake handles subtitle tracks more gracefully than ffmpeg for DVD sources — it can burn in forced subtitles automatically. If you have discs with forced subtitle tracks (common for foreign-language scenes), HandBrake is the better choice.
!!! note "ffprobe still required"
HandBrake handles encoding, but Discarr still uses ffprobe for disc metadata scanning. Keep ffmpeg/ffprobe installed even when using HandBrake as the transcoder.

View file

@ -0,0 +1,82 @@
# SSH Transcode Workers
Offload encoding to a remote machine over SSH. Useful when your NAS or media server is low-powered and you have a separate box with more CPU or a GPU encoder.
## How it works
When SSH transcode is configured, Discarr:
1. Copies the source disc files to the remote host over SCP
2. Runs ffmpeg or HandBrake on the remote machine
3. Copies the encoded output back
4. Triggers the arr notification from the local machine
```
Discarr (local)
│ scp source files →
Remote encode host (SSH)
│ ffmpeg / HandBrake
│ ← scp encoded output
Discarr (local)
│ notify Sonarr/Radarr
Arr import
```
## Configuration
```bash
SSH_TRANSCODE_HOST=strahl # hostname or IP of the encode machine
SSH_TRANSCODE_USER=alan # SSH user on that machine
SSH_TRANSCODE_MEDIA_ROOT=/media # path where media is accessible on the remote
SSH_TRANSCODE_KEY=~/.ssh/id_ed25519 # optional: SSH key (defaults to ~/.ssh/id_rsa)
```
## Setting up SSH key auth
Generate a key pair if you don't have one:
```bash
ssh-keygen -t ed25519 -C "discarr-transcode"
```
Copy the public key to the remote host:
```bash
ssh-copy-id -i ~/.ssh/id_ed25519.pub alan@strahl
```
Verify passwordless login:
```bash
ssh -i ~/.ssh/id_ed25519 alan@strahl echo "OK"
```
## Shared media mount (recommended)
If both machines mount the same NFS share, Discarr can skip the SCP copy entirely — it passes the already-accessible path directly to the remote transcoder.
Set the same `SSH_TRANSCODE_MEDIA_ROOT` as the NFS mount point on the remote:
```bash
SSH_TRANSCODE_MEDIA_ROOT=/mnt/media # must match the NFS mount on the remote
```
Discarr detects the shared mount and avoids copying.
## Requirements on the remote host
- `ffmpeg` + `ffprobe` (always)
- `HandBrakeCLI` (if using HandBrake as the transcoder)
- SSH server running and accessible from the Discarr host
- Write access to `SSH_TRANSCODE_MEDIA_ROOT`
## Tips
- Use a dedicated SSH key for Discarr rather than your personal key
- If encoding stalls, check disk space on the remote — HEVC encodes of full discs can use 50100 GB of temp space
- For GPU-accelerated remote encoding (NVENC), make sure the ffmpeg on the remote is built with NVENC support: `ffmpeg -encoders | grep nvenc`

64
mkdocs.yml Normal file
View file

@ -0,0 +1,64 @@
site_name: Discarr
site_description: Disc rip to Sonarr/Radarr pipeline — web UI for VIDEO_TS/BDMV/ISO import
site_url: https://pyr0ball.github.io/discarr
repo_url: https://github.com/pyr0ball/discarr
repo_name: pyr0ball/discarr
edit_uri: edit/main/docs/
theme:
name: material
palette:
- scheme: default
primary: deep purple
accent: cyan
toggle:
icon: material/brightness-7
name: Switch to dark mode
- scheme: slate
primary: deep purple
accent: cyan
toggle:
icon: material/brightness-4
name: Switch to light mode
features:
- navigation.tabs
- navigation.sections
- navigation.top
- content.code.copy
- content.code.annotate
plugins:
- search
markdown_extensions:
- admonition
- pymdownx.details
- pymdownx.superfences
- pymdownx.highlight:
anchor_linenums: true
- pymdownx.tabbed:
alternate_style: true
- tables
- toc:
permalink: true
nav:
- Home: index.md
- Getting Started:
- Installation: install.md
- Quick Start: quickstart.md
- Configuration:
- Config Reference: config.md
- Environment Variables: env.md
- Integrations:
- Sonarr: integrations/sonarr.md
- Radarr: integrations/radarr.md
- qBittorrent: integrations/qbittorrent.md
- Tdarr: integrations/tdarr.md
- Transcoders:
- ffmpeg: transcoders/ffmpeg.md
- HandBrake: transcoders/handbrake.md
- SSH Transcode Workers: transcoders/ssh-workers.md
- Reference:
- Disc Formats: reference/disc-formats.md
- Troubleshooting: reference/troubleshooting.md