Knit UI
GitHub

Playground

Loading playground…

true
Playground
<Audio
  source="https://samplelib.com/mp3/sample-30s.mp3"
  size="md"
  controls
  loop={false}
  muted={false}
/>

Examples

Basic

Loading example…

BasicSourceStorybook

With Metadata

Loading example…

With MetadataSourceStorybook

Lock Screen

Lock-screen / now-playing controls with a cover preview. Setting lockScreen publishes the title/artist/album/artwork to the OS: on native (expo-audio) it owns the iOS lock screen / Android media notification, and on web it drives the browser MediaSession API — so the artwork shows as the cover in the OS media controls / hardware-key UI. Play it, then check your system media controls (or lock the device on a native build).

Loading example…

Lock ScreenSourceStorybook

Looping

Loading example…

LoopingSourceStorybook

Sizes

Loading example…

SizesSourceStorybook

Custom Control Bar

Compose a custom bar from the exported parts.

Loading example…

Custom Control BarSourceStorybook

Headless

Headless: no transport, just the header. Drive it via Audio.useAudio().

Loading example…

HeadlessSourceStorybook

Styles

Per-slot style overrides.

Loading example…

StylesSourceStorybook

Themed

Theme-driven recolor. The whole player is built on $colorN ramp tokens, so dropping it under a <Theme> recolors it with zero per-component logic — the same property that themes Button/ActionIcon. No hardcoded colors anywhere.

Loading example…

ThemedSourceStorybook

Alternate Source

Loading example…

Alternate SourceSourceStorybook

Long Track

A full, minutes-long track — gives the scrubber real range to drag across and a meaningful elapsed/remaining readout (the short sample clips are only seconds).

Loading example…

Long TrackSourceStorybook

Two Players

Two players sharing ONE shared audio engine (the default singleton). Press play on one, then play on the other: the engine switches to the second track and the first pauses — there is only ever ONE <audio> element. Return to the first and it resumes from where you left off.

Loading example…

Two PlayersSourceStorybook

Props

PropTypeDefaultDescription
source requiredstring | number | AudioSourceObject | nullhttps://samplelib.com/mp3/sample-30s.mp3The audio to play.
albumstring | undefinedNow-playing album.
artiststring | undefinedNow-playing artist.
artworkstring | undefinedArtwork image URL.
autoPlayboolean | undefinedBegin playback as soon as the source is ready.
controlsReactNodetrueThe control chrome. `true` (default) renders the built-in control bar; `false` renders no chrome; a node renders custom chrome inside the context (compose `Audio.*` parts).
getController((controller: AudioController) => void) | undefinedReceives the controller once ready.
idstring | undefinedStable identity for the shared-engine registry. Defaults to a generated id (each `<Audio>` is its own player); pass an explicit `id` to make two mounts address the SAME shared-engine slot.
keyboardboolean | undefinedEnable keyboard shortcuts (space, arrows, m, …). Default `true`.
labelstring | undefinedAccessible label for the player region. Default `"Audio player"`.
lockScreenboolean | AudioMetadata | undefinedEnable lock-screen / now-playing controls with the given metadata. `true` derives metadata from `title`/`artist`/`album`/`artwork`.
loopboolean | undefinedfalseReplay automatically on end.
maxWidthnumber | Animated.AnimatedNode | GetThemeValueForKey<"maxWidth"> | null | undefinedFrame max width.
mutedboolean | undefinedfalseStart muted (required by browsers for unattended autoplay).
onEnded(() => void) | undefined
onError((error: AudioError) => void) | undefined
onPlayingChange((playing: boolean) => void) | undefined
onReady(() => void) | undefinedFired once the player first becomes ready to play.
onStatusChange((status: AudioStatus, error: AudioError | null) => void) | undefined
onTimeUpdate((currentTime: number) => void) | undefined
playbackRatenumber | undefinedInitial playback rate.
shouldCorrectPitchboolean | undefinedCorrect pitch when the rate changes. Default `true`.
showHeaderboolean | undefinedShow the metadata header. Defaults to `true` when any metadata is given.
size system"xxs" | "xs" | "sm" | "md" | "lg" | "xl" | "xxl" | undefined
xxs · xs · sm · md · lg · xl · xxl
mdControl sizing scale. Default `'md'`.
styles systemSlotStyles<AudioStyles> | undefinedPer-slot style overrides.
testIDstring | undefined
titlestring | undefinedNow-playing title (shown in the header + used for lock-screen metadata).
updateIntervalnumber | undefinedStatus / `timeUpdate` interval, ms (native). The unified name.
volumenumber | undefinedInitial volume, 0..1.
widthnumber | GetThemeValueForKey<"width"> | Animated.AnimatedNode | null | undefinedFrame width.

Style slots

Every part of Audio can be styled through the styles prop. Explicit props on the component always win over slot styles.

SlotUsage
artiststyles={{ artist: { … } }}
artworkstyles={{ artwork: { … } }}
controlBarstyles={{ controlBar: { … } }}
headerstyles={{ header: { … } }}
rootstyles={{ root: { … } }}
timestyles={{ time: { … } }}
titlestyles={{ title: { … } }}