Skip to main content

Type Alias: MediaPlaybackStatus

type MediaPlaybackStatus = "playing" | "paused" | "buffering" | "stopped" | "error";

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

Coarse playback status, broadcast by the app.

These are the five states from the spec doc. Deliberately not media3's Player.STATE_* nor AVPlayer.timeControlStatus — this is the union the app thinks in; each platform maps it to its own vocabulary (see BroadcastPlayer.getState / HybridRnMediaMediaSession.publishNowPlayingInfo).

Platform: iOS collapses three of these into one

Android distinguishes all five — media3 gets STATE_READY+playWhenReady, STATE_BUFFERING, STATE_IDLE, and for error a real PlaybackException. iOS has no playback-state key at all for an app to write: the only lever MPNowPlayingInfoCenter gives is MPNowPlayingInfoPropertyPlaybackRate, and paused, stopped and error all publish a rate of 0, so every iOS remote surface renders them identically. MPNowPlayingInfoCenter.playbackState looks like the missing lever and is not: it exists on iOS 13+ but Apple documents it as "This property only applies to macOS" (developer.apple.com/documentation/mediaplayer/mpnowplayinginfocenter/playbackstate, read 2026-08-16), so writing it on iOS is not something the platform promises to honour and it is deliberately not written.

buffering does survive on iOS, because it is expressed the same way it is on Android — as a rate of 0 with the transport still advertised — but it too is indistinguishable from paused on the lock screen.

NOTE: every member of a string union becomes a native enumerator whose name is the member, upper-cased with separators stripped (skipToNextSKIPTONEXT, Swift .skiptonext). Members must therefore stay distinct case-insensitively, and must not collide with a C macro or a Swift keyword — the same constraint that forced defaultMode in @afkcodes/timbre-audio-session.