first commit
This commit is contained in:
@@ -0,0 +1,95 @@
|
||||
# `<AudioPlayer>`
|
||||
|
||||
<!-- begin:auto-docs -->
|
||||
_(no submodules)_
|
||||
<!-- end:auto-docs -->
|
||||
|
||||
## Purpose
|
||||
|
||||
`<AudioPlayer>` is the generic media-player surface for a live
|
||||
`AudioPlayerPlugin` instance from
|
||||
`@suaveplan/audio-fx-plugin-audio-player`. It renders the full
|
||||
playback control surface — play / pause / stop / seek / volume / loop
|
||||
/ playback rate — bound directly to the plugin's dedicated mutators
|
||||
(`play`, `pause`, `stop`, `seek`, `setVolume`, `setLoop`,
|
||||
`setPlaybackRate`). State is sampled by polling `plugin.getState()` at
|
||||
the configured tick rate so the seek bar stays in sync with the
|
||||
audio-thread position.
|
||||
|
||||
The component is composed entirely against the plugin: there is no
|
||||
React-side cache of playback state. Loading is handled via the
|
||||
optional `src` prop which auto-calls `plugin.load(src)` on mount.
|
||||
|
||||
## Features
|
||||
|
||||
- Full control surface bound to plugin mutators.
|
||||
- Optional `src` triggers async `plugin.load(src)` on mount.
|
||||
- Surfaces plugin / load errors via an inline `role="alert"` element.
|
||||
- `showLoop` / `showPlaybackRate` props toggle the optional controls.
|
||||
- Live seek bar reflects `plugin.getState().currentTimeSec`.
|
||||
- Polls at `sampleRateHz` (default 30, clamped `>= 1`).
|
||||
- Unmounting cancels the in-flight `load()` so late resolutions cannot
|
||||
setState on a torn-down component.
|
||||
|
||||
## Usage: Basic Example
|
||||
|
||||
```tsx
|
||||
import { AudioPlayerPlugin } from "@suaveplan/audio-fx-plugin-audio-player";
|
||||
import { AudioProvider, AudioPlayer } from "@suaveplan/react-audio";
|
||||
|
||||
const plugin = new AudioPlayerPlugin({});
|
||||
|
||||
export function App() {
|
||||
return (
|
||||
<AudioProvider>
|
||||
<AudioPlayer plugin={plugin} />
|
||||
</AudioProvider>
|
||||
);
|
||||
}
|
||||
```
|
||||
|
||||
## Usage: Advanced Example
|
||||
|
||||
```tsx
|
||||
import { AudioPlayerPlugin } from "@suaveplan/audio-fx-plugin-audio-player";
|
||||
import { AudioProvider, AudioPlayer } from "@suaveplan/react-audio";
|
||||
|
||||
const plugin = new AudioPlayerPlugin({});
|
||||
|
||||
export function Streamer() {
|
||||
return (
|
||||
<AudioProvider>
|
||||
<AudioPlayer
|
||||
plugin={plugin}
|
||||
src="https://cdn/track.wav"
|
||||
showPlaybackRate={false}
|
||||
sampleRateHz={60}
|
||||
className="streamer"
|
||||
/>
|
||||
</AudioProvider>
|
||||
);
|
||||
}
|
||||
```
|
||||
|
||||
## API Reference
|
||||
|
||||
| Prop | Type | Default | Notes |
|
||||
| ------------------- | -------------------------- | ------- | ------------------------------------------- |
|
||||
| `plugin` | `AudioPlayerPlugin` | — | Required. |
|
||||
| `className` | `string \| undef` | — | Forwarded to the outer `<section>`. |
|
||||
| `src` | `string \| undef` | — | Auto-load this URL on mount. |
|
||||
| `sampleRateHz` | `number \| undef` | `30` | State polling rate. |
|
||||
| `showLoop` | `boolean \| undef` | `true` | When `false`, hides the loop toggle. |
|
||||
| `showPlaybackRate` | `boolean \| undef` | `true` | When `false`, hides the rate input. |
|
||||
|
||||
## Implementation Notes
|
||||
|
||||
Errors thrown by the underlying plugin are caught at every mutation
|
||||
site and surfaced via a single `role="alert"` element so callers can
|
||||
style or speak the error consistently. The cancel-on-unmount guard
|
||||
uses a local `cancelled` flag captured in the effect closure rather
|
||||
than an `AbortController` because `plugin.load` does not expose its
|
||||
inner fetch signal; this still prevents the standard "setState on
|
||||
unmounted component" warning. State polling runs in a separate
|
||||
effect from the load effect so changing `src` does not restart the
|
||||
poll.
|
||||
Reference in New Issue
Block a user