Build a Rocksky remote UI over the remote-control WebSocket
(see remote-ws/PROTOCOL.md) — the other half of Rocksky.RemotePlayer.
connect/2,3 registers in the background; you observe the user's players by
polling next_event/1 (or via listen/2) and drive them with commands
(set_primary/2, play/2, pause/2, next/2, previous/2, seek/3,
queue_jump/3, queue_remove/3, enqueue/6). Heartbeat, reconnect, and the
register handshake are handled by the native core.
Every command takes a target device id; pass nil (or "") to broadcast to
all the user's devices.
ctl = Rocksky.RemoteController.connect(token, "My Controller")
Rocksky.RemoteController.listen(ctl, %{
devices: fn e -> render(e["devices"]) end,
now_playing: fn e -> show_track(e["deviceId"], e["track"]) end
})
Rocksky.RemoteController.set_primary(ctl, device_id)
Rocksky.RemoteController.pause(ctl, device_id)
Rocksky.RemoteController.seek(ctl, device_id, 42_000)The handle is an opaque NIF resource (freed by GC). Commands return
{:ok, value} | {:error, message}.
Summary
Functions
Connect and register a controller. name is a registration label (controllers
are hidden from device lists); url overrides the WebSocket endpoint
(nil = public). Returns the opaque controller handle.
Disconnect and stop the background task.
Enqueue tracks (a list of queue-item maps, camelCase string keys) on the
target device. mode is "now" | "next" | "last"; shuffle is a boolean;
start_index is 0-based. nil target broadcasts.
Spawn a process that loops next_event/1 and dispatches each event to the
matching function in handlers. Returns {:ok, pid}. The loop ends when the
controller disconnects.
Skip to the next track (nil target broadcasts).
Block until the next update, returned as a decoded event map with a "type"
key ("devices", "device_registered", "device_unregistered",
"primary_changed", "now_playing", "status", "queue"). Returns nil
once the controller is disconnected.
Pause (nil target broadcasts).
Play. target is a device id, or nil to broadcast to all devices.
Skip to the previous track (nil target broadcasts).
Jump to index in the target device's queue (nil target broadcasts).
Remove queue item index on the target device (nil target broadcasts).
Seek the target device to position_ms (nil target broadcasts).
Choose the primary (scrobble/profile) device.
Functions
Connect and register a controller. name is a registration label (controllers
are hidden from device lists); url overrides the WebSocket endpoint
(nil = public). Returns the opaque controller handle.
Disconnect and stop the background task.
Enqueue tracks (a list of queue-item maps, camelCase string keys) on the
target device. mode is "now" | "next" | "last"; shuffle is a boolean;
start_index is 0-based. nil target broadcasts.
Spawn a process that loops next_event/1 and dispatches each event to the
matching function in handlers. Returns {:ok, pid}. The loop ends when the
controller disconnects.
handlers is a map keyed by event type; each function receives the full event
map: :devices, :device_registered, :device_unregistered,
:primary_changed, :now_playing, :status, :queue. Unhandled events are
ignored.
Skip to the next track (nil target broadcasts).
Block until the next update, returned as a decoded event map with a "type"
key ("devices", "device_registered", "device_unregistered",
"primary_changed", "now_playing", "status", "queue"). Returns nil
once the controller is disconnected.
Pause (nil target broadcasts).
Play. target is a device id, or nil to broadcast to all devices.
Skip to the previous track (nil target broadcasts).
Jump to index in the target device's queue (nil target broadcasts).
Remove queue item index on the target device (nil target broadcasts).
Seek the target device to position_ms (nil target broadcasts).
Choose the primary (scrobble/profile) device.