Intro
festivald is a music server that plays on the device it is running on, and is remotely controlled by clients.
It can also serve music resources such as song files, album art, and organized archives of whole artists.
The 3 main APIs festivald exposes:
JSON-RPC 2.0for state retrieval & controlRESTendpoints for serving large resources (audio, art, etc)Docs-festivaldserves the very docs you are reading right now
The transport used is HTTP(s).
A public instance of festivald with Creative Commons licensed music is available at:
https://daemon.festival.pm
For a general quick start, see the next chapter: Quick Start.
Clients
To interact with festivald, you need a client.
The reference JSON-RPC client is festival-cli.
General purpose HTTP clients like curl, wget or a web browser will also do.
The documentation will use festival-cli & curl on the default http://localhost:18425 for examples.
JSON-RPC
For the JSON-RPC API, anything that can transmit JSON over HTTP(s) can be a client, like curl:
# Toggle playback.
curl http://localhost:18425 -d '{"jsonrpc":"2.0","id":0,"method":"toggle"}'
The equivalent wget command:
wget -qO- http://localhost:18425 --post-data '{"jsonrpc":"2.0","id":0,"method":"toggle"}'
The equivalent festival-cli command:
festival-cli toggle
For a quick start on the JSON-RPC API, see JSON-RPC/Quick Start.
REST
For the REST API, you can use anything that can handle HTTP(s), like a web browser:
# Download this exact song.
http://localhost:18425/map/Artist Name/Artist Title/Song Title
The equivalent curl command:
curl -JO http://localhost:18425/map/Artist%20Name/Artist%20Title/Song%20Title
The equivalent wget command:
wget --content-disposition "http://localhost:18425/map/Artist Name/Artist Title/Song Title"
For a quick start on the REST API, see REST/Quick Start.
To disable the REST API, set the config option rest to false OR pass --disable-rest via command line on start up.
Documentation
festivald will also serve this documentation.
To access it, start festivald and open the root link in a web browser:
http://localhost:18425
Or you can open the files locally with:
festivald --docs
To disable serving documentation, set the config option docs to false OR pass --disable-docs via command line on start up.
Quick Start
A quick start to using festivald and its JSON-RPC & REST APIs.
More JSON-RPC specific examples here, and more REST specific examples here.
Important things to know:
- The main music library/database in
festivaldis called theCollection - The
Collectionis created by scanning the filesystemfestivaldis running on - Everything revolves around the
Collection, you should create one before doing anything - In
festivald, there are "objects" that appear often, seeCommon Objectsfor more info
Launch festivald
Start festivald with no options:
./festivald
festivald will use a default configuration and open up on http://localhost:18425.
To view this documentation locally after starting festivald, you can open it in a web browser:
http://localhost:18425
Or you can open the files locally with:
./festivald --docs
Create a Collection with the JSON-RPC method collection_new
This scans the default Music directory on festivald's filesystem and creates a Collection from it.
festival-cli collection_new
OR
curl http://localhost:18425 -d '{"jsonrpc":"2.0","id":0,"method":"collection_new","params":{"paths":null}}'
Download a random Artist with the REST endpoint /rand/artist
Opening this link in a web browser will cause festivald to collect, organize, and archive all the Album's of a random Artist, and send it over.
http://localhost:18425/rand/artist
View metadata about a specific Album with the JSON-RPC method map_album
This will retrieve the Album "Cigarette & Alcohol" by the Artist "LUCKY TAPES".
festival-cli map_album --artist "LUCKY TAPES" --album "Cigarette & Alcohol"
OR
curl http://localhost:18425 -d '{"jsonrpc":"2.0","id":0,"method":"map_album","params":{"artist":"LUCKY TAPES","album":"Cigarette & Alcohol"}}'
The response looks like:
{
"jsonrpc": "2.0",
"result": {
"title": "Cigarette & Alcohol",
"key": 752,
"artist": 169,
"release": "2016-07-06",
"runtime": 2593,
"song_count": 10,
"songs": [
7611,
7616,
7618,
7619,
7620,
7621,
7622,
7623,
7624,
7626
],
"discs": 0,
"art": 1947006,
"genre": null
},
"id": 0
}
Search for an Artist with the JSON-RPC method search_artist
This will look up all Artist's in the Collection, and return the one that is the most similar (lexicographically) to the input "lUcKee TaPeZ":
festival-cli search_artist --input "lUcKee TaPeZ" --kind top1
OR
curl http://localhost:18425 -d '{"jsonrpc":"2.0","id":0,"method":"search_artist","params":{"input":"lUcKee TaPeZ","kind":"top1"}}'
We found "LUCKY TAPES":
{
"jsonrpc": "2.0",
"result": {
"artists": [
{
"name": "LUCKY TAPES",
"key": 169,
"runtime": 2593,
"albums": [
752
],
"songs": [
7611,
7616,
7618,
7619,
7620,
7621,
7622,
7623,
7624,
7626
]
}
]
},
"id": 0
}
Audio
Miscellaneous parts of festivald related to audio.
Audio Output Device
festivald automatically connects to the "default" audio output device on the machine it is running on.
If a connection failure occurs during playback, it will continue to play, frequently attempting to reconnect.
If started without any audio output devices available, it will attempt to reconnect every 5 seconds, forever.
Thus, reconnecting hardware/interfaces mid-playback should be fine.
This behavior is π΄ Unstable and may change in the future.
Ideally, an enumeration and customizable selection of all audio devices would be available.
Audio State
By default, festivald will save audio state upon clean shutdown (or CTRL+C/SIGINT), and recover audio state upon startup.
This means audio will start playing exactly where it left off, and the queue will be intact.
This can be disabled with the recover_audio_state config option or the --disable-restore-audio-state command-line flag.
Media Controls
By default, festivald will hook into the OS's native media controls to display some metadata and allow for playback via the OS's interface or via keyboard play/pause/stop/etc signals.
This can be disabled with the media_controls config option or the --disable-media-controls command-line flag.
Config
festivald reads and loads its configuration file festivald.toml on startup.
It controls various behaviors of festivald.
Exactly where this file is depends on the OS, more details in the Disk section.
Command Line flags will override any overlapping config values.
festivald.toml
This is the default configuration file festivald creates and uses.
If festivald is started with no --flags, e.g:
./festivald
Then it will be equivalent to this config file.
#================#
# festivald.toml #
#================================================================#
# This is `festivald`'s config file. #
# It is in the TOML (https://en.wikipedia.org/wiki/TOML) format. #
# #
# Values will be loaded from this file on startup. #
# If overlapping `--command-flags` are provided, #
# they will be used instead. #
# #
# For full documentation on config options, see: #
# <https://docs.festival.pm/daemon/config.html> #
#================================================================#
#----------------------------------------------------------#
# NETWORK #
#----------------------------------------------------------#
# The IPv4 address `festivald` will bind to.
#
# DEFAULT | "127.0.0.1"
# EXAMPLE | "192.168.2.10", "0.0.0.0"
# TYPE | IPv4 string
ip = "127.0.0.1"
# The port `festivald` bind to.
#
# Using port 0 will select a random port.
#
# DEFAULT | 18425
# EXAMPLE | 15000, 8080, 9999
# TYPE | 16-bit unsigned integer (0..65535)
port = 18425
# The max amount of connections `festivald`
# will serve at any given moment.
# `0` means unlimited.
#
# Note that 1 client doesn't necessarily mean
# 1 connection. A single web browser client for
# example can make many multiple connections
# to `festivald`.
#
# DEFAULT | 0
# EXAMPLE | 2, 4, 8, 16, 32, 64, 1000, 99999
# TYPE | unsigned integer
max_connections = 0
# `festivald` will only serve connections coming
# from these IPs. An empty array `[]` or an array
# containing "0.0.0.0" will serve all IP ranges.
#
# DEFAULT | []
# EXAMPLE | ["127.0.0.1", "192.168.2.10", "13.248.169.48"]
# TYPE | array of IPv4 addresses
exclusive_ips = []
# Upon a failed, potentially malicious request, instead of
# immediately responding, `festivald` will randomly sleep
# up to this many milliseconds before responding to the connection.
#
# This includes:
# - Authentication failure
# - IPs not in the `exclusive_ips` list
# - IPv6 connections
#
# If 0, `festivald` will immediately respond. This may
# not be wanted due to potential DoS and timing attacks.
#
# If you're hosting locally (127.0.0.1), you can set this
# to 0 (unless you don't trust your local network?).
#
# DEFAULT | 3000
# EXAMPLE | 0, 1000, 3000, 10000, 300000
# TYPE | unsigned integer
sleep_on_fail = 3000
#----------------------------------------------------------#
# COLLECTION #
#----------------------------------------------------------#
# Upon a `collection_new` JSON-RPC method call, if the
# `paths` parameter is empty, these PATHs will be scanned
# instead.
#
# If this is also empty, the default OS `Music`
# directory will be scanned.
#
# Windows-style PATHs will only work if `festivald`
# is running on Windows (`C:\\Users\\User\\Music`)
#
# DEFAULT | []
# EXAMPLE | ["/home/user/Music/albums", "/home/user/data/songs"]
# TYPE | array of PATHs
collection_paths = []
#----------------------------------------------------------#
# TLS #
#----------------------------------------------------------#
# Enable/disable HTTPS.
#
# You must also provide a PEM-formatted X509 certificate and key
# in the below options for this to work.
#
# DEFAULT | false
# VALUES | true, false
# TYPE | boolean
tls = false
# The PEM-formatted X509 certificate used for TLS.
#
# DEFAULT | ""
# EXAMPLE | "/my/path/to/cert.pem"
# TYPE | PATH string
certificate = ""
# The PEM-formatted key for the above X509 certificate.
#
# DEFAULT | ""
# EXAMPLE | "/my/path/to/key.pem"
# TYPE | PATH string
key = ""
#----------------------------------------------------------#
# API #
#----------------------------------------------------------#
# Enable/disable the REST API.
# This is responsible for the `/rest` API that
# serves image, audio, and other heavy resource data.
#
# Setting this to `false` will disable this part
# of the system, and will only leave the JSON-RPC
# API available.
#
# DEFAULT | true
# VALUES | true, false
# TYPE | boolean
rest = true
# Enable/disable serving documentation.
#
# By default, `festivald` serves a markdown book
# of it's own documentation, accessible at the
# root `/` endpoint, e.g:
# ```
# http://localhost:18425/
# ```
#
# Setting this to `false` will disable that.
#
# DEFAULT | true
# VALUES | true, false
# TYPE | boolean
docs = true
# Enable/disable inlined resources for the REST API.
#
# By default, accessing the REST API via a
# browser will open the resource inlined within
# the browser, if possible.
#
# Setting this to true will make browsers download
# the file directly, instead of opening it.
#
# Currently this only supports art, although in
# the future it will most likely support song files
# opening up as inline mini-players in the browser.
#
# DEFAULT | false
# VALUES | true, false
# TYPE | boolean
direct_download = false
# When files are downloaded via the REST API, and the
# file is a nested object referencing multiple things
# (e.g, an _album_ owned by an _artist_), we must include
# that information, but what string should separate them?
#
# The default separator is " - ", e.g:
# ```
# Artist Name - Album Title.zip
# ```
# it can be changed to any string, like "/":
# ```
# Artist Name/Album Title.zip
# ```
# or left empty "" for no separator at all.
#
# This cannot include a slash: `/`
# as that is the legal PATH separator in ZIP files.
#
# DEFAULT | " - "
# EXAMPLE | " --- ", "_", ""
# TYPE | string
filename_separator = " - "
#----------------------------------------------------------#
# LOGGING #
#----------------------------------------------------------#
# The logging level `festivald` will use.
#
# "error" will only show critical error messages,
# "warn" will in addition show warnings,
# "info" will in addition show info, etc, etc.
#
# DEFAULT | "error"
# VALUES | "off", "error", "warn", "info", "debug", "trace"
# TYPE | string, one of the above
log_level = "error"
#----------------------------------------------------------#
# FILESYSTEM #
#----------------------------------------------------------#
# Enable/disable watching the filesystem for signals
#
# Other than RPC calls, `festivald` can send signals
# to another local `festivald`, e.g:
# `./festivald --play`
#
# The way this is done is by creating a file
# in Festival's `signal` directory.
#
# `./festivald --FLAG` just creates a file in that directory,
# which an existing Festival will notice and do the appropriate task.
#
# Setting this to `false` will disable that part of the system so that
# filesystem signals won't work, e.g, `./festivald --play` will not work.
#
# DEFAULT | true
# VALUES | true, false
# TYPE | boolean
watch = true
# Enable/disable cleaning up cache
#
# When serving `ZIP` files via the REST API, `festivald`
# will first write them to disk, then serve those files
# instead of directly storing everything in memory,
# as to not get OOM-killed on more than a few requests.
#
# Setting this to `false` will make `festivald`
# never clean those files up, ever.
#
# This will make `cache_time` not do anything and will
# also prevent `festivald` from the usual startup/shutdown
# cache cleaning that it does.
#
# DEFAULT | true
# VALUES | true, false
# TYPE | boolean
cache_clean = true
# Set the REST API cache time limit
#
# This option sets the time limit on how many seconds
# `festivald` will hold onto this cache for.
#
# Once the time limit is up, `festivald` will remove the
# file. This cache is also reset on startup and shutdown.
#
# This does nothing if `cache_clean` is `false`.
#
# DEFAULT | 3600 (1 hour)
# EXAMPLE | 60 (1 minute), 600 (10 minutes), 1800 (30 minutes), 14400 (4 hours)
# TYPE | unsigned integer
cache_time = 3600
#----------------------------------------------------------#
# AUDIO #
#----------------------------------------------------------#
# Enable/disable audio state restoration
#
# Upon startup, `festivald` will recover audio state
# (volume, exact position in song, queue, etc) if this
# setting is `true`.
#
# DEFAULT | true
# VALUES | true, false
# TYPE | boolean
restore_audio_state = true
# Reset threshold for the `previous` JSON-RPC method
#
# The `previous` method comes with an optional
# `threshold` parameter that specifies:
#
# ```
# If the current `Song` runtime (seconds) has passed this number,
# this method will reset the current `Song` instead of skipping backwards.
# Setting this to `0` will make this method always go to the previous `Song`.
# ```
#
# But if that parameter is `null`, this option
# will be used instead. The default if not
# specified here is 3 seconds.
#
# For example:
# - A song is 3+ seconds in
# - A `previous` method was received
# - It will reset the current song instead of going back
#
# Setting this to `0` will make `previous`
# always go back if `threshold` is not specified.
#
# DEFAULT | 3
# VALUES | 0, 3, 5, 100
# TYPE | unsigned integer
previous_threshold = 3
# Enable/disable OS media controls
#
# `festivald` plugs into the native OS's media controls so that signals
# like `play/pause/stop` and/or keyboard controls can be processed.
#
# Setting this to `false` will disable media controls.
#
# DEFAULT | true
# VALUES | true, false
# TYPE | boolean
media_controls = true
#----------------------------------------------------------#
# AUTHORIZATION #
#----------------------------------------------------------#
# Only process connections to `festivald` that have a
# "authorization" HTTP header with this username and password.
#
# If either the `no_auth_rpc` or `no_auth_rest` options are
# used, then every RPC call/REST endpoint _NOT_ in those lists
# will require this authorization.
#
# TLS must be enabled for this feature to work
# or `festivald` will refuse to start.
#
# To set authorization EVEN IF TLS IS DISABLED,
# See `--confirm-no-tls-auth`.
#
# This value must be:
# 1. The "username"
# 2. Followed by a single colon ":"
# 3. Then the "password", e.g:
# ```
# curl -u my_user:my_pass https://127.0.0.1:18425
# ```
# or the equivalent wget command:
# ```
# wget --user my_user --password my_pass https://localhost:18425
# ```
#
# An empty string disables this feature.
#
# Alternatively, you can input an absolute PATH to a file
# `festivald` can access, containing the string, e.g:
# ```
# authorization = "/path/to/user_and_pass.txt"
# ```
# In this case, `festivald` will read the file and attempt
# to parse it with the same syntax, i.e, the file should contain:
# ```
# my_user:my_pass
# ```
#
# DEFAULT | "" (disabled)
# EXAMPLE | "my_username:my_password", "my_username:aoig2A%^$AWS^%", "/path/to/file"
# TYPE | string or PATH to file
authorization = ""
# Allow authorization even without TLS
#
# This will let you set the authorization
# setting even if TLS is disabled.
#
# This means your `user:pass` will be sent in clear-text HTTP,
# unless you are wrapping HTTP in something else, like SSH
# port forwarding, or Tor.
#
# DEFAULT | false
# VALUES | true, false
# TYPE | boolean
confirm_no_tls_auth = false
# Allow specified JSON-RPC calls without authorization,
# while still requiring authorization for everything else.
#
# If a JSON-RPC method is listed in this array,
# `festivald` will allow any client to use it,
# regardless of authorization.
#
# This allows you to have `authorization` enabled
# across the board, but allow specific JSON-RPC
# calls for public usage.
#
# For example, if only `toggle` is listed, then
# clients WITHOUT authorization will only be
# allowed to use the `toggle` method, for every
# other method, they must authenticate.
#
# The method names listed here must match the
# exact names when using them, or shown in the
# documentation, see here:
#
# <https://docs.festival.pm/daemon/json-rpc/json-rpc.html>
#
# OR WITH
#
# ```
# festivald data --docs
# ```
# DEFAULT | [] (disabled)
# EXAMPLE | ["toggle", "state_audio", "volume"]
# TYPE | string, must be a method name
no_auth_rpc = []
# Allow specified REST resources without authorization,
# while still requiring authorization for everything else.
#
# REST resources:
# - `collection`
# - `playlist`
# - `artist`
# - `album`
# - `song`
# - `art`
#
# If a REST resource is listed in this array,
# `festivald` will allow any client to use it,
# regardless of authorization.
#
# For example, if only `art` is listed, then
# clients WITHOUT authorization will only be
# allowed to use the `art` related endpoints
# (/rand/art, /current/art, etc). For every
# other endpoint (/rand/song, /collection, etc),
# they must authenticate.
#
# DEFAULT | [] (disabled)
# EXAMPLE | ["art", "song", "album"]
# TYPE | string, must be a REST resource
no_auth_rest = []
# Allow documentation to be served without authorization,
# while still requiring authorization for everything else.
#
# DEFAULT | false
# VALUES | true, false
# TYPE | boolean
no_auth_docs = false
Disk
festivald saves all of its files within various "User OS" directories, owned by the user running it.
You can list all the PATHs on your system with:
./festivald --path
And delete them with with:
./festivald --delete
festivald saves everything into daemon/ because other Festival frontends also use the same festival project directory, e.g:
~/.local/share/festival/
ββ gui/
ββ daemon/
ββ cli/
Cache
Where festivald's cache data is saved (REST ZIP cache, etc).
| Platform | Value | Example |
|---|---|---|
| Windows | {FOLDERID_LocalAppData}\Festival\cache\daemon | C:\Users\Alice\AppData\Local\Festival\cache\daemon |
| macOS | $HOME/Library/Caches/Festival/daemon | /Users/Alice/Library/Caches/Festival/daemon |
| Linux | $HOME/.cache/festival/daemon | /home/alice/.cache/festival/daemon |
The Cache sub-directories/files, and their purpose:
ββ daemon/
β
ββ zip/ # Cached ZIP files
β
ββ collection/ # Cached `Collection` ZIPs, created by the `/collection` REST endpoint
β β
β ββ tmp/ # Temporary, un-finished ZIP files
β
ββ playlist/ # Cached `Playlist` ZIPs, created by the `/playlist/*` REST endpoints
β β
β ββ tmp/
β
ββ artist/ # Cached `Artist` ZIPs, created by the `*_artist` REST endpoints
β β
β ββ tmp/
β
ββ album/ # Cached `Artist` ZIPs, created by the `*_album` REST endpoints
β β
β ββ tmp/
β
ββ art/ # Cached `Artist` ZIPs, created by the `art_*` REST endpoints
β β
β ββ tmp/
Config
Where festivald's configuration files are saved.
| Platform | Value | Example |
|---|---|---|
| Windows | {FOLDERID_RoamingAppData}\Festival\config\daemon | C:\Users\Alice\AppData\Roaming\Festival\config\daemon |
| macOS | $HOME/Library/Application Support/Festival/daemon | /Users/Alice/Library/Application Support/Festival/daemon |
| Linux | $HOME/.config/festival/daemon | /home/alice/.config/festival/daemon |
The Config sub-directories/files, and their purpose:
ββ daemon/
β
ββ festivald.toml # Config file used by `festivald`
Data
Where festivald's main data is saved (the Collection, audio state, etc).
| Platform | Value | Example |
|---|---|---|
| Windows | {FOLDERID_RoamingAppData}\Festival\data\daemon | C:\Users\Alice\AppData\Roaming\Festival\data\daemon |
| macOS | $HOME/Library/Application Support/Festival/daemon | /Users/Alice/Library/Application Support/Festival/daemon |
| Linux | $HOME/.local/share/festival/daemon | /home/alice/.local/share/festival/daemon |
The Data sub-directories/files, and their purpose:
ββ daemon/
β
ββ state/
β ββ audio.bin # Audio state, e.g: elapsed time, current song.
β ββ collection.bin # The main music `Collection`, holds metadata and PATHs to audio files.
β ββ playlists.bin # The `Playlists` database, holds all playlist data
β
ββ txt/
β ββ crash.txt # Crash/panic data. Useful for bug reports.
β ββ perf.json # Collection creation performance timings, in JSON.
β
ββ docs/ # The static documentations files served by `festivald`
β
ββ image/ # Full-sized, un-changed `Album` art
β
ββ signal/ # This is how `festivald` communicates with an existing one
# (e.g `festivald signal --play`), via filesystem-based signals.
# `festivald signal --play` quite literally just creates an empty
# file inside this folder called `play`.
Tor
Like other web services, festivald can be set-up & accessed via Tor.
A public instance of festivald with Creative Commons licensed music is available at:
https://daemon.festival.pm
and its Onion Service is available at:
http://omjo63yjj66ga7jlvhqib4z4qgx6y6oigjcpjcr5ehhfdugfuami3did.onion
Onion Service
festivald doesn't have special integration with Tor, but it can easily be turned into an Onion Service.
After getting festivald setup normally, follow the Onion Service instructions here.
Your torrc should look something like:
HiddenServiceDir /var/lib/tor/festivald
HiddenServicePort 80 127.0.0.1:18425
And in /var/lib/tor/festivald, you should have your onion service hostname, keys, etc.
This onion service will allow you to interact with festivald in all the normal ways, although, you must connect to it via Tor.
JSON-RPC
To use festivald's JSON-RPC API over Tor, your HTTP client must either use a proxy, or be wrapped with torsocks.
ONION="http://omjo63yjj66ga7jlvhqib4z4qgx6y6oigjcpjcr5ehhfdugfuami3did.onion"
festival-cli
--proxy socks5://127.0.0.1:9050 \ # The Tor SOCKS5 proxy.
--festivald $ONION \ # The onion address mapped to `festivald`
daemon_state # Method
# or with `torsocks`
torsocks festival-cli -f $ONION daemon_state
ONION="http://omjo63yjj66ga7jlvhqib4z4qgx6y6oigjcpjcr5ehhfdugfuami3did.onion"
curl \
--socks5-hostname 127.0.0.1:9050 \ # The Tor SOCKS5 proxy.
--festivald $ONION \ # The onion address mapped to `festivald`
-d '{"jsonrpc":"2.0","id":0,"method":"daemon_state"}' # Method
REST
For the REST API, it is the same: your HTTP client must connect over Tor.
Although you could just use Tor Browser.
http://omjo63yjj66ga7jlvhqib4z4qgx6y6oigjcpjcr5ehhfdugfuami3did.onion/map/Ludwig van Beethoven/Moonlight Sonata 1/Moonlight Sonata Op. 27, No. 2 In C Sharp Minor: Allegretto
The equivalent curl command:
ONION="http://omjo63yjj66ga7jlvhqib4z4qgx6y6oigjcpjcr5ehhfdugfuami3did.onion"
SOCKS="127.0.0.1:9050"
curl --socks5-hostname $SOCKS -JO $ONION/map/Artist%20Name/Artist%20Title/Song%20Title
Authentication
Since Onion Service's are end-to-end encrypted, HTTPS is not required.
Thus, festivald can freely pass authentication tokens around when used as an Onion Service.
Although, since festivald cannot know if an onion address is being mapped to it, you must pass:
festivald --confirm-no-tls-auth
or set the confirm_no_tls_auth configuration to confirm that you allow authentication without TLS.
If the IP festivald is binding to is localhost/127.0.0.1, this setting will be enabled by default.
For festival-cli, it will automatically detect if you're connecting to an onion address and will allow authentication.
systemd
This is a relatively hardened systemd service file for festivald.
${USER} should be replaced by a user that has access to an audio server (like PulseAudio).
It should be placed at:
/etc/systemd/system/festivald.service
and launched with:
sudo systemctl start festivald
festivald.service
#===================#
# festivald.service #
#=======================================================#
# This is a systemd user service file for `festivald`. #
# It is relatively hardened for public usage. #
# #
# ${USER} should be replaced by a user that has #
# access to an audio server (like PulseAudio). #
#=======================================================#
[Unit]
Description=Festival Daemon
After=network-online.target
StartLimitIntervalSec=300
StartLimitBurst=5
[Service]
User=${USER} # <- Replace Me
Type=simple
ExecStart=/usr/bin/festivald
## Wait 35 seconds before sending SIGTERM on exit
KillSignal=SIGTERM
TimeoutStopSec=35s
SendSIGKILL=true
## Hardening
CapabilityBoundingSet=~CAP_NET_ADMIN CAP_SYS_PTRACE CAP_SYS_ADMIN CAP_KILL CAP_SYS_PACCT CAP_SYS_BOOT CAP_SYS_CHROOT CAP_LEASE CAP_MKNOD CAP_CHOWN CAP_FSETID CAP_SETFCAP CAP_SETUID CAP_SETGID CAP_SETPCAP CAP_SYS_TIME CAP_IPC_LOCK CAP_LINUX_IMMUTABLE CAP_FOWNER CAP_IPC_OWNER CAP_SYS_RESOURCE
RestrictNamespaces=true
ProtectHostname=true
ProtectClock=true
ProtectKernelModules=true
ProtectKernelLogs=true
ProtectProc=invisible
ProcSubset=pid
ProtectControlGroups=true
ProtectKernelTunables=true
PrivateUsers=true
NoNewPrivileges=true
PrivateTmp=true
ProtectSystem=strict
[Install]
WantedBy=default.target
Command Line
festivald takes in --flags for many purposes.
Arguments passed to festivald will always take priority over the same configuration options read from disk.
festivald also has a signal sub-command. For example, to send a signal to a festivald running on the same local machine, you can run:
./festivald signal --play
All these "signal"-related --flags live in the signal sub-command.
Examples
Here are some command-line usage examples.
Start festivald on http://localhost:18425 (by default)
./festivald
Print the PATH used by festivald
./festivald --path
Delete all data created/used by festivald
./festivald --delete
Set log level, disable everything except JSON-RPC, start festivald
./festivald --log-level DEBUG --disable-watch --disable-media-controls --disable-rest --disable-docs
Top-level flags
Usage: festivald [OPTIONS] [COMMAND + OPTIONS] [ARGS...]
Arguments passed to `festivald` will always take
priority over configuration options read from disk.
Commands:
signal Send a signal to a `festivald` running on the same machine
help Print this message or the help of the given subcommand(s)
Options:
--ip <IP>
The IPv4 address `festivald` will bind to [default: 127.0.0.1]
--port <PORT>
The port `festivald` will bind to [default: 18425]
Using port `0` will select a random port.
--max-connections <NUMBER>
Max amount of connections [default: unlimited]
The max amount of connections `festivald`
will serve at any given moment.
`0` means unlimited.
Note that 1 client doesn't necessarily mean
1 connection. A single web browser client for
example can make many multiple connections
to `festivald`.
--exclusive-ip <IP>
Only accept connections from these IPs
`festivald` will only serve connections coming
from these IPs. If there's no value given or
any of the values is "0.0.0.0", `festivald`
will serve all IP ranges.
To allow multiple IPs, use this flag per IP.
Example: `festivald --exclusive-ip 127.0.0.1 --exclusive-ip 192.168.2.1`
--tls
Enable HTTPS
You must also provide a PEM-formatted X509 certificate
and key in the below options for this to work.
Example: `festivald --tls --certificate /path/to/cert.pem --key /path/to/key.pem`
--certificate <FILE>
The PEM-formatted X509 certificate file used for TLS
--key <FILE>
The PEM-formatted key file used for TLS
--authorization <USER:PASS or FILE>
Enforce a `username` and `password` for connections to `festivald`
Only process connections to `festivald` that have a
"authorization" HTTP header with this username and password.
If either the `--no-auth-rpc` or `--no-auth-rest` options are
used, then every RPC call/REST endpoint _NOT_ in those lists
will require this authorization.
TLS must be enabled or `festivald` must be started
on `localhost` for this feature to work or `festivald`
will refuse to start.
To set authorization EVEN IF TLS IS DISABLED,
See `--confirm-no-tls-auth`.
This value must be:
1. The "username"
2. Followed by a single colon ":"
3. Then the "password", e.g:
```
festivald --authorization my_user:my_pass
```
An empty string disables this feature.
Alternatively, you can input an absolute PATH to a file
`festivald` can access, containing the string, e.g:
```
festivald --authorization "/path/to/user_and_pass.txt"
```
In this case, `festivald` will read the file and attempt
to parse it with the same syntax, i.e, the file should contain:
```
my_user:my_pass
```
--confirm-no-tls-auth
Allow `--authorization` even without TLS
This will let you set the authorization
setting even if TLS is disabled.
This means your `user:pass` will be sent in clear-text HTTP,
unless you are wrapping HTTP in something else, like SSH
port forwarding, or Tor.
--no-auth-rpc <METHOD>
Allow specified JSON-RPC calls without authorization
If a JSON-RPC method is listed in this array,
`festivald` will allow any client to use it,
regardless of authorization.
This allows you to have `authorization` enabled
across the board, but allow specific JSON-RPC
calls for public usage.
For example, if only `toggle` is listed, then
clients WITHOUT authorization will only be
allowed to use the `toggle` method, for every
other method, they must authenticate.
The method names listed here must match the
exact names when using them, or shown in the
documentation, see here:
<https://docs.festival.pm/daemon/json-rpc/json-rpc.html>
OR WITH
```
festivald data --docs
```
To allow multiple methods, use this flag per method.
Example: `festivald --no-auth-rpc toggle --no-auth-rpc volume`
--no-auth-rest <RESOURCE>
Allow specified REST resources without authorization
REST resources:
- `collection`
- `playlist`
- `artist`
- `album`
- `song`
- `art`
If a REST resource is listed in this array,
`festivald` will allow any client to use it,
regardless of authorization.
For example, if only `art` is listed, then
clients WITHOUT authorization will only be
allowed to use the `art` related endpoints
(/rand/art, /current/art, etc). For every
other endpoint (/rand/song, /collection, etc),
they must authenticate.
To allow multiple methods, use this flag per method.
Example: `festivald --no-auth-rest art --no-auth-rest song`
--no-auth-docs
Allow documentation to be served without authorization
--sleep-on-fail <MILLI>
Sleep before responding to a (potentially malicious) failed connections
Upon a failed, potentially malicious request, instead of
immediately responding, `festivald` will randomly sleep
up to this many milliseconds before responding to the connection.
This includes:
- Authentication failure
- IPs not in the `exclusive_ips` list
- IPv6 connections
If 0, `festivald` will immediately respond. This may
not be wanted to due potential DoS and timing attacks.
If you're hosting locally (127.0.0.1), you can set this
to 0 (unless you don't trust your local network?).
--collection-path <PATH>
Default PATHs to use for the `Collection`
Upon a `collection_new` JSON-RPC method call, if the
`paths` parameter is empty, these PATHs will be scanned
instead.
If this is not set, the default OS `Music` directory will be scanned.
If `festivald` is running on Windows, you can use
Windows-style PATHs: `C:\\Users\\User\\Music`.
To set multiple PATHs, use this flag per PATH.
Example: `festivald --collection-path /my/path/1 --collection-path /my/path/2`
--direct-download
Enable direct downloads via the REST API for browsers
By default, accessing the REST API via a browser
will open the resource in the browser (audio player,
image viewer, etc)
Using this flag will make browsers download
the file directly, without opening it.
--filename-separator <SEPARATOR>
When files are downloaded via the REST API, and the
file is a nested object referencing multiple things
(e.g, an _album_ owned by an _artist_), we must include
that information, but what string should separate them?
The default separator is " - ", e.g:
```
Artist Name - Album Title.zip
```
it can be changed to any string, like "/":
```
Artist Name/Album Title.zip
```
or left empty "" for no separator at all.
This cannot include a slash: `/`
as that is the legal PATH separator in ZIP files.
--disable-cache-clean
Enable/disable cleaning up cache
When serving `ZIP` files via the REST API, `festivald`
will first write them to disk, then serve those files
instead of directly storing everything in memory,
as to not get OOM-killed on more than a few requests.
Setting this to `false` will make `festivald`
never clean those files up, ever.
This will make `cache_time` not do anything and will
also prevent `festivald` from the usual startup/shutdown
cache cleaning that it does.
--cache-time <SECONDS>
Set the REST API cache time limit
This option sets the time limit on how many seconds
`festivald` will hold onto this cache for.
Once the time limit is up, `festivald` will remove the
file. This cache is also reset on startup and shutdown.
This does nothing if `--disable-cache-clean` is passed.
--disable-restore-audio-state
Disable audio state restoration
Upon startup, `festivald` (by default) will recover
audio state (volume, exact position in song, queue, etc).
Using this option disables this.
--disable-watch
Disable watching the filesystem for signals
The way a newly launched `festivald` communicates to
an already existing one (e.g, `festivald signal --play`) is
by creating a file in `festivald`'s `signal` directory.
`festivald signal --FLAG` just creates a file in that directory,
which an existing `festivald` will notice and do the appropriate task.
Using `--disable-watch` will disable that part of the system so that
filesystem signals won't work, e.g, `festivald signal --play` will not work.
--disable-media-controls
Disable OS media controls
`festivald` plugs into the native OS's media controls so that signals
like `play/pause/stop` and/or keyboard controls can be processed.
`--disable-media-controls` disables this.
--disable-rest
Disable the REST API
This is responsible for the `/rest` API that
serves image, audio, and other heavy resource data.
`--disable-rest` will disable this part of the system,
and will only leave the JSON-RPC API available.
--disable-docs
Enable/disable serving documentation
By default, `festivald` serves a markdown book
of it's own documentation, accessible at the
root `/` endpoint, e.g:
```
http://localhost:18425/
```
`--disable-docs` will disable that.
--log-level <OFF|ERROR|INFO|WARN|DEBUG|TRACE>
Set filter level for console logs
--dry-run
Print the configuration `festivald` would have used, but don't actually startup
This will go through the regular process of:
- Reading disk for config
- Reading command-line
- Merging options together
- Validating options
and then print them out as JSON, and exit.
--docs
Open documentation locally in browser
This opens `festivald'`s documentation in a web
browser, and does not start `festivald` itself.
--path
Print the PATHs used by `festivald`
All data saved by `festivald` is saved in these directories.
For more information, see: <https://docs.festival.pm/daemon/disk.html>
--reset-config
Reset the current `festivald.toml` config file to the default
Exits with `0` if everything went ok, otherwise shows error.
--reset-cache
Reset the `festivald` cache folder
This deletes all currently existing `REST` resource cache.
--delete
Delete all `festivald` files that are on disk
This deletes all `daemon` Festival folders.
The PATHs deleted will be printed on success.
--methods
Print all the JSON-RPC methods available
-v, --version
Print version
-h, --help
Print help (see a summary with '-h')
Sub-command: signal
Send a signal to a `festivald` running on the same machine
This will not start a new `festivald`, but send a
signal to an already running one. This only works
if there's a `festivald` already running on the
same machine.
The flag `--disable-watch` disables this feature.
Usage: festivald signal OPTION [ARG]
Options:
--play
Start playback
--pause
Pause playback
--toggle
Toggle playback (play/pause)
--next
Skip to next track
--previous
Play previous track
--stop
Clear queue and stop playback
--clear
Clear queue but don't stop playback
--shuffle
Shuffle the current queue and reset to the first song
--repeat-song
Turn on single `Song` track repeat
--repeat-queue
Turn on queue repeat
--repeat-off
Turn off repeating
--volume <VOLUME>
Set the volume to `VOLUME` (0-100)
--seek <SECOND>
Seek to the absolute `SECOND` second in the current song
--seek-forward <SECOND>
Seek `SECOND` seconds forwards in the current song
--seek-backward <SECOND>
Seek `SECOND` seconds backwards in the current song
--index <NUMBER>
Set the current song to the index `NUMBER` in the queue.
NOTE:
The queue index starts from 1 (first song is `--index 1`).
Providing an index that is out-of-bounds
will end the queue (even if repeat is turned on).
--skip <NUMBER>
Skip `NUMBER` amount of songs
If the last song in the queue is skipped over,
and queue repeat is turned on, this will reset
the current song to the 1st in the queue.
--back <NUMBER>
Go backwards in the queue by `NUMBER` amount of songs
If `NUMBER` is greater than the amount of songs we can
skip backwards, this will reset the current song to
the 1st in the queue.
-h, --help
Print help (see a summary with '-h')
Authorization
festivald has a Basic access authentication option in its configuration, with a username + password setup.
An optional bypass is available on specified JSON-RPC methods, REST resources, and documentation.
If authorization is enabled, festivald will only process connections to it that have the "authorization" HTTP header with this username and password (unless specified in the bypass options).
TLS must be enabled for this feature to work or festivald will refuse to start.
However, there are cases where authorization without TLS is okay (reverse proxy, Tor Onion Service, etc). In these cases, the confirm_no_tls_auth option will allow authorization without TLS.
If festivald is started on localhost (127.0.0.1), it will allow authorization without TLS as well.
authorization can either be set in the config file or passed via a command-line flag.
Syntax
The username & password syntax is specified in RFC 7617.
The "authorization" value must be:
- The username
- Followed by a single colon ":"
- Then the password
For example:
my_user:my_pass
A request including this information looks like:
curl -u my_user:my_pass https://127.0.0.1:18425
or the equivalent wget command:
wget --user my_user --password my_pass --auth-no-challenge https://localhost:18425
or the equivalent festival-cli command:
festival-cli -u my_user -p my_pass https://localhost:18425
Alternatively, you can input an absolute PATH to a file festivald can access, containing the string, e.g:
authorization = "/path/to/user_and_pass.txt"
In this case, festivald will read the file and attempt to parse it with the same syntax, i.e, the file should contain:
my_user:my_pass
RFC 7617
Note that curl, wget and festival-cli all follow RFC 7617, as in, they craft their HTTP authorization header to be:
Basic <user:pass in base64>
So these commands:
# Curl
curl -u user:pass https://localhost:18425
# Wget
wget --user=user --password=pass --auth-no-challenge https://localhost:18425
# festival-cli
festival-cli -u user:pass https://localhost:18425
sends this as the HTTP authorization header:
Basic dXNlcjpwYXNz
If you are creating a client for festivald, you must do this for authorization as well.
Web Browser
If connecting to festivald via a web browser, you will receive a visual prompt for authorization:

JSON-RPC
The no_auth_rpc config option or --no-auth-rpc command-line flag will allow specified JSON-RPC calls without authorization, while still requiring authorization for everything else.
If a JSON-RPC method is listed in these options festivald will allow any client to use it, regardless of authorization.
This allows you to have authorization enabled across the board, but allow specific JSON-RPC calls for public usage.
Usage
The method names in the option must match the exact names of the actual methods.
For example:
If a specified method name is incorrect, festivald will not start.
Example
For example, if toggle is listed, then ALL clients will be allowed to use the toggle method, for every other method, they must authenticate.
festivald.toml:
authorization = "user:pass"
no_auth_rpc = ["toggle"]
Unauthorized client:
# Even though we didn't specify `-u user:pass`,
# `festivald` will accept this RPC call.
curl https://localhost:18425 -d '{"jsonrpc":"2.0","id":0,"method":"toggle"}'
# But not this one.
curl https://localhost:18425 -d '{"jsonrpc":"2.0","id":0,"method":"stop"}'
Authorized client:
# This _does_ have authentication,
# so it can do whatever it wants.
curl https://localhost:18425 -u user:pass -d '{"jsonrpc":"2.0","id":0,"method":"stop"}'
REST
The no_auth_rest config option or --no-auth-rest command-line flag will allow specified REST resources without authorization, while still requiring authorization for everything else.
If a REST resource is listed in these options festivald will allow any client to access it, regardless of authorization.
This allows you to have authorization enabled across the board, but allow specific REST resources for public usage.
Usage
The specified REST resources must be one of these string's:
REST resource | Allows | Example endpoint |
|---|---|---|
collection | Access to downloading the whole Collection | /collection |
playlist | Access to downloading Playlist ZIPs | /playlist |
artist | Access to downloading Artist ZIPs | /current/artist, /map/artist |
album | Access to downloading Album ZIPs | /current/album, /map/album |
song | Access to downloading Song files | /current/song, /map/song |
art | Access to downloading Art ZIPs & files | /current/art, /art/artist |
If a specified REST resource name is incorrect, festivald will not start.
Example
For example, if the value is ["art", "song"], ALL clients will be allowed to use the art and song-related endpoints, for all other endpoints, they must authenticate.
festivald.toml:
authorization = "user:pass"
no_auth_rest = ["art", "song"]
Unauthorized client:
# Even though we didn't specify `-u user:pass`,
# `festivald` will let us download some art.
curl https://localhost:18425/rand/art
# And some song files.
curl https://localhost:18425/rand/song
# BUT it will not let us download whole albums.
curl https://localhost:18425/rand/album
# Or playlists.
curl https://localhost:18425/playlist/sorted/Playlist 1
Authorized client:
# This _does_ have authentication,
# so it can do whatever it wants.
curl https://localhost:18425/rand/album -u user:pass
curl https://localhost:18425/playlist/sorted/Playlist 1 -u user:pass
Documentation
The no_auth_docs config option or --no-auth-docs command-line flag will allow documentation to be served without authorization, while still requiring authorization for everything else.
Example
festivald.toml:
authorization = "user:pass"
no_auth_docs = true
Unauthorized client:
# Even though we didn't specify `-u user:pass`,
# `festivald` will let us download/read docs.
curl https://localhost:18425
# BUT if `REST` requires authentication, this will not work.
curl https://localhost:18425/rand/album
Authorized client:
# This _does_ have authentication,
# so it can do whatever it wants.
curl https://localhost:18425/rand/album -u user:pass
API Stability
Some notes on what parts of festivald's API can/cannot be relied upon.
In general - things may be added, but never removed.
If something is unstable, it will be marked as such.
Anything that feels like an API but isn't explicitly marked in festivald's documentation should be assumed to be π΄ Unstable.
Breaking Changes
Breaking changes to the stable API may occur in 3 situations:
festivald v2.0.0release- There is a fundamental/security bug that must be fixed in
festivald - There is a difference between this documentation and the actual
festivaldinput/output
These will be noted in release notes if they ever occur.
Marker
In the documentation for all Objects, JSON-RPC methods, and REST endpoints there will be a "marker" defining the stability of that API. It will be 1 of the 4 listed markers here.
π’ Stable
This marks that this API's input/output will never change, and can be relied upon.
π‘ Incomplete
This marks that the output of this API may have additions in the future.
The existing inputs/outputs will not change, however, additional output may appear.
π΄ Unstable
This marks that this API may in the future:
- Have additions to input/output
- Have subtractions to input/output
- Be renamed
- Be completely removed
It should not be relied across different festivald versions.
β«οΈ Deprecated
This marks that this API has been superseded by a better one.
The old API will continue to exist, but it is recommended to use the newer one.
JSON-RPC
JSON-RPC-specific API stability edge cases.
Naming
All method names, parameter names, and field names are in lower_case_snake_case.
This is π’ Stable.
Ordering
The ordering of non-stable output/object fields is π΄ Unstable.
The ordering of π’ Stable output/object fields is π’ Stable.
Old v1.0.0 JSON-RPC example:
// π‘ Incomplete Response
{
"jsonrpc": "2.0",
"result": {
"field1": "Output field 1",
"field2": "Output field 2"
},
"id": 0,
}
// π’ Stable Response
{
"jsonrpc": "2.0",
"result": {
"field1": "Output field 1", // Will always be 1, then 2.
"field2": "Output field 2"
},
"id": 0,
}
New v1.1.0 JSON-RPC example:
// π‘ Incomplete Response
{
"jsonrpc": "2.0",
"result": {
"field3": "Output field 3", // Ordering may
"field1": "Output field 1", // shift around
"field4": "Output field 4", // on incomplete
"field2": "Output field 2" // methods.
},
"id": 0,
}
// π’ Stable Response
{
"jsonrpc": "2.0",
"result": {
"field1": "Output field 1", // Still 1, 2.
"field2": "Output field 2"
},
"id": 0,
}
REST
REST-specific API stability edge cases.
ZIP
- For
RESTendpoints that serve large collections of files, theZIPformat will be used - There is no compression applied to the files, they are stored as-is
- These ZIPs can be found the in
Cachefolder with the exact same name as sent to the client
These points are all π’ Stable.
ZIP /
ZIP files cannot have internal filenames with /, as that is the legal PATH separator, so all:
- File names
PlaylistnamesArtistnamesAlbumtitlesSongtitles
inside ZIPs that contain / will always be replaced with a single dash with no spaces: -
This also applies to the filename_separator, it cannot include /.
Example:
Artist/With/Slash.zip # This is fine, the actual ZIP filename will be quoted.
β
ββArtist/With/Slash # This will be turned into `Artist-With-Slash`
β
ββ Album With//Slashes # This will be turned into `Album With--Slashes`
β
ββ Song With/A Slash # This will be turned into `Song With-A Slash`
This is π΄ Unstable. The behavior may change in the future.
Duplicate Filenames
When packaging Song's into ZIPs, if there a multiple Song's with the same name in the same Album, it will be suffixed with an incrementing number in parentheses starting from 1.
For example:
My Song.flac
My Song (1).flac
My Song (2).flac
My Song (3).flac
This is π΄ Unstable. The behavior may change in the future.
File Format & Names
The file format type and names of those files1 in the REST API are both π’ Stable.
(1 The filenames depend on the user-specified filename_separator, but the general formatting of them is stable)
The below example uses the default - as the filename_separator.
REST resource | File Format Type | Filename Formatting |
|---|---|---|
collection | zip | Collection - ${CREATION_UNIX_TIMESTAMP}.zip |
playlist | zip | Playlist - ${PLAYLIST_NAME}.zip |
artist | zip | ${ARTIST_NAME}.zip |
album | zip | ${ARTIST_NAME} - ${ALBUM_TITLE}.zip |
song | Original audio format (flac, mp3, etc) | ${ARTIST_NAME} - ${ALBUM_TITLE} - ${SONG_TITLE}.${AUDIO_FORMAT} |
art | Original image format (png, jpg, etc) | ${ARTIST_NAME} - ${ALBUM_TITLE}.${IMAGE_FORMAT} |
ZIP File Hierarchy
The file hierarchy within ZIPs, and the internal file/folder names are both π’ Stable.
This below example will be the same for the rest of festivald v1.x.x:
# Input
https://localhost:18425/collection
# Output
Collection - ${CREATION_UNIX_TIMESTAMP}.zip
# Extracted
Collection - ${CREATION_UNIX_TIMESTAMP}/
β
ββ ${ARTIST_NAME}/
β β
β ββ ${ALBUM_TITLE}/
β β
β ββ ${ALBUM_TITLE}.${IMAGE_FORMAT}
β ββ ${SONG_TITLE}.${AUDIO_FORMAT}
β
β
ββ ${ARTIST_NAME}/
β β
β ββ ${ALBUM_TITLE}/
β β
β ββ ${ALBUM_TITLE}.${IMAGE_FORMAT}
β ββ ${SONG_TITLE}.${AUDIO_FORMAT}
β
β
[ ... etc ... ]
Misc
Miscellaneous parts of festivald that can or cannot be relied on.
festival-cli
festivald and festival-cli's versions are tied together to represent their compatibility.
festivald will be able to respond to any π’ Stable festival-cli request as long as festivald's:
- Major version is the same
- Minor version is the same or greater
For example, festivald v1.2.x is compatible with:
festival-cli v1.2.xfestival-cli v1.1.xfestival-cli v1.0.x
but not necessarily with festival-cli v1.3.x and beyond.
Note that festivald will still be able to communicate with newer/older festival-cli's, however:
- If a new
festival-cliis requesting a method unknown to an oldfestivald, or - If a new
festivaldhas additional output unknown to an oldfestival-cli(use ofnon-stableAPI)
there will be communication issues.
Config
confignames areπ’ Stable(max_connectionswill always be namedmax_connections)- Their expected inputs are
π’ Stable(max_connectionswill always want an unsigned integer) - Their expected behavior is
π‘ Incomplete(direct_downloadmay include song files someday) - Default config values may be changed (default
portvalue may not always be18425) - Additional fields may be added in the future
Referencing any JSON-RPC methods and/or REST resources that are π΄ Unstable in options like no_auth_rpc & no_auth_rest will also make your configuration π΄ Unstable.
In general, behavior for existing config options may be extended if it does not break current behavior too much.
For example, direct_download will most likely support showing inline audio files eventually.
Command Line
--flagsand sub-command names areπ’ Stable(festivald --pathwill always befestivald --path)- Their expected inputs/outputs are
π’ Stable - Additional flags and/or sub-commands may be added in the future
Disk
All locations and filenames of all files written to disk by festivald are π’ Stable.
| Type | Example |
|---|---|
Cache | Artist ZIP cache is always at ~/.cache/festival/daemon/zip/artist |
Config | Config file is always at ~/.config/festival/daemon/festivald.toml |
Data | Collection file is always at ~/.local/share/festival/daemon/state/collection.bin |
Documentation
Do not rely on the exact name or position of something within this documentation.
For example, this section API Stability may be renamed to API Reliability and/or moved to a different chapter.
Documentation may change at any given moment to provide the most accurate information.
Errors
Do not rely on the details of the JSON-RPC & REST API errors.
You can rely that an input that leads to OK/ERROR will always be the same.
Logs
Do not rely on the log output of festivald.
HTTP Headers
Do not rely on the specific HTTP headers festivald returns, or their values.
Protocol
- Transports other than HTTP(s) may be supported in the future
- Version
2.0ofJSON-RPCwill always be used JSON-RPCwill always requireHTTP POSTrequestsRESTand documentation will always requireHTTP GETrequests
Common Objects
These objects often appear in the output of many JSON-RPC calls.
The definitions of these objects will be here, instead of everywhere they appear in the documentation.
Collection
The Collection is the main music library/database in festivald.
The 3 Common Objects
The 3 common "objects" that appear almost everywhere are:
Keys
And the number key that acts as the identifier for them:
ArtistkeyAlbumkeySongkey
Entry
Entry is an "absolute" key, as it holds all integer Key's and all string key's relating to a Song.
Playlist
Playlist's are regular lists of Song's.
The "entries" within a Playlist aren't Song objects themselves, but Entry-like objects called Playlist Entry's.
Generic Response
This is the generic "success" response object, just an empty result:
{
"jsonrpc": "2.0",
"result": null, // <--- everything went ok.
"id": 0 // the `result` field existing in JSON-RPC means success,
} // so the value in this case (null) doesn't matter.
This is the response to many JSON-RPC as well, typically the Playback Control methods.
If an error occurred in this situation, the JSON-RPC defined error would be used:
{
"jsonrpc": "2.0",
"error": { // <--- something went wrong.
"code": -1, // <--- the error code.
"message": "...", // <--- short message of the error.
},
"id": 0
}
Collection
π‘ Incomplete
This API's output may have additions in the future.
This is the main music "library" or "database" that festivald creates and uses.
It is the central component, and almost all other methods/endpoints use it in some way.
It does not contain actual audio/image data, but rather metadata and links to where those resources can be found.
The Collection contains many nested objects, including the common 3:
The sort_* fields are a bunch of keys that represent an ordering.
For example, the sort_artist_lexi array contains Artist keys that are in Artist name A-Z ordering, so the first Artist in that array will be something like ArtistStartingWithA and the last will probably be something like ZArtist.
String sorting is done lexicographically as per Rust's string ordering implementation. UTF-8 strings are accepted, so non-English characters and emojis will work, although it is unclear which languages come first/last, or whether πΊ is before/after π€‘. Regardless, the implementation linked handles that.
This full Collection object can be received via the collection_full method.
| Field | Type | Description |
|---|---|---|
| empty | boolean | If the Collection does NOT have any Artist's, Album's, or Song's |
| timestamp | unsigned integer | The UNIX timestamp of when this Collection was created |
| count_artist | unsigned integer | How many unique Artist's there are in this Collection |
| count_album | unsigned integer | How many unique Album's there are in this Collection |
| count_song | unsigned integer | How many unique Song's there are in this Collection |
| count_art | unsigned integer | How much unique Album art there are in this Collection |
| artists | array of Artist objects | An array of Artist objects |
| albums | array of Album objects | An array of Album objects |
| songs | array of Song objects | An array of Song objects |
| sort_artist_lexi | array of Artist keys (unsigned integers) | Artists A-Z |
| sort_artist_lexi_rev | array of Artist keys (unsigned integers) | Artists Z-A |
| sort_artist_album_count | array of Artist keys (unsigned integers) | Artists per album count (least to most) |
| sort_artist_album_count_rev | array of Artist keys (unsigned integers) | Artists per album count (most to least) |
| sort_artist_song_count | array of Artist keys (unsigned integers) | Artists per song count (least to most) |
| sort_artist_song_count_rev | array of Artist keys (unsigned integers) | Artists per song count (most to least) |
| sort_artist_runtime | array of Artist keys (unsigned integers) | Artists runtime shortest-longest |
| sort_artist_runtime_rev | array of Artist keys (unsigned integers) | Artists runtime longest-shortest |
| sort_artist_name | array of Artist keys (unsigned integers) | Artist name shortest-longest |
| sort_artist_name_rev | array of Artist keys (unsigned integers) | Artist name longest-shortest |
| sort_album_release_artist_lexi | array of Album keys (unsigned integers) | Artists A-Z, albums oldest-latest |
| sort_album_release_artist_lexi_rev | array of Album keys (unsigned integers) | Artists Z-A, albums oldest-latest |
| sort_album_release_rev_artist_lexi | array of Album keys (unsigned integers) | Artists A-Z, albums latest-oldest |
| sort_album_release_rev_artist_lexi_rev | array of Album keys (unsigned integers) | Artists Z-A, albums latest-oldest |
| sort_album_lexi_artist_lexi | array of Album keys (unsigned integers) | Artists A-Z, albums A-Z |
| sort_album_lexi_artist_lexi_rev | array of Album keys (unsigned integers) | Artists Z-A, albums A-Z |
| sort_album_lexi_rev_artist_lexi | array of Album keys (unsigned integers) | Artists A-Z, albums Z-A |
| sort_album_lexi_rev_artist_lexi_rev | array of Album keys (unsigned integers) | Artists Z-A, albums Z-A |
| sort_album_lexi | array of Album keys (unsigned integers) | Albums A-Z |
| sort_album_lexi_rev | array of Album keys (unsigned integers) | Albums Z-A |
| sort_album_release | array of Album keys (unsigned integers) | Albums oldest-latest |
| sort_album_release_rev | array of Album keys (unsigned integers) | Albums latest-oldest |
| sort_album_runtime | array of Album keys (unsigned integers) | Albums shortest-longest |
| sort_album_runtime_rev | array of Album keys (unsigned integers) | Albums longest-shortest |
| sort_album_title | array of Album keys (unsigned integers) | Album title shortest-longest |
| sort_album_title_rev | array of Album keys (unsigned integers) | Album title longest-shortest |
| sort_song_album_release_artist_lexi | array of Song keys (unsigned integers) | Artists A-Z, albums oldest-latest, songs in track order |
| sort_song_album_release_artist_lexi_rev | array of Song keys (unsigned integers) | Artists Z-A, albums oldest-latest, songs in track order |
| sort_song_album_release_rev_artist_lexi | array of Song keys (unsigned integers) | Artists A-Z, albums latest-oldest, songs in track order |
| sort_song_album_release_rev_artist_lexi_rev | array of Song keys (unsigned integers) | Artists Z-A, albums latest-oldest, songs in track order |
| sort_song_album_lexi_artist_lexi | array of Song keys (unsigned integers) | Artists A-Z, albums A-Z, songs in track order |
| sort_song_album_lexi_artist_lexi_rev | array of Song keys (unsigned integers) | Artists Z-A, albums A-Z, songs in track order |
| sort_song_album_lexi_rev_artist_lexi | array of Song keys (unsigned integers) | Artists A-Z, albums Z-A, songs in track order |
| sort_song_album_lexi_rev_artist_lexi_rev | array of Song keys (unsigned integers) | Artists Z-A, albums Z-A, songs in track order |
| sort_song_lexi | array of Song keys (unsigned integers) | Songs A-Z |
| sort_song_lexi_rev | array of Song keys (unsigned integers) | Songs Z-A |
| sort_song_release | array of Song keys (unsigned integers) | Songs oldest-latest |
| sort_song_release_rev | array of Song keys (unsigned integers) | Songs latest-oldest |
| sort_song_runtime | array of Song keys (unsigned integers) | Songs shortest-longest |
| sort_song_runtime_rev | array of Song keys (unsigned integers) | Songs longest-shortest |
| sort_song_title | array of Song keys (unsigned integers) | Song title shortest-longest |
| sort_song_title_rev | array of Song keys (unsigned integers) | Song title longest-shortest |
Example
{
"jsonrpc": "2.0",
"result": {
"empty": false,
"timestamp": 1691018515,
"count_artist": 3,
"count_album": 4,
"count_song": 7,
"count_art": 4,
"artists": [
{
"name": "artist_1",
"key": 0,
"runtime": 4,
"albums": [
0,
1
],
"songs": [
0,
1,
2,
3
]
},
{
"name": "artist_2",
"key": 1,
"runtime": 2,
"albums": [
2
],
"songs": [
4,
5
]
},
{
"name": "artist_3",
"key": 2,
"runtime": 1,
"albums": [
3
],
"songs": [
6
]
}
],
"albums": [
{
"title": "album_1",
"key": 0,
"artist": 0,
"release": "2018-04-25",
"runtime": 2,
"song_count": 2,
"songs": [
0,
1
],
"discs": 0,
"art": 10239,
"genre": null
},
{
"title": "album_2",
"key": 1,
"artist": 0,
"release": "2018-04-25",
"runtime": 2,
"song_count": 2,
"songs": [
2,
3
],
"discs": 0,
"art": 10239,
"genre": null
},
{
"title": "album_3",
"key": 2,
"artist": 1,
"release": "2018-04-25",
"runtime": 2,
"song_count": 2,
"songs": [
4,
5
],
"discs": 1,
"art": 10239,
"genre": null
},
{
"title": "album_4",
"key": 3,
"artist": 2,
"release": "2018-04-25",
"runtime": 1,
"song_count": 1,
"songs": [
6
],
"discs": 0,
"art": 10239,
"genre": null
}
],
"songs": [
{
"title": "mp3",
"key": 0,
"album": 0,
"runtime": 1,
"sample_rate": 48000,
"track": 1,
"disc": 2,
"mime": "audio/mpeg",
"extension": "mp3"
},
{
"title": "mp3",
"key": 1,
"album": 0,
"runtime": 1,
"sample_rate": 48000,
"track": 2,
"disc": 2,
"mime": "audio/mpeg",
"extension": "mp3"
},
{
"title": "mp3",
"key": 2,
"album": 1,
"runtime": 1,
"sample_rate": 48000,
"track": 1,
"disc": 2,
"mime": "audio/mpeg",
"extension": "mp3"
},
{
"title": "flac",
"key": 3,
"album": 1,
"runtime": 1,
"sample_rate": 48000,
"track": 2,
"disc": 2,
"mime": "audio/x-flac",
"extension": "flac"
},
{
"title": "m4a",
"key": 4,
"album": 2,
"runtime": 1,
"sample_rate": 48000,
"track": 1,
"disc": null,
"mime": "audio/m4a",
"extension": "m4a"
},
{
"title": "song_6",
"key": 5,
"album": 2,
"runtime": 1,
"sample_rate": 48000,
"track": 2,
"disc": 2,
"mime": "audio/ogg",
"extension": "ogg"
},
{
"title": "mp3",
"key": 6,
"album": 3,
"runtime": 1,
"sample_rate": 48000,
"track": 1,
"disc": 2,
"mime": "audio/mpeg",
"extension": "mp3"
}
],
"sort_artist_lexi": [
0,
1,
2
],
"sort_artist_lexi_rev": [
2,
1,
0
],
"sort_artist_album_count": [
1,
2,
0
],
"sort_artist_album_count_rev": [
0,
2,
1
],
"sort_artist_song_count": [
2,
1,
0
],
"sort_artist_song_count_rev": [
0,
1,
2
],
"sort_artist_runtime": [
2,
1,
0
],
"sort_artist_runtime_rev": [
0,
1,
2
],
"sort_artist_name": [
0,
1,
2
],
"sort_artist_name_rev": [
2,
1,
0
],
"sort_album_release_artist_lexi": [
0,
1,
2,
3
],
"sort_album_release_artist_lexi_rev": [
3,
2,
0,
1
],
"sort_album_release_rev_artist_lexi": [
1,
0,
2,
3
],
"sort_album_release_rev_artist_lexi_rev": [
3,
2,
1,
0
],
"sort_album_lexi_artist_lexi": [
0,
1,
2,
3
],
"sort_album_lexi_artist_lexi_rev": [
3,
2,
0,
1
],
"sort_album_lexi_rev_artist_lexi": [
1,
0,
2,
3
],
"sort_album_lexi_rev_artist_lexi_rev": [
3,
2,
1,
0
],
"sort_album_lexi": [
0,
1,
2,
3
],
"sort_album_lexi_rev": [
3,
2,
1,
0
],
"sort_album_release": [
0,
1,
2,
3
],
"sort_album_release_rev": [
3,
2,
1,
0
],
"sort_album_runtime": [
3,
0,
1,
2
],
"sort_album_runtime_rev": [
2,
1,
0,
3
],
"sort_album_title": [
0,
1,
2,
3
],
"sort_album_title_rev": [
3,
2,
1,
0
],
"sort_song_album_release_artist_lexi": [
0,
1,
2,
3,
4,
5,
6
],
"sort_song_album_release_artist_lexi_rev": [
6,
4,
5,
0,
1,
2,
3
],
"sort_song_album_release_rev_artist_lexi": [
2,
3,
0,
1,
4,
5,
6
],
"sort_song_album_release_rev_artist_lexi_rev": [
6,
4,
5,
2,
3,
0,
1
],
"sort_song_album_lexi_artist_lexi": [
0,
1,
2,
3,
4,
5,
6
],
"sort_song_album_lexi_artist_lexi_rev": [
6,
4,
5,
0,
1,
2,
3
],
"sort_song_album_lexi_rev_artist_lexi": [
2,
3,
0,
1,
4,
5,
6
],
"sort_song_album_lexi_rev_artist_lexi_rev": [
6,
4,
5,
2,
3,
0,
1
],
"sort_song_lexi": [
3,
4,
0,
1,
2,
6,
5
],
"sort_song_lexi_rev": [
5,
6,
2,
1,
0,
4,
3
],
"sort_song_release": [
0,
1,
2,
3,
4,
5,
6
],
"sort_song_release_rev": [
6,
5,
4,
3,
2,
1,
0
],
"sort_song_runtime": [
0,
1,
2,
3,
4,
5,
6
],
"sort_song_runtime_rev": [
6,
5,
4,
3,
2,
1,
0
],
"sort_song_title": [
0,
1,
2,
4,
6,
3,
5
],
"sort_song_title_rev": [
5,
3,
6,
4,
2,
1,
0
]
},
"id": 0
}
Artist
π‘ Incomplete
This API's output may have additions in the future.
A unique "artist" inside your Collection.
Uniqueness is defined by the Artist's name.
Artist objects hold keys to all of their Album's and Song's, acting as a relation link.
The keys inside albums is sorted by Release date.
The keys inside songs is sorted by Track + Disc order.
| Field | Type | Description |
|---|---|---|
| name | string | The Artist's name |
| key | Artist key (unsigned integer) | The Artist key associated with this Artist |
| runtime | unsigned integer | The total runtime of all songs owned by this Artist in seconds |
| albums | array of Album keys (unsigned integers) | Keys to all Album's owned by this Artist, in release order |
| songs | array of Song keys (unsigned integers) | Keys to all Songs's owned by this Artist, in Album release order, then Song track order |
Example
{
"name": "Artist Name",
"key": 65,
"runtime": 7583,
"albums": [
255,
263
],
"songs": [
2829,
2832,
2835,
2841
]
}
Album
π‘ Incomplete
This API's output may have additions in the future.
A unique Album owned by an Artist.
Uniqueness is defined by the Album's title.
Album objects hold keys to all of its Song's, acting as a relation link.
The keys inside songs is sorted by Track + Disc order.
| Field | Type | Description |
|---|---|---|
| title | string | The title of this Album |
| key | Album key (unsigned integer) | The Album key associated with this Album |
| artist | Artist key (unsigned integer) | The Artist key of the Artist that owns this Album |
| release | string | Release date of this Album in YYYY-MM-DD/YYYY-MM/YYYY format, ????-??-?? if unknown |
| runtime | unsigned integer | The total runtime of this Album in seconds |
| song_count | unsigned integer | How many Song's are in this Album |
| songs | array of Song keys (unsigned integers) | Keys to all of the Song's in this Album, in track order |
| discs | unsigned integer | Count of how many "discs" are in this Album, most will be 0 |
| art | optional (maybe null) unsigned integer | Size of this Album's art in bytes, null if not found |
| genre | optional (maybe null) string | Genre of this Album, null if not found |
Example
{
"title": "Album Title",
"key": 100,
"artist": 16,
"release": "2011-07-13",
"runtime": 2942,
"song_count": 3,
"songs": [
972,
1024,
1051,
],
"discs": 0,
"art": 306410,
"genre": null
}
Song
π‘ Incomplete
This API's output may have additions in the future.
A Song inside an Album, owned by an Artist.
Song objects hold keys to the Album it is in, acting as a relation link.
| Field | Type | Description |
|---|---|---|
| title | string | The title of this Song |
| key | Song key (unsigned integer) | The Song key associated with this Song |
| album | Album key (unsigned integer) | The Album key of the Album this Song is from |
| runtime | unsigned integer | The total runtime of this Song in seconds |
| sample_rate | unsigned integer | The sample rate of this Song in hertz, e.g: 44100 |
| track | optional (maybe null) unsigned integer | Track number of this Song, null if not found |
| disc | optional (maybe null) unsigned integer | Disc number this Song belongs to, null if not found |
| mime | string | Audio MIME type of this Song |
| extension | string | File extension of this Song |
Example
{
"title": "Song Title",
"key": 401,
"album": 42,
"runtime": 132,
"sample_rate": 44100,
"track": 5,
"disc": null,
"mime": "audio/x-flac",
"extension": "flac"
}
Key
π’ Stable
This API is stable since festivald v1.0.0.
Common Objects all have an unsigned integer associated with them:
These keys directly map to a given object, and can be used to retrieve them.
In the case of Album art, the Album key doubles as the key (since art belongs to an album), so to access the art of Album 123 in the REST API, you would use:
http://localhost:18425/key/art/123
Key's start at 0 and are unique per object group, meaning there is an Artist 0 key AND Album 0 key AND Song 0 key.
The actual number value of Key's aren't significant, and should be treated as random.
Thus, the songs field in Album won't necessarily be incrementing by 1, e.g, [0, 1, 2, ...]. It could be [0, 6, 112, 3, ...]. Same with Album keys within Artist's.
Where
Key's can be found in multiple JSON-RPC methods, such as map_artist, search_album, etc.
Each object contains its own key within itself as well, and there are links in-between them:
Artist_0 Artist_1
______|______ ______|_________________
/ \ / \ \
Album_13 Album_5 Album_0 Album_4 Album_8
__|__ __|__ __|__ __|__ \___
/ \ / \ / \ / \ \
[Song_5, Song_0, ...] [Song_3, ...] [Song_76, ...] [Song_45, ...] [Song_41, ...]
- An
Artistcontains keys leading toAlbum's Album's have a key pointing back to the owningArtist, and keys leading toSong'sSong's have a key pointing back to the owningAlbum
For convenience, all Artist's also have an array of all their Song's.
Why
Key's are a number that represent direct access to a unique Artist/Album/Song.
Think of it as an index into an array (that's what they really are, implemented).
Reasons why key's exist:
- Accessing objects via a key is faster than with
stringinputs - Storing/sending/parsing integers is faster & cheaper than
string's - As long as your
Collectionis stable, the key's are stable - Accessing
Song's with the same title in the sameAlbumby the sameArtistis impossible withstring's, however, each one of thoseSong's will have a uniqueKey, which it makes it possible to access them that way
Why NOT
Key's can only be relied upon as long as the Collection has not been reset.
When the Collection is reset, it is not guaranteed that the same key will map to the same object. Using map_* and search_* methods as the main way to retrieve information may be more convenient so that Artist names, Album and Song titles can be used as inputs instead.
Example
Let's search for a song that has a title similar to: "hello"
curl http://localhost:18425 -d '{"jsonrpc":"2.0","id":0,"method":"search_song","params":{"input":"hello","kind":"top1"}}'
The output gives us back a Song object, which contains some keys:
{
"jsonrpc": "2.0",
"result": {
"songs": [
{
"title": "HELLO",
"key": 15850, // <--- This is the `Song`'s key
"album": 737, // <--- This is the key of the `Album` this `Song` belongs too
"runtime": 243,
"sample_rate": 44100,
"track": 8,
"disc": 1,
"mime": "audio/x-flac",
"extension": "flac"
}
]
},
"id": 0
}
We can now use that Album key to get the Album:
curl http://localhost:18425 -d '{"jsonrpc":"2.0","id":0,"method":"key_album","params":{"key":"737"}}'
And we get the Album object back:
{
"jsonrpc": "2.0",
"result": {
"title": "Hero",
"key": 737, // <--- This is the `Album`'s key
"artist": 196, // <--- This is the key of the `Artist` this `Album` belongs too
"release": "2001-12-29",
"runtime": 4676,
"song_count": 3,
"songs": [
15850, // <--- Hey look, it's the original `Song` key
9771,
15853
],
"discs": 0,
"art": 8348685,
"genre": null
},
"id": 0
}
We can now use that Artist key to get the Artist:
curl http://localhost:18425 -d '{"jsonrpc":"2.0","id":0,"method":"key_artist","params":{"key":"196"}}'
And we get the Artist object back:
{
"jsonrpc": "2.0",
"result": {
"name": "Tac",
"key": 196, // <--- This is the `Artist`' key
"runtime": 15636,
"albums": [
737, // <--- Hey look, it's the original `Album` key
],
"songs": [
15850, // <--- Hey look, it's the original `Song` key
9771,
15853
]
},
"id": 0
}
With these keys, you traverse up and down the relational graph.
Entry
π’ Stable
This API is stable since festivald v1.0.0.
An "absolute" key to:
This object contains all the relational data of a Song, along with its filesystem PATH.
| Field | Type | Description |
|---|---|---|
| path | string (PATH) | The PATH of this Song on the filesystem festivald is running on |
| key_artist | Artist key (unsigned integer) | The Artist key |
| key_album | Album key (unsigned integer) | The Album key |
| key_song | Song key (unsigned integer) | This Song's key |
| artist | string | The Artist name |
| album | string | The Album title |
| song | string | This Song's title |
Example
{
"path": "/home/hinto/Music/song.mp3",
"key_artist": 0,
"key_album": 0,
"key_song": 0,
"artist": "Artist Name",
"album": "Album Title",
"song": "Song Title"
}
Playlist
π’ Stable
This API is stable since festivald v1.0.0.
Playlist's are objects where
- The key is the playlist name (
string) - The value is an array of
Entry-like objects,Playlist Entries
| Field | Type | Description |
|---|---|---|
${PLAYLIST_NAME} | array of Playlist Entry's | The name of the playlist as the key, and the Song entries in an array |
Playlist Entry
The Entry object in the context of playlists is similar to Entry, except it does not have the path field.
The Playlist Entry takes 2 forms: valid & invalid:
Playlist Entry form | Meaning |
|---|---|
valid | This is a valid Song; it exists within the current Collection |
invalid | This Song does NOT exist in the current Collection, although it did in a previous one (it may have been lost in-between Collection resets) |
These objects will appear in playlist-related methods, like playlist_full & playlist_single.
Example:
{
"hello": [ // <--- the playlist name is "hello"
// This is an "valid" entry.
// The underlying Song exists in the current Collection.
{
"valid": {
"key_artist": 46,
"key_album": 168,
"key_song": 1756,
"artist": "Artist Name",
"album": "Album Title",
"song": "Song Title"
}
},
// This is an "invalid" entry.
// The underlying Song doesn't exist in Collection anymore.
{
"invalid": {
"artist": "Artist Name",
"album": "Album Title",
"song": "Song Title"
}
}
]
}
valid
The data definition for valid playlist entry types.
Exact same as Entry but does not have path.
| Field | Type | Description |
|---|---|---|
| key_artist | Artist key (unsigned integer) | This entry's Artist key |
| key_album | Album key (unsigned integer) | This entry's Album key |
| key_song | Song key (unsigned integer) | This entry's Song key |
| artist | string | The Artist name |
| album | string | The Album title |
| song | string | The Song title |
Example:
{
"key_artist": 46,
"key_album": 168,
"key_song": 1762,
"artist": "Artist Name",
"album": "Album Title",
"song": "Song Title"
}
invalid
The data definition for invalid playlist entry types is the same as valid, but with no keys.
| Field | Type | Description |
|---|---|---|
| artist | string | The Artist name |
| album | string | The Album title |
| song | string | The Song title |
Example:
{
"artist": "Artist Name",
"album": "Album Title",
"song": "Song Title"
}
Validation
Upon a Collection reset, it is not guaranteed that the same Song's will even exist at all.
This is a problem since existing Playlist's may now be referencing Song's that don't exist anymore.
The way festivald handles this is not to delete them, but "mark" those entries as invalid.
These invalid entries will continue to exist indefinitely.
Upon every future Collection reset, if an invalid entry is able to recover (a matching Song file is found with the correct metadata), it will turn back into a valid entry automatically.
JSON-RPC
festivald exposes a JSON-RPC 2.0 API for general state retrieval & signal control.
It can be accessed by sending a HTTP POST request containing a JSON-RPC 2.0 request in the body, to the root endpoint, /.
All method documentation will include:
- What inputs it needs
- What output to expect
- Examples
The title of the section itself is the method name, for example, collection_new is the method name.
All method names, parameter names, and field names are in lower_case_snake_case.
For a quick start on using the JSON-RPC API, see the next section: Quick Start.
Missing resource
If a JSON-RPC method is interacting with an underlying resource and that resource is missing from the filesystem, festivald will not respond to the client with an error, however, it will log an error message on the machine it is running on.
For example, if a queue_add_key_song method is sent, and that Song's underlying PATH is missing/moved/renamed from when the Collection was created:
mv "Song Title" "Song_Title"
festivald will now have a reference to a non-existent PATH and will not be able to find the file, so it will log an error that looks something like:
Audio - PATH error: No such file or directory (os error 2) ... /path/to/unknown/song.mp3
You can re-create the Collection with collection_new to re-link these PATHs.
Example JSON-RPC 2.0 request:
{
"jsonrpc": "2.0", // JSON-RPC version. MUST be exactly "2.0"
"method": "method", // A string of the method name
"param": null, // Optional parameters needed by the method
"id": 0, // An ID, MUST be a String, Number, or NULL value if included
}
Example Shell script for sending a request:
IP=localhost # ip of festivald
PORT=18425 # port of festivald
METHOD='previous' # the method to call
PARAMS='{"threshold":3}' # the parameters of the method
ID=0 # the ID of this request
# Send JSON-RPC request to goto the previous song
# (or reset the current, if more than 3 seconds has passed).
curl \
http://$IP:$PORT \
-d '{"jsonrpc":"2.0","id":$ID,"method":"'$METHOD'","params":'$PARAMS'}'
Example JSON-RPC 2.0 SUCCESSFUL response:
{
"jsonrpc": "2.0", // JSON-RPC version. Will always be exactly "2.0"
"result": { // The field containing the result of the SUCCESSFUL response
// This can contain fields that
// are nested arbitrarily deep.
// Although, most times they
// will be simple "key": value
// pairs.
},
"id": 0, // The ID associated with the client
}
Example JSON-RPC 2.0 FAILED response:
{
"jsonrpc": "2.0", // JSON-RPC version. Will always be exactly "2.0"
"error": { // The field containing the result of the FAILED response
"code": -32601, // A number that indicates the error type that occurred
"message": "", // A string providing a short description of the error
"data": null, // An OPTIONAL field containing extra data about the error
},
"id": 0, // The ID associated with the client
}
Parameters
For methods with optional parameters, the field(s) can be omitted:
festival-cli queue_add_key_artist --key 0 --append back
curl http://localhost:18425 -d '{"jsonrpc":"2.0","id":0,"method":"queue_add_key_artist","params":{"key":0,"append":"back","clear":false}}'
The exception is collection_new, since it has a single optional field. You must specify it (even if null).
curl http://localhost:18425 -d '{"jsonrpc":"2.0","id":0,"method":"collection_new","params":{"paths":null}}'
JSON-RPC Quick Start
A quick start to using festivald's JSON-RPC 2.0 API.
Create the Collection and start playing an Artist
- First, scan the default
Musicdirectory onfestivald's filesystem, and create aCollectionwithcollection_new:
festival-cli collection_new
curl http://localhost:18425 -d '{"jsonrpc":"2.0","id":0,"method":"collection_new","params":{"paths":null}}'
- Add the
Artist"LUCKY TAPES" to the queue withqueue_add_map_artist:
festival-cli queue_add_map_artist --artist "LUCKY TAPES"
curl http://localhost:18425 -d '{"jsonrpc":"2.0","id":0,"method":"queue_add_map_artist","params":{"artist":"LUCKY TAPES"}}'
- Start playing with
play:
festival-cli play
curl http://localhost:18425 -d '{"jsonrpc":"2.0","id":0,"method":"play"}'
View state of current audio playback with state_audio
festival-cli state_audio
curl http://localhost:18425 -d '{"jsonrpc":"2.0","id":0,"method":"state_audio"}'
Set the volume to 10% with volume
festival-cli volume --volume 10
curl http://localhost:18425 -d '{"jsonrpc":"2.0","id":0,"method":"volume","params":{"volume":10}}'
View the current Album with current_album
festival-cli current_album
curl http://localhost:18425 -d '{"jsonrpc":"2.0","id":0,"method":"current_album"}'
Clear the queue and stop playback with stop
festival-cli stop
curl http://localhost:18425 -d '{"jsonrpc":"2.0","id":0,"method":"stop"}'
Create and add an Artist to a playlist with playlist_add_map_artist
festival-cli playlist_add_map_artist --playlist "Playlist Name" --artist "Artist Name" --append back
curl http://localhost:18425 -d '{"jsonrpc":"2.0","id":0,"method":"playlist_add_map_artist","params":{"playlist":"Playlist Name","artist":"Artist Name","append":"back","clear":false}}'
Collection
Methods related for creating and viewing various info about the Collection.
collection_new
π‘ Incomplete
This API's output may have additions in the future.
Create a new Collection (and replace the current one).
While this method is in progress, other JSON-RPC/REST requests will be rejected.
festivald will respond with some stats when the Collection reset has finished.
Inputs
| Field | Type | Description |
|---|---|---|
| paths | optional (maybe-null) array of PATHs | An array of filesystem PATHs to scan for the new Collection. These must be absolute PATHs on the system festivald is running on, not PATHs on the client. If null is provided, the default Music directory will be used. |
Outputs
| Field | Type | Description |
|---|---|---|
| time | float | How many seconds it took festivald to reset AND respond |
| empty | boolean | If the Collection does NOT have any Artist's, Album's, or Song's |
| timestamp | unsigned integer | The UNIX timestamp of when this Collection was created |
| count_artist | unsigned integer | How many unique Artist's there are in this Collection |
| count_album | unsigned integer | How many unique Album's there are in this Collection |
| count_song | unsigned integer | How many unique Song's there are in this Collection |
| count_art | unsigned integer | How much unique Album art there are in this Collection |
Example Request 1
Use default Music PATH.
festival-cli collection_new
curl http://localhost:18425 -d '{"jsonrpc":"2.0","id":0,"method":"collection_new","params":{"paths":null}}'
Example Request 2
Use the PATH /home/user/Music/collection on festivald's filesystem.
festival-cli collection_new --paths "/home/user/Music/collection"
curl http://localhost:18425 -d '{"jsonrpc":"2.0","id":0,"method":"collection_new","params":{"paths":["/home/user/Music/collection"]}}'
Example Request 3
Windows PATH works too if \ is escaped (and if festivald is running on Windows).
festival-cli collection_new --paths "C:\\Users\\User\\Music\\collection"
curl http://localhost:18425 -d '{"jsonrpc":"2.0","id":0,"method":"collection_new","params":{"paths":["C:\\Users\\User\\Music\\collection"]}}'
Example Response
{
"jsonrpc": "2.0",
"result": {
"time": 0.462621988,
"empty": false,
"timestamp": 1690579397,
"count_artist": 195,
"count_album": 825,
"count_song": 8543,
"count_art": 824
},
"id": 0
}
collection_brief
π‘ Incomplete
This API's output may have additions in the future.
Retrieve some brief metadata about the current Collection.
This method is a subset of the collection_full method.
Inputs
None
Outputs
| Field | Type | Description |
|---|---|---|
| empty | boolean | If the Collection does NOT have any Artist's, Album's, or Song's |
| timestamp | unsigned integer | The UNIX timestamp of when this Collection was created |
| count_artist | unsigned integer | How many unique Artist's there are in this Collection |
| count_album | unsigned integer | How many unique Album's there are in this Collection |
| count_song | unsigned integer | How many unique Song's there are in this Collection |
| count_art | unsigned integer | How much unique Album art there are in this Collection |
Example Request
festival-cli collection_brief
curl http://localhost:18425 -d '{"jsonrpc":"2.0","id":0,"method":"collection_brief"}'
Example Response
{
"jsonrpc": "2.0",
"result": {
"empty": false,
"timestamp": 1690410052,
"count_artist": 195,
"count_album": 825,
"count_song": 8543,
"count_art": 824
},
"id": 0
}
collection_full
π‘ Incomplete
This API's output may have additions in the future.
Retrieve full metadata about the current Collection.
Inputs
None
Outputs
The output of this method will be a full Collection object.
Example Request
festival-cli collection_full
curl http://localhost:18425 -d '{"jsonrpc":"2.0","id":0,"method":"collection_full"}'
Example Response
{
"jsonrpc": "2.0",
"result": {
"empty": false,
"timestamp": 1691018515,
"count_artist": 3,
"count_album": 4,
"count_song": 7,
"count_art": 4,
"artists": [
{
"name": "artist_1",
"key": 0,
"runtime": 4,
"albums": [
0,
1
],
"songs": [
0,
1,
2,
3
]
},
{
"name": "artist_2",
"key": 1,
"runtime": 2,
"albums": [
2
],
"songs": [
4,
5
]
},
{
"name": "artist_3",
"key": 2,
"runtime": 1,
"albums": [
3
],
"songs": [
6
]
}
],
"albums": [
{
"title": "album_1",
"key": 0,
"artist": 0,
"release": "2018-04-25",
"runtime": 2,
"song_count": 2,
"songs": [
0,
1
],
"discs": 0,
"art": 10239,
"genre": null
},
{
"title": "album_2",
"key": 1,
"artist": 0,
"release": "2018-04-25",
"runtime": 2,
"song_count": 2,
"songs": [
2,
3
],
"discs": 0,
"art": 10239,
"genre": null
},
{
"title": "album_3",
"key": 2,
"artist": 1,
"release": "2018-04-25",
"runtime": 2,
"song_count": 2,
"songs": [
4,
5
],
"discs": 1,
"art": 10239,
"genre": null
},
{
"title": "album_4",
"key": 3,
"artist": 2,
"release": "2018-04-25",
"runtime": 1,
"song_count": 1,
"songs": [
6
],
"discs": 0,
"art": 10239,
"genre": null
}
],
"songs": [
{
"title": "mp3",
"key": 0,
"album": 0,
"runtime": 1,
"sample_rate": 48000,
"track": 1,
"disc": 2,
"mime": "audio/mpeg",
"extension": "mp3"
},
{
"title": "mp3",
"key": 1,
"album": 0,
"runtime": 1,
"sample_rate": 48000,
"track": 2,
"disc": 2,
"mime": "audio/mpeg",
"extension": "mp3"
},
{
"title": "mp3",
"key": 2,
"album": 1,
"runtime": 1,
"sample_rate": 48000,
"track": 1,
"disc": 2,
"mime": "audio/mpeg",
"extension": "mp3"
},
{
"title": "flac",
"key": 3,
"album": 1,
"runtime": 1,
"sample_rate": 48000,
"track": 2,
"disc": 2,
"mime": "audio/x-flac",
"extension": "flac"
},
{
"title": "m4a",
"key": 4,
"album": 2,
"runtime": 1,
"sample_rate": 48000,
"track": 1,
"disc": null,
"mime": "audio/m4a",
"extension": "m4a"
},
{
"title": "song_6",
"key": 5,
"album": 2,
"runtime": 1,
"sample_rate": 48000,
"track": 2,
"disc": 2,
"mime": "audio/ogg",
"extension": "ogg"
},
{
"title": "mp3",
"key": 6,
"album": 3,
"runtime": 1,
"sample_rate": 48000,
"track": 1,
"disc": 2,
"mime": "audio/mpeg",
"extension": "mp3"
}
],
"sort_artist_lexi": [
0,
1,
2
],
"sort_artist_lexi_rev": [
2,
1,
0
],
"sort_artist_album_count": [
1,
2,
0
],
"sort_artist_album_count_rev": [
0,
2,
1
],
"sort_artist_song_count": [
2,
1,
0
],
"sort_artist_song_count_rev": [
0,
1,
2
],
"sort_artist_runtime": [
2,
1,
0
],
"sort_artist_runtime_rev": [
0,
1,
2
],
"sort_artist_name": [
0,
1,
2
],
"sort_artist_name_rev": [
2,
1,
0
],
"sort_album_release_artist_lexi": [
0,
1,
2,
3
],
"sort_album_release_artist_lexi_rev": [
3,
2,
0,
1
],
"sort_album_release_rev_artist_lexi": [
1,
0,
2,
3
],
"sort_album_release_rev_artist_lexi_rev": [
3,
2,
1,
0
],
"sort_album_lexi_artist_lexi": [
0,
1,
2,
3
],
"sort_album_lexi_artist_lexi_rev": [
3,
2,
0,
1
],
"sort_album_lexi_rev_artist_lexi": [
1,
0,
2,
3
],
"sort_album_lexi_rev_artist_lexi_rev": [
3,
2,
1,
0
],
"sort_album_lexi": [
0,
1,
2,
3
],
"sort_album_lexi_rev": [
3,
2,
1,
0
],
"sort_album_release": [
0,
1,
2,
3
],
"sort_album_release_rev": [
3,
2,
1,
0
],
"sort_album_runtime": [
3,
0,
1,
2
],
"sort_album_runtime_rev": [
2,
1,
0,
3
],
"sort_album_title": [
0,
1,
2,
3
],
"sort_album_title_rev": [
3,
2,
1,
0
],
"sort_song_album_release_artist_lexi": [
0,
1,
2,
3,
4,
5,
6
],
"sort_song_album_release_artist_lexi_rev": [
6,
4,
5,
0,
1,
2,
3
],
"sort_song_album_release_rev_artist_lexi": [
2,
3,
0,
1,
4,
5,
6
],
"sort_song_album_release_rev_artist_lexi_rev": [
6,
4,
5,
2,
3,
0,
1
],
"sort_song_album_lexi_artist_lexi": [
0,
1,
2,
3,
4,
5,
6
],
"sort_song_album_lexi_artist_lexi_rev": [
6,
4,
5,
0,
1,
2,
3
],
"sort_song_album_lexi_rev_artist_lexi": [
2,
3,
0,
1,
4,
5,
6
],
"sort_song_album_lexi_rev_artist_lexi_rev": [
6,
4,
5,
2,
3,
0,
1
],
"sort_song_lexi": [
3,
4,
0,
1,
2,
6,
5
],
"sort_song_lexi_rev": [
5,
6,
2,
1,
0,
4,
3
],
"sort_song_release": [
0,
1,
2,
3,
4,
5,
6
],
"sort_song_release_rev": [
6,
5,
4,
3,
2,
1,
0
],
"sort_song_runtime": [
0,
1,
2,
3,
4,
5,
6
],
"sort_song_runtime_rev": [
6,
5,
4,
3,
2,
1,
0
],
"sort_song_title": [
0,
1,
2,
4,
6,
3,
5
],
"sort_song_title_rev": [
5,
3,
6,
4,
2,
1,
0
]
},
"id": 0
}
collection_brief_artists
π’ Stable
This API is stable since festivald v1.0.0.
Retrieve an array of every Artist name in the current Collection.
The returned array of string's is in lexicographical order.
Inputs
None
Outputs
| Field | Type | Description |
|---|---|---|
| len | unsigned integer | How many Artist's there are |
| artists | array of string's | The title of every Artist in the Collection |
Example Request
festival-cli collection_brief_artists
curl http://localhost:18425 -d '{"jsonrpc":"2.0","id":0,"method":"collection_brief_artists"}'
Example Response
{
"jsonrpc": "2.0",
"result": {
"len": 3,
"artists": [
"aaa",
"bbb",
"ccc"
]
},
"id": 0
}
collection_brief_albums
π’ Stable
This API is stable since festivald v1.0.0.
Retrieve an array of every Album title in the current Collection.
The returned array of string's is in lexicographical order.
Inputs
None
Outputs
| Field | Type | Description |
|---|---|---|
| len | unsigned integer | How many Album's there are |
| albums | array of string's | The title of every Album in the Collection |
Example Request
festival-cli collection_brief_albums
curl http://localhost:18425 -d '{"jsonrpc":"2.0","id":0,"method":"collection_brief_albums"}'
Example Response
{
"jsonrpc": "2.0",
"result": {
"len": 3,
"albums": [
"aaa",
"bbb",
"ccc"
]
},
"id": 0
}
collection_brief_songs
π’ Stable
This API is stable since festivald v1.0.0.
Retrieve an array of every Song title in the current Collection.
The returned array of string's is in lexicographical order.
Inputs
None
Outputs
| Field | Type | Description |
|---|---|---|
| len | unsigned integer | How many Song's there are |
| songs | array of string's | The title of every Song in the Collection |
Example Request
festival-cli collection_brief_songs
curl http://localhost:18425 -d '{"jsonrpc":"2.0","id":0,"method":"collection_brief_songs"}'
Example Response
{
"jsonrpc": "2.0",
"result": {
"len": 3,
"songs": [
"aaa",
"bbb",
"ccc"
]
},
"id": 0
}
collection_full_artists
π‘ Incomplete
This API's output may have additions in the future.
Retrieve an array of every Artist object in the current Collection.
The returned array is in incrementing key order, as in:
Artist 0,
Artist 1,
Artist 2,
[... etc ...]
Inputs
None
Outputs
| Field | Type | Description |
|---|---|---|
| len | unsigned integer | How many Artist's there are |
| artists | array of Artist objects | Every Artist in the Collection |
Example Request
festival-cli collection_full_artists
curl http://localhost:18425 -d '{"jsonrpc":"2.0","id":0,"method":"collection_full_artists"}'
Example Response
{
"jsonrpc": "2.0",
"result": {
"len": 1,
"artists": [
{
"name": "Artist Name",
"key": 0,
"runtime": 3561,
"albums": [
0,
1
],
"songs": [
0,
1,
5,
20,
22,
23
]
}
]
},
"id": 0
}
collection_full_albums
π‘ Incomplete
This API's output may have additions in the future.
Retrieve an array of every Album object in the current Collection.
The returned array is in incrementing key order, as in:
Album 0,
Album 1,
Album 2,
[... etc ...]
Inputs
None
Outputs
| Field | Type | Description |
|---|---|---|
| len | unsigned integer | How many Album's there are |
| albums | array of Album objects | Every Album in the Collection |
Example Request
festival-cli collection_full_albums
curl http://localhost:18425 -d '{"jsonrpc":"2.0","id":0,"method":"collection_full_albums"}'
Example Response
{
"jsonrpc": "2.0",
"result": {
"len": 2,
"albums": [
{
"title": "Album Title",
"key": 0,
"artist": 0,
"release": "2019",
"runtime": 1385,
"song_count": 4,
"songs": [
0,
1,
7,
11
],
"discs": 0,
"art": 525016,
"genre": null
},
{
"title": "Album Title 2",
"key": 1,
"artist": 0,
"release": "2019",
"runtime": 3605,
"song_count": 4,
"songs": [
12,
16,
22,
23
],
"discs": 0,
"art": 628931,
"genre": null
}
]
},
"id": 0
}
collection_full_songs
π‘ Incomplete
This API's output may have additions in the future.
Retrieve an array of every Song object in the current Collection.
The returned array is in incrementing key order, as in:
Song 0,
Song 1,
Song 2,
[... etc ...]
Inputs
None
Outputs
| Field | Type | Description |
|---|---|---|
| len | unsigned integer | How many Song's there are |
| songs | array of Song objects | Every Song in the Collection |
Example Request
festival-cli collection_full_songs
curl http://localhost:18425 -d '{"jsonrpc":"2.0","id":0,"method":"collection_full_songs"}'
Example Response
{
"jsonrpc": "2.0",
"result": {
"len": 2,
"songs": [
{
"title": "Song Title 1",
"key": 0,
"album": 0,
"runtime": 371,
"sample_rate": 96000,
"track": 1,
"disc": 1,
"mime": "audio/x-flac",
"extension": "flac"
},
{
"title": "Song Title 2",
"key": 1,
"album": 0,
"runtime": 348,
"sample_rate": 96000,
"track": 2,
"disc": 1,
"mime": "audio/x-flac",
"extension": "flac"
}
]
},
"id": 0
}
collection_entries
π’ Stable
This API is stable since festivald v1.0.0.
Retrieve an array of Entry's of every Song in the current Collection.
The returned array is in incrementing key order, as in:
Entry 0 (Song key 0),
Entry 1 (Song key 1),
Entry 2 (Song key 2),
[... etc ...]
Inputs
None
Outputs
| Field | Type | Description |
|---|---|---|
| len | unsigned integer | How many Entry's (Song's) there are |
| entries | array of Entry objects | Every Song in the Collection (in Entry form) |
Example Request
festival-cli collection_entries
curl http://localhost:18425 -d '{"jsonrpc":"2.0","id":0,"method":"collection_entries"}'
Example Response
{
"jsonrpc": "2.0",
"result": [
{
"path": "/home/hinto/festival/assets/audio/song_1.mp3",
"key_artist": 0,
"key_album": 0,
"key_song": 0,
"artist": "artist_1",
"album": "album_1",
"song": "mp3"
},
{
"path": "/home/hinto/festival/assets/audio/song_2.mp3",
"key_artist": 0,
"key_album": 0,
"key_song": 1,
"artist": "artist_1",
"album": "album_1",
"song": "mp3"
},
{
"path": "/home/hinto/festival/assets/audio/song_3.mp3",
"key_artist": 0,
"key_album": 1,
"key_song": 2,
"artist": "artist_1",
"album": "album_2",
"song": "mp3"
},
{
"path": "/home/hinto/festival/assets/audio/song_4.flac",
"key_artist": 0,
"key_album": 1,
"key_song": 3,
"artist": "artist_1",
"album": "album_2",
"song": "flac"
},
{
"path": "/home/hinto/festival/assets/audio/song_5.m4a",
"key_artist": 1,
"key_album": 2,
"key_song": 4,
"artist": "artist_2",
"album": "album_3",
"song": "m4a"
},
{
"path": "/home/hinto/festival/assets/audio/song_6.ogg",
"key_artist": 1,
"key_album": 2,
"key_song": 5,
"artist": "artist_2",
"album": "album_3",
"song": "song_6"
},
{
"path": "/home/hinto/festival/assets/audio/song_7.mp3",
"key_artist": 2,
"key_album": 3,
"key_song": 6,
"artist": "artist_3",
"album": "album_4",
"song": "mp3"
}
],
"id": 0
}
collection_health
π’ Stable
This API is stable since festivald v1.0.0.
Retrieve the health of the current Collection.
This method tells you how many Song's referenced by the current Collection have a missing underlying file, i.e, there is no file at the PATH the Collection points to for a particular Song.
Missing Song's will be returned in Entry form.
The returned array of missing Entry's is in incrementing Song key order, as in:
Entry 10 (Song key 10),
Entry 13 (Song key 13),
Entry 75 (Song key 75),
Entry 76 (Song key 76),
[... etc ...]
Inputs
None
Outputs
| Field | Type | Description |
|---|---|---|
| all_ok | boolean | If the underlying file for every single Song exists, this is true, else if even 1 is missing, it is false |
| song_len | unsigned integer | The total count of Song's in the Collection |
| missing_len | unsigned integer | The total count of Song's with missing underlying files |
| missing | array of Entry objects | An array of each Song that is missing, in Entry object form |
Example Request
festival-cli collection_health
curl http://localhost:18425 -d '{"jsonrpc":"2.0","id":0,"method":"collection_health"}'
Example Response
{
"jsonrpc": "2.0",
"result": {
"all_ok": false,
"song_len": 24,
"missing_len": 2,
"missing": [
{
"path": "/home/hinto/Music/song.flac",
"key_artist": 0,
"key_album": 0,
"key_song": 0,
"artist": "Artist Name",
"album": "Album Title",
"song": "Song Title"
},
{
"path": "/home/hinto/Music/song2.flac",
"key_artist": 1,
"key_album": 1,
"key_song": 1,
"artist": "Artist Name 2",
"album": "Album Title 2",
"song": "Song Title 2"
}
]
},
"id": 0
}
collection_perf
π’ Stable
This API is stable since festivald v1.0.0.
View some performance stats about the latest Collection reset.
Inputs
None
Outputs
| Field | Type | Description |
|---|---|---|
| bytes | unsigned integer | Total size of the Collection (collection.bin only, not audio/art) in bytes |
| user | float | Collection creation time in seconds, for the user |
| sys | float | Collection creation time in seconds, for the system festivald is running on |
Example Request
festival-cli collection_perf
curl http://localhost:18425 -d '{"jsonrpc":"2.0","id":0,"method":"collection_perf"}'
Example Response
{
"jsonrpc": "2.0",
"result": {
"bytes": 2554823,
"user": 0.45682073,
"sys": 0.48661286
},
"id": 0
}
collection_resource_size
π’ Stable
This API is stable since festivald v1.0.0.
View the size of the current Collection's underlying resources (audio files and art).
The output of this method reflects the live audio file size, not the one at the time of the Collection creation. For example, if an underlying audio file is changed:
my_song_file.flac (5MB) -> my_song_file.flac (33MB)
Then this method will reflect that change.
However, Art is cached by festivald and only updated upon a Collection reset.
Inputs
None
Outputs
| Field | Type | Description |
|---|---|---|
| audio | unsigned integer | Total size of the Collection's underlying audio files in bytes |
| art | unsigned integer | Total size of the Collection's underlying Album art in bytes |
Example Request
festival-cli collection_resource_size
curl http://localhost:18425 -d '{"jsonrpc":"2.0","id":0,"method":"collection_resource_size"}'
Example Response
{
"jsonrpc": "2.0",
"result": {
"audio": 315060491209,
"art": 877030803
},
"id": 0
}
Daemon
These methods are for retrieving/modifying festivald in "system"-related ways.
daemon_config
π΄ Unstable
This API's output may be changed in the future.
Retrieve the active configuration of festivald.
The output is almost a mirror of the configuration file.
See the Config chapter to see the full description of these fields.
The reason why this method is π΄ Unstable is because it will output all JSON-RPC methods & REST resources, even π΄ Unstable ones, which may not exist in the future.
Inputs
None
Outputs
| Field | Type |
|---|---|
| ip | string (IPv4 address) |
| port | unsigned integer |
| max_connections | optional (maybe-null) unsigned integer |
| exclusive_ips | optional (maybe-null) array of strings (IPv4 addresses) |
| sleep_on_fail | optional (maybe-null) unsigned integer |
| collection_paths | array of strings (PATHs) |
| tls | boolean |
| certificate | optional (maybe-null) string (PATH) |
| key | optional (maybe-null) string (PATH) |
| rest | boolean |
| docs | boolean |
| direct_download | boolean |
| filename_separator | string |
| log_level | string, one of OFF, ERROR, WARN, INFO, DEBUG, ERROR |
| watch | boolean |
| cache_clean | boolean |
| cache_time | unsigned integer |
| restore_audio_state | boolean |
| media_controls | boolean |
| authorization | boolean |
| confirm_no_tls_auth | boolean |
| no_auth_rpc | optional (maybe-null) array of JSON-RPC Method names |
| no_auth_rest | optional (maybe-null) array of REST Resource names |
| no_auth_docs | boolean |
Example Request
festival-cli daemon_config
curl http://localhost:18425 -d '{"jsonrpc":"2.0","id":0,"method":"daemon_config"}'
Example Response
{
"jsonrpc": "2.0",
"result": {
"ip": "127.0.0.1",
"port": 18425,
"max_connections": null,
"exclusive_ips": null,
"sleep_on_fail": 3000,
"collection_paths": [
"/home/hinto/Music"
],
"tls": true,
"certificate": "/home/hinto/festival/assets/tls/cert.pem",
"key": "/home/hinto/festival/assets/tls/key.pem",
"rest": true,
"docs": true,
"direct_download": false,
"filename_separator": " - ",
"log_level": "TRACE",
"watch": true,
"cache_clean": true,
"cache_time": 3600,
"restore_audio_state": true,
"media_controls": true,
"authorization": true,
"confirm_no_tls_auth": false,
"no_auth_rpc": [
"toggle"
],
"no_auth_rest": [
"song"
],
"no_auth_docs": true
},
"id": 0
}
daemon_methods
π΄ Unstable
This API's output may be changed in the future.
Retrieve all JSON-RPC methods this festivald knows about.
The reason why this method is π΄ Unstable is because it will output all methods, even π΄ Unstable ones, which may not exist in the future.
Ordering of the method names should not be relied upon.
Inputs
None
Outputs
| Field | Type | Description |
|---|---|---|
| len | unsigned integer | Total amount of methods |
| methods | array of string's | The names of all the methods this festivald knows about |
Example Request
festival-cli daemon_methods
curl http://localhost:18425 -d '{"jsonrpc":"2.0","id":0,"method":"daemon_methods"}'
Example Response
{
"jsonrpc": "2.0",
"result": {
"len": 109,
"methods": [
"collection_new",
"collection_brief",
"collection_full",
"collection_brief_artists",
"collection_brief_albums",
"collection_brief_songs",
"collection_full_artists",
"collection_full_albums",
"collection_full_songs",
"collection_entries",
"collection_perf",
"collection_health",
"collection_resource_size",
"daemon_config",
"daemon_methods",
"daemon_no_auth_rpc",
"daemon_no_auth_rest",
"daemon_remove_cache",
"daemon_save",
"daemon_seen_ips",
"daemon_shutdown",
"daemon_state",
"state_audio",
"state_queue_key",
"state_queue_song",
"state_queue_entry",
"state_playing",
"state_repeat",
"state_runtime",
"state_volume",
"key_artist",
"key_album",
"key_song",
"key_entry",
"key_artist_albums",
"key_artist_songs",
"key_artist_entries",
"key_album_artist",
"key_album_songs",
"key_album_entries",
"key_song_artist",
"key_song_album",
"key_other_albums",
"key_other_songs",
"key_other_entries",
"map_artist",
"map_album",
"map_song",
"map_entry",
"map_artist_albums",
"map_artist_songs",
"map_artist_entries",
"map_album_songs",
"map_album_entries",
"current_artist",
"current_album",
"current_song",
"current_entry",
"rand_artist",
"rand_album",
"rand_song",
"rand_entry",
"search",
"search_artist",
"search_album",
"search_song",
"search_entry",
"toggle",
"play",
"pause",
"next",
"stop",
"previous",
"clear",
"seek",
"skip",
"back",
"shuffle",
"repeat",
"volume",
"volume_up",
"volume_down",
"queue_add_key_artist",
"queue_add_key_album",
"queue_add_key_song",
"queue_add_map_artist",
"queue_add_map_album",
"queue_add_map_song",
"queue_add_rand_artist",
"queue_add_rand_album",
"queue_add_rand_song",
"queue_add_rand_entry",
"queue_add_playlist",
"queue_set_index",
"queue_remove_range",
"playlist_new",
"playlist_remove",
"playlist_clone",
"playlist_get_index",
"playlist_remove_index",
"playlist_add_key_artist",
"playlist_add_key_album",
"playlist_add_key_song",
"playlist_add_map_artist",
"playlist_add_map_album",
"playlist_add_map_song",
"playlist_single",
"playlist_brief",
"playlist_full"
]
},
"id": 0
}
daemon_no_auth_rpc
π΄ Unstable
This API's output may be changed in the future.
Retrieve all JSON-RPC methods this festivald allows without authorization, set in the no_auth_rpc option
The reason why this method is π΄ Unstable is because it will output all methods, even π΄ Unstable ones, which may not exist in the future.
Ordering of the method names should not be relied upon.
Inputs
None
Outputs
| Field | Type | Description |
|---|---|---|
| len | unsigned integer | Total amount of methods |
| rpc | array of string's | The names of all the methods this festivald allows without authorization |
Example Request
festival-cli daemon_no_auth_rpc
curl http://localhost:18425 -d '{"jsonrpc":"2.0","id":0,"method":"daemon_no_auth_rpc"}'
Example Response
{
"jsonrpc": "2.0",
"result": {
"len": 3,
"rpc": [
"collection_brief_artists",
"key_artist_entries",
"search_album"
]
},
"id": 0
}
daemon_no_auth_rest
π΄ Unstable
This API's output may be changed in the future.
Retrieve all REST resources this festivald allows without authorization, set in the no_auth_rest option
The reason why this method is π΄ Unstable is because it will output all REST resources, even π΄ Unstable ones, which may not exist in the future.
Ordering of the resource names should not be relied upon.
Inputs
None
Outputs
| Field | Type | Description |
|---|---|---|
| len | unsigned integer | Total amount of methods |
| rest | array of string's | The names of all the REST resources this festivald allows without authorization |
Example Request
festival-cli daemon_no_auth_rest
curl http://localhost:18425 -d '{"jsonrpc":"2.0","id":0,"method":"daemon_no_auth_rest"}'
Example Response
{
"jsonrpc": "2.0",
"result": {
"len": 2,
"rest": [
"song",
"art"
]
},
"id": 0
}
daemon_remove_cache
π’ Stable
This API is stable since festivald v1.0.0.
Remove all the cached REST resource files on disk.
Warning: If there is a connection currently using this cache, it will error.
Inputs
None
Outputs
The output is an un-named array containing:
| Field | Type | Description |
|---|---|---|
| path | string (PATH) | A file that was removed |
| bytes | unsigned integer | How many bytes that file was |
Example Request
festival-cli daemon_remove_cache
curl http://localhost:18425 -d '{"jsonrpc":"2.0","id":0,"method":"daemon_remove_cache"}'
Example Response
{
"jsonrpc": "2.0",
"result": [
{
"path": "/home/hinto/.cache/festival/daemon/zip/artist/Artist Name.zip"
"bytes": 345673
},
{
"path": "/home/hinto/.cache/festival/daemon/zip/album/Album Title.zip"
"bytes": 345673
}
],
"id": 0
}
daemon_save
π‘ Incomplete
This API's output may have additions in the future.
Save festivald data to disk.
Currently this saves:
The Collection is always saved automatically after creation.
Inputs
None
Outputs
null if everything went ok.
Example Request
festival-cli daemon_save
curl http://localhost:18425 -d '{"jsonrpc":"2.0","id":0,"method":"daemon_save"}'
Example Response
{
"jsonrpc": "2.0",
"result": null, // <--- everything went ok.
"id": 0
}
daemon_seen_ips
π’ Stable
This API is stable since festivald v1.0.0.
Retrieve an array of the IP addresses festivald has seen.
Inputs
None
Outputs
The output is an un-named array containing:
| Field | Type | Description |
|---|---|---|
| ip | string (IPv4 address) | IP address festivald has seen |
| count | unsigned integer | How many connections this IP has made to festivald |
Example Request
festival-cli daemon_seen_ips
curl http://localhost:18425 -d '{"jsonrpc":"2.0","id":0,"method":"daemon_seen_ips"}'
Example Response
{
"jsonrpc": "2.0",
"result": [
{
"ip": "127.0.0.1",
"count": 14
},
{
"ip": "192.168.2.1",
"count": 2
}
],
"id": 0
}
daemon_shutdown
π‘ Incomplete
This API's output may have additions in the future.
Send a shutdown signal to festivald.
festivald will:
- Reject future connections
- Wait for a
Collectionreset to finish if occurring - Clean cache
- Save state to disk
Then shutdown.
Inputs
None
Outputs
| Field | Type | Description |
|---|---|---|
| uptime | unsigned integer | Uptime of festivald in seconds |
| uptime_readable | string | Uptime of festivald in human-readable time (60 is 1 minute) |
| total_requests | unsigned integer | Total amount of requests festivald has received since starting |
| total_connections | unsigned integer | Total amount of connections festivald has received since starting |
Example Request
festival-cli daemon_shutdown
curl http://localhost:18425 -d '{"jsonrpc":"2.0","id":0,"method":"daemon_shutdown"}'
Example Response
{
"jsonrpc": "2.0",
"result": {
"uptime": 4,
"uptime_readable": "4 seconds",
"total_requests": 1,
"total_connections": 1
},
"id": "festival-cli"
}
daemon_state
π‘ Incomplete
This API's output may have additions in the future.
Retrieve state about the status of festivald itself.
Inputs
None
Outputs
| Field | Type | Description |
|---|---|---|
| uptime | unsigned integer | Uptime of festivald in seconds |
| uptime_readable | string | Uptime of festivald in human-readable time (60 is 1 minute) |
| saving | boolean | If festivald is currently saving a recently created Collection to disk |
| total_requests | unsigned integer | Total amount of requests festivald has received since starting |
| total_connections | unsigned integer | Total amount of connections festivald has received since starting |
| current_connections | unsigned integer | Amount of open connections festivald currently has |
| rest | boolean | If this festivald's REST API is enabled |
| docs | boolean | If this festivald's documentation serving is enabled |
| direct_download | boolean | If this festivald's REST API has direct_download enabled |
| authorization | boolean | If this festivald has authorization enabled |
| version | string | Semantic version of this festivald |
| commit | string | Git commit of this festivald |
| os | string | The OS this festivald was built for |
Example Request
festival-cli search_daemon
curl http://localhost:18425 -d '{"jsonrpc":"2.0","id":0,"method":"daemon_state"}'
Example Response
{
"jsonrpc": "2.0",
"result": {
"uptime": 43,
"uptime_readable": "43 seconds",
"saving": false,
"total_requests": 1447,
"total_connections": 297,
"current_connections": 3,
"rest": true,
"docs": true,
"direct_download": false,
"authorization": false,
"version": "v1.0.0",
"commit": "ae086becca9a603b53ded80de870794858c272d0",
"os": "Linux x64"
},
"id": 0
}
State Retrieval
These methods are for retrieving state (mostly audio state), and do not mutate any part of the system.
state_audio
π‘ Incomplete
This API's output may have additions in the future.
Retrieve the current audio state.
Inputs
None
Outputs
| Field | Type | Description |
|---|---|---|
| queue | array of Song keys (unsigned integers) | Array of Song keys that are in the queue, in order of what will be played next |
| queue_idx | optional (maybe-null) unsigned integer | The queue index festivald is currently on, null if no Song is set |
| playing | boolean | If festivald is currently playing |
| song_key | optional (maybe-null) Song key (unsigned integer) | The key of current Song, null if no Song is set |
| elapsed | unsigned integer | Elapsed runtime of current Song in seconds |
| runtime | unsigned integer | Total runtime of current Song in seconds |
| repeat | string, one of song, queue, or off | Audio repeat behavior. song means the Song will repeat after ending, queue means the whole queue will repeat after ending, off means the queue will be cleared and playback will stop when ending |
| volume | unsigned integer in between 0..100 | The current volume level |
| song | optional (maybe-null) Song object | The current Song as an object, null if no Song is set |
Example Request
festival-cli state_audio
curl http://localhost:18425 -d '{"jsonrpc":"2.0","id":0,"method":"state_audio"}'
Example Response
{
"jsonrpc": "2.0",
"result": {
"queue": [
14
],
"queue_len": 1,
"queue_idx": 0,
"playing": false,
"song_key": 14,
"elapsed": 0,
"runtime": 349,
"repeat": "off",
"volume": 25,
"song": {
"title": "γγ€γ",
"key": 14,
"album": 9,
"runtime": 349,
"sample_rate": 44100,
"track": 1,
"disc": 1,
"mime": "audio/x-flac",
"extension": "flac"
}
},
"id": 0
}
state_queue_key
π’ Stable
This API is stable since festivald v1.0.0.
Retrieve state about the queue.
This returns the queue as Song key's.
Returned key's are in order of what will be played next.
Inputs
None
Outputs
| Field | Type | Description |
|---|---|---|
| len | unsigned integer | Length of the queue |
| keys | array of Song keys (unsigned integers) | Array of the queue's Song's as keys |
Example Request
festival-cli state_queue_key
curl http://localhost:18425 -d '{"jsonrpc":"2.0","id":0,"method":"state_queue_key"}'
Example Response
{
"jsonrpc": "2.0",
"result": {
"len": 5,
"keys": [
2896,
2899,
2904,
2906,
2911
]
},
"id": 0
}
state_queue_song
π‘ Incomplete
This API's output may have additions in the future.
Retrieve state about the queue.
This returns the queue as full Song objects.
Returned Song's are in order of what will be played next.
Inputs
None
Outputs
| Field | Type | Description |
|---|---|---|
| len | unsigned integer | Length of the queue |
| songs | array of Song objects | Array of the queue's Song's |
Example Request
festival-cli state_queue_song
curl http://localhost:18425 -d '{"jsonrpc":"2.0","id":0,"method":"state_queue_song"}'
Example Response
{
"jsonrpc": "2.0",
"result": {
"len": 2,
"songs": [
{
"title": "SUNFLOWER",
"key": 2539,
"album": 237,
"runtime": 252,
"sample_rate": 44100,
"track": 1,
"disc": null,
"mime": "audio/mpeg",
"extension": "mp3"
},
{
"title": "BEST FRIEND",
"key": 2517,
"album": 237,
"runtime": 262,
"sample_rate": 44100,
"track": 2,
"disc": null,
"mime": "audio/mpeg",
"extension": "mp3"
}
]
},
"id": 0
}
state_queue_entry
π’ Stable
This API is stable since festivald v1.0.0.
Retrieve state about the queue.
This is the same as state_queue except it returns Entry's instead of Song's.
Returned Entry's are in order of what will be played next.
Inputs
None
Outputs
| Field | Type | Description |
|---|---|---|
| len | unsigned integer | Length of the queue |
| entries | array of Entry objects | Array of the queue's Song's, in Entry form |
Example Request
festival-cli state_queue_entry
curl http://localhost:18425 -d '{"jsonrpc":"2.0","id":0,"method":"state_queue_entry"}'
Example Response
{
"jsonrpc": "2.0",
"result": {
"len": 2,
"entries": [
{
"path": "/home/hinto/Music/Rex Orange County/RAINBOW/SUNFLOWER.mp3",
"key_artist": 65,
"key_album": 237,
"key_song": 2539,
"artist": "Rex Orange County",
"album": "RAINBOW",
"song": "SUNFLOWER"
},
{
"path": "/home/hinto/Music/Rex Orange County/RAINBOW/BEST FRIEND.mp3",
"key_artist": 65,
"key_album": 237,
"key_song": 2517,
"artist": "Rex Orange County",
"album": "RAINBOW",
"song": "BEST FRIEND"
}
]
},
"id": 0
}
state_playing
π’ Stable
This API is stable since festivald v1.0.0.
Retrieve playback status.
Inputs
None
Outputs
| Field | Type | Description |
|---|---|---|
| playing | boolean | Are we currently playing? |
Example Request
festival-cli state_playing
curl http://localhost:18425 -d '{"jsonrpc":"2.0","id":0,"method":"state_playing"}'
Example Response
{
"jsonrpc": "2.0",
"result": {
"playing": true
},
"id": 0
}
state_repeat
π’ Stable
This API is stable since festivald v1.0.0.
Retrieve the currently set repeat mode.
Inputs
None
Outputs
| Field | Type | Description |
|---|---|---|
| mode | string, one of off, song, queue | The currently set repeat mode. off mean repeat is off, song means Song repeating, queue means queue repeating. |
Example Request
festival-cli state_repeat
curl http://localhost:18425 -d '{"jsonrpc":"2.0","id":0,"method":"state_repeat"}'
Example Response
{
"jsonrpc": "2.0",
"result": {
"mode": "off"
},
"id": 0
}
state_runtime
π’ Stable
This API is stable since festivald v1.0.0.
Retrieve the elapsed runtime & total runtime of the currently set Song.
This will return 0 values (0:00) if there is no Song set.
Inputs
None
Outputs
| Field | Type | Description |
|---|---|---|
| elapsed | unsigned integer | Elapsed runtime of current Song in seconds |
| runtime | unsigned integer | Total runtime of current Song in seconds |
| elapsed_readable | string | Human-readable version of elapsed (5 would be 0:05) |
| runtime_readable | string | Human-readable version of runtime (60 would be 1:00) |
Example Request
festival-cli state_runtime
curl http://localhost:18425 -d '{"jsonrpc":"2.0","id":0,"method":"state_runtime"}'
Example Response 1
Song is set:
{
"jsonrpc": "2.0",
"result": {
"elapsed": 12,
"runtime": 125,
"elapsed_readable": "0:12",
"runtime_readable": "2:05"
},
"id": 0
}
Example Response 2
Song is not set:
{
"jsonrpc": "2.0",
"result": {
"elapsed": 0,
"runtime": 0,
"elapsed_readable": "0:00",
"runtime_readable": "0:00"
},
"id": 0
}
state_volume
π’ Stable
This API is stable since festivald v1.0.0.
Retrieve the current volume level.
Inputs
None
Outputs
| Field | Type | Description |
|---|---|---|
| volume | unsigned integer in between 0..100 | The current volume level |
Example Request
festival-cli state_volume
curl http://localhost:18425 -d '{"jsonrpc":"2.0","id":0,"method":"state_volume"}'
Example Response
{
"jsonrpc": "2.0",
"result": {
"volume": 25
},
"id": 0
}
Key
Use key's to retrieve various Common Objects.
If the key is invalid, a JSON-RPC error will be returned.
To use regular string's as input instead (Artist name, Album title, Song title, etc), see Map.
key_artist
π‘ Incomplete
This API's output may have additions in the future.
Input an Artist key, retrieve an Artist.
Inputs
| Field | Type | Description |
|---|---|---|
| key | Artist key (unsigned integer) | See Key |
Outputs
| Field | Type | Description |
|---|---|---|
| artist | Artist object | See Artist |
Example Request
festival-cli key_artist --key 65
curl http://localhost:18425 -d '{"jsonrpc":"2.0","id":0,"method":"key_artist","params":{"key":65}}'
Example Response
{
"jsonrpc": "2.0",
"result": {
"artist": {
"name": "Rex Orange County",
"key": 65,
"runtime": 7583,
"albums": [
237
],
"songs": [
2800,
2803,
2809
]
}
},
"id": 0
}
key_album
π‘ Incomplete
This API's output may have additions in the future.
Input an Album key, retrieve an Album.
Inputs
| Field | Type | Description |
|---|---|---|
| key | Album key (unsigned integer) | See Key |
Outputs
| Field | Type | Description |
|---|---|---|
| album | Album object | See Album |
Example Request
festival-cli key_album --key 237
curl http://localhost:18425 -d '{"jsonrpc":"2.0","id":0,"method":"key_album","params":{"key":237}}'
Example Response
{
"jsonrpc": "2.0",
"result": {
"album": {
"title": "RAINBOW",
"key": 237,
"artist": 65,
"release": "????-??-??",
"runtime": 1090,
"song_count": 6,
"songs": [
2594,
2540,
2600,
2496,
2557,
2500
],
"discs": 0,
"art": 7753,
"genre": null
}
},
"id": 0
}
key_song
π‘ Incomplete
This API's output may have additions in the future.
Input a Song key, retrieve a Song.
Inputs
| Field | Type | Description |
|---|---|---|
| key | Song key (unsigned integer) | See Key |
Outputs
| Field | Type | Description |
|---|---|---|
| song | Song object | See Song |
Example Request
festival-cli key_song --key 2594
curl http://localhost:18425 -d '{"jsonrpc":"2.0","id":0,"method":"key_song","params":{"key":2594}}'
Example Response
{
"jsonrpc": "2.0",
"result": {
"song": {
"title": "SUNFLOWER",
"key": 2594,
"album": 237,
"runtime": 252,
"sample_rate": 44100,
"track": 1,
"disc": null,
"mime": "audio/mpeg",
"extension": "mp3"
}
},
"id": 0
}
key_entry
π’ Stable
This API is stable since festivald v1.0.0.
Input a Song key, retrieve an Entry.
Inputs
| Field | Type | Description |
|---|---|---|
| key | Song key (unsigned integer) | See Key |
Outputs
| Field | Type | Description |
|---|---|---|
| entry | Entry object | See Entry |
Example Request
festival-cli key_entry --key 5151
curl http://localhost:18425 -d '{"jsonrpc":"2.0","id":0,"method":"key_entry","params":{"key":5151}}'
Example Response
{
"jsonrpc": "2.0",
"result": {
"entry": {
"path": "/home/hinto/Music/song.flac",
"key_artist": 108,
"key_album": 488,
"key_song": 5151,
"artist": "Artist Name",
"album": "Album Title",
"song": "Song Title"
}
},
"id": 0
}
key_artist_albums
π‘ Incomplete
This API's output may have additions in the future.
Input an Artist key, retrieve all their Album's.
The Album's are sorted by Release date.
Inputs
| Field | Type | Description |
|---|---|---|
| key | Artist key (unsigned integer) | See Key |
Outputs
| Field | Type | Description |
|---|---|---|
| len | unsigned integer | How many Album's there are |
| albums | array of Album objects | See Album |
Example Request
festival-cli key_artist_albums --key 62
curl http://localhost:18425 -d '{"jsonrpc":"2.0","id":0,"method":"key_artist_albums","params":{"key":62}}'
Example Response
{
"jsonrpc": "2.0",
"result": {
"len": 3,
"albums": [
{
"title": "Apricot Princess",
"key": 234,
"artist": 62,
"release": "2017",
"runtime": 2370,
"song_count": 10,
"songs": [
2463,
2471,
2483,
2492,
2498,
2504,
2514,
2522,
2530,
2536
],
"discs": 0,
"art": 307745,
"genre": "Pop"
},
{
"title": "Pony",
"key": 241,
"artist": 62,
"release": "2019-09-19",
"runtime": 2032,
"song_count": 10,
"songs": [
2540,
2545,
2548,
2553,
2558,
2567,
2573,
2578,
2581,
2587
],
"discs": 0,
"art": 190830,
"genre": "Alternative & Indie"
},
{
"title": "WHO CARES?",
"key": 247,
"artist": 62,
"release": "2022",
"runtime": 2091,
"song_count": 11,
"songs": [
2590,
2592,
2596,
2598,
2602,
2606,
2607,
2610,
2614,
2618,
2622
],
"discs": 0,
"art": 80994,
"genre": "Alternative & Indie"
}
]
},
"id": 0
}
key_artist_songs
π‘ Incomplete
This API's output may have additions in the future.
Input an Artist key, retrieve all their Song's.
The Song's are sorted by Album release date, then Track + Disc order.
Inputs
| Field | Type | Description |
|---|---|---|
| key | Artist key (unsigned integer) | See Key |
Outputs
| Field | Type | Description |
|---|---|---|
| len | unsigned integer | How many Song's there are |
| songs | array of Song objects | See Song |
Example Request
festival-cli key_artist_songs --key 62
curl http://localhost:18425 -d '{"jsonrpc":"2.0","id":0,"method":"key_artist_songs","params":{"key":62}}'
Example Response
{
"jsonrpc": "2.0",
"result": {
"len": 2,
"songs": [
{
"title": "SUNFLOWER",
"key": 2444,
"album": 222,
"runtime": 252,
"sample_rate": 44100,
"track": 1,
"disc": null,
"mime": "audio/mpeg",
"extension": "mp3"
},
{
"title": "BEST FRIEND",
"key": 2398,
"album": 222,
"runtime": 262,
"sample_rate": 44100,
"track": 2,
"disc": null,
"mime": "audio/mpeg",
"extension": "mp3"
}
]
},
"id": 0
}
key_artist_entries
π’ Stable
This API is stable since festivald v1.0.0.
Input an Artist key, retrieve all their Song's in Entry form.
The Entry's are sorted by Album release date, then Track + Disc order.
Inputs
| Field | Type | Description |
|---|---|---|
| key | Artist key (unsigned integer) | See Key |
Outputs
| Field | Type | Description |
|---|---|---|
| len | unsigned integer | How many Entry's there are |
| entries | array of Entry objects | See Entry |
Example Request
festival-cli key_artist_entries --key 62
curl http://localhost:18425 -d '{"jsonrpc":"2.0","id":0,"method":"key_artist_entries","params":{"key":62}}'
Example Response
{
"jsonrpc": "2.0",
"result": {
"len": 2,
"entries": [
{
"path": "/home/hinto/Music/Rex Orange County/RAINBOW/SUNFLOWER.mp3",
"key_artist": 62,
"key_album": 222,
"key_song": 2444,
"artist": "Rex Orange County",
"album": "RAINBOW",
"song": "SUNFLOWER"
},
{
"path": "/home/hinto/Music/Rex Orange County/RAINBOW/BEST FRIEND.mp3",
"key_artist": 62,
"key_album": 222,
"key_song": 2398,
"artist": "Rex Orange County",
"album": "RAINBOW",
"song": "BEST FRIEND"
}
]
},
"id": 0
}
key_album_artist
π‘ Incomplete
This API's output may have additions in the future.
Input an Album key, retrieve its Artist.
Inputs
| Field | Type | Description |
|---|---|---|
| key | Album key (unsigned integer) | See Key |
Outputs
| Field | Type | Description |
|---|---|---|
| artist | Artist object | See Artist |
Example Request
festival-cli key_album_artist --key 237
curl http://localhost:18425 -d '{"jsonrpc":"2.0","id":0,"method":"key_album_artist","params":{"key":237}}'
Example Response
{
"jsonrpc": "2.0",
"result": {
"artist": {
"name": "Rex Orange County",
"key": 65,
"runtime": 7583,
"albums": [
237
],
"songs": [
2800,
2803,
2809
]
}
},
"id": 0
}
key_album_songs
π‘ Incomplete
This API's output may have additions in the future.
Input an Album key, retrieve all of its Song's.
The Song's are sorted by Track + Disc order.
Inputs
| Field | Type | Description |
|---|---|---|
| key | Artist key (unsigned integer) | See Key |
Outputs
| Field | Type | Description |
|---|---|---|
| len | unsigned integer | How many Song's there are |
| songs | array of Song objects | See Song |
Example Request
festival-cli key_album_songs --key 222
curl http://localhost:18425 -d '{"jsonrpc":"2.0","id":0,"method":"key_album_songs","params":{"key":222}}'
Example Response
{
"jsonrpc": "2.0",
"result": {
"len": 2,
"songs": [
{
"title": "SUNFLOWER",
"key": 2444,
"album": 222,
"runtime": 252,
"sample_rate": 44100,
"track": 1,
"disc": null,
"mime": "audio/mpeg",
"extension": "mp3"
},
{
"title": "BEST FRIEND",
"key": 2398,
"album": 222,
"runtime": 262,
"sample_rate": 44100,
"track": 2,
"disc": null,
"mime": "audio/mpeg",
"extension": "mp3"
}
]
},
"id": 0
}
key_album_entries
π’ Stable
This API is stable since festivald v1.0.0.
Input an Album key, retrieve all of its Song's in Entry form.
The Entry's are sorted by Track + Disc order.
Inputs
| Field | Type | Description |
|---|---|---|
| key | Album key (unsigned integer) | See Key |
Outputs
| Field | Type | Description |
|---|---|---|
| len | unsigned integer | How many Entry's there are |
| entries | array of Entry objects | See Entry |
Example Request
festival-cli key_album_entries --key 222
curl http://localhost:18425 -d '{"jsonrpc":"2.0","id":0,"method":"key_album_entries","params":{"key":222}}'
Example Response
{
"jsonrpc": "2.0",
"result": {
"len": 2,
"entries": [
{
"path": "/home/hinto/Music/Rex Orange County/RAINBOW/SUNFLOWER.mp3",
"key_artist": 62,
"key_album": 222,
"key_song": 2444,
"artist": "Rex Orange County",
"album": "RAINBOW",
"song": "SUNFLOWER"
},
{
"path": "/home/hinto/Music/Rex Orange County/RAINBOW/BEST FRIEND.mp3",
"key_artist": 62,
"key_album": 222,
"key_song": 2398,
"artist": "Rex Orange County",
"album": "RAINBOW",
"song": "BEST FRIEND"
}
]
},
"id": 0
}
key_song_artist
π‘ Incomplete
This API's output may have additions in the future.
Input a Song key, retrieve its Artist.
Inputs
| Field | Type | Description |
|---|---|---|
| key | Song key (unsigned integer) | See Key |
Outputs
| Field | Type | Description |
|---|---|---|
| artist | Artist object | See Artist |
Example Request
festival-cli key_song_artist --key 2800
curl http://localhost:18425 -d '{"jsonrpc":"2.0","id":0,"method":"key_song_artist","params":{"key":2800}}'
Example Response
{
"jsonrpc": "2.0",
"result": {
"artist": {
"name": "Rex Orange County",
"key": 65,
"runtime": 7583,
"albums": [
237
],
"songs": [
2800,
2803,
2809
]
}
},
"id": 0
}
key_song_album
π‘ Incomplete
This API's output may have additions in the future.
Input a Song key, retrieve its Album.
Inputs
| Field | Type | Description |
|---|---|---|
| key | Song key (unsigned integer) | See Key |
Outputs
| Field | Type | Description |
|---|---|---|
| album | Album object | See Album |
Example Request
festival-cli key_song_album --key 2540
curl http://localhost:18425 -d '{"jsonrpc":"2.0","id":0,"method":"key_song_album","params":{"key":2540}}'
Example Response
{
"jsonrpc": "2.0",
"result": {
"album": {
"title": "Pony",
"key": 241,
"artist": 62,
"release": "2019-09-19",
"runtime": 2032,
"song_count": 10,
"songs": [
2540,
2545,
2548,
2553,
2558,
2567,
2573,
2578,
2581,
2587
],
"discs": 0,
"art": 190830,
"genre": "Alternative & Indie"
}
},
"id": 0
}
key_other_albums
π‘ Incomplete
This API's output may have additions in the future.
Input an Album key, retrieve all Album's by the same Artist.
The Album's are sorted by Release date.
Inputs
| Field | Type | Description |
|---|---|---|
| key | Album key (unsigned integer) | See Key |
Outputs
| Field | Type | Description |
|---|---|---|
| len | unsigned integer | How many Album's there are |
| albums | array of Album objects | See Album |
Example Request
festival-cli key_other_albums --key 234
curl http://localhost:18425 -d '{"jsonrpc":"2.0","id":0,"method":"key_other_albums","params":{"key":234}}'
Example Response
{
"jsonrpc": "2.0",
"result": {
"len": 3,
"albums": [
{
"title": "Apricot Princess",
"key": 234,
"artist": 62,
"release": "2017",
"runtime": 2370,
"song_count": 10,
"songs": [
2463,
2471,
2483,
2492,
2498,
2504,
2514,
2522,
2530,
2536
],
"discs": 0,
"art": 307745,
"genre": "Pop"
},
{
"title": "Pony",
"key": 241,
"artist": 62,
"release": "2019-09-19",
"runtime": 2032,
"song_count": 10,
"songs": [
2540,
2545,
2548,
2553,
2558,
2567,
2573,
2578,
2581,
2587
],
"discs": 0,
"art": 190830,
"genre": "Alternative & Indie"
},
{
"title": "WHO CARES?",
"key": 247,
"artist": 62,
"release": "2022",
"runtime": 2091,
"song_count": 11,
"songs": [
2590,
2592,
2596,
2598,
2602,
2606,
2607,
2610,
2614,
2618,
2622
],
"discs": 0,
"art": 80994,
"genre": "Alternative & Indie"
}
]
},
"id": 0
}
key_other_songs
π‘ Incomplete
This API's output may have additions in the future.
Input a Song key, retrieve all Song's in the same Album.
The Song's are sorted by Track + Disc order.
Inputs
| Field | Type | Description |
|---|---|---|
| key | Song key (unsigned integer) | See Key |
Outputs
| Field | Type | Description |
|---|---|---|
| len | unsigned integer | How many Song's there are |
| songs | array of Song objects | See Song |
Example Request
festival-cli key_other_songs --key 2444
curl http://localhost:18425 -d '{"jsonrpc":"2.0","id":0,"method":"key_other_songs","params":{"key":2444}}'
Example Response
{
"jsonrpc": "2.0",
"result": {
"len": 2,
"songs": [
{
"title": "SUNFLOWER",
"key": 2444,
"album": 222,
"runtime": 252,
"sample_rate": 44100,
"track": 1,
"disc": null,
"mime": "audio/mpeg",
"extension": "mp3"
},
{
"title": "BEST FRIEND",
"key": 2398,
"album": 222,
"runtime": 262,
"sample_rate": 44100,
"track": 2,
"disc": null,
"mime": "audio/mpeg",
"extension": "mp3"
}
]
},
"id": 0
}
key_other_entries
π’ Stable
This API is stable since festivald v1.0.0.
Input a Song key, retrieve all Song's in the same Album in Entry form.
The Entry's are sorted by Track + Disc order.
Inputs
| Field | Type | Description |
|---|---|---|
| key | Song key (unsigned integer) | See Key |
Outputs
| Field | Type | Description |
|---|---|---|
| len | unsigned integer | How many Entry's there are |
| entries | array of Entry objects | See Entry |
Example Request
festival-cli key_other_entries --key 2444
curl http://localhost:18425 -d '{"jsonrpc":"2.0","id":0,"method":"key_other_entries","params":{"key":2444}}'
Example Response
{
"jsonrpc": "2.0",
"result": {
"len": 2,
"entries": [
{
"path": "/home/hinto/Music/Rex Orange County/RAINBOW/SUNFLOWER.mp3",
"key_artist": 62,
"key_album": 222,
"key_song": 2444,
"artist": "Rex Orange County",
"album": "RAINBOW",
"song": "SUNFLOWER"
},
{
"path": "/home/hinto/Music/Rex Orange County/RAINBOW/BEST FRIEND.mp3",
"key_artist": 62,
"key_album": 222,
"key_song": 2398,
"artist": "Rex Orange County",
"album": "RAINBOW",
"song": "BEST FRIEND"
}
]
},
"id": 0
}
Map
These methods are the same as the key_* methods, but instead of key's, you can directly use:
strings to lookup Common Objects.
So instead of:
festival-cli key_artist --key 100
you can use:
festival-cli map_artist --artist 'γ«γγ³γ’γ€γ'
If the input is invalid, a JSON-RPC error will be returned.
Warning
Inputs are case-sensitive and must be exactly correct.
If you have an Album called Hello World, none of these inputs will work:
Hello worldhello WorldHELlo WorldHelloWorldH3ll0 W0rld
The input must be exactly Hello World.
Collisions
When using map_album you must specify:
ArtistnameAlbumtitle
and when using map_song you must specify:
ArtistnameAlbumtitleSongtitle
The reason these have to be specified is to prevent collisions.
If there's 2 Song's in your Collection called: Hello World, festivald cannot know which one you want.
Since Artist names are unique, and Album titles within Artist's are unique, they serve as an identifier.
Duplicate Song Names
An uncommon "bug" you may encounter when using:
ArtistnamesAlbumtitlesSongtitles
as the key for searching objects is that:
- if multiple
Song's with the same name exist - in the same
Album - by the same
Artist
it is impossible to specify which one you want.
This may occur in Album's that have "interlude" tracks, which may be different, but have the same name, e.g:
Artist Name/
β
ββ Album Name/
β
ββ Song 1
ββ Interlude # <------------- same name
ββ Song 3.flac
ββ Interlude # <------------- same name
ββ Song 5.flac
The workaround is by using Song key's to retrieve these instead, as they are unique per file, regardless of metadata.
map_artist
π‘ Incomplete
This API's output may have additions in the future.
Input an Artist name, retrieve an Artist object.
Inputs
| Field | Type | Description |
|---|---|---|
| artist | string | Artist name |
Outputs
| Field | Type | Description |
|---|---|---|
| artist | Artist object | See Artist |
Example Request
festival-cli map_artist --artist "Rex Orange County"
curl http://localhost:18425 -d '{"jsonrpc":"2.0","id":0,"method":"map_artist","params":{"artist":"Rex Orange County"}}'
Example Response
{
"jsonrpc": "2.0",
"result": {
"artist": {
"name": "Rex Orange County",
"key": 65,
"runtime": 7583,
"albums": [
237
],
"songs": [
2800,
2803,
2809
]
}
},
"id": 0
}
map_album
π‘ Incomplete
This API's output may have additions in the future.
Input an Artist name and Album title, retrieve an Album object.
Inputs
| Field | Type | Description |
|---|---|---|
| artist | string | Artist name |
| album | string | Album title |
Outputs
| Field | Type | Description |
|---|---|---|
| album | Album object | See Album |
Example Request
festival-cli map_album --artist "Rex Orange County" --album RAINBOW
curl http://localhost:18425 -d '{"jsonrpc":"2.0","id":0,"method":"map_album","params":{"artist":"Rex Orange County","album":"RAINBOW"}}'
Example Response
{
"jsonrpc": "2.0",
"result": {
"album": {
"title": "RAINBOW",
"key": 237,
"artist": 65,
"release": "????-??-??",
"runtime": 1090,
"song_count": 6,
"songs": [
2594,
2540,
2600,
2496,
2557,
2500
],
"discs": 0,
"art": 7753,
"genre": null
}
},
"id": 0
}
map_song
π‘ Incomplete
This API's output may have additions in the future.
Input an Artist name, Album title, and Song title, retrieve a Song object.
Inputs
| Field | Type | Description |
|---|---|---|
| artist | string | Artist name |
| album | string | Album title |
| song | string | Song title |
Outputs
| Field | Type | Description |
|---|---|---|
| song | Song object | See Song |
Example Request
festival-cli map_song --artist "Rex Orange County" --album RAINBOW --song SUNFLOWER
curl http://localhost:18425 -d '{"jsonrpc":"2.0","id":0,"method":"map_song","params":{"artist":"Rex Orange County","album":"RAINBOW","song":"SUNFLOWER"}}'
Example Response
{
"jsonrpc": "2.0",
"result": {
"song": {
"title": "SUNFLOWER",
"key": 2539,
"album": 237,
"runtime": 252,
"sample_rate": 44100,
"track": 1,
"disc": null,
"mime": "audio/mpeg",
"extension": "mp3"
}
},
"id": 0
}
map_entry
π’ Stable
This API is stable since festivald v1.0.0.
Input an Artist name, Album title, and Song title, retrieve an Entry object.
Inputs
| Field | Type | Description |
|---|---|---|
| artist | string | Artist name |
| album | string | Album title |
| song | string | Song title |
Outputs
| Field | Type | Description |
|---|---|---|
| entry | Entry object | See Entry |
Example Request
festival-cli map_entry --artist "Rex Orange County" --album RAINBOW --song SUNFLOWER
curl http://localhost:18425 -d '{"jsonrpc":"2.0","id":0,"method":"map_entry","params":{"artist":"Rex Orange County","album":"RAINBOW","song":"SUNFLOWER"}}'
Example Response
{
"jsonrpc": "2.0",
"result": {
"entry": {
"path": "/home/hinto/Music/Rex Orange County/RAINBOW/SUNFLOWER.mp3",
"key_artist": 65,
"key_album": 237,
"key_song": 2539,
"artist": "Rex Orange County",
"album": "RAINBOW",
"song": "SUNFLOWER"
}
},
"id": 0
}
map_artist_albums
π‘ Incomplete
This API's output may have additions in the future.
Input an Artist name, retrieve all of their Album's.
The Album's are sorted by Release date.
Inputs
| Field | Type | Description |
|---|---|---|
| artist | string | Artist name |
Outputs
| Field | Type | Description |
|---|---|---|
| len | unsigned integer | How many Album's there are |
| albums | array of Album objects | See Album |
Example Request
festival-cli map_artist_albums --artist "Rex Orange County"
curl http://localhost:18425 -d '{"jsonrpc":"2.0","id":0,"method":"map_artist_albums","params":{"artist":"Rex Orange County"}}'
Example Response
{
"jsonrpc": "2.0",
"result": {
"len": 3,
"albums": [
{
"title": "Apricot Princess",
"map": 234,
"artist": 62,
"release": "2017",
"runtime": 2370,
"song_count": 10,
"songs": [
2463,
2471,
2483,
2492,
2498,
2504,
2514,
2522,
2530,
2536
],
"discs": 0,
"art": 307745,
"genre": "Pop"
},
{
"title": "Pony",
"map": 241,
"artist": 62,
"release": "2019-09-19",
"runtime": 2032,
"song_count": 10,
"songs": [
2540,
2545,
2548,
2553,
2558,
2567,
2573,
2578,
2581,
2587
],
"discs": 0,
"art": 190830,
"genre": "Alternative & Indie"
},
{
"title": "WHO CARES?",
"map": 247,
"artist": 62,
"release": "2022",
"runtime": 2091,
"song_count": 11,
"songs": [
2590,
2592,
2596,
2598,
2602,
2606,
2607,
2610,
2614,
2618,
2622
],
"discs": 0,
"art": 80994,
"genre": "Alternative & Indie"
}
]
},
"id": 0
}
map_artist_songs
π‘ Incomplete
This API's output may have additions in the future.
Input an Artist name, retrieve all their Song's.
The Song's are sorted by Album release date, then Track + Disc order.
Inputs
| Field | Type | Description |
|---|---|---|
| artist | string | Artist name |
Outputs
| Field | Type | Description |
|---|---|---|
| len | unsigned integer | How many Song's there are |
| songs | array of Song objects | See Song |
Example Request
festival-cli map_artist_songs --artist "Rex Orange County"
curl http://localhost:18425 -d '{"jsonrpc":"2.0","id":0,"method":"map_artist_songs","params":{"artist":"Rex Orange County"}}'
Example Response
{
"jsonrpc": "2.0",
"result": {
"len": 2,
"songs": [
{
"title": "SUNFLOWER",
"map": 2444,
"album": 222,
"runtime": 252,
"sample_rate": 44100,
"track": 1,
"disc": null,
"mime": "audio/mpeg",
"extension": "mp3"
},
{
"title": "BEST FRIEND",
"map": 2398,
"album": 222,
"runtime": 262,
"sample_rate": 44100,
"track": 2,
"disc": null,
"mime": "audio/mpeg",
"extension": "mp3"
}
]
},
"id": 0
}
map_artist_entries
π’ Stable
This API is stable since festivald v1.0.0.
Input an Artist name, retrieve all their Song's in Entry form.
The Entry's are sorted by Album release date, then Track + Disc order.
Inputs
| Field | Type | Description |
|---|---|---|
| artist | string | Artist name |
Outputs
| Field | Type | Description |
|---|---|---|
| len | unsigned integer | How many Entry's there are |
| entries | array of Entry objects | See Entry |
Example Request
festival-cli map_artist_entries --artist "Rex Orange County"
curl http://localhost:18425 -d '{"jsonrpc":"2.0","id":0,"method":"map_artist_entries","params":{"artist":"Rex Orange County"}}'
Example Response
{
"jsonrpc": "2.0",
"result": {
"len": 2,
"entries": [
{
"path": "/home/hinto/Rex Orange County/RAINBOW/SUNFLOWER.mp3",
"key_artist": 62,
"key_album": 222,
"key_song": 2444,
"artist": "Rex Orange County",
"album": "RAINBOW",
"song": "SUNFLOWER"
},
{
"path": "/home/hinto/Rex Orange County/RAINBOW/BEST FRIEND.mp3",
"key_artist": 62,
"key_album": 222,
"key_song": 2398,
"artist": "Rex Orange County",
"album": "RAINBOW",
"song": "BEST FRIEND"
}
]
},
"id": 0
}
map_album_songs
π‘ Incomplete
This API's output may have additions in the future.
Input an Artist name and Album title, retrieve all the Song's in that Album.
The Song's are sorted by Track + Disc order.
Inputs
| Field | Type | Description |
|---|---|---|
| artist | string | Artist name |
| album | string | Album title |
Outputs
| Field | Type | Description |
|---|---|---|
| len | unsigned integer | How many Song's there are |
| songs | array of Song objects | See Song |
Example Request
festival-cli map_album_songs --artist "Rex Orange County" --album RAINBOW
curl http://localhost:18425 -d '{"jsonrpc":"2.0","id":0,"method":"map_album_songs","params":{"artist":"Rex Orange County","album":"RAINBOW"}}'
Example Response
{
"jsonrpc": "2.0",
"result": {
"len": 2,
"songs": [
{
"title": "SUNFLOWER",
"map": 2444,
"album": 222,
"runtime": 252,
"sample_rate": 44100,
"track": 1,
"disc": null,
"mime": "audio/mpeg",
"extension": "mp3"
},
{
"title": "BEST FRIEND",
"map": 2398,
"album": 222,
"runtime": 262,
"sample_rate": 44100,
"track": 2,
"disc": null,
"mime": "audio/mpeg",
"extension": "mp3"
}
]
},
"id": 0
}
map_album_entries
π’ Stable
This API is stable since festivald v1.0.0.
Input an Artist name and Album title, retrieve all the Song's in that Album in Entry form.
The Entry's are sorted by Track + Disc order.
Inputs
| Field | Type | Description |
|---|---|---|
| artist | string | Artist name |
| album | string | Album title |
Outputs
| Field | Type | Description |
|---|---|---|
| len | unsigned integer | How many Entry's there are |
| entries | array of Entry objects | See Entry |
Example Request
festival-cli map_album_entries --artist "Rex Orange County" --album RAINBOW
curl http://localhost:18425 -d '{"jsonrpc":"2.0","id":0,"method":"map_album_entries","params":{"artist":"Rex Orange County","album":"RAINBOW"}}'
Example Response
{
"jsonrpc": "2.0",
"result": {
"len": 2,
"entries": [
{
"path": "/home/hinto/Rex Orange County/RAINBOW/SUNFLOWER.mp3",
"key_artist": 62,
"key_album": 222,
"key_song": 2444,
"artist": "Rex Orange County",
"album": "RAINBOW",
"song": "SUNFLOWER"
},
{
"path": "/home/hinto/Rex Orange County/RAINBOW/BEST FRIEND.mp3",
"key_artist": 62,
"key_album": 222,
"key_song": 2398,
"artist": "Rex Orange County",
"album": "RAINBOW",
"song": "BEST FRIEND"
}
]
},
"id": 0
}
Current
Access the currently set Song, its Album, or its Artist, or in Entry form.
If no Song is set, a JSON-RPC error will be returned.
current_artist
π‘ Incomplete
This API's output may have additions in the future.
Access the Artist of the currently set Song.
Inputs
None
Outputs
| Field | Type | Description |
|---|---|---|
| artist | Artist object | See Artist |
Example Request
festival-cli current_artist
curl http://localhost:18425 -d '{"jsonrpc":"2.0","id":0,"method":"current_artist"}'
Example Response
{
"jsonrpc": "2.0",
"result": {
"artist": {
"name": "Rex Orange County",
"key": 65,
"runtime": 7583,
"albums": [
237
],
"songs": [
2800,
2803,
2809
]
}
},
"id": 0
}
current_album
π‘ Incomplete
This API's output may have additions in the future.
Access the Album of the currently set Song.
Inputs
None
Outputs
| Field | Type | Description |
|---|---|---|
| album | Album object | See Album |
Example Request
festival-cli current_album
curl http://localhost:18425 -d '{"jsonrpc":"2.0","id":0,"method":"current_album"}'
Example Response
{
"jsonrpc": "2.0",
"result": {
"album": {
"title": "RAINBOW",
"key": 237,
"artist": 65,
"release": "????-??-??",
"runtime": 1090,
"song_count": 6,
"songs": [
2594,
2540,
2600,
2496,
2557,
2500
],
"discs": 0,
"art": 7753,
"genre": null
}
},
"id": 0
}
current_song
π‘ Incomplete
This API's output may have additions in the future.
Access the currently set Song.
Inputs
None
Outputs
| Field | Type | Description |
|---|---|---|
| song | Song object | See Song |
Example Request
festival-cli current_song
curl http://localhost:18425 -d '{"jsonrpc":"2.0","id":0,"method":"current_song"}'
Example Response
{
"jsonrpc": "2.0",
"result": {
"song": {
"title": "SUNFLOWER",
"key": 2594,
"album": 237,
"runtime": 252,
"sample_rate": 44100,
"track": 1,
"disc": null,
"mime": "audio/mpeg",
"extension": "mp3"
}
},
"id": 0
}
current_entry
π’ Stable
This API is stable since festivald v1.0.0.
Access the currently set Song, in Entry form.
Inputs
None
Outputs
| Field | Type | Description |
|---|---|---|
| entry | Entry object | See Entry |
Example Request
festival-cli current_entry
curl http://localhost:18425 -d '{"jsonrpc":"2.0","id":0,"method":"current_entry"}'
Example Response
{
"jsonrpc": "2.0",
"result": {
"entry": {
"path": "/home/hinto/Music/Rex Orange County/RAINBOW/SUNFLOWER.mp3",
"key_artist": 65,
"key_album": 237,
"key_song": 2539,
"artist": "Rex Orange County",
"album": "RAINBOW",
"song": "SUNFLOWER"
}
},
"id": 0
}
Rand
Access a random Song, Album, or Artist, or in Entry form.
If the Collection is empty, a JSON-RPC error will be returned.
Repeating is not prevented, so there is nothing preventing you from retrieving the same object multiple times in a row.
rand_artist
π‘ Incomplete
This API's output may have additions in the future.
Access a random Artist in your Collection.
Inputs
None
Outputs
| Field | Type | Description |
|---|---|---|
| artist | Artist object | See Artist |
Example Request
festival-cli rand_artist
curl http://localhost:18425 -d '{"jsonrpc":"2.0","id":0,"method":"rand_artist"}'
Example Response
{
"jsonrpc": "2.0",
"result": {
"artist": {
"name": "γ«γγ³γ’γ€γ",
"key": 65,
"runtime": 4709,
"albums": [
276,
256
],
"songs": [
2883,
2504,
2859,
2863,
2866,
2869,
2873,
2874,
2693,
2694
]
}
},
"id": 0
}
rand_album
π‘ Incomplete
This API's output may have additions in the future.
Access a random Album in your Collection.
Inputs
None
Outputs
| Field | Type | Description |
|---|---|---|
| album | Album object | See Album |
Example Request
festival-cli rand_album
curl http://localhost:18425 -d '{"jsonrpc":"2.0","id":0,"method":"rand_album"}'
Example Response
{
"jsonrpc": "2.0",
"result": {
"album": {
"title": "hug",
"key": 243,
"artist": 65,
"release": "2016",
"runtime": 1276,
"song_count": 5,
"songs": [
2541,
2546,
2550,
2554,
2556
],
"discs": 0,
"art": 220954,
"genre": null
}
},
"id": 0
}
rand_song
π‘ Incomplete
This API's output may have additions in the future.
Access a random Song in your Collection.
Inputs
None
Outputs
| Field | Type | Description |
|---|---|---|
| song | Song object | See Song |
Example Request
festival-cli rand_song
curl http://localhost:18425 -d '{"jsonrpc":"2.0","id":0,"method":"rand_song"}'
Example Response
{
"jsonrpc": "2.0",
"result": {
"song": {
"title": "Home Alone",
"key": 2825,
"album": 269,
"runtime": 182,
"sample_rate": 48000,
"track": 1,
"disc": 1,
"mime": "audio/x-flac",
"extension": "flac"
}
},
"id": 0
}
rand_entry
π’ Stable
This API is stable since festivald v1.0.0.
Access a random Entry in your Collection.
Inputs
None
Outputs
| Field | Type | Description |
|---|---|---|
| entry | Entry object | See Entry |
Example Request
festival-cli rand_entry
curl http://localhost:18425 -d '{"jsonrpc":"2.0","id":0,"method":"rand_entry"}'
Example Response
{
"jsonrpc": "2.0",
"result": {
"entry": {
"path": "/home/hinto/Music/γ«γγ³γ’γ€γ/η₯η₯/Home Alone.flac",
"key_artist": 65,
"key_album": 269,
"key_song": 2825,
"artist": "γ«γγ³γ’γ€γ",
"album": "η₯η₯",
"song": "Home Alone"
}
},
"id": 0
}
Search
Fuzzy similarity searches for Song's, Album's, Artist's, and Entry's.
In general: input a string, receive some objects that are similar to the input.
If you know the exact string for a Song, Album, or Artist, consider using the Map methods instead for a direct lookup.
If you know the exact key, use the Key methods instead.
Kind
These are different "kinds" of searches you can do, affecting the result output.
Each search method requires one of these as input.
All of these return objects sorted from most-to-least similar.
| Kind | Description |
|---|---|
all | ALL objects will be returned |
sim60 | Only objects 60% similar |
sim70 | Only objects 70% similar |
sim80 | Only objects 80% similar |
top25 | Only the top 25 results |
top5 | Only the top 5 results |
top1 | Only the top result |
Warning
The output array may return empty given no matches or an empty Collection:
{
"jsonrpc": "2.0",
"result": {
"songs": []
},
"id": 0
}
search
π‘ Incomplete
This API's output may have additions in the future.
Input a string, retrieve arrays of Artist's, Album's, and Song's, sorted by how similar their names/titles are to the input.
Inputs
| Field | Type | Description |
|---|---|---|
| input | string | The string to match against, to use as input |
| kind | string, one of all, sim60, sim70, sim80, top25, top5, top1 | See Search/Kind |
Outputs
| Field | Type | Description |
|---|---|---|
| artists | array of Artist objects | An array of Artist objects, sorted by most similar name first |
| albums | array of Album objects | An array of Album objects, sorted by most similar title first |
| songs | array of Song objects | An array of Song objects, sorted by most similar title first |
Example Request
festival-cli search --input twice --kind sim70
curl http://localhost:18425 -d '{"jsonrpc":"2.0","id":0,"method":"search","params":{"input":"twice","kind":"sim70"}}'
Example Response
{
"jsonrpc": "2.0",
"result": {
"artists": [
{
"name": "TWICE",
"key": 106,
"runtime": 343,
"albums": [
598
],
"songs": [
5411
]
},
],
"albums": [
{
"title": "TIME",
"key": 271,
"artist": 42,
"release": "2014-01-21",
"runtime": 2904,
"song_count": 3,
"songs": [
3058,
3095,
3121
],
"discs": 0,
"art": 1264656,
"genre": null
}
],
"songs": [
{
"title": "TIME",
"key": 5560,
"album": 538,
"runtime": 249,
"sample_rate": 44100,
"track": 5,
"disc": 1,
"mime": "audio/x-flac",
"extension": "flac"
}
]
},
"id": 0
}
search_artist
π‘ Incomplete
This API's output may have additions in the future.
Input a string, retrieve an array of Artist's, sorted by how similar their names are to the input.
Inputs
| Field | Type | Description |
|---|---|---|
| input | string | The string to match against, to use as input |
| kind | string, one of all, sim60, sim70, sim80, top25, top5, top1 | See Search/Kind |
Outputs
| Field | Type | Description |
|---|---|---|
| artists | array of Artist objects | An array of Artist objects, sorted by most similar name first |
Example Request
festival-cli search_artist --input twice --kind sim70
curl http://localhost:18425 -d '{"jsonrpc":"2.0","id":0,"method":"search_artist","params":{"input":"twice","kind":"sim70"}}'
Example Response
{
"jsonrpc": "2.0",
"result": {
"artists": [
{
"name": "TWICE",
"key": 106,
"runtime": 343,
"albums": [
598
],
"songs": [
5411
]
}
]
},
"id": 0
}
search_album
π‘ Incomplete
This API's output may have additions in the future.
Input a string, retrieve an array of Album's, sorted by how similar their titles are to the input.
Inputs
| Field | Type | Description |
|---|---|---|
| input | string | The string to match against, to use as input |
| kind | string, one of all, sim60, sim70, sim80, top25, top5, top1 | See Search/Kind |
Outputs
| Field | Type | Description |
|---|---|---|
| albums | array of Album objects | An array of Album objects, sorted by most similar title first |
Example Request
festival-cli search_album --input time --kind sim70
curl http://localhost:18425 -d '{"jsonrpc":"2.0","id":0,"method":"search_album","params":{"input":"time","kind":"sim70"}}'
Example Response
{
"jsonrpc": "2.0",
"result": {
"albums": [
{
"title": "TIME",
"key": 271,
"artist": 42,
"release": "2014-01-21",
"runtime": 2904,
"song_count": 3,
"songs": [
3058,
3095,
3121
],
"discs": 0,
"art": 1264656,
"genre": null
}
]
},
"id": 0
}
search_song
π‘ Incomplete
This API's output may have additions in the future.
Input a string, retrieve an array of Song's, sorted by how similar their titles are to the input.
Inputs
| Field | Type | Description |
|---|---|---|
| input | string | The string to match against, to use as input |
| kind | string, one of all, sim60, sim70, sim80, top25, top5, top1 | See Search/Kind |
Outputs
| Field | Type | Description |
|---|---|---|
| songs | array of Song objects | An array of Song objects, sorted by most similar title first |
Example Request
festival-cli search_song --input time --kind sim70
curl http://localhost:18425 -d '{"jsonrpc":"2.0","id":0,"method":"search_song","params":{"input":"time","kind":"sim70"}}'
Example Response
{
"jsonrpc": "2.0",
"result": {
"songs": [
{
"title": "TIME",
"key": 5412,
"album": 528,
"runtime": 249,
"sample_rate": 44100,
"track": 5,
"disc": 1,
"mime": "audio/x-flac",
"extension": "flac"
}
]
},
"id": 0
}
search_entry
π’ Stable
This API is stable since festivald v1.0.0.
Input a string, retrieve an array of Song's (in Entry form), sorted by how similar their titles are to the input.
Inputs
| Field | Type | Description |
|---|---|---|
| input | string | The string to match against, to use as input |
| kind | string, one of all, sim60, sim70, sim80, top25, top5, top1 | See Search/Kind |
Outputs
| Field | Type | Description |
|---|---|---|
| entries | Entry object | See Entry |
Example Request
festival-cli search_entry --input time --kind top1
curl http://localhost:18425 -d '{"jsonrpc":"2.0","id":0,"method":"search_entry","params":{"input":"time","kind":"top1"}}'
Example Response
{
"jsonrpc": "2.0",
"result": {
"entries": [
{
"path": "/home/hinto/Music/Kero Kero Bonito/Time 'n' Place/Time Today.flac",
"key_artist": 148,
"key_album": 665,
"key_song": 6768,
"artist": "Kero Kero Bonito",
"album": "Time 'n' Place",
"song": "Time Today"
}
]
},
"id": 0
}
Playback Control
Methods for controlling festivald audio playback, shuffling, seeking, etc.
Most of the responses of these methods will be the generic null response, indicating success.
See Queue for adding/removing Song's from the queue.
toggle
π‘ Incomplete
This API's output may have additions in the future.
Toggle playback.
Inputs
None
Outputs
null if everything went ok.
Example Request
festival-cli toggle
curl http://localhost:18425 -d '{"jsonrpc":"2.0","id":0,"method":"toggle"}'
Example Response
{
"jsonrpc": "2.0",
"result": null, // <--- everything went ok.
"id": 0
}
play
π‘ Incomplete
This API's output may have additions in the future.
Start playback.
Inputs
None
Outputs
null if everything went ok.
Example Request
festival-cli play
curl http://localhost:18425 -d '{"jsonrpc":"2.0","id":0,"method":"play"}'
Example Response
{
"jsonrpc": "2.0",
"result": null, // <--- everything went ok.
"id": 0
}
pause
π‘ Incomplete
This API's output may have additions in the future.
Pause playback.
Inputs
None
Outputs
null if everything went ok.
Example Request
festival-cli pause
curl http://localhost:18425 -d '{"jsonrpc":"2.0","id":0,"method":"pause"}'
Example Response
{
"jsonrpc": "2.0",
"result": null, // <--- everything went ok.
"id": 0
}
clear
π‘ Incomplete
This API's output may have additions in the future.
Clear the queue.
Inputs
| Field | Type | Description |
|---|---|---|
| playback | boolean | If there is a Song currently set and playing, should we continue playback? |
Outputs
| Field | Type | Description |
|---|---|---|
| len | unsigned integer | Amount of Song's cleared from the queue |
Example Request
festival-cli clear
curl http://localhost:18425 -d '{"jsonrpc":"2.0","id":0,"method":"clear","params":{"playback":false}}'
Example Response
{
"jsonrpc": "2.0",
"result": {
"len": 207
},
"id": 0
}
stop
π‘ Incomplete
This API's output may have additions in the future.
Clear the queue and stop playback.
Inputs
None
Outputs
| Field | Type | Description |
|---|---|---|
| len | unsigned integer | Amount of Song's cleared from the queue |
Example Request
festival-cli stop
curl http://localhost:18425 -d '{"jsonrpc":"2.0","id":0,"method":"stop"}'
Example Response
{
"jsonrpc": "2.0",
"result": {
"len": 207
},
"id": 0
}
next
π‘ Incomplete
This API's output may have additions in the future.
Skip to the next song in the queue.
Ends the queue (or repeats if a repeat mode is on) if at the last song.
Does nothing if the queue is empty.
Inputs
None
Outputs
null if everything went ok.
Example Request
festival-cli next
curl http://localhost:18425 -d '{"jsonrpc":"2.0","id":0,"method":"next"}'
Example Response
{
"jsonrpc": "2.0",
"result": null, // <--- everything went ok.
"id": 0
}
previous
π‘ Incomplete
This API's output may have additions in the future.
Set the current Song to the previous in the queue.
If threshold is not specified, the previous_threshold config option will be used.
Inputs
| Field | Type | Description |
|---|---|---|
| threshold | optional (maybe-null) unsigned integer | If the current Song runtime (seconds) has passed this number, this method will reset the current Song instead of skipping backwards. Setting this to 0 will make this method always go to the previous Song. |
Outputs
null if everything went ok.
Example Request
festival-cli previous --threshold 0
curl http://localhost:18425 -d '{"jsonrpc":"2.0","id":0,"method":"previous","params":{"threshold":0}}'
Example Response
{
"jsonrpc": "2.0",
"result": null, // <--- everything went ok.
"id": 0
}
skip
π‘ Incomplete
This API's output may have additions in the future.
Skip forward a variable amount of Song's in the queue.
Inputs
| Field | Type | Description |
|---|---|---|
| skip | unsigned integer | How many Song's to skip. If greater than the rest of the Song's in the queue, the queue will end (unless a repeat mode is on). |
Outputs
null if everything went ok.
Example Request
festival-cli skip --skip 3
curl http://localhost:18425 -d '{"jsonrpc":"2.0","id":0,"method":"skip","params":{"skip":3}}'
Example Response
{
"jsonrpc": "2.0",
"result": null, // <--- everything went ok.
"id": 0
}
back
π‘ Incomplete
This API's output may have additions in the future.
Go backwards a variable amount of Song's in the queue.
This method ignores the previous_threshold config option, it will always go back.
Inputs
| Field | Type | Description |
|---|---|---|
| back | unsigned integer | How many Song's to go backwards. This will not wrap around if we hit the 1st Song in the queue. |
Outputs
null if everything went ok.
Example Request
festival-cli back --back 10
curl http://localhost:18425 -d '{"jsonrpc":"2.0","id":0,"method":"back","params":{"back":10}}'
Example Response
{
"jsonrpc": "2.0",
"result": null, // <--- everything went ok.
"id": 0
}
seek
π‘ Incomplete
This API's output may have additions in the future.
Seek forwards/backwards or to an absolute second in the current Song.
Seeking forwards pass the remaining Song length will finish the Song.
Seeking to an absolute position longer than the Song length will also finish the Song.
Seeking backwards more than already-played Song length will reset the Song.
Inputs
| Field | Type | Description |
|---|---|---|
| kind | string, one of forward, backward, absolute | The "type" of seeking we should do. forward means advance the current Song by the provided second. backward means go back in the current Song by the provided second. absolute means skip to the exact second in the Song, e.g, to skip to the 1 minute mark in the current Song, you would use absolute + 60. |
| second | unsigned integer | The second to seek forward/backwards/to. |
Outputs
null if everything went ok.
Example Request
festival-cli seek --kind absolute --second 60
curl http://localhost:18425 -d '{"jsonrpc":"2.0","id":0,"method":"seek","params":{"kind":"absolute","second":60}}'
Example Response
{
"jsonrpc": "2.0",
"result": null, // <--- everything went ok.
"id": 0
}
shuffle
π‘ Incomplete
This API's output may have additions in the future.
Shuffle the current queue, then set the current Song to the 1st Song in the queue.
Inputs
None
Outputs
null if everything went ok.
Example Request
festival-cli shuffle
curl http://localhost:18425 -d '{"jsonrpc":"2.0","id":0,"method":"shuffle"}'
Example Response
{
"jsonrpc": "2.0",
"result": null, // <--- everything went ok.
"id": 0
}
repeat
π’ Stable
This API is stable since festivald v1.0.0.
Set the playback repeat mode.
Inputs
| Field | Type | Description |
|---|---|---|
| mode | string, one of off, song, queue | The repeat mode to set. off turns off repeating, song turns on Song repeating, queue turns on queue repeating. |
Outputs
| Field | Type | Description |
|---|---|---|
| previous | string, one of off, song, queue | What the repeat mode was set to previously |
| current | string, one of off, song, queue | What the repeat mode is now set at |
Example Request
festival-cli repeat --mode off
curl http://localhost:18425 -d '{"jsonrpc":"2.0","id":0,"method":"repeat","params":{"mode":"off"}}'
Example Response
{
"jsonrpc": "2.0",
"result": {
"previous": "off",
"current": "song"
},
"id": 0
}
volume
π’ Stable
This API is stable since festivald v1.0.0.
Set the playback volume.
Inputs
| Field | Type | Description |
|---|---|---|
| volume | unsigned integer | The volume % to set. Must be in-between 0..100. If greater than 100, it will set the volume to 100. |
Outputs
| Field | Type | Description |
|---|---|---|
| previous | unsigned integer | What the volume was set to previously |
| current | unsigned integer | What the volume is now set at |
Example Request
festival-cli volume --volume 15
curl http://localhost:18425 -d '{"jsonrpc":"2.0","id":0,"method":"volume","params":{"volume":15}}'
Example Response
{
"jsonrpc": "2.0",
"result": {
"previous": 0,
"current": 15
},
"id": "festival-cli"
}
volume_up
π’ Stable
This API is stable since festivald v1.0.0.
Raise the playback volume.
Inputs
| Field | Type | Description |
|---|---|---|
| up | unsigned integer | The number to raise the volume by. Must be in-between 0..100. If greater than 100, it will set the volume to 100. Volume cannot go higher than 100. |
Outputs
| Field | Type | Description |
|---|---|---|
| previous | unsigned integer | What the volume was set to previously |
| current | unsigned integer | What the volume is now set at |
Example Request
festival-cli volume_up --up 15
curl http://localhost:18425 -d '{"jsonrpc":"2.0","id":0,"method":"volume_up","params":{"up":15}}'
Example Response
{
"jsonrpc": "2.0",
"result": {
"previous": 0,
"current": 15
},
"id": "festival-cli"
}
volume_down
π’ Stable
This API is stable since festivald v1.0.0.
Lower the playback volume.
Inputs
| Field | Type | Description |
|---|---|---|
| down | unsigned integer | The number to lower the volume by. Must be in-between 0..100. Volume cannot go lower than 0. |
Outputs
| Field | Type | Description |
|---|---|---|
| previous | unsigned integer | What the volume was set to previously |
| current | unsigned integer | What the volume is now set at |
Example Request
festival-cli volume_down --down 15
curl http://localhost:18425 -d '{"jsonrpc":"2.0","id":0,"method":"volume_down","params":{"down":15}}'
Example Response
{
"jsonrpc": "2.0",
"result": {
"previous": 15,
"current": 0
},
"id": "festival-cli"
}
Queue
Methods for adding/removing Songs to/from the queue.
Append
These are different way you can append to the queue.
All queue methods involving appending requires one of these as input.
| Kind | Description |
|---|---|
front | Append Song(s) to the front of the queue |
back | Append Song(s) to the back of the queue |
index | Append Song(s) at a specific index in the queue. Queue index starts at 0, so to mimic front, you would provide 0. |
If the index append is used, the separate index field must be non-null and provide an index.
The way this works is that the provided Song(s)'s will be inserted into the queue, starting from that index, for example:
#![allow(unused)] fn main() { // Our queue. [0] Song A // <- Currently Playing. [1] Song A [2] Song A // The songs we'd like to add at `index 2` Song B Song B Song B // The queue after appending. [0] Song A // <- Currently Playing. [1] Song A [2] Song B // <- our songs were inserted [3] Song B // into the queue, starting [4] Song B // from index 2. [5] Song A }
offset
All queue methods involving appending multiple Song's has an optional input: offset.
If the method happens to set the current Song (added to empty queue, added to front, etc), this field lets you start at a particular Song offset in the Artist/Album/Playlist.
The Song's before the offset will still be added, but the current Song set will be the one at the offset.
The exact ordering of the Artist's songs and what the offsets are relative to is the same as the object's internal ordering: Album in release order, then Song track order.
Ordering for an Album's songs is by Track + Disc order.
Ordering for Playlist is just their regular array order.
For example, given "offset": 3:
#![allow(unused)] fn main() { // Artist's songs. [0] song_1 // <----/ These are still added to the queue, but.. [1] song_2 // <---/ [2] song_3 // <--/ [3] song_4 // <-/ We will start playing from this `Song`. [4] song_5 [5] song_6 }
queue_add_key_artist
π‘ Incomplete
This API's output may have additions in the future.
Add an Artist to the queue with an Artist key.
Inputs
| Field | Type | Description |
|---|---|---|
| key | Artist key (unsigned integer) | See Key |
| append | string, one of front, back or index | See Queue/Append |
| clear | boolean | Should the queue be cleared before adding? |
| play | boolean | Should we start playing? |
| index | optional (maybe-null) unsigned integer | If the index append is chosen, this will be the index used |
| offset | optional (maybe-null) unsigned integer | See Queue/offset |
Outputs
result: null if everything went ok.
error: ... if there was an index/offset error.
Example Request 1
Add to back of the queue.
festival-cli queue_add_key_artist --key 123 --append back
curl http://localhost:18425 -d '{"jsonrpc":"2.0","id":0,"method":"queue_add_key_artist","params":{"key":123,"append":"back","clear":false,"play":false}}'
Example Request 2
Insert at queue index 4.
festival-cli queue_add_key_artist --key 123 --append index --index 4
curl http://localhost:18425 -d '{"jsonrpc":"2.0","id":0,"method":"queue_add_key_artist","params":{"key":123,"append":"index","clear":false,"play":false,"index":4}}'
Example Request 3
Clear the queue, add all the Song's by this Artist, but start at the 5th Song (offset 4).
festival-cli queue_add_key_artist --key 123 --append front --clear --play --offset 4
curl http://localhost:18425 -d '{"jsonrpc":"2.0","id":0,"method":"queue_add_key_artist","params":{"key":123,"append":"front","clear":true,"play":true,"offset":4}}'
Example Response
{
"jsonrpc": "2.0",
"result": null, // <--- everything went ok.
"id": 0
}
queue_add_key_album
π‘ Incomplete
This API's output may have additions in the future.
Add an Album to the queue with an Album key.
Inputs
| Field | Type | Description |
|---|---|---|
| key | Album key (unsigned integer) | See Key |
| append | string, one of front, back or index | See Queue/Append |
| clear | boolean | Should the queue be cleared before adding? |
| play | boolean | Should we start playing? |
| index | optional (maybe-null) unsigned integer | If the index append is chosen, this will be the index used |
| offset | optional (maybe-null) unsigned integer | See Queue/offset |
Outputs
result: null if everything went ok.
error: ... if there was an index/offset error.
Example Request 1
Add to back of the queue.
festival-cli queue_add_key_album --key 123 --append back
curl http://localhost:18425 -d '{"jsonrpc":"2.0","id":0,"method":"queue_add_key_album","params":{"key":123,"append":"back","clear":false,"play":false}}'
Example Request 2
Insert at queue index 4.
festival-cli queue_add_key_album --key 123 --append index --index 4
curl http://localhost:18425 -d '{"jsonrpc":"2.0","id":0,"method":"queue_add_key_album","params":{"key":123,"append":"index","clear":false,"play":false,"index":4}}'
Example Request 3
Clear the queue, add all the Song's in this Album, but start at the 5th Song (offset 4).
festival-cli queue_add_key_album --key 123 --append front --clear --play --offset 4
curl http://localhost:18425 -d '{"jsonrpc":"2.0","id":0,"method":"queue_add_key_album","params":{"key":123,"append":"front","clear":true,"play":true,"offset":4}}'
Example Response
{
"jsonrpc": "2.0",
"result": null, // <--- everything went ok.
"id": 0
}
queue_add_key_song
π‘ Incomplete
This API's output may have additions in the future.
Add a Song to the queue with a Song key.
Inputs
| Field | Type | Description |
|---|---|---|
| key | Song key (unsigned integer) | See Key |
| append | string, one of front, back or index | See Queue/Append |
| clear | boolean | Should the queue be cleared before adding? |
| play | boolean | Should we start playing? |
| index | optional (maybe-null) unsigned integer | If the index append is chosen, this will be the index used |
Outputs
result: null if everything went ok.
error: ... if there was an index/offset error.
Example Request 1
Add to back of the queue.
festival-cli queue_add_key_song --key 123 --append back
curl http://localhost:18425 -d '{"jsonrpc":"2.0","id":0,"method":"queue_add_key_song","params":{"key":123,"append":"back","clear":false,"play":false}'
Example Request 2
Insert at queue index 4.
festival-cli queue_add_key_song --key 123 --append index --index 4
curl http://localhost:18425 -d '{"jsonrpc":"2.0","id":0,"method":"queue_add_key_song","params":{"key":123,"append":"index","clear":false,"play":false,"index":4}'
Example Request 3
Clear the queue, add Song 123.
festival-cli queue_add_key_song --key 123 --append front --clear --play
curl http://localhost:18425 -d '{"jsonrpc":"2.0","id":0,"method":"queue_add_key_song","params":{"key":123,"append":"front","clear":true,"play":true}'
Example Response
{
"jsonrpc": "2.0",
"result": null, // <--- everything went ok.
"id": 0
}
queue_add_map_artist
π‘ Incomplete
This API's output may have additions in the future.
Add an Artist to the queue with an Artist name.
Inputs
| Field | Type | Description |
|---|---|---|
| artist | string | Artist name |
| append | string, one of front, back or index | See Queue/Append |
| clear | boolean | Should the queue be cleared before adding? |
| play | boolean | Should we start playing? |
| index | optional (maybe-null) unsigned integer | If the index append is chosen, this will be the index used |
| offset | optional (maybe-null) unsigned integer | See Queue/offset |
Outputs
result: null if everything went ok.
error: ... if there was an index/offset error.
Example Request 1
Add to back of the queue.
festival-cli queue_add_map_artist --artist TWICE --append back
curl http://localhost:18425 -d '{"jsonrpc":"2.0","id":0,"method":"queue_add_map_artist","params":{"artist":"TWICE","append":"back","clear":false,"play":false}}'
Example Request 2
Insert at queue index 4.
festival-cli queue_add_map_artist --artist TWICE --append index --index 4
curl http://localhost:18425 -d '{"jsonrpc":"2.0","id":0,"method":"queue_add_map_artist","params":{"artist":"TWICE","append":"index","clear":false,"play":false,"index":4}}'
Example Request 3
Clear the queue, add all the Song's by this Artist, but start at the 5th Song (offset 4).
festival-cli queue_add_map_artist --artist TWICE --append front --clear --play --offset 4
curl http://localhost:18425 -d '{"jsonrpc":"2.0","id":0,"method":"queue_add_map_artist","params":{"artist":"TWICE","append":"front","clear":true,"play":true,"offset":4}}'
Example Response
{
"jsonrpc": "2.0",
"result": null, // <--- everything went ok.
"id": 0
}
queue_add_map_album
π‘ Incomplete
This API's output may have additions in the future.
Add an Album to the queue with an Artist name and Album title.
Inputs
| Field | Type | Description |
|---|---|---|
| artist | string | Artist name |
| album | string | Album title |
| append | string, one of front, back or index | See Queue/Append |
| clear | boolean | Should the queue be cleared before adding? |
| play | boolean | Should we start playing? |
| index | optional (maybe-null) unsigned integer | If the index append is chosen, this will be the index used |
| offset | optional (maybe-null) unsigned integer | See Queue/offset |
Outputs
result: null if everything went ok.
error: ... if there was an index/offset error.
Example Request 1
Add to back of the queue.
festival-cli queue_add_map_album --artist TWICE --album "PAGE TWO" --append back
curl http://localhost:18425 -d '{"jsonrpc":"2.0","id":0,"method":"queue_add_map_album","params":{"artist":"TWICE","album":"PAGE TWO","append":"back","clear":false,"play":false}}'
Example Request 2
Insert at queue index 4.
festival-cli queue_add_map_album --artist TWICE --album "PAGE TWO" --append index --index 4
curl http://localhost:18425 -d '{"jsonrpc":"2.0","id":0,"method":"queue_add_map_album","params":{"artist":"TWICE","album":"PAGE TWO","append":"index","clear":false,"play":false,"index":4}}'
Example Request 3
Clear the queue, add all the Song's in this Album, but start at the 5th Song (offset 4).
festival-cli queue_add_map_album --artist TWICE --album "PAGE TWO" --append front --clear --play --offset 4
curl http://localhost:18425 -d '{"jsonrpc":"2.0","id":0,"method":"queue_add_map_album","params":{"artist":"TWICE","album":"PAGE TWO","append":"front","clear":true,"play":true,"offset":4}}'
Example Response
{
"jsonrpc": "2.0",
"result": null, // <--- everything went ok.
"id": 0
}
queue_add_map_song
π‘ Incomplete
This API's output may have additions in the future.
Add a Song to the queue with an Artist name Album title, and Song title.
Inputs
| Field | Type | Description |
|---|---|---|
| artist | string | Artist name |
| album | string | Album title |
| song | string | Song title |
| append | string, one of front, back or index | See Queue/Append |
| clear | boolean | Should the queue be cleared before adding? |
| play | boolean | Should we start playing? |
| index | optional (maybe-null) unsigned integer | If the index append is chosen, this will be the index used |
Outputs
result: null if everything went ok.
error: ... if there was an index/offset error.
Example Request 1
Add to back of the queue.
festival-cli queue_add_map_song --artist TWICE --album "PAGE TWO" --song "CHEER UP" --append back
curl http://localhost:18425 -d '{"jsonrpc":"2.0","id":0,"method":"queue_add_map_song","params":{"artist":"TWICE","album":"PAGE TWO","song":"CHEER UP","append":"back","clear":false,"play":false}}'
Example Request 2
Insert at queue index 4, start from Song 3 (offset 2).
festival-cli queue_add_map_song --artist TWICE --album "PAGE TWO" --song "CHEER UP" --append index --index 4
curl http://localhost:18425 -d '{"jsonrpc":"2.0","id":0,"method":"queue_add_map_song","params":{"artist":"TWICE","album":"PAGE TWO","song":"CHEER UP","append":"index","clear":false,"play":false,"index":4}}'
Example Request 3
Clear the queue, add the Song "CHEER UP".
festival-cli queue_add_map_song --artist TWICE --album "PAGE TWO" --song "CHEER UP" --append front --clear --play
curl http://localhost:18425 -d '{"jsonrpc":"2.0","id":0,"method":"queue_add_map_song","params":{"artist":"TWICE","album":"PAGE TWO","song":"CHEER UP","append":"front","clear":true,"play":true}}'
Example Response
{
"jsonrpc": "2.0",
"result": null, // <--- everything went ok.
"id": 0
}
queue_add_rand_artist
π‘ Incomplete
This API's output may have additions in the future.
Add a random Artist to the queue.
Inputs
| Field | Type | Description |
|---|---|---|
| append | string, one of front, back or index | See Queue/Append |
| clear | boolean | Should the queue be cleared before adding? |
| play | boolean | Should we start playing? |
| index | optional (maybe-null) unsigned integer | If the index append is chosen, this will be the index used |
| offset | optional (maybe-null) unsigned integer | See Queue/offset |
Outputs
| Field | Type | Description |
|---|---|---|
| artist | Artist object | The Artist that was added to the queue |
Example Request 1
Add to back of the queue.
festival-cli queue_add_rand_artist --append back
curl http://localhost:18425 -d '{"jsonrpc":"2.0","id":0,"method":"queue_add_rand_artist","params":{"append":"back","clear":false,"play":false}}'
Example Request 2
Insert at queue index 4.
festival-cli queue_add_rand_artist --append index --index 4
curl http://localhost:18425 -d '{"jsonrpc":"2.0","id":0,"method":"queue_add_rand_artist","params":{"append":"index","clear":false,"play":false,"index":4}}'
Example Request 3
Clear the queue, add all the Song's by this Artist, but start at the 5th Song (offset 4).
festival-cli queue_add_rand_artist --append front --clear --play --offset 4
curl http://localhost:18425 -d '{"jsonrpc":"2.0","id":0,"method":"queue_add_rand_artist","params":{"append":"front","clear":true,"play":true,"offset":4}}'
Example Response
{
"jsonrpc": "2.0",
"result": {
"artist": {
"name": "Rex Orange County",
"key": 65,
"runtime": 7583,
"albums": [
237
],
"songs": [
2800,
2803,
2809
]
}
},
"id": 0
}
queue_add_rand_album
π‘ Incomplete
This API's output may have additions in the future.
Add a random Album to the queue.
Inputs
| Field | Type | Description |
|---|---|---|
| append | string, one of front, back or index | See Queue/Append |
| clear | boolean | Should the queue be cleared before adding? |
| play | boolean | Should we start playing? |
| index | optional (maybe-null) unsigned integer | If the index append is chosen, this will be the index used |
| offset | optional (maybe-null) unsigned integer | See Queue/offset |
Outputs
| Field | Type | Description |
|---|---|---|
| album | Album object | The Album that was added to the queue |
Example Request 1
Add to back of the queue.
festival-cli queue_add_rand_album --append back
curl http://localhost:18425 -d '{"jsonrpc":"2.0","id":0,"method":"queue_add_rand_album","params":{"append":"back","clear":false,"play":false}}'
Example Request 2
Insert at queue index 4.
festival-cli queue_add_rand_album --append index --index 4
curl http://localhost:18425 -d '{"jsonrpc":"2.0","id":0,"method":"queue_add_rand_album","params":{"append":"index","clear":false,"play":false,"index":4}}'
Example Request 3
Clear the queue, add all the Song's in this Album, but start at the 5th Song (offset 4).
festival-cli queue_add_rand_album --append front --clear --play --offset 4
curl http://localhost:18425 -d '{"jsonrpc":"2.0","id":0,"method":"queue_add_rand_album","params":{"append":"front","clear":true,"play":true,"offset":4}}'
Example Response
{
"jsonrpc": "2.0",
"result": {
"album": {
"title": "RAINBOW",
"key": 237,
"artist": 65,
"release": "????-??-??",
"runtime": 1090,
"song_count": 6,
"songs": [
2594,
2540,
2600,
2496,
2557,
2500
],
"discs": 0,
"art": 7753,
"genre": null
}
},
"id": 0
}
queue_add_rand_song
π‘ Incomplete
This API's output may have additions in the future.
Add a random Song to the queue.
Inputs
| Field | Type | Description |
|---|---|---|
| append | string, one of front, back or index | See Queue/Append |
| clear | boolean | Should the queue be cleared before adding? |
| play | boolean | Should we start playing? |
| index | optional (maybe-null) unsigned integer | If the index append is chosen, this will be the index used |
Outputs
| Field | Type | Description |
|---|---|---|
| song | Song object | The Song that was added to the queue |
Example Request 1
Add to back of the queue.
festival-cli queue_add_rand_song --append back
curl http://localhost:18425 -d '{"jsonrpc":"2.0","id":0,"method":"queue_add_rand_song","params":{"append":"back","clear":false,"play":false}}'
Example Request 2
Insert at queue index 4.
festival-cli queue_add_rand_song --append index --index 4
curl http://localhost:18425 -d '{"jsonrpc":"2.0","id":0,"method":"queue_add_rand_song","params":{"append":"index","clear":false,"play":false,"index":4}}'
Example Request 3
Clear the queue, add to front of queue.
festival-cli queue_add_rand_song --append front --clear --play
curl http://localhost:18425 -d '{"jsonrpc":"2.0","id":0,"method":"queue_add_rand_song","params":{"append":"front","clear":true,"play":true}}'
Example Response
{
"jsonrpc": "2.0",
"result": {
"song": {
"title": "SUNFLOWER",
"key": 2594,
"album": 237,
"runtime": 252,
"sample_rate": 44100,
"track": 1,
"disc": null,
"mime": "audio/mpeg",
"extension": "mp3"
}
},
"id": 0
}
queue_add_rand_entry
π‘ Incomplete
This API's output may have additions in the future.
Add a random Song to the queue, receive it back in Entry form.
This is the same as queue_add_rand_song but returns an Entry.
Inputs
| Field | Type | Description |
|---|---|---|
| append | string, one of front, back or index | See Queue/Append |
| clear | boolean | Should the queue be cleared before adding? |
| play | boolean | Should we start playing? |
| index | optional (maybe-null) unsigned integer | If the index append is chosen, this will be the index used |
Outputs
| Field | Type | Description |
|---|---|---|
| entry | Entry object | The Song that was added to the queue, in Entry form |
Example Request 1
Add to back of the queue.
festival-cli queue_add_rand_entry --append back
curl http://localhost:18425 -d '{"jsonrpc":"2.0","id":0,"method":"queue_add_rand_entry","params":{"append":"back","clear":false,"play":false}}'
Example Request 2
Insert at queue index 4.
festival-cli queue_add_rand_entry --append index --index 4
curl http://localhost:18425 -d '{"jsonrpc":"2.0","id":0,"method":"queue_add_rand_entry","params":{"append":"index","clear":false,"play":false,"index":4}}'
Example Request 3
Clear the queue, add to front of queue.
festival-cli queue_add_rand_entry --append front --clear --play
curl http://localhost:18425 -d '{"jsonrpc":"2.0","id":0,"method":"queue_add_rand_entry","params":{"append":"front","clear":true,"play":true}}'
Example Response
{
"jsonrpc": "2.0",
"result": {
"entry": {
"path": "/home/hinto/Music/Rex Orange County/RAINBOW/SUNFLOWER.mp3",
"key_artist": 69,
"key_album": 254,
"key_song": 2738,
"artist": "Rex Orange County",
"album": "RAINBOW",
"song": "SUNFLOWER"
}
},
"id": 0
}
queue_add_playlist
π‘ Incomplete
This API's output may have additions in the future.
Add a Playlist to the queue.
Inputs
| Field | Type | Description |
|---|---|---|
| playlist | string | The Playlist's name |
| append | string, one of front, back or index | See Queue/Append |
| clear | optional (maybe-null) boolean | Should the queue be cleared before adding? |
| play | optional (maybe-null) boolean | Should we start playing? |
| index | optional (maybe-null) unsigned integer | If the index append is chosen, this will be the index used |
| offset | optional (maybe-null) unsigned integer | See Queue/offset |
Outputs
result: null if everything went ok.
error: ... if there was an index/offset error or if the playlist didn't exist.
Example Request 1
Add to back of the queue.
festival-cli queue_add_playlist --playlist my_playlist --append back
curl http://localhost:18425 -d '{"jsonrpc":"2.0","id":0,"method":"queue_add_playlist","params":{"playlist":"my_playlist","append":"back","clear":false,"play":false}}'
Example Request 2
Insert at queue index 4, start from Song 3 (offset 2).
festival-cli queue_add_playlist --playlist my_playlist --append index --index 4 --offset 2
curl http://localhost:18425 -d '{"jsonrpc":"2.0","id":0,"method":"queue_add_playlist","params":{"playlist":"my_playlist","append":"index","clear":false,"play":false,"index":4,"offset":2}}'
Example Request 3
Clear the queue, add starting from Song 5 (offset 4).
festival-cli queue_add_playlist --playlist my_playlist --append front --clear --play --offset 4
curl http://localhost:18425 -d '{"jsonrpc":"2.0","id":0,"method":"queue_add_playlist","params":{"playlist":"my_playlist","append":"front","clear":true,"play":false,"offset":4}}'
Example Response
{
"jsonrpc": "2.0",
"result": null, // <--- everything went ok.
"id": 0
}
queue_set_index
π‘ Incomplete
This API's output may have additions in the future.
Set the current Song to a queue index.
If the index is out-of-bounds (queue has 10 songs, index is 10 or greater), this method will do nothing.
Inputs
| Field | Type | Description |
|---|---|---|
| index | unsigned integer | An index in the queue (1st Song is index 0, 2nd Song is index 1, etc). The current state of the "queue" can be viewed with state_audio. |
Outputs
| Field | Type | Description |
|---|---|---|
| out_of_bounds | boolean | If the provided index was equal to or greater than the queue length. |
| index | unsigned integer | The provided index |
| queue_len | unsigned integer | The queue length |
Example Request
Set the current Song to index 4.
festival-cli queue_set_index --index 123
curl http://localhost:18425 -d '{"jsonrpc":"2.0","id":0,"method":"queue_set_index","params":{"index":123}'
Example Response
{
"jsonrpc": "2.0",
"result": {
"out_of_bounds": true,
"index": 123,
"queue_len": 0
},
"id": 0
}
queue_remove_range
π‘ Incomplete
This API's output may have additions in the future.
Remove a range of queue indices.
If either start or end is out-of-bounds, this method will do nothing.
Inputs
| Field | Type | Description |
|---|---|---|
| start | unsigned integer | The beginning index to start removing from |
| end | unsigned integer | The index to stop at |
| skip | boolean | Should we skip to the next song if the range includes the current one? false will leave playback as is, even if the current song is wiped from the queue. |
start and end
This method will start removing from the start index up UNTIL the end index.
It is a NON-inclusive range, i.e: it is 0..4, not 0..=4.
For example, given "start": 0 and "end": 4:
# The queue.
index 0 | song_1 <--- We start removing from here.
index 1 | song_2 |
index 2 | song_3 |
index 3 | song_4 <--- To here.
index 4 | song_5 <--- This song is not removed.
index 5 | song_6
Outputs
| Field | Type | Description |
|---|---|---|
| out_of_bounds | boolean | If either start or end was out-of-bounds |
| start | unsigned integer | The provided start |
| end | unsigned integer | The provided end |
| queue_len | unsigned integer | The queue length before removing |
Example Request 1
Remove the 1st Song in the queue.
festival-cli queue_remove_range --start 0 --end 1 --skip
curl http://localhost:18425 -d '{"jsonrpc":"2.0","id":0,"method":"queue_remove_range","params":{"start":0,"end":1,"skip":true}}'
Example Request 2
Remove 2, 3, 4 from the queue.
festival-cli queue_remove_range --start 2 --end 5 --skip
curl http://localhost:18425 -d '{"jsonrpc":"2.0","id":0,"method":"queue_remove_range","params":{"start":2,"end":5,"skip":true}}'
Example Response
{
"jsonrpc": "2.0",
"result": {
"out_of_bounds": false,
"start": 2,
"end": 5,
"queue_len": 5
},
"id": 0
}
Playlist
Methods related for creating/modifying/viewing various info about Playlist's.
Append
Playlist methods are similar to the Queue methods, all Playlist methods involving appending requires an append type as input.
These append types are the exact same as the Queue, see Queue/Append for more info.
playlist_new
π’ Stable
This API is stable since festivald v1.0.0.
Create a new empty Playlist, overwriting an existing one.
Inputs
| Field | Type | Description |
|---|---|---|
| playlist | string | The name of the new Playlist |
Outputs
| Field | Type | Description |
|---|---|---|
| len | optional (maybe-null) unsigned integer | If the Playlist existed (and thus, overwritten), the amount of Playlist Entry's it had is returned, else if it didn't exist, null |
| entries | optional (maybe-null) array of Playlist Entry objects | If the Playlist existed (and thus, overwritten), its Playlist Entry's are returned, else if it didn't exist, null |
Example Request
festival-cli playlist_new --playlist "Playlist 1"
curl http://localhost:18425 -d '{"jsonrpc":"2.0","id":0,"method":"playlist_new","params":{"playlist":"Playlist 1"}}'
Example Response 1
The playlist did not previously exist:
{
"jsonrpc": "2.0",
"result": {
"len": null
"entries": null
},
"id": 0
}
Example Response 2
The playlist previously existed, it was empty, and was overwritten:
{
"jsonrpc": "2.0",
"result": {
"len": 0,
"entries": []
},
"id": 0
}
Example Response 3
The playlist previously existed, it contained this 1 Playlist Entry, and was overwritten:
{
"jsonrpc": "2.0",
"result": {
"len": 1,
"entries": [
{
"valid": {
"key_artist": 67,
"key_album": 238,
"key_song": 2588,
"artist": "Rex Orange County",
"album": "Apricot Princess",
"song": "Waiting Room"
}
}
]
},
"id": 0
}
playlist_remove
π’ Stable
This API is stable since festivald v1.0.0.
Remove a Playlist.
This method errors if playlist does not exist.
Inputs
| Field | Type | Description |
|---|---|---|
| playlist | string | The name of the Playlist to remove |
Outputs
| Field | Type | Description |
|---|---|---|
| len | unsigned integer | The amount of Playlist Entry's this removed Playlist had |
| entries | array of Playlist Entry objects | The Playlist Entry's of the remove Playlist |
Example Request
festival-cli playlist_remove --playlist Playlist 1
curl http://localhost:18425 -d '{"jsonrpc":"2.0","id":0,"method":"playlist_remove","params":{"playlist":"Playlist 1"}}'
Example Response 1
The playlist existed, it was empty, and was removed:
{
"jsonrpc": "2.0",
"result": {
"len": 0,
"entries": []
},
"id": 0
}
Example Response 2
The playlist existed, it contained this 1 Playlist Entry, and was removed:
{
"jsonrpc": "2.0",
"result": {
"len": 1,
"entries": [
{
"valid": {
"key_artist": 67,
"key_album": 238,
"key_song": 2588,
"artist": "Rex Orange County",
"album": "Apricot Princess",
"song": "Waiting Room"
}
}
]
},
"id": 0
}
playlist_clone
π’ Stable
This API is stable since festivald v1.0.0.
Clone an existing Playlist and all it's Entry's into a new one.
This method errors if from does not exist.
If to already exists, it will be overwritten.
Inputs
| Field | Type | Description |
|---|---|---|
| from | string | The name of the Playlist to clone FROM |
| to | string | The name of the new Playlist to clone TO |
Outputs
| Field | Type | Description |
|---|---|---|
| len | optional (maybe-null) unsigned integer | If to already existed (and thus, overwritten), the amount of Playlist Entry's it had is returned, else if it didn't exist, null |
| entries | optional (maybe-null) array of Playlist Entry objects | If to already existed, its Playlist Entry's are returned, else if it didn't exist, null |
Example Request
festival-cli playlist_clone --from original --to clone
curl http://localhost:18425 -d '{"jsonrpc":"2.0","id":0,"method":"playlist_remove","params":{"from":"original","to":"clone"}}'
Example Response 1
The playlist did not previously exist:
{
"jsonrpc": "2.0",
"result": {
"len": null
"entries": null
},
"id": 0
}
Example Response 2
The playlist previously existed, it was empty, and was overwritten:
{
"jsonrpc": "2.0",
"result": {
"len": 0,
"entries": []
},
"id": 0
}
Example Response 3
The playlist previously existed, it contained this 1 Playlist Entry, and was overwritten:
{
"jsonrpc": "2.0",
"result": {
"len": 1,
"entries": [
{
"valid": {
"key_artist": 67,
"key_album": 238,
"key_song": 2588,
"artist": "Rex Orange County",
"album": "Apricot Princess",
"song": "Waiting Room"
}
}
]
},
"id": 0
}
playlist_get_index
π’ Stable
This API is stable since festivald v1.0.0.
Retrieve a single Playlist Entry from a Playlist, using its index number.
This method errors if the playlist does not exist or if index is out-of-bounds.
Inputs
| Field | Type | Description |
|---|---|---|
| playlist | string | The name of the Playlist |
| index | unsigned integer | The index of the entry in the playlist |
Outputs
| Field | Type | Description |
|---|---|---|
| entry | Playlist Entry object | The Playlist Entry that was at index |
Example Request
Retrieve the 1st entry in playlist "Hello"
festival-cli playlist_get_index --playlist Hello --index 0
curl http://localhost:18425 -d '{"jsonrpc":"2.0","id":0,"method":"playlist_get_index","params":{"playlist":"Hello","index":0}}'
Example Response
{
"jsonrpc": "2.0",
"result": {
"entry": {
"valid": {
"key_artist": 65,
"key_album": 237,
"key_song": 2539,
"artist": "Rex Orange County",
"album": "RAINBOW",
"song": "SUNFLOWER"
}
}
},
"id": 0
}
playlist_remove_index
π’ Stable
This API is stable since festivald v1.0.0.
Remove a single Playlist Entry from a Playlist, using its index number.
This method errors if the playlist does not exist or if index is out-of-bounds.
Inputs
| Field | Type | Description |
|---|---|---|
| playlist | string | The name of the Playlist |
| index | unsigned integer | The index of the entry in the playlist |
Outputs
| Field | Type | Description |
|---|---|---|
| entry | Playlist Entry object | The Playlist Entry that was removed |
Example Request
Remove the 1st entry in playlist "Hello"
festival-cli playlist_remove_index --playlist Hello --index 0
curl http://localhost:18425 -d '{"jsonrpc":"2.0","id":0,"method":"playlist_remove_index","params":{"playlist":"Hello","index":0}}'
Example Response
{
"jsonrpc": "2.0",
"result": {
"entry": {
"valid": {
"key_artist": 65,
"key_album": 237,
"key_song": 2539,
"artist": "Rex Orange County",
"album": "RAINBOW",
"song": "SUNFLOWER"
}
}
},
"id": 0
}
playlist_add_key_artist
π’ Stable
This API is stable since festivald v1.0.0.
Add an Artist to a Playlist with a Key.
If the specified playlist does not already exist, it will be created.
This method errors if there was an index error.
Inputs
| Field | Type | Description |
|---|---|---|
| key | Artist key (unsigned integer) | Artist key of the Artist to add |
| playlist | string | The name of the Playlist |
| append | string, one of front, back or index | See Playlist/Append |
| index | optional (maybe-null) unsigned integer | If the index append is chosen, this will be the index used |
Outputs
| Field | Type | Description |
|---|---|---|
| existed | boolean | If playlist already existed or not |
| old_len | unsigned integer | The old length of playlist |
| new_len | unsigned integer | The new length of playlist |
Example Request 1
Add to back of the playlist "Hello".
festival-cli playlist_add_key_artist --playlist Hello --key 0 --append back
curl http://localhost:18425 -d '{"jsonrpc":"2.0","id":0,"method":"playlist_add_key_artist","params":{"playlist":"Hello","key":0,"append":"back"}}'
Example Request 2
Append at playlist index 4.
festival-cli playlist_add_key_artist --playlist Hello --key 0 --append index --index 4
curl http://localhost:18425 -d '{"jsonrpc":"2.0","id":0,"method":"playlist_add_key_artist","params":{"playlist":"Hello","key":0,"append":"index","index":4}}'
Example Response
{
"jsonrpc": "2.0",
"result": {
"existed": false,
"old_len": 0,
"new_len": 15
},
"id": 0
}
playlist_add_key_album
π’ Stable
This API is stable since festivald v1.0.0.
Add an Album to a Playlist with a Key.
If the specified playlist does not already exist, it will be created.
This method errors if there was an index error.
Inputs
| Field | Type | Description |
|---|---|---|
| key | Album key (unsigned integer) | Album key of the Album to add |
| playlist | string | The name of the Playlist |
| append | string, one of front, back or index | See Playlist/Append |
| index | optional (maybe-null) unsigned integer | If the index append is chosen, this will be the index used |
Outputs
| Field | Type | Description |
|---|---|---|
| existed | boolean | If playlist already existed or not |
| old_len | unsigned integer | The old length of playlist |
| new_len | unsigned integer | The new length of playlist |
Example Request 1
Add to back of the playlist "Hello".
festival-cli playlist_add_key_album --playlist Hello --key 0 --append back
curl http://localhost:18425 -d '{"jsonrpc":"2.0","id":0,"method":"playlist_add_key_album","params":{"playlist":"Hello","key":0,"append":"back"}}'
Example Request 2
Append at playlist index 4.
festival-cli playlist_add_key_album --playlist Hello --key 0 --append index --index 4
curl http://localhost:18425 -d '{"jsonrpc":"2.0","id":0,"method":"playlist_add_key_album","params":{"playlist":"Hello","key":0,"append":"index","index":4}}'
Example Response
{
"jsonrpc": "2.0",
"result": {
"existed": true,
"old_len": 115,
"new_len": 125
},
"id": 0
}
playlist_add_key_song
π’ Stable
This API is stable since festivald v1.0.0.
Add a Song to a Playlist with a Key.
If the specified playlist does not already exist, it will be created.
This method errors if there was an index error.
Inputs
| Field | Type | Description |
|---|---|---|
| key | Song key (unsigned integer) | Song key of the Song to add |
| playlist | string | The name of the Playlist |
| append | string, one of front, back or index | See Playlist/Append |
| index | optional (maybe-null) unsigned integer | If the index append is chosen, this will be the index used |
Outputs
| Field | Type | Description |
|---|---|---|
| existed | boolean | If playlist already existed or not |
| old_len | unsigned integer | The old length of playlist |
| new_len | unsigned integer | The new length of playlist |
Example Request 1
Add to back of the playlist "Hello".
festival-cli playlist_add_key_song --playlist Hello --key 0 --append back
curl http://localhost:18425 -d '{"jsonrpc":"2.0","id":0,"method":"playlist_add_key_song","params":{"playlist":"Hello","key":0,"append":"back"}}'
Example Request 2
Append at playlist index 4.
festival-cli playlist_add_key_song --playlist Hello --key 0 --append index --index 4
curl http://localhost:18425 -d '{"jsonrpc":"2.0","id":0,"method":"playlist_add_key_song","params":{"playlist":"Hello","key":0,"append":"index","index":4}}'
Example Response
{
"jsonrpc": "2.0",
"result": {
"existed": false,
"old_len": 0,
"new_len": 187
},
"id": 0
}
playlist_add_map_artist
π’ Stable
This API is stable since festivald v1.0.0.
If the specified playlist does not already exist, it will be created.
This method errors if there was an index error.
Inputs
| Field | Type | Description |
|---|---|---|
| artist | string | Artist name |
| playlist | string | The name of the Playlist |
| append | string, one of front, back or index | See Playlist/Append |
| index | optional (maybe-null) unsigned integer | If the index append is chosen, this will be the index used |
Outputs
| Field | Type | Description |
|---|---|---|
| existed | boolean | If playlist already existed or not |
| old_len | unsigned integer | The old length of playlist |
| new_len | unsigned integer | The new length of playlist |
Example Request 1
Add to back of the playlist "Hello".
festival-cli playlist_add_map_artist --playlist Hello --artist TWICE --append back
curl http://localhost:18425 -d '{"jsonrpc":"2.0","id":0,"method":"playlist_add_map_artist","params":{"playlist":"Hello","artist":"TWICE","append":"back"}}'
Example Request 2
Append at playlist index 4.
festival-cli playlist_add_map_artist --playlist Hello --artist TWICE --append index --index 4
curl http://localhost:18425 -d '{"jsonrpc":"2.0","id":0,"method":"playlist_add_map_artist","params":{"playlist":"Hello","artist":"TWICE","append":"index","index":4}}'
Example Response
{
"jsonrpc": "2.0",
"result": {
"existed": true,
"old_len": 10,
"new_len": 187
},
"id": 0
}
playlist_add_map_album
π’ Stable
This API is stable since festivald v1.0.0.
If the specified playlist does not already exist, it will be created.
This method errors if there was an index error.
Inputs
| Field | Type | Description |
|---|---|---|
| artist | string | Artist name |
| album | string | Album title |
| playlist | string | The name of the Playlist |
| append | string, one of front, back or index | See Playlist/Append |
| index | optional (maybe-null) unsigned integer | If the index append is chosen, this will be the index used |
Outputs
| Field | Type | Description |
|---|---|---|
| existed | boolean | If playlist already existed or not |
| old_len | unsigned integer | The old length of playlist |
| new_len | unsigned integer | The new length of playlist |
Example Request 1
Add to back of the playlist "Hello".
festival-cli playlist_add_map_album --playlist "Hello" --artist TWICE --album "PAGE TWO" --append back
curl http://localhost:18425 -d '{"jsonrpc":"2.0","id":0,"method":"playlist_add_map_album","params":{"playlist":"Hello","artist":"TWICE","album":"PAGE TWO","append":"back"}}'
Example Request 2
Append at playlist index 4.
festival-cli playlist_add_map_album --playlist Hello --artist TWICE --album "PAGE TWO" --append index --index 4
curl http://localhost:18425 -d '{"jsonrpc":"2.0","id":0,"method":"playlist_add_map_album","params":{"playlist":"Hello","artist":"TWICE","album":"PAGE TWO","append":"index","index":4}}'
Example Response
{
"jsonrpc": "2.0",
"result": {
"existed": true,
"old_len": 0,
"new_len": 187
},
"id": 0
}
playlist_add_map_song
π’ Stable
This API is stable since festivald v1.0.0.
If the specified playlist does not already exist, it will be created.
This method errors if there was an index error.
Inputs
| Field | Type | Description |
|---|---|---|
| artist | string | Artist name |
| album | string | Album title |
| song | string | Song title |
| playlist | string | The name of the Playlist |
| append | string, one of front, back or index | See Playlist/Append |
| index | optional (maybe-null) unsigned integer | If the index append is chosen, this will be the index used |
Outputs
| Field | Type | Description |
|---|---|---|
| existed | boolean | If playlist already existed or not |
| old_len | unsigned integer | The old length of playlist |
| new_len | unsigned integer | The new length of playlist |
Example Request 1
Add to back of the playlist "Hello".
festival-cli playlist_add_map_song --playlist Hello --artist TWICE --album "PAGE TWO" --song "CHEER UP" --append back
curl http://localhost:18425 -d '{"jsonrpc":"2.0","id":0,"method":"playlist_add_map_song","params":{"playlist":"Hello","artist":"TWICE","album":"PAGE TWO","song":"CHEER UP","append":"back"}}'
Example Request 2
Append at playlist index 4.
festival-cli playlist_add_map_song --playlist Hello --artist TWICE --album "PAGE TWO" --song "CHEER UP" --append index --index 4
curl http://localhost:18425 -d '{"jsonrpc":"2.0","id":0,"method":"playlist_add_map_song","params":{"playlist":"Hello","artist":"TWICE","album":"PAGE TWO","song":"CHEER UP","append":"index","index":4}}'
Example Response
{
"jsonrpc": "2.0",
"result": {
"existed": false,
"old_len": 0,
"new_len": 17
},
"id": 0
}
playlist_single
π’ Stable
This API is stable since festivald v1.0.0.
Retrieve a single Playlist.
This method errors if playlist does not exist.
Inputs
| Field | Type | Description |
|---|---|---|
| playlist | string | The name of the Playlist |
Outputs
| Field | Type | Description |
|---|---|---|
| playlist | string | The name of the Playlist |
| all_valid | boolean | If all the Playlist Entry's are valid |
| entry_len | unsigned integer | How many Playlist Entry's there are in this Playlist |
| valid_len | unsigned integer | How many Playlist Entry's are valid |
| invalid_len | unsigned integer | How many Playlist Entry's are invalid |
| entries | array of Playlist Entry objects | The Playlist Entry's of the Playlist |
Example Request
festival-cli playlist_single --playlist Hello
curl http://localhost:18425 -d '{"jsonrpc":"2.0","id":0,"method":"playlist_single","params":{"playlist":"Hello"}}'
Example Response
{
"jsonrpc": "2.0",
"result": {
"playlist": "Hello",
"all_valid": false,
"entry_len": 2,
"valid_len": 1,
"invalid_len": 1,
"entries": [
{
"invalid": {
"artist": "Artist Name",
"album": "Album Title",
"song": "Song Title"
}
},
{
"valid": {
"key_artist": 46,
"key_album": 168,
"key_song": 1762,
"artist": "Artist Name",
"album": "Album Title",
"song": "Song Title"
}
}
]
},
"id": 0
}
playlist_brief
π’ Stable
This API is stable since festivald v1.0.0.
Retrieve the names of all Playlist's.
Names are sorted in lexicographical order.
Inputs
None
Outputs
| Field | Type | Description |
|---|---|---|
| len | unsigned integer | How many Playlist's there are |
| playlists | array of string's | The names of all Playlist's |
Example Request
festival-cli playlist_brief
curl http://localhost:18425 -d '{"jsonrpc":"2.0","id":0,"method":"playlist_brief"}'
Example Response
{
"jsonrpc": "2.0",
"result": {
"len": 3,
"playlists": [
"Playlist A",
"Playlist B",
"Playlist C"
]
},
"id": 0
}
playlist_full
π’ Stable
This API is stable since festivald v1.0.0.
Retrieve full data of all Playlist's.
Playlists are sorted by their names in lexicographical order.
Inputs
None
Outputs
| Field | Type | Description |
|---|---|---|
| all_valid | boolean | If every Playlist Entry is valid |
| playlist_len | unsigned integer | How many Playlist's there are |
| entry_len | unsigned integer | How many total Playlist Entry's there are |
| valid_len | unsigned integer | How many Playlist Entry's are valid |
| invalid_len | unsigned integer | How many Playlist Entry's are invalid |
| playlists | map of Playlist objects | The map's field keys are string's, the playlist names themselves |
Example Request
festival-cli playlist_full
curl http://localhost:18425 -d '{"jsonrpc":"2.0","id":0,"method":"playlist_full"}'
Example Response 1
{
"jsonrpc": "2.0",
"result": {
"all_valid": false,
"playlist_len": 2,
"entry_len": 3,
"valid_len": 2,
"invalid_len": 1,
"playlists": { // <--- Note the '{' not '[' - this is a MAP not an ARRAY
"hello": [ // <--- This Playlist's name is "hello"
{
"valid": {
"key_artist": 46,
"key_album": 168,
"key_song": 1762,
"artist": "Artist Name",
"album": "Album Title",
"song": "Song Title"
}
}
],
"hmm": [ // <--- This Playlist's name is "hmm"
{
"invalid": {
"artist": "Artist Name",
"album": "Album Title",
"song": "Song Title"
}
},
{
"valid": {
"key_artist": 46,
"key_album": 168,
"key_song": 1762,
"artist": "Artist Name",
"album": "Album Title",
"song": "Song Title"
}
}
]
}
},
"id": 0
}
Example Response 2
If there are no playlists at all:
{
"jsonrpc": "2.0",
"result": {
"all_valid": true,
"playlist_len": 0,
"entry_len": 0,
"valid": 0,
"invalid": 0,
"playlists": {} // Empty MAP, not array `[]`
},
"id": 0
}
Example Response 3
If there is 1 empty playlist:
{
"jsonrpc": "2.0",
"result": {
"all_valid": true,
"playlist_len": 1,
"entry_len": 0,
"valid_len": 0,
"invalid_len": 0,
"playlists": {
"hello": [] // <--- One empty playlist named "hello"
}
},
"id": 0
}
REST
festivald (by default) exposes REST endpoints for accessing the underlying resources associated with the Collection via HTTP GET requests.
A simple way to access these files is via a browser, e.g, opening this link:
http://localhost:18425/art/Artist Name/Album Title
This will make the art of the album Album Title, owned by the artist Artist Name open directly in the browser (or make it download the image, if the direct_download configuration setting is enabled).
Opening something like:
http://localhost:18425/map/Artist Name/Album Title/Song Title
will download that song directly. In the future, the behavior of showing an inline player in browsers may be added to the direct_download config option.
If a file downloaded has a nested filename, the filename_separator config option will control what the separator will be. By default, this is -, so the filename of an archive of an Artist will look like:
Artist Name - Album Title.zip
Resource
The REST endpoint resources are in loosely grouped based on what type of data they are and what format they are outputted as.
These "groups" are referenced in authorization & API Stability.
REST resource | File Format Type | Description | Example Endpoint | Filename Formatting |
|---|---|---|---|---|
collection | zip | The whole Collection | /collection | Collection - ${CREATION_UNIX_TIMESTAMP}.zip |
playlist | zip | Individual Playlist's | /playlist | Playlist - ${PLAYLIST_NAME}.zip |
artist | zip | Individual Artist's | /map/artist | ${ARTIST_NAME}.zip |
album | zip | Individual Album's | /current/album | ${ARTIST_NAME} - ${ALBUM_TITLE}.zip |
song | Original audio format (flac, mp3, etc) | Individual Song's | /rand/song | ${ARTIST_NAME} - ${ALBUM_TITLE} - ${SONG_TITLE}.${AUDIO_FORMAT} |
art | Original image format (png, jpg, etc) | Individual Album art | /current/art | ${ARTIST_NAME} - ${ALBUM_TITLE}.${IMAGE_FORMAT} |
Missing Resource
If the underlying file for a resource is missing from the filesystem, festivald will respond to REST requests with an HTTP error.
For example, if an Artist is requested:
http://localhost:18425/map/Artist
And any underlying PATH is missing/moved/renamed from when the Collection was created:
mv "Song Title" "Song_Title"
festivald will now have a reference to a non-existent PATH and will not be able to find the file(s), so it will respond with something along the lines of:
Song file error: ${ARTIST_NAME} - ${ALBUM_TITLE} - Song Title.flac
You can re-create the Collection with collection_new to re-link these PATHs.
Disk Cache
festivald exclusively uses the Disk when operating with potentially heavy data.
All heavy files are streamed from disk, so none of them take up full space in physical memory.
Practically, what this means is that when serving files, festivald can get by with very little memory, although the Cache folder may get quite heavy.
The cache behavior can be configured in the config or via command-line options.
REST Quick Start
A quick start to using festivald's REST API.
View random Album art in a web browser with /rand/art
http://localhost:18425/rand/art
Download a random Song with /rand/song
http://localhost:18425/rand/song
Download a random Album in the ZIP format with /rand/album
http://localhost:18425/rand/album
Download a specific Artist in the ZIP format with /map/$ARTIST_NAME
http://localhost:18425/map/Artist Name
Download a specific Album by specific Artist in the ZIP format with /map/$ARTIST_NAME
http://localhost:18425/map/Artist Name/Album Title
Download the currently set Song with /current/song
http://localhost:18425/current/song
View the art of the currently set Song with /current/art
http://localhost:18425/current/art
Download all the art belonging to an Artist with /art/$ARTIST_NAME
http://localhost:18425/art/Artist Name
Download all the Song's in a Playlist in the ZIP format with /playlist/$PLAYLIST_NAME
http://localhost:18425/playlist/My Playlist 1
/key
Access audio files and/or art via a key.
This endpoint expects 2 more endpoints/inputs:
Where ${COMMON_OBJECT} is one of:
artistalbumsongart
The key must be the key number associated with the object.
See Common Objects/Key for more information on keys.
/key/artist/$ARTIST_KEY
π’ Stable
This API is stable since festivald v1.0.0.
Download an Artist, using an Artist key.
Input
| Input | Type |
|---|---|
Artist key | unsigned integer |
Output
ZIP of all artist's albums (including art if found).
Example Input
http://localhost:18425/key/artist/123
Example Output
File:
Artist Name.zip
Extracted:
Artist Name/
ββ Album Title 1/
β ββ Album Title 1.jpg
β ββ Song Title 1.mp3
β ββ Song Title 2.flac
β ββ Song Title 3.ogg
β
ββ Album Title 2/
β ββ Album Title 2.png
β ββ Song Title 4.mp3
β ββ Song Title 5.flac
β ββ Song Title 6.ogg
β
ββ Album Title 3/
ββ Song Title 7.mp3
ββ Song Title 8.flac
ββ Song Title 9.ogg
/key/album/$ALBUM_KEY
π’ Stable
This API is stable since festivald v1.0.0.
Download an Album using an Album key.
Input
| Input | Type |
|---|---|
| Album key | unsigned integer |
Output
Album in ZIP (including art if found).
Example Input
http://localhost:18425/key/album/123
Example Output
File:
Artist Name - Album Title.zip
Extracted:
Artist Name - Album Title/
ββ Album Title.jpg
ββ Song Title 1.mp3
ββ Song Title 2.flac
ββ Song Title 3.ogg
/key/song/$SONG_KEY
π’ Stable
This API is stable since festivald v1.0.0.
Download a Song using a Song key.
Input
| Input | Type |
|---|---|
Song key | unsigned integer |
Output
Song in original format.
Example Input
http://localhost:18425/key/song/123
Example Output
Artist Name - Album Title - Song Title.flac
/key/art/$ALBUM_KEY
π’ Stable
This API is stable since festivald v1.0.0.
Download this Album's art, using an Album key.
Input
| Input | Type |
|---|---|
Album key | unsigned integer |
Output
Art in original format.
Example Input
http://localhost:18425/key/art/123
Example Output
File:
Artist Name - Album Title.jpg
/map
This is the same as the /key endpoint, but instead of numbers, you can directly use:
ArtistnamesAlbumtitlesSongtitles
So instead of:
http://localhost:18425/key/song/123
you can use:
http://localhost:18425/map/Artist Name/Artist Title/Song Title
Browsers will secretly percent-encode this URL, so it'll actually be:
http://localhost:18425/map/Artist%20Name/Artist%20Title/Song%20Title
This is fine, festivald will decode it, along with any other percent encoding, so you can use spaces or any other UTF-8 characters directly in the URL:
http://localhost:18425/map/Π°ΡΡΠΈΡΡ/β€οΈ/γγ³γ γγγͺγ
The reason Artist names and Album titles have to be specified is to prevent collisions.
If there's 2 songs in your Collection called: Hello World, which one should festivald return?
Since Artist names are unique, and Album titles within Artist's are unique, they serve as an identifier.
Also note: words are case-sensitive and must be exact.
If you have an Album called Hello World, none of these inputs will work:
Hello worldhello WorldHELlo WorldHelloWorldH3ll0 W0rld
The input must exactly be Hello World.
/map/$ARTIST_NAME
π’ Stable
This API is stable since festivald v1.0.0.
Download an Artist, using the Artist's name.
Input
| Input | Type |
|---|---|
Artist name | string |
Output
ZIP of all artist's albums (including art if found).
Example Input
http://localhost:18425/map/Artist Name
Example Output
File:
Artist Name.zip
Extracted:
Artist Name/
ββ Album Title 1/
β ββ Album Title 1.jpg
β ββ Song Title 1.mp3
β ββ Song Title 2.flac
β ββ Song Title 3.ogg
β
ββ Album Title 2/
β ββ Album Title 2.png
β ββ Song Title 4.mp3
β ββ Song Title 5.flac
β ββ Song Title 6.ogg
β
ββ Album Title 3/
ββ Song Title 7.mp3
ββ Song Title 8.flac
ββ Song Title 9.ogg
/map/$ARTIST_NAME/$ALBUM_TITLE
π’ Stable
This API is stable since festivald v1.0.0.
Download an Album using the Artist's name, and Album title.
Input
| Input | Type |
|---|---|
Artist name | string |
Album title | string |
Output
Album in ZIP (including art if found).
Example Input
http://localhost:18425/map/Artist Name/Album Title
Example Output
File:
Artist Name - Album Title.zip
Extracted:
Artist Name - Album Title/
ββ Album Title.jpg
ββ Song Title 1.mp3
ββ Song Title 2.flac
ββ Song Title 3.ogg
/map/$ARTIST_NAME/$ALBUM_TITLE/$SONG_TITLE
π’ Stable
This API is stable since festivald v1.0.0.
Download a Song, using the Artist's name, Album title, and Song title.
Input
| Input | Type |
|---|---|
Artist name | string |
Album title | string |
Song title | string |
Output
| Output | Type |
|---|---|
| Song in original format | audio file |
Example Input
http://localhost:18425/map/Artist Name/Album Title/Song Title
Example Output
Artist Name - Album Title - Song Title.flac
/current
Download the currently set Artist, Album, Song, or art.
Returns an HTTP error if no Song is currently set.
/current/artist
π’ Stable
This API is stable since festivald v1.0.0.
Download the Artist of the currently set Song.
Input
None
Output
ZIP of all artist's albums (including art if found).
Example Input
http://localhost:18425/current/artist
Example Output
File:
Artist Name.zip
Extracted:
Artist Name/
ββ Album Name 1/
β ββ Album Name 1.jpg
β ββ Song Name 1.mp3
β ββ Song Name 2.flac
β ββ Song Name 3.ogg
β
ββ Album Name 2/
β ββ Album Name 2.png
β ββ Song Name 4.mp3
β ββ Song Name 5.flac
β ββ Song Name 6.ogg
β
ββ Album Name 3/
ββ Song Name 7.mp3
ββ Song Name 8.flac
ββ Song Name 9.ogg
/current/album
π’ Stable
This API is stable since festivald v1.0.0.
Download the Album of the currently set Song (including art if found).
Input
None
Output
Album in archive (including art if found).
Example Input
http://localhost:18425/current/album
Example Output
File:
Artist Name - Album Title.zip
Extracted:
Artist Name - Album Title/
ββ Album Name.jpg
ββ Song Name 1.mp3
ββ Song Name 2.flac
ββ Song Name 3.ogg
/current/song
π’ Stable
This API is stable since festivald v1.0.0.
Download the currently set Song.
Input
None
Output
Song in original format.
Example Input
http://localhost:18425/current/song
Example Output
Artist Name - Album Title - Song Title.flac
/current/art
π’ Stable
This API is stable since festivald v1.0.0.
Download the Album art of the currently set Song.
If no art was found, this will respond with an HTTP error.
Input
None
Output
Art in original format.
Example Input
http://localhost:18425/current/art
Example Output
Artist Name - Album Title.jpg
/rand
Download a random Artist, Album, Song or art.
This will return an HTTP error if the Collection is empty.
Repeating is allowed, so you may encounter the same object multiple times in a row.
/rand/artist
π’ Stable
This API is stable since festivald v1.0.0.
Download a random Artist.
Input
None
Output
ZIP of all artist's albums (including art if found).
Example Input
http://localhost:18425/rand/artist
Example Output
File:
Artist Name.zip
Extracted:
Artist Name/
ββ Album Name 1/
β ββ Album Name 1.jpg
β ββ Song Name 1.mp3
β ββ Song Name 2.flac
β ββ Song Name 3.ogg
β
ββ Album Name 2/
β ββ Album Name 2.png
β ββ Song Name 4.mp3
β ββ Song Name 5.flac
β ββ Song Name 6.ogg
β
ββ Album Name 3/
ββ Song Name 7.mp3
ββ Song Name 8.flac
ββ Song Name 9.ogg
/rand/album
π’ Stable
This API is stable since festivald v1.0.0.
Download a random Album.
Input
None
Output
Album in ZIP (including art if found).
Example Input
http://localhost:18425/rand/album
Example Output
File:
Artist Name - Album Title.zip
Extracted:
Artist Name - Album Title/
ββ Album Name.jpg
ββ Song Name 1.mp3
ββ Song Name 2.flac
ββ Song Name 3.ogg
/rand/song
π’ Stable
This API is stable since festivald v1.0.0.
Download a random Song.
Input
None
Output
Song in original format.
Example Input
http://localhost:18425/rand/song
Example Output
Artist Name - Album Title - Song Title.flac
/rand/art
π’ Stable
This API is stable since festivald v1.0.0.
Download a random Album art.
If no art was found, the response will be an HTTP error.
Input
None
Output
Art in original format.
Example Input
http://localhost:18425/rand/art
Example Output
Artist Name - Album Title.jpg
/art
This is the same as the /map endpoint, but only for downloading Album art.
/art/$ARTIST_NAME
π’ Stable
This API is stable since festivald v1.0.0.
Download all the Album art owned by this Artist, using the Artist's name.
Input
| Input | Type |
|---|---|
Artist name | string |
Output
ZIP of all the art owned by this Artist.
Example Input
http://localhost:18425/art/Artist Name
Example Output
File:
Art - Artist Name.zip
Extracted:
Art - Artist Name/
ββ Album Name 1.jpg
ββ Album Name 2.png
ββ Album Name 3.webp
/art/$ARTIST_NAME/$ALBUM_TITLE
π’ Stable
This API is stable since festivald v1.0.0.
Download an Album's art, using the Artist's name, and Album title
Input
| Input | Type |
|---|---|
Artist name | string |
Album title | string |
Output
Album art in original format.
Example Input
http://localhost:18425/art/Artist Name/Album Title
Example Output
Art - Artist Name - Album Title.png
/playlist/$PLAYLIST_NAME
π’ Stable
This API is stable since festivald v1.0.0.
Download all the Song's in a Playlist.
Invalid Entry's will be ignored.
Each Song file will be prefixed with its index in the playlist.
The formatting is as such:
${INDEX}${SEPARATOR}${ARTIST_NAME}${SEPARATOR}${ALBUM_TITLE}${SEPARATOR}${SONG_TITLE}.${SONG_EXTENSION}
For example, if the filename_separator was left as the default -:
11 - Artist Name - Album Title - Song Title.mp3
Index starts at 0.
Input
| Input | Type |
|---|---|
Playlist name | string |
Output
Playlist (valid Song files only) in ZIP.
Example Input
http://localhost:18425/playlist/My Playlist 2
Example Output
File:
Playlist - My Playlist 2.zip
Extracted:
Playlist - My Playlist 2/
ββ 0 - Artist Name - Album Title - Song Name.mp3
ββ 1 - Artist Name - Album Title - Song Name.flac
ββ 2 - Artist Name - Album Title - Song Name.ogg
/collection
π’ Stable
This API is stable since festivald v1.0.0.
Download the entire Collection.
Warning
This will cause festivald to use at least the same amount of disk space your Collection's audio & art files take up.
For example, if all your Song's combined are 100GB in size, festivald will use at least 100GB in disk space when receiving this request. Further same requests will not further disk usage, depending on your cache_time configuration.
festivald may also take a while to respond to the client, as it is copying, organizing, and archiving the entire Collection.
Input
None
Output
Archive including:
Example Input
http://localhost:18425/collection
Example Output
File:
Collection${FILENAME_SEPARATOR}${CREATION_UNIX_TIMESTAMP}.zip
E.g:
Collection - 1690812809.zip
Extracted:
Collection - 1690812809/
β
β
ββ Artist Name 1/
β ββ Album Name 1/
β β ββ Album Name 1.jpg
β β ββ Song Name 1.mp3
β β ββ Song Name 2.flac
β β ββ Song Name 3.ogg
β β
β ββ Album Name 2/
β β ββ Album Name 2.png
β β ββ Song Name 4.mp3
β β ββ Song Name 5.flac
β β ββ Song Name 6.ogg
β β
β ββ Album Name 3/
β ββ Song Name 7.mp3
β ββ Song Name 8.flac
β ββ Song Name 9.ogg
β
β
ββ Artist Name 2/
β ββ Album Name 4/
β β ββ Album Name 4.jpg
β β ββ Song Name 10.mp3
β β ββ Song Name 12.flac
β β ββ Song Name 13.ogg
β β
β ββ Album Name 5/
β β ββ Album Name 5.png
β β ββ Song Name 14.mp3
β β ββ Song Name 15.flac
β β ββ Song Name 16.ogg
β β
β ββ Album Name 6/
β ββ Song Name 17.mp3
β ββ Song Name 18.flac
β ββ Song Name 19.ogg
β
β
ββ [... etc ...]