Note
This is a fork of JMusicBot from jagrosh I started this because it was not maintained and was not working anymore.
A cross-platform Discord music bot with a clean interface, and that is easy to set up and run yourself!
This version of JMusicBot changes/updates various dependencies. To ensure your bot continues to function correctly, please note the following mandatory changes:
-
Java 25 Minimum: The bot now requires Java 25 or higher.
-
LibDave/udpqueue: You must have glibc >= 2.38. If you are using Docker, this is already handled for you.
-
Privileged Gateway Intents: You must enable the Message Content Intent in your Discord Developer Portal.
- Navigate to: Your Application > Bot > Privileged Gateway Intents > Toggle "Message Content Intent" to ON.
- Without this, the bot will not see your commands.
- Easy to run (just make sure Java is installed, and run!)
- Fast loading of songs
- No external keys needed (besides a Discord Bot token)
- Smooth playback
- Server-specific setup for the "DJ" role that can moderate the music
- Clean and beautiful menus
- Supports many sites, including Youtube, Soundcloud, and more
- Supports many online radio/streams
- Supports local files
- Playlist support (both web/youtube, and local)
JMusicBot supports all sources and formats supported by lavaplayer:
- YouTube
- SoundCloud
- Bandcamp
- Vimeo
- Twitch streams
- Local files
- HTTP URLs
- MP3
- FLAC
- WAV
- Matroska/WebM (AAC, Opus or Vorbis codecs)
- MP4/M4A (AAC codec)
- OGG streams (Opus, Vorbis and FLAC codecs)
- AAC streams
- Stream playlists (M3U and PLS)
Please see the Setup Page to run this bot yourself!
When running JMusicBot directly (not in Docker), make sure to pass these JVM flags:
Linux / macOS / Windows (CMD):
java -Dfile.encoding=UTF-8 -Dnogui=true --enable-native-access=ALL-UNNAMED -jar JMusicBot-0.6.2-All.jarWindows (PowerShell): PowerShell treats -D as its own parameter. Quote each JVM option so they are passed to java correctly:
java "-Dfile.encoding=UTF-8" "-Dnogui=true" "--enable-native-access=ALL-UNNAMED" "-jar" ".\JMusicBot-0.6.2-All.jar"Alternatively, use the stop-parsing token so the rest of the line is passed literally: java --% -Dfile.encoding=UTF-8 -Dnogui=true ...
-Dfile.encoding=UTF-8 ensures non-English characters (Cyrillic, Japanese, etc.) display correctly in Discord. On Windows or older JDKs, omitting it can cause mojibake in slash-command autocomplete and embeds.
Important: Your system must have glibc version 2.38 or higher. Failure to meet this requirement will result in errors when using JDave and udpqueue.
Note: Ubuntu 24.04 "Noble" and Debian 13 "Trixie" already include a compatible glibc version out of the box.
You can check your glibc version with:
ldd --versionOn Debian/Ubuntu-based systems, you may also need to install the following native audio library dependencies:
# Install required native library dependencies
sudo apt-get update
sudo apt-get install -y libopus0 libsodium23If your version is below 2.38, you will need to upgrade your system or use a compatible runtime. (You can also use Docker, which is recommended.)
JMusicBot can be run using Docker for easy deployment and management. Pre-built images are available from the GitHub Container Registry. The container is configured to run headless and automatically generate a default config.txt on first run.
If you already have a directory with your config.txt, Playlists/ folder, and other bot files, either provide the path to that directory or run the container from within it:
docker run --rm -it \
--name jmusicbot \
-v "$(pwd):/musicbot" \
ghcr.io/arif-banai/musicbot:latestThis mounts your current directory as the musicbot volume, so the bot will use your existing configuration and playlists.
-
Create a directory for your bot and run the container:
mkdir -p /path/to/jmusicbot docker run --rm -it \ --name jmusicbot \ -v "/path/to/musicbot:/musicbot" \ ghcr.io/arif-banai/musicbot:latest -
First Run:
- On first run, if the mounted directory is empty, the bot will automatically generate a default
config.txtfile. - Edit
/path/to/musicbot/config.txton your host and add your Discord bot token. - Run the container again.
- On first run, if the mounted directory is empty, the bot will automatically generate a default
If you prefer docker-compose, copy the example compose file and update the volume path:
cp docker-compose.example.yml docker-compose.yml
# Edit docker-compose.yml and update the volume path
docker-compose up -dExample docker-compose.yml:
services:
jmusicbot:
image: ghcr.io/arif-banai/musicbot:latest
container_name: jmusicbot
volumes:
- /path/to/musicbot:/musicbot
restart: unless-stoppedCheck the Docker Compose Example for more details.
- Config Persistence: The
/musicbotvolume must be mounted for your configuration to persist. The bot reads and writesconfig.txtfrom/musicbot(the container's working directory). - First Run: If
config.txtdoesn't exist, the bot will generate a default one automatically. You'll need to edit it with your bot token before the bot can start. - Image Tags:
- Use
ghcr.io/arif-banai/musicbot:latestfor the latest build from the master branch - Use
ghcr.io/arif-banai/musicbot:0.6.1(replace with actual version) to pin a specific release version - Recommendation: For production, pin your image tag rather than using
latest
- Use
- JAVA_OPTS: The container uses ZGC and AlwaysPreTouch by default. Set
JAVA_OPTSto add heap limits (e.g.-Xms256m -Xmx512m) or other flags. See Performance Tuning for details.
To view published images, visit: https://github.com/arif-banai/MusicBot/pkgs/container/musicbot
For optimal audio quality with minimal stuttering, the following JVM and configuration options are recommended.
The bot works best with ZGC (Z Garbage Collector) which provides sub-millisecond pause times:
java -Dfile.encoding=UTF-8 \
-XX:+UseZGC \
-XX:+AlwaysPreTouch \
-Dnogui=true \
--enable-native-access=ALL-UNNAMED \
-jar JMusicBot-*.jarFlag explanations:
-Dfile.encoding=UTF-8: Ensures non-English characters display correctly in Discord (required on Windows or older JDKs)-XX:+UseZGC: Sub-millisecond GC pauses (generational mode is default in JDK 24+)-XX:+AlwaysPreTouch: Pre-allocates memory at startup to avoid page faults-Xms/-Xmx: Optional; set heap size if you want to limit or fix memory (e.g.-Xms256m -Xmx512m)
The Docker image uses ZGC and AlwaysPreTouch by default. Set JAVA_OPTS to add heap limits or override:
environment:
- JAVA_OPTS=-Xms256m -Xmx512m -XX:+UseZGC -XX:+AlwaysPreTouchThe bot includes configurable audio buffers that protect against GC pauses. These can be tuned in config.txt:
performance {
# NAS buffer duration in ms (protects against JVM pauses up to this duration)
nasBufferMs = 800
# Lavaplayer frame buffer duration in ms (amount of decoded audio to buffer)
frameBufferMs = 2000
}Higher values provide more protection against stuttering but add latency. The defaults (800ms NAS, 2000ms frame buffer) should work well for most setups.
JMusicBot supports granular proxy configuration, allowing you to route specific components through a proxy while letting others connect directly. This is useful when you need to proxy audio traffic (e.g., to bypass regional restrictions) without affecting Discord API communication.
Add the following to your config.txt:
proxy {
# Proxy server hostname and port
host = "127.0.0.1"
port = 8080
# Enable proxy for specific components
lavaplayer = true # Audio source requests (YouTube, SoundCloud, etc.)
jda = false # Discord API traffic
github = false # Version check requests
}Route only audio traffic through proxy (most common):
proxy {
host = "127.0.0.1"
port = 18080
lavaplayer = true
jda = false
github = false
}Route all traffic through proxy:
proxy {
host = "proxy.example.com"
port = 8080
lavaplayer = true
jda = true
github = true
}- Leave
hostempty orportas 0 to disable proxy entirely - Each component can be independently enabled/disabled
- HTTP proxies are supported (SOCKS proxies are not currently supported)
This project follows a trunk-based development workflow. The master branch is always releasable, and all work happens in short-lived branches:
feature/<slug>- New features (e.g.,feature/new-player-ui)fix/<slug>- Bug fixes (e.g.,fix/youtube-oauth)chore/<slug>- Maintenance tasks (e.g.,chore/update-deps)deps/<slug>- Dependency experiments (e.g.,deps/youtube-source-pr195)release/<version>- Release stabilization (optional, e.g.,release/0.6.3)
Branch names are automatically validated by CI to ensure consistency. For detailed information about the development workflow, branch naming rules, and best practices, see DEVELOPMENT_WORKFLOW.md.
Please read the Issues List before suggesting a feature.
If you have a question, need troubleshooting help, or want to brainstorm a new feature, please start a Discussion.
The Discord server is also available for questions and suggestions. Click here to join.
If you'd like to suggest a feature or report a reproducible bug, please open an Issue on this repository. If you like this bot, be sure to add a star to the libraries that make this possible:
This bot (and the source code here) might not be easy to edit for inexperienced programmers. The main purpose of having the source public is to show the capabilities of the libraries, to allow others to understand how the bot works, and to allow those knowledgeable about java, JDA, and Discord bot development to contribute. There are many requirements and dependencies required to edit and compile it, and there will not be support provided for people looking to make changes on their own. Instead, consider making a feature request (see the above section). If you choose to make edits, please do so in accordance with the Apache 2.0 License.



