D-Bus API (MPRIS2)
On Linux deployments, both the SnapDog Server and SnapDog Client register standard MPRIS2 (Media Player Remote Interoperability Specification) interfaces on the D-Bus bus. This allows media keys, system tray controllers, lock screens, and home automation tools to query and control playback natively.
1. SnapDog Server D-Bus (Audio Zones)
The snapdog server registers an MPRIS2 interface for each configured audio zone, exposing each zone as a separate media player device.
Interface & Bus Details
- Bus Name:
org.mpris.MediaPlayer2.snapdog.zone{N}(where{N}is the 1-based index of the zone). - Object Path:
/org/mpris/MediaPlayer2 - Bus Type: Session Bus when
DBUS_SESSION_BUS_ADDRESSis available; otherwise System Bus fallback for headless services.
Implemented Methods (org.mpris.MediaPlayer2.Player)
| Method | Arguments | Description |
|---|---|---|
Play() | — | Resumes playback on the zone. |
Pause() | — | Pauses playback. |
PlayPause() | — | Toggles the active play/pause state. |
Stop() | — | Stops playback and releases zone audio buffers. |
Next() | — | Skips to the next track in the queue. |
Previous() | — | Skips to the previous track or restarts the song. |
Seek(Offset) | Offset (Int64 microseconds) | Seeks relative to the current play position. |
SetPosition(Id, Pos) | Id (ObjectPath), Pos (Int64 us) | Seeks to an absolute position. |
Implemented Properties (org.mpris.MediaPlayer2.Player)
PlaybackStatus(String) —"Playing","Paused", or"Stopped".Volume(Double) — Volume level between0.0(mute) and1.0(100%).Position(Int64) — Current play position in microseconds.Metadata(Dict) — Standard Xesam metadata tags:mpris:trackid(ObjectPath) —/org/mpris/MediaPlayer2/snapdog/zone{id}/track.mpris:length(Int64) — Track length in microseconds.mpris:artUrl(String) — HTTP cover art link (e.g.http://<host>:<port>/api/v1/zones/{id}/cover).xesam:title(String) — Track or stream title.xesam:artist(Array of Strings) — Artist array.xesam:album(String) — Album title.
CanPlay/CanPause/CanSeek/CanGoNext/CanGoPrevious/CanControl(Boolean) — Capabilities flags.Shuffle(Boolean) — Read-write shuffle state.LoopStatus(String) — Read-write repeat state:"None","Track", or"Playlist".Rate/MinimumRate/MaximumRate(Double) — Fixed at1.0.
Server Command-Line Examples
playerctl automatically detects and formats MPRIS2 commands.
# List all active SnapDog server zone playersplayerctl --list-all | grep snapdog.zone
# Toggle Play/Pause on Zone 1playerctl -p snapdog.zone1 play-pause
# Skip to the next track in Zone 2playerctl -p snapdog.zone2 next
# Retrieve active track title and artist in Zone 1playerctl -p snapdog.zone1 metadata --format "{{title}} - {{artist}}"For low-level shell scripting or system diagnostics, use busctl.
# Query active playback status of Zone 1busctl --user get-property \ org.mpris.MediaPlayer2.snapdog.zone1 \ /org/mpris/MediaPlayer2 \ org.mpris.MediaPlayer2.Player \ PlaybackStatus
# Send raw Play command to Zone 2busctl --user call \ org.mpris.MediaPlayer2.snapdog.zone2 \ /org/mpris/MediaPlayer2 \ org.mpris.MediaPlayer2.Player \ Play2. SnapDog Client D-Bus (Player Endpoints)
The snapdog-client player registers an MPRIS2 interface on speaker endpoints, mapping controls locally on the player board.
Interface & Bus Details
- Bus Name:
org.mpris.MediaPlayer2.snapdog_client(for primary instance).- Multi-Instance: If running multiple player instances on the same host, subsequent instances bind to
org.mpris.MediaPlayer2.snapdog_client.instance{N}(e.g.,instance2).
- Multi-Instance: If running multiple player instances on the same host, subsequent instances bind to
- Object Path:
/org/mpris/MediaPlayer2 - Bus Type: Hybrid Bus. The client binds to the Session Bus if
DBUS_SESSION_BUS_ADDRESSis defined. If absent (e.g., on a headless Raspberry Pi boot environment), it automatically falls back to the System Bus.
Implemented Methods (org.mpris.MediaPlayer2.Player)
| Method | Arguments | Description |
|---|---|---|
Play() | — | Sends a custom control payload instructing the server to play. |
Pause() | — | Instructs the server to pause. |
PlayPause() | — | Toggles playback locally. |
Stop() | — | Stops playback. |
Next() | — | Skips to the next track. |
Previous() | — | Skips to the previous track. |
Seek(Offset) | Offset (Int64 microseconds) | Sends seek offset command to the server. |
Implemented Properties (org.mpris.MediaPlayer2.Player)
PlaybackStatus(String) —"Playing"or"Stopped".Volume(Double) — Local soundcard volume level[0.0..1.0]. Writing to this updates the local mixer gain and notifies the server.Shuffle(Boolean) — Read-write flag. Modifying this sends a shuffle toggle command to the server.LoopStatus(String) — Read-write. Returns"None","Track", or"Playlist". Writing updates the server repeat mode.Position(Int64) — Current playback position in microseconds.Metadata(Dict) — Standard Xesam metadata tags:mpris:trackid(ObjectPath) —/org/snapdog/track.mpris:length(Int64) — Length in microseconds.mpris:artUrl(String) — Local file link to pre-cached cover art (file://<path>).xesam:title/xesam:album(String) andxesam:artist(Array of Strings) — Metadata details.
Client Command-Line Examples
# Control the primary local client playerplayerctl -p snapdog_client play-pause
# Adjust local speaker volume to 80% (0.8)playerctl -p snapdog_client volume 0.8
# Query shuffle state on local clientplayerctl -p snapdog_client metadata --format "{{shuffle}}"# Query Client Player volume status (using System bus fallback)busctl --system get-property \ org.mpris.MediaPlayer2.snapdog_client \ /org/mpris/MediaPlayer2 \ org.mpris.MediaPlayer2.Player \ Volume
# Monitor Client 1 state changes in real timebusctl --user monitor org.mpris.MediaPlayer2.snapdog_client3. D-Bus Signals
Both the server and client players emit standard signals:
Seeked(Position)(Int64) Fired under theorg.mpris.MediaPlayer2.Playerinterface when a seek operation completes. The payload contains the new position in microseconds.PropertiesChanged(Interface, Changed, Invalidated)Standard D-Bus notification fired underorg.freedesktop.DBus.Propertieswhenever properties likePlaybackStatus,Metadata,Shuffle, orVolumechange. Listening client widgets update their UI states reactively based on this signal.
4. Headless Server & Systemd Service Setup
Under headless Linux servers running SnapDog as a background systemd daemon, services will fail to locate a session bus by default. Use one of the following methods to establish D-Bus sessions:
The cleanest approach is running SnapDog as a user unit, which automatically binds to the user’s session bus.
- Place your unit file in
~/.config/systemd/user/snapdog.service. - Enable lingering so the session bus spawns on boot and persists after logout:
Terminal window loginctl enable-linger snapdog - Start the service:
Terminal window systemctl --user enable --now snapdog
If you must run SnapDog as a system-wide service, you can run a user-level D-Bus broker manually and inject its socket address into the systemd service file:
- Edit
/etc/systemd/system/snapdog.serviceand add theEnvironmentparameter:[Service]ExecStart=/usr/local/bin/snapdog --config /etc/snapdog/snapdog.toml# Bind to user DBUS session socket (replace UID '1000' with your target user UID)Environment=DBUS_SESSION_BUS_ADDRESS=unix:path=/run/user/1000/busUser=snapdogGroup=audio - Reload and restart:
Terminal window sudo systemctl daemon-reloadsudo systemctl restart snapdog