From dc768a8dbba7d32153f0b46a01a8600bda97bc0f Mon Sep 17 00:00:00 2001 From: pyr0ball Date: Wed, 27 May 2026 09:45:29 -0700 Subject: [PATCH] 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. --- docs/config.md | 103 ++++++++++++++++++++++ docs/env.md | 26 ++++++ docs/index.md | 59 +++++++++++++ docs/install.md | 110 +++++++++++++++++++++++ docs/integrations/qbittorrent.md | 48 ++++++++++ docs/integrations/radarr.md | 42 +++++++++ docs/integrations/sonarr.md | 49 +++++++++++ docs/integrations/tdarr.md | 26 ++++++ docs/quickstart.md | 80 +++++++++++++++++ docs/reference/disc-formats.md | 55 ++++++++++++ docs/reference/troubleshooting.md | 142 ++++++++++++++++++++++++++++++ docs/requirements.txt | 2 + docs/transcoders/ffmpeg.md | 49 +++++++++++ docs/transcoders/handbrake.md | 49 +++++++++++ docs/transcoders/ssh-workers.md | 82 +++++++++++++++++ mkdocs.yml | 64 ++++++++++++++ 16 files changed, 986 insertions(+) create mode 100644 docs/config.md create mode 100644 docs/env.md create mode 100644 docs/index.md create mode 100644 docs/install.md create mode 100644 docs/integrations/qbittorrent.md create mode 100644 docs/integrations/radarr.md create mode 100644 docs/integrations/sonarr.md create mode 100644 docs/integrations/tdarr.md create mode 100644 docs/quickstart.md create mode 100644 docs/reference/disc-formats.md create mode 100644 docs/reference/troubleshooting.md create mode 100644 docs/requirements.txt create mode 100644 docs/transcoders/ffmpeg.md create mode 100644 docs/transcoders/handbrake.md create mode 100644 docs/transcoders/ssh-workers.md create mode 100644 mkdocs.yml diff --git a/docs/config.md b/docs/config.md new file mode 100644 index 0000000..b2b7e2c --- /dev/null +++ b/docs/config.md @@ -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). diff --git a/docs/env.md b/docs/env.md new file mode 100644 index 0000000..176595f --- /dev/null +++ b/docs/env.md @@ -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 | diff --git a/docs/index.md b/docs/index.md new file mode 100644 index 0000000..370097a --- /dev/null +++ b/docs/index.md @@ -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). diff --git a/docs/install.md b/docs/install.md new file mode 100644 index 0000000..4d93413 --- /dev/null +++ b/docs/install.md @@ -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 +``` diff --git a/docs/integrations/qbittorrent.md b/docs/integrations/qbittorrent.md new file mode 100644 index 0000000..b898ae6 --- /dev/null +++ b/docs/integrations/qbittorrent.md @@ -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 +``` diff --git a/docs/integrations/radarr.md b/docs/integrations/radarr.md new file mode 100644 index 0000000..66c7700 --- /dev/null +++ b/docs/integrations/radarr.md @@ -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": } + ▼ +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. diff --git a/docs/integrations/sonarr.md b/docs/integrations/sonarr.md new file mode 100644 index 0000000..e7b8ecc --- /dev/null +++ b/docs/integrations/sonarr.md @@ -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": } + ▼ +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. diff --git a/docs/integrations/tdarr.md b/docs/integrations/tdarr.md new file mode 100644 index 0000000..5907d60 --- /dev/null +++ b/docs/integrations/tdarr.md @@ -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 diff --git a/docs/quickstart.md b/docs/quickstart.md new file mode 100644 index 0000000..59d9db9 --- /dev/null +++ b/docs/quickstart.md @@ -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) diff --git a/docs/reference/disc-formats.md b/docs/reference/disc-formats.md new file mode 100644 index 0000000..adc7953 --- /dev/null +++ b/docs/reference/disc-formats.md @@ -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 diff --git a/docs/reference/troubleshooting.md b/docs/reference/troubleshooting.md new file mode 100644 index 0000000..1d100e1 --- /dev/null +++ b/docs/reference/troubleshooting.md @@ -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 50–100 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 +``` diff --git a/docs/requirements.txt b/docs/requirements.txt new file mode 100644 index 0000000..0da0ecb --- /dev/null +++ b/docs/requirements.txt @@ -0,0 +1,2 @@ +mkdocs>=1.5,<2 +mkdocs-material>=9.5,<10 diff --git a/docs/transcoders/ffmpeg.md b/docs/transcoders/ffmpeg.md new file mode 100644 index 0000000..63abbc0 --- /dev/null +++ b/docs/transcoders/ffmpeg.md @@ -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 | + |---|---|---| + | 18–20 | Near-lossless | Archival | + | 22–24 | High quality | Standard library | + | 26–28 | 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. diff --git a/docs/transcoders/handbrake.md b/docs/transcoders/handbrake.md new file mode 100644 index 0000000..a397fe3 --- /dev/null +++ b/docs/transcoders/handbrake.md @@ -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. diff --git a/docs/transcoders/ssh-workers.md b/docs/transcoders/ssh-workers.md new file mode 100644 index 0000000..7d4686c --- /dev/null +++ b/docs/transcoders/ssh-workers.md @@ -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 50–100 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` diff --git a/mkdocs.yml b/mkdocs.yml new file mode 100644 index 0000000..6284a13 --- /dev/null +++ b/mkdocs.yml @@ -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