Warning
Lydian is currently in a beta state, before its v1.0.0 release it may be unstable and subject to a number of bugs. Pre-releases should work reasonably well, but it should likely be kept to smaller servers for the time being.
If you do encounter bugs, please check the existing issues to see if it's been reported already, and open a new issue if it hasn't.
Lydian is a Discord bot for playing music. It uses yt-dlp to
extract info and download media from URLs, and thus will support any source that yt-dlp
supports. Lydian does not support
Spotify links. Use the -help command to see all available commands, or -help <command> to see
information on a specific command. The bot's queue only clears when -clear is used or the bot is
shut down.
Bug reports, feature suggestions, questions: https://github.com/svioletg/lydian/issues/new
Project board: https://github.com/users/svioletg/projects/6/views/1
Docs: https://lydian.readthedocs.io/en/latest/
Important
Lydian is designed to be used in only one server at a time. Trying to play music in two or more different servers at once may cause unexpected issues and is unsupported for the time being.
- Setup: Discord
- Setup: Lydian
- Usage: Running the bot
- Usage: Bot console commands
- Usage: CLI commands
- URL and extractor filtering
- Permissions
- Debug Mode
Follow the instructions here: https://discordpy.readthedocs.io/en/stable/discord.html
The bot permissions you'll need to tick are:
- Read Messages/View Channels
- Send Messages
- Embed Links
- Connect
- Speak
Lydian requires Python 3.14 or higher. If you haven't installed Python or aren't sure how to manage multiple versions or virtual environments, using uv is recommended.
You will need to install git to install Lydian as a python package.
Click to show
- Install uv per the "Standalone installer" instructions here: https://docs.astral.sh/uv/getting-started/installation/
- Run
uv python install 3.14. - Create a directory to run Lydian in, then navigate to it in your terminal.
- Run
uv venvto create a virtual environment, which will keep Lydian contained to your current directory. - Run
uv pip install git+https://github.com/svioletg/lydian.gitto install Lydian in this directory.- This will install the most recent available version of Lydian. If you want to install a
specific version, add an
@to the end of the URL followed by a tag name.
- This will install the most recent available version of Lydian. If you want to install a
specific version, add an
- Once installed, run
uv run lydian --versionand ensure it outputs "Lydian v[your version]"
You can now start the bot by running uv run lydian in this directory, at which points it should
handle the rest of the setup via a few prompts. You can also use uv run lydian-manage or
uv run lydian-cli for a small collection of Lydian-related utilities. Keep in mind that you will
need to preface every Lydian command with uv run and ensure you are in this directory.
Lydian can be updated in the future by running the same installation command above with the -U
option: uv pip install -U git+https://github.com/svioletg/lydian.git
Click to show
The bot is structured as a Python package, so you can install it using pip:
pip install git+https://github.com/svioletg/lydian.gitThis will install Lydian and its commands (lydian and lydian-manage) to your virtual environment
if one is active, otherwise it'll be available in your global Python environment. The bot can be
updated in the future by running this same command with -U added after install.
pip install -U git+https://github.com/svioletg/lydian.gitYou must provide your bot's token via the LYDIAN_TOKEN environment variable. The recommended way
to do this is by creating a text file called .env in the directory you'll run the bot from, and
write in LYDIAN_TOKEN=<token> where <token> should be replaced with your real bot token. Running
lydian without a lydian-config.toml file present in the current directory will give you a prompt
to input your token into, and the .env file will be created automatically.
Note
Make sure that the file is named exactly .env, and not .env.txt or anything else. If you're
using Windows or macOS, file extensions may be hidden in your file browser by default.
Use the lydian command to start running the bot. If lydian-config.toml is not in your current
directory, you'll be asked if you want to create the necessary files automatically. If it is
present, the bot should start up normally. You should make a folder somewhere on your PC, for
example named lydian, then when Lydian installed, run the lydian command in that directory to
set it up.
The bot can be stopped either by using the stop command or hitting Ctrl+D while focused on the
window, after which the bot will try to shut itself down cleanly. If this isn't working for some
reason, you should be able to hit Ctrl+C to send a keyboard interrupt and forcibly stop the process.
Note
All commands starting with debug require debug mode to use.
Warning
This command uses the eval() function, which is unsafe to use with untrusted user
input and enables potentially
destructive actions. You should be using a separate bot token for debug mode (set with
LYDIAN_DEBUG_TOKEN), and as long as you're only running the bot locally on a secure machine this
shouldn't be an issue.
Prints the result of an expression to stdout, or logs it as a DEBUG-level log if the --log flag is
given. This command has access to the config object, perms object, a dbg dictionary which
stores references to various things specifically for debugging or development usage, the store
dictionary (see debug store) as well as Python's built-ins. For convenience, ? can be used in
place of dbg. at the beginning of the expression, e.g. ?bot.user is parsed as dbg.bot.user.
$ can be used in the same way for store..
Arguments:
- expression (string)
Options:
--log(flag)
Example:
> debug eval dbg.cog.voice.queue
debug_context['cog.voice.queue'] == MediaQueue([])
> debug eval --log dbg.cog.voice.queue
[2026-04-30 00:51:30] [bot::thread_console/DEBUG]: debug_context['cog.voice.queue'] == MediaQueue([])
Warning
This command uses the eval() function, which is unsafe to use with untrusted user
input and enables potentially
destructive actions. You should be using a separate bot token for debug mode (set with
LYDIAN_DEBUG_TOKEN), and as long as you're only running the bot locally on a secure machine this
shouldn't be an issue.
Stores either the result of an expression or the expression itself to a key in the store
dictionary, to be accessed later by debug eval. To do the latter, prefix the expression with &.
Stored expressions will be evaluated on the fly on every run of debug eval store.<key>, when just
storing the result (no &) the expression is evaluated once right then and a deep-copy of the value
is stored to read later.
The expression given to this command does not support the expansions/shortcuts that debug eval
supports, e.g. ?cog.voice.now_playing does not work and would have to be written fully as
dbg.cog.voice.now_playing.
Arguments:
- expression (string)
- destination key (string)
Example:
> debug store dbg.cog.voice.now_playing np
> debug eval $np
dbg.cog.voice.now_playing == MediaItem(title='Victoria (2019 Remaster)',
url='https://www.youtube.com/watch?v=vaIzujp0IpI', duration=219)
> debug store &dbg.cog.voice.now_playing np
> debug eval $np
dbg.cog.voice.now_playing == MediaItem(title='Victoria (2019 Remaster)',
url='https://www.youtube.com/watch?v=vaIzujp0IpI', duration=219)Shows a description for a given command, or all commands if given no arguments.
Arguments:
- command name (string) [optional]
Attempts to shut the bot down cleanly.
Arguments: N/A
Prints out how long the bot has been running for.
Arguments: N/A
Lydian provides some utilities under the lydian-cli or lydian-manage commands. Either can be
used, they will behave exactly the same.
Prints the total size being taken up by the downloaded media directory and asks if the user would like to delete its contents.
Arguments: N/A
Prints the filepath to the most recently created log file.
Arguments: N/A
The bot uses regular expressions (commonly "regex") for the user-configured input URL and yt-dlp extractor filters. If you're unfamiliar, you can view a quick reference for regex syntax here: https://www.rexegg.com/regex-quickstart.php
List of yt-dlp extractors: https://github.com/yt-dlp/yt-dlp/blob/master/supportedsites.md
Add - to the beginning of the pattern to make it a blacklisted expression.
The URL will be matched against the expression from the beginning of the string, so you don't need
account for anything after it (i.e. no need for ending every expression in .* or starting it with
^), but you will need to add .* to the end of your extractor filters to match anything
following that expression.
Note
When entering these regular expressions into your config TOML, make sure to use single quotes to ensure it is treated as a "literal" string.
Dots (.) are special character in regex, so make sure to escape any literal dots with a
backslash.
Examples:
| Regex | Description |
|---|---|
https://.+\.youtube\.com/ |
Matches any YouTube link |
https://music\.youtube\.com/ |
Matches only YouTube Music links |
https://youtu\.be/ |
Matches shortened "youtu.be" share links |
https://.+\.bandcamp\.com/ |
Matches any Bandcamp link |
https://kinggizzard\.bandcamp\.com/ |
Matches only one artist's Bandcamp page |
Role-based permissions are handled separately from lydian-config.toml, in an optional
YAML file called permissions.yml kept in the same directory as the TOML config. YAML is slightly
more complex than TOML, but its usage here should be relatively straightforward. You can read about
it at yaml.info.
Note
If permissions.yml is not found, no permissions are applied; i.e. all commands will be available
to any user.
Just like the config, permission rules are only loaded once when the bot starts up. If you make
any changes to permissions.yml you want reflected, you'll need to stop the bot and start it
again.
The basics to know as far as we're concerned are:
-
Instead of
key = value, YAML uses a colon, e.g.key: value. -
Boolean values can be either
true/falseoryes/no -
YAML lists are written with hyphens, basically acting as bullet points for each item.
list: - "item 1" - "item 2"
-
YAML key values can contain more keys, creating nested tables ("mappings") indicated by indentation
top-category: subcategory-1: a: 1 b: "two" c: true subcategory-2: a: 4 b: "five" c: false
commands is a mapping of command names to a list (roles) and a whitelist key. roles accepts
a list of either role names (as a string) or role IDs (as an integer). Using IDs is recommended
since role names can change, while an ID will always point to the same role—you can use comments
(any text written after # on a line) to make a note of the role's name by its ID. An empty list
can be given by giving the key and no value, e.g. roles:.
whitelist can be either true or false: if true (whitelisting), only either those with any of
the listed roles can use this command, if false (blacklisting) only those without the listed
roles can use this command.
commands also accepts a .default key with the same structure described above, which defines
fallback rules to use when a command does not have any rules defined. The default rules are...
.default:
whitelist: no
roles:...meaning any user with any or no roles can use any command without defined permissions.
Example:
commands:
.default:
whitelist: false
roles:
remove:
whitelist: true
roles:
- 'mod'
skip:
whitelist: true
roles:
- 1500575589361520640 # "Can Skip" roleThis indicates:
-removecan only be used by users with a role namedmod-skipcan only be used by users that have a role with the ID1500575589361520640- For all other commands that aren't listed here,
.defaultis used, in which any user regardless of roles can use them
Debug mode can be enabled either by setting the LYDIAN_DEBUG environment variable to 1 or by
setting debug to true in lydian-config.toml. This will:
- Use the
LYDIAN_DEBUG_TOKENenvironment variable's value instead ofLYDIAN_TOKENfor the bot token - Enable bot commands from the
DebugCogcommands cog; see - Enable debug-only console commands (see Usage: CLI commands)