Discord Music Bot
A self-hosted Discord music bot whose audio path is built out of two external programs rather than a JavaScript extractor.
The audio path refuses to depend on anything that rots: yt-dlp resolves metadata only and ffmpeg reads the media URL itself, so when YouTube rotates its player, updating one pinned binary is the whole fix.
Facts
- Fourteen slash commands, and no Lavalink, no Java, no Python and no native Opus or sodium package — Node 22's aes-256-gcm covers voice encryption and ffmpeg does the Opus encoding
- The install script downloads the pinned binary and the SHA2-256SUMS file from the same release, verifies the checksum, and refuses to install a binary that does not match
- Preflight checks ffmpeg, the opus muxer, yt-dlp and the environment before the bot logs in
- Opus in-band FEC is on by default, and output is pinned to 48 kHz stereo with 20 ms frames
- At most one ffmpeg child per guild, killed on stop, skip, seek, volume change, player destruction and process exit
- An expired media URL is re-resolved exactly once and retried before an error is shown
- 128 offline checks run with no network, no .env file and no yt-dlp binary; 13 live checks are opt-in
Stack
- Node.js
- discord.js
- @discordjs/voice
- yt-dlp
- ffmpeg
There is no repository link here because there is no repository. The project was
set up deliberately without git, and scripts/snapshot.sh is the rollback
mechanism: a labelled tarball that excludes node_modules, the yt-dlp binary,
the environment file and previous snapshots.
Two decisions carry the design. yt-dlp returns metadata and nothing else, so
ffmpeg reads the media URL directly and -ss becomes a cheap HTTP range request
— seeking does not re-download from zero. And volume and seek are the same
operation, a restart of ffmpeg at the current position with new arguments, which
is why the PCM path and a native Opus encoder are not in the dependency tree at
all.