first commit

This commit is contained in:
2026-05-29 08:20:56 +01:00
commit 949299f58d
6368 changed files with 527176 additions and 0 deletions

View File

@@ -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.