STREAMING 24/7

FMDJ

A DJ that never sleeps.

FMDJ beatmatches the entire Jo Luno catalogue into one endless, seamless set — detected, time-stretched, and crossfaded entirely by code, then streamed live around the clock.

Listen live

Stay here. Press play.

The same endless set sent to YouTube and Twitch can play directly on this page. Choose a platform; the player loads only after you ask for it.

Ready when you are

Open the Twitch player

Playback starts on your click, with sound and controls left in your hands.

The playlist

One giant arc. No cliffs.

Every track's BPM is detected up front, then the whole library is laid out as an arch: start at the median tempo, climb to 200 BPM, dive to 60, and glide back home. Every song plays once per cycle, with different tracks on the climb and descent. Neighboring songs stay close in tempo, and the final song returns to the first song's BPM. This is the real curve, drawn from the live playlist:

200 BPM 150 100 125 · start 200 · peak 60 · floor 125 · loops back ↺
913tracks in the library
1×each song per cycle
∞cycles — the set keeps going
6.45largest BPM step anywhere
0BPM across the loop seam
On screen

What's playing, always.

A Pillow renderer pulls each track's ID3 tags and embedded album art, wraps long titles, and streams the strip to FFmpeg as raw RGBA frames — the overlay flips to the next track mid-crossfade, right as the new song takes over.

Rendered live by overlay_renderer.py at 2 fps, composited by FFmpeg.

Architecture

Four processes and a named pipe.

No DAW, no DJ software, no browser sources — just Python feeding FFmpeg through a FIFO, with every stage supervised and able to reconnect if its neighbour restarts.

~/Music/Jo Luno
913 MP3s
ID3 tags + album art
playlist_manager.py
detects BPM · time-stretches · equal-power crossfades (16 beats)
audio FIFO
raw PCM
44.1 kHz stereo
ffmpeg
x264 1080p30 + AAC
tee muxer, auto-reconnect
YouTube + Twitch
simulcast RTMP
either can drop, the other stays live
overlay_renderer.py → RGBA frames @ 2 fps, composited into the video by ffmpeg
Under the hood

Built to run unattended.

Beatmatched crossfades

BPM is detected via onset autocorrelation, the incoming track is time-stretched with scipy, and the two are blended with an equal-power curve — 4 bars, like a real DJ.

Arch-shaped playlist

The library is pre-analysed once, then ordered as a rise-and-fall arch so tempo drifts, never jumps — including where the cycle wraps around.

A living overlay

Album art, wrapped titles and the Jo Luno crescent, re-rendered the instant the track flips. Falls back to plain drawtext, then to no overlay, if anything's missing.

Self-healing pipeline

If the network drops, FFmpeg restarts and the playlist blocks on the pipe until it's back. If the playlist dies, the pipe disappears and the stream stops cleanly instead of hanging.

One encode, two platforms

A single x264 encode is tee'd to YouTube and Twitch with onfail=ignore — one destination failing never takes down the other.

Zero-touch operations

A macOS LaunchAgent starts the stream at login and revives it after crashes. Every component logs to its own timestamped file.