{"id":48452804,"url":"https://github.com/freemkv/libfreemkv","last_synced_at":"2026-06-07T06:02:07.996Z","repository":{"id":349574667,"uuid":"1203035029","full_name":"freemkv/libfreemkv","owner":"freemkv","description":"4K UHD / Blu-ray / DVD drive library — open source raw disc access","archived":false,"fork":false,"pushed_at":"2026-06-05T04:46:43.000Z","size":4288,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-06-05T06:02:38.558Z","etag":null,"topics":["4k","blu-ray","disc-ripping","dvd","linux","open-source","optical-drive","rust","uhd"],"latest_commit_sha":null,"homepage":null,"language":"Rust","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/freemkv.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"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-04-06T16:51:50.000Z","updated_at":"2026-06-05T04:46:46.000Z","dependencies_parsed_at":"2026-06-05T06:02:01.904Z","dependency_job_id":null,"html_url":"https://github.com/freemkv/libfreemkv","commit_stats":null,"previous_names":["freemkv/libfreemkv"],"tags_count":178,"template":false,"template_full_name":null,"purl":"pkg:github/freemkv/libfreemkv","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/freemkv%2Flibfreemkv","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/freemkv%2Flibfreemkv/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/freemkv%2Flibfreemkv/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/freemkv%2Flibfreemkv/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/freemkv","download_url":"https://codeload.github.com/freemkv/libfreemkv/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/freemkv%2Flibfreemkv/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":34010556,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-06-07T02:00:07.652Z","response_time":124,"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":["4k","blu-ray","disc-ripping","dvd","linux","open-source","optical-drive","rust","uhd"],"created_at":"2026-04-06T21:04:20.749Z","updated_at":"2026-06-07T06:02:07.963Z","avatar_url":"https://github.com/freemkv.png","language":"Rust","funding_links":[],"categories":[],"sub_categories":[],"readme":"[![Crates.io](https://img.shields.io/crates/v/libfreemkv)](https://crates.io/crates/libfreemkv)\n[![docs.rs](https://img.shields.io/docsrs/libfreemkv)](https://docs.rs/libfreemkv)\n[![License: AGPL-3.0](https://img.shields.io/badge/license-AGPL--3.0-blue)](LICENSE)\n\n# libfreemkv\n\nRust library for 4K UHD / Blu-ray / DVD optical drives. Drive access, disc scanning, stream labels, AACS decryption, CSS decryption, KEYDB updates, and content reading in one crate. Bundled drive profiles — no external files needed.\n\nBuilt-in keys cover DVDs and Blu-rays (AACS 1.0). For UHD (AACS 2.0 / 2.1) discs, an optional `keydb.cfg` supplies disc-specific volume unique keys.\n\n**12+ MB/s** sustained read speeds on BD. Full init: unlock, firmware upload, speed calibration — all from pure Rust.\n\nMulti-lingual by design — the library outputs structured data and numeric error codes, never English text. Build any UI or localization on top.\n\n**[API Documentation](https://docs.rs/libfreemkv)** · **[Technical Docs](docs/)**\n\nPart of the [freemkv](https://github.com/freemkv) project.\n\n## Install\n\n```toml\n[dependencies]\nlibfreemkv = \"0.25\"\n```\n\n## Quick Start\n\n```rust\nuse libfreemkv::{Drive, Disc, ScanOptions};\nuse std::path::Path;\n\n// Open drive — profiles are bundled, auto-identified\nlet mut drive = Drive::open(Path::new(\"/dev/sg4\"))?;\ndrive.wait_ready()?;              // wait for disc\ndrive.init()?;                     // unlock + firmware upload\ndrive.probe_disc()?;               // probe disc surface for optimal speeds\n\n// Scan disc — UDF, playlists, streams, AACS (all automatic)\nlet disc = Disc::scan(\u0026mut drive, \u0026ScanOptions::default())?;\n\nfor title in \u0026disc.titles {\n    println!(\"{} — {} streams\", title.duration_display(), title.streams.len());\n}\n\n// Stream pipeline — read PES frames from any source, write to any output\nlet opts = libfreemkv::InputOptions::default();\nlet mut input = libfreemkv::input(\"iso://Disc.iso\", \u0026opts)?;\nlet title = input.info().clone();\nlet mut output = libfreemkv::output(\"mkv://Movie.mkv\", \u0026title)?;\nwhile let Ok(Some(frame)) = input.read() {\n    output.write(\u0026frame)?;\n}\noutput.finish()?;\n```\n\n### Multi-pass recovery rip\n\nFor damaged discs the library exposes two flat verbs — `Disc::sweep` for the\nforward Pass 1 and `Disc::patch` for retrying bad ranges. The library never\nloops; the multipass policy is the caller's job. See\n[`docs/rip-recovery.md`](docs/rip-recovery.md).\n\n```rust\nuse libfreemkv::{SweepOptions, PatchOptions};\nuse libfreemkv::disc::{mapfile, mapfile_path_for};\nuse std::path::Path;\n\nlet iso = Path::new(\"disc.iso\");\n\n// Pass 1: disc → ISO. Skip-on-error, zero-fill, write the sidecar mapfile.\ndisc.sweep(\u0026mut drive, iso, \u0026SweepOptions {\n    decrypt: true,\n    resume: false,\n    batch_sectors: None,\n    skip_on_error: true,\n    progress: None,\n    halt: None,\n})?;\n\n// Pass 2..N: retry every non-finished range. Idempotent.\nloop {\n    let map = mapfile::Mapfile::load(\u0026mapfile_path_for(iso))?;\n    let stats = map.stats();\n    if stats.bytes_pending + stats.bytes_unreadable == 0 { break; }\n\n    let outcome = disc.patch(\u0026mut drive, iso, \u0026PatchOptions {\n        decrypt: true,\n        block_sectors: None,\n        full_recovery: true,\n        reverse: true,\n        wedged_threshold: 50,\n        progress: None,\n        halt: None,\n    })?;\n    if outcome.bytes_recovered_this_pass == 0 { break; }\n}\n\n// Mux from the ISO via the normal stream pipeline (no drive involvement).\n```\n\n## What It Does\n\n- **Drive access** — open, identify, unlock, firmware upload, speed calibration, eject\n- **12+ MB/s reads** — auto-detects kernel transfer limits, sustained full speed\n- **Disc scanning** — UDF 2.50 filesystem, MPLS playlists, CLPI clip info\n- **Stream labels** — 5 BD-J format parsers (Paramount, Criterion, Pixelogic, CTRM, Deluxe)\n- **AACS decryption** — transparent key resolution and content decrypt (1.0 + 2.0 bus decryption)\n- **KEYDB updates** — download, verify, save from any HTTP URL (zero deps, raw TCP)\n- **Content reading** — adaptive batch reads with automatic decryption\n- **Stream I/O** — unified stream pipeline for reading and writing any format\n\n### Streams\n\n| Stream | Input | Output | Transport |\n|--------|-------|--------|-----------|\n| DiscStream | Yes | -- | Optical drive via SCSI |\n| IsoStream | Yes | -- | Blu-ray ISO image file (read via stream pipeline; written via `Disc::sweep()`) |\n| MkvStream | Yes | Yes | Matroska container |\n| M2tsStream | Yes | Yes | BD transport stream with FMKV metadata header |\n| NetworkStream | Yes (listen) | Yes (connect) | TCP with FMKV metadata header |\n| StdioStream | Yes (stdin) | Yes (stdout) | Raw byte pipe |\n| NullStream | -- | Yes | Discard sink (byte counter for benchmarks) |\n\nStreams implement `FrameSource` (read) and/or `FrameSink` (write); direction is type-checked. `input()` / `output()` resolve URL strings to PES stream instances. All URLs use the `scheme://path` format — bare paths are rejected.\n\n### Keys\n\nDVDs (CSS) decrypt out of the box — the 1999-era public player keys are compiled into the library.\n\nBlu-rays and UHD (AACS) require a `keydb.cfg` at `~/.config/freemkv/keydb.cfg` (or passed via `ScanOptions`). The file holds all DKs, PKs, host certs, and per-disc VUKs. No AACS key material is compiled into the binary.\n\n## Architecture\n\n```text\nDrive                  — open, identify, init, unlock, single-shot read\n  ├── ScsiTransport    — SG_IO (Linux), IOKit (macOS), SPTI (Windows)\n  ├── DriveProfile     — per-drive unlock parameters (bundled)\n  └── PlatformDriver   — MediaTek (supported), Renesas (planned)\n\nDisc                   — scan titles, streams, AACS/CSS state\n  ├── UDF reader       — Blu-ray UDF 2.50 with metadata partitions\n  ├── MPLS parser      — playlists → titles + clips + streams\n  ├── CLPI parser      — clip info → EP map → sector extents\n  ├── IFO parser       — DVD title sets, PGC chains, cell addresses\n  ├── Labels           — 5 BD-J format parsers (detect + parse)\n  ├── AACS             — key resolution + content decryption\n  ├── CSS              — DVD CSS cipher (table-driven, no keys needed)\n  └── KEYDB            — download + verify + save\n\nStreams                — unified PES pipeline\n  ├── FrameSource      — read() PES frames (direction-typed)\n  ├── FrameSink        — write() PES frames (direction-typed)\n  ├── DiscStream       — sectors → decrypt → TS demux → PES\n  ├── IsoStream        — ISO file → decrypt → TS demux → PES\n  ├── MkvStream        — MKV mux/demux\n  ├── M2tsStream       — BD transport stream\n  ├── NetworkStream    — TCP with FMKV metadata header\n  ├── StdioStream      — stdin/stdout pipe\n  └── NullStream       — discard sink\n```\n\nSee [docs/](docs/) for detailed technical documentation on each module.\n\n## Error Codes\n\nAll errors are structured with numeric codes. No user-facing English text — applications format their own messages.\n\n| Range | Category |\n|-------|----------|\n| E1xxx | Device errors (not found, permission) |\n| E2xxx | Profile errors (unsupported drive) |\n| E3xxx | Unlock errors (failed, signature) |\n| E4xxx | SCSI errors (command failed, timeout) |\n| E5xxx | I/O errors |\n| E6xxx | Disc format errors |\n| E7xxx | AACS errors |\n| E8xxx | KEYDB update errors |\n\n## Platform Support\n\n| Platform | Status | Backend |\n|----------|--------|---------|\n| Linux | Supported | SG_IO ioctl |\n| macOS | Supported | IOKit SCSITask |\n| Windows | Supported | SPTI |\n\n## Contributing\n\nRun `freemkv info disc:// --share` with the [freemkv CLI](https://github.com/freemkv/freemkv) to contribute your drive's profile.\n\n## License\n\nAGPL-3.0-only\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ffreemkv%2Flibfreemkv","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ffreemkv%2Flibfreemkv","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ffreemkv%2Flibfreemkv/lists"}