DJSync logo

DJSync

Find music, put it on your Rekordbox USB drive, ready for Pioneer CDJs — without going through Rekordbox.
One file on your USB drive, any computer: Windows, macOS, Linux.

Version Python License Platform

--- ## What DJSync does DJSync is a **portable** desktop app — it runs straight from the USB drive, on any Windows, macOS or Linux computer, nothing to install — that works on a drive exported by Rekordbox: - **Search and download** from YouTube Music (results as you type, preview before downloading), or **import a link** from Spotify, YouTube or SoundCloud (single track or playlist). - **Write directly into the drive's library**: `exportLibrary.db` (OneLibrary, recent players) **and** `export.pdb` (older players), with date added and artwork. - **Analyse tracks** without Rekordbox: BPM, beat grid, key (shown in Camelot notation), Pioneer waveforms (ANLZ files), in the background (Library ▸ *Not analysed*). Tracks already analysed by Rekordbox are never changed. - **Manage the library** like a mini Rekordbox: playlists and folders, drag and drop, track order, harmonic filter, built-in player with waveform. - **Fix** a shifted beat grid (also straight from the player), **find and merge duplicates**, edit title / artist. - **Update the Rekordbox collection of this computer** too (Rekordbox 6/7, `master.db`): same features as for a USB drive — download into the collection, playlists and folders, analysis, beat grid, title/artist, duplicates. DJSync only writes while Rekordbox is closed. - **Copy playlists between libraries** (USB drive ↔ this computer, drive ↔ drive) with their analysis, **complete missing metadata** of existing tracks, add a **memory cue on the first downbeat**. - **Backups and one-click restore**: the drive's original library (before DJSync) is kept forever, plus manual backups and yearly / monthly / weekly / recent ones (`DJSync_Backups/` on the drive). DJSync can also **remove itself from the drive** (Settings ▸ Drive backups). - **Eject** the drive safely from DJSync. English interface (French available in Settings; other languages can be added — see below), 20 colour themes, zoom from 80 to 200 %. Fast Qt interface (PySide6), no animations. > ⚠️ Personal project, not affiliated with Pioneer DJ / AlphaTheta. The drive formats are reverse-engineered: > **keep a copy of your drive** and close Rekordbox while DJSync writes to it. ## Videos | Full tour — every menu (3 min, 1080p) | Short — the main workflow (1 min 30, vertical) | |---|---| | [![DJSync video tour](docs/videos/djsync-tour.jpg)](https://github.com/user-attachments/assets/202ed7d1-8311-40cf-93b4-9a8f64c88e1d) | [![DJSync short video](docs/videos/djsync-short.jpg)](https://github.com/user-attachments/assets/7ceb08e1-6a5e-4979-b6a6-39328b6b4e94) | Click a picture to play the video. Demo library with made-up artists; regenerate them with `python tools/tour_video.py tour.mp4` and `python tools/teaser_video.py short.mp4`. ## Screenshots | Library | Beat grid editor | |---|---| | ![Library](docs/captures/library.png) | ![Grid](docs/captures/grid.png) | ## Download | Your computer | Download | |---|---| | **Windows** 10 / 11 | ⬇ [**DJSync.exe**](https://github.com/Pikkol0/djsync/releases/latest/download/DJSync.exe) — one file | | **macOS** 11+ (Apple silicon) — *beta* | ⬇ [**DJSync-macOS.dmg**](https://github.com/Pikkol0/djsync/releases/latest/download/DJSync-macOS.dmg) — drag DJSync onto your drive | | **Linux** x86-64 — *beta* | ⬇ [**DJSync-Linux-x86_64.tar.gz**](https://github.com/Pikkol0/djsync/releases/latest/download/DJSync-Linux-x86_64.tar.gz) — DJSync folder | Put it on your USB drive and open it: nothing to install on the computer, FFmpeg and the JavaScript runtime needed for YouTube are included, settings stay on the drive. DJSync tells you when a new version is out. > **How light is it?** Rekordbox needs **2 GB** free on your computer to install. DJSync fits **on your > USB drive in ~250 MB** (~300 MB with its backups) — less than 25 tracks in MP3 320 — and runs on any > computer you plug the drive into. Step by step: **[quick installation guide](docs/INSTALL.md)** ([français](docs/INSTALL.fr.md)) · pre-releases and older versions: [all releases](https://github.com/Pikkol0/djsync/releases). ## Help test DJSync (beta) Testers wanted — especially **with real players** (CDJ / XDJ, not a controller). Download the latest [pre-release](https://github.com/Pikkol0/djsync/releases), follow the **[tester guide](docs/TESTING.md)** ([français](docs/TESTING.fr.md)) and send a [test report](https://github.com/Pikkol0/djsync/issues/new?template=deck_test.yml) or a [bug report](https://github.com/Pikkol0/djsync/issues/new?template=bug.yml) with the log file. ## Run from source ### Requirements - **Python 3.10+** (developed and tested with 3.12) - **FFmpeg** (`ffmpeg`): download, m4a playback, analysis. In the `PATH`, or the folder set in *Settings ▸ FFmpeg*. - A **JavaScript runtime** for YouTube downloads (yt-dlp): Deno, Node.js or [QuickJS-NG](https://github.com/quickjs-ng/quickjs) (`qjs`, 2.5 MB — the one shipped with the builds). ### Steps ```bash git clone https://github.com/Pikkol0/djsync.git cd djsync python -m venv .venv .venv\Scripts\activate # Windows (Linux/macOS: source .venv/bin/activate) pip install -r requirements.txt python app.py ``` ### Building the executables The **Build** GitHub workflow (`.github/workflows/windows.yml`, run it from the *Actions* tab or by pushing a `v*` tag) builds Windows, macOS and Linux. **macOS**: `DJSync.app` (Apple silicon), ad-hoc signed, in a `.dmg` (dmgbuild: background telling to drag it onto the USB drive). Not signed by Apple: the first launch needs *Open Anyway* once; DJSync then lifts the quarantine of its copy on the drive and relaunches from it (`portable.leave_translocation`). **Linux**: the `DJSync` folder (built on Ubuntu 22.04 for an old glibc), tar.gz. Both ship an audio-only FFmpeg (`TARGET=native packaging/build_ffmpeg.sh`) and QuickJS, and are self-tested. **Windows**: a **single `DJSync.exe`**: a 150 KB launcher (`packaging/launcher`, C + miniz) with the application folder zipped behind it. On first launch (or after an update, or if the folder was deleted) it extracts the application into the hidden `.djsync/app` next to itself, keeps `.djsync/data` (settings), then starts it — later launches are instant. Unlike a PyInstaller one-file exe, nothing is unpacked to the computer at every launch. The workflow tests the result like a user would (DJSync.exe alone in an empty folder, self-test of the application). Optional code signing with the `SIGN_CERT_PFX` / `SIGN_CERT_PASSWORD` secrets. By hand: ```bash pip install pyinstaller pyinstaller packaging/DJSync.spec # -> dist/DJSync/ (DJSync.exe + _internal) packaging/build_ffmpeg.sh out/ # (Linux, mingw-w64) -> ffmpeg.exe, ffprobe.exe -> dist/DJSync/tools/ packaging/build_launcher.sh out/ # (Linux, mingw-w64) -> launcher.exe python packaging/pack_single_exe.py out/launcher.exe dist/DJSync 1.0.0 DJSync.exe ``` ### Download engine updates yt-dlp is **never updated on its own**. When a download or a link import fails in a way that looks like "YouTube changed", DJSync offers once to install the new version (official wheel from PyPI, SHA-256 checked, installed in the settings folder — the exe is not modified, no restart needed, failed downloads are retried). *Settings ▸ Download engine* checks / installs by hand and goes back to the previous version. ## Quick use | Shortcut | Action | |---|---| | `Ctrl+K` | Search a track or paste a link, from anywhere | | `Ctrl+1` … `Ctrl+6` | Home, Search, Library, Downloads, Import URL, Settings | | `Ctrl+F` | Search / filter field of the page | | `Space` | Play / pause | | `Ctrl+→` / `Ctrl+←` | Next / previous track | | `F1` | Help | The in-app **Shortcuts & help** button has a short guide. ## Command-line tools (read-only) ```bash python -m djsync.db.diagnose E: # check a drive's database python -m djsync.db.pdb.check E: # check export.pdb python -m djsync.analysis track.m4a # analyse a file (BPM, key, grid) without writing anything python -m djsync.analysis --compare E: # compare DJSync's analysis with Rekordbox's on a drive ``` ## Languages Everything (interface, error messages, logs, command-line output) is written in **English**. Other languages only translate the interface: `djsync/i18n/fr.py` is a dictionary `key -> text`; **a missing key simply falls back to English**, so a translation can be partial. To add a language, copy `fr.py`, translate what you want and register it in `djsync/i18n/__init__.py`. ## Code layout ``` app.py entry point (python app.py) djsync/ core/ YouTube Music search, download (yt-dlp), Spotify import, duplicates, Camelot db/ USB drive: exportLibrary.db (SQLCipher) in library/, export.pdb in pdb/, artwork analysis/ BPM, grid, key, waveforms, ANLZ files (numpy + FFmpeg only) audio/ built-in player, artwork ui/ Qt interface (PySide6): app, controller (ctrl/), views (views/), table, dialogs i18n/ English (en.py, reference) and French (fr.py) texts tests/ pytest tests (fake drive, synthetic tracks) tools/ development tools: screenshots, logo export packaging/ PyInstaller spec + icon docs/ technical notes (in French for now) ``` ## Tests ```bash pip install pytest python -m pytest -q # everything, UI included (Qt "offscreen": no display needed) ``` Tests use neither the network nor a real drive: generated Rekordbox database, synthetic tracks. A test also checks that no French text is hard-coded outside the translation file. Screenshot tool (no display needed): `python tools/ui_screenshots.py shots --sizes 860x560,1280x800 --lang en --dialogs`. ## Technical notes (French) - [Audio analysis, artwork, date added](docs/analyse_audio.md) — calibration on a real drive - [Comparing DJSync's analysis with Rekordbox's](docs/comparaison_rekordbox.md) — procedure and sample size - [export.pdb (older players)](docs/export_pdb.md) - [V0.2.0 interface, beat grid, duplicates](docs/interface_v020.md) ## Version history | Version | Changes | |---|---| | **1.2.2** | **Edit info** (right-click a track, the player or Tools): title, artists, album, year, genre and artwork (keep, pick one found on Deezer, an image from the computer, or none) — the audio file is never touched. **Uniformise** a playlist or the whole library: clean titles (no *feat.*, no *Official Video*), artists separated by commas with guests taken from the title, album / year / genre / artwork filled in when empty; a review page where nothing is written until you validate track by track and *Save*, progress kept between sessions, suggestions unticked for tracks not downloaded by DJSync. **Playlists by genre** (off by default): a *DJSync ▸ Genres* folder, one playlist per genre or group of genres, kept up to date as you download or edit, even once moved or renamed; tracks you add yourself are never removed. Developer: voice-over and subtitles for the tour video (`tools/narrate.py`), French tour (`--lang fr`). | | **1.2.1** | **Feedback tab**: report bugs, ideas and comments from the app, several remarks per sending, each with its type, text and up to 3 screenshots (capture of the DJSync window, image picked or dropped), technical details and the end of the log without personal paths if wanted; sent by e-mail through a small Google Apps Script of the author (`tools/feedback/`, setup in `docs/FEEDBACK_SETUP.fr.md`), otherwise a pre-filled GitHub issue. **Library**: choose the columns shown (right-click a header), widths and the sort of each playlist remembered, `#` wide enough for 700+ tracks, new **Source** column (YouTube Music, YouTube, SoundCloud…). **Playlist picker** as a folder tree with search, new playlists created in the selected folder. **Search**: Everything / Title / Artist / Album selector (an artist's tracks, not tracks named after them), albums opened in one double-click with all their tracks ready to download, maximum duration and "hide tracks already owned" filters. Grid editor zoom (Ctrl/⌘ + wheel, pinch, − / +). Duplicates: playlists of each version, *Start* / *Middle* listening. Progress bars in each download row, overall download progress, estimated progress of the track being analysed, one *Activity* card in the sidebar. | | 1.2.0 | **macOS (Apple silicon, .dmg) and Linux builds** (beta), built and self-tested by the *Build* workflow next to Windows; on macOS, the first launch lifts the quarantine by itself and relaunches from the drive. DJSync tells you when a new version is out (Settings, once a day; test versions also see pre-releases). Grid backups and the grid waveform cache are capped. GPL-3.0 license, tester guide (computer, Rekordbox, players) and issue forms. Presentation videos (`tools/tour_video.py`, `tools/teaser_video.py`). rc.3: drive restore points (Settings ▸ Drive backups), remove DJSync from a drive, clearer computer-library errors. **rc.4**: **update DJSync from the app** (Settings ▸ DJSync: download, SHA-256 check, restart into the new version; stable or test channel), exact version shown everywhere (a test build now sees the next test build); **m4a beat grids no longer early in Rekordbox** (measured −32.5 ms on 52 tracks, now compensated: re-analyse m4a tracks, *Tools* ▸ *Analyse selection* ▸ *Re-analyse*), ½-beat button in the grid editor, half-beat count in `--compare`; Rekordbox saving master.db in place is picked up before DJSync writes; click-to-seek bar, spinner while a track loads, Space after *Listen* and keyboard media keys; collapse/expand button for the sidebar; playlist picker with search and full-height list; dialogs stay above the window on macOS (full screen too); French fixes; About (license, third-party components, credits). | | 1.1.0 | **Library diagnostic** (Home ▸ *Diagnostic*, one button per library: USB drive and computer): duplicates, low-quality files (MP3 < 192 kbps, AAC < 112 kbps, < 44.1 kHz) and bad sources (music video, live, lyrics, visualizer, sped up…). For each problem: keep one of the versions, or **download a clean version** (YouTube Music, SoundCloud as a fallback) that replaces the old one(s) in all their playlists, at the same position, and is analysed again; *Ignore* is remembered. Beat grid editor: no more old waveform for 2 s, the Rekordbox-style waveform is cached (instant on reopening). `python -m djsync.analysis --compare` also reads this computer's Rekordbox collection (`--compare local --under E:\Contents`), ignores tracks analysed by DJSync itself and gives 95 % confidence intervals ([procedure](docs/comparaison_rekordbox.md)). Presentation video tool (`tools/demo_video.py`). | | 1.0.0 | First release: ONE file to download, DJSync.exe (prepares itself on first launch, repairs itself if moved or deleted, keeps settings across updates), published as a GitHub release with its SHA-256 and notes built from this table. Everything from 0.1 to 0.5: search and download from YouTube Music, Spotify/YouTube/SoundCloud import, USB drives (exportLibrary.db + export.pdb) and the Rekordbox library of the computer, BPM/key/grid/waveform analysis, beat grid editor, duplicates, playlist copy between libraries, metadata completion, memory cue, eject, yt-dlp updates on demand. | | 0.5.1 | Windows CI: full test suite passes on Windows (280 tests); failing tests are reported as annotations on the run page; GitHub actions moved to Node 24. | | 0.5.0 | Portable build that looks like a single file (DJSync.exe + hidden `.djsync` folder), audio-only FFmpeg and QuickJS instead of full FFmpeg + Deno (≈ 250 MB less), GitHub workflow for the Windows build with optional signing. Player on miniaudio instead of pygame (streams, nothing decoded in full). yt-dlp updated only on failure or by hand (Settings ▸ Download engine), with rollback. Eject button; when running from a USB drive, the host computer's Rekordbox library is opened only after asking (remembered per computer). Copy a playlist to another library (USB ↔ computer, drive ↔ drive) with its analysis reused, not recomputed. Complete missing metadata (Deezer) of existing tracks. Memory cue on the first downbeat (ANLZ + database). Download format M4A (original) or MP3 320, optional loudness normalisation. Analysis memory peak reduced (≈ -30 % on a long mix, same results). | | 0.4.0 | Rekordbox library of this computer (`master.db`, Rekordbox 6/7): opened automatically when no drive is plugged in, or from Home / Settings. Downloads go to Music/DJSync (configurable) and into the collection with analysis (ANLZ files under `share`, named after the track UUID), artwork (640/240/80 px), album, genre, label, year; playlists and folders (masterPlaylists6.xml kept in sync), beat grid, title/artist, duplicates, delete. Never writes while Rekordbox is open; master.db copied before each change. Built on pyrekordbox. | | 0.3.1 | Polished interface: icons on buttons, menus, tables and the sidebar, rounded cards, key pills, larger search fields, messages as small pop-ups; explanations moved to tooltips (ⓘ) and needless texts removed. New "Downloads & analysis" page: downloads table + analysis table (every unanalysed track, search in the whole library to re-analyse, beat grid editor icon on each analysed track). | | 0.3.0 | New Qt interface (PySide6) replacing customtkinter: native widgets, much smoother scrolling, resizing and table updates. Zoom and theme colour apply instantly without rebuilding the window; the zoom no longer follows the window size. Plainer look: flat dark theme, square corners, no shadows or animations, no per-row artwork or placeholder rows. Beat grid editor: drag the listening cursor on the waveform, "Bar starts here" (a downbeat exactly on the cursor), shift by ±1/±10/±100 ms, BPM ×2 / ÷2. Rekordbox 3-band waveforms (`.2EX`): track previews now look like Rekordbox's own instead of blue (re-analyse older tracks). Downloads complete album, year, genre, label, track number and ISRC (Deezer, can be turned off). Same features as 0.2.4 otherwise; UI tests run without a display. | | 0.2.4 | Background analysis: Library ▸ *Not analysed* section with "Analyse all" / "Stop", progress card in the sidebar, the rest of the app stays usable. Player: beat grid button and track options (title/artist, analyse again, compatible keys, show in library). export.pdb: track updates no longer eat the free space (in-place rewrite, deleted rows reclaimed), clearer "export.pdb is full" message. Beat grid editor is now a page of the main window (the separate window vanished or froze the app on Windows). Fixes: dialogs sized for the zoom and kept on screen, key pill now shown right after analysis. | | 0.2.3 | Windows start-up fix: the main window stayed invisible after the splash screen, and the splash shrank to a corner (DPI awareness set too late). | | 0.2.2 | Window always opens inside the screen (saved size/position clamped, maximised state remembered); lightweight splash screen at launch (also a native splash for the Windows executable). | | 0.2.1 | Fully English software: error messages, logs and command-line tools included; French kept as an optional interface translation (partial translations fall back to English). English README, obsolete console demos removed. | | 0.2.0 | New interface: Home + omnibar, search as you type, "All tracks", Camelot pills, drag and drop onto playlists, harmonic filter, player previous/next + waveform, zoom and small windows, English by default, logo per colour. On-demand analysis, beat grid editor, duplicates tool, help and shortcuts. Code split (library, controller). | | 0.1.6 | Local BPM / key / ANLZ waveform analysis, date added and artwork in both databases, calibration on a real drive (MP3 encoder delay). | | 0.1.x | YouTube Music search and download, Spotify/YouTube/SoundCloud import, writing to exportLibrary.db then export.pdb, library and playlists, player, portable mode. | ## Releasing `djsync/__init__.py` holds the version. Add its row to the table above, then push a tag: `git tag v1.0.0-rc.1 && git push origin v1.0.0-rc.1` publishes a **pre-release** to test on real hardware; `git tag v1.0.0 && git push origin v1.0.0` publishes the release. The *Build* workflow refuses a tag that does not match the version, runs the tests on Windows, macOS and Linux, builds the three downloads and attaches them to the release. ## Roadmap - [ ] Beta with testers, on real players (recent CDJ/XDJ reading OneLibrary, older ones reading export.pdb) - [ ] Compare the analysis with Rekordbox on 300–500 varied tracks ([procedure](docs/comparaison_rekordbox.md)) - [ ] Signed executables (no Windows SmartScreen / macOS Gatekeeper warning) - [ ] macOS on Intel Macs; Linux as a single AppImage file - [ ] Public release ## Credits - [pyrekordbox](https://github.com/dylanljones/pyrekordbox) and the community documentation [Deep Symmetry / crate-digger](https://djl-analysis.deepsymmetry.org/) for the Rekordbox formats. - [yt-dlp](https://github.com/yt-dlp/yt-dlp), [ytmusicapi](https://github.com/sigma67/ytmusicapi), [Qt for Python (PySide6)](https://doc.qt.io/qtforpython-6/), [SQLCipher](https://www.zetetic.net/sqlcipher/). ## License DJSync is free software under the [GNU General Public License v3.0](LICENSE): you can use, study, share and modify it; modified versions you distribute must stay under the GPL, with their source code. Bundled components keep their own licenses: see [THIRD_PARTY_NOTICES.md](THIRD_PARTY_NOTICES.md). Only download content you have the right to use.