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:
parent
49f4a48fda
commit
dc768a8dbb
16 changed files with 986 additions and 0 deletions
103
docs/config.md
Normal file
103
docs/config.md
Normal 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
26
docs/env.md
Normal 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
59
docs/index.md
Normal 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
110
docs/install.md
Normal 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
|
||||
```
|
||||
48
docs/integrations/qbittorrent.md
Normal file
48
docs/integrations/qbittorrent.md
Normal 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
|
||||
```
|
||||
42
docs/integrations/radarr.md
Normal file
42
docs/integrations/radarr.md
Normal 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.
|
||||
49
docs/integrations/sonarr.md
Normal file
49
docs/integrations/sonarr.md
Normal 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.
|
||||
26
docs/integrations/tdarr.md
Normal file
26
docs/integrations/tdarr.md
Normal 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
80
docs/quickstart.md
Normal 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)
|
||||
55
docs/reference/disc-formats.md
Normal file
55
docs/reference/disc-formats.md
Normal 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
|
||||
142
docs/reference/troubleshooting.md
Normal file
142
docs/reference/troubleshooting.md
Normal 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 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
|
||||
```
|
||||
2
docs/requirements.txt
Normal file
2
docs/requirements.txt
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
mkdocs>=1.5,<2
|
||||
mkdocs-material>=9.5,<10
|
||||
49
docs/transcoders/ffmpeg.md
Normal file
49
docs/transcoders/ffmpeg.md
Normal 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 |
|
||||
|---|---|---|
|
||||
| 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.
|
||||
49
docs/transcoders/handbrake.md
Normal file
49
docs/transcoders/handbrake.md
Normal 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.
|
||||
82
docs/transcoders/ssh-workers.md
Normal file
82
docs/transcoders/ssh-workers.md
Normal 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 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`
|
||||
64
mkdocs.yml
Normal file
64
mkdocs.yml
Normal 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
|
||||
Loading…
Reference in a new issue