Skip to main content

Class: BaseMediaHandler

Defined in: packages/media-session/src/handler.ts:20

No-op implementation of every MediaHandler method.

Subclass and override only what the app supports; the set the app advertises is PlaybackState.capabilities, so a no-op here is never reachable from a correctly-broadcasting app — it exists so adding a method to the interface is not a breaking change for every consumer.

Implements

Constructors

Constructor

new BaseMediaHandler(): BaseMediaHandler;

Returns

BaseMediaHandler

Methods

customAction()

customAction(_name: string, _extras?: Record<string, unknown>): void | Promise<void>;

Defined in: packages/media-session/src/handler.ts:60

One of PlaybackState.customActions was pressed.

Android only. MPRemoteCommandCenter's command set is fixed and carries no app-defined identifier, so no iOS remote surface can invoke a custom action and this is never called there by the session — see MediaCustomAction. Call it from your own UI if you want one code path on both platforms.

Parameters

ParameterType
_namestring
_extras?Record<string, unknown>

Returns

void | Promise<void>

Implementation of

MediaHandler.customAction


getChildren()

getChildren(_parentId: string): Promise<BrowseItem[]>;

Defined in: packages/media-session/src/handler.ts:106

Default: an empty tree.

Correct by construction rather than by luck: an empty list is what Google asks a browse node with no children to return, so an app that never implements this shows a car an app with nothing in it — not an error, not a crash, and not a browse entry that does nothing when tapped.

Parameters

ParameterType
_parentIdstring

Returns

Promise<BrowseItem[]>

Implementation of

MediaHandler.getChildren


getMediaItem()

getMediaItem(_id: string): Promise<BrowseItem | undefined>;

Defined in: packages/media-session/src/handler.ts:111

Default: no such item. See getChildren.

Parameters

ParameterType
_idstring

Returns

Promise<BrowseItem | undefined>

Implementation of

MediaHandler.getMediaItem


onAdjustDeviceVolume()

onAdjustDeviceVolume(_direction: RemoteVolumeDirection): void | Promise<void>;

Defined in: packages/media-session/src/handler.ts:54

Default: nothing. Only ever called for a volumeControl: 'relative' device — see MediaHandler.onAdjustDeviceVolume.

Parameters

ParameterType
_directionRemoteVolumeDirection

Returns

void | Promise<void>

Implementation of

MediaHandler.onAdjustDeviceVolume


onPlaybackResumption()

onPlaybackResumption(): void | Promise<void>;

Defined in: packages/media-session/src/handler.ts:82

Default: nothing.

Correct by design — by the time this fires the service has already put the persisted track on screen and the user's play is queued for replay on this same handler. Resumption works without a line of code here; the hook exists for logging and for work that must happen before that replayed play() (refreshing an expired stream token, say).

Returns

void | Promise<void>

Implementation of

MediaHandler.onPlaybackResumption


onSessionError()

onSessionError(error: SessionError): void | Promise<void>;

Defined in: packages/media-session/src/handler.ts:94

The one method here that is not a no-op, and the exception is the point: every other default is silent because the app advertises what it supports, but a silent default on an error channel would swallow the very failures the channel was added to stop swallowing (CLAUDE.md principle 6).

So the default logs — the same floor the service applies to a handler that does not implement the method at all. Override it to render the failure; call super.onSessionError(error) if you want the log as well.

Parameters

ParameterType
errorSessionError

Returns

void | Promise<void>

Implementation of

MediaHandler.onSessionError


onSetDeviceMuted()

onSetDeviceMuted(_muted: boolean): void | Promise<void>;

Defined in: packages/media-session/src/handler.ts:58

Default: nothing. See onSetDeviceVolume.

Parameters

ParameterType
_mutedboolean

Returns

void | Promise<void>

Implementation of

MediaHandler.onSetDeviceMuted


onSetDeviceVolume()

onSetDeviceVolume(_volume: number): void | Promise<void>;

Defined in: packages/media-session/src/handler.ts:49

Default: nothing — and unreachable until the app publishes a remote device with setRemotePlayback, so an app whose audio never leaves the phone can ignore these three entirely.

With the usual volumeControl: 'absolute', this is also where a hardware volume key lands: the library turns the notch into a level first (see onAdjustDeviceVolume), so an absolute backend needs this method and nothing else.

Parameters

ParameterType
_volumenumber

Returns

void | Promise<void>

Implementation of

MediaHandler.onSetDeviceVolume


onSetRepeatMode()

onSetRepeatMode(_mode: MediaRepeatMode): void | Promise<void>;

Defined in: packages/media-session/src/handler.ts:36

Default: nothing — and unlike the transport methods, doing nothing here is visible. The remote surface's repeat button will spring back to whatever the app last broadcast, because the state only moves when the app moves it. That is the same acknowledge-by-broadcast contract every other command follows; it is only more noticeable because the control is a toggle.

Parameters

ParameterType
_modeMediaRepeatMode

Returns

void | Promise<void>

Implementation of

MediaHandler.onSetRepeatMode


onSetShuffle()

onSetShuffle(_enabled: boolean): void | Promise<void>;

Defined in: packages/media-session/src/handler.ts:38

Default: nothing. See onSetRepeatMode.

Parameters

ParameterType
_enabledboolean

Returns

void | Promise<void>

Implementation of

MediaHandler.onSetShuffle


onSleepTimer()

onSleepTimer(): void | Promise<void>;

Defined in: packages/media-session/src/handler.ts:71

Default: nothing.

Correct by design — the pause has already happened natively by the time this is called (see MediaHandler.onSleepTimer), so an app that only wants "stop playing after 30 minutes" needs no code here at all.

Returns

void | Promise<void>

Implementation of

MediaHandler.onSleepTimer


onTaskRemoved()

onTaskRemoved(): void | Promise<void>;

Defined in: packages/media-session/src/handler.ts:59

Android only: the app's task was swiped out of Recents.

The native default policy (keep playing if playing, otherwise stop the service) has already been decided by the time this runs — overriding this method is for side effects (persistence, analytics), not for changing that decision. Call stopService() here to force a stop.

Returns

void | Promise<void>

Implementation of

MediaHandler.onTaskRemoved


pause()

pause(): void | Promise<void>;

Defined in: packages/media-session/src/handler.ts:22

Returns

void | Promise<void>

Implementation of

MediaHandler.pause


play()

play(): void | Promise<void>;

Defined in: packages/media-session/src/handler.ts:21

Returns

void | Promise<void>

Implementation of

MediaHandler.play


playFromMediaId()

playFromMediaId(id: string): void | Promise<void>;

Defined in: packages/media-session/src/handler.ts:129

The second method here that is not a no-op, and for the same reason onSessionError is the first: the default that would be silent is the bug.

A handler that overrides getChildren and forgets this one hands a car a full browse tree in which every single leaf does nothing when tapped — no error, no log, no playback (ARCHITECTURE §27). There is nothing this class can play on the app's behalf, so it says so on the channel the app already reads.

Overriding it silences the report, which is the point: implementing the method is the fix.

Parameters

ParameterType
idstring

Returns

void | Promise<void>

Implementation of

MediaHandler.playFromMediaId


seekTo()

seekTo(_position: number): void | Promise<void>;

Defined in: packages/media-session/src/handler.ts:24

Parameters

ParameterType
_positionnumber

Returns

void | Promise<void>

Implementation of

MediaHandler.seekTo


setRate()

setRate(_rate: number): void | Promise<void>;

Defined in: packages/media-session/src/handler.ts:28

Parameters

ParameterType
_ratenumber

Returns

void | Promise<void>

Implementation of

MediaHandler.setRate


skipToNext()

skipToNext(): void | Promise<void>;

Defined in: packages/media-session/src/handler.ts:25

Returns

void | Promise<void>

Implementation of

MediaHandler.skipToNext


skipToPrevious()

skipToPrevious(): void | Promise<void>;

Defined in: packages/media-session/src/handler.ts:26

Returns

void | Promise<void>

Implementation of

MediaHandler.skipToPrevious


skipToQueueItem()

skipToQueueItem(_index: number): void | Promise<void>;

Defined in: packages/media-session/src/handler.ts:27

Play an arbitrary entry of the broadcast queue.

Reached from a remote surface on Android only — Android Auto, Wear, a car head unit, any controller that renders the queue (Player.COMMAND_SEEK_TO_MEDIA_ITEM). MPRemoteCommandCenter has no queue-jump command, so no iOS remote surface can invoke this; it is still part of the interface because your own UI calls it on both platforms.

Parameters

ParameterType
_indexnumber

Returns

void | Promise<void>

Implementation of

MediaHandler.skipToQueueItem


stop()

stop(): void | Promise<void>;

Defined in: packages/media-session/src/handler.ts:23

Release resources. Does NOT end background execution — call stopService() for that.

Returns

void | Promise<void>

Implementation of

MediaHandler.stop