wavesurf 1.0.0
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.
- package/LICENSE +21 -0
- package/README.md +348 -0
- package/dist/index.d.mts +212 -0
- package/dist/index.d.ts +212 -0
- package/dist/index.js +707 -0
- package/dist/index.js.map +1 -0
- package/dist/index.mjs +695 -0
- package/dist/index.mjs.map +1 -0
- package/dist/styles.css +395 -0
- package/package.json +65 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 TheDecipherist
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,348 @@
|
|
|
1
|
+
# wavesurf
|
|
2
|
+
|
|
3
|
+
A React audio player with WaveSurfer.js waveform visualization, global state management, and mini-player support.
|
|
4
|
+
|
|
5
|
+
## Features
|
|
6
|
+
|
|
7
|
+
- **WaveSurfer.js Integration** - Beautiful waveform visualization for audio playback
|
|
8
|
+
- **Global Audio State** - React Context for managing playback across your app
|
|
9
|
+
- **Mini Player** - A persistent bottom/top bar for controlling playback
|
|
10
|
+
- **Pre-computed Peaks Support** - Fast loading with pre-generated waveform data
|
|
11
|
+
- **Volume Fade-in Effect** - Smooth 3-second volume fade when starting playback
|
|
12
|
+
- **Volume Persistence** - Remember user's volume preference via localStorage
|
|
13
|
+
- **Lazy Loading** - Load waveforms only when visible using IntersectionObserver
|
|
14
|
+
- **Mobile Responsive** - Adapts to different screen sizes
|
|
15
|
+
- **CSS Variables** - Easy theming with CSS custom properties
|
|
16
|
+
- **TypeScript** - Full TypeScript support with exported types
|
|
17
|
+
|
|
18
|
+
## Installation
|
|
19
|
+
|
|
20
|
+
```bash
|
|
21
|
+
npm install wavesurf wavesurfer.js
|
|
22
|
+
# or
|
|
23
|
+
yarn add wavesurf wavesurfer.js
|
|
24
|
+
# or
|
|
25
|
+
pnpm add wavesurf wavesurfer.js
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
## Quick Start
|
|
29
|
+
|
|
30
|
+
### 1. Wrap your app with the provider
|
|
31
|
+
|
|
32
|
+
```tsx
|
|
33
|
+
import { AudioPlayerProvider } from 'wavesurf';
|
|
34
|
+
|
|
35
|
+
function App() {
|
|
36
|
+
return (
|
|
37
|
+
<AudioPlayerProvider>
|
|
38
|
+
<YourApp />
|
|
39
|
+
</AudioPlayerProvider>
|
|
40
|
+
);
|
|
41
|
+
}
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
### 2. Add the MiniPlayer component
|
|
45
|
+
|
|
46
|
+
```tsx
|
|
47
|
+
import { MiniPlayer } from 'wavesurf';
|
|
48
|
+
|
|
49
|
+
function Layout({ children }) {
|
|
50
|
+
return (
|
|
51
|
+
<div>
|
|
52
|
+
{children}
|
|
53
|
+
<MiniPlayer />
|
|
54
|
+
</div>
|
|
55
|
+
);
|
|
56
|
+
}
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
### 3. Use the WaveformPlayer for songs
|
|
60
|
+
|
|
61
|
+
```tsx
|
|
62
|
+
import { WaveformPlayer } from 'wavesurf';
|
|
63
|
+
import 'wavesurf/styles.css';
|
|
64
|
+
|
|
65
|
+
function SongList({ songs }) {
|
|
66
|
+
return (
|
|
67
|
+
<div>
|
|
68
|
+
{songs.map((song) => (
|
|
69
|
+
<WaveformPlayer
|
|
70
|
+
key={song.id}
|
|
71
|
+
song={{
|
|
72
|
+
id: song.id,
|
|
73
|
+
title: song.title,
|
|
74
|
+
artist: song.artist,
|
|
75
|
+
audioUrl: song.url,
|
|
76
|
+
duration: song.duration,
|
|
77
|
+
peaks: song.peaks, // Optional: pre-computed waveform data
|
|
78
|
+
}}
|
|
79
|
+
/>
|
|
80
|
+
))}
|
|
81
|
+
</div>
|
|
82
|
+
);
|
|
83
|
+
}
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
## API Reference
|
|
87
|
+
|
|
88
|
+
### AudioPlayerProvider
|
|
89
|
+
|
|
90
|
+
Wrap your application with this provider to enable global audio state management.
|
|
91
|
+
|
|
92
|
+
```tsx
|
|
93
|
+
<AudioPlayerProvider config={config}>
|
|
94
|
+
{children}
|
|
95
|
+
</AudioPlayerProvider>
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
#### Config Options
|
|
99
|
+
|
|
100
|
+
| Property | Type | Default | Description |
|
|
101
|
+
|----------|------|---------|-------------|
|
|
102
|
+
| `fadeInEnabled` | `boolean` | `true` | Enable volume fade-in effect on play |
|
|
103
|
+
| `fadeInDuration` | `number` | `3000` | Duration of fade-in in milliseconds |
|
|
104
|
+
| `persistVolume` | `boolean` | `true` | Persist volume to localStorage |
|
|
105
|
+
| `storageKey` | `string` | `'audioPlayerVolume'` | localStorage key for volume |
|
|
106
|
+
| `defaultVolume` | `number` | `1` | Default volume level (0-1) |
|
|
107
|
+
| `onPlay` | `(song: Song) => void` | - | Callback when playback starts |
|
|
108
|
+
| `onPause` | `() => void` | - | Callback when playback pauses |
|
|
109
|
+
| `onEnd` | `() => void` | - | Callback when song ends |
|
|
110
|
+
| `onTimeUpdate` | `(time: number) => void` | - | Callback on time update |
|
|
111
|
+
|
|
112
|
+
### useAudioPlayer Hook
|
|
113
|
+
|
|
114
|
+
Access the audio player state and controls from any component.
|
|
115
|
+
|
|
116
|
+
```tsx
|
|
117
|
+
import { useAudioPlayer } from 'wavesurf';
|
|
118
|
+
|
|
119
|
+
function CustomControls() {
|
|
120
|
+
const {
|
|
121
|
+
// State
|
|
122
|
+
currentSong,
|
|
123
|
+
isPlaying,
|
|
124
|
+
currentTime,
|
|
125
|
+
duration,
|
|
126
|
+
volume,
|
|
127
|
+
displayVolume,
|
|
128
|
+
isFadingIn,
|
|
129
|
+
// Actions
|
|
130
|
+
play,
|
|
131
|
+
pause,
|
|
132
|
+
togglePlay,
|
|
133
|
+
seek,
|
|
134
|
+
setVolume,
|
|
135
|
+
stop,
|
|
136
|
+
} = useAudioPlayer();
|
|
137
|
+
|
|
138
|
+
return (
|
|
139
|
+
<button onClick={togglePlay}>
|
|
140
|
+
{isPlaying ? 'Pause' : 'Play'}
|
|
141
|
+
</button>
|
|
142
|
+
);
|
|
143
|
+
}
|
|
144
|
+
```
|
|
145
|
+
|
|
146
|
+
### WaveformPlayer
|
|
147
|
+
|
|
148
|
+
Displays a waveform visualization with play controls for a single song.
|
|
149
|
+
|
|
150
|
+
```tsx
|
|
151
|
+
<WaveformPlayer
|
|
152
|
+
song={song}
|
|
153
|
+
waveformConfig={{
|
|
154
|
+
waveColor: '#666666',
|
|
155
|
+
progressColor: '#D4AF37',
|
|
156
|
+
height: 60,
|
|
157
|
+
}}
|
|
158
|
+
lazyLoad={true}
|
|
159
|
+
showTime={true}
|
|
160
|
+
className="my-player"
|
|
161
|
+
renderHeader={(song, isPlaying) => (
|
|
162
|
+
<div>{song.title} {isPlaying && '▶'}</div>
|
|
163
|
+
)}
|
|
164
|
+
renderControls={(song, isPlaying) => (
|
|
165
|
+
<button>Share</button>
|
|
166
|
+
)}
|
|
167
|
+
/>
|
|
168
|
+
```
|
|
169
|
+
|
|
170
|
+
#### Props
|
|
171
|
+
|
|
172
|
+
| Prop | Type | Default | Description |
|
|
173
|
+
|------|------|---------|-------------|
|
|
174
|
+
| `song` | `Song` | required | The song object to play |
|
|
175
|
+
| `waveformConfig` | `WaveformConfig` | - | Waveform styling options |
|
|
176
|
+
| `lazyLoad` | `boolean` | `true` | Enable lazy loading via IntersectionObserver |
|
|
177
|
+
| `showTime` | `boolean` | `true` | Show time display below waveform |
|
|
178
|
+
| `className` | `string` | `''` | Additional CSS class |
|
|
179
|
+
| `renderHeader` | `(song, isPlaying) => ReactNode` | - | Custom header renderer |
|
|
180
|
+
| `renderControls` | `(song, isPlaying) => ReactNode` | - | Custom controls renderer |
|
|
181
|
+
|
|
182
|
+
### MiniPlayer
|
|
183
|
+
|
|
184
|
+
A fixed position player bar for persistent playback control.
|
|
185
|
+
|
|
186
|
+
```tsx
|
|
187
|
+
<MiniPlayer
|
|
188
|
+
position="bottom"
|
|
189
|
+
showVolume={true}
|
|
190
|
+
showClose={true}
|
|
191
|
+
onClose={() => console.log('Player closed')}
|
|
192
|
+
className="my-mini-player"
|
|
193
|
+
waveformConfig={{
|
|
194
|
+
progressColor: '#FF0000',
|
|
195
|
+
}}
|
|
196
|
+
/>
|
|
197
|
+
```
|
|
198
|
+
|
|
199
|
+
#### Props
|
|
200
|
+
|
|
201
|
+
| Prop | Type | Default | Description |
|
|
202
|
+
|------|------|---------|-------------|
|
|
203
|
+
| `position` | `'top' \| 'bottom'` | `'bottom'` | Position on screen |
|
|
204
|
+
| `showVolume` | `boolean` | `true` | Show volume control (auto-hidden on mobile) |
|
|
205
|
+
| `showClose` | `boolean` | `true` | Show close button |
|
|
206
|
+
| `onClose` | `() => void` | - | Callback when close is clicked |
|
|
207
|
+
| `className` | `string` | `''` | Additional CSS class |
|
|
208
|
+
| `waveformConfig` | `WaveformConfig` | - | Waveform styling options |
|
|
209
|
+
|
|
210
|
+
### Song Interface
|
|
211
|
+
|
|
212
|
+
```typescript
|
|
213
|
+
interface Song {
|
|
214
|
+
id: string; // Unique identifier
|
|
215
|
+
title: string; // Display title
|
|
216
|
+
artist?: string; // Artist name (optional)
|
|
217
|
+
album?: string; // Album name (optional)
|
|
218
|
+
audioUrl: string; // URL to the audio file
|
|
219
|
+
duration?: number; // Duration in seconds (optional)
|
|
220
|
+
peaks?: number[]; // Pre-computed waveform peaks (optional)
|
|
221
|
+
}
|
|
222
|
+
```
|
|
223
|
+
|
|
224
|
+
### WaveformConfig Interface
|
|
225
|
+
|
|
226
|
+
```typescript
|
|
227
|
+
interface WaveformConfig {
|
|
228
|
+
waveColor?: string; // Color of the waveform (default: '#666666')
|
|
229
|
+
progressColor?: string; // Color of played portion (default: '#D4AF37')
|
|
230
|
+
cursorColor?: string; // Color of playhead (default: '#D4AF37')
|
|
231
|
+
barWidth?: number; // Width of bars in px (default: 2)
|
|
232
|
+
barGap?: number; // Gap between bars in px (default: 1)
|
|
233
|
+
barRadius?: number; // Border radius of bars (default: 2)
|
|
234
|
+
height?: number; // Height in pixels (default: 60)
|
|
235
|
+
normalize?: boolean; // Normalize waveform (default: true)
|
|
236
|
+
}
|
|
237
|
+
```
|
|
238
|
+
|
|
239
|
+
## Styling & Theming
|
|
240
|
+
|
|
241
|
+
### Using the default styles
|
|
242
|
+
|
|
243
|
+
Import the CSS file in your app:
|
|
244
|
+
|
|
245
|
+
```tsx
|
|
246
|
+
import 'wavesurf/styles.css';
|
|
247
|
+
```
|
|
248
|
+
|
|
249
|
+
### Customizing with CSS Variables
|
|
250
|
+
|
|
251
|
+
Override the CSS variables to customize the appearance:
|
|
252
|
+
|
|
253
|
+
```css
|
|
254
|
+
:root {
|
|
255
|
+
/* Colors */
|
|
256
|
+
--wsp-wave-color: #888888;
|
|
257
|
+
--wsp-progress-color: #FF5500;
|
|
258
|
+
--wsp-cursor-color: #FF5500;
|
|
259
|
+
--wsp-background: transparent;
|
|
260
|
+
|
|
261
|
+
/* Button Colors */
|
|
262
|
+
--wsp-button-bg: #FF5500;
|
|
263
|
+
--wsp-button-bg-hover: #FF7733;
|
|
264
|
+
--wsp-button-text: #ffffff;
|
|
265
|
+
|
|
266
|
+
/* Text Colors */
|
|
267
|
+
--wsp-text: #ffffff;
|
|
268
|
+
--wsp-text-muted: #999999;
|
|
269
|
+
|
|
270
|
+
/* Sizing */
|
|
271
|
+
--wsp-height: 60px;
|
|
272
|
+
--wsp-mini-height: 40px;
|
|
273
|
+
--wsp-button-size: 56px;
|
|
274
|
+
|
|
275
|
+
/* Mini Player */
|
|
276
|
+
--wsp-mini-bg: #1a1a1a;
|
|
277
|
+
--wsp-mini-border-color: #FF5500;
|
|
278
|
+
}
|
|
279
|
+
```
|
|
280
|
+
|
|
281
|
+
### Using your own styles
|
|
282
|
+
|
|
283
|
+
You can also write completely custom CSS targeting the class names:
|
|
284
|
+
|
|
285
|
+
- `.wsp-player` - Main player container
|
|
286
|
+
- `.wsp-play-button` - Play/pause button
|
|
287
|
+
- `.wsp-waveform` - Waveform container
|
|
288
|
+
- `.wsp-time-display` - Time display
|
|
289
|
+
- `.wsp-mini-player` - Mini player container
|
|
290
|
+
- `.wsp-mini-play-button` - Mini player play button
|
|
291
|
+
- `.wsp-mini-waveform` - Mini player waveform
|
|
292
|
+
|
|
293
|
+
## Pre-computed Peaks
|
|
294
|
+
|
|
295
|
+
For optimal performance, especially with large audio files, you can pre-compute waveform peaks on your server. This eliminates the need to decode audio on the client.
|
|
296
|
+
|
|
297
|
+
### Generating peaks with audiowaveform
|
|
298
|
+
|
|
299
|
+
```bash
|
|
300
|
+
# Install audiowaveform (on Ubuntu/Debian)
|
|
301
|
+
sudo apt install audiowaveform
|
|
302
|
+
|
|
303
|
+
# Generate peaks JSON
|
|
304
|
+
audiowaveform -i audio.mp3 -o peaks.json --pixels-per-second 10
|
|
305
|
+
```
|
|
306
|
+
|
|
307
|
+
### Using peaks in your app
|
|
308
|
+
|
|
309
|
+
```tsx
|
|
310
|
+
const song = {
|
|
311
|
+
id: '1',
|
|
312
|
+
title: 'My Song',
|
|
313
|
+
audioUrl: '/audio/song.mp3',
|
|
314
|
+
duration: 180, // 3 minutes
|
|
315
|
+
peaks: peaksData, // Array of numbers from audiowaveform
|
|
316
|
+
};
|
|
317
|
+
|
|
318
|
+
<WaveformPlayer song={song} />
|
|
319
|
+
```
|
|
320
|
+
|
|
321
|
+
## TypeScript
|
|
322
|
+
|
|
323
|
+
All types are exported from the package:
|
|
324
|
+
|
|
325
|
+
```typescript
|
|
326
|
+
import type {
|
|
327
|
+
Song,
|
|
328
|
+
AudioPlayerState,
|
|
329
|
+
AudioPlayerActions,
|
|
330
|
+
AudioPlayerConfig,
|
|
331
|
+
WaveformConfig,
|
|
332
|
+
WaveformPlayerProps,
|
|
333
|
+
MiniPlayerProps,
|
|
334
|
+
} from 'wavesurf';
|
|
335
|
+
```
|
|
336
|
+
|
|
337
|
+
## Browser Support
|
|
338
|
+
|
|
339
|
+
This package requires browsers that support:
|
|
340
|
+
- Web Audio API
|
|
341
|
+
- CSS Custom Properties
|
|
342
|
+
- IntersectionObserver (for lazy loading)
|
|
343
|
+
|
|
344
|
+
All modern browsers (Chrome, Firefox, Safari, Edge) are supported.
|
|
345
|
+
|
|
346
|
+
## License
|
|
347
|
+
|
|
348
|
+
MIT
|
package/dist/index.d.mts
ADDED
|
@@ -0,0 +1,212 @@
|
|
|
1
|
+
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
2
|
+
import { ReactNode } from 'react';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Represents a song/track that can be played by the audio player.
|
|
6
|
+
*/
|
|
7
|
+
interface Song {
|
|
8
|
+
/** Unique identifier for the song */
|
|
9
|
+
id: string;
|
|
10
|
+
/** Display title of the song */
|
|
11
|
+
title: string;
|
|
12
|
+
/** Artist name (optional) */
|
|
13
|
+
artist?: string;
|
|
14
|
+
/** Album name (optional) */
|
|
15
|
+
album?: string;
|
|
16
|
+
/** URL to the audio file */
|
|
17
|
+
audioUrl: string;
|
|
18
|
+
/** Duration in seconds (optional, will be detected if not provided) */
|
|
19
|
+
duration?: number;
|
|
20
|
+
/** Pre-computed waveform peaks for fast visualization (optional) */
|
|
21
|
+
peaks?: number[];
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Internal state of the audio player.
|
|
25
|
+
*/
|
|
26
|
+
interface AudioPlayerState {
|
|
27
|
+
/** Currently loaded song (null if none) */
|
|
28
|
+
currentSong: Song | null;
|
|
29
|
+
/** Whether audio is currently playing */
|
|
30
|
+
isPlaying: boolean;
|
|
31
|
+
/** Current playback position in seconds */
|
|
32
|
+
currentTime: number;
|
|
33
|
+
/** Total duration in seconds */
|
|
34
|
+
duration: number;
|
|
35
|
+
/** User's target/saved volume (0-1) */
|
|
36
|
+
volume: number;
|
|
37
|
+
/** Actual current volume, follows fade-in animation (0-1) */
|
|
38
|
+
displayVolume: number;
|
|
39
|
+
/** Whether volume is currently fading in */
|
|
40
|
+
isFadingIn: boolean;
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* Actions available to control the audio player.
|
|
44
|
+
*/
|
|
45
|
+
interface AudioPlayerActions {
|
|
46
|
+
/** Play a song (loads and starts playback with fade-in) */
|
|
47
|
+
play: (song: Song) => void;
|
|
48
|
+
/** Pause playback */
|
|
49
|
+
pause: () => void;
|
|
50
|
+
/** Toggle between play and pause */
|
|
51
|
+
togglePlay: () => void;
|
|
52
|
+
/** Seek to a specific time in seconds */
|
|
53
|
+
seek: (time: number) => void;
|
|
54
|
+
/** Set volume (0-1, persisted to localStorage if enabled) */
|
|
55
|
+
setVolume: (volume: number) => void;
|
|
56
|
+
/** Stop playback and clear current song */
|
|
57
|
+
stop: () => void;
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* Combined context value including state and actions.
|
|
61
|
+
*/
|
|
62
|
+
interface AudioPlayerContextValue extends AudioPlayerState, AudioPlayerActions {
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* Configuration options for the AudioPlayerProvider.
|
|
66
|
+
*/
|
|
67
|
+
interface AudioPlayerConfig {
|
|
68
|
+
/** Enable volume fade-in effect on play (default: true) */
|
|
69
|
+
fadeInEnabled?: boolean;
|
|
70
|
+
/** Duration of fade-in effect in milliseconds (default: 3000) */
|
|
71
|
+
fadeInDuration?: number;
|
|
72
|
+
/** Persist volume to localStorage (default: true) */
|
|
73
|
+
persistVolume?: boolean;
|
|
74
|
+
/** localStorage key for volume persistence (default: 'audioPlayerVolume') */
|
|
75
|
+
storageKey?: string;
|
|
76
|
+
/** Default volume level 0-1 (default: 1) */
|
|
77
|
+
defaultVolume?: number;
|
|
78
|
+
/** Callback when a song starts playing */
|
|
79
|
+
onPlay?: (song: Song) => void;
|
|
80
|
+
/** Callback when playback is paused */
|
|
81
|
+
onPause?: () => void;
|
|
82
|
+
/** Callback when a song ends */
|
|
83
|
+
onEnd?: () => void;
|
|
84
|
+
/** Callback when current time changes (called frequently) */
|
|
85
|
+
onTimeUpdate?: (time: number) => void;
|
|
86
|
+
}
|
|
87
|
+
/**
|
|
88
|
+
* Configuration options for waveform visualization.
|
|
89
|
+
*/
|
|
90
|
+
interface WaveformConfig {
|
|
91
|
+
/** Color of the waveform (default: '#666666') */
|
|
92
|
+
waveColor?: string;
|
|
93
|
+
/** Color of the played/progress portion (default: '#D4AF37') */
|
|
94
|
+
progressColor?: string;
|
|
95
|
+
/** Color of the cursor/playhead (default: '#D4AF37') */
|
|
96
|
+
cursorColor?: string;
|
|
97
|
+
/** Width of each bar in pixels (default: 2) */
|
|
98
|
+
barWidth?: number;
|
|
99
|
+
/** Gap between bars in pixels (default: 1) */
|
|
100
|
+
barGap?: number;
|
|
101
|
+
/** Border radius of bars in pixels (default: 2) */
|
|
102
|
+
barRadius?: number;
|
|
103
|
+
/** Height of the waveform in pixels (default: 60) */
|
|
104
|
+
height?: number;
|
|
105
|
+
/** Normalize waveform to fill height (default: true) */
|
|
106
|
+
normalize?: boolean;
|
|
107
|
+
}
|
|
108
|
+
/**
|
|
109
|
+
* Props for the WaveformPlayer component.
|
|
110
|
+
*/
|
|
111
|
+
interface WaveformPlayerProps {
|
|
112
|
+
/** The song to display/play */
|
|
113
|
+
song: Song;
|
|
114
|
+
/** Waveform styling configuration */
|
|
115
|
+
waveformConfig?: WaveformConfig;
|
|
116
|
+
/** Enable lazy loading via IntersectionObserver (default: true) */
|
|
117
|
+
lazyLoad?: boolean;
|
|
118
|
+
/** Show time display below waveform (default: true) */
|
|
119
|
+
showTime?: boolean;
|
|
120
|
+
/** Additional CSS class name */
|
|
121
|
+
className?: string;
|
|
122
|
+
/** Custom render function for the header area */
|
|
123
|
+
renderHeader?: (song: Song, isPlaying: boolean) => React.ReactNode;
|
|
124
|
+
/** Custom render function for additional controls */
|
|
125
|
+
renderControls?: (song: Song, isPlaying: boolean) => React.ReactNode;
|
|
126
|
+
}
|
|
127
|
+
/**
|
|
128
|
+
* Position of the mini player.
|
|
129
|
+
*/
|
|
130
|
+
type MiniPlayerPosition = 'top' | 'bottom';
|
|
131
|
+
/**
|
|
132
|
+
* Props for the MiniPlayer component.
|
|
133
|
+
*/
|
|
134
|
+
interface MiniPlayerProps {
|
|
135
|
+
/** Position on screen (default: 'bottom') */
|
|
136
|
+
position?: MiniPlayerPosition;
|
|
137
|
+
/** Show volume control (default: true on desktop, false on mobile) */
|
|
138
|
+
showVolume?: boolean;
|
|
139
|
+
/** Show close button (default: true) */
|
|
140
|
+
showClose?: boolean;
|
|
141
|
+
/** Callback when close button is clicked */
|
|
142
|
+
onClose?: () => void;
|
|
143
|
+
/** Additional CSS class name */
|
|
144
|
+
className?: string;
|
|
145
|
+
/** Waveform styling configuration for the mini waveform */
|
|
146
|
+
waveformConfig?: WaveformConfig;
|
|
147
|
+
}
|
|
148
|
+
/**
|
|
149
|
+
* Return type for the useLazyLoad hook.
|
|
150
|
+
*/
|
|
151
|
+
interface UseLazyLoadResult {
|
|
152
|
+
/** Ref to attach to the element to observe */
|
|
153
|
+
ref: React.RefObject<HTMLDivElement>;
|
|
154
|
+
/** Whether the element is visible/intersecting */
|
|
155
|
+
isVisible: boolean;
|
|
156
|
+
}
|
|
157
|
+
/**
|
|
158
|
+
* Options for the useLazyLoad hook.
|
|
159
|
+
*/
|
|
160
|
+
interface UseLazyLoadOptions {
|
|
161
|
+
/** Root margin for IntersectionObserver (default: '100px') */
|
|
162
|
+
rootMargin?: string;
|
|
163
|
+
/** Visibility threshold 0-1 (default: 0) */
|
|
164
|
+
threshold?: number;
|
|
165
|
+
/** Start as visible (skip lazy loading) */
|
|
166
|
+
forceVisible?: boolean;
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
declare const MINI_PLAYER_PLAY_EVENT = "wavesurfer-player-mini-play";
|
|
170
|
+
interface AudioPlayerProviderProps {
|
|
171
|
+
children: ReactNode;
|
|
172
|
+
config?: AudioPlayerConfig;
|
|
173
|
+
}
|
|
174
|
+
declare function AudioPlayerProvider({ children, config: userConfig, }: AudioPlayerProviderProps): react_jsx_runtime.JSX.Element;
|
|
175
|
+
declare function useAudioPlayer(): AudioPlayerContextValue;
|
|
176
|
+
|
|
177
|
+
declare function WaveformPlayer({ song, waveformConfig: userWaveformConfig, lazyLoad, showTime, className, renderHeader, renderControls, }: WaveformPlayerProps): react_jsx_runtime.JSX.Element;
|
|
178
|
+
|
|
179
|
+
declare function MiniPlayer({ position, showVolume, showClose, onClose, className, waveformConfig: userWaveformConfig, }: MiniPlayerProps): react_jsx_runtime.JSX.Element | null;
|
|
180
|
+
|
|
181
|
+
/**
|
|
182
|
+
* Hook for lazy loading elements using IntersectionObserver.
|
|
183
|
+
* Returns a ref to attach to the target element and a boolean indicating visibility.
|
|
184
|
+
*
|
|
185
|
+
* @param options - Configuration options for the IntersectionObserver
|
|
186
|
+
* @returns Object containing ref and isVisible state
|
|
187
|
+
*
|
|
188
|
+
* @example
|
|
189
|
+
* const { ref, isVisible } = useLazyLoad();
|
|
190
|
+
*
|
|
191
|
+
* return (
|
|
192
|
+
* <div ref={ref}>
|
|
193
|
+
* {isVisible && <ExpensiveComponent />}
|
|
194
|
+
* </div>
|
|
195
|
+
* );
|
|
196
|
+
*/
|
|
197
|
+
declare function useLazyLoad(options?: UseLazyLoadOptions): UseLazyLoadResult;
|
|
198
|
+
|
|
199
|
+
/**
|
|
200
|
+
* Formats seconds into a human-readable time string (M:SS or MM:SS).
|
|
201
|
+
*
|
|
202
|
+
* @param seconds - The number of seconds to format
|
|
203
|
+
* @returns Formatted time string (e.g., "3:45" or "12:05")
|
|
204
|
+
*
|
|
205
|
+
* @example
|
|
206
|
+
* formatTime(125) // "2:05"
|
|
207
|
+
* formatTime(0) // "0:00"
|
|
208
|
+
* formatTime(3600) // "60:00"
|
|
209
|
+
*/
|
|
210
|
+
declare function formatTime(seconds: number): string;
|
|
211
|
+
|
|
212
|
+
export { type AudioPlayerActions, type AudioPlayerConfig, type AudioPlayerContextValue, AudioPlayerProvider, type AudioPlayerState, MINI_PLAYER_PLAY_EVENT, MiniPlayer, type MiniPlayerPosition, type MiniPlayerProps, type Song, type UseLazyLoadOptions, type UseLazyLoadResult, type WaveformConfig, WaveformPlayer, type WaveformPlayerProps, formatTime, useAudioPlayer, useLazyLoad };
|