README.md (3444B)
1 # makemkv 2 3 Ansible playbook that provisions a Debian desktop as a Blu-ray/DVD archiving box: MakeMKV and HandBrake (via Flatpak), ffmpeg, a headless TigerVNC + XFCE4 desktop, an NFS-mounted movie library, and a `rip`/`encode` script pair for turning a disc into a Jellyfin-ready x265 file. 4 5 ## Target 6 7 | | | 8 |---|---| 9 | Host | `192.168.0.118` (`debian_desktop` in `inventory/hosts.yml`) | 10 | User | `cjr` | 11 | Optical drive | `/dev/sr0` (USB Blu-ray writer) | 12 | Library | NFS share `192.168.0.240:/mnt/Movies` → `/mnt/Movies` | 13 14 ## Running the playbook 15 16 ```bash 17 # Full provision 18 ansible-playbook -i inventory/hosts.yml site.yml --ask-vault-pass 19 20 # Individual roles 21 ansible-playbook -i inventory/hosts.yml site.yml --tags vnc --ask-vault-pass 22 ansible-playbook -i inventory/hosts.yml site.yml --tags flatpaks --ask-vault-pass 23 ansible-playbook -i inventory/hosts.yml site.yml --tags nfs --ask-vault-pass 24 ansible-playbook -i inventory/hosts.yml site.yml --tags scripts --ask-vault-pass 25 ansible-playbook -i inventory/hosts.yml site.yml --tags update --ask-vault-pass 26 27 # Dry run 28 ansible-playbook -i inventory/hosts.yml site.yml --check --ask-vault-pass 29 ``` 30 31 Lint with `ansible-lint site.yml`. 32 33 ## Secrets 34 35 `group_vars/all/vault.yml` is Ansible Vault-encrypted and holds `vnc_password`. Always pass `--ask-vault-pass`. Never commit plaintext secrets. 36 37 ```bash 38 ansible-vault edit group_vars/all/vault.yml 39 ``` 40 41 ## Roles 42 43 | Role | Purpose | 44 |------|---------| 45 | `system_update` | `apt dist-upgrade` + autoremove/autoclean | 46 | `vnc` | TigerVNC on display `:5`, XFCE4 session, systemd service `vncserver@5`; adds `cjr` to `video`/`render` for VA-API GPU access | 47 | `flatpaks` | Flathub remote, MakeMKV + HandBrake flatpaks, DVD libs (`libdvdcss` via `libdvd-pkg`), `ffmpeg` | 48 | `nfs` | Mounts `192.168.0.240:/mnt/Movies` → `/mnt/Movies`, persisted in fstab | 49 | `scripts` | Deploys `rip`, `encode`, and `notify` to `~/.scripts/` and adds it to `PATH` | 50 51 Key variables live in `group_vars/all/vars.yml`; role defaults live under `roles/*/defaults/`. 52 53 ## The rip → encode pipeline 54 55 `rip` and `encode` are deployed to `~/.scripts/` on the target and used interactively over SSH or the VNC desktop. 56 57 ``` 58 rip [disc] [title] [crf] [--software] [--name "Movie Title"] 59 ``` 60 61 1. Verifies `/dev/sr0` exists and a disc is actually readable in it before doing anything else. 62 2. Queries the disc title via `makemkvcon info` and proposes an auto-detected movie name (stripping junk tokens like `WS`/`FS`/`4X3`). 63 3. Prompts for a name override — auto-accepts the detected name after 60 seconds of no input, so the pipeline never hangs unattended. 64 4. Checks `/mnt/Movies/.rip.db` (SQLite) for a prior rip of the same disc and warns before re-ripping. 65 5. Extracts the main feature to `/mnt/Movies` with `makemkvcon`, then calls `encode` on the result. 66 6. Records the rip in the database, triggers a Jellyfin library scan, and ejects the disc. 67 68 ``` 69 encode <input.mkv> [output.mkv] [crf] [--software] 70 ``` 71 72 Transcodes to x265 — `hevc_vaapi` hardware encoding on `/dev/dri/renderD128` by default, or `libx265` software with `--software` — and strips non-English audio/subtitle tracks. 73 74 Query the rip history: 75 76 ```bash 77 sqlite3 /mnt/Movies/.rip.db "SELECT title, output_file, ripped_at FROM rips ORDER BY ripped_at DESC;" 78 ``` 79 80 ## Naming conventions 81 82 Output files must be Jellyfin/TMDB-scrapable: `Movie Title (Year)/Movie Title (Year).mkv`, spaces not dots.