Rip Audio CDs, DVDs, and Blu-rays on Linux — available as a CLI tool and a Flutter desktop GUI.
- Audio CD → FLAC, with metadata from MusicBrainz / CDDB / CD-TEXT and cover art from the Cover Art Archive
- DVD → lossless MKV via libdvdread (CSS decryption) or VOB concat fallback
- Blu-ray → lossless MKV via libbluray (AACS/BD+) or direct M2TS concat fallback
Drive detection updates in real time using udevadm monitor and the CDROM_DRIVE_STATUS ioctl.
| Package | Path | Description |
|---|---|---|
disc_buddy |
disc_buddy_lib/ |
Pure-Dart library — disc parsing, ripping, metadata, naming |
disc_buddy_cli |
disc_buddy_cli/ |
CLI binary |
disc_buddy_ui |
disc_buddy_ui/ |
Flutter desktop GUI |
Runtime:
| Tool | Purpose |
|---|---|
ffmpeg + ffprobe |
encoding / probing |
lsblk, udevadm, eject |
drive detection and disc management |
libdvdread (optional) |
CSS decryption on encrypted DVDs |
libbluray + KEYDB.cfg (optional) |
AACS decryption on encrypted Blu-rays |
discid (optional) |
accurate MusicBrainz disc ID lookup |
mkvextract + subtile-ocr (optional) |
subtitle extraction / OCR — feeds LLM auto-naming |
whisper-cli + ggml model (optional) |
whisper.cpp audio-transcription fallback for auto-naming titles without subtitles (config keys whisper / whisper-model, CLI --whisper / --whisper-model; use a multilingual model such as ggml-small.bin for non-English discs) |
Build (CLI): Dart SDK ≥ 3.13. disc-buddy --version prints the version baked in at
compile time (dart compile exe -DDISC_BUDDY_VERSION=v1.2.3 …; CI uses the git tag).
Build (UI): Flutter ≥ 3.47 (stable channel)
Install runtime dependencies on Fedora:
sudo dnf install ffmpeg lsblk util-linux udev libdvdread libbluray libaacs discid
# KEYDB.cfg for AACS: copy to ~/.config/aacs/KEYDB.cfgdart pub get
dart run disc_buddy_cli/bin/rip.dart [options]Or compile to a native binary:
dart compile exe disc_buddy_cli/bin/rip.dart -o disc-buddy-cli-linux-x64
./disc-buddy-cli-linux-x64 [options]cd disc_buddy_ui
flutter pub get
flutter run -d linuxOr build a release bundle:
flutter build linux --release
# Output: disc_buddy_ui/build/linux/x64/release/bundle/Usage: disc-buddy [options]
-d, --device Optical device (e.g. /dev/sr0) [env: DISC_DEVICE]
-o, --output Output directory [env: OUTDIR, default: ./output]
--ffmpeg Path to ffmpeg binary [default: ffmpeg]
--ffprobe Path to ffprobe binary [default: ffprobe]
-f, --force Overwrite existing files; skip language prompts
-h, --help Show help
When --device is omitted, an interactive drive selection menu is shown. The menu updates in real time as discs are inserted or removed.
output/
DISC_TITLE/ # DVD / Blu-ray
title_01.mkv
title_02.mkv
...
Artist/ # Audio CD
Album (Year)/
01-Track Title.flac
02-Track Title.flac
cover.jpg
- Reads the TOC via
discidor FFI SG_IO to compute an exact MusicBrainz disc ID. - Looks up metadata in MusicBrainz, falls back to CDDB/GnuDB, then CD-TEXT.
- Downloads front cover art from the Cover Art Archive (if a MusicBrainz release is found).
- Rips selected tracks to FLAC with full metadata tags (title, artist, album, track number, MusicBrainz IDs, …).
- Parses
VIDEO_TS.IFOand allVTS_XX_0.IFOfiles to enumerate titles with their duration, audio tracks (codec, channels, language), subtitle tracks, and cell ranges. - Smart auto-selection suggests titles for ripping:
- Filters out clips shorter than 5 minutes (menus, trailers).
- Detects series when ≥ 3 titles have similar duration (±30 % of median).
- Otherwise selects the longest title (main feature).
- Rips using libdvdread (via FFI) for CSS-encrypted discs. Falls back to VOB concat for unencrypted discs.
- Audio and subtitle tracks are mapped in IFO order; language codes and codec titles are written as MKV metadata.
- Parses MPLS playlist files and CLPI stream info files to enumerate titles with duration, audio, and subtitle tracks.
- Uses the same smart auto-selection logic as DVD.
- Rips using libbluray (via ffmpeg) when available. Falls back to direct M2TS concat for unencrypted discs.
- LPCM audio tracks are transcoded to FLAC; all other tracks are stream-copied.
The pure-Dart modules are exported from package:disc_buddy/disc_buddy.dart and can be used in Flutter apps without modification:
import 'package:disc_buddy/disc_buddy.dart';
// DVD titles
final ripper = DVDRipper(opts);
final result = await ripper.loadTitles();
// Blu-ray titles
final ripper = BlurayRipper(opts);
final result = await ripper.loadTitles();
// MusicBrainz lookup
final meta = await MusicBrainz.lookup(discId, startTimes, leadOut);
// Cover art
final bytes = await CoverArt.fetchFront(releaseMbid);disc_buddy_lib/ Pure-Dart library (Dart workspace)
lib/src/
selection/
title_selector.dart Auto-selection logic for DVD and Blu-ray titles
device/
drive_detector.dart Lists optical drives via lsblk + udevadm
drive_status.dart CDROM_DRIVE_STATUS ioctl (tray open / loading / no disc)
disc_type_detector.dart Detects Audio CD / DVD / Blu-ray via udevadm
cdrom_toc.dart SG_IO READ TOC for exact MusicBrainz disc ID
dvdread.dart libdvdread FFI for CSS-decrypted VOB streaming
resilient_read.dart Retry / bisect / zero-fill of unreadable DVD sectors
ffmpeg/
ffmpeg_runner.dart Runs ffmpeg with progress tracking
metadata/
musicbrainz.dart MusicBrainz Web Service v2 lookup
cddb.dart CDDB / GnuDB lookup (fallback)
disc_id.dart MusicBrainz disc ID computation
cover_art.dart Cover Art Archive fetch
models/ Data classes (DriveInfo, DvdTitle, BlurayTitle, …)
naming/
auto_namer.dart Orchestrates LLM/TMDB auto-naming
subtitle_source.dart Subtitle / transcript loading + LLM summary
title_resolver.dart TMDB title search and scoring
episode_matcher.dart Episode matching, verification, conflicts
episode_math.dart Pure stem / multi-part / duration helpers
rippers/
audiocd_ripper.dart Audio CD → FLAC
dvd_ripper.dart DVD → MKV (libdvdread + VOB concat fallback)
bluray_ripper.dart Blu-ray → MKV (libbluray + M2TS concat fallback)
rip_report.dart Per-title read-error / duration report
utils/
log.dart LogCallback + stdio/emit helpers (lib never prints itself)
prompter.dart Prompter interface (TTY and non-interactive)
atomic_output.dart .part file + atomic rename for every rip
… mount, sanitize, languages, …
disc_buddy_cli/ CLI binary (Dart workspace)
bin/rip.dart Entry point: drive/ISO flow, eject, disc waiting
lib/src/cli/
options_builder.dart Argument parser + CLI/config resolution
naming_flow.dart Rename / auto-name / subtitle prompts
directory_mode.dart Directory and single-MKV modes
rename.dart Renames with sidecar files
menu.dart Drive selection menu (real-time udevadm monitor)
test/ CLI unit tests (no drive needed)
disc_buddy_ui/ Flutter desktop GUI (outside workspace)
lib/
main.dart App entry point
screens/ Home and settings screens
widgets/ Drive list, title selection, rip progress, …
providers/ Riverpod state management
models/ UI-side data models
linux/ Linux runner (CMake)