Skip to main content

Platterpus

Platterpus

A secure, EAC-style CD ripper for Linux (FLAC, WAV, WavPack, MP3). Aims for EAC-equivalent (Exact Audio Copy) archival quality on Linux, packaged as a single-file AppImage. It drives the cyanrip ripping engine and verifies every rip against AccurateRip and CTDB.

Status: v0.7.104, pre-1.0. Platterpus installs one pinned build of its own fork of cyanrip, and a new build becomes the default only after a handshake round: both projects check each other's work and both declare GO. Which build that is, and which round approved it, is shown in Help → About Platterpus… (the Ripper section) and in the generated map in DEPENDENCIES.md. 0.7.100 is the first release with a full-green hardware acceptance run behind it (2026-10-07), made on 0.6.66 with the fork build .21; round 31 approved that pair, and 0.7.103 is the first release that installs .21 by default, and passed its own full-green run with it on 2026-10-12. 0.8.1 needs a second such pass on another machine and distro (docs/testing.md §5B). What changed in each release: CHANGELOG.md.

On the Pioneer BDR-209D, leave Overread (-O) off. With it on, cyanrip stopped at the last track's lead-out for about 23 minutes (2026-07-22, reproduced the next day; stock cyanrip 0.9.3, before the fork). Platterpus only passes the flag: the read that stalled is cyanrip's. What is not yet settled is the split between the drive refusing to read past the end of the disc and cyanrip retrying that refused read for so long. It has not been tried on the fork's builds, and our next handshake lap asks the fork (docs/dependency-contracts.md).

What is in it. No-terminal first-run setup (the AppImage adds itself to your menu; a guided wizard installs the ripping stack), read-offset auto-fill from the bundled AccurateRip drive list, cyanrip as the single ripping backend (KDD-18; the Platterpus fork is KDD-32/33), multiple output formats (FLAC is always the lossless master; WavPack, MP3 and WAV are derived from it), goal presets (Fast Verified / Archival Exact / Portable), an at-a-glance verification verdict (AccurateRip + CTDB) with a JSON rip report beside the log, in-app updates, cover art from the Cover Art Archive, filing finished rips into your library folder, and an EAC-compatible companion log with a per-track EAC CRC32 column. It is validated on real hardware (Bazzite, Pioneer BDR-209D). This is an early release for wider testing: expect rough edges, and please open an issue for anything you hit.

Getting started

This guide takes you through your first archival rip: one ordinary audio CD, from downloading Platterpus to a folder of verified FLAC files. Allow about twenty minutes for the setup, plus the rip itself, which depends on the disc and the drive.

You need an audio CD, a CD, DVD or Blu-ray drive, and an Internet connection, because the disc is looked up on MusicBrainz and checked against AccurateRip and CTDB.

Words in bold, like Start rip, are labels you will see in the app, spelled as they appear there.

1. Download Platterpus and open it

Download platterpus-x86_64.AppImage from the project's Releases page on GitHub. It is one file: there is nothing to install.

Before it can run, your system has to be told that the file is a program. In your file manager, right-click the file, open its properties, and on the permissions page tick the option that lets it run as a program. Then double-click it.

2. Let Platterpus set itself up

The first time it opens, Platterpus may offer to add itself to your applications menu. Accept if you want it there.

It then asks Set up Platterpus: the ripping tool, cyanrip, runs in a small container so that it never touches the rest of your system, and Platterpus installs it for you. Answer Yes. It takes a few minutes and may ask for your password once. Nothing here needs a terminal.

If you said no, or want to run it again, it is in Tools → Setup & Updates… as Run setup….

3. Set up your drive

Every drive starts reading a few samples early or late. The read offset corrects that, and a rip is only bit-perfect, and only matches AccurateRip, when it is right. You set it once per drive.

After setup, Platterpus offers to do this. You can also open it any time from Tools → Setup & Updates… with Set up drive….

For most drives the offset is already known from AccurateRip's list of drives and is filled in for you: press Save offset. No disc is needed. If your drive is not in that list, type its offset into Read offset (samples): by hand.

4. Look at the settings

Open Tools → Settings…. The defaults are already the archival ones, so for your first rip you do not need to change anything:

  • Output format: is FLAC, lossless, and the file every other format is made from.
  • The rip is checked against AccurateRip, and Verify with CTDB after a rip is on.
  • A track AccurateRip cannot confirm is read again until two reads agree.
  • Cover art: is embedded in every file.

One thing is off by default: Write an EAC-compatible log beside each rip. Tick it if you want a log in the layout Exact Audio Copy users know. Platterpus always keeps cyanrip's own log and its report either way.

Your music goes under Output directory:, one folder per album.

5. Insert the disc

Put the CD in the drive. Platterpus reads it and looks it up on MusicBrainz.

If more than one release matches, Pick a MusicBrainz release asks which one is yours. Choose the one whose country, year and barcode match your copy.

The album appears: Album title:, Album artist:, Year: and the track list. Correct anything that is wrong here. What you see is what is written into the files.

6. Rip

Press Start rip. Every track is ripped unless you untick it in the track list.

The progress bar shows how far the rip has got, with the track being read and an estimate of the time left. You can press Cancel at any time.

7. Read the verdict

When the rip finishes, a verification banner appears above the results and stays there:

  • green, Bit-perfect: every track matches other people's rips of the same disc in AccurateRip. This is the archival standard.
  • amber: some tracks matched and some did not. The table says which.
  • grey: AccurateRip has no rips of this disc to compare with. That is not a failure, but the audio has not been checked against anyone else's.

The per-track results are in the table below the banner, and the CTDB result is on the Details tab.

8. What you get

In the album's folder:

  • one FLAC file per track, tagged, with the cover art inside it;
  • a cue sheet, the map of the disc's tracks;
  • cyanrip's log, the record of the rip, which cyanrip can verify was not edited;
  • the report, .platterpus.json, with every result in a form a program can read;
  • the EAC-style log, if you turned it on.

Keep the logs and the report with the music. They are the proof of what was read.

9. If a track is not fully verified

Two results deserve a second look:

  • One frame only: AccurateRip matched one frame of the track, 1/75 of a second, and nothing else. The rest of the track is not verified.
  • A track that needed heavy re-reading, or whose reads never agreed: the drive could not read it the same way twice.

Clean the disc and rip it again. Help → User Guide… explains every result in full, and how to compare the new rip with the last one.

At a glance

  • Linux only. Primary target is Bazzite KDE Plasma 6; should work on any modern desktop Linux running Qt 6 (Fedora, Arch, Ubuntu, Tumbleweed).
  • Runs cyanrip inside Distrobox. The GUI calls the host-exported cyanrip binary; it never bundles cyanrip, and the guided wizard installs it inside the container. This is intentional — see PLANNING.md §8 KDD-07.
  • Single-file AppImage for the GUI itself; no system-level installs required.
  • No terminal prompts from the ripper — the GUI queries MusicBrainz directly, then runs cyanrip offline with the chosen release's tags, so its interactive prompt never surfaces.
  • Choose your output format — FLAC (default), WavPack, MP3, or WAV. FLAC is always produced as the lossless master; other formats are derived from it, so you never lose the archival copy. See Audio output.
  • Distribution model: AppImage primary, pipx secondary.

Capability & EAC-parity matrix

Where Platterpus stands against EAC-equivalent archival quality: what it has, what's missing, whether each gap is closeable, and — if closing it needs an upstream pull request — from which project's maintainer. ✅ have it · ⚠️ partial · ❌ not yet. Maintainers: cyanreg = cyanrip, rocky = libcdio-paranoia, itismadness = OPS/Orpheus Logchecker.

Capability Status Reachable? — how / who
Bit-perfect audio, CRC-provable ✅ Have it — AccurateRip + CTDB CRCs
AccurateRip verify (v1 + v2) ✅ Have it
CTDB audio-CRC verify ✅ Have it — CRC hardware-validated (KDD-16)
EAC-style log + per-track EAC CRC32 column + software-version provenance ✅ Have it
MusicBrainz tags · front/back/booklet art · UPC/catalog/label · ReplayGain ✅ Have it
AppImage · zero-terminal setup · in-app update · FLAC master + WavPack/MP3/WAV ✅ Have it
Gap / INDEX 00 pre-gap detection ✅ Have it, on the Platterpus fork, which carries PR #115's sub-channel pregap reader (pregap.c). On the reference disc it finds every pregap EAC finds, to the hundredth of a second (output_reference/cyanrip_fork_flac/, 2026-08-04, held by tests/test_fork_rip_eac_parity.py), and writes them into the cue as INDEX 00 (on the 2026-10-07 run, the same nine tracks as EAC's cue). Stock cyanrip 0.9.3 finds none
HTOA (audio hidden before track 1) ➖ Out of scope: such discs are rare, none has been tested, and ripping that audio is not offered (docs/eac-parity.md)
Test & Copy (two full passes) ✅ Have it (KDD-30) — cyanrip -Z re-read consensus is the two-reads-agree guarantee; a confirmed track renders as a matching Test CRC / Copy CRC pair, and Verify every track runs it disc-wide
Cache-defeat verdict ✅ Have it (KDD-29) — measured with cd-paranoia -A (libcdio's copy of cyanrip's own read engine) via Set up drive → Analyse cache; still honestly "(unknown)" when inconclusive, never faked
Log integrity checksum (ours, openly verifiable) ✅ Have it (KDD-28) — a plain SHA-256 of the log text, at least as strong as EAC's and checkable with sha256sum (no secret key). Clearly labelled not an EAC checksum
C2 error pointers ✅* Aligned with EAC archival best practice — which disables C2. The perfect-rip guide leaves C2 unchecked even when the drive supports it (drives falsely report clean reads while dropping C2 internally); the archival path relies on re-reads + AccurateRip/CTDB. So "no C2" is correct, not a gap
Signed EAC log checksum ❌ Never — signing our log as EAC forges provenance (bannable fake log). No PR, ever
Elite-tracker (RED/OPS/Orpheus) log acceptance ❌ Out of scope — identity-walled (checkers score cyanrip 0 regardless of audio). Honest path: rip with a ripper the log checkers accept, or a 2-PR chain cyanreg → itismadness (low odds)

In short: everything that proves a good archival rip — bit-perfect audio, AccurateRip + CTDB verification, a measured cache-defeat verdict, Test & Copy, an openly-verifiable log checksum, tags, art, provenance — is in place. Each of those was closed with equal-or-stronger rigor than EAC, honestly labelled as ours — we never forge EAC's output. Pre-gap detection, the gap this sentence used to name, is closed on the fork: it finds every pregap EAC finds. What remains is two tracks of the reference disc. Every track has been read AccurateRip-verified, but never all fourteen in one rip: track 3 reads differently from pass to pass on our drive, and track 5's verified read (one EAC itself did not get) has come once in 18 rips (docs/eac-parity.md, TL;DR item 1). Hidden track-one audio (HTOA) is out of scope. The rest is either never (signed checksum = forgery), aligned with best practice (C2 stays off), or identity-walled (elite-tracker acceptance). Contributor detail: docs/cyanrip-upstream.md and docs/cyanrip-fork.md Part A §10.

Point-by-point vs. the EAC "perfect rip" checklist

Mapped directly to the settings the Archival-Grade Extraction master guide calls out for EAC 1.8 (docs/archive/archival-extraction-guide-2026-06.md). ✅ matches · ⚠️ partial/in-progress · ➖ deliberately N/A.

EAC "perfect rip" setting Platterpus / cyanrip equivalent Match
Secure Mode — re-read sectors until statistical parity cyanrip paranoia = max + -Z N consensus re-read (re-reads a track until N+1 reads are identical) ✅
Accurate Stream drive feature no equivalent: cyanrip does not report it, and the EAC-compatible log says so ((not reported by the ripper)) ➖
Drive caches audio data → flush cache between re-reads (cache-defeat) libcdio-paranoia attempts cache-defeat every rip, and Set up drive → Analyse cache now measures the verdict with cd-paranoia -A — libcdio's own copy of that same read engine — recording a real Yes/No per drive into the EAC-compatible log (KDD-29). Inconclusive stays honestly "(unknown)", never a faked "Yes" (KDD-25) ✅
C2 error info — leave UNCHECKED (disable, even if supported) We don't use C2 → exactly what the guide prescribes ✅
Read sample offset correction applied via cyanrip -s, value from the bundled AccurateRip drive DB (by model, e.g. +667) or manual entry. Instead of EAC's one-shot "Key Disc" probe, every rip that matches the AccurateRip consensus re-confirms the offset on your own drive and promotes its trust line to confirmed (KDD-31) — the same corrected result, continuously re-proven ✅
Overread into Lead-In/Lead-Out — off unless firmware-verified off by default, as the guide says: the few samples the read offset pushes past the disc's edge are filled with silence, which is what EAC does with overread off (tracks 1 and 14 match EAC and AccurateRip). Settings → Overread reads the real outermost samples (cyanrip -O) for a drive that supports it; the BDR-209D does not (above) ✅
Allow speed reduction on scratches Platterpus's adaptive read-speed ladder: a pass with read errors is re-ripped a rung slower (8×, 4×, 2×, through cyanrip -S). Whole-disc passes, not EAC's per-sector slow-down ✅
Gap/Index — Detection Method A, Secure the Platterpus fork reads each pregap from the sub-channel (PR #115's reader, carried) and finds every pregap EAC finds on the reference disc, to the hundredth of a second; they are written into the cue as INDEX 00 ✅
AccurateRip verify v1 + v2 (+ offset-variant) ✅
CTDB verify present — CRC hardware-validated (KDD-16) ✅
FLAC -8 -V -j (max compression + decode-verify + threads) cyanrip FLAC at maximum compression → post-rip FLAC verify (decodes clean) ✅
WAV uncompressed baseline WAV output (no tags — the UI warns) ✅
WavPack hybrid -c + -m -v WavPack lossless, encoded from the verified FLAC master. After every encode, the .wv and its master are decoded and their PCM compared, which is a stronger proof than -v. The hybrid's lossy half is what the MP3 output is for ✅
LAME -V 0 -q 4 (dodge the r6147 noise_shaping_amp bug) MP3 is encoded by ffmpeg VBR, not lame.exe -q 0..3 — so that LAME-specific footgun isn't in our path ➖
Vorbis / APEv2 / ID3 tags per format FLAC→Vorbis (cyanrip), MP3/WavPack tags via ffmpeg ✅
Signed EAC log checksum never — signing our log as EAC forges provenance ➖ (refused)

Installation

You don't need the command line. Download the GUI, double-click, and it sets itself up by asking a couple of questions.

  1. Download platterpus-x86_64.AppImage from the Releases page (one file).
  2. Allow it to run (a one-time Linux step — a downloaded program isn't runnable until you say so):
    • KDE (Dolphin): right-click the file → Properties → Permissions → tick Is executable → OK.
    • GNOME (Files): right-click → Properties → Permissions → enable Allow executing file as program.
  3. Double-click it. On first launch it will offer to:
    • add Platterpus to your applications menu (so next time you just click it in the menu), and
    • set up the ripping tool — a guided wizard installs everything ripping needs (it may ask for your password once). It takes a few minutes: it creates the container and builds the ripper. No terminal.
  4. Then in the app: Tools → Setup & Updates… → Set up drive… — your drive's read offset is filled in automatically; click Save offset. Insert a CD and Start rip.

That's the whole thing: one download, a couple of clicks, answer the prompts. (Updating later: Tools → Setup & Updates… → Check for updates — the app updates itself.)

Easy second option — one command with pipx

Comfortable with a terminal? A single copy-paste installs Platterpus from PyPI and puts it on your PATH (the GUI still runs the first-run wizard to set up the ripping stack):

pipx install platterpus    # then run:  platterpus

Don't have pipx? sudo dnf install pipx (Fedora/Bazzite) or sudo apt install pipx (Ubuntu/Debian). Upgrade later with pipx upgrade platterpus. (To run unreleased/dev code from a checkout instead, see Method B.)

Why a wizard? Ripping runs through cyanrip inside a small container so it never touches your system (why). The first-run wizard sets that container up for you — the same work the scripts below do by hand.

Quickstart for testers / scripted install

Prefer one command? This installs the host stack (Distrobox + cyanrip) and the GUI, plus shortcuts:

curl -fsSL https://raw.githubusercontent.com/rmccann-hub/Platterpus/main/install.sh | bash

Prefer to download and run it yourself? Grab install.sh from the Releases page, then bash install.sh. Useful flags: --dry-run (preview), --no-host (GUI only, host stack already set up), --appimage PATH (use a local AppImage). First run takes ~20–40 min because it builds the container.

Before it installs the AppImage it downloads, the script checks it the way the app checks an update: against the release's .sha256, and against its build attestation as well when an installed GitHub CLI can check it (gh 2.51.0 or later; with an older gh it says only the checksum was checked). A file that fails either check is refused, and an AppImage you already have is left as it was.

Then, inside the GUI: Tools → Setup & Updates… → Set up drive… to calibrate your drive's read offset (one time), insert a CD, and rip. To remove everything later, use the Uninstall Platterpus shortcut (or see Uninstalling).

Already have cyanrip + Distrobox set up (e.g. re-installing on the same machine, or installing the GUI on a second box that shares the stack)? Skip the host build and just add the GUI: curl -fsSL …/install.sh | bash -s -- --no-host (or bash install.sh --no-host).

Why two pieces under the hood? The GUI can't rip without the host stack — that's by design (why). install.sh just sets up both for you; you can still do each step by hand (below).

Supported distributions

The one-line installer works on any modern desktop Linux. It auto-detects your package manager to install Distrobox + podman; everything ripping-related runs in a Fedora container, so your host distro only needs Distrobox and a container backend.

Distro family Auto-handled by the installer? Notes
Fedora / Bazzite / Silverblue / RHEL / CentOS ✅ Fully Bazzite & Silverblue ship Distrobox + podman already; nothing extra.
Ubuntu / Debian (24.04+) ✅ Fully Installs podman too (the distrobox package only recommends it).
Linux Mint / Pop!_OS / elementary ✅ Fully Ubuntu-based — same path as Ubuntu/Debian.
Arch / Manjaro / EndeavourOS ✅ Fully Installs distrobox + podman via pacman.
openSUSE Leap / Tumbleweed ✅ Fully Installs distrobox + podman via zypper.
Other / older distros ⚠️ Fallback Uses Distrobox's official installer. Make sure podman (or docker) is present first.

If the installer can't set up the host stack on your distro, do the manual steps once — they work everywhere and are the source of truth.

The rest of this section is the long form — read it if the quickstart hits a snag or you'd rather do each step by hand.

Fast path — one command (Steps 1-4 + 7)

setup-host.sh automates the host setup: it installs Distrobox (if needed), creates the ripping container, installs cyanrip + flac inside it, exports the binaries to your host, then clones this repo and runs dev-setup.sh (venv + editable install + app-menu shortcut).

# From a fresh clone:
bash setup-host.sh

# …or straight from the web (no clone needed first):
curl -fsSL https://raw.githubusercontent.com/rmccann-hub/Platterpus/main/setup-host.sh | bash

Useful flags: --dry-run (print every command, change nothing), --yes (skip confirmations), --no-gui (host stack only). It's idempotent — safe to re-run. It does not calibrate your drive (do that in the GUI: Tools → Setup & Updates… → Set up drive…) or install Picard. Picard is optional, so the app never asks about it on its own: to install it, open Tools → Setup & Updates… and press Check dependencies, which offers a one-click Flatpak install.

Prefer to do it by hand, or the script hit a snag? The manual steps below are the source of truth.

Manual steps

There are seven steps, one of them optional. Plan on 20-40 minutes the first time. Once it's done, you don't touch most of it again.

Step What Why
1 Install Distrobox Provides an isolated Fedora environment for cyanrip
2 Create a ripping container Where cyanrip actually lives
3 Install cyanrip + flac in the container The tools that do the ripping
4 Export them to the host So Platterpus can find them
5 Set your drive's read offset One-time calibration for accurate rips
6 Install MusicBrainz Picard (optional) Manual tag editing for unknown discs
7 Install Platterpus This project

If a step doesn't behave as written: skip to the Troubleshooting section near the end of this README. The common surprises — "no drives found", cyanrip: command not found, HTTPS clone authentication failure — all have entries there.

Step 1 — Install Distrobox

Distrobox lets you run a different Linux distribution's tools alongside your host system. It's the recommended way to run cyanrip on immutable distros like Bazzite.

Distrobox needs a container backend — podman (recommended) or docker. Bazzite, Fedora Silverblue, and most atomic distros ship podman already. On Ubuntu/Debian it isn't guaranteed, so install it alongside Distrobox (the commands below do this). If distrobox create later fails with "Cannot find a container manager", a missing backend is why — sudo apt install podman fixes it.

On Bazzite (already pre-installed):

distrobox --version

If you see a version, skip to Step 2.

On Fedora / Fedora Silverblue:

sudo dnf install distrobox

On Arch / Manjaro:

sudo pacman -S distrobox

On Ubuntu / Debian (24.04+):

sudo apt install distrobox podman

(Installing podman explicitly here is the Ubuntu-specific gotcha — the distrobox package only recommends it, so on minimal installs it can be absent and distrobox create then fails.)

On Linux Mint / Pop!_OS / elementary OS:

These are Ubuntu-based, so the Ubuntu command works:

sudo apt install distrobox podman

On openSUSE Leap / Tumbleweed:

sudo zypper install distrobox podman

(If your openSUSE version doesn't package distrobox yet, use the one-line installer under "older systems" below — but install podman with zypper first, since the installer doesn't pull a backend.)

On older systems:

Distrobox has a one-line installer:

curl -s https://raw.githubusercontent.com/89luca89/distrobox/main/install | sudo sh

Verify with distrobox --version.

Step 2 — Create the ripping container

Create a Fedora-based container named ripping. The brief specifies Fedora 40; later Fedora versions also work — substitute :41 or :latest if you prefer.

distrobox create --name ripping --image registry.fedoraproject.org/fedora-toolbox:latest

Distrobox will prompt to pull the image — type Y and press Enter. The download is about 600 MB the first time. Once it finishes:

distrobox enter ripping

You're now inside the container. The prompt should change to show you're in the ripping environment. To leave at any time, type exit.

Why :latest and not :40? The brief specifies Fedora 40; newer Fedora releases (42, 43, 44…) also work and ship newer security fixes. :latest resolves to whatever's current. Don't pin below Fedora 43, though: the cyanrip COPR (barsnick/non-fed) only builds for Fedora 43–45 and rawhide (checked 2026-10-07), so an older container would fail the Step 3 dnf install cyanrip.

Step 3 — Install cyanrip and flac

⚠ READ THIS BEFORE YOU RUN EITHER PATH ON THIS PAGE

Neither the script nor the manual steps below install the ripper Platterpus is verified against. Both add the barsnick/non-fed COPR, which ships stock cyanrip 0.9.3.1. Platterpus pins one build of its fork (Help → About Platterpus… names it in its Ripper section, and so does the generated map in DEPENDENCIES.md), and a rip made with any other build is recorded as unapproved in its rip report (.platterpus.json). The EAC-compatible export names the build that made it, and cyanrip's own log is cyanrip's: Platterpus does not edit it. That is not a warning about quality: the audio is still bit-perfect and still AccurateRip-verified. It is a provenance fact, and provenance is most of why this project exists.

The route to the pinned fork is in the app, and it needs no terminal: the first-run wizard offers it, and --install-ripper does it on demand — see Command-line usage (advanced) and the --install-ripper entry there. It builds the pinned commit; nothing packaged can, because the fork publishes no COPR.

So use the steps below only to get a working container and flac, or as a fallback if the in-app build fails. Then run --install-ripper to replace the stock binary. Two consequences you would otherwise meet as bugs: stock 0.9.3 exits non-zero on --version (the flag table below explains why), so the verification command in the next section fails on it; and the banner it prints carries no platterpus-fork parenthetical, which is the thing that section tells you to look for.

Easiest path for the container and flac: run setup-host.sh (or the one-line installer above). The manual steps below are only if you're doing it by hand.

Inside the container (your prompt should still show you're in ripping):

# flac provides both the `flac` decoder and `metaflac` (the tag editor).
sudo dnf install flac

# cyanrip isn't packaged by Fedora — add the barsnick COPR (GPG-checked), then install it:
sudo dnf copr enable barsnick/non-fed
sudo dnf install cyanrip

# cd-paranoia measures your drive's cache defeat (optional, but exported in Step 4):
sudo dnf install /usr/bin/cd-paranoia

Verify the tools are installed:

cyanrip --version
metaflac --version

On the fork, cyanrip --version prints a version followed by a parenthetical that starts platterpus-fork-g and ends with the commit it was built from. The parenthetical is the part that matters: it names the fork, which is the build Platterpus is verified against — and it is what approved versus unapproved in every rip report is keyed on. Help → About Platterpus… shows whether the build you have is the one this release pins.

If you got here straight from the COPR step above, this command will fail, and that is expected rather than a broken install: stock 0.9.3 exits non-zero on --version, and even when it prints a banner there is no platterpus-fork parenthetical in it. Run --install-ripper first (see the warning in Step 3), then come back to this check.

On the version flag: no single spelling works on every cyanrip. Measured, and published in the fork's own provider contract:

build --version -V -v
stock, before the genopt rewrite (0.9.3) fails works fails
stock, genopt onward (0.9.4-rc1) works fails works
the Platterpus fork works works works

-V and --version are exactly complementary across the stock line, so a probe that has to cover both needs two attempts by construction. On the fork you install here, all three work — use --version. metaflac is part of the flac package.

Step 4 — Export the binaries to your host

Still inside the container, export the binaries. Export all four. The in-app wizard exports all four; setup-host.sh exports the first three. Each one is load-bearing. Run --install-ripper after this step, not before: it exports the fork from /usr/local/bin/cyanrip, and whichever export runs last is the binary Platterpus uses, so the stock export below would otherwise replace the fork:

distrobox-export --bin /usr/bin/cyanrip       # the ripper
distrobox-export --bin /usr/bin/metaflac      # tag + cover-art writing
distrobox-export --bin /usr/bin/flac          # decodes audio for the CTDB check
distrobox-export --bin /usr/bin/cd-paranoia   # measures your drive's cache defeat

This creates wrapper scripts at ~/.local/bin/<name> on the host (not in the container). Those wrappers transparently enter the container when called, so from the host's perspective cyanrip looks like a regular installed program.

Skipping flac is the easy mistake: CTDB verification is on by default and decodes your audio with the host flac, so without it the CTDB check does not run, and the results say so. cd-paranoia is optional — without it the cache-defeat verdict stays honestly "(unknown)".

Now leave the container:

exit

You're back on the host. Verify the wrappers work:

which cyanrip
# → /home/<you>/.local/bin/cyanrip

cyanrip --version
# → cyanrip <version> (platterpus-fork-g<commit>)
#   (`--version`, not `-V`. A stock build prints its own version with no
#    `platterpus-fork` parenthetical.)

If which returns nothing, your ~/.local/bin isn't on $PATH. Most desktop Linux setups put it there automatically; if yours doesn't, add this to ~/.bashrc or ~/.zshrc:

export PATH="$HOME/.local/bin:$PATH"

Then open a new terminal.

Step 5 — Set your drive's read offset

Every optical drive reads audio slightly off from where it "should" — by a positive or negative number of samples. For bit-perfect archival rips that match AccurateRip's database, the offset for your drive has to be known so cyanrip can correct for it.

This is a one-time, in-app step — there's no terminal command for it. cyanrip reads no config file of its own; Platterpus stores the offset in its own config at ~/.config/platterpus/config.toml and passes it to cyanrip at rip time via the -s flag. You set it through the drive-setup wizard, offered on first launch (or anytime from Tools → Setup & Updates… → Set up drive…), which gives you two ways to get the value:

  • Automatic, no disc needed — if Platterpus recognises your drive model, it fills the offset in from the bundled AccurateRip drive-offset list (e.g. +667 for the Pioneer BDR-209D). Just click Save offset.
  • Enter it by hand — look your drive up in the AccurateRip offset list and type the value into the wizard's manual-entry field. Handy if your model isn't recognised, or if you only have CD-Rs.

Why no "detect from a disc" button? cyanrip does have an offset finder (-f, which needs a disc AccurateRip knows), and on the reference drive it found the listed +667 (the 2026-10-07 run). Platterpus does not offer it yet. The drive-offset list is the reliable, disc-free source, and a rip that then verifies against AccurateRip is what confirms the offset is right for your unit.

What about ~/.config/whipper/whipper.conf? That file is a leftover from older versions, if it exists at all. Platterpus no longer reads it, and neither does cyanrip — the offset lives only in Platterpus's own config, set in the drive-setup wizard. There's nothing to create or edit there, and the uninstaller removes it if present.

Step 6 — Install MusicBrainz Picard (optional)

Picard is what you'll use to manually fix tags for discs MusicBrainz doesn't recognize. The GUI installs it as a Flatpak and opens it via flatpak run. Picard is optional, so the app never asks about it on its own: open Tools → Setup & Updates… and press Check dependencies, which offers a one-click install.

Ubuntu/Debian prerequisite: the GUI installs Picard through Flatpak, which isn't installed on Ubuntu by default. Install it once and the GUI's auto-install works as-is afterwards (the GUI's install command points at a .flatpakref that adds the Flathub remote for you, so you don't need a separate flatpak remote-add step):

sudo apt install flatpak

Bazzite, Fedora Silverblue, and most KDE/GNOME spins already ship Flatpak. Picard is optional — if you skip it, the GUI simply lists it as "Optional (not installed)" and never nags; you only need it for hand-editing tags on unrecognized discs.

To pre-install Picard yourself rather than letting the GUI do it:

flatpak install --user flathub org.musicbrainz.Picard

Verify:

flatpak run org.musicbrainz.Picard --version

In File → Rip as Unknown Album…, tick Launch MusicBrainz Picard when the rip finishes to have Platterpus open Picard on the rip folder. The Settings option only decides whether that box starts ticked.

Step 7 — Install Platterpus

Recommended: Method A (AppImage). As of v0.1.0 it's published as a downloadable release asset — this is the simplest path for most people. Method B (pipx install platterpus) installs from PyPI, where the wheel is published automatically on each tagged release via Trusted Publishing (live through the current release). Method C runs the GUI from a source clone and is aimed at developers.

Pick one of the methods below.

Download the latest platterpus-x86_64.AppImage from the Releases page, then:

chmod +x platterpus-x86_64.AppImage
./platterpus-x86_64.AppImage

That's it — the AppImage bundles Python, Qt, and the GUI's dependencies, so there's nothing else to install on the GUI side. (You still need the host stack for ripping to work — the first-run wizard sets it up.)

Menu entry / desktop icon: you don't need to do anything — on its first run the AppImage offers to add itself to your applications menu (and copies its icon), moving itself to ~/Applications so it lives with your other apps instead of staying in Downloads. Just say yes. (The old install-appimage.sh helper still exists for scripted setups and offers an --uninstall, but it's no longer required. AppImageLauncher also works if you prefer.)

Updates: use Tools → Setup & Updates… → Check for updates — if a newer release exists the app downloads it in the background, verifies it against the release's published checksum and its build attestation (an update that fails either check is not installed), installs it to ~/Applications, and restarts itself. (Releases also ship a .zsync file and the AppImage embeds standard update-information, but AppImageUpdate can't use them yet. The update-information asks GitHub for the latest release, GitHub leaves pre-releases out of that, and every v0.* release is a pre-release, so AppImageUpdate gets an HTTP 404 and updates nothing. Use Check for updates instead.)

On a FUSE-less host (rare on desktop Linux, but some minimal setups): run with APPIMAGE_EXTRACT_AND_RUN=1 ./platterpus-x86_64.AppImage, or see AppImage won't launch in Troubleshooting.

pipx installs Python applications in isolated environments and adds them to your PATH.

Install pipx if you don't have it (Bazzite ships with it):

sudo dnf install pipx     # Fedora / Bazzite
# or
sudo apt install pipx     # Ubuntu / Debian

Then install Platterpus:

pipx install platterpus

The wheel is published to PyPI automatically on each tagged release (via Trusted Publishing), so pipx install platterpus is live. To pin a version, pipx install platterpus==X.Y.Z. (Install from a local checkout — git clone … then pipx install . — only when you want unreleased/dev code.)

Run with platterpus from any terminal.

Method C — From source (for developers)

The repository is public, so no authentication is needed to clone over HTTPS. (If you plan to push changes, set up SSH or gh auth login — but for just running from source, a plain clone works.)

Clone and install:

git clone https://github.com/rmccann-hub/Platterpus.git
cd Platterpus

The default main branch contains the full source — no branch switch needed.

From here you have two options.

Option 1 — one-shot setup script (recommended):

bash dev-setup.sh
source .venv/bin/activate
platterpus

dev-setup.sh creates a venv, upgrades pip, and runs pip install -e . for you. Run it again later (after git pull) to refresh dependencies if anything's been added.

Option 2 — manual steps (same effect, if you want to see each one):

# Create a virtual environment. On Bazzite, Fedora 38+, Ubuntu 24.04+,
# and other distros with PEP 668 enforcement, this is required — a
# plain `pip install` against the system Python will refuse with
# "error: externally-managed-environment".
python3 -m venv .venv
source .venv/bin/activate

# pip in a fresh venv is usually outdated; upgrade before installing
# anything else. Avoids "WARNING: ... newer version of pip available."
pip install --upgrade pip

# Install the package in editable mode. From now on, anything you
# edit in src/platterpus/ is picked up the next time you run the GUI.
pip install -e .

# Run the GUI. The console-script entry point lives in .venv/bin
# (added to PATH by the `activate` line above).
platterpus

To re-enter the same environment in a future terminal session:

cd ~/Platterpus
source .venv/bin/activate
platterpus

To leave the venv: deactivate.

To build an AppImage from your local checkout:

pip install --user build "python-appimage>=1.4,<2"
bash build/build_appimage.sh

The resulting platterpus-x86_64.AppImage appears at the repo root. See build/python-appimage/README.md for details.


Ripping backend: cyanrip

The GUI drives a single ripping engine: cyanrip — actively maintained, EAC-equivalent archival quality. There's no backend setting or toggle; cyanrip is it. (The project originally used a different ripper, whose cd-paranoia has a known bug at read offsets over 587 samples that can fail tracks — e.g. the Pioneer BDR-209D's +667; cyanrip applies the offset correctly with its own paranoia even past that threshold, which is why we switched. See KDD-18.)

The GUI does the MusicBrainz lookup itself and then runs cyanrip offline — with -N (no network metadata lookup) and the chosen release's tags fed in via -a/-t — so cyanrip's own interactive prompt never surfaces and the rip needs no in-container network. Cover art is fetched separately by the GUI from the Cover Art Archive.

Audio output: what you get, what you don't

Output format is chosen in Settings → Output format: FLAC (default), WavPack (.wv), MP3, or WAV. Every rip produces FLAC first — the lossless archival master — and for any other choice the GUI keeps that FLAC and creates the selected format alongside it (a quick post-rip transcode via ffmpeg). So you never lose the lossless master, whatever you pick.

Format Lossless? Tags Cover art Use it for
FLAC ✅ (verified bit-perfect) ✅ ✅ embedded The archive. The master copy.
WavPack (.wv) ✅ ✅ folder cover.jpg¹ A lossless library in a different container
MP3 ❌ best-quality VBR (~245 kbps) ✅ ✅ embedded Phones, cars, portability
WAV ✅ ❌ ❌ Raw PCM interchange only (the GUI warns)

¹ The front cover always lands in the album folder as an image file; ffmpeg can't embed art inside a .wv (a known limitation — see docs/archive/mp3-wav-support-2026-06.md). For embedded lossless art, FLAC is the choice.

The flag-by-flag detail below is about how each format is encoded.

(cyanrip reads through libcdio-paranoia and encodes FLAC through FFmpeg at maximum compression. The proof that a read is right comes afterwards, from AccurateRip and CTDB.)

FLAC (default — the lossless archival master)

cyanrip reads each track through libcdio-paranoia at its most careful setting and encodes it to FLAC through FFmpeg at maximum compression. Paranoia corrects read errors; it does not prove the result. The proof is the AccurateRip and CTDB check after the rip, and Verify FLACs checks each file against its stored MD5. There's no compression-level knob to set: it's already at the top.

Earlier versions listed a greyed-out "Re-compress FLACs" toggle in Settings. It could never do anything with cyanrip, so it has been removed. An old settings file that still mentions it loads normally.

For background: all FLAC compression levels are lossless — -0 and -8 decode to identical audio; only file size (and a little decode CPU) differ. cyanrip's max-compression output is the smallest standard FLAC; whether its audio is bit-perfect is what the AccurateRip and CTDB checks say.

The full FLAC encoder reference is at xiph.org/flac/documentation_tools_flac.html.

WavPack, MP3, and WAV (derived from the FLAC master)

When you pick a non-FLAC format, after each rip the GUI transcodes the FLAC master to your choice with ffmpeg, keeping the FLAC. It runs in the background (never freezes the window), writes each file atomically, and never costs you the lossless master — a transcode failure just means you still have the FLAC to retry from. Per file:

# WavPack — lossless, tags carried over (APEv2)
ffmpeg -i <file>.flac -map_metadata 0 -map 0:a -c:a wavpack <file>.wv

# MP3 — best-quality VBR (== lame -V0, ~245 kbps), tags + embedded cover
ffmpeg -i <file>.flac -map_metadata 0 -id3v2_version 3 -c:v copy \
       -c:a libmp3lame -q:a 0 <file>.mp3

# WAV — raw 16-bit PCM (no tags or cover art — RIFF can't hold them)
ffmpeg -i <file>.flac -map 0:a -c:a pcm_s16le <file>.wav

ffmpeg is the single encoder dependency for all three, and it must be on the host's PATH. The setup wizard does not install or export it: cyanrip uses FFmpeg's libraries inside its container, which gives the host no ffmpeg command. Bazzite ships it; elsewhere install your distribution's package. It is detected through the same dependency self-management subsystem as everything else — no bespoke install code. MP3 quality is a setting (MP3 VBR quality, 0–9); the default, 0, is HydrogenAudio's Recommended LAME VBR -V0 (joint-stereo on), the highest-quality VBR. Design + the full encoder-argument rationale: docs/archive/mp3-wav-support-2026-06.md.

Compared to EAC's bit-perfect settings

The widely-cited Perfect CD Ripping to FLAC with Exact Audio Copy guide is the gold standard for archival rips on Windows. The full point-by-point mapping lives once, in the capability & EAC-parity matrix at the top of this README; the per-setting audit is PLANNING.md KDD-13 and the deep-dive is docs/eac-parity.md.

Bit-perfection here is proven the open way — AccurateRip and CTDB CRCs, checkable by anyone against public databases — not by chasing acceptance from private trackers (RED/OPS/Orpheus). That acceptance is a deliberate non-goal: it's gated on ripper identity, not audio quality, so no honest partial score exists to chase. See PLANNING.md KDD-24 and docs/eac-parity.md.

Rip settings at a glance

Now in Settings (surfaced in the Settings dialog):

  • Goal preset — Fast Verified / Archival Exact / Portable snaps the format/verification/quality controls to your intent; editing any of them switches the goal to Custom
  • Output format — FLAC (the lossless master, always produced), WavPack, MP3, or WAV
  • Cover art — fetch + embed in FLAC, save next to it, or both (defaults to embed)
  • Max retries (default 5) — cyanrip's -r: how often a sector that won't read is retried, and the most times a whole track may be read while the next setting looks for identical reads, so keep it above that number
  • Extra matching reads to trust a track — rip once at full speed, then re-read only the tracks that didn't match AccurateRip until this many further reads match one, i.e. N+1 identical reads (cyanrip's -Z; on by default, 2, so three identical reads). See "How ripping works" below.
  • Verify with CTDB after a rip (a second, whole-disc verification path alongside AccurateRip; the CRC is hardware-validated — a match means verified)
  • Verify FLACs after a rip (decode-test each output against its stored MD5)
  • Overread: Read the disc's outermost samples (overread lead-in/out) (off by default) — ask the drive to read the disc's real outermost samples instead of writing them as silence (cyanrip -O). Leave it off unless your drive is known to support overreading: on the Pioneer BDR-209D it stalled a rip for about 23 minutes.
  • Also re-read tracks where only one frame matched AccurateRip (on by default) — such a track is re-ripped like one that did not match at all.
  • Verify every track with a second read (EAC-style Test & Copy) (off by default) — runs the matching-reads check on the whole disc, not only on tracks that need it.
  • MP3 VBR quality (0–9, default 0 = LAME -V0) — used only when the output format is MP3.
  • Move finished rips to a library folder (empty = off) — once every post-rip check has settled (verification, transcode, checksums, the rip report), the album folder is filed into your library; a name collision lands in a "(2)" sibling, never an overwrite
  • Auto-eject after a successful rip, plus read-offset calibration via the drive-setup wizard

(Of the three toggles removed with the previous backend (KDD-18) — force overread, keep-going-on-track-failure, and continue-ripping-CD-Rs — the last two stay gone: cyanrip handles track failures and CD-Rs natively with no equivalent flag. Force overread returned in v0.5.0, rebuilt cyanrip-native as the Overread toggle above.)

After a rip, the results pane shows an at-a-glance verification verdict (green = every track verified against AccurateRip, amber = partial, grey = not in the database) above the per-track table, plus the CTDB result.

How ripping works

Platterpus rips the disc once at full speed and checks every track against AccurateRip. A track that matches the database on that first read is already proven bit-perfect, so it's left alone. Only the tracks that didn't match (and, by default, a track where AccurateRip matched only one frame) are then secure-re-ripped — re-read until enough reads are identical — Extra matching reads to trust a track plus one, so three at the default of 2 (cyanrip's -Z, on by default; Max retries caps how many reads that may take) — and the better read is kept. So a clean disc is a single fast pass (roughly real-time), and the careful, slow work happens only where it's actually needed. If read errors appear, an adaptive read-speed ladder also re-reads the disc more slowly. The FLAC master is always kept and, unless disabled, decode-verified against its stored MD5; any non-FLAC output is derived from that verified master.

See TASKS.md under "EAC bit-perfect parity gaps" for the history.


First run

When you launch Platterpus for the first time:

  1. Set up Platterpus. The first launch offers to install the ripping tools (the container and the ripper). Answer Yes; it takes a few minutes.

    Dependency check. The GUI checks its seven dependencies in the background — cyanrip, metaflac, flac, ffmpeg, cd-paranoia, Picard, and the musicbrainzngs library — and interrupts only if a required one is missing. Tools → Setup & Updates… → Check dependencies shows them all, with one of three resolutions for anything missing:

    • Auto-install (Picard): one OK and it runs flatpak install --user.
    • Pending installs: a checklist for items that need batching or confirmation.
    • Manual install: a copyable search string for anything that needs root (or a reboot) to install.
  2. Drive offset (first launch only). Rips can't be made bit-perfect until your drive's read offset is set. If none is configured yet, the GUI offers the drive-setup wizard once. It can fill the offset in automatically from the bundled AccurateRip drive list (no disc needed), or take a value you enter by hand (look your drive up at accuraterip.com/driveoffsets.htm — handy if your model isn't recognised or you only have CD-Rs). It's a one-time, dismissible prompt; afterwards re-run it anytime from Tools → Setup & Updates… → Set up drive….

  3. Pick a drive. The dropdown at the top of the window lists the optical drives detected on your system. Click Refresh if you plug in a drive after launch.

  4. Insert a CD. The GUI fetches the disc's MusicBrainz ID, looks it up, and shows the match status. If multiple releases match, a picker dialog appears. (The GUI does the MusicBrainz lookup itself and runs cyanrip offline, so the ripper never prompts you for anything — this picker is where any disambiguation happens.)

  5. Edit metadata. The track table is editable. Fix any tags that look wrong before you rip.

  6. Click "Start rip." Overall progress, a live progress bar on the track currently ripping, and per-track AccurateRip confidence appear as the rip runs. You can cancel mid-rip.

  7. View the log. When the rip finishes, View log opens the rip log in a read-only viewer inside the app; its Open externally… button hands it to your editor. If Move finished rips to is set in Settings, the album folder is filed into your library once every post-rip check has settled — the View log / report / folder buttons follow it to its new home.

For discs MusicBrainz doesn't recognize, use the Unknown Album flow from the menu — the GUI rips with placeholder Track NN tags and optionally launches Picard for you to fix them up.


Command-line usage (advanced)

Platterpus is a GUI first, but it has a few command-line flags for diagnostics. There is no platterpus command on your PATH unless you installed via pipx (Method B) or ran dev-setup.sh (Method C). If you run the downloaded AppImage (the recommended install), the AppImage is the executable — pass the flags to it directly (its launcher forwards every argument straight to the app):

First, check where the AppImage actually is. If you accepted the first-run offer to add Platterpus to your application menu, the app moved itself to ~/Applications/platterpus-x86_64.AppImage — it names the new path in the dialog that follows, and there is nothing left in your Downloads folder. Every ./platterpus-x86_64.AppImage … command below then becomes ~/Applications/platterpus-x86_64.AppImage …; a ./-relative command run from where you downloaded it will just say No such file or directory. If you declined the offer, the file is still wherever you put it and ./ works from that folder. When in doubt: ls ~/Applications/platterpus-x86_64.AppImage.

# Show the version and build fingerprint, then exit
./platterpus-x86_64.AppImage --version

# "Doctor" — a no-CD first-pass check of the ripping environment, then exit
./platterpus-x86_64.AppImage --doctor

# Install or update the ripping stack from the terminal, then exit: the
# Distrobox container, cyanrip, and the pinned Platterpus fork of cyanrip built
# over it. Same steps as Tools → Setup & Updates… → Run setup…, and idempotent —
# anything already in place reports "already present" and is left alone.
./platterpus-x86_64.AppImage --install-ripper

# Verify an already-ripped album against the CUETools Database (CTDB) and sweep
# the CRC offset to confirm the read offset aligns with the pressing. No CD or
# re-rip needed — it reads the FLACs already on disk.
./platterpus-x86_64.AppImage --ctdb-calibrate "/path/to/Artist/Album/"

# Audit every already-ripped album under a folder and exit. Read-only: no CD,
# no re-rip, nothing modified. Reports, per album, which cyanrip built it,
# whether the ripper said it finished, which disc of a multi-disc set the tags
# came from, what pre-gap provenance was seen, whether the audio files the
# log claims actually have bytes in them, and any audio file the log does not
# account for, such as the partial file a cancelled rip leaves behind. Exits
# non-zero if anything needs attention, so it is usable from a script.
./platterpus-x86_64.AppImage --audit-rips ~/Music/rips/

# Run a batch of UI tests without a person in front of the machine. FILE holds
# one step per line (open a dialog, check what is on screen, take a screenshot,
# run the ripper and assert its exit code); the app opens its test console with
# the file loaded and starts it immediately. The window is real and on screen —
# this is "no person needed", not "no display needed". A failing step is recorded
# and the batch keeps going, so you always come back to a complete transcript.
# The test-script console (Tools → Advanced → Run test script…) has the same
# thing as a saved setting, with an option to run it on every launch.
./platterpus-x86_64.AppImage --run-script ~/my-tests.txt

# Run the unattended hardware-session harness into a folder, then exit. One
# artifact per step, and it never stops on a failure — a failing step is data.
# Covers: both versions, --doctor, the ripper's own -j probe (which a rip never
# sends; its -x cache probe is not run, because it goes on to rip the whole disc),
# pre-gap screening, --audit-rips, an ETA sweep, report sizes, a fresh clone of
# the ripper's source, handshake status and preflight. Send the whole folder.
./platterpus-x86_64.AppImage --rig-session ~/rig-session-output

# The cyanrip seam check on its own. `--rig-session` already runs this, so you
# rarely need it directly — it exists because the cyanrip fork's own script calls
# it, and both write into the same MANIFEST.txt so the two projects' evidence is
# one upload rather than two piles. Read-only: nothing rips or re-encodes.
# Inside a test script the same check is the `rig-check` verb.
./platterpus-x86_64.AppImage --rig-check ~/seam-out \
    --rig-check-album "/path/to/Album" --rig-check-device /dev/sr0

# Compare two rips of the SAME disc track-by-track (which tracks are byte-for-
# byte identical, which differ, and which rip is the better master). Points at
# the .platterpus.json report each rip writes beside the FLACs.
./platterpus-x86_64.AppImage --compare "/path/old/Album.platterpus.json" \
                                        "/path/new/Album.platterpus.json"

# Assemble the best of two rips of the same disc into a new folder — copies, per
# track, whichever rip is the better master. Non-destructive: your two source
# folders are never touched.
./platterpus-x86_64.AppImage --assemble-best-of "/path/BestOf/" \
    "/path/old/Album.platterpus.json" "/path/new/Album.platterpus.json"

When to use --compare: re-ripping a disc you already ripped? Compare the new report against the old one. Tracks that come back identical are rock-solid; a track whose result changed (e.g. an exact AccurateRip match last time, offset-variant this time) points to a read-stability problem on that track worth a closer look. The GUI does this automatically after a rip when it finds a prior rip of the same disc in your library, and shows a one-line summary in the results pane.

Path tip for --ctdb-calibrate: a rip folder can contain a look-alike colon (∶, U+2236) where the album title had a : — cyanrip substitutes it so the folder name is filesystem-safe. Don't type a normal : (the path won't be found); let the shell supply the real character — cd into the folder and pass "$PWD", or use tab-completion / a glob (…/Every\ Breath\ You\ Take*).

Keeping cyanrip up to date: the app does it, and you never type a commit. Platterpus checks the fork's published releases a few seconds after launch and again from Tools → Setup & Updates… → Check for cyanrip updates. When the build it finds is one the handshake record in this repository has approved — which includes the common case of your ripper isn't the build this Platterpus was verified against — it offers Install it now, and one click builds and installs it. There is no SHA to copy and nothing to read first, because taking that build is what makes your rips report approved.

The launch-time check is silent unless it has something to offer. It looks at the stable channel by default; tick Offer beta (pre-release) cyanrip builds in Tools → Setup & Updates… to include beta builds.

When the newest published build is one no round here has verified yet, the app tells you, states plainly that every rip made with it would report its ripper as unapproved, and offers it only when it is the build a handshake round is testing, as Install it anyway, which is not the default button.

When to use --install-ripper: to install another build the app knows, use Tools → Setup & Updates… → Choose a build…. --install-ripper <commit> does the same from a terminal (it is the route a rig script calls), and is the only way to install a commit the app does not list: a mid-round test pin, or going back to an older one. It prints the pin it is building and the build tag the finished binary must report, so you can see which ripper you ended up with.

It takes a commit:

# ~/Applications/… if you let the app add itself to your menu (see the note at
# the top of this section); ./platterpus-x86_64.AppImage if you declined.
~/Applications/platterpus-x86_64.AppImage --install-ripper <commit>

Without an argument it builds the pin baked into this Platterpus build. With a commit it builds that commit through the same steps and checks that the binary reports platterpus-fork-g<commit>. It does not predict the version string for a commit Platterpus does not pin, and it tells you up front that rips with a non-pinned build report ripper handshake approval: unapproved.

For a script that wants the channel's newest build rather than a named one, pass latest (the fork's stable channel) or latest-beta (its beta channel) in place of a commit. Platterpus reads the fork's release manifest, prints which commit that is, and installs it exactly as --install-ripper <that commit> would — including the note when no closed round has approved it. It is never the default, and if the manifest cannot be read it installs nothing rather than something else.

If you installed with pipx (Method B), the same flags work on the platterpus command instead — e.g. platterpus --doctor.


Troubleshooting

pip install fails with "does not appear to be a Python project"

Make sure you're in the cloned repository directory (where pyproject.toml lives) and that the clone completed:

ls pyproject.toml    # should exist

Then re-run pip install -e . (or bash dev-setup.sh).

sudo dnf install gh fails on Bazzite

Bazzite is an immutable distro — the host filesystem is read-only and dnf only works inside containers. Two paths:

  • Use SSH instead (recommended for one-time auth setup). See Method C in the install instructions above.
  • Or install gh system-wide via rpm-ostree: rpm-ostree install gh && systemctl reboot. Requires a reboot. After the reboot, gh auth login will work.

pip install fails with "error: externally-managed-environment"

Bazzite, Fedora 38+, Ubuntu 24.04+, and other distros now ship a PEP 668 marker that blocks pip install against the system Python. The fix is to install into a virtual environment, which Method C already does for you:

cd Platterpus
python3 -m venv .venv
source .venv/bin/activate
pip install -e .

If you tried pip install -e . without activating a venv first, no harm done — re-run with the venv active and it'll work.

git clone fails with "Password authentication is not supported"

The repository is public, so a plain git clone https://github.com/rmccann-hub/Platterpus.git needs no authentication. If you only want to run the GUI, you don't need to clone at all — use the AppImage from the Releases page (Method A).

If you plan to push changes, GitHub deprecated HTTPS password auth in 2021, so set up auth first — either an SSH key on your account (clone via git@github.com:…) or gh auth login (web-browser login; stores a token in your git credential helper).

Where is my drive's read offset stored?

cyanrip uses no config file of its own. Platterpus stores your drive's read offset in its own config at ~/.config/platterpus/config.toml and passes it to cyanrip at rip time. Set or change it in the GUI via Tools → Setup & Updates… → Set up drive…. (A ~/.config/whipper/whipper.conf left over from older versions is not read by Platterpus or cyanrip; the uninstaller removes it if present.)

cyanrip: command not found

Your ~/.local/bin isn't on $PATH. Add this to ~/.bashrc or ~/.zshrc:

export PATH="$HOME/.local/bin:$PATH"

Open a new terminal. Verify with which cyanrip.

platterpus: command not found

There's no platterpus command unless you installed via pipx (Method B) or ran dev-setup.sh (Method C). If you run the AppImage, the AppImage is the executable — invoke it directly, e.g. ./platterpus-x86_64.AppImage --doctor. See Command-line usage.

"no drives found" when launching the GUI

The drive list comes from the host's /dev/sr*, so "(no drives found)" means the host shows no optical drive. Check the drive is connected, then press Refresh. Tools → Setup & Updates… → Diagnose drive access… checks the device node and its permissions.

If the drive is listed but a disc cannot be read, check the container. Bazzite, Fedora Silverblue, and most modern distros pass optical drives through automatically. If yours doesn't:

distrobox stop ripping
distrobox enter ripping
# inside the container:
sudo dnf install eudev

(Some minimal container bases don't include udev; this restores device-node passthrough.)

You can also confirm the container can see the drive device node from inside it:

distrobox enter ripping
ls -l /dev/sr*

If the device shows up inside the container but a rip still cannot read it, the export wrapper isn't passing through device access. Re-run Tools → Setup & Updates… → Run setup… (or, inside the container, distrobox-export --bin /usr/local/bin/cyanrip — the fork's install path).

"MusicBrainz error: rate limited"

MusicBrainz throttles unidentified queries. The GUI already sets a User-Agent at launch; if you're still hitting limits, you're sharing an IP with a busy network. Wait a minute and try again.

AppImage won't launch

Most modern Linux distros have FUSE installed and AppImages just work. On Bazzite, no extra steps. If you see "AppImages require FUSE", either install FUSE or extract the AppImage:

./platterpus-x86_64.AppImage --appimage-extract
./squashfs-root/AppRun

The GUI launches but freezes

If a rip stops making progress, the window shows a stall notice. Press Cancel, and Force stop if it does not stop; then eject and try a clean disc. If the window itself stops responding, check the log at ~/.local/share/platterpus/log.txt and open an issue.

The drive-setup wizard says my drive isn't in AccurateRip

If Platterpus doesn't recognise your drive model (so the offset isn't filled in automatically), look your drive up at accuraterip.com/driveoffsets.htm and enter the value by hand in the wizard's manual-entry field. After a rip, the AccurateRip verdict tells you whether the offset was right — matching tracks confirm it; zero matches (on a disc that's in the database) suggest the offset is wrong.

"metaflac: command not found" only when ripping

You exported cyanrip but not metaflac. Re-enter the container:

distrobox enter ripping
distrobox-export --bin /usr/bin/metaflac
exit

Updating

Update Platterpus

  • AppImage: Tools → Setup & Updates… → Check for updates — the app downloads, verifies and installs the new release, then restarts.
  • pipx: pipx upgrade platterpus
  • From source: git pull && pip install -e .

Update cyanrip or metaflac

  • cyanrip: Tools → Setup & Updates… → Check for cyanrip updates (or --install-ripper). This builds the pinned fork; dnf upgrade only updates the stock COPR package, which the fork replaces.
  • flac / metaflac: distrobox enter ripping -- sudo dnf upgrade flac

The host-exported wrappers don't change; they always run whatever is currently inside the container.

Update the container's base Fedora version

distrobox enter ripping
sudo dnf system-upgrade download --refresh --releasever=44   # stay >= 43: the cyanrip COPR builds for Fedora 43-45 + rawhide
sudo dnf system-upgrade reboot   # inside the container only

Uninstalling

Easiest — no terminal: open the app and use Tools → Uninstall Platterpus…, or click the Uninstall Platterpus entry the AppImage adds to your application menu (under System). It removes everything the app installed — shortcuts, the cyanrip/metaflac/flac/cd-paranoia commands (and any leftovers from older versions, such as ~/.local/bin/whipper), the ripping container, optionally the AppImage file itself, and the app's own settings and logs (including the stored read offset) — with a confirmation first and per-item checkboxes. Never touched: your music, and Distrobox/podman themselves (any other containers you have keep working). The same uninstaller can be launched from a terminal with ./platterpus-x86_64.AppImage --uninstall (or platterpus --uninstall on a pipx install).

Script alternative (source checkouts, or if you prefer the terminal): the uninstall.sh script tears everything down in layers, safest-first — it also covers the dev .venv/, which the in-app uninstaller doesn't (a packaged app doesn't know your checkout's location). It never removes your ripped music or a source checkout without an explicit flag.

# Interactive — removes the GUI's venv/config/logs by default, then prompts
# you about the broader stack (Picard, the ripping container,
# the host-exported binaries) one at a time.
bash uninstall.sh

# Preview only — print what would be removed, change nothing.
bash uninstall.sh --dry-run

# Everything except your music files and the cloned repo, no prompts.
bash uninstall.sh --full --yes

bash uninstall.sh --help   # full option list

To remove the host stack fully by hand instead:

distrobox rm ripping            # remove the container
rm -f ~/.local/bin/cyanrip ~/.local/bin/metaflac \
      ~/.local/bin/flac ~/.local/bin/cd-paranoia   # host exports (all four)
rm -f ~/.local/bin/whipper      # leftover from older versions, if present
rm -rf ~/.config/platterpus ~/.local/share/platterpus
rm -rf ~/.config/whipper        # leftover from older versions, if present

Your music at ~/Music/rips/ (or wherever Settings points) is never touched by any of this.

Where things live

Path Contents
~/.local/bin/cyanrip The Distrobox-exported ripper wrapper. Always present. Don't edit.
~/.local/bin/metaflac The Distrobox-exported tag-editor wrapper. Don't edit.
~/.local/bin/whipper Leftover from older versions, if present — no longer used; safe to remove.
~/Applications/platterpus-x86_64.AppImage The app itself, after menu integration moves it out of Downloads.
~/.config/platterpus/config.toml The GUI's own settings (output dir, templates, toggles) and your drive's read offset. The real settings file.
~/.config/whipper/whipper.conf Leftover from older versions, if present — Platterpus no longer reads it (the offset lives in config.toml above); the uninstaller removes it.
~/.local/share/platterpus/log.txt GUI log file. Check here when something goes sideways.
~/Music/rips/ (default) Where rips land, under Artist/Album/. Configurable in Settings.
…/Artist/Album/ The rip itself: the FLAC tracks plus the sidecars — cyanrip's own .log and .cue, Platterpus's <Album>.platterpus.json report, the optional <Album> (EAC-compatible).log, <Album>.platterpus-securing-pass.txt and <log stem>.platterpus-addendum.txt when a re-read ran, and any saved cover.<ext> / back.<ext> / booklet-NN.<ext> artwork.
~/.config/platterpus/drive_profiles.json The per-drive trust ledger (KDD-23): your drive's fingerprint, its read offset and where that value came from, and the measured cache-defeat verdict.
~/.local/bin/ The four host-exported wrappers — cyanrip, metaflac, flac, cd-paranoia — each of which transparently enters the ripping container.

Documentation for contributors

Core project documents (in this directory):

  • CLAUDE.md — project rules and conventions (read before contributing); Project operations section has current build/run/test/uninstall commands
  • PLANNING.md — architecture, directory tree, per-module responsibilities, keyed design decisions (KDD-01 through KDD-44)
  • TASKS.md — active task checklist: dated, ranked lists and handshake-round sections first, then the original P0 (T01-T32, complete), P1.1, P1, P2 and Out of scope.
  • DEPENDENCIES.md — pinned versions, last upstream release dates, replacement plans, retirement-review log

Source documents and reference material (in docs/):

Build / dev tooling:

  • setup-host.sh — one-command full bootstrap (Distrobox + container + cyanrip + export + clone + dev-setup)
  • dev-setup.sh — one-command post-clone setup (venv + pip + editable install + app-menu shortcut)
  • uninstall.sh — tear-down counterpart (use --help for options)
  • build/build_appimage.sh — produce the AppImage locally
  • build/make_icon.py — regenerate the app icon
  • build/python-appimage/README.md — AppImage recipe details
  • CI / releases: .github/workflows/ci.yml runs the tests on every push/PR; .github/workflows/release.yml builds the AppImage and publishes it to a GitHub Release when a vX.Y.Z tag is pushed or the workflow is dispatched with the tag as input — after bumping __version__ and rolling the CHANGELOG.md [Unreleased] section (see CLAUDE.md → CI / release; the build fails if the version and tag disagree). No local build or manual upload.

License

GPL-3.0-only. Chosen to align with the free-software CD-ripping ecosystem this builds on (cyanrip, cdparanoia, CUETools) and to keep the tool and any forks open. cyanrip and other GPL tools are invoked as separate processes (not linked), and PySide6 is used under its LGPL-3 option — so the combined work is cleanly GPL-3.0.

See PLANNING.md KDD-10 for the rationale.

Copyright (C) 2026 rmccann-hub.

Platterpus is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 3 only. It is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE for the full terms.


Last updated for Platterpus v0.7.104.

Metadata

Release files for platterpus 0.7.104

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for platterpus 0.7.104
File Size Uploaded
platterpus-0.7.104.tar.gz 3.9 MB Details

Built distribution (wheel)

Table of built distributions (wheels) for platterpus 0.7.104
File Interpreter ABI Platform
platterpus-0.7.104-py3-none-any.whl Python 3 none any Details

Total release size: 5.8 MB

Release files / platterpus-0.7.104.tar.gz

Download URL platterpus-0.7.104.tar.gz
Size 3.9 MB
Tags Source
SHA-256 checksum
How to use checksums
0da1630dccadedf3f4d959257f865d0a288aaaa2ea185fac4f2c5d57b6cd05fc
BLAKE2b-256 checksum
How to use checksums
c62b9801eac642baf4d094824b4a9acb137ac5ddc88fd9a3ef9f49d84a3e7a43
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 13, 2026.

Transparency log

Release files / platterpus-0.7.104-py3-none-any.whl

Download URL platterpus-0.7.104-py3-none-any.whl
Size 1.8 MB
Tags Python 3
SHA-256 checksum
How to use checksums
1361d7caf1449f054b0a641faf6edbd24a81e58d1a5dd1d18b72479713533f90
BLAKE2b-256 checksum
How to use checksums
324a83a4880b9c68d6fab314ca90477c7802ffc3677d089ca45dfb98b750ba20
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 13, 2026.

Transparency log

Release history Release notifications | RSS feed

This release

0.7.104 This release

2 release files

0.6.65

2 release files

0.6.64

2 release files

0.6.63

2 release files

0.6.62

2 release files

0.6.61

2 release files

0.6.60

2 release files

0.6.59

2 release files

0.6.58

2 release files

0.6.57

2 release files

0.6.56

2 release files

0.6.55

2 release files

0.6.54

2 release files

0.6.53

2 release files

0.6.52

2 release files

0.6.51

2 release files

0.6.50

2 release files

0.6.49

2 release files

0.6.48

2 release files

0.6.47

2 release files

0.6.32

2 release files

0.6.31

2 release files

0.6.30

2 release files

0.6.29

2 release files

0.6.28

2 release files

0.6.26

2 release files

0.6.25

2 release files

0.6.24

2 release files

0.6.23

2 release files

0.6.21

2 release files

0.6.20

2 release files

0.6.19

2 release files

0.6.18

2 release files

0.6.17

2 release files

0.6.16

2 release files

0.6.15

2 release files

0.6.14

2 release files

0.6.13

2 release files

0.6.12

2 release files

0.6.11

2 release files

0.6.10

2 release files

0.6.9

2 release files

0.6.8

2 release files

0.6.6

2 release files

0.6.5

2 release files

0.6.4

2 release files

0.6.3

2 release files

0.6.2

2 release files

0.6.1

2 release files

0.6.0

2 release files

0.5.20

2 release files

0.5.19

2 release files

0.5.18

2 release files

0.5.17

2 release files

0.5.15

2 release files

0.5.14

2 release files

0.5.13

2 release files

0.5.12

2 release files

0.5.11

2 release files

0.5.10

2 release files

0.5.9

2 release files

0.5.8

2 release files

0.5.7

2 release files

0.5.6

2 release files

0.5.5

2 release files

0.5.0

2 release files

0.4.9

2 release files

0.4.8

2 release files

0.4.7

2 release files

0.4.6

2 release files

0.4.5

2 release files

0.4.4

2 release files

0.4.2

2 release files

0.4.1

2 release files

0.4.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page