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.0
for state retrieval & controlREST
endpoints for serving large resources (audio, art, etc)Docs
-festivald
serves 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
festivald
is called theCollection
- The
Collection
is created by scanning the filesystemfestivald
is running on - Everything revolves around the
Collection
, you should create one before doing anything - In
festivald
, there are "objects" that appear often, seeCommon Objects
for 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.0
release- There is a fundamental/security bug that must be fixed in
festivald
- There is a difference between this documentation and the actual
festivald
input/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
REST
endpoints that serve large collections of files, theZIP
format will be used - There is no compression applied to the files, they are stored as-is
- These ZIPs can be found the in
Cache
folder 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
Playlist
namesArtist
namesAlbum
titlesSong
titles
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.x
festival-cli v1.1.x
festival-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-cli
is requesting a method unknown to an oldfestivald
, or - If a new
festivald
has additional output unknown to an oldfestival-cli
(use ofnon-stable
API)
there will be communication issues.
Config
config
names areπ’ Stable
(max_connections
will always be namedmax_connections
)- Their expected inputs are
π’ Stable
(max_connections
will always want an unsigned integer) - Their expected behavior is
π‘ Incomplete
(direct_download
may include song files someday) - Default config values may be changed (default
port
value 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
--flags
and sub-command names areπ’ Stable
(festivald --path
will 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.0
ofJSON-RPC
will always be used JSON-RPC
will always requireHTTP POST
requestsREST
and documentation will always requireHTTP GET
requests
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:
Artist
keyAlbum
keySong
key
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
Artist
contains 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
string
inputs - Storing/sending/parsing integers is faster & cheaper than
string
's - As long as your
Collection
is stable, the key's are stable - Accessing
Song
's with the same title in the sameAlbum
by the sameArtist
is 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
Music
directory onfestivald
's filesystem, and create aCollection
withcollection_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
Collection
reset 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 world
hello World
HELlo World
HelloWorld
H3ll0 W0rld
The input must be exactly Hello World
.
Collisions
When using map_album
you must specify:
Artist
nameAlbum
title
and when using map_song
you must specify:
Artist
nameAlbum
titleSong
title
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:
Artist
namesAlbum
titlesSong
titles
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:
artist
album
song
art
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:
Artist
namesAlbum
titlesSong
titles
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 world
hello World
HELlo World
HelloWorld
H3ll0 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 ...]