Skip to content

Custom Binary Protocol

SnapDog client boards (snapdog-client and SnapDog OS) communicate with the server daemon over an extended binary protocol built on top of Snapcast. Standard Snapcast clients ignore these proprietary message headers, while SnapDog players parse and act upon them.


1. Frame Structure & Message Types

All messages are prefixed with a header containing a 2-byte Message Type ID (big-endian), a 4-byte Payload Length (big-endian), and the variable-length payload bytes.

SnapDog extends the protocol using message type IDs 10 through 15:

Type IDNameDirectionFormatDescription
10MSG_TYPE_EQ_CONFIGServer → ClientJSONUser-configured Parametric EQ coefficients for client-side DSP hardware.
11MSG_TYPE_SPEAKER_EQServer → ClientJSONRoom correction PEQ coefficients from matching Spinorama speaker profiles.
12MSG_TYPE_FADE_OUTServer → ClientBinaryTriggers immediate client-side volume fade-out.
13MSG_TYPE_PLAYBACK_CONTROLClient → ServerJSONKey presses/actions from physical buttons on client hardware.
14MSG_TYPE_TRACK_METADATAServer → ClientJSONPlayback status and track tags to render on client OLED/LCD screens.
15MSG_TYPE_COVER_ARTServer → ClientBinaryRaw cover art image data (JPEG/PNG) streamed in chunks.

2. Payload Schemas

Type 10 & 11: Equalizer Coefficients (EqConfig)

Used to configure the hardware DSP filters. Both the user EQ (Type 10) and speaker correction profiles (Type 11) share this JSON schema.

  • Payload Format: JSON
  • Maximum EQ Bands: 10
{
"enabled": true,
"bands": [
{
"freq": 80.0,
"gain": -3.2,
"q": 1.41,
"type": "peaking"
},
{
"freq": 1000.0,
"gain": 1.5,
"q": 1.0,
"type": "high_shelf"
}
],
"preset": "custom"
}

Band Properties

  • freq (f32) — Center/cutoff frequency in Hz.
  • gain (f32) — Boost or cut in dB (ignored for low/high pass).
  • q (f32) — Filter quality factor (bandwidth selector).
  • type (String) — Filter curve. Supported options:
    • "low_shelf" — Boosts/attenuates below cutoff.
    • "high_shelf" — Boosts/attenuates above cutoff.
    • "peaking" — Peak band filter.
    • "low_pass" — Low pass attenuation.
    • "high_pass" — High pass attenuation.

Type 12: Fade-out Trigger

Triggers client-side fading before stream preemption or zone switching.

  • Payload Format: Binary
  • Size: 2 bytes (u16 little-endian representing fade duration in milliseconds).
  • Example: [44, 1] translates to 0x012C = 300 milliseconds.

Type 13: Playback Control (PlaybackControl)

Transmits client button inputs (e.g. physical buttons on a speaker chassis or custom remote) back to the server.

  • Payload Format: JSON (enum tagged with cmd)

Available Commands

Play
{ "cmd": "play" }
Pause
{ "cmd": "pause" }
Stop
{ "cmd": "stop" }
Next Track
{ "cmd": "next" }
Previous Track
{ "cmd": "previous" }
Seek

Supports absolute position or relative offset seeks in milliseconds.

{
"cmd": "seek",
"position_ms": 45000,
"offset_ms": null
}

or

{
"cmd": "seek",
"position_ms": null,
"offset_ms": -5000
}
Shuffle
{
"cmd": "shuffle",
"enabled": true
}
Repeat Mode
{
"cmd": "repeat",
"mode": "track"
}

(modes: "off", "track", "playlist")

Specific Playlist Switch
{
"cmd": "playlist",
"index": 2,
"track": 0
}
Playlist Navigation
{ "cmd": "playlist_next" }
{ "cmd": "playlist_previous" }

Type 14: Track Metadata (TrackMetadata)

Pushed to the client upon stream state changes to update local player displays.

  • Payload Format: JSON
{
"playback": "playing",
"source": "subsonic_playlist",
"shuffle": false,
"repeat": "off",
"title": "Acoustic Song",
"artist": "The Band",
"album": "Unplugged",
"album_artist": "The Band",
"genre": "Rock",
"year": 2024,
"track_number": 2,
"disc_number": 1,
"duration_ms": 240000,
"position_ms": 12400,
"seekable": true,
"cover_url": "/api/v1/zones/1/cover",
"bitrate_kbps": 320,
"content_type": "audio/flac",
"track_index": 2,
"track_count": 10,
"playlist": 1,
"playlist_name": "My Acoustic Playlist",
"playlist_total": 5,
"can_playlist_next": true,
"can_playlist_prev": true,
"can_next": true,
"can_prev": false,
"volume": 75,
"muted": false
}

Type 15: Cover Art Binary Stream

Pushed to clients to render album art thumbnails on color player screens.

  • Payload Format: Binary
  • Payload Content: Raw image binary buffer (JPEG or PNG bytes) with no headers or wrapper frames. Clients can immediately decode and draw the buffer to video buffers.

Next Steps