Welcome to the Obsidian API Documentation! This document describes mostly everything about the WebSocket and HTTP server.
Magma is the name for the WebSocket and REST server!
- Current Version: 1.0.0-pre
As of version 1.0.0 of obsidian the REST API is only used for loading tracks. This will most likely change in future
releases.
Allows clients to view the route planner and free-up addresses.
GET /routeplanner/status
Authorization: <password>
Example Response
{
"class": "RotatingNanoIpRoutePlanner",
"details": {
"ip_block": {
"type": "Inet6Address",
"size": "1208925819614629174706176"
},
"failing_addresses": [
{
"address": "/1.0.0.0",
"failing_timestamp": 1573520707545,
"failing_time": "Mon Nov 11 20:05:07 EST 2019"
}
],
"block_index": "0",
"current_address_index": "36792023813"
}
}If no route planner was configured, both class and details will be null, the responses vary depending on what route planner was configured. Fields that are consistent:
classstring name of the route plannerdetails.ip_blockstring the current ip-blockdetails.failing_addressesarray of objects describing a failed address.
RotatingIpRoutePlanner
details.rotate_indexstring containing the number of rotations which happened since the server had started.details.ip_indexstring containing the current offset of the ip-block.details.current_addressstring containing the currently used ip-address.
NanoIpRoutePlanner
details.current_address_indexlong representing the current offset in the ip-block.
RotatingNanoIpRoutePlanner
details.block_indexstring containing the file information in which /64 block ips are chosen, this number increases on each ban.details.current_address_indexlong representing the current offset in the ip-block.
GET /routeplanner/free/address
Authorization: <password>
body:
{
"address": "420.69.69.420"
}Example Response
204 - No Content
GET /routeplanner/free/all
Authorization: <password>
Example Response
204 - No Content
Allows non-jvm clients to search and decode tracks using Obsidian!
GET /loadtracks?identifier=D-ocerKPufk
Authorization: <configured password>
Example Response
this was actually taken from a response btw
{
"load_type": "TRACK_LOADED",
"playlist_info": null,
"tracks": [
{
"track": "...",
"info": {
"title": "The Kid LAROI - SELFISH (Official Video)",
"author": "TheKidLAROIVEVO",
"uri": "https://www.youtube.com/watch?v=D-ocerKPufk",
"identifier": "D-ocerKPufk",
"length": 270000,
"position": 0,
"is_stream": false,
"is_seekable": true
}
}
],
"exception": null
}Singular
GET /decodetrack?track=QAAAkQIAKF...
Authorization: <configured password>
Example Response
{
"title": "The Kid LAROI - SELFISH (Official Video)",
"author": "TheKidLAROIVEVO",
"uri": "https://www.youtube.com/watch?v=D-ocerKPufk",
"identifier": "D-ocerKPufk",
"length": 270000,
"position": 0,
"is_stream": false,
"is_seekable": true
}Multiple
POST /decodetracks
Authorization: <configured password>
body:
{
"tracks": [
"..."
]
}Example Response
ok, yknow what... idc man
jk the response is just an array filled with track info objects (refer to the singular track response)
Magma also has a WebSocket used for real-time player updates, it also allows for player control
To connect you must have these headers assigned
Authorization: Password configured in `.obsidianrc`
User-Id: The user id of the bot you're playing music with
Resume-Key: The resume key (like lavalink), however this is only needed if the client needs to be resumed.
Client-Name: Name of your bot or project, may be required but the node you are connecting to.
Close Codes
| close code | reason |
|---|---|
| 4001 | You specified invalid authorization |
| 4002 | No User-Id header was specified |
| 4004 | A session for the User-Id header already exists |
| 4005 | An error occurred while handling incoming frames |
| 4006 | The server requires the Client-Name header to be present. |
- op: numeric op code
- d: payload data
{
"op": 0,
"d": {}
}| op code/name | description |
|---|---|
| 0 • submit voice update | allows obsidian to connect to the discord voice server |
| 1 • stats | has resource usage for both the system and jvm, also includes player count |
| 2 • player event | dispatched when a player event occurs, e.g. track end, track start |
| 3 • player update | used to keep track of player state, e.g. current position and filters |
| 4 • play track | used to play tracks |
| 5 • stop track | stops the current track |
| 6 • pause | configures the pause state of the player |
| 7 • filters | configures the current filters |
| 8 • seek | seeks to the specified position |
| 9 • destroy | used to destroy players |
| 10 • setup resuming | configures resuming |
| 11 • setup dispatch buffer | configures dispatch buffer |
The equivalent of voiceUpdate for lavalink and voice-state-update for andesite
{
"op": 0,
"d": {
"guild_id": "751571246189379610",
"token": "your token",
"session_id": "your session id",
"endpoint": "smart.loyal.discord.gg"
}
}tokenandendpointcan be received from Discord'sVOICE_SERVER_UPDATEdispatch eventsession_idcan be received from Discord'sVOICE_STATE_UPDATEdispatch event
Stats on the node
{
"op": 1,
"d": {
"memory": {
"free": 46609784,
"used": 26790536,
"allocated": 73400320,
"reservable": 2061500416
},
"cpu": {
"cores": 4,
"system_load": 0.011964233239578523,
"process_load": 0.15813777759120104
},
"links": {
"active": 1,
"total": 1
},
"frames": {
"sent": 3000,
"nulled": 0,
"deficit": 0
}
}
}List of current player events Example:
{
"op": 2,
"d": {
"type": "TRACK_START",
"guild_id": "751571246189379610",
"track": "QAAAmAIAO0tTSSDigJMgUGF0aWVuY2UgKGZlYXQuIFlVTkdCTFVEICYgUG9sbyBHKSBbT2ZmaWNpYWwgQXVkaW9dAANLU0kAAAAAAALG8AALTXJmVTRhVGNVYU0AAQAraHR0cHM6Ly93d3cueW91dHViZS5jb20vd2F0Y2g/dj1NcmZVNGFUY1VhTQAHeW91dHViZQAAAAAAAAAA"
}
}code blocks below represent data in the d field
Dispatched when a track starts
trackself-explanatory
{
...
"track": "..."
}Dispatched when a track ends
trackthe track that had endedreasonReason for why the track had ended
{
...
"track": "...",
"reason": "REPLACED"
}End Reasons
STOPPED,REPLACED,CLEANUP,LOAD_FAILED,FINISHED
For more information visit ** AudioTrackEndReason.java**
dispatched when track playback is stuck
trackself-explanatorythreshold_msThe wait threshold that was exceeded for this event to trigger
{
...
"track": "",
"threshold_ms": 1000
}Dispatched when lavaplayer encounters an error while playing a track
trackthe track that threw an exception during playbackexceptioneverything is self-explanatorymessagecauseseveritysee Severity Types
{
...
"track": "...",
"exception": {
"message": "This video is too cool for the people listening",
"cause": "Lack of coolness by the listeners",
"severity": "COMMON"
}
}- COMMON, FAULT, SUSPICIOUS
For more information visit this
Dispatched when the voice websocket receives the READY op
targetvoice server ipssrcvoice ssrc
refer to the Discord voice docs for what ssrc is for
{
...
"target": "420.69.69.9",
"ssrc": 42069
}Dispatched when the voice websocket closes
codeclose codereasonclose reason
{
...
"code": 4000,
"reason": ""
}framesdescribes the number of frames, in the last minute, that have been sent or lostcurrent_trackdescribes the current playing tracktrackthe base64 encoded trackpositionthe current playback positionpausedwhether playback is paused
{
"op": 3,
"d": {
"guild_id": "751571246189379610",
"frames": {
"lost": 0,
"sent": 3000
},
"current_track": {
"track": "...",
"position": 3192719,
"paused": false
}
}
}start_timespecifies the number of milliseconds to offset the track byend_timespecifies when to stop the track (in milliseconds)no_replacewhen specified, the server will ignore this request if a track is already playing
{
"op": 4,
"d": {
"guild_id": "...",
"track": "...",
"end_time": 30000,
"start_time": 130000,
"no_replace": false
}
}{
"op": 4,
"d": {
"guild_id": "..."
}
}statewhether playback should be paused.
{
"op": 6,
"d": {
"state": true
}
}p.s. this operation overrides any filters that were previously configured, also I didn't really care to fill out the example lol
-
volumethe volume to set.0.0through5.0is accepted, where1.0is 100% -
tremolocreates a shuddering effect, where the volume quickly oscillatesfrequencyEffect frequency •0 < xdepthEffect depth •0 < x ≤ 1
-
equalizerThere are 15 bands (0-14) that can be configured. Each band has a gain and band field, band being the band number and gain being a number between-0.25and1.0-0.25means the band is completed muted and0.25meaning it's doubled -
timescaleTime stretch and pitch scale filter implementationpitchSets the audio pitchpitch_octavesSets the audio pitch in octaves, this cannot be used in conjunction with the other two optionspitch_semi_tonesSets the audio pitch in semi tones, this cannot be used in conjunction with the other two pitch optionsrateSets the audio rate, cannot be used in conjunction withrate_changerate_changeSets the audio rate, in percentage, relative to the defaultspeedSets the playback speed, cannot be used in conjunction withspeed_changespeed_changeSets the playback speed, in percentage, relative to the default
-
karaokeUses equalization to eliminate part of a band, usually targeting vocals. None of these i have explanations for... ask natan igfilter_band,filter_width,level,mono_level
-
channel_mixThis filter mixes both channels (left and right), with a configurable factor on how much each channel affects the other. With the defaults, both channels are kept independent of each other. Setting all factors to0.5means both channels get the same audioright_to_leftThe current right-to-left factor. The default is0.0right_to_rightThe current right-to-right factor. The default is1.0left_to_rightThe current left-to-right factor. The default is0.0left_to_leftThe current left-to-left factor. The default is1.0
-
vibratoSimilar to tremolo. While tremolo oscillates the volume, vibrato oscillates the pitchfrequencyEffect frequency •0 < x ≤ 14depthEffect depth •0 < x ≤ 1
-
rotationThis filter simulates an audio source rotating around the listenerrotation_hzThe frequency the audio should rotate around the listener, in Hertz
-
low_passHigher frequencies get suppressed, while lower frequencies pass through this filter, thus the name low passsmoothingSmoothing to use. 20 is the default
{
"op": 7,
"d": {
"guild_id": "...",
"volume": 1.0,
"timescale": {},
"karaoke": {},
"channel_mix": {},
"vibrato": {},
"rotation": {},
"low_pass": {},
"tremolo": {},
"equalizer": {
"bands": []
}
}
}keyResume keytimeoutResume timeout in milliseconds
{
"op": 10,
"d": {
"key": "d9qd02hbd190bd801",
"timeout": 60000
}
}timeoutBuffer timeout in milliseconds
{
"op": 11,
"d": {
"timeout": 60000
}
}