{"id":47637352,"url":"https://github.com/cebarks/bluback","last_synced_at":"2026-04-18T05:07:40.995Z","repository":{"id":344481784,"uuid":"1181967955","full_name":"cebarks/bluback","owner":"cebarks","description":"Rust CLI/TUI tool for backing up Blu-ray discs to MKV files using ffmpeg","archived":false,"fork":false,"pushed_at":"2026-03-30T08:10:27.000Z","size":1578,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-04-02T08:26:25.014Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"Rust","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"agpl-3.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/cebarks.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":"docs/ROADMAP-1.0.md","authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-03-14T21:39:23.000Z","updated_at":"2026-03-30T08:10:29.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/cebarks/bluback","commit_stats":null,"previous_names":["cebarks/bluback"],"tags_count":18,"template":false,"template_full_name":null,"purl":"pkg:github/cebarks/bluback","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cebarks%2Fbluback","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cebarks%2Fbluback/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cebarks%2Fbluback/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cebarks%2Fbluback/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/cebarks","download_url":"https://codeload.github.com/cebarks/bluback/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cebarks%2Fbluback/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":31463018,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-05T21:22:52.476Z","status":"online","status_checked_at":"2026-04-06T02:00:07.287Z","response_time":112,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2026-04-02T00:23:25.110Z","updated_at":"2026-04-06T07:05:27.425Z","avatar_url":"https://github.com/cebarks.png","language":"Rust","funding_links":[],"categories":[],"sub_categories":[],"readme":"# bluback\n\nA CLI/TUI tool for backing up Blu-ray discs to MKV files using FFmpeg library bindings + libaacs, with optional TMDb integration for automatic episode naming.\n\nSupports TV shows (sequential or manual episode assignment, including multi-episode playlists) and movies. All rips are lossless remuxes — no re-encoding. Blu-ray chapter markers are automatically embedded during remux.\n\n## Requirements\n\n### Runtime\n\n- **FFmpeg shared libraries** (libavformat, libavcodec, libavutil, libswscale, libswresample) — bluback links against these at runtime via `ffmpeg-the-third` bindings. No `ffmpeg` or `ffprobe` CLI tools needed.\n- **libbluray** — for Blu-ray playlist enumeration\n- **libaacs** with a populated `~/.config/aacs/KEYDB.cfg` (containing device keys, processing keys, and/or per-disc VUKs)\n- A Blu-ray drive accessible as a block device:\n  - **Linux:** `/dev/sr0`, `/dev/sr1`, etc.\n  - **macOS:** `/dev/disk2`, `/dev/disk3`, etc. (use `diskutil list` to find)\n\nOptional:\n- A [TMDb API key](https://www.themoviedb.org/settings/api) for automatic show/episode metadata lookup\n\n### Build\n\nFFmpeg development libraries and clang are required at build time for FFI binding generation:\n\n| Distro | Packages |\n|---|---|\n| **Fedora/RHEL** | `sudo dnf install ffmpeg-free-devel clang clang-libs pkg-config` (or `ffmpeg-devel` from [RPMFusion](https://rpmfusion.org/) for broader codec support) |\n| **Ubuntu/Debian** | `sudo apt install libavformat-dev libavcodec-dev libavutil-dev libswscale-dev libswresample-dev libavfilter-dev libavdevice-dev pkg-config clang libclang-dev` |\n| **Arch** | `sudo pacman -S ffmpeg clang pkgconf` |\n| **macOS** | `brew install ffmpeg llvm pkg-config` (ensure llvm's clang is in PATH: `export PATH=\"/opt/homebrew/opt/llvm/bin:$PATH\"`) |\n\n### Runtime Dependencies by Platform\n\n**Linux:**\n- `udisksctl` (from `udisks2`) for disc mounting\n- `eject` for disc ejection and speed control\n\n**macOS:**\n- `diskutil` (built-in) for disc mounting and volume info\n- `drutil` (built-in) for optical drive detection\n- FFmpeg, libbluray, libaacs: `brew install ffmpeg libbluray libaacs`\n\n## Installation\n\n### From GitHub releases\n\nPre-built binaries for Linux x86_64 and aarch64 are available on the [releases page](https://github.com/cebarks/bluback/releases). These are statically linked against FFmpeg and can be run directly.\n\n### From source\n\nRequires FFmpeg development libraries and clang (see [Build requirements](#build) above).\n\n```bash\ngit clone https://github.com/cebarks/bluback.git\ncd bluback\ncargo build --release\n# Binary at target/release/bluback\n```\n\nFor detailed macOS setup, see [docs/macos-installation.md](docs/macos-installation.md).\n\n## Usage\n\n```\nbluback [OPTIONS]\n```\n\nBy default, bluback auto-detects your Blu-ray drive and launches a TUI wizard that walks you through the ripping process.\n\n### Examples\n\n```bash\n# Auto-detect drive, interactive TUI\nbluback\n\n# Specify device and output directory\nbluback -d /dev/sr0 -o ~/rips\n\n# TV show: pre-set season 2, starting at episode 5\nbluback -s 2 -e 5 -o ~/rips\n\n# Movie mode\nbluback --movie -o ~/movies\n\n# Dry run (show what would be ripped)\nbluback --dry-run\n\n# Use Plex-style filenames\nbluback --format-preset plex -o ~/media\n\n# Custom filename template\nbluback --format \"S{season}E{episode}_{title}.mkv\"\n\n# Plain text mode (no TUI)\nbluback --no-tui\n\n# List playlists with stream details (useful for --tracks)\nbluback --list-playlists -v\n\n# Keep only 5.1 audio and first subtitle from each playlist\nbluback --tracks \"a:1;s:0\" -o ~/rips\n\n# Open settings panel (no disc required)\nbluback --settings\n\n# Use a custom config file\nbluback --config ~/my-config.toml\n```\n\n### Options\n\n| Flag | Description |\n|---|---|\n| `-d, --device \u003cPATH\u003e` | Blu-ray device path (default: auto-detect) |\n| `-o, --output \u003cDIR\u003e` | Output directory (default: `.`) |\n| `-s, --season \u003cNUM\u003e` | Season number (skips prompt) |\n| `-e, --start-episode \u003cNUM\u003e` | Starting episode number (skips prompt) |\n| `--min-duration \u003cSECS\u003e` | Minimum seconds for episode detection (default: 900) |\n| `--movie` | Movie mode (skip episode assignment) |\n| `--format \u003cTEMPLATE\u003e` | Custom filename template |\n| `--format-preset \u003cNAME\u003e` | Built-in preset: `default`, `plex`, `jellyfin` |\n| `--dry-run` | Show what would be ripped |\n| `--no-tui` | Plain text mode (auto if not a TTY) |\n| `--eject` | Eject disc after successful rip |\n| `--no-eject` | Don't eject disc after rip (overrides config) |\n| `--no-max-speed` | Don't set drive to maximum read speed |\n| `-y, --yes` | Accept all defaults without prompting (auto if stdin not a TTY) |\n| `--title \u003cSTRING\u003e` | Set show/movie title directly (skips TMDb) |\n| `--year \u003cSTRING\u003e` | Movie release year (with `--title` in `--movie` mode) |\n| `--playlists \u003cSEL\u003e` | Select specific playlists (e.g. `1,2,3` or `1-3` or `all`) |\n| `--specials \u003cSEL\u003e` | Mark playlists as specials (uses filtered indices, e.g. `1,3`) |\n| `--list-playlists` | Print playlist info and exit |\n| `-v, --verbose` | Verbose output (with `--list-playlists`: show stream details) |\n| `--overwrite` | Overwrite existing output files instead of skipping |\n| `--no-metadata` | Don't embed metadata tags in output MKV files |\n| `--no-hooks` | Disable post-rip/post-session hooks for this run |\n| `--audio-lang \u003cLANGS\u003e` | Filter audio by language, comma-separated (e.g. `eng,jpn`) |\n| `--subtitle-lang \u003cLANGS\u003e` | Filter subtitles by language (e.g. `eng`) |\n| `--tracks \u003cSPEC\u003e` | Select streams by type-local index (e.g. `a:0,2;s:0-1`) |\n| `--prefer-surround` | Prefer surround audio (select surround + one stereo) |\n| `--all-streams` | Include all streams, ignoring config filters |\n| `--aacs-backend \u003cBACKEND\u003e` | AACS decryption backend: `auto`, `libaacs`, or `libmmbd` |\n| `--verify` | Verify output files after ripping |\n| `--verify-level \u003cLEVEL\u003e` | Verification level: `quick` (header) or `full` (+ frame decode) |\n| `--no-verify` | Disable verification (overrides config) |\n| `--batch` | Batch mode: rip → eject → wait → repeat |\n| `--no-batch` | Disable batch mode (overrides config) |\n| `--check` | Validate environment setup and exit (no disc required) |\n| `--settings` | Open settings panel (no disc/ffmpeg required) |\n| `--log-level \u003cLEVEL\u003e` | Stderr log verbosity: `error`, `warn`, `info`, `debug`, `trace` |\n| `--no-log` | Disable log file output |\n| `--log-file \u003cPATH\u003e` | Custom log file path (overrides default location) |\n| `--config \u003cPATH\u003e` | Path to config file (also: `BLUBACK_CONFIG` env var) |\n\n## Configuration\n\nConfig file: `~/.config/bluback/config.toml` (override with `--config \u003cPATH\u003e` or `BLUBACK_CONFIG` env var)\n\nYou can edit the config interactively with `bluback --settings` or by pressing `Ctrl+S` during any TUI screen. Saving from the settings panel writes all fields with defaults commented out for reference.\n\n```toml\n# Default output directory\n# output_dir = \".\"\n\n# Default device (or \"auto-detect\")\n# device = \"auto-detect\"\n\n# Auto-eject disc after rip\neject = true\n\n# Set drive to max read speed\n# max_speed = true\n\n# Minimum playlist duration (seconds) for episode detection (default: 900)\nmin_duration = 900\n\n# Filename preset: \"default\", \"plex\", or \"jellyfin\"\n# preset = \"plex\"\n\n# Or custom format templates (overrides preset)\n# tv_format = \"S{season}E{episode}_{title}.mkv\"\n# movie_format = \"{title}_({year}).mkv\"\n# special_format = \"{show} S00E{episode} {title}.mkv\"\n\n# Show playlists below min_duration by default in Playlist Manager\n# show_filtered = false\n\n# Stream selection — filter by language, prefer surround, etc.\n[streams]\n# audio_languages = [\"eng\", \"jpn\"]\n# subtitle_languages = [\"eng\"]\n# prefer_surround = false\n\n# Show libbluray debug output on stderr (default: false, suppressed to avoid TUI corruption)\n# verbose_libbluray = false\n\n# TMDb API key (also checked in ~/.config/bluback/tmdb_api_key and TMDB_API_KEY env var)\n# tmdb_api_key = \"your-key-here\"\n```\n\n### Environment Variables\n\nSettings can also be set via environment variables. When the settings panel opens, it detects and imports any set `BLUBACK_*` variables:\n\n| Variable | Config Key |\n|---|---|\n| `BLUBACK_OUTPUT_DIR` | `output_dir` |\n| `BLUBACK_DEVICE` | `device` |\n| `BLUBACK_EJECT` | `eject` |\n| `BLUBACK_MAX_SPEED` | `max_speed` |\n| `BLUBACK_MIN_DURATION` | `min_duration` |\n| `BLUBACK_PRESET` | `preset` |\n| `BLUBACK_TV_FORMAT` | `tv_format` |\n| `BLUBACK_MOVIE_FORMAT` | `movie_format` |\n| `BLUBACK_SPECIAL_FORMAT` | `special_format` |\n| `BLUBACK_SHOW_FILTERED` | `show_filtered` |\n| `BLUBACK_VERBOSE_LIBBLURAY` | `verbose_libbluray` |\n| `BLUBACK_RESERVE_INDEX_SPACE` | `reserve_index_space` |\n| `BLUBACK_AACS_BACKEND` | `aacs_backend` |\n| `BLUBACK_OVERWRITE` | `overwrite` |\n| `BLUBACK_BATCH` | `batch` |\n| `BLUBACK_VERIFY` | `verify` |\n| `BLUBACK_VERIFY_LEVEL` | `verify_level` |\n| `BLUBACK_METADATA` | `metadata.enabled` |\n| `BLUBACK_AUDIO_LANGUAGES` | `streams.audio_languages` |\n| `BLUBACK_SUBTITLE_LANGUAGES` | `streams.subtitle_languages` |\n| `BLUBACK_PREFER_SURROUND` | `streams.prefer_surround` |\n| `TMDB_API_KEY` | `tmdb_api_key` |\n\nEnvironment variables take precedence over config file values at runtime. When saving, a warning notes which env vars will override the saved config.\n\n### Filename Templates\n\nTemplates use `{placeholder}` syntax. Available placeholders: `{show}`, `{season}`, `{episode}`, `{title}`, `{year}`, `{resolution}`, `{audio}`, `{channels}`, `{codec}`.\n\nBracket groups `[...]` auto-collapse when their contents are empty (useful for optional metadata).\n\n**Priority chain** (highest to lowest): `--format` CLI flag \u003e `--format-preset` \u003e `tv_format`/`movie_format` in config \u003e `preset` in config \u003e `\"default\"` preset.\n\n## TUI Keybindings\n\n| Key | Action |\n|---|---|\n| `Enter` | Confirm / submit / search / select |\n| `Esc` | Go back / skip TMDb / cancel edit |\n| `Up/Down` | Navigate lists / scroll episodes |\n| `Space` | Toggle playlist selection |\n| `Tab` | Toggle movie/TV mode (TMDb search) |\n| `e` | Edit episode assignment inline |\n| `s` | Toggle special (season 0) marking |\n| `t` | Expand/collapse track list (video/audio/subtitle streams) |\n| `r` / `R` | Reset current / all episode assignments |\n| `f` | Show/hide filtered (short) playlists |\n| `Ctrl+S` | Open settings panel |\n| `Ctrl+R` | Rescan disc and restart wizard |\n| `Ctrl+E` | Eject disc |\n| `Ctrl+C` | Quit immediately |\n| `q` | Quit (except during input/ripping) |\n\n## Chapter Preservation\n\nbluback automatically extracts chapter markers from the Blu-ray's MPLS playlist files and embeds them directly into the output MKV files during remux (via the FFmpeg AVChapter API). No external tools like `mkvpropedit` are needed.\n\nThe disc is temporarily mounted via `udisksctl` to read the playlist data, then unmounted after extraction. Chapter counts are displayed alongside each playlist during selection in TUI mode.\n\n## Stream Selection\n\nBy default, bluback includes all video, audio, and subtitle streams from each playlist. You can filter streams in three ways:\n\n**Config defaults** — Set language preferences in `config.toml` that apply to every rip:\n\n```toml\n[streams]\naudio_languages = [\"eng\", \"jpn\"]\nsubtitle_languages = [\"eng\"]\nprefer_surround = true\n```\n\n**CLI flags** — Override config for a single run:\n\n```bash\n# Keep only English and Japanese audio, English subtitles\nbluback --audio-lang eng,jpn --subtitle-lang eng\n\n# Select specific streams by index (use --list-playlists -v to see indices)\nbluback --tracks \"a:1;s:0-1\"\n\n# Override config filters, include everything\nbluback --all-streams\n```\n\n**TUI track picker** — Press `t` on any playlist in the Playlist Manager to expand its stream list. Toggle individual streams with `Space`. Custom selections are shown in the Ch column as `1v 2a 3s*`.\n\nLanguage filters are preferences, not hard requirements: if no streams match a configured language, all streams of that type are included with a warning. Streams without language tags (`und`) are always included.\n\n## Rip Verification\n\nbluback can verify output files after ripping to catch corruption:\n\n```bash\nbluback --verify                    # Quick: probe headers (duration, streams, chapters)\nbluback --verify --verify-level full  # Full: headers + sample frame decode at 5 seek points\n```\n\nEnable by default in config: `verify = true`, `verify_level = \"quick\"`. In TUI mode, failed verification prompts to delete \u0026 retry, keep, or skip.\n\n## AACS Decryption Notes\n\nbluback relies on libaacs for AACS decryption. You need a `KEYDB.cfg` file at `~/.config/aacs/KEYDB.cfg` containing device keys, processing keys, host certificates, and/or per-disc Volume Unique Keys (VUKs).\n\n**USB drive caveat:** The only publicly available AACS host certificate is revoked in MKBv72+. Discs with newer MKBs require a per-disc VUK entry in the KEYDB. If bluback hangs during disc scanning, check for an orphaned `libmmbd.so.0` on your system — if present without a working MakeMKV backend, libaacs can hang indefinitely.\n\n## AI Disclosure\n\nPortions of this codebase were developed with the assistance of generative AI (Claude Code). This project was started as a test of Claude Code's limits, but turned out to be a genuinely useful tool. \n\n## License\n\n[AGPL-3.0-or-later](LICENSE)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcebarks%2Fbluback","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fcebarks%2Fbluback","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcebarks%2Fbluback/lists"}