Play your Plex music in Discord with style. Alpha 0.5
| Modern Visual Player | Classic Player Embed |
|---|---|
PlexBot is a next-generation Discord music bot designed for Plex users. Seamlessly stream your personal music library (and more!) into your server's voice channels, enjoy a beautiful visual player, and take advantage of a robust extension system for ultimate flexibility.
- Stream from Plex: Play tracks, albums, artists, and playlists directly from your Plex server.
- Plex Sonic Features: Mood & genre browsing via
/search, plus Similar Tracks, Radio, and Sonic Adventure buttons on the player, all powered by Plex's neural audio analysis. - Radio: Start a radio station from any track with one button press. Optionally enable infinite radio to auto-refill the queue.
- YouTube Support: Search and play music from YouTube via extension.
- Interactive Player UI: Choose between a modern image-based player or a classic Discord embed.
- Static Player Channel: Optionally dedicate a channel for the persistent player UI.
- Rich Queue Management: Add, remove, shuffle, and loop tracks with intuitive controls.
- Slash Commands: Clean, discoverable, and autocomplete-enabled.
- Extensible: Powerful Extensions system for custom features.
- Easy Setup: Guided installation and Docker support.
- Troubleshooting & Guides: Player UI Guide, Troubleshooting, and more.
- More Music Sources: Spotify, SoundCloud, and additional streaming integrations.
- User Custom Playlists: Save, manage, and share your own playlists within Discord.
- Expanded Command Set: More slash commands for advanced control and new features.
- Command Panel UI: In static player channels, use an interactive command panel (embed with buttons) for a seamless experience (no slash commands needed).
- Additional Visual Player Styles: Choose from more themes and layouts for the player UI.
- And much more...
PlexBot offers two distinct player UIs:
- Sleek, image-based: Uses album art as a background, overlaying track info and controls for a rich, modern look.
- Best for dedicated channels: Looks stunning as a persistent player in a static channel.
- Traditional Discord embed: Familiar, compact, and works anywhere.
- Great for multi-purpose channels: Shows album art as a thumbnail.
All player settings are in config.fds (see Configuration below).
For more, see the Player UI Guide.
/search [mode] [query]
Search across all sources with a unified mode selector. The mode dropdown includes built-in Plex features and any extension providers (YouTube, etc.). For Mood, Genre, and Radio modes the query autocomplete populates with real choices from your Plex library.
| Mode | Description | Query |
|---|---|---|
| Plex Library | Search your Plex music library for artists, albums, and tracks | Free text |
| Find by Mood | Browse tracks by mood tags (e.g. "Happy", "Sad", "Energetic") | Autocomplete lists moods (randomized sample of 25) |
| Find by Genre | Browse tracks by genre (e.g. "Rock", "Jazz", "Electronic") | Autocomplete lists all genres |
| Radio Station | Pick a station or seed radio from a track | Autocomplete lists stations |
| YouTube, etc. | Extension providers appear automatically when loaded | Free text |
Examples:
/search mode:Plex Library query:"The Beatles"/search mode:Find by Mood query:Happypick a mood from the autocomplete dropdown/search mode:Find by Genre query:Rockpick a genre from the autocomplete dropdown/search mode:Radio Station query:Library Radiopick a station from autocomplete, or type a track name to seed radio
/playlist [playlist] [shuffle]
Play a full Plex playlist, optionally shuffled.Example:
/playlist playlist:"Summer Hits" shuffle:true
/play [query]
Quickly play a track, album, or artist by search term.Example:
/play query:"Bohemian Rhapsody"
/help
Show an interactive help menu with all commands and usage tips./ping
Test if the bot is responding to interactions.The visual player's second row includes three Plex Sonic buttons that use neural audio analysis on the currently playing track:
| Button | Emoji | What it does |
|---|---|---|
| Radio | 📻 | Opens a panel with Replace Queue / Add to Queue / Similar Tracks options, seeded from the current track |
| Similar | 🔍 | Instantly shows 25 sonically similar tracks in a select menu |
| Adventure | 🧭 | Opens a popup where you type a destination track, then builds a sonic path from what's playing to the destination |
All three require a Plex track to be playing. When infinite radio is enabled in config.fds, the queue automatically refills when it runs low.
See the Installation Guide and Configuration Guide for full details.
- Docker & Docker Compose (Docker Desktop recommended)
- Discord bot token (Developer Portal)
- Plex server URL and token (How to get a Plex token)
git clone https://github.com/kalebbroo/PlexBot.git
cd PlexBot-
Secrets: Copy
RenameMe.env.txtto.envand fill in your credentials:DISCORD_TOKEN=your-discord-bot-token PLEX_URL=http://your-plex-ip:32400 PLEX_TOKEN=your-plex-token
-
App settings (optional):
config.fdsis auto-created from the template with sensible defaults if it doesn't exist. To customize player style, logging, or behavior, copyRenameMe.config.fdstoconfig.fdsand edit it before starting (see Configuration below). -
Run the install script:
Install/win-install.bat(Windows) orInstall/linux-install.sh(Linux). This generates the Lavalink config, builds the Docker images, and starts the bot.
PlexBot uses two config files:
| File | Purpose | Template |
|---|---|---|
.env |
Secrets & infrastructure (tokens, URLs, passwords) | RenameMe.env.txt (manual copy required) |
config.fds |
Application settings (player UI, logging, behavior) | RenameMe.config.fds (auto-created if missing) |
| Variable | Description | Required |
|---|---|---|
DISCORD_TOKEN |
Discord bot token | Yes |
PLEX_URL |
Plex server URL with port (e.g. http://192.168.1.50:32400) |
Yes |
PLEX_TOKEN |
Plex authentication token | Yes |
LAVALINK_HOST |
Lavalink hostname. Use Lavalink for Docker, or an IP/hostname for remote (default: Lavalink) |
No |
LAVALINK_SERVER_PORT |
Lavalink port (default: 2333) |
No |
LAVALINK_SERVER_PASSWORD |
Lavalink password (default: youshallnotpass) |
No |
LAVALINK_SECURE |
Use HTTPS/WSS for Lavalink. Set true for remote servers behind SSL (default: false) |
No |
Uses Frenetic Data Syntax (YAML-like format). All settings have sensible defaults and you only need to change what you want to customize.
| Key | Type | Default | Description |
|---|---|---|---|
visualPlayer.useModernPlayer |
bool | true |
true = album art image player, false = classic Discord embed |
visualPlayer.inactivityTimeout |
float | 2.0 |
Minutes of silence before the bot auto-disconnects from voice |
visualPlayer.staticChannel.enabled |
bool | false |
Lock the player to one specific channel |
visualPlayer.staticChannel.channelId |
int | 0 |
Discord channel ID (right-click channel > Copy Channel ID) |
visualPlayer.progressBar.enabled |
bool | true |
Show a live-updating progress bar (updates every second). Disable to reduce Discord API calls |
visualPlayer.progressBar.size |
string | medium |
Bar width: small (mobile-friendly, 10 segments), medium (default, 16 segments), large (wide displays, 22 segments) |
visualPlayer.progressBar.emoji.* |
int | (empty) | Custom Discord emoji IDs for smooth-fill progress bar. Leave empty for unicode fallback (▓░) |
| Key | Type | Default | Description |
|---|---|---|---|
plex.maxConcurrentResolves |
int | 3 |
Max parallel track resolves when loading playlists/albums from Plex. Lower if tracks fail to load; higher loads faster but may overwhelm Plex |
plex.maxConcurrentYouTubeResolves |
int | 5 |
Max parallel track resolves when loading from YouTube. Separate limit allows higher concurrency for YouTube sources |
plex.radio.infinite |
bool | false |
Enable infinite radio, which automatically refills the queue when it runs low |
plex.radio.refillThreshold |
int | 5 |
Queue size threshold that triggers a refill when infinite radio is enabled |
plex.radio.batchSize |
int | 30 |
Number of tracks to fetch per radio request (initial batch or refill) |
| Key | Type | Default | Description |
|---|---|---|---|
logging.level |
string | INFO |
Console log level: VERBOSE, DEBUG, INFO, WARN, ERROR. Log files always save all levels |
logging.saveToFile |
bool | true |
Save log files to disk |
logging.path |
string | logs/plex-bot-[year]-[month]-[day].log |
Log file path (supports [year], [month], [day], [hour], [minute], [second], [pid]) |
| Key | Type | Default | Description |
|---|---|---|---|
bot.environment |
string | (empty) | Set to Development for guild-scoped slash commands (faster updates during dev) |
PlexBot includes 30 custom emoji for a smooth-fill progress bar. Without them, the bar uses unicode block characters (▓░) which work everywhere but look less polished.
Setup instructions
- Go to the Discord Developer Portal and select your bot application
- Click Emojis in the left sidebar
- Upload all 30
.pngfiles fromImages/Icons/progress/. The filenames become the emoji names automatically - Copy each emoji's numeric ID and paste it into
config.fdsundervisualPlayer.progressBar.emoji
The 30 emoji are organized into three groups:
| Group | Count | Keys |
|---|---|---|
| Left cap | 8 | bar_left_empty, bar_left_filled_1 to bar_left_filled_6, bar_left_filled |
| Middle | 14 | bar_mid_empty, bar_filled_1 to bar_filled_12, bar_mid_filled |
| Right cap | 8 | bar_right_empty, bar_right_filled_1 to bar_right_filled_6, bar_right_filled |
All 30 IDs must be provided for custom emoji to activate. If any are missing, the bot falls back to unicode.
See the Configuration Guide for a detailed walkthrough with screenshots.
PlexBot supports Docker for easy deployment. See the Docker Guide.
The default install runs both PlexBot and Lavalink together in Docker with no extra setup needed.
By default, the install scripts run Lavalink alongside PlexBot in Docker. If you want to run Lavalink on a separate machine (e.g. a dedicated audio server, or a shared Lavalink instance), you can point PlexBot to it by changing three values in your .env:
LAVALINK_HOST=192.168.1.100 # IP or hostname of your Lavalink server
LAVALINK_SERVER_PORT=2333 # Must match Lavalink's application.yml
LAVALINK_SERVER_PASSWORD=mypassword # Must match Lavalink's application.yml
LAVALINK_SECURE=false # Set true if behind a reverse proxy with SSLThen remove or comment out the lavalink service and depends_on block in Install/Docker/docker-compose.yml. PlexBot will connect to your remote Lavalink instead.
Note: When running Lavalink separately, you are responsible for installing Java 17+, downloading the Lavalink server jar, configuring its
application.yml, and keeping it updated. See the Lavalink docs for setup instructions.
PlexBot's Extensions system lets you add custom features, integrations, and automations. Build your own or browse community extensions.
If you experience brief audio stuttering or "CD skip" sounds during playback, especially when other applications are running on the same machine, this is caused by Lavalink's audio thread being interrupted by the OS.
How audio streaming works: Lavalink (a Java process) must send an Opus audio frame to Discord exactly every 20 milliseconds. When your CPU is under load, the OS scheduler can preempt Lavalink's thread, causing a missed frame and an audible glitch. PlexBot itself does not touch the audio stream and only handles commands and UI.
Two optional settings can help:
Uncomment _JAVA_OPTIONS in your .env file to switch Java from its default garbage collector to ZGC, which keeps GC pauses under 1ms (the default can pause for 10-50ms).
_JAVA_OPTIONS=-XX:+UseZGC -XX:+ZGenerational -Xms256m -Xmx512m| Pros | Cons |
|---|---|
| Eliminates GC-related audio stuttering | Uses ~10-20% more memory than the default GC |
| Sub-millisecond pause times | Requires Java 21+ (included in the Lavalink 4 Docker image) |
Uncomment cpuset and cpu_shares in Install/Docker/docker-compose.yml to reserve dedicated CPU cores for Lavalink so other processes cannot starve it. These are Docker Compose directives and can only be configured in the YAML file.
cpuset: "0,1"
cpu_shares: 2048| Pros | Cons |
|---|---|
| Prevents other processes from starving the audio thread | Pinned cores are less available to other containers |
| No stuttering even under heavy host CPU load | Requires knowing which cores to dedicate |
Only enable these if you are experiencing stuttering. Most users running PlexBot on a dedicated server or low-traffic machine will not need them.
MIT License. See LICENSE.
DOWNLOADING OR USING THIS SOFTWARE CONSTITUTES ACCEPTANCE OF THE TERMS AND CONDITIONS OF THE MIT LICENSE. THIS SOFTWARE IS PROVIDED "AS IS" AND WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESSED OR IMPLIED.
PlexBot is not affiliated with Plex, YouTube, or Discord. PlexBot and Kaalebbroo.Dev are affiliated with Hartsy.AI (Allowing artists to control how their work is used)
