Files
2026-05-27 23:29:53 +01:00

113 lines
5.5 KiB
Markdown

# OpenSpec Change: enterprise-react-audio-player
- **Change ID**: enterprise-react-audio-player
- **Package**: `@suaveplan/react-audio-player`
- **Category**: react
- **Target path**: `packages/ui/react/react-audio-player`
- **Status**: PROPOSED
- **Date**: 2026-05-15
- **Design**: `./design.md`
- **Spec delta**: `./specs/react-audio-player/spec.md`
> Replaces the prior 2026-04-24 draft flagged `NEEDS-REWRITE`. See `../REACT_AUDIO_WAVE_REWRITE_COMPLETE.md`.
---
## Summary
Deliver `@suaveplan/react-audio-player` on genesis from scratch at enterprise quality. The package is a track-style media player UI suite built on the unified architecture: it consumes `AudioPlayerPlugin` from `@suaveplan/audio-fx-plugin-base` as its playback source, hosts an optional FX chain via the universal `PluginChain` primitive, exposes a Zustand-backed player store layered over the transport, and provides three player variants (`<BasicPlayer>`, `<AudioPlayer>`, `<PremiumPlayer>`) plus karaoke (LRC parsing + `<LyricsDisplay>`), localStorage-backed playlist, two visualisers (waveform + spectrum) sourced from `useAnalyser`, two R3F screensavers (`<GLBViewer>`, `<ShaderBackground>`), and (in the premium variant) WebRTC multi-peer playback sync via `@suaveplan/react-audio-stream`.
The package owns **no DSP, no transport scheduler, no parameter automation, no audio context**. Every audio operation goes through `@suaveplan/react-audio`'s hooks; UI state goes into a per-provider Zustand store; persistence goes through an injectable store (default `localStorage`).
---
## Current-state audit (genesis)
The package does not exist on genesis yet — fresh build replacing the obsolete pre-tier 2026-04-24 draft.
---
## Parity Checklist (vs upstream `../suaveplan/packages/react/media/react-audio-player/`)
| Capability | Upstream | Migrated | Notes |
|---|:---:|:---:|---|
| Zustand `useAudioPlayerStore` | ✅ | ⬆️ | Slimmer; no playback state (lives on transport). UI + playlist + lyrics state only. |
| `<AudioPlayerProvider>` | ✅ | ✅ | Thin wrapper that nests `<AudioProvider>` from `react-audio` and adds player-specific stores. |
| `createPluginManager` | ✅ | ⚠️ refactored | Replaced by the generic `<PluginChainView>` from `react-audio`; consumers can drop in any `AudioFxPlugin`. |
| `<PlayPauseButton>` | ✅ | ✅ | Uses `useTransport().play/pause`. |
| `<VolumeControl>` | ✅ | ✅ | Drives the player's `AudioPlayerPlugin` volume parameter. |
| `<ProgressBar>` | ✅ | ✅ | Reads `useTransportTime`. |
| `<Queue>` (playlist) | ✅ | ✅ | Backed by `usePlaylist` from `react-audio`. |
| 3-band EQ + presets | ✅ | ⬆️ | Built on `EQPlugin` from `audio-fx-plugin-base`. Presets via `usePreset`. |
| LRC karaoke parser | ✅ | ✅ | Universal parser; no UI deps. |
| `<LyricsDisplay>` | ✅ | ✅ | Reads `useTransportTime` for per-line highlight. |
| `createNetworkSyncManager` (WebRTC/WebSocket multi-peer) | ✅ | ⬆️ | Delegated to `@suaveplan/react-audio-stream`; this package consumes its hooks. |
| localStorage-backed track storage | ✅ | ✅ | Through injectable store (default `localStorage`). |
| `<GLBViewer>` R3F screensaver | ✅ | ✅ | Optional subpath; r3f peer dep. |
| `<ShaderBackground>` R3F screensaver | ✅ | ✅ | Optional subpath; r3f peer dep. |
| `<WaveformVisualizer>` | ✅ | ⬆️ | Reads `useAnalyser` from `react-audio`. |
| `<SpectrumAnalyzer>` | ✅ | ⬆️ | Reads `useAnalyser` from `react-audio`. |
| Coverage | partial | ✅ | 100/100/100/100. |
| Storybook | partial | ✅ | Every component: default + interactive + edge. |
No 🚫 rows.
---
## Available workspace deps on genesis
| Package | Role |
|---|---|
| `@suaveplan/react-audio` (`workspace:^`) | Provider + hooks (`useAudioFxPlugin`, `useTransport`, `useTransportTime`, `useAnalyser`, `usePlaylist`) |
| `@suaveplan/audio-fx-plugin-base` (`workspace:^`) | `AudioPlayerPlugin`, `EQPlugin`, `PluginChain` |
| `@suaveplan/audio-transport` (`workspace:^`) | Transport reference |
| `@suaveplan/error`, `@suaveplan/types`, `@suaveplan/opentelemetry`, `@suaveplan/events` | foundations |
| `react`, optional `@react-three/fiber` + `three` for screensavers (peer deps; gated by subpath) |
| `zustand` (`catalog:state`), `framer-motion` (`catalog:animation`), `lucide-react` (`catalog:ui`), `zod` (`catalog:forms`) |
---
## File layout
```text
packages/ui/react/react-audio-player/
src/
index.ts
error-codes.ts
provider/ audio-player-provider/
stores/ use-audio-player-store/ use-playlist-store/ use-lyrics-store/
hooks/ use-audio-player/ use-playlist-controls/ use-lyrics/ use-eq-band/
karaoke/ lrc-parser/ lyrics-display/ use-active-lyric/
components/
basic-player/ audio-player/ premium-player/
play-pause-button/ volume-control/ progress-bar/
queue/ eq-panel/ preset-selector-3band/
waveform-visualizer/ spectrum-analyzer/
screensavers/ ← optional subpaths, R3F-gated
glb-viewer/ shader-background/
sync/ ← optional subpaths, WebRTC-gated
use-multi-peer-sync/
__benchmarks__/
lrc-parse.bench.ts
visualizer.bench.ts
tests/
integration.test.tsx
purity.test.ts
exports.test.ts
e2e/
play.spec.ts
karaoke.spec.ts
```
---
## Impact
**Breaking changes**: none — fresh build.
**Prerequisites**: `react-audio`, `audio-fx-plugin-base`, `audio-transport`, foundations.
### Affected dependents
No dependents in this batch (verified by `bunx turbo ls --filter=...@suaveplan/react-audio-player`).