@molecule/app-audio
Core interface · audio · App (browser) · v1.0.2 · Apache-2.0
Audio player core interface for molecule.dev.
npm install @molecule/app-audioHow it works
@molecule/app-audio is the audio core interface on the app (browser) side: the API your app calls, with no vendor inside.
Choose the implementation by bonding one of its 1 provider: @molecule/app-audio-howler.
import { requireProvider, setProvider } from '@molecule/app-audio'
import { provider } from '@molecule/app-audio-howler'
setProvider(provider) // at startup
const player = requireProvider().createPlayer({
src: '/audio/track.mp3',
volume: 0.8,
onEnd: () => console.log('Playback finished'),
})
playButton.onclick = () => player.play() // user gesture — autoplay is blockedProviders (1): @molecule/app-audio-howler
Works with: @molecule/app-bond
Reference
Audio player core interface for molecule.dev.
Provides a standardized API for audio playback. Bond a provider
(e.g. @molecule/app-audio-howler) to supply the concrete implementation.
Auto-generated, AI-first package reference for the molecule.dev ecosystem. It is written to be read by coding agents as much as by people, and is generated from this package's source — edit
src/index.tsJSDoc, not this file.
Quick Start
import { requireProvider, setProvider } from '@molecule/app-audio'
import { provider } from '@molecule/app-audio-howler'
setProvider(provider) // at startup
const player = requireProvider().createPlayer({
src: '/audio/track.mp3',
volume: 0.8,
onEnd: () => console.log('Playback finished'),
})
playButton.onclick = () => player.play() // user gesture — autoplay is blocked
Type
core
Installation
npm install @molecule/app-audio @molecule/app-bond
API
Interfaces
AudioPlayerOptions
Configuration options for creating an audio player.
interface AudioPlayerOptions {
/** Audio source URL(s). Multiple URLs provide format fallbacks. */
src: string | string[]
/** Whether to start playing automatically. Defaults to `false`. */
autoplay?: boolean
/** Whether to loop playback. Defaults to `false`. */
loop?: boolean
/** Initial volume level (0.0 to 1.0). Defaults to `1.0`. */
volume?: number
/** Callback when playback reaches the end. */
onEnd?: () => void
/** Callback invoked during playback with current time and total duration. */
onProgress?: (time: number, duration: number) => void
}
AudioPlayerInstance
A live audio player instance returned by the provider.
interface AudioPlayerInstance {
/**
* Starts or resumes playback.
*/
play(): void
/**
* Pauses playback.
*/
pause(): void
/**
* Stops playback and resets position to the beginning.
*/
stop(): void
/**
* Seeks to a specific time position.
*
* @param time - Position in seconds to seek to.
*/
seek(time: number): void
/**
* Sets the playback volume.
*
* @param volume - Volume level from 0.0 (muted) to 1.0 (full).
*/
setVolume(volume: number): void
/**
* Returns the current playback volume.
*
* @returns Volume level from 0.0 to 1.0.
*/
getVolume(): number
/**
* Returns the total duration of the audio in seconds.
*
* @returns Duration in seconds.
*/
getDuration(): number
/**
* Returns the current playback position in seconds.
*
* @returns Current time in seconds.
*/
getCurrentTime(): number
/**
* Checks whether the audio is currently playing.
*
* @returns `true` if audio is playing.
*/
isPlaying(): boolean
/**
* Destroys the player instance and releases all resources.
*/
destroy(): void
}
AudioProvider
Audio player provider interface.
All audio providers must implement this interface to create and manage audio playback.
interface AudioProvider {
/** Provider name identifier. */
readonly name: string
/**
* Creates a new audio player instance.
*
* @param options - Configuration for the player.
* @returns An audio player instance.
*/
createPlayer(options: AudioPlayerOptions): AudioPlayerInstance
}
Functions
setProvider(provider)
Registers an audio provider as the active singleton.
function setProvider(provider: AudioProvider): void
provider— The audio provider implementation to bond.
getProvider()
Retrieves the bonded audio provider, or null if none is bonded.
function getProvider(): AudioProvider | null
Returns: The active audio provider, or null.
hasProvider()
Checks whether an audio provider has been bonded.
function hasProvider(): boolean
Returns: true if an audio provider is available.
requireProvider()
Retrieves the bonded audio provider, throwing if none is configured.
function requireProvider(): AudioProvider
Returns: The active audio provider.
Available Providers
| Provider | Package |
|---|---|
| Howler | @molecule/app-audio-howler |
Injection Notes
Requirements
Peer dependencies:
@molecule/app-bond^1.0.1
Runtime Dependencies
-
@molecule/app-bond -
Wire it with THIS package's
setProvider()orbond('audio', …).setProvider()delegates into the shared@molecule/app-bondregistry, so both write the same slot;requireProvider()throws until one has run. -
Browsers block autoplay.
autoplay: trueorplay()outside a user gesture is silently ignored until the user has interacted with the page — start playback from a click/tap handler, and treat "no sound on page load" as policy, not a bug. -
destroy()the player when its view unmounts — leaked instances keep buffers and callbacks alive across navigation. -
getDuration()returns 0 until the audio metadata has loaded; read it inonProgress(or after playback starts), not synchronously aftercreatePlayer.
E2E Tests
Playback verification — drive the real rendered UI (live preview, no mocks), adapt each item to this app's actual audio screens/controls, and check every box off one by one. This core is PLAYBACK ONLY (no recording); a box you can't check is an integration bug to fix — not a skip:
- Loading a track and pressing the play control actually plays: the current-time readout advances, the progress bar moves, and the UI shows the playing state (isPlaying() true, getCurrentTime() keeps climbing). Confirm sound is audible, not just that the state flipped — start it from a click/tap so autoplay policy does not silently block it.
- The pause control halts playback: current time freezes, the progress bar stops, and the control toggles back to "play"; pressing play resumes from the same position, not the start.
- Dragging/clicking the scrubber to a target position seeks there: getCurrentTime() jumps to that time and the displayed elapsed time matches.
- The volume/mute control changes output: raising/lowering the slider is audible and getVolume() reflects it; muting (volume 0) silences the audio without pausing it.
- Total duration and elapsed time render correctly once metadata loads (getDuration() > 0, read via onProgress), not "0:00 / 0:00" stuck on screen.
- Reaching the end fires the ended state: the onEnd callback runs and the UI resets to the start (or advances to the next track), not a silent hang.
- The audio source loads from the app's own origin (a bundled/served asset), not a broken external URL — no 404/CORS error in the console and sound actually reaches the output.