Skip to main content

cratedrop

Your music library on a USB stick that every Pioneer / AlphaTheta deck reads natively — no Rekordbox, no cloud sync, no laptop at the gig.

tests PyPI

Drop audio files in a folder. cratedrop analyzes them (BPM, beatgrid, key, hot cues, waveforms, artwork) and maintains a USB image carrying both device database formats, so one stick works across every current player generation. Plug it in and play.

~/music ──▶ analyze ──▶ USB image ──▶ flash ──▶ CDJ / XDJ
        (BPM·grid·key·cues·waveforms·art)      (plays natively)

Why

Rekordbox's sync workflows fail DJs constantly: tracks missing from USBs, cloud sync errors, no laptop on hand to fix any of it. cratedrop replaces the whole pipeline with one folder and two commands — the deck can't tell the difference.

Supported hardware

Players Database format Status
XDJ-AZ, OPUS-QUAD, CDJ-3000X, OMNIS-DUO OneLibrary (exportLibrary.db) ✅ verified on XDJ-AZ
CDJ-3000, XDJ-XZ, XDJ-RX3, XDJ-RR, CDJ-2000NXS2 and older legacy export.pdb + ANLZ ✅ verified on XDJ-XZ (full 180+ track library)

Every stick carries both formats. To our knowledge this is the first open-source from-scratch writer for OneLibrary accepted by hardware.

Install

macOS (Apple Silicon or Intel):

brew install ffmpeg
uv tool install "cratedrop[dsp]"   # or: pipx install "cratedrop[dsp]"
cratedrop doctor                   # verify the environment

(the dsp extra is beat/key detection — torch + essentia; omit it on machines that only build/flash images from precomputed analysis)

From source, for development:

git clone https://github.com/maurycyw/cratedrop && cd cratedrop
uv sync --extra dsp && uv run pytest

Quickstart

cratedrop config set staging-dir ~/Music/library     # where your audio lives
cratedrop config set processed-dir ~/Music/cdj-image # the maintained USB image

cratedrop process                  # analyze everything, build the image
cratedrop flash --volume MYUSB     # sync to /Volumes/MYUSB

Then plug the stick into a deck. Subsequent runs are incremental: new tracks analyze once (cached by content hash), and flash copies only what changed — adding 5 tracks to a 10,000-track stick takes seconds.

For a hands-off library, leave the watcher running instead of calling process:

cratedrop watch     # auto-ingests files dropped into the staging dir

Files are only picked up once fully written (safe for slow network copies).

Playlists

Every stick gets an all-tracks playlist, plus (all additive):

  • date-added playlists (10/10/2026 — the day a track entered the library): on by default, cratedrop config set playlists-by-date false to disable
  • your existing playlists: drop .m3u/.m3u8 files (exported from Rekordbox, iTunes, Serato, …) anywhere in the staging dir — entries are matched by path or filename, so playlists exported on another machine still resolve
  • folder playlists: cratedrop config set playlists-from-folders true turns each top-level staging folder into a playlist (for genre/crate-organized libraries)

What a track gets

  • BPM + beatgrid — Beat This! beats/downbeats, fitted to a constant grid or a segmented one for multi-tempo edits; validated against Rekordbox's own analysis (±0.05 BPM, ±20 ms phase on steady tracks); low-confidence results are flagged
  • Key — essentia's EDM-tuned profiles → Camelot, keyfinder-cli fallback
  • Hot cues A–D — first kick, drop, breakdown, outro; snapped to downbeats, labeled and colored
  • Waveforms — all formats decks use (blue, RGB, 3-band), calibrated byte-level against real Rekordbox output
  • Phrase analysis — song-structure bars (intro/verse/chorus/outro) for CDJ-3000-era displays, derived from the cue heuristics
  • Artwork — embedded tag art, extracted and sized for decks; cratedrop enrich fills gaps from Deezer/iTunes
  • Metadata — tags → folder structure (Artist/Album/track) → Artist - Title filenames, in that priority

Switching from Rekordbox? Bring everything

Export your collection once (Rekordbox: File → Export Collection in xml format), then:

cratedrop import-rekordbox ~/Documents/rekordbox.xml   # --with-grids to keep your beatgrids too
cratedrop process

Your hot cues, memory cues, loops and playlists come across as protected user data — they survive re-analysis and every re-flash. Tracks are matched by path, falling back to filename, so an XML exported on another machine still resolves.

The deck writes back — nothing is lost

Decks write to the stick: hot cues, memory cues, loops, play history, settings. flash harvests before it syncs: deck-set cues and loops merge into the library as protected user data (they survive re-analysis and every re-flash; automatic heuristics never displace them), play history archives locally (cratedrop history), and anything unrecognized is snapshotted raw before being touched.

CLI reference

command what it does
config set staging-dir / processed-dir point at your folders
process analyze new/changed tracks, update the USB image
watch [--interval 10] [--settle 15] daemon: auto-process drops
flash --volume NAME [--dry-run] [--prune] [--eject] [--no-harvest] harvest deck data, then incremental sync
harvest --volume NAME import deck-written cues/history without flashing
import-rekordbox XML [--with-grids] one-time migration: cues, loops, grids, playlists from a Rekordbox export
enrich [--dry-run] [--min-score 0.72] [--force] fill missing art/metadata from the web (fills blanks only)
override FILE --bpm X --first-beat-ms X --key 8A pin manual values for a track (survives re-analysis)
verify [--volume NAME] [--deep] pre-gig check: everything present, parseable, consistent
dupes [--threshold 0.8] find near-duplicate recordings by audio fingerprint (needs brew install chromaprint)
settings import <stick-or-dir> ship deck preferences (waveform color mode etc.) from a Rekordbox-exported stick
history play sessions harvested from decks
status staging vs image: what's new
doctor environment check
inspect PATH pretty-print a USB tree, .pdb, or ANLZ file
diff OURS GOLDEN structure-aware diff against a real Rekordbox export

Safety: flash is the only code that touches /Volumes, and it refuses anything that isn't a removable FAT32/exFAT volume that's empty or already a DJ stick. Deletions only ever happen with --prune, and only for files cratedrop itself wrote.

Current limitations

  • Beatgrids are constant or piecewise-constant (segmented); continuously drifting tempo (live drummers) gets a flagged best fit
  • Developed and tested on macOS; the format writers are pure Python and portable, flash's device safety checks are macOS-specific for now
  • Reverse-engineered formats: a Rekordbox/firmware update could change things. Test your stick before a gig. Use at your own risk.
  • The OneLibrary database encryption key is not distributed with cratedrop: it is resolved at first use from public community documentation (one-time network fetch, cached locally) or from the CRATEDROP_ONELIBRARY_KEY environment variable

How it's verified

Every generated file round-trips through independent parsers, and byte-level diffs run against "golden" USB exports made by real Rekordbox (see tests/fixtures/golden/README.md for how to capture your own). Analysis quality is cross-validated against Rekordbox's stored results for the same audio files.

Standing on shoulders

cratedrop is not affiliated with, endorsed by, or supported by AlphaTheta Corporation. Pioneer DJ, rekordbox, CDJ and XDJ are trademarks of their respective owners, used here only to describe compatibility.

License

MIT

Metadata

Release files for cratedrop 0.1.1

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

Source distribution (sdist)

Source distribution for cratedrop 0.1.1
File Size Uploaded
cratedrop-0.1.1.tar.gz 235.2 kB Details

Built distribution (wheel)

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

Total release size: 448.7 kB

Release files / cratedrop-0.1.1.tar.gz

Download URL cratedrop-0.1.1.tar.gz
Size 235.2 kB
Tags Source
SHA-256 checksum
How to use checksums
886f3d3b338a26cdb5c33b8a626bbeb7ba3112dc67630de46095c7425f1455dd
BLAKE2b-256 checksum
How to use checksums
a3687d0c431e62b5a0ba5ef88702dcccc4020cc60ee6eeec729d230800a609fe
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.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 10, 2026.

Transparency log

Release files / cratedrop-0.1.1-py3-none-any.whl

Download URL cratedrop-0.1.1-py3-none-any.whl
Size 213.5 kB
Tags Python 3
SHA-256 checksum
How to use checksums
f1d2d55812f0c1ee2653a4323bf12d0ad7db59cbb756cf8dbb51cd088518c51e
BLAKE2b-256 checksum
How to use checksums
7913c9650178d63f36911d21bd330a487ac5b528f6747a9ee536031fe992fac4
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.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 10, 2026.

Transparency log

Release history Release notifications | RSS feed

This release

0.1.1 This release

2 release files

0.1.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