Documentation
Everything you need to get OpenDJ running and making the most of your library.
Installation
macOS (recommended)
Requires Apple Silicon (an M-series Mac, 2020 or later) — there's no Intel build. Stem separation depends on ONNX Runtime, which doesn't ship a prebuilt binary for Intel Macs, so an Intel-compatible build isn't currently possible without dropping that feature entirely. Running the .dmg on an Intel Mac will fail to launch; there's no workaround short of Apple Silicon hardware.
OpenDJ isn't Apple-notarized yet (that requires a paid Developer account), so a plain browser download of the .dmg gets flagged by Gatekeeper as “damaged” on first launch — misleading, since nothing is actually corrupt. The install script sidesteps this entirely by fetching and installing the app directly, outside the browser download path that triggers the flag in the first place:
No dialog, no extra steps. yt-dlp and ffmpeg ship inside the app either way — nothing else to install.
Prefer downloading by hand? Grab the .dmg from the download page and drag OpenDJ to Applications instead — but that path will trigger the Gatekeeper dialog. Clear it with:
Then open OpenDJ normally. You only need to do this once per download.
From source
If you want to build from source, you'll need Rust, Node.js, and pnpm — plus yt-dlp and ffmpeg on your own PATH, since the bundling step only runs in release CI, not a local cargo tauri dev:
$ git clone https://github.com/illyangz/open-dj.git
$ cd open-dj
$ pnpm install
$ cargo tauri dev
Quick Start
- Open OpenDJ
- Choose a download folder in Settings (or use the default)
- Paste a link into the Queue tab — any URL from YouTube, SoundCloud, etc.
- Tracks download automatically, convert to 320kbps MP3, and organize into your folder structure
System Requirements
| Component | Requirement |
|---|---|
| OS | macOS 12+ (Monterey or later) |
| RAM | 4 GB minimum, 8 GB recommended |
| Disk | ~300 MB for app (yt-dlp and ffmpeg included) + space for your library |
| Dependencies | None — yt-dlp and ffmpeg are bundled |
Downloading Tracks
OpenDJ accepts input in three ways:
- Paste — Paste a URL directly into the Queue tab (Cmd+V)
- Drop — Drag and drop a URL or local audio file anywhere in the window
- Batch — Paste multiple URLs, one per line. Playlists are automatically expanded.
Each track goes through the pipeline:
- Resolve — Metadata is fetched from the source (title, artist, artwork, BPM, key)
- Download — Audio is downloaded at the highest available quality
- Convert — ffmpeg converts to MP3 320kbps if needed
- Tag — ID3 tags are written (title, artist, album, artwork, genre, etc.)
- Organize — File is moved to the destination folder based on your template
Supported Sources
OpenDJ uses yt-dlp under the hood, which supports 1800+ sites. The most common for DJs:
| Source | Audio Quality | Notes |
|---|---|---|
| YouTube | Up to 320kbps | Best audio format selected automatically |
| SoundCloud | Up to 320kbps | Direct API download, no yt-dlp needed |
| Beatport | 320kbps MP3 | Full metadata including BPM & key |
| Bandcamp | Up to FLAC/320 | Downloads the highest quality available |
| Spotify | Metadata only | DRM-protected — falls back to YouTube search |
| Apple Music | Metadata only | DRM-protected — falls back to YouTube search |
DRM notice: Spotify, Apple Music, and Deezer tracks are DRM-protected and cannot be downloaded directly. OpenDJ will search YouTube for a matching track when possible. Always respect copyright.
SoundCloud Likes
The SoundCloud tab lets you fetch and download any SoundCloud user's liked tracks:
- Enter a SoundCloud username (or paste their profile URL)
- Click Fetch Likes — OpenDJ fetches their entire likes library via the SoundCloud API
- Browse the results, search by title or artist
- Click MP3 on individual tracks, or Download All MP3 for the whole list
No API key is required. OpenDJ auto-detects SoundCloud's client ID from their website — the same approach used by browser extensions and scripts.
Auto-Organization
OpenDJ organizes downloaded tracks using a configurable folder template. The default is:
Available template variables:
| Variable | Description |
|---|---|
{artist} | Track artist (or uploader if no artist tag) |
{album} | Album name (if available) |
{title} | Track title |
{genre} | Genre tag |
{bpm} | BPM (if detected) |
{key} | Musical key (if detected) |
{year} | Release year |
Batch Tagging
Select multiple tracks in the Queue and edit their tags simultaneously. Useful for:
- Fixing artist capitalization across a set
- Adding a genre to a batch of tracks
- Normalizing title formatting
Repair & Restore
Every file mutation OpenDJ makes is journaled with a checksum. The Repair tab shows:
- All modifications made to your library
- Original file backups (stored alongside or in a backup directory)
- One-click restore to revert any change
Your files are safe. OpenDJ never deletes originals without creating a backup first. The journal is your audit trail.
Colored Waveform & Hot Cues
Click a track's title (or the expand icon) in Library to open its enlarged waveform. Three color modes are available, switchable from the same view:
- RGB — low, mid, and high frequencies blended into one continuous color
- 3-Band — low/mid/high rendered as distinct solid bands
- Classic Blue — a single-color amplitude waveform, no frequency coloring
Click anywhere on the waveform to set the cue cursor — the track does not need to be playing. Press 1–8 to drop or jump to a hot cue at that position.
Stem Separation
From the same enlarged waveform view, Download Stems runs real source separation — not an EQ filter — splitting a track into isolated vocals, drums, bass, and other. Check the boxes for whichever stems you want to keep.
Separation runs fully on-device (CPU) via an ONNX/htdemucs model. The first split on a machine downloads the model (roughly 200MB, one time); every split after that starts immediately. A full track typically takes anywhere from several seconds to a couple of minutes depending on your machine.
All four stems are always computed. The separation model produces vocals/drums/bass/other together in one pass — unchecking a stem only skips saving that file, it doesn't speed up the split.
Cloud Sync
Turn on Settings → Sync to sync BPM, key, hot cues, and preferences across your devices. There's no account: the first time you enable it, OpenDJ generates a random recovery key on your device and registers it anonymously.
- To use the same identity on another device, copy your recovery key from Settings and paste it into "Use on this device" there
- The recovery key is a secret, not a password — anyone with it can use your identity, and there's no way to recover it if lost
- Sync is off by default and never required to use OpenDJ
Community
The Community tab is a lightweight, anonymous feed layered on the same recovery-key identity as Sync. Setting a username (from the Community tab or the sidebar) is required to post, upvote, or comment — not to read.
- Share a Crate — posts your crate's track list (title/artist/key/BPM, plus a source link wherever OpenDJ can resolve one from your download history) as a metadata snapshot, never the audio itself
- Share a Song — paste any link with a title and optional artist
- Post — plain text, no track attached
- Upvote, reply in flat (non-threaded) comments, and @mention other usernames — typing
@suggests real usernames as you type - A + button on song/crate shares downloads the song, or creates a local crate matched against tracks you already have
Settings Reference
| Setting | Default | Description |
|---|---|---|
| Download folder | App data folder | Where downloaded tracks are saved |
| Folder template | {artist}/{album}/{title} | Organizational structure for downloaded tracks |
| Network concurrency | 6 | How many tracks download simultaneously (1–16) |
| File mutation concurrency | 1 | How many file renames/moves happen in parallel |
| Analytics | Off | Anonymous usage stats (never includes file paths or audio) |
Concurrency
OpenDJ downloads tracks in parallel. The default concurrency is 6, which means 6 tracks download at the same time.
- 1–2 — Conservative, good for slow connections
- 4–6 — Balanced, works well on most connections
- 8–16 — Aggressive, use on fast connections with high bandwidth
You can adjust this in Settings → Concurrency → Simultaneous network jobs.
Folder Templates
Templates use {variable} syntax. Slashes create subdirectories. Unknown variables are skipped.
Examples:
{genre}/{artist} - {title} → House/DJ Name - Some Track.mp3
{bpm}bpm/{artist}/{title} → 128bpm/Artist/Track.mp3
CLI Usage
OpenDJ is a GUI application, but you can use yt-dlp directly from the command line for scripting:
$ yt-dlp --flat-playlist --dump-json "PLAYLIST_URL" | jq '.title'
Troubleshooting
"yt-dlp not found" or "ffmpeg not found"
Both ship inside official OpenDJ downloads, so this shouldn't happen — if it does, your install is likely corrupted; redownload from the download page. Running from source instead? Install both yourself: brew install yt-dlp ffmpeg, and confirm they're on your PATH.
Downloads are slow
Check your network concurrency setting. Default is 6 simultaneous downloads. Increase to 8–16 on fast connections.
Spotify/Apple Music tracks not downloading
These services use DRM protection. OpenDJ searches YouTube for a matching track instead. The match quality varies.
SoundCloud client_id not detected
SoundCloud periodically rotates their JavaScript assets. If detection fails, restart OpenDJ to re-fetch the latest scripts.
macOS says OpenDJ "is damaged and can't be opened"
This is Gatekeeper, not an actually corrupt download — OpenDJ isn't Apple-notarized yet, so a fresh browser download gets quarantined and macOS shows this (misleading) message instead of the usual "unidentified developer" prompt. Two ways to fix it:
Avoid it next time: use the install script instead of the browser download — it clears the quarantine flag as part of installing, so the dialog never shows.
Already hit it? Fix it once per download from Terminal, after dragging OpenDJ.app to Applications:
Then launch it normally from Applications or Spotlight.
Downloads fail with "Failed to load Python shared library" / "different Team IDs"
Fixed in v0.3.12. Earlier builds enabled macOS Hardened Runtime on the whole app bundle, which blocked the bundled yt-dlp binary from loading its own embedded Python runtime (a code-signing Team ID mismatch between yt-dlp and its bundled framework). Update to the latest version to fix it — no other workaround needed.
Can't find what you need? Open an issue on GitHub.