@djangocfg/ui-nextjs 2.1.83 → 2.1.85

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (36) hide show
  1. package/package.json +4 -4
  2. package/src/tools/AudioPlayer/README.md +60 -166
  3. package/src/tools/AudioPlayer/components/HybridAudioPlayer.tsx +0 -35
  4. package/src/tools/AudioPlayer/components/HybridSimplePlayer.tsx +0 -11
  5. package/src/tools/AudioPlayer/components/ReactiveCover/AudioReactiveCover.tsx +23 -21
  6. package/src/tools/AudioPlayer/components/index.ts +4 -8
  7. package/src/tools/AudioPlayer/context/index.ts +1 -8
  8. package/src/tools/AudioPlayer/hooks/index.ts +6 -13
  9. package/src/tools/AudioPlayer/index.ts +25 -89
  10. package/src/tools/AudioPlayer/types/index.ts +10 -18
  11. package/src/tools/index.ts +51 -56
  12. package/src/tools/AudioPlayer/@refactoring3/00-IMPLEMENTATION-ROADMAP.md +0 -1146
  13. package/src/tools/AudioPlayer/@refactoring3/01-WAVESURFER-STREAMING-ANALYSIS.md +0 -611
  14. package/src/tools/AudioPlayer/@refactoring3/02-MEDIA-VIEWER-ANALYSIS.md +0 -560
  15. package/src/tools/AudioPlayer/@refactoring3/03-HYBRID-ARCHITECTURE-PROPOSAL.md +0 -769
  16. package/src/tools/AudioPlayer/@refactoring3/04-CRACKLING-ISSUE-DIAGNOSIS.md +0 -373
  17. package/src/tools/AudioPlayer/components/AudioEqualizer.tsx +0 -200
  18. package/src/tools/AudioPlayer/components/AudioPlayer.tsx +0 -236
  19. package/src/tools/AudioPlayer/components/AudioShortcutsPopover.tsx +0 -99
  20. package/src/tools/AudioPlayer/components/SimpleAudioPlayer.tsx +0 -278
  21. package/src/tools/AudioPlayer/components/VisualizationToggle.tsx +0 -64
  22. package/src/tools/AudioPlayer/context/AudioProvider.tsx +0 -376
  23. package/src/tools/AudioPlayer/context/selectors.ts +0 -96
  24. package/src/tools/AudioPlayer/hooks/useAudioAnalysis.ts +0 -110
  25. package/src/tools/AudioPlayer/hooks/useAudioHotkeys.ts +0 -150
  26. package/src/tools/AudioPlayer/hooks/useAudioSource.ts +0 -155
  27. package/src/tools/AudioPlayer/hooks/useSharedWebAudio.ts +0 -109
  28. package/src/tools/AudioPlayer/progressive/ProgressiveAudioPlayer.tsx +0 -303
  29. package/src/tools/AudioPlayer/progressive/WaveformCanvas.tsx +0 -381
  30. package/src/tools/AudioPlayer/progressive/index.ts +0 -40
  31. package/src/tools/AudioPlayer/progressive/peaks.ts +0 -234
  32. package/src/tools/AudioPlayer/progressive/types.ts +0 -179
  33. package/src/tools/AudioPlayer/progressive/useAudioElement.ts +0 -340
  34. package/src/tools/AudioPlayer/progressive/useProgressiveWaveform.ts +0 -267
  35. package/src/tools/AudioPlayer/types/audio.ts +0 -121
  36. package/src/tools/AudioPlayer/types/components.ts +0 -98
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@djangocfg/ui-nextjs",
3
- "version": "2.1.83",
3
+ "version": "2.1.85",
4
4
  "description": "Next.js UI component library with Radix UI primitives, Tailwind CSS styling, charts, and form components",
5
5
  "keywords": [
6
6
  "ui-components",
@@ -58,8 +58,8 @@
58
58
  "check": "tsc --noEmit"
59
59
  },
60
60
  "peerDependencies": {
61
- "@djangocfg/api": "^2.1.83",
62
- "@djangocfg/ui-core": "^2.1.83",
61
+ "@djangocfg/api": "^2.1.85",
62
+ "@djangocfg/ui-core": "^2.1.85",
63
63
  "@types/react": "^19.1.0",
64
64
  "@types/react-dom": "^19.1.0",
65
65
  "consola": "^3.4.2",
@@ -110,7 +110,7 @@
110
110
  "wavesurfer.js": "^7.12.1"
111
111
  },
112
112
  "devDependencies": {
113
- "@djangocfg/typescript-config": "^2.1.83",
113
+ "@djangocfg/typescript-config": "^2.1.85",
114
114
  "@types/node": "^24.7.2",
115
115
  "eslint": "^9.37.0",
116
116
  "tailwindcss-animate": "1.0.7",
@@ -1,30 +1,21 @@
1
1
  # AudioPlayer
2
2
 
3
- Audio player library with multiple player implementations for different use cases.
3
+ Audio player with native HTML5 streaming and audio-reactive visualizations.
4
4
 
5
- ## Player Comparison
5
+ ## Features
6
6
 
7
- | Feature | HybridSimplePlayer | SimpleAudioPlayer | ProgressiveAudioPlayer |
8
- |---------|-------------------|-------------------|------------------------|
9
- | **Recommended for** | Streaming, general use | Local files, full waveform | Large streaming files |
10
- | **Audio Engine** | HTML5 `<audio>` | WaveSurfer.js | HTML5 `<audio>` |
11
- | **Visualization** | Real-time frequency bars | Static waveform | Progressive waveform |
12
- | **Reactive Effects** | ✅ Full support | ✅ Full support | ❌ No |
13
- | **Streaming Support** | ✅ Native | ⚠️ Requires prefetch | ✅ Native |
14
- | **Seek Any Position** | ✅ Yes | ⚠️ Limited by buffer | ✅ Yes |
15
- | **No Crackling** | ✅ Guaranteed | ⚠️ Fixed in v2.1.82 | ✅ Yes |
16
- | **Memory Usage** | Low | High (full file) | Low |
7
+ - Native HTML5 audio playback (no crackling, native streaming support)
8
+ - Web Audio API for real-time frequency analysis
9
+ - Audio-reactive cover effects (glow, orbs, spotlight, mesh)
10
+ - Frequency visualization waveform
11
+ - Full playback controls
17
12
 
18
- ---
19
-
20
- ## Quick Start (Recommended)
21
-
22
- ### HybridSimplePlayer — Best for Most Cases
13
+ ## Quick Start
23
14
 
24
15
  ```tsx
25
16
  import { HybridSimplePlayer } from '@djangocfg/ui-nextjs';
26
17
 
27
- // Minimal
18
+ // Simple usage
28
19
  <HybridSimplePlayer src="https://example.com/audio.mp3" />
29
20
 
30
21
  // With metadata and reactive cover
@@ -43,15 +34,17 @@ import { HybridSimplePlayer } from '@djangocfg/ui-nextjs';
43
34
  title="Track Title"
44
35
  coverArt={coverUrl}
45
36
  showWaveform
37
+ waveformMode="frequency" // 'frequency' | 'static'
38
+ showLoop
46
39
  reactiveCover
47
- variant="spotlight"
48
- intensity="medium"
49
- colorScheme="vibrant"
50
- layout="horizontal"
40
+ variant="spotlight" // 'glow' | 'orbs' | 'spotlight' | 'mesh' | 'none'
41
+ intensity="medium" // 'subtle' | 'medium' | 'strong'
42
+ colorScheme="primary" // 'primary' | 'vibrant' | 'cool' | 'warm'
43
+ layout="horizontal" // 'vertical' | 'horizontal'
51
44
  />
52
45
  ```
53
46
 
54
- ### HybridSimplePlayer Props
47
+ ## Props
55
48
 
56
49
  | Prop | Type | Default | Description |
57
50
  |------|------|---------|-------------|
@@ -65,7 +58,7 @@ import { HybridSimplePlayer } from '@djangocfg/ui-nextjs';
65
58
  | `waveformHeight` | `number` | `64` | Waveform height in pixels |
66
59
  | `showTimer` | `boolean` | `true` | Show time display |
67
60
  | `showVolume` | `boolean` | `true` | Show volume control |
68
- | `showLoop` | `boolean` | `true` | Show loop/repeat button |
61
+ | `showLoop` | `boolean` | `true` | Show loop button |
69
62
  | `reactiveCover` | `boolean` | `true` | Enable reactive effects |
70
63
  | `variant` | `VisualizationVariant` | `'spotlight'` | Effect variant |
71
64
  | `intensity` | `EffectIntensity` | `'medium'` | Effect intensity |
@@ -74,26 +67,27 @@ import { HybridSimplePlayer } from '@djangocfg/ui-nextjs';
74
67
  | `loop` | `boolean` | `false` | Loop playback |
75
68
  | `layout` | `'vertical' \| 'horizontal'` | `'vertical'` | Layout direction |
76
69
 
77
- ---
78
-
79
70
  ## Advanced Usage
80
71
 
81
- ### Using HybridAudioProvider + HybridAudioPlayer
72
+ ### HybridAudioProvider + HybridAudioPlayer
82
73
 
83
- For full control over the hybrid player:
74
+ For custom layouts:
84
75
 
85
76
  ```tsx
86
- import { HybridAudioProvider, HybridAudioPlayer, useHybridAudioContext } from '@djangocfg/ui-nextjs';
77
+ import {
78
+ HybridAudioProvider,
79
+ HybridAudioPlayer,
80
+ AudioReactiveCover,
81
+ useHybridAudioContext
82
+ } from '@djangocfg/ui-nextjs';
87
83
 
88
84
  function MyPlayer({ audioUrl }: { audioUrl: string }) {
89
85
  return (
90
86
  <HybridAudioProvider src={audioUrl}>
91
- <HybridAudioPlayer
92
- showControls
93
- showWaveform
94
- showTimer
95
- showVolume
96
- />
87
+ <AudioReactiveCover variant="spotlight" onClick={handleClick}>
88
+ <img src={coverUrl} alt="Cover" />
89
+ </AudioReactiveCover>
90
+ <HybridAudioPlayer showWaveform showControls />
97
91
  <CustomControls />
98
92
  </HybridAudioProvider>
99
93
  );
@@ -104,7 +98,6 @@ function CustomControls() {
104
98
 
105
99
  return (
106
100
  <div>
107
- <p>Playing: {state.isPlaying ? 'Yes' : 'No'}</p>
108
101
  <p>Bass level: {(audioLevels.bass * 100).toFixed(0)}%</p>
109
102
  <button onClick={controls.togglePlay}>
110
103
  {state.isPlaying ? 'Pause' : 'Play'}
@@ -114,26 +107,26 @@ function CustomControls() {
114
107
  }
115
108
  ```
116
109
 
117
- ### Hybrid Hooks
110
+ ## Hooks
118
111
 
119
- #### useHybridAudioContext
112
+ ### useHybridAudioContext
120
113
 
121
- Full access to audio state, controls, and Web Audio API:
114
+ Full context access:
122
115
 
123
116
  ```tsx
124
117
  const {
125
- state, // { isReady, isPlaying, currentTime, duration, volume, isMuted, isLooping, buffered }
126
- controls, // { play, pause, togglePlay, seek, seekTo, skip, setVolume, toggleMute, toggleLoop, restart }
127
- audioLevels, // { bass, mid, high, overall } - for reactive effects
128
- webAudio, // { context, analyser, sourceNode } - for custom visualizations
118
+ state, // { isReady, isPlaying, currentTime, duration, volume, isMuted, isLooping }
119
+ controls, // { play, pause, togglePlay, seek, skip, setVolume, toggleMute, toggleLoop }
120
+ audioLevels, // { bass, mid, high, overall }
121
+ webAudio, // { context, analyser, sourceNode }
129
122
  audioRef, // React ref to HTMLAudioElement
130
123
  } = useHybridAudioContext();
131
124
  ```
132
125
 
133
- #### Specialized Hooks
126
+ ### Specialized Hooks
134
127
 
135
128
  ```tsx
136
- // State only (read-only)
129
+ // State only
137
130
  const { isPlaying, currentTime, duration } = useHybridAudioState();
138
131
 
139
132
  // Controls only (no re-render on time updates)
@@ -146,100 +139,36 @@ const { bass, mid, high, overall } = useHybridAudioLevels();
146
139
  const { context, analyser, sourceNode } = useHybridWebAudio();
147
140
  ```
148
141
 
149
- ---
150
-
151
- ## WaveSurfer-based Player (Legacy)
152
-
153
- For cases where you need the static waveform visualization:
154
-
155
- ```tsx
156
- import { SimpleAudioPlayer } from '@djangocfg/ui-nextjs';
157
-
158
- <SimpleAudioPlayer
159
- src={audioUrl}
160
- prefetch={true} // Required for streaming URLs
161
- title="Track Title"
162
- showWaveform
163
- reactiveCover
164
- />
165
- ```
166
-
167
- > **Note:** `prefetch={true}` downloads the entire file before playing. For large files or streaming, use `HybridSimplePlayer` instead.
168
-
169
- ---
170
-
171
142
  ## Components
172
143
 
173
- ### HybridWaveform
174
-
175
- Real-time frequency visualization canvas:
176
-
177
- ```tsx
178
- <HybridWaveform
179
- mode="frequency" // 'frequency' | 'static'
180
- height={64}
181
- barWidth={3}
182
- barGap={2}
183
- barRadius={2}
184
- progressColor="hsl(217 91% 60%)"
185
- waveColor="hsl(217 91% 60% / 0.3)"
186
- bufferedColor="hsl(217 91% 60% / 0.15)"
187
- onSeek={(time) => console.log('Seeked to', time)}
188
- />
189
- ```
190
-
191
144
  ### AudioReactiveCover
192
145
 
193
146
  Album art wrapper with audio-reactive effects:
194
147
 
195
148
  ```tsx
196
149
  <AudioReactiveCover
197
- variant="spotlight" // 'glow' | 'orbs' | 'spotlight' | 'mesh'
198
- intensity="medium" // 'subtle' | 'medium' | 'strong'
199
- colorScheme="primary" // 'primary' | 'vibrant' | 'cool' | 'warm'
150
+ variant="spotlight" // 'glow' | 'orbs' | 'spotlight' | 'mesh'
151
+ intensity="medium" // 'subtle' | 'medium' | 'strong'
152
+ colorScheme="primary" // 'primary' | 'vibrant' | 'cool' | 'warm'
200
153
  onClick={() => nextVariant()}
201
154
  >
202
155
  <img src={coverArt} alt="Album cover" />
203
156
  </AudioReactiveCover>
204
157
  ```
205
158
 
206
- ### AudioEqualizer
159
+ ### HybridWaveform
207
160
 
208
- Real-time frequency visualizer with animated bars:
161
+ Real-time frequency visualization:
209
162
 
210
163
  ```tsx
211
- <AudioEqualizer
212
- barCount={24}
213
- height={48}
214
- gap={2}
215
- showPeaks
216
- barColor="hsl(217 91% 60%)"
217
- peakColor="hsl(217 91% 70%)"
164
+ <HybridWaveform
165
+ mode="frequency" // 'frequency' | 'static'
166
+ height={64}
167
+ barWidth={3}
168
+ barGap={2}
218
169
  />
219
170
  ```
220
171
 
221
- ---
222
-
223
- ## Keyboard Shortcuts
224
-
225
- | Key | Action |
226
- |-----|--------|
227
- | `Space` | Play/Pause |
228
- | `←` / `J` | Skip 10s backward |
229
- | `→` / `L` | Skip 10s forward |
230
- | `↑` | Volume up |
231
- | `↓` | Volume down |
232
- | `M` | Mute/Unmute |
233
- | `0-9` | Jump to 0-90% |
234
-
235
- Enable with:
236
-
237
- ```tsx
238
- useAudioHotkeys({ enabled: true, skipDuration: 10, volumeStep: 0.1 });
239
- ```
240
-
241
- ---
242
-
243
172
  ## Effect Variants
244
173
 
245
174
  | Variant | Description |
@@ -250,8 +179,6 @@ useAudioHotkeys({ enabled: true, skipDuration: 10, volumeStep: 0.1 });
250
179
  | `mesh` | Large gradient blobs with movement |
251
180
  | `none` | Effects disabled |
252
181
 
253
- ---
254
-
255
182
  ## Architecture
256
183
 
257
184
  ```
@@ -259,54 +186,21 @@ AudioPlayer/
259
186
  ├── index.ts # Public API exports
260
187
  ├── types/ # TypeScript types
261
188
  ├── hooks/
262
- │ ├── useHybridAudio.ts # 🆕 HTML5 audio + Web Audio hook
263
- │ ├── useHybridAudioAnalysis.ts # 🆕 Frequency analysis for hybrid
264
- │ ├── useSharedWebAudio.ts # Shared AudioContext (WaveSurfer)
265
- │ ├── useAudioAnalysis.ts # Web Audio frequency analysis
266
- │ ├── useAudioHotkeys.ts # Keyboard shortcuts
189
+ │ ├── useHybridAudio.ts # HTML5 audio + Web Audio hook
190
+ │ ├── useHybridAudioAnalysis.ts # Frequency analysis
267
191
  │ └── useVisualization.tsx # Visualization settings
268
192
  ├── context/
269
- ├── HybridAudioProvider.tsx # 🆕 Hybrid audio context
270
- │ ├── AudioProvider.tsx # WaveSurfer context
271
- │ └── selectors.ts # Hook selectors
193
+ └── HybridAudioProvider.tsx # Audio context provider
272
194
  ├── components/
273
- │ ├── HybridAudioPlayer.tsx # 🆕 Main hybrid player
274
- │ ├── HybridSimplePlayer.tsx # 🆕 All-in-one hybrid wrapper
275
- │ ├── HybridWaveform.tsx # 🆕 Frequency visualization
276
- │ ├── AudioPlayer.tsx # WaveSurfer player
277
- │ ├── SimpleAudioPlayer.tsx # WaveSurfer wrapper
278
- │ ├── AudioEqualizer.tsx # Frequency bars
195
+ │ ├── HybridAudioPlayer.tsx # Main player component
196
+ │ ├── HybridSimplePlayer.tsx # All-in-one wrapper
197
+ │ ├── HybridWaveform.tsx # Frequency visualization
279
198
  │ └── ReactiveCover/ # Reactive effects
280
- ├── progressive/ # Progressive/streaming player
281
- └── effects/ # Effect calculations
282
- ```
283
-
284
- ---
285
-
286
- ## Migration Guide
287
-
288
- ### From SimpleAudioPlayer to HybridSimplePlayer
289
-
290
- ```tsx
291
- // Before
292
- <SimpleAudioPlayer
293
- src={url}
294
- prefetch={true}
295
- showWaveform
296
- reactiveCover
297
- variant="spotlight"
298
- />
299
-
300
- // After
301
- <HybridSimplePlayer
302
- src={url}
303
- showWaveform
304
- reactiveCover
305
- variant="spotlight"
306
- />
199
+ ├── effects/ # Effect calculations
200
+ └── utils/ # Utilities
307
201
  ```
308
202
 
309
- Key differences:
310
- - No `prefetch` prop needed streaming works natively
311
- - `waveformMode="frequency"` shows real-time bars instead of static waveform
312
- - Same reactive effects support
203
+ Key design:
204
+ - HTML5 `<audio>` for playback (native streaming, no crackling)
205
+ - Web Audio API AnalyserNode for visualization only (not connected to output)
206
+ - Audio graph: `source → destination` + `source → analyser` (passive)
@@ -30,9 +30,6 @@ import {
30
30
  import { Button, Slider, cn } from '@djangocfg/ui-nextjs';
31
31
  import { useHybridAudioContext } from '../context/HybridAudioProvider';
32
32
  import { HybridWaveform } from './HybridWaveform';
33
- import { AudioEqualizer } from './AudioEqualizer';
34
- import { AudioShortcutsPopover } from './AudioShortcutsPopover';
35
- import { useAudioHotkeys } from '../hooks';
36
33
  import { formatTime } from '../utils';
37
34
 
38
35
  // =============================================================================
@@ -48,23 +45,12 @@ export interface HybridAudioPlayerProps {
48
45
  waveformMode?: 'frequency' | 'static';
49
46
  /** Waveform height in pixels */
50
47
  waveformHeight?: number;
51
- /** Show equalizer bars */
52
- showEqualizer?: boolean;
53
48
  /** Show time display */
54
49
  showTimer?: boolean;
55
50
  /** Show volume control */
56
51
  showVolume?: boolean;
57
52
  /** Show loop button */
58
53
  showLoop?: boolean;
59
- /** Equalizer options */
60
- equalizerOptions?: {
61
- barCount?: number;
62
- height?: number;
63
- gap?: number;
64
- showPeaks?: boolean;
65
- barColor?: string;
66
- peakColor?: string;
67
- };
68
54
  /** Additional CSS class */
69
55
  className?: string;
70
56
  /** Inline styles */
@@ -80,19 +66,14 @@ export const HybridAudioPlayer = memo(function HybridAudioPlayer({
80
66
  showWaveform = true,
81
67
  waveformMode = 'frequency',
82
68
  waveformHeight = 64,
83
- showEqualizer = false,
84
69
  showTimer = true,
85
70
  showVolume = true,
86
71
  showLoop = true,
87
- equalizerOptions = {},
88
72
  className,
89
73
  style,
90
74
  }: HybridAudioPlayerProps) {
91
75
  const { state, controls } = useHybridAudioContext();
92
76
 
93
- // Enable keyboard shortcuts
94
- useAudioHotkeys({ enabled: state.isReady });
95
-
96
77
  const isLoading = !state.isReady;
97
78
 
98
79
  const handleVolumeChange = (value: number[]) => {
@@ -120,19 +101,6 @@ export const HybridAudioPlayer = memo(function HybridAudioPlayer({
120
101
  </div>
121
102
  )}
122
103
 
123
- {/* Equalizer animation */}
124
- {showEqualizer && (
125
- <AudioEqualizer
126
- barCount={equalizerOptions.barCount}
127
- height={equalizerOptions.height}
128
- gap={equalizerOptions.gap}
129
- showPeaks={equalizerOptions.showPeaks}
130
- barColor={equalizerOptions.barColor}
131
- peakColor={equalizerOptions.peakColor}
132
- className="px-1"
133
- />
134
- )}
135
-
136
104
  {/* Timer */}
137
105
  {showTimer && (
138
106
  <div className="flex justify-between text-xs text-muted-foreground tabular-nums px-1">
@@ -239,9 +207,6 @@ export const HybridAudioPlayer = memo(function HybridAudioPlayer({
239
207
  <Repeat className="h-4 w-4" />
240
208
  </Button>
241
209
  )}
242
-
243
- {/* Shortcuts help */}
244
- <AudioShortcutsPopover compact />
245
210
  </div>
246
211
  )}
247
212
  </div>
@@ -33,7 +33,6 @@ import { HybridAudioProvider } from '../context/HybridAudioProvider';
33
33
  import { HybridAudioPlayer } from './HybridAudioPlayer';
34
34
  import { AudioReactiveCover } from './ReactiveCover';
35
35
  import { VisualizationProvider, useVisualization } from '../hooks';
36
- import type { EqualizerOptions } from '../types';
37
36
  import type { EffectIntensity, EffectColorScheme } from '../effects';
38
37
  import type { VisualizationVariant } from '../hooks';
39
38
 
@@ -66,9 +65,6 @@ export interface HybridSimplePlayerProps {
66
65
  /** Waveform height in pixels */
67
66
  waveformHeight?: number;
68
67
 
69
- /** Show equalizer bars */
70
- showEqualizer?: boolean;
71
-
72
68
  /** Show timer */
73
69
  showTimer?: boolean;
74
70
 
@@ -99,9 +95,6 @@ export interface HybridSimplePlayerProps {
99
95
  /** Initial volume (0-1) */
100
96
  initialVolume?: number;
101
97
 
102
- /** Equalizer customization */
103
- equalizerOptions?: EqualizerOptions;
104
-
105
98
  /** Layout direction */
106
99
  layout?: 'vertical' | 'horizontal';
107
100
 
@@ -146,7 +139,6 @@ function HybridSimplePlayerContent({
146
139
  showWaveform = true,
147
140
  waveformMode = 'frequency',
148
141
  waveformHeight = 64,
149
- showEqualizer = false,
150
142
  showTimer = true,
151
143
  showVolume = true,
152
144
  showLoop = true,
@@ -157,7 +149,6 @@ function HybridSimplePlayerContent({
157
149
  autoPlay = false,
158
150
  loop = false,
159
151
  initialVolume = 1,
160
- equalizerOptions,
161
152
  layout = 'vertical',
162
153
  className,
163
154
  onPlay,
@@ -275,11 +266,9 @@ function HybridSimplePlayerContent({
275
266
  showWaveform={showWaveform}
276
267
  waveformMode={waveformMode}
277
268
  waveformHeight={waveformHeight}
278
- showEqualizer={showEqualizer}
279
269
  showTimer={showTimer}
280
270
  showVolume={showVolume}
281
271
  showLoop={showLoop}
282
- equalizerOptions={equalizerOptions}
283
272
  className="border-0 bg-transparent"
284
273
  />
285
274
  </div>
@@ -6,13 +6,12 @@
6
6
  * Uses effects utilities for clean data preparation before render.
7
7
  * Click on cover to switch between effect variants.
8
8
  *
9
- * Audio analysis is performed in the AudioProvider context to persist
10
- * across variant changes (including switching to 'none' and back).
9
+ * Must be used within HybridAudioProvider context.
11
10
  */
12
11
 
13
12
  import { type ReactNode } from 'react';
14
13
  import { cn } from '@djangocfg/ui-nextjs';
15
- import { useAudioElement } from '../../context';
14
+ import { useHybridAudioLevels, useHybridAudioState } from '../../context/HybridAudioProvider';
16
15
  import {
17
16
  type EffectVariant,
18
17
  type EffectIntensity,
@@ -64,8 +63,9 @@ export function AudioReactiveCover({
64
63
  onClick,
65
64
  className,
66
65
  }: AudioReactiveCoverProps) {
67
- // Get audio levels from context (persists across variant changes)
68
- const { isPlaying, audioLevels: levels } = useAudioElement();
66
+ // Get audio state from HybridAudioProvider context
67
+ const { isPlaying } = useHybridAudioState();
68
+ const levels = useHybridAudioLevels();
69
69
 
70
70
  // =========================================================================
71
71
  // PREPARE DATA BEFORE RENDER
@@ -110,22 +110,24 @@ export function AudioReactiveCover({
110
110
  transition: 'transform 0.1s ease-out',
111
111
  }}
112
112
  >
113
- {/* Effect layers */}
114
- {glowData && (
115
- <GlowEffect data={glowData} colors={colors} isPlaying={isPlaying} />
116
- )}
117
-
118
- {orbsData && (
119
- <OrbsEffect orbs={orbsData} blur={effectConfig.blur} isPlaying={isPlaying} />
120
- )}
121
-
122
- {spotlightData && (
123
- <SpotlightEffect data={spotlightData} colors={colors} blur={effectConfig.blur} isPlaying={isPlaying} />
124
- )}
125
-
126
- {meshData && (
127
- <MeshEffect gradients={meshData} blur={effectConfig.blur} isPlaying={isPlaying} />
128
- )}
113
+ {/* Effect layers container - under cover, non-interactive */}
114
+ <div className="absolute inset-0 z-0 pointer-events-none overflow-visible">
115
+ {glowData && (
116
+ <GlowEffect data={glowData} colors={colors} isPlaying={isPlaying} />
117
+ )}
118
+
119
+ {orbsData && (
120
+ <OrbsEffect orbs={orbsData} blur={effectConfig.blur} isPlaying={isPlaying} />
121
+ )}
122
+
123
+ {spotlightData && (
124
+ <SpotlightEffect data={spotlightData} colors={colors} blur={effectConfig.blur} isPlaying={isPlaying} />
125
+ )}
126
+
127
+ {meshData && (
128
+ <MeshEffect gradients={meshData} blur={effectConfig.blur} isPlaying={isPlaying} />
129
+ )}
130
+ </div>
129
131
 
130
132
  {/* Content (cover art) */}
131
133
  <div
@@ -1,15 +1,11 @@
1
1
  /**
2
2
  * AudioPlayer components - Public API
3
+ *
4
+ * Uses HTML5 audio for playback + Web Audio API for visualization.
5
+ * No crackling, native streaming support.
3
6
  */
4
7
 
5
- // WaveSurfer-based components (original)
6
- export { AudioPlayer } from './AudioPlayer';
7
- export { SimpleAudioPlayer, type SimpleAudioPlayerProps } from './SimpleAudioPlayer';
8
- export { AudioEqualizer } from './AudioEqualizer';
9
- export { AudioShortcutsPopover } from './AudioShortcutsPopover';
10
- export { VisualizationToggle, type VisualizationToggleProps } from './VisualizationToggle';
11
-
12
- // Hybrid player components (HTML5 audio + Web Audio for visualization)
8
+ // Player components
13
9
  export { HybridAudioPlayer, type HybridAudioPlayerProps } from './HybridAudioPlayer';
14
10
  export { HybridSimplePlayer, type HybridSimplePlayerProps } from './HybridSimplePlayer';
15
11
  export { HybridWaveform, type HybridWaveformProps } from './HybridWaveform';
@@ -1,16 +1,9 @@
1
1
  /**
2
2
  * AudioPlayer context - Public API
3
3
  *
4
- * Re-exports provider and selector hooks
4
+ * HybridAudioProvider: HTML5 audio + Web Audio API for visualization
5
5
  */
6
6
 
7
- // WaveSurfer-based provider (original)
8
- export { AudioProvider, AudioPlayerContext } from './AudioProvider';
9
-
10
- // Selector hooks for WaveSurfer provider
11
- export { useAudio, useAudioControls, useAudioState, useAudioElement } from './selectors';
12
-
13
- // Hybrid provider (HTML5 audio + Web Audio for visualization)
14
7
  export {
15
8
  HybridAudioProvider,
16
9
  useHybridAudioContext,
@@ -1,14 +1,8 @@
1
1
  /**
2
- * AudioPlayer hooks - re-exports all hooks
2
+ * AudioPlayer hooks - Public API
3
3
  */
4
4
 
5
- // Internal hooks (used by provider)
6
- export { useSharedWebAudio } from './useSharedWebAudio';
7
- export { useAudioAnalysis } from './useAudioAnalysis';
8
- export { useAudioSource } from './useAudioSource';
9
- export type { UseAudioSourceResult } from './useAudioSource';
10
-
11
- // Hybrid player hooks
5
+ // Core hybrid audio hook
12
6
  export { useHybridAudio } from './useHybridAudio';
13
7
  export type {
14
8
  UseHybridAudioOptions,
@@ -17,15 +11,14 @@ export type {
17
11
  HybridWebAudioAPI,
18
12
  UseHybridAudioReturn,
19
13
  } from './useHybridAudio';
20
- export { useHybridAudioAnalysis } from './useHybridAudioAnalysis';
21
14
 
22
- // Public hooks
23
- export { useAudioHotkeys, AUDIO_SHORTCUTS } from './useAudioHotkeys';
24
- export type { AudioHotkeyOptions, ShortcutItem, ShortcutGroup } from './useAudioHotkeys';
15
+ // Frequency analysis hook
16
+ export { useHybridAudioAnalysis } from './useHybridAudioAnalysis';
25
17
 
18
+ // Visualization settings (localStorage persistence)
26
19
  export {
27
20
  useVisualization,
28
- useAudioVisualization, // backward compat alias
21
+ useAudioVisualization,
29
22
  VisualizationProvider,
30
23
  VARIANT_INFO,
31
24
  INTENSITY_INFO,