AI DJ PRO
Back to Home

Guide & Support

AI DJ Pro — Complete Technical Guide

Combined reference for architecture, sessions, library, mixing, session alignment, waveform fades, Set Cue, stems, deck effects, loops, sound FX, sampler, backup, crowd requests, MC, AI tools, configuration, and troubleshooting.

New to AI DJ Pro?

Prefer plain language? The user guide covers the same workflows without technical jargon — perfect for first-time DJs and party hosts.

Simple User Guide

1. Big picture

AI DJ is a local-first DJ application: your music stays on your machine, playback and mixing run in the desktop app, and a Python DJ brain on your PC chooses tracks, drives auto-mix timing, and generates host (MC) announcements. Optional cloud APIs (OpenAI, ElevenLabs) power AI search, set planning, and voice — but core playback does not require them.

Plain-language guide for first-time DJs and party hosts — no technical jargon required.

Simple User Guide
See also: Session alignment controls (section 11), MC system (/guide/mc).
Architecture: Electron client (UI, decks, waveforms, Web Audio) ↔ WebSocket server on port 8765 (session, queue, smart picks, MC) + HTTP file/stream server on 8766 + Crowd request page on 8767.

Division of labour

LayerResponsibility
Electron clientDual decks (A/B), crossfader, waveforms, transport, library UI, MC audio playback, volume ducking during MC
WebSocket serverSession state, track queue, smart next-track picks, MC text generation, TTS orchestration, crowd queue, license checks
HTTP file serverServes local files from your music folder; proxies YouTube streams for in-browser playback
Crowd HTTP serverSimple web form on your LAN so guests can request songs from their phones

The client and server talk over ws://127.0.0.1:8765. The UI must stay connected for crowd requests and server-driven auto mix to work.

2. Components and ports

PortServicePurpose
8765WebSocket (AIDJ_WS_PORT)All DJ commands and real-time updates
8766HTTP (AIDJ_HTTP_PORT)Local audio files, /health, YouTube stream proxy
8767Crowd HTTP (AIDJ_CROWD_HTTP_PORT)Guest song-request form (LAN)

Key source files

AreaFile
Backend hubaidj_server.py
Feature helpersaidj_features.py
Waveform / mix cueswaveform_analysis.py
Library AI searchlibrary_ai_search.py
AI set builderai_set_builder.py
MC templates / AI linesmc_brain.py
Desktop UI logicelectron_mock/renderer.js
Electron shellelectron_mock/main.js
Waveform renderingelectron_mock/ProfessionalWaveform.js
Backup / Restore UIelectron_mock/BackupRestore.js
User quick startREADME.md

Production vs development

  • Installed app: Electron spawns bundled aidj-server.exe, waits for http://127.0.0.1:8766/health, then opens the UI.
  • Development: Run python aidj_server.py and npm start in electron_mock/ separately.

Default music folder on first install: Documents\AI DJ\Music (Windows) or ~/Documents/AI DJ/Music (macOS).

3. First run and data storage

Setup wizard

On first successful library load, a 4-step setup wizard may appear (unless you already completed it):

  1. Music folder — point at your MP3/M4A/FLAC library
  2. API keys — optional OpenAI / ElevenLabs for AI and MC voice
  3. Crowd requests — LAN URL and QR code for guests
  4. Analyze a track — BPM/key for beat grid and auto cues

Completion is stored in browser localStorage as AIDJ_SETUP_COMPLETE.

Where data lives (Windows example)

%APPDATA%\AI_DJ_Demo_Pro\

DataLocation
App configaidj_config.json
Track genres / metadatatrack_metadata.json
Waveform cachewaveform_cache/
Crowd blocklistcrowd/blocklist.json
License blobEncrypted, via license_storage.py
Server logaidj-server.log (packaged)
Sampler banks + settingsElectron userData\sampler\ (banks.json, settings.json)
Sampler audio filesuserData\sampler\files\ or user-chosen folder (settings.json → filesDir)

On Windows packaged builds, Electron userData is typically %APPDATA%\AI DJ\.

The client also mirrors the library in IndexedDB (AIDJLibrary) so reopening the library panel can show tracks immediately while refreshing from the server in the background.

4. The music library

Scanning local files

On startup (and when you change the music folder), the server scans AIDJ_MUSIC_DIR for: .mp3, .m4a, .flac, .wav, .ogg, .aac

For each file it builds a library item with title, artist, duration, BPM and musical key (Camelot), genre, album art, beat grid origin, and mix cue.

Library panel (client)

  • Search, filter by genre / BPM / Camelot / date added
  • Sort and drag-to-reorder (playlist order)
  • Half / Full layout — half docks the sheet so decks stay usable; drag tracks onto Deck A/B
  • Wave column — spectral waveform thumbs (fetched via get_library_waveforms; YouTube ids / filenames matched for streams)
  • Album art when available; compact rows for 1080p
  • Double-click — set as starting track or play (mode-dependent)
  • Right-click — queue next (auto mode)
  • Genre editing, AI genre detect, dedications, remove from playlist, add to saved playlist
  • Stems button — local files only; YouTube streams show N/A
  • In manual mode: Load Deck A / B buttons per row (requires Start Session first — in-app reminder if you load early; DJ Phone Start syncs desktop started)
  • In auto mode (session active): live/next deck indicators on rows

Request full library sync: client sends get_library → server responds with { type: "library", tracks: [...] }.

Saved playlists & analysis tools

Save the current library view to IndexedDB (named playlists) and reload later, including save filtered by genre. Add to playlist appends a single track into a named list. Wire-format playlists from YouTube preserve order; sequential queue mode plays them in list order instead of smart reordering.

ActionWhat it does
Analyze missing BPMBatch BPM, beat grid, Camelot for tracks that lack them
Detect genre (AI)OpenAI one-word genre for a single track
Analysis queueFull waveform + cue analysis for all tracks missing data

5. YouTube and streaming

Single track import

Paste a URL → Load YouTube (Add) or Replace. Server uses yt-dlp + FFmpeg to download (or stream), analyzes BPM/key, adds to state.lib, and pushes library_update to the client. Duplicate detection can warn before adding a second copy of the same song.

Playlist import (stream mode)

  1. Resolve — yt_playlist_resolve returns track list without downloading everything
  2. Load — yt_playlist_load adds entries as stream URLs: http://127.0.0.1:8766/stream/youtube?id=VIDEO_ID
  3. Background preload — parallel BPM/key/genre for tracks that need metadata (configurable concurrency)
  4. Download — ai_set_download with source: "yt_playlist" writes audio into a user-chosen folder (same download pipeline as AI Set Builder)
  5. Cancel on new load — client bumps playlist_load_generation / beginPlaylistLoad so stale preload/analysis cannot clear busy state for a newer list

Replace during a live session: the library swaps, but the currently playing track keeps going until it ends or you skip — the new list does not hijack the mix mid-song. Stems: streamed YouTube paths are not Demucs-eligible; library UI shows N/A.

Playback URLs

  • Local files → file:// or http://127.0.0.1:8766/... (served from music dir only — path traversal blocked)
  • YouTube → stream proxy on 8766

First play of a YouTube stream may take 15–30 seconds while the pipeline starts. Duplicate detection can warn before adding a second copy of the same song.

6. Running a session

Start

  1. Load a library (local folder and/or YouTube playlist).
  2. Optionally double-click a starting track in the library.
  3. Press Start on the desktop or Start from DJ Phone (/dj/mc) → client sends { type: "start" } (phone path uses remote_control → proxy_ws). Optional welcome MC if MC is enabled.
  4. Desktop sets local started = true (phone Start also calls applyLocalSessionStarted so Library load/queue works without a second Start on the PC).
  5. Server sets started = true and the player loop picks the first track (crowd queue, DJ-selected starting track, or first in queue).
  6. Server sends incoming (with optional next_track) → client loads the live deck and soft-preloads the next track on the idle deck in parallel.

During the session

  • Pause — freezes client audio and server track clock; resume continues the same song.
  • Next Track (auto only) — skip to next pick with an immediate linear crossfade (quickFade: skips beat-phrase wait). Soft-reuse plays the idle deck if already buffered; otherwise takes over the in-progress soft-preload without restarting the download. Gain nodes call cancelScheduledValues before setValueAtTime so a leftover fade curve cannot throw and abort the load.
  • Energy slider — crowd energy 0–100; biases BPM targets for smart selection.
  • End — goodbye MC (optional) → music fade out → session reset.

Stop

  1. Client: { type: "stop" }
  2. Optional goodbye MC → client plays TTS wav
  3. Server: fade_out (default ~8s) → client fades gains → fade_complete
  4. Server: stop_ack — library queue reset, stats finalized

Decks A and B

Two logical decks alternate in auto mode. Server toggles state.deck between A and B each transition. Live deck = on air; idle deck = soft-preloaded with the next track as soon as session start / post-mix (maybePreloadNextTrackOnIdleDeck, preloadOnly: true) so Next can take over immediately.

7. Auto mix vs manual mix

Toggle via mix control mode (stored in localStorage, synced to server as mix_control_mode). In manual mode the horizontal crossfader uses a center dead zone (snaps near 50%): at center, both decks stay at full volume — fading only begins when you move past center toward Deck A or Deck B.

Auto mixManual mix
Track advanceServer timer + skip; sends incomingYou load decks from library; server holds queue
incoming messagesLoaded and crossfadedIgnored
Next Track buttonActiveDisabled
CrossfaderAutomated (gains follow live deck)You blend Deck A ↔ B (center = both full)
Phrase / Bar / Phase lock / Set CueActiveAuto-only — not used for manual blends
LibraryBrowse, queue, indicatorsLoad Deck A / B per row (after Start Session)
MCServer premix/postmix/intervalIntro when you press play on a deck
Deck effects / hot cues / loopsAvailable on both decksSame — primary tool for live performance

Use auto for hands-off hosting; manual when you want full DJ control with the crossfader. In manual mode, Load Deck A / B does nothing until Start Session — the app shows a reminder if you try early. DJ Phone Start syncs desktop started so Library load/queue works after a remote start.

Manual crossfader curve

  • Center — both gainA and gainB at full level (~80% peak headroom).
  • Left of center — Deck A stays full; Deck B fades out toward the left extreme.
  • Right of center — Deck B stays full; Deck A fades out toward the right extreme.

This matches hardware DJ mixers with a wide overlap at center. Saved position is in client memory; switching back to auto resets the fader to the live deck.

8. How a transition works

Auto mix is a cooperation between server timing and client audio engineering.

Server side

After sending incoming, the server waits roughly track duration minus overlap. While paused, that clock does not advance. On timeout or skip, it calls pick_next_track(), flips deck, sends the next incoming.

Client side (playOnDeck)

  1. Resolve crossfade length — always from outgoing waveform analysis (Manual Xfade faders removed; isXfadeAutoMode() is always true).
  2. Resolve mix-in point (Set Cue: Auto / Drop / Chorus / Beginning from waveform — Manual Set Cue removed from UI). Beginning always starts at 0:00.
  3. Snap cue to Phrase or Bar grid (see Session alignment controls, section 11).
  4. Beat-align incoming to outgoing (tempo + phase) at mix start.
  5. Schedule crossfade; run phase lock during overlap. Non-shock mixes may use slow overlap hold (crossfadeToOverlapHold).
  6. Update UI: waveforms, deck titles, library deck indicators.

Shock mix (hard transitions)

When Shock mix is enabled (checkbox next to Align on mix), the client may replace a normal crossfade with a shock transition:

  1. Spinback — outgoing playback rate ramps down + spinback SFX, then hard drop; or
  2. Echo out — deck Echo wet/feedback automation trails while the next track drops (crossfadeToShockTransition flavor echo).
ModeCondition
BPMIncoming vs outgoing BPM differs by more than ~8%
GenreGenres are incompatible for a smooth blend (genresCompatibleForMix)
BothEither condition qualifies (default)

Style (Auto / Spinback / Echo out): Auto biases spinback on BPM jumps and echo on genre-only jumps.

Runs on natural track end and when you press Next Track. Requires genre metadata for genre-based detection. When Shock is off, or the pair does not qualify for shock, auto mixes use a slow center-hold overlap so both tracks stay audible longer. Fade begin also prefers mixing before beat collapse (vocals-only / soft outro).

Client: evaluateShockTransition() / crossfadeToShockTransition() / crossfadeToOverlapHold() in renderer.js. Persisted: localStorage keys aidj_auto_shock_transition, aidj_shock_mix_trigger, aidj_shock_mix_style. Shock mix is auto mode only — disabled in manual mix, and also disabled while Mashup is Creative (UI greyed out; resolveShockTransitionForMix returns no shock).

Creative Mashup (stem choreography)

When Mashup → Creative is on (session bar, next to Set arc), auto crossfades may choreograph Demucs stem gains on both decks:

  1. prepareCreativeStemMashup checks both decks for local files + stem cache ready + stem audio loaded.
  2. Enables stem playback; arms a rotating recipe (vocal_ride, beat_bed, bass_swap).
  3. After crossfadeToken increments, armPendingStemMashup schedules V/D/B/O gain ramps for the fade duration.
  4. Shock transitions clear any pending mashup and skip stem choreography.

Persisted: localStorage key aidj_creative_mashup. See Session alignment controls (section 11) — Mashup.

Crossfade audio graph

audioA ──► gainFullMixA ──┐
stem A (V/D/B/O) ─────────┼──► stemBusA ──► … ──► gainA ──┐
                          │                                ├──► gainMusicDuck ──► speakers
audioB ──► gainFullMixB ──┤                                │
stem B (V/D/B/O) ─────────┘──► stemBusB ──► … ──► gainB ──┘
audioMC ──► gainMC ──► (parallel, for host voice)

MC ducking lowers gainMusicDuck during announcements so the crossfader gains on A/B are untouched. In Stems mode, ducking targets vocals on the active stem deck instead.

9. Smart track selection and set arc

When AIDJ_SMART_SELECTION=1 (default), the server does not pick tracks randomly. find_best_next_track() scores candidates.

Pick priority

  1. Manually queued track (queue_next / right-click in library)
  2. Crowd queue (FIFO, approved requests)
  3. Sequential playlist — if enabled, next in wire order
  4. Smart selection — scored best match
  5. Fallback — first available track ≠ current
FactorTypical weightNotes
GenreprimaryGenre-first ranking in auto mix (camelot_first path); after AIDJ_GENRE_STREAK (default 4) same-genre plays, prefer_genre_variety flips ranking to switch genres
BPM closenesshighTolerance AIDJ_BPM_TOL (default 6)
Camelot keymediumHarmonic mixing; optional hard filter
Energy curvemediumSet arc phase + crowd energy slider
DiversitylowerPrefer different artists
Recent historyAvoid last N tracks (AIDJ_AVOID_RECENT)

Set arc (energy curve)

Set arc dropdown → server energy_arc_mode. See Session alignment controls (section 11) for how Set arc differs from Phrase, Bar, and Phase lock.

ModeBehaviour
AutoPhases by tracks played: build → peak → cooldown (defaults: 3 + 5 tracks). Sequential playlists keep order.
Warm upForce build phase — gentler, rising BPM; overrides sequential playlist order
PeakForce peak — high energy maintenance; overrides playlist order
Cool downForce wind-down — lower BPM bias; overrides playlist order

Crowd energy slider (0–100) further nudges target BPM within each phase. Harmonic filter in the library (Δ column vs live deck key) is a UI filter for browsing; smart selection uses its own key logic server-side.

10. Waveforms, cues, and beat alignment

Server analyzes audio (librosa + FFmpeg) to produce peak waveform segments (multi-band colours on deck display), beat grid (BPM + beat_grid_origin), and mix cue (structural mix-in point). Results cached under waveform_cache/ by file hash.

Set Cue modes (client)

ModeMix-in point
Auto CueWaveform structural cue + grid snap (default)
DropEmphasis on drop detection
ChorusEmphasis on chorus / lift
BeginningAlways mix in from 0:00 with a slower beat-matched fade

Removed: Manual Set Cue (fixed seconds fader) and the Xfade / Next vertical faders. Fade timing is always waveform Auto Xfade. Full detail: section 18 — Waveform fades and Set Cue.

Fade timing

Always Auto Xfade: fade starts where outgoing waveform energy drops (including before beatless outros). Non-shock transitions may lengthen into a slow overlap hold.

Session alignment toolbar

Phrase, Bar, Phase lock, Set arc, Mashup, Set Cue, Align on mix, and Shock mix — documented in Session alignment controls (section 11) and section 18. Deck waveforms use a centered playhead; near track end the playhead walks right again when the viewport pins. The beat bar dots (1–2–3–4) show live beat position on the playing deck.

11. Session alignment controls

These settings sit in the top control bar (next to Start, Pause, and Next Track). They apply in auto mix mode only — not when you are blending decks manually with the crossfader.

There is a single auto-mix engine (no separate Classic / Smooth / Full Auto picker). Phrase, Bar, and Phase lock shape how transitions are timed and beat-aligned. Set arc shapes what track the server picks next. Mashup shapes how stem levels behave during auto crossfades. The four dots under the toolbar show the live beat position (1–2–3–4) on the currently playing deck in a 4/4 bar.

Phrase

Options: 16, 24, 32, 48, 64 beats (default: 32). Align mixes to longer musical phrases on the outgoing track's analyzed beat grid.

Phrase controls when the next crossfade is allowed to start (the app waits for the next phrase boundary when possible) and where the incoming track's mix cue snaps (aligned to the same phrase length on the incoming grid). At 128 BPM, 32 beats is roughly 15 seconds (about 8 bars in 4/4) — a common DJ phrase length.

SettingEffect
Shorter (16–24)Tighter, more frequent transitions
32Balanced default — musical without feeling rushed
Longer (48–64)Mixes land on bigger section changes

If waiting for a full phrase would run past the waveform fade window, the app falls back to Bar, then to a single beat, so the mix still happens in time. Saved in browser localStorage (persists across sessions on this machine).

Bar

Options: 4 or 8 beats (default: 4). Finer beat-grid alignment when a full phrase is not used or as a fallback.

  • 4 = one bar (four beats in 4/4)
  • 8 = two bars

Bar affects the same two things as Phrase — crossfade timing and cue snap — but on a shorter grid. Use 8 for slightly looser bar-line mixes; 4 for tighter alignment to every bar. Saved in browser localStorage.

Phase lock

Options: Off, Low, Medium, High (default: Medium in code; UI may show High if you changed it). Keep beats locked during the crossfade overlap.

While both decks are audible, the app briefly nudges the incoming deck's tempo so its beat phase matches the outgoing deck. When the fade finishes, tempo returns to normal.

SettingEffect
OffNo beat pulling during the blend
LowGentle correction
MediumBalanced
HighStrongest lock — beats line up fastest; more noticeable tempo micro-adjustments

Phase lock does not change which song plays next or when the fade is scheduled — only how tightly the beats align while the two tracks overlap. Saved in browser localStorage.

Set arc

Options: Auto, Warm up, Peak, Cool down (default: Auto). Tell the server which energy curve to use when choosing the next track in smart / auto playback.

This does not control crossfade length, cue points, or beat alignment. It influences BPM and energy of upcoming picks (and related smart-selection logic). Saved on the server for the active session (sent over WebSocket when you change the dropdown).

ModeBehavior
AutoNatural set flow over time: build energy early, maintain a peak, then cool down. With a fixed playlist / sequential queue, order is preserved.
Warm upPrefer lower-BPM build zone picks — overrides strict playlist order
PeakPrefer higher-BPM peak picks — overrides playlist order
Cool downPrefer easing / lower-energy picks — overrides playlist order

Mashup

Options: Off, Creative (default: Off). Optional Creative stem choreography during auto crossfades.

When Creative is on and both decks have Demucs stems cached and loaded:

  1. The client enables stem playback on outgoing + incoming decks.
  2. During the crossfade, V/D/B/O gains follow a rotating recipe (e.g. vocal ride over incoming beat, beat bed → vocal handoff, bass swap).
  3. After the fade, stem mutes restore to full stems (or you can switch back to Full mix manually).
RequirementNotes
Local filesYouTube / stream decks are skipped
Stems readySeparate stems on both tracks first
Auto mixIgnored in manual mix mode

Mutual exclusion with Shock mix: While Mashup is Creative, the Shock mix checkbox and trigger dropdown are disabled, and shock transitions will not run. Turning Mashup Off restores Shock mix to your saved preference.

Client: prepareCreativeStemMashup / scheduleStemMashupMacro in renderer.js. Saved in browser localStorage key aidj_creative_mashup.

How they work together

Outgoing track playing
        │
        ▼
Phrase / Bar ──► wait for grid boundary (when possible)
        │
        ▼
Incoming track cue snapped to same grid idea
        │
        ▼
Mashup (if Creative + stems ready) ──► stem recipe armed
        │
        ▼
Crossfade starts (timing follows waveform Auto Xfade)
        │   (Shock mix skipped when Mashup is Creative)
        ▼
Phase lock ──► micro-tempo on incoming deck during overlap
        │
        ▼
Set arc ──► (parallel) server picks next track for following transition
ControlAffectsScope
PhraseLong-grid mix start + cue snapClient (auto mix)
BarShort-grid mix start + cue snap / fallbackClient (auto mix)
Phase lockBeat alignment during overlapClient (auto mix)
Set arcNext-track energy / BPM bias (locked modes override playlist order)Server
MashupStem V/D/B/O choreography during auto fadesClient (auto mix)

Related settings (not in this toolbar)

  • Fade timing — always waveform Auto Xfade (Manual Xfade / Next faders removed). See section 18.
  • Set Cue — Auto Cue / Drop / Chorus / Beginning mix-in (session toolbar; Manual Set Cue removed). See section 18.
  • Shock mix — spinback or echo-out on big BPM/genre jumps; otherwise slow overlap hold (auto mode only; disabled while Mashup is Creative). See section 8 and /guide/user#shock-mix.
  • Deck effects / hot cues / auto loops — per-deck knobs, C1–C8 cues, and 4/8 beat loops. See section 20.
  • Sound FX / Sampler / Backup — one-shots, custom pads, and disaster-recovery export. See section 21 and /guide/user#sound-fx-sampler.
  • Manual mix mode — Phrase, Bar, Phase lock, and Mashup are for auto mix; in manual mode press Start Session, then load decks and blend yourself. DJ Phone Start syncs desktop started so Library load/queue works after a remote start.

Tips

  • Start with Phrase 32, Bar 4, Phase lock Medium or High, Set arc Auto, Mashup Off for typical club/party sets.
  • Raise Phrase if mixes feel too busy; lower it if you want quicker turnover.
  • Use Set arc → Warm up at the start of an event or Cool down for last hour — without touching mix timing controls.
  • Use Mashup → Creative only when both decks show Stems ready; otherwise the log will say the mashup was skipped.

12. The MC (host) system

The MC is an optional AI/host voice that speaks between or over tracks.

Generation pipeline

  1. Prompt — event context, venue, track title, energy, dedication, Mem0 memories (optional).
  2. Line source — OpenAI (AIDJ_LIVE_AI_MC) and/or script templates (default, hype, smooth, wedding, etc.).
  3. TTS — ElevenLabs if API key configured; else local pyttsx3.
  4. Delivery — server sends { type: "mc", text, wav_path, duck_enabled, duck_level } → client plays audioMC.
TriggerWhen
introSession welcome
premixBefore track (if enabled + seconds configured)
postmixShortly after track starts
intervalEvery N minutes (mc_interval_min)
goodbyeSession end
manualTest button or manual deck intro (manual mix)

Ducking & settings

While MC speaks, music volume ramps down via gainMusicDuck (default ~30%). On end, music restores and client sends mc_done so the server can continue timing.

  • Event prompt, venue name, DJ name
  • Enable/disable MC, interval minutes, premix/postmix delay seconds
  • Template set vs live AI lines; language, tone, voice
  • Dedicate — one-shot shout-out tied to a specific library track

Rapid Next Track presses temporarily disable skip to prevent chaos. MC announcements can delay skip processing so crossfade timing stays musical.

Deep dive into OpenAI prompting, Mem0, ElevenLabs, Event Prompt customization, banned phrases, and troubleshooting.

Read the full MC System guide

13. Crowd song requests

Guests on the same Wi‑Fi open the crowd page (default http://<your-LAN-IP>:8767/).

Guest flow

  1. Enter song search (artist + title) and optional dedication/name.
  2. Optional PIN (AIDJ_CROWD_REQUEST_PIN).
  3. Content filters block explicit, commercial, and movie-trailer style queries.

Server processing

  1. Fuzzy match local library (AIDJ_CROWD_MIN_MATCH_SCORE, default 0.52).
  2. Optional AI verification for borderline queries.
  3. If no match → YouTube search + download/stream for crowd.
  4. Queue in crowd_play_queue or pending approval if AIDJ_CROWD_REQUIRE_APPROVAL=1.

DJ tools: Crowd link and QR in the top bar, approve/reject pending requests, blocklist for repeat bad queries. Crowd tracks show REQUEST badge in library; play with priority after manual queue.

DJ Phone (booth remote)

Separate from the guest form: open http://<LAN-IP>:8767/dj/mc, unlock with the DJ Phone PIN from MC Settings.

  • Start / Pause / Next, deck loads, MC triggers, mix toggles (energy, mashup, shock, cue, SFX)
  • Commands arrive as remote_control → proxy_ws on the desktop WebSocket client
  • Start from phone calls applyLocalSessionStarted so desktop started matches — Library load / queue works without pressing Start again on the PC

PIN setup, LAN URL, and what you can control from your phone.

Simple User Guide — DJ Phone

14. AI features

All AI features require OPENAI_API_KEY unless noted. Keys are stored via server config (not logged).

Library AI Search

Natural-language search: "1980s wedding opener", lyric queries, theme/era/mood. Returns matches from your library plus YouTube suggestions. Paginated load more results. WebSocket: library_ai_search → library_ai_search_result.

AI Set Builder

Plans a full 6–40 track set from a prompt with energy flow (warmup → build → peak → cooldown), BPM/key smoothing, and marks library vs YouTube import needs. Stream set loads the set as the live queue (library fuzzy match + YouTube stream fallback). Download set writes audio into a user-chosen folder plus an .m3u playlist (ai_set_download). WebSocket: ai_set_builder → ai_set_builder_result; ai_set_download → progress / result.

Genre detection & MC

  • Genre: ID3 tags → heuristics → AI detect (OpenAI) → manual override
  • MC lines: OpenAI + optional Mem0 for venue-specific memories
  • ElevenLabs v3 emotional tags optional for richer TTS

15. Client ↔ server communication

URL: ws://127.0.0.1:8765 (configurable via AIDJ_WS_PORT). On connect: license status, API config, energy arc, mix control mode, MC context. Reconnect with exponential backoff if server restarts.

Important client → server messages

MessagePurpose
start / pause / stopSession transport
cmd + skipNext track (auto)
mix_control_modeAuto vs manual
get_library / set_music_dirLibrary sync
yt_add / yt_playlist_resolve / yt_playlist_loadYouTube
set_starting_track / queue_nextDJ overrides
set_energy_arc / energySet arc + crowd energy
library_ai_search / ai_set_builder / ai_set_downloadAI tools
analyze_track / analyze_missing_bpm / start_analysis_queueAnalysis
mc_context / mc_advanced / mc_dedication_setMC settings
crowd_request_action / crowd_blocklist_addCrowd moderation
manual_live_trackManual mode: tell server what's live
fade_complete / mc_doneClient acknowledgements

Important server → client messages

MessagePurpose
library / library_updateFull or partial library sync
incomingLoad and mix next track (auto)
next_trackPreview of upcoming pick
mcHost audio + ducking params
pause_ack / stop_ack / fade_outSession control
skip_button_stateRate-limit UI
yt_import_progress / playlist_preload_*YouTube pipeline status
library_ai_search_result / ai_set_builder_resultAI responses
crowd_queue / crowd_request_ackCrowd UI
logLive log ticker
license_status / license_requiredLicensing

Many operations are license-gated (start, library load, YouTube, AI search, set builder, etc.). Set LICENSE_DISABLE=1 in dev config to bypass. Max WebSocket frame size: 32 MiB (large libraries with embedded art).

16. Configuration reference

Config merges: environment variables → user aidj_config.json → bundled aidj_config.json.

Core

VariableDefaultMeaning
AIDJ_WS_PORT8765WebSocket
AIDJ_HTTP_PORT8766File/stream HTTP
AIDJ_CROWD_HTTP_PORT8767Crowd form
AIDJ_MUSIC_DIR(see §2)Library root
AIDJ_OVERLAP_SEC8Overlap hint for track timing
AIDJ_STOP_FADE_SEC8End-of-session fade

Selection / energy

VariableDefaultMeaning
AIDJ_SMART_SELECTION1Enable smart next-track scoring
AIDJ_GENRE_STREAK4Same-genre plays before variety flip
AIDJ_BPM_TOL6BPM match tolerance
AIDJ_REQUIRE_KEY_MATCH0Hard-filter incompatible keys
AIDJ_REQUIRE_GENRE_MATCH0Hard-filter genre mismatches
AIDJ_AVOID_RECENT5Recent track memory
AIDJ_ENERGY_CURVE1Energy phase BPM biasing
AIDJ_ENERGY_BUILD3Tracks in build phase
AIDJ_ENERGY_PEAK5Tracks in peak phase

YouTube / preload

VariableDefaultMeaning
AIDJ_FFMPEG_DIRautoFFmpeg + ffprobe for yt-dlp
AIDJ_PRELOAD_CONCURRENCY4Parallel metadata preload threads
AIDJ_PRELOAD_AI_GENRE(see config)AI genre during playlist preload

Crowd

VariableDefaultMeaning
AIDJ_CROWD_HTTP1Enable crowd server
AIDJ_CROWD_REQUEST_PINOptional guest PIN
AIDJ_CROWD_REQUIRE_APPROVAL0Hold requests for DJ approve
AIDJ_CROWD_MIN_MATCH_SCORE0.52Library fuzzy match threshold
AIDJ_CROWD_BLOCK_EXPLICIT1Block explicit YouTube imports
AIDJ_CROWD_BLOCK_COMMERCIAL1Block ad-like content
AIDJ_CROWD_BLOCK_MOVIE1Block film/trailer content

AI / voice

VariableMeaning
OPENAI_API_KEYLibrary search, set builder, genre, MC
ELEVEN_API_KEY / ELEVEN_VOICE_IDMC TTS voice
AIDJ_LIVE_AI_MCEnable live AI MC lines
AIDJ_LLM_MODELOpenAI model (e.g. gpt-4o-mini)

Client-only (localStorage)

KeyMeaning
mixControlModeauto / manual
aidj_mix_phrase_beatsPhrase length (16–64)
aidj_mix_bar_beatsBar length (4 or 8)
aidj_phase_lock_strengthPhase lock 0–3
aidj_auto_shock_transitionShock mix enabled
aidj_shock_mix_triggerShock mix trigger: both / bpm / genre
aidj_shock_mix_styleShock mix style: auto / spinback / echo
aidj_creative_mashupCreative Mashup on/off
cueModeSet Cue mode: auto / drop / chorus / beginning
AIDJ_SETUP_COMPLETESetup wizard done

17. License and troubleshooting

License

Online validation (Gumroad / Paddle / FastSpring / generic REST) + offline crypto + trusted keys. UI modals for activation; periodic re-check (~12h). Dev bypass: LICENSE_DISABLE=1 in config.

Common issues

SymptomCheck
WebSocket error / 1006Is aidj_server.py running on 8765?
No audio from YouTubeFFmpeg path (AIDJ_FFMPEG_DIR), yt-dlp, server console errors
ffprobe Win32 errorBroken ffprobe on PATH; use bundled electron_mock/resources/ffmpeg
Crowd page unreachableFirewall, same Wi‑Fi, correct LAN IP, port 8767
Library always loadingServer connected? IndexedDB cache should show tracks while syncing
Resume plays wrong trackServer pause clock fix — restart server after updates
MC silentElevenLabs quota/key, or pyttsx3 fallback on system

Logs

  • Packaged: %APPDATA%\AI_DJ_Demo_Pro\aidj-server.log
  • Dev: terminal running python aidj_server.py
  • Client: in-app log panel + browser DevTools console

18. Waveform fades and Set Cue

Auto mix fade timing is always waveform-driven. The old vertical Xfade, Next, and Manual Set Cue faders (and Manual/Auto Xfade dropdown) were removed from the UI. In code, isXfadeAutoMode() is always true and isXfadeManualMode() always false.

Set Cue remains as a session-toolbar dropdown: Auto Cue / Drop / Chorus / Beginning.

In manual mix mode, Phrase/Bar/Set Cue/Shock/Align apply to auto transitions only — you load decks yourself and blend with the horizontal crossfader. Loading a deck before Start Session opens an in-app reminder. DJ Phone Start syncs desktop started so Library load/queue works after a remote start.

Related: Phrase / Bar / Phase lock (section 11) snap crossfade start and cue points to the beat grid.

Outgoing fade (Auto Xfade)

  • Fade start and length come from waveform analysis on the outgoing track (detectFadeBeginOnWaveform; prefers mixing before beat collapse / soft outros).
  • Fade duration = content end minus fade start (clamped roughly 2–30s; slow-overlap path may lengthen further).
  • On the live deck waveform, an orange Fade marker shows where the blend will begin.
  • Deck time may count down to fade.
  • Automatic transitions: the client watches the live deck and sends a skip when the fade trigger is reached.
  • Next Track: immediate linear blend (quickFade / skipBeatAlignment); soft-reuses the idle deck when ready; cancels leftover gain curves before priming.

Set Cue (mix-in)

UI: session toolbar — Auto Cue / Drop / Chorus / Beginning (no Manual mode, no cue fader).

ModeMix-in detection
Auto CueGeneral structural mix point from waveform
DropEmphasis on drop / impact
ChorusEmphasis on chorus / lift
BeginningAlways from 0:00; slower beat-matched fade (never uses short Next fade length)
  • Mix-in comes from server waveform analysis (mix_cue_sec, mix_cue_drop_sec, mix_cue_chorus_sec), cached per track (skipped in Beginning mode).
  • The app aligns that structural point to the outgoing fade window (getAlignedMixCueSec).
  • Result is snapped to the Phrase or Bar grid when beat alignment is on (Next Track itself skips beat wait).
  • First track of a session always plays from 0:00.
  • Temporary fallback: 1s until analysis completes (SMART_CUE_FALLBACK_SEC).
  • Waveform markers: live deck orange Fade; incoming deck green Mix.
  • Saved in browser localStorage (cueMode).

Non-shock vs shock crossfades

PathBehavior
Shock (when enabled + trigger matches)Spinback or echo-out hard transition
Slow overlap (default otherwise)Longer fade, ease to center, hold both decks, then finish (crossfadeToOverlapHold)

End-to-end: natural mix vs Next Track

Natural mix:
Live deck playing
  → client hits fade trigger (waveform Auto Xfade)
  → client sends skip to server
  → server picks next track, sends incoming
  → client loads other deck at Set Cue point (soft-preload idle deck)
  → beat-aligned crossfade (Phrase/Bar wait if needed; shock or slow overlap)
  → new live deck

Next Track:
You press Next Track
  → pendingSkip; server skip
  → soft-reuse idle deck if buffered (else take over soft-preload)
  → quickFade=true; cancelScheduledValues on gains
  → immediate linear blend (no phrase / beat wait)

The server's playback timer (AIDJ_OVERLAP_SEC, default 8s) is a rough overlap hint; the client governs the audible blend.

Quick reference

ControlUINotes
Fade out(automatic)Always waveform Auto Xfade
Next TrackButtonImmediate blend; soft-reuse idle deck
Set CueAuto / Drop / Chorus / BeginningSession toolbar; no Manual fader
Shock mixCheckbox + trigger + styleOptional hard transition
Manual mixCrossfaderLoad Deck A/B after Start Session
Mode comboTypical use
Auto Cue + Shock offSmooth party blends with slow overlap
Auto Cue + Shock on (Both / Auto style)Hard cuts on big BPM/genre jumps
Drop / ChorusSteer mix-in character after analysis
BeginningAlways start incoming from 0:00 with a slower fade
Manual mixFull hands-on control with crossfader

Plain-language walkthrough for waveform fades, Set Cue, and deck playheads.

Simple User Guide — How mixes land

19. Stem separation (Demucs)

AI DJ can split local tracks into four stems using Demucs htdemucs (vocals, drums, bass, other).

Architecture

  • aidj-stems (Windows: aidj-stems.exe; macOS: aidj-stems binary) — bundled worker (PyTorch + Demucs + NumPy). Runs as a subprocess only; the main server never imports torch.
  • Cache — per-user folder with four WAV files + meta.json per track hash: %AppData%\AI_DJ_Demo_Pro\stems\<hash>\ (Windows) or ~/Library/Application Support/AI_DJ_Demo_Pro/stems/<hash>/ (macOS).
  • HTTP — stems stream at http://127.0.0.1:8766/stems/<cache_key>/<role>.wav.
  • Queue — one separation job at a time (CPU/GPU heavy).

Both Windows and macOS installers bundle the stem worker when the PyInstaller build step succeeds (build-installer.bat / build-installer.sh step [2b/6]).

Using stems on decks

Each deck has V / D / B / O pads, a Full mix / Stems toggle, and a status chip.

  1. Load a local file (not a YouTube stream).
  2. Click Separate stems in the library row (status sync via stem_status / stem_cache_sync).
  3. When status shows Stems ready, click Full mix to switch to Stems (short gain crossfade; stems start muted then fade in).
  4. Click pads to mute; Alt+click to solo a stem.

Waveform and BPM analysis still use the full mix file.

Playback notes

  • Stem role gains use STEM_PLAYBACK_MAKEUP (~+2.6 dB) so recombined stems are closer in level to the original file. Demucs separation still sounds slightly different (artifacts / thinner highs) — that is expected.
  • Switching Full mix ↔ Stems uses a short Web Audio ramp (STEM_MODE_XFADE_SEC) to avoid a hard mute gap.
  • Do not optimistic-queue Demucs on every deck load; the client prefers stem_status_get / cache sync so a stale queued entry cannot shadow a ready cache.

Creative Mashup (auto)

With Mashup → Creative, auto mixes call prepareCreativeStemMashup before the crossfade and schedule stem macros during the fade. Requires stems ready on both decks. Mutually exclusive with Shock mix. See section 8 — Creative Mashup.

MC ducking with stems

When Stems mode is active on a playing deck, MC volume ducking lowers vocals only on that deck instead of ducking the entire mix.

First run & installer size

  • First separation downloads htdemucs weights (~80 MB) into the torch hub cache. CPU works; CUDA or Apple Silicon GPU may be used when available.
  • The stem worker adds roughly 1.5–2 GB to the installer (PyTorch + Demucs). Build the worker on the same OS and CPU architecture you ship.

Development (from source)

pip install -r requirements-stems.txt
python aidj_server.py

In dev, the server runs stem_worker.py via your Python interpreter instead of the bundled aidj-stems binary.

Building / rebuilding the stem worker

Full installer builds include the worker automatically. To rebuild only the stem worker (e.g. after a fix):

Windows:

pip install -r requirements-stems.txt "pyinstaller>=6.14.1"
rmdir /s /q electron_mock\resources\aidj-stems
python -m PyInstaller --noconfirm --onedir --console --name aidj-stems --log-level WARN ^
  --collect-all demucs --collect-all torch --collect-all torchaudio --collect-all soundfile --collect-all numpy ^
  stem_worker.py
xcopy /E /I /Y dist\aidj-stems\* electron_mock\resources\aidj-stems\
electron_mock\resources\aidj-stems\aidj-stems.exe check

macOS:

pip3 install -r requirements-stems.txt "pyinstaller>=6.14.1"
rm -rf electron_mock/resources/aidj-stems
python3 -m PyInstaller --noconfirm --onedir --console --name aidj-stems --log-level WARN \
  --collect-all demucs --collect-all torch --collect-all torchaudio --collect-all soundfile --collect-all numpy \
  stem_worker.py
mkdir -p electron_mock/resources/aidj-stems
cp -R dist/aidj-stems/* electron_mock/resources/aidj-stems/
chmod +x electron_mock/resources/aidj-stems/aidj-stems
electron_mock/resources/aidj-stems/aidj-stems check

The check command should print JSON with "ok": true. Then rebuild the Electron app (npm run dist / npm run dist:mac) or run the full build-installer.bat / build-installer.sh.

Stem troubleshooting

SymptomLikely causeFix
Stems unavailable / worker not foundStem worker not bundled or build step [2b/6] failedRebuild installer; confirm electron_mock/resources/aidj-stems/ exists before electron-builder
No module named numpy.core.multiarrayOld stem worker missing NumPy binariesRebuild with --collect-all numpy and PyInstaller ≥ 6.14.1
Separation stuck / failedMissing FFmpeg, corrupt file, or out of disk/RAMEnsure bundled ffmpeg is present; try a local MP3/WAV; check server log
YouTube trackStems require a decoded local fileDownload or use a file from your music folder
Very slowDemucs on CPUNormal for long tracks; only one job runs at a time
Creative mashup skippedStems not ready / not local on both decksSeparate stems on both tracks; check log for the skip reason

Plain-language walkthrough for V / D / B / O pads, MC + stems, and common fixes.

Simple User Guide — Stem separation

20. Deck effects, hot cues, loops, and manual crossfader

Per-deck performance tools live in the Electron client (renderer.js, EchoEffect.js). They work in auto and manual mix.

Effects signal path

eqMix (post-EQ) ──┬──► dry bus ──► effectsOutput ──► analysers ──► gainMusicDuck
                  │
                  └──► parallel wet effects ──► wet mix ──┘

Each deck has 12 effect sends in two UI rows plus a separate Filter panel (low/high/band-pass when enabled).

KnobAudio behavior
ReverbConvolution reverb (generated impulse)
DelayFeedback delay; D.Time / D.Feedback knobs
FlangerShort modulated delay
PhaserAll-pass filter chain
EchoStereo ping-pong delay (EchoEffect.js) — BPM-synced, damped feedback
SpiralLFO-modulated short delay
Slip RollTight looping delay
RobotRing-mod style timbre
Mob SawSaw LFO → resonant low-pass
Mob TriTriangle LFO → band-pass

Echo (electron_mock/EchoEffect.js): dual delay lines with cross-feedback, high-pass on input, low-pass on feedback and wet path. Delay time maps from dotted-eighth to quarter note using deckABPM / deckBBPM when known.

FX bypass toggle

Round FX buttons (deckFxToggleA / deckFxToggleB) appear under the channel fader when the Effects panel is expanded. They toggle effectsAEnabled / effectsBEnabled — wet gains go to zero while knob values are preserved.

Hot cues

  • 8 slots per deck (C1–C8); was 4 in earlier builds.
  • Shift+click or Shift+1…8 stores the current playhead.
  • Cues persist per track URL in localStorage.
  • HOT_CUE_COUNT = 8 in renderer.js.

Auto loops (4 / 8)

  • Each deck has 4 and 8 buttons (loopAuto4A/B, loopAuto8A/B) beside Loop In/Out.
  • Click arms an N-beat loop from the playhead (requires BPM).
  • Click again exits.
  • Ctrl+click halves length; Shift+click doubles (max 64 beats).
  • Active button label updates to the current beat length.

MIDI

Effect and filter knobs are exposed to the MIDI learn system (same pattern as EQ). Hot cue MIDI actions use deck-specific note/CC mappings.

Sampler: pads 1–8 (note on/off = hold/gate like the UI), bank previous/next, stop all, grab beats / grab loop. Stems: mode buttons still enable all stems; individual stem actions match the UI. Creative mashup has a toggle action. The Extended MIDI preset includes default notes for sampler (ch1 notes 12–24) and creative mashup (ch1 note 25).

Exit confirm

Closing the main window requests an in-app confirm (showAppExitConfirm via IPC app-request-exit-confirm / app-exit-confirm-response) instead of the native OS dialog.

Plain-language walkthrough for effect knobs, FX bypass, filters, and C1–C8 cues.

Simple User Guide — Deck effects & hot cues

4/8 beat auto loops, exit, and length modifiers.

Simple User Guide — Loops

21. Sound FX, sampler, and backup

Center-column performance tools and disaster-recovery backup. Implemented in electron_mock/renderer.js, main.js / preload.js (sampler IPC), and BackupRestore.js.

  • Sound FX (gainSfx) and Sampler (gainSampler) are separate buses into gainMaster — FX volume does not affect pads.
  • Sampler: banks of 8 pads, optional custom WAV folder, polyphonic playback, pad editor (trim / BPM / sync / loop).
  • Pad gestures: Right-click opens/closes the pad editor; Ctrl+click (Cmd on Mac) clears; Shift+click renames.
  • Deck capture grabs beats or loop regions; in stem mode, only audible V/D/B/O stems are mixed into the WAV.
  • Backup (BackupRestore.js) can optionally embed sampler banks + audio via sampler-export-bundle / sampler-import-bundle.
  • Settings → Shortcuts — editable app keyboard shortcut help (#shortcutsHelp).

Sound FX bus

  • Built-in library (SFX_LIBRARY) plays through gainSfx → gainMaster.
  • sfxVolumePercent (UI: #volSfx) controls only that bus.
  • Triggers create fresh HTMLAudioElements so presses stack/overlap.

Sampler architecture

PieceRole
BanksuserData/sampler/banks.json — multiple banks × 8 pads
SettingsuserData/sampler/settings.json — optional custom filesDir
Audio filesHex fileId + extension under files/ or custom folder
Playback busgainSampler → gainMaster (independent of gainSfx)
VoicessamplerVoices Map — polyphonic (one voice per pad)

Pad model: label, fileId, originalName, shortcut, volume, tempo, bpm, loop, trimStart, trimEnd.

  • Play / hold: quick tap latches (single plays through trim; loop until re-tap); longer press gates until release. Keyboard shortcuts mirror hold/tap.
  • Live pad volume rides HTMLMediaElement.volume with a square-law curve; GainNode holds fixed SAMPLER_PAD_GAIN_MAX makeup so fast slider drags stay reliable in Chromium.
  • Clear pad removes the bank reference and deletes the WAV via sampler-delete-file unless another pad still references the same fileId.

Deck capture → pad

IPC: sampler-save-bytes writes a generated WAV.

ActionRegion
Grab beatsLast N beats ending at playhead (needs deck BPM)
Grab loopNormalized Loop In/Out

Stem-aware capture: if deckStemsReady(side), decode/mix only audible stem roles (solo or unmuted V/D/B/O) via toStemPlaybackURL + decodeAudioData. Otherwise use the full-mix deckAudioBufferCache buffer. Peak-normalize before encode (SAMPLER_CAPTURE_TARGET_PEAK).

Sampler IPC (Electron)

ChannelPurpose
sampler-get-state / sampler-save-stateBanks JSON
sampler-get-files-dir / choose / reset / openCustom storage folder
sampler-import-files / sampler-import-pathsCopy audio into store
sampler-file-url / sampler-delete-fileResolve / remove
sampler-save-bytesCapture / generated WAV
sampler-export-bundle / sampler-import-bundleBackup bundle (banks + base64 files)

Key files

FileRole
electron_mock/renderer.jsPads, capture, stem-aware chop, polyphony
electron_mock/main.js / preload.jsSampler IPC + custom folder + exit confirm
electron_mock/BackupRestore.jsExport/import UI and payload

Backup & Restore

BackupRestore.js builds aidj-backup JSON: server snapshot, IndexedDB playlists/EQ/tracks, localStorage, optional license.

When Include sampler is checked, sampler-export-bundle embeds banks + audio (hard cap ~200 MB). Restore calls sampler-import-bundle into the current files directory (does not force the old PC's absolute filesDir).

UI: #backupRestoreModal — license + sampler checkboxes on export; same sampler checkbox gates restore.

Pad banks, editor, deck grab (including stems), and Backup walkthrough.

Simple User Guide — Sound FX and Sampler

What is included in exports and how restore remaps library / sampler folders.

Simple User Guide — Backup & Restore

Quick workflows

Party (auto, hands-off)

  1. Load YouTube playlist or local folder.
  2. Run Analyze missing BPM if needed.
  3. Set Set arc → Auto, MC on with event prompt.
  4. Enable crowd QR.
  5. Start — let smart selection and crossfades run.

Club segment (manual)

  1. Switch to manual mix mode.
  2. Load tracks on Deck A / B from library.
  3. Blend with crossfader (center = both decks full); use hot cues and deck effects.
  4. MC intro fires when you play a deck.

Planned wedding set

  1. AI Set Builder — "wedding cocktail 2h, 90s–today, no explicit".
  2. Review results, import missing YouTube tracks.
  3. Stream set (or Download set) with sequential mode.
  4. Warm up set arc at start; switch to Peak for dancing.

Still need help?

Contact our support team for licensing, setup, or technical questions.

support@aidjpro.app