Media service — media_service
The server that owns music sources, library, queues and synchronized playback. The project owns
rooms and physical outputs; a media service consumes that configuration and must not import its
own player inventory back into the project.
Why a service is a device, and why it is structural
Structural rather than av, on the same grounds app_shelf is: every other contract in that
category is a box with a power cord, and there is nothing here for a virtual driver to pretend to
be. Nobody buys a Spotify Connect, and nobody points a remote at one.
Because everything else somebody configures is one. Adding Music Assistant has the same shape as
adding a bridge — it gets a name, a settings page, a place in the item list and a project that
remembers it. The driver talks to the external service API; provider-specific configuration stays
behind that boundary rather than becoming a second set of Juno service devices.
The service owns playback; the project owns outputs
Nothing on this contract carries or decodes audio. Core periodically gives the service the exact
set of project media_output proxies it may use. The service may keep private protocol players
for those outputs — Sendspin clients in Music Assistant — but those are implementation details,
not new Juno devices. Playback commands name only ids from that synchronized set.
Pushed or chosen
is_pushed still distinguishes a phone-owned receiver, but Music Assistant is driven here and
sets it false. Its provider integrations remain Music Assistant's concern; Juno only selects a
project output and asks the service to act on its queue.
Capabilities
Declared in the driver manifest under [[proxy]] capabilities. Anything not declared takes the default below.
| Capability | Type | Default | Meaning |
|---|
has_multiroom | bool | false | |
has_search | bool | false | |
is_pushed | bool | true | |
protocol | string | "" | |
Commands
join
| Parameter | Type | Notes |
|---|
leader | string | |
outputs | string | JSON array of outputs to add |
leave
| Parameter | Type | Notes |
|---|
leader | string | Current leader before this change |
remaining | string | JSON array of outputs that remain, new leader first |
removed | string | JSON array of outputs leaving |
pause
| Parameter | Type | Notes |
|---|
leader | string | |
play
| Parameter | Type | Notes |
|---|
artist | string (optional) | |
artwork | string (optional) | |
at | string (optional) | Requested start instant; synchronized services may use their own stream clock |
outputs | string | JSON array of allowed service-private player ids, leader first |
title | string (optional) | |
url | string | Music Assistant URI or a URL it can resolve |
resume
| Parameter | Type | Notes |
|---|
leader | string | |
search
Only present when has_search is declared true.
| Parameter | Type | Notes |
|---|
limit | u32 (optional) | |
media_types | string (optional) | JSON array such as ["track","playlist"] |
query | string | |
token | string (optional) | Echoed on the matching search_results |
stop
| Parameter | Type | Notes |
|---|
leader | string | |
sync_outputs
Replace the service's allowed output set. outputs is a JSON array whose entries contain
player_id, binding, device, name, and room. The ids are service-private routing keys;
the bindings remain the only output objects in the project. An empty array means no output may be
used. This is full desired state, not a delta.
| Parameter | Type | Notes |
|---|
outputs | string | JSON array of project media-output routes |
Notifications
online_changed
| Parameter | Type | Notes |
|---|
online | bool | |
outputs_changed
| Parameter | Type | Notes |
|---|
outputs | string | JSON array of configured output status objects |
search_results
Only present when has_search is declared true.
| Parameter | Type | Notes |
|---|
items | json | Playable results with stable id, name, subtitle and metadata |
token | string (optional) | |
total | u32 (optional) | |
service_changed
What this service is and what it is called, after setup or an edit.
| Parameter | Type | Notes |
|---|
name | string (optional) | What outputs advertise it as. Empty means each uses its room's name. |
protocol | string | |
State
Last-known values core keeps for a binding of this proxy.
| Key | Type | Meaning |
|---|
name | string | |
online | bool | |
outputs | string | |
protocol | string | |