Advanced FLAC authenticity analyzer - Detects MP3-to-FLAC transcodes with high precision
Project description
🎵 FLAC Detective
Find the fake FLACs in your music library.
Anyone can take an MP3, re-save it as FLAC, and it looks lossless — but the quality is already gone. FLAC Detective reads each file, spots the fingerprints a lossy codec leaves behind, and tells you which files are real and which are fakes.
pip install flac-detective # needs Python 3.10+
flac-detective /path/to/music # scan a file or a whole folder
Every file gets a verdict, like a traffic light:
✅ AUTHENTIC real lossless → keep it
❓ WARNING borderline → give it a listen
⚠️ SUSPICIOUS probably a transcode → likely a fake
❌ FAKE_CERTAIN definitely a fake → replace it
The scan only reads your files — it never changes anything.
🟢 New to all this? → Start Here — the 5-minute beginner's guide No command line, no jargon. From "what is this?" to "I checked my music".
📊 See why a file was flagged
Add --format html and you get a single self-contained page: a triage table sorted
worst-first, plus a spectrum plot for every flagged file. The MP3 "cliff" — a sharp drop
well below the real ceiling — is right there for the eye, with the detected cutoff marked.
Three transcodes at different MP3 bitrates show the wall falling at different frequencies (96 kbps ~11 kHz, 128 kbps ~16 kHz, 160 kbps ~17.5 kHz); the authentic file runs full-range.
🔍 How it works
An MP3 re-saved as FLAC is lossless as a container, but the audio already passed through a lossy codec — and that leaves fingerprints. The clearest is the spectral cliff: MP3 discards everything above a bitrate-dependent frequency, so the spectrum falls off a wall where a real recording keeps going.
FLAC Detective scores each file with 11 heuristic rules built around that idea (cutoff frequency, MP3-bitrate signatures, compression artefacts) plus protection rules so genuine vinyl rips, cassette transfers and naturally quiet recordings aren't flagged. An optional 12th rule — a small CNN — sharpens borderline verdicts. The rules sum to a 0–150 score:
| Verdict | Score | What to do |
|---|---|---|
| ✅ AUTHENTIC | ≤ 30 | keep it |
| ❓ WARNING | 31–54 | borderline — check manually |
| ⚠️ SUSPICIOUS | 55–85 | likely a transcode |
| ❌ FAKE_CERTAIN | ≥ 86 | definitely transcoded |
The guiding principle is "protect authentic files first": a false alarm on real music is worse than missing a borderline fake. Treat AUTHENTIC as "no evidence of transcoding", not a guarantee.
→ Every rule explained: Technical Details.
⚙️ Usage
flac-detective /path/to/music # scan a folder
flac-detective # interactive (prompts for a path)
flac-detective /music --format csv -o triage.csv # spreadsheet, worst-first
flac-detective /music --format html -o report.html # visual report (see above)
flac-detective /music --deep # catch high-bitrate AAC/Opus/Vorbis (slower)
flac-detective /music --advanced # show the plumbing: scores, cutoff, per-rule detail
By default the output is easy mode — a plain-language verdict and a recommended action
per file ("Almost certainly a fake — the sound stops dead at ~16 kHz, the wall of a
128 kbps MP3. → Replace it."). Add --advanced for the scores, cutoff frequencies and
per-rule reasoning. The desktop GUI has the same Advanced toggle.
Analyses FLAC, WAV, ALAC (.m4a) and APE (.ape) — codec-agnostic, and a lossy .m4a
is correctly rejected (the real codec is probed, never trusted by extension).
→ Full guide & every flag: User Guide.
🖥️ Prefer a window to a command line?
pip install "flac-detective[gui]"
flac-detective-gui
A desktop app (PySide6): choose a folder or drag it in, watch the progress bar, then triage a sortable, colour-coded verdict table — click any file to see its spectrum with the detected cutoff marked and the reasons for its verdict. Export to HTML/CSV/JSON.
🎚️ It also catches fake hi-res
Beyond lossy-as-lossless, FLAC Detective flags files sold as high-resolution that
aren't: 44.1/48 kHz upsampled to 96/192 kHz (a hard spectral cliff with digital
silence above it), and 16-bit audio padded into a 24-bit container. This is a
separate axis from the transcode verdict — reported as hires_verdict
(GENUINE_HIRES / UPSAMPLED / PADDED_DEPTH / …) in the CSV report, the GUI and the
Python API. A genuine 96 kHz recording that simply rolls off early reads GENUINE_HIRES,
not a false alarm.
Install options & upgrading
pip install flac-detective # base
pip install "flac-detective[ml]" # + optional CNN (Rule 12)
pip install "flac-detective[gui]" # + desktop GUI (flac-detective-gui)
docker pull ghcr.io/guillain-rdcde/flac_detective:latest # or Docker (amd64 + arm64)
pip install does not upgrade an existing install — use -U to get the latest release:
pip install -U flac-detective
flac-detective --version
Use it from Python or beets
Python API:
from flac_detective import FLACAnalyzer
result = FLACAnalyzer().analyze_file("song.flac")
print(result["verdict"]) # AUTHENTIC, WARNING, SUSPICIOUS, or FAKE_CERTAIN
beets plugin — triage transcodes without leaving your workflow:
pip install "flac-detective[beets]"
# in config.yaml: plugins: flacdetective
beet flacdetective # analyse & tag the whole library
beet ls flacdetective_verdict:FAKE_CERTAIN # list the certain fakes
Stores flacdetective_verdict and flacdetective_score on each item; an optional
auto: yes analyses files as they're imported.
🤖 The ML side: a case study worth reading
Rule 12's model went through a real R&D saga, written up as a learning resource: a false-positive audit over 11 234 real FLACs, four instructive dead-ends, a debunked "AUC 0.99" caught by cross-validation, and a twist where a "fundamental limit" turned out to be an artifact of listening in mono — fixed by going stereo. Real-world specificity on 11 234 authentic FLACs climbed from 80 % to 95 %.
📖 Read the ML detective story →
📚 More
- 📖 Full documentation site — getting started, user guide, technical details, API
- 🚀 Getting Started — install, first analysis, accuracy & file-safety notes
- 📋 Changelog · 🤝 Contributing · 🔒 Security
- 💬 Issues · Discussions
Licensed under the MIT License.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file flac_detective-1.7.0.tar.gz.
File metadata
- Download URL: flac_detective-1.7.0.tar.gz
- Upload date:
- Size: 15.5 MB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
f9df0a5d1aade8c03d4b04a0cc18a46be96dd942cf97c82b7b25f73ae68c11df
|
|
| MD5 |
9ab2fed98933313e71ea6b003052c765
|
|
| BLAKE2b-256 |
b4d190e154d05d558e99776a5e0beb44762bcbb74359f8dc9d614973678a0266
|
Provenance
The following attestation bundles were made for flac_detective-1.7.0.tar.gz:
Publisher:
release.yml on Guillain-RDCDE/FLAC_Detective
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
flac_detective-1.7.0.tar.gz -
Subject digest:
f9df0a5d1aade8c03d4b04a0cc18a46be96dd942cf97c82b7b25f73ae68c11df - Sigstore transparency entry: 1978506245
- Sigstore integration time:
-
Permalink:
Guillain-RDCDE/FLAC_Detective@4f4e2c6b024432454d54fc14ec9db0d4738c53ce -
Branch / Tag:
refs/tags/v1.7.0 - Owner: https://github.com/Guillain-RDCDE
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@4f4e2c6b024432454d54fc14ec9db0d4738c53ce -
Trigger Event:
push
-
Statement type:
File details
Details for the file flac_detective-1.7.0-py3-none-any.whl.
File metadata
- Download URL: flac_detective-1.7.0-py3-none-any.whl
- Upload date:
- Size: 15.5 MB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
f0dcb2e24d392f7692aa40315133c77ae9803ab08faa983fd6515dd674b7a7eb
|
|
| MD5 |
7043783af9cf817e53c3ff779dacf48d
|
|
| BLAKE2b-256 |
5466e1ea2d7213d0cd1c01ae321ae7d475e0e6bd4d5f694502c6c20cf43f0cb7
|
Provenance
The following attestation bundles were made for flac_detective-1.7.0-py3-none-any.whl:
Publisher:
release.yml on Guillain-RDCDE/FLAC_Detective
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
flac_detective-1.7.0-py3-none-any.whl -
Subject digest:
f0dcb2e24d392f7692aa40315133c77ae9803ab08faa983fd6515dd674b7a7eb - Sigstore transparency entry: 1978506460
- Sigstore integration time:
-
Permalink:
Guillain-RDCDE/FLAC_Detective@4f4e2c6b024432454d54fc14ec9db0d4738c53ce -
Branch / Tag:
refs/tags/v1.7.0 - Owner: https://github.com/Guillain-RDCDE
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@4f4e2c6b024432454d54fc14ec9db0d4738c53ce -
Trigger Event:
push
-
Statement type: