OptionaldestroyOptional: tear down per-session resources. The browser reference impl uses this to remove the silent-audio prime element when the last session is destroyed. Bridges that need no per-session teardown may omit this field.
Subscribe to OS-level action events (user clicks play/pause/seek/next/prev on the transport surface). Returns an unsubscribe handle.
The callback receives (sessionId, action, value?). sessionId is the
bridge's currently-active session (the browser impl tracks this internally
via setActionHandler-at-fire-time; native impls track via setActiveSession).
value is populated for action === 'seek' (seek target in seconds) and
for action === 'volume' (0.0-1.0). The service dispatches the resulting
media.command envelope to the owning napplet of that session.
OptionalsetOptional: notify the bridge that the active session has changed. The browser reference impl uses this to switch which session's metadata/state is mirrored to the singleton navigator.mediaSession and to install (or clear) action handlers for the session's declared capabilities.
The optional actions parameter carries the session's declared capability
set so the bridge can narrow which OS transport buttons are active. When
omitted, the bridge applies its default set. Native OS bridges that track
active-session state internally may omit this field entirely.
Optionalactions: readonly MediaAction[]Set the metadata displayed on the OS transport surface for a session. Called on session.create (with initial metadata) and on session.update (with merged metadata) whenever the session is the active session. Implementations MUST be idempotent.
Set the playback state for a session. Called on media.state reports whenever the session is the active session. State strings match nap-media MediaState.status exactly. Implementations MUST be idempotent.
Host-bridge contract for pluggable media backends.
The browser reference implementation (createBrowserMediaBridge) mirrors napplet-reported metadata/state to
navigator.mediaSessionand installssetActionHandlercallbacks that fan into the bridge's onAction subscribers. It satisfies this interface with all 5 fields implemented (setActiveSession switches the active session and optionally re-applies action-handler narrowing; destroySession tears down the silent-audio prime on last-session teardown).Host apps (Electron, Tauri) implement this interface in their own code and pass it via
createMediaService({ hostBridge: myBridge })— the service then delegates metadata/state mirroring + action routing to the bridge and remains browser-free. Session-ownership bookkeeping (which windowId owns which sessionId, which send callback routes media.command back to which napplet) stays in the service layer — that's wire-protocol concern, not a bridge concern.Reference implementations for Electron / Tauri are explicitly out of v1.4 scope and live in host-app examples / follow-up milestones (see REQUIREMENTS.md "Future Requirements").
Example