A Python toolkit for digitizing vinyl records and managing your music collection with automatic metadata tagging from Discogs.
discogstool2 helps you process audio recordings from vinyl records and automatically tag them with accurate metadata from the Discogs database. It can split multi-track WAV files, normalize audio levels, convert between formats, and organize your collection.
- Automatic Metadata Tagging: Fetches release and track information from Discogs API
- Multi-track WAV Splitting: Automatically splits single WAV files into individual tracks using regions
- Audio Processing: EBU R128 loudness normalization (immune to vinyl pops) and converts to AIFF format
- Collection Management: Compare your local files against your Discogs collection
- Cover Art: Automatically downloads and embeds album artwork
- Format Support: Handles WAV, FLAC, MP3, M4A, AAC, and AIFF files
- Local Caching: SQLite database caches Discogs API responses to minimize API calls
- Firefox Extension: One-click label printing from any Discogs release page
You need the following command-line tools installed:
- ffmpeg: Audio conversion and normalization (
brew install ffmpegon macOS,apt install ffmpegon Ubuntu) - flac: FLAC decoding (
brew install flacon macOS,apt install flacon Ubuntu) - normalize-audio or normalize: (Optional) Only needed if using
--legacy-normalizeflag (brew install normalizeon macOS,apt install normalize-audioon Ubuntu)
pip install -r requirements.txtRequired packages:
- mutagen (audio metadata handling)
- tqdm (progress bars)
- python3-discogs-client (Discogs API integration)
- numpy (audio data processing)
- urllib3 (HTTP requests)
You need a Discogs account. On first run, the tool will:
- Display an authorization URL
- Ask you to visit the URL and authorize the application
- Prompt you to enter the verification code
- Store your credentials in
~/.discogstool/discogs_auth
- Clone this repository
- Install system dependencies (ffmpeg, normalize, flac)
- Install Python dependencies:
pip install -r requirements.txt - Make the scripts executable:
chmod +x dt_process dt_collection
Important: This tool does NOT record audio from your turntable. It's a post-processing tool that works with audio files you've already captured using Reaper.
- Connect your turntable to your computer via audio interface/USB
- Create a new Reaper project and set up your audio input
- Record the entire side of the vinyl as a single take
- Stop recording when the side finishes
Important: Use Regions, not just markers. Regions define both the start AND end of each track, allowing for precise boundaries even when there's silence between tracks.
- Select the audio range for the first track by clicking and dragging
- Press Shift+R (or right-click → Create Region from Selection)
- Repeat for each track on the recording
- Region names are optional - the tool only uses the boundaries
If you only place markers at track starts (without defining regions), the tool will assume each track runs until the next marker. This causes problems when there's silence between tracks:
- Without regions: A 4-minute track followed by 1 minute of silence would be exported as 5 minutes
- With regions: The track is cut precisely at the region boundary you defined
- File → Render (or Ctrl+Alt+R)
- Set Output Format to WAV
- Name the file:
[r{RELEASE_ID}].wav- Example:
[r12345678].wav - Find the release ID from the Discogs URL:
https://www.discogs.com/release/12345678-...
- Example:
- Under "Embed metadata" or "Include", ensure these are enabled:
- "Write markers + regions" - Critical for track splitting
- Click Render
The regions are stored in the WAV file's smpl chunk as loop points, which dt_process reads to determine track boundaries.
Now use this tool to split, normalize, tag, and organize:
./dt_process -o ~/Music/Processed '[r12345678].wav'The tool will:
- Split the WAV using your regions
- Fetch metadata from Discogs
- Normalize audio levels
- Convert to AIFF format
- Embed cover art
- Tag with all metadata (artist, title, year, label, etc.)
- Rename files appropriately
Instead of using regions, you can export each track separately:
- Select the audio for each track individually
- Export each as:
{RELEASE_ID}{POSITION}.wav- Examples:
12345678A1.wav,12345678A2.wav,12345678B1.wav
- Examples:
- No regions needed with this method
Convert and tag audio files with Discogs metadata.
Files must follow specific naming patterns to identify the Discogs release and track position:
For individual tracks:
{RELEASE_ID}{POSITION}.{EXTENSION}
Examples:
12345678A1.wav- Release 12345678, track A112345678B.flac- Release 12345678, track B12345678A2.mp3- Release 12345678, track A2
For multi-track WAV files (to be split):
[r{RELEASE_ID}].wav
Example:
[r12345678].wav- Will be split into individual tracks based on cue markers
./dt_process -o /path/to/output/directory file1.wav file2.flac [r12345].wav-o, --outdir(required): Output directory for processed files-v, --verbose: Enable debug messages-j, --jobs N: Number of parallel normalization jobs (default: CPU count)--legacy-normalize: Use legacy peak normalization instead of EBU R128 (see Normalization below)
Process a single track:
./dt_process -o ~/Music/Processed 12345678A1.wavProcess multiple files:
./dt_process -o ~/Music/Processed 12345678A1.wav 12345678A2.wav 12345678B1.flacSplit and process a multi-track WAV file:
./dt_process -o ~/Music/Processed '[r12345678].wav'-
For WAV files with regions (named
[rXXXX].wav):- Reads regions from the
smplchunk (Reaper exports regions as loop points) - Falls back to consecutive cue marker positions if no regions found
- Splits into individual tracks (minimum 30 seconds, or 6 seconds for releases with many short tracks)
- Creates temporary files named
{RELEASE_ID}.{POSITION}.wav
- Reads regions from the
-
For all audio files:
- Fetches metadata from Discogs (artist, album, track title, year, genre, label, etc.)
- For WAV/FLAC: Normalizes audio using EBU R128 loudnorm, converts to 44.1kHz/16-bit AIFF
- For MP3: Copies and tags without re-encoding
- Embeds cover artwork
- Renames files to:
{ARTIST} - {TITLE} {TRACK_NUM} [{LABEL}].{ext}
By default, dt_process uses EBU R128 loudness normalization (via ffmpeg's loudnorm filter), which is ideal for vinyl digitization:
- Target: -14 LUFS integrated loudness (standard for electronic/DJ music)
- True Peak Limit: -1 dBTP (prevents digital clipping)
- Two-pass processing: Analyzes first, then applies precise normalization
- Linear mode: No dynamic compression, only gain adjustment + peak limiting
Why this matters for vinyl: Traditional peak normalization can be fooled by vinyl pops/clicks. A single loud pop becomes the "peak", preventing the actual music from being normalized properly. EBU R128 measures integrated loudness over time, so short transients (pops) don't affect the calculation. The true peak limiter catches any pops that would clip, while the music passes through with only gain adjustment.
Legacy mode: Use --legacy-normalize to use the old peak-based normalization (requires normalize-audio/normalize utility). This normalizes to -1.5dB peak, which may result in quieter tracks if vinyl pops are present.
Analyze your music collection and compare it against your Discogs collection.
./dt_collection /path/to/music/directory-c, --collection FILE: CSV file exported from your Discogs collection-u, --update-metadata: Refresh metadata/images from Discogs for all found files-n, --dry-run: Show what would be done without making changes-v, --verbose: Output diagnostic messages-Y, --min-year YEAR: Ignore releases older than specified year
Report options (requires -c):
-a, --all-reports: Generate all reports-M, --missing: Report tracks found locally but not in Discogs collection-D, --discogs-missing: Report releases in Discogs collection not found locally-P, --partially-recorded: Report releases that are only partially recorded
Scan a directory and update metadata:
./dt_collection -u ~/Music/VinylCompare local files to Discogs collection:
./dt_collection -c ~/Downloads/collection.csv ~/Music/VinylGenerate all reports:
./dt_collection -c ~/Downloads/collection.csv -a ~/Music/VinylFind what you haven't recorded yet:
./dt_collection -c ~/Downloads/collection.csv -D ~/Music/VinylDry run to see what would be updated:
./dt_collection -n -u ~/Music/Vinyl- Go to https://www.discogs.com/settings/exports
- Request a new export
- Download the CSV file when ready
- Use this file with the
-coption
Audio files are tagged with metadata stored in the comment field:
{LABEL} [{CATALOG_NUMBER}] Discogs: {RELEASE_ID}
This allows the tool to:
- Identify which Discogs release a file belongs to
- Refresh metadata when the release data changes
- Verify track counts match the release
The tool creates a directory at ~/.discogstool/ containing:
discogs_auth: OAuth tokens for Discogs APIdiscogs.db: SQLite database caching API responses (7-day default cache)- Cover art images (hashed by URI)
The tool handles various track position formats:
- Standard: A1, A2, B1, B2
- Without numbers: A, B (treated as A1, B1)
- Double-sided: AA1, AA2 (for side B on some pressings)
- Alternative formats: 1B instead of B1
- With periods: A1., B2.
- Regions: Multi-track WAV splitting requires regions exported from Reaper (stored in the
smplchunk) - API Rate Limiting: Discogs API has rate limits (the tool includes delays to handle this)
- File Format: Only processes files in supported formats (WAV, FLAC, MP3, M4A, AAC, AIFF)
"missing normalize utility"
- This only occurs when using
--legacy-normalize - Install normalize-audio (Ubuntu) or normalize (macOS)
- Or remove the
--legacy-normalizeflag to use the default EBU R128 normalization (recommended)
"Release XXXXX not found"
- Verify the release ID exists on Discogs
- Check your internet connection
- The release may have been deleted or merged on Discogs
"Unexpected region count"
- The number of detected regions doesn't match the track count on Discogs
- Ensure you created regions (Shift+R), not just markers
- Check that the Discogs tracklist is accurate
- Run with
-vto see which regions are being detected and their durations
Tracks include unwanted silence at the end
- You're using markers instead of regions - the tool is using the next marker as the track end
- In Reaper: use regions (Shift+R) to define precise start and end points for each track
- Make sure "Write markers + regions" is enabled when rendering
"Couldn't find position X in release Y"
- The track position in your filename doesn't exist in the Discogs release
- Check the tracklist on Discogs and verify your position labels
Rate limiting errors
- The tool includes automatic retry logic and delays
- If persistent, wait a few minutes and try again
A browser extension lets you print a dt_label sleeve label directly from any Discogs release page — no terminal required.
1. Create and activate the virtual environment
python3 -m venv .venv
.venv/bin/pip install -r requirements.txt2. Start dt_server
Run manually to monitor output:
.venv/bin/python3 dt_serverOr install as a login item so it starts automatically:
./install_server.shThis generates a launchd plist with the correct paths for your machine,
installs it to ~/Library/LaunchAgents/, and starts the server immediately.
Logs are written to ~/Library/Logs/discogstool/server.log.
To stop and remove:
./install_server.sh --unloadTo restart the server without reinstalling (e.g. after a code change):
launchctl kickstart -k gui/$(id -u)/com.discogstool.serverThe -k flag kills any running instance first, so this doubles as a restart command.
3. Load the extension in Firefox
- Navigate to
about:debugging - Click This Firefox → Load Temporary Add-on
- Select
firefox-ext/manifest.json
Temporary vs. permanent: the about:debugging method is temporary — the extension disappears when Firefox restarts. For a permanent installation, sign it as unlisted on AMO using the provided script.
4. Permanent Installation (signed .xpi)
Requires npm (for web-ext). On the first run the script prompts for AMO API credentials and saves them to ~/.discogstool/amo_auth; subsequent runs reuse them automatically.
-
Create free AMO API credentials at:
https://addons.mozilla.org/en-US/developers/addon/api/key/ -
Run the signing script:
./sign_extension.sh
The script signs the extension, saves the
.xpitoweb-ext-artifacts/, and opens it in Firefox. -
Click Add when Firefox prompts.
-
Commit the stable copy so others can install without re-signing:
git add discogs-label-printer.xpi git commit -m "Update signed extension"On another machine: drag
discogs-label-printer.xpiinto Firefox, or run:open -a Firefox.app discogs-label-printer.xpi
Updating the extension after code changes
- Bump
"version"infirefox-ext/manifest.json - Re-run
./sign_extension.sh - Click Add in Firefox — the updated version replaces the old one
- Browse to any Discogs release page (e.g.
discogs.com/release/12345678-...) - The label icon activates in the Firefox toolbar
- Click it to open the print popup
- Choose a label profile, optionally toggle Preview only, and click Print Label
Preview mode renders the label as a PNG and opens it in a new tab. Print mode sends directly to the configured thermal printer.
The server port (default 5679) is configurable in the popup footer and is saved between sessions.
If you modify firefox-ext/make_icons.py:
.venv/bin/python3 firefox-ext/make_icons.pyThe test suite uses pytest. Install it alongside the project dependencies if you haven't already:
pip install pytest
pip install -r requirements.txtThen run the full suite from the project root:
python3 -m pytest tests/Run a single test file:
python3 -m pytest tests/test_wavfile.pyRun with verbose output to see individual test names:
python3 -m pytest tests/ -vStop on the first failure:
python3 -m pytest tests/ -xThe suite covers all modules (util, database, libtags, client_interface, wavfile, beatport) and all top-level scripts (dt_find, dt_label, dt_process, dt_server). Scripts without a .py extension are loaded as modules using importlib.machinery.SourceFileLoader. Network calls and filesystem side-effects are isolated with unittest.mock so no Discogs credentials or local files are needed to run the tests.
See LICENSE file for details.