@waveform-playlist/media-element-playout 5.0.0-alpha.14
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.md +21 -0
- package/README.md +137 -0
- package/dist/index.d.mts +235 -0
- package/dist/index.d.ts +235 -0
- package/dist/index.js +369 -0
- package/dist/index.js.map +1 -0
- package/dist/index.mjs +340 -0
- package/dist/index.mjs.map +1 -0
- package/package.json +51 -0
package/LICENSE.md
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
The MIT License (MIT)
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2015 Naomi
|
|
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,137 @@
|
|
|
1
|
+
# @waveform-playlist/media-element-playout
|
|
2
|
+
|
|
3
|
+
A lightweight, HTMLMediaElement-based playout engine for waveform-playlist with **pitch-preserving playback rate control**.
|
|
4
|
+
|
|
5
|
+
## Features
|
|
6
|
+
|
|
7
|
+
- **Pitch-preserving playback rate** (0.5x - 2.0x) - uses browser's built-in time-stretching
|
|
8
|
+
- **Pre-computed peaks** - no AudioBuffer decoding required, instant visualization
|
|
9
|
+
- **Lightweight** - no Tone.js dependency
|
|
10
|
+
- **Simple API** - designed for single-track playback use cases
|
|
11
|
+
|
|
12
|
+
## When to Use
|
|
13
|
+
|
|
14
|
+
Use `MediaElementPlayout` when you need:
|
|
15
|
+
- Playback speed control for language learning, podcasts, etc.
|
|
16
|
+
- Single-track playback with minimal overhead
|
|
17
|
+
- Quick load times with pre-computed peaks
|
|
18
|
+
|
|
19
|
+
Use `TonePlayout` from `@waveform-playlist/playout` when you need:
|
|
20
|
+
- Multi-track mixing and editing
|
|
21
|
+
- Clip-level effects and fades
|
|
22
|
+
- Precise sample-accurate timing
|
|
23
|
+
|
|
24
|
+
## Installation
|
|
25
|
+
|
|
26
|
+
```bash
|
|
27
|
+
npm install @waveform-playlist/media-element-playout
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
## Usage
|
|
31
|
+
|
|
32
|
+
```typescript
|
|
33
|
+
import { MediaElementPlayout } from '@waveform-playlist/media-element-playout';
|
|
34
|
+
import WaveformData from 'waveform-data';
|
|
35
|
+
|
|
36
|
+
// Load pre-computed peaks
|
|
37
|
+
const response = await fetch('/audio/podcast.dat');
|
|
38
|
+
const arrayBuffer = await response.arrayBuffer();
|
|
39
|
+
const peaks = WaveformData.create(arrayBuffer);
|
|
40
|
+
|
|
41
|
+
// Create playout
|
|
42
|
+
const playout = new MediaElementPlayout({
|
|
43
|
+
masterVolume: 1.0,
|
|
44
|
+
playbackRate: 1.0,
|
|
45
|
+
});
|
|
46
|
+
|
|
47
|
+
// Add a track
|
|
48
|
+
playout.addTrack({
|
|
49
|
+
source: '/audio/podcast.mp3', // URL or Blob URL
|
|
50
|
+
peaks: peaks,
|
|
51
|
+
name: 'Podcast Episode 1',
|
|
52
|
+
});
|
|
53
|
+
|
|
54
|
+
// Control playback
|
|
55
|
+
playout.play(0); // Play from beginning
|
|
56
|
+
playout.setPlaybackRate(0.75); // Slow down to 75% speed (pitch preserved)
|
|
57
|
+
playout.pause();
|
|
58
|
+
playout.seekTo(30); // Seek to 30 seconds
|
|
59
|
+
playout.play(); // Resume
|
|
60
|
+
|
|
61
|
+
// Clean up
|
|
62
|
+
playout.dispose();
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
## API
|
|
66
|
+
|
|
67
|
+
### MediaElementPlayout
|
|
68
|
+
|
|
69
|
+
```typescript
|
|
70
|
+
interface MediaElementPlayoutOptions {
|
|
71
|
+
masterVolume?: number; // 0.0 to 1.0 (default: 1.0)
|
|
72
|
+
playbackRate?: number; // 0.5 to 2.0 (default: 1.0)
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
class MediaElementPlayout {
|
|
76
|
+
// Lifecycle
|
|
77
|
+
init(): Promise<void>; // No-op for media element
|
|
78
|
+
dispose(): void;
|
|
79
|
+
|
|
80
|
+
// Track management
|
|
81
|
+
addTrack(options: MediaElementTrackOptions): MediaElementTrack;
|
|
82
|
+
removeTrack(trackId: string): void;
|
|
83
|
+
getTrack(trackId: string): MediaElementTrack | undefined;
|
|
84
|
+
|
|
85
|
+
// Playback
|
|
86
|
+
play(when?: number, offset?: number, duration?: number): void;
|
|
87
|
+
pause(): void;
|
|
88
|
+
stop(): void;
|
|
89
|
+
seekTo(time: number): void;
|
|
90
|
+
getCurrentTime(): number;
|
|
91
|
+
|
|
92
|
+
// Volume & Rate
|
|
93
|
+
setMasterVolume(volume: number): void;
|
|
94
|
+
setPlaybackRate(rate: number): void; // 0.5 to 2.0, pitch preserved
|
|
95
|
+
|
|
96
|
+
// State
|
|
97
|
+
readonly isPlaying: boolean;
|
|
98
|
+
readonly duration: number;
|
|
99
|
+
readonly playbackRate: number;
|
|
100
|
+
}
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
### MediaElementTrack
|
|
104
|
+
|
|
105
|
+
```typescript
|
|
106
|
+
interface MediaElementTrackOptions {
|
|
107
|
+
source: string | HTMLAudioElement; // URL or audio element
|
|
108
|
+
peaks: WaveformDataObject; // Pre-computed peaks
|
|
109
|
+
id?: string;
|
|
110
|
+
name?: string;
|
|
111
|
+
volume?: number;
|
|
112
|
+
playbackRate?: number;
|
|
113
|
+
}
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
## Generating Peaks
|
|
117
|
+
|
|
118
|
+
Use [audiowaveform](https://github.com/bbc/audiowaveform) or [waveform-data.js](https://github.com/bbc/waveform-data.js) to pre-compute peaks:
|
|
119
|
+
|
|
120
|
+
```bash
|
|
121
|
+
# Generate peaks file with audiowaveform
|
|
122
|
+
audiowaveform -i audio.mp3 -o peaks.dat -b 16
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
## Browser Support
|
|
126
|
+
|
|
127
|
+
Pitch-preserving playback rate is supported in:
|
|
128
|
+
- Chrome 77+
|
|
129
|
+
- Firefox 20+
|
|
130
|
+
- Safari 14.1+
|
|
131
|
+
- Edge 79+
|
|
132
|
+
|
|
133
|
+
Older browsers will still work but may change pitch with speed.
|
|
134
|
+
|
|
135
|
+
## License
|
|
136
|
+
|
|
137
|
+
MIT
|
package/dist/index.d.mts
ADDED
|
@@ -0,0 +1,235 @@
|
|
|
1
|
+
import { WaveformDataObject } from '@waveform-playlist/core';
|
|
2
|
+
|
|
3
|
+
interface MediaElementTrackOptions {
|
|
4
|
+
/** The audio source - can be a URL, Blob URL, or HTMLAudioElement */
|
|
5
|
+
source: string | HTMLAudioElement;
|
|
6
|
+
/** Pre-computed waveform data for visualization (required - no AudioBuffer decoding) */
|
|
7
|
+
peaks: WaveformDataObject;
|
|
8
|
+
/** Track ID */
|
|
9
|
+
id?: string;
|
|
10
|
+
/** Track name for display */
|
|
11
|
+
name?: string;
|
|
12
|
+
/** Initial volume (0.0 to 1.0) */
|
|
13
|
+
volume?: number;
|
|
14
|
+
/** Initial playback rate (0.5 to 2.0, pitch preserved) */
|
|
15
|
+
playbackRate?: number;
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Single-track playback using HTMLAudioElement.
|
|
19
|
+
*
|
|
20
|
+
* Benefits over AudioBuffer/Tone.js:
|
|
21
|
+
* - Pitch-preserving playback rate (0.5x - 2.0x) via browser's built-in algorithm
|
|
22
|
+
* - No AudioBuffer decoding required (uses pre-computed peaks for visualization)
|
|
23
|
+
* - Simpler, lighter-weight for single-track use cases
|
|
24
|
+
*
|
|
25
|
+
* Limitations:
|
|
26
|
+
* - Single track only (no multi-track mixing)
|
|
27
|
+
* - No clip-level effects or fades (track-level volume only)
|
|
28
|
+
* - Relies on browser's time-stretching quality
|
|
29
|
+
*/
|
|
30
|
+
declare class MediaElementTrack {
|
|
31
|
+
private audioElement;
|
|
32
|
+
private ownsElement;
|
|
33
|
+
private _peaks;
|
|
34
|
+
private _id;
|
|
35
|
+
private _name;
|
|
36
|
+
private _playbackRate;
|
|
37
|
+
private onStopCallback?;
|
|
38
|
+
private onTimeUpdateCallback?;
|
|
39
|
+
constructor(options: MediaElementTrackOptions);
|
|
40
|
+
private handleEnded;
|
|
41
|
+
private handleTimeUpdate;
|
|
42
|
+
/**
|
|
43
|
+
* Start playback from a specific time
|
|
44
|
+
*/
|
|
45
|
+
play(offset?: number): void;
|
|
46
|
+
/**
|
|
47
|
+
* Pause playback
|
|
48
|
+
*/
|
|
49
|
+
pause(): void;
|
|
50
|
+
/**
|
|
51
|
+
* Stop playback and reset to beginning
|
|
52
|
+
*/
|
|
53
|
+
stop(): void;
|
|
54
|
+
/**
|
|
55
|
+
* Seek to a specific time
|
|
56
|
+
*/
|
|
57
|
+
seekTo(time: number): void;
|
|
58
|
+
/**
|
|
59
|
+
* Set volume (0.0 to 1.0)
|
|
60
|
+
*/
|
|
61
|
+
setVolume(volume: number): void;
|
|
62
|
+
/**
|
|
63
|
+
* Set playback rate (0.5 to 2.0, pitch preserved)
|
|
64
|
+
*/
|
|
65
|
+
setPlaybackRate(rate: number): void;
|
|
66
|
+
/**
|
|
67
|
+
* Set muted state
|
|
68
|
+
*/
|
|
69
|
+
setMuted(muted: boolean): void;
|
|
70
|
+
/**
|
|
71
|
+
* Set callback for when playback ends
|
|
72
|
+
*/
|
|
73
|
+
setOnStopCallback(callback: () => void): void;
|
|
74
|
+
/**
|
|
75
|
+
* Set callback for time updates
|
|
76
|
+
*/
|
|
77
|
+
setOnTimeUpdateCallback(callback: (time: number) => void): void;
|
|
78
|
+
/**
|
|
79
|
+
* Clean up resources
|
|
80
|
+
*/
|
|
81
|
+
dispose(): void;
|
|
82
|
+
get id(): string;
|
|
83
|
+
get name(): string;
|
|
84
|
+
get peaks(): WaveformDataObject;
|
|
85
|
+
get currentTime(): number;
|
|
86
|
+
get duration(): number;
|
|
87
|
+
get isPlaying(): boolean;
|
|
88
|
+
get volume(): number;
|
|
89
|
+
get playbackRate(): number;
|
|
90
|
+
get muted(): boolean;
|
|
91
|
+
/**
|
|
92
|
+
* Get the underlying audio element (for advanced use cases)
|
|
93
|
+
*/
|
|
94
|
+
get element(): HTMLAudioElement;
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
interface MediaElementPlayoutOptions {
|
|
98
|
+
/** Initial master volume (0.0 to 1.0) */
|
|
99
|
+
masterVolume?: number;
|
|
100
|
+
/** Initial playback rate (0.5 to 2.0) */
|
|
101
|
+
playbackRate?: number;
|
|
102
|
+
}
|
|
103
|
+
/**
|
|
104
|
+
* Single-track playout engine using HTMLAudioElement.
|
|
105
|
+
*
|
|
106
|
+
* This is a lightweight alternative to TonePlayout for single-track use cases
|
|
107
|
+
* that need pitch-preserving playback rate control.
|
|
108
|
+
*
|
|
109
|
+
* Key features:
|
|
110
|
+
* - Pitch-preserving playback rate (0.5x - 2.0x)
|
|
111
|
+
* - Uses pre-computed peaks (no AudioBuffer required)
|
|
112
|
+
* - Simpler API for single-track playback
|
|
113
|
+
*
|
|
114
|
+
* Limitations:
|
|
115
|
+
* - Single track only - will warn if multiple tracks added
|
|
116
|
+
* - No clip-level effects or crossfades
|
|
117
|
+
* - No multi-track mixing
|
|
118
|
+
*
|
|
119
|
+
* For multi-track editing, use TonePlayout from @waveform-playlist/playout instead.
|
|
120
|
+
*/
|
|
121
|
+
declare class MediaElementPlayout {
|
|
122
|
+
private track;
|
|
123
|
+
private _masterVolume;
|
|
124
|
+
private _playbackRate;
|
|
125
|
+
private _isPlaying;
|
|
126
|
+
private onPlaybackCompleteCallback?;
|
|
127
|
+
constructor(options?: MediaElementPlayoutOptions);
|
|
128
|
+
/**
|
|
129
|
+
* Initialize the playout engine.
|
|
130
|
+
* For MediaElementPlayout this is a no-op (no AudioContext to start).
|
|
131
|
+
*/
|
|
132
|
+
init(): Promise<void>;
|
|
133
|
+
/**
|
|
134
|
+
* Add a track to the playout.
|
|
135
|
+
* Note: Only one track is supported. Adding a second track will dispose the first.
|
|
136
|
+
*/
|
|
137
|
+
addTrack(options: MediaElementTrackOptions): MediaElementTrack;
|
|
138
|
+
/**
|
|
139
|
+
* Remove a track by ID.
|
|
140
|
+
*/
|
|
141
|
+
removeTrack(trackId: string): void;
|
|
142
|
+
/**
|
|
143
|
+
* Get a track by ID.
|
|
144
|
+
*/
|
|
145
|
+
getTrack(trackId: string): MediaElementTrack | undefined;
|
|
146
|
+
/**
|
|
147
|
+
* Start playback.
|
|
148
|
+
* @param _when - Ignored (HTMLAudioElement doesn't support scheduled start)
|
|
149
|
+
* @param offset - Start position in seconds
|
|
150
|
+
* @param duration - Duration to play in seconds (optional)
|
|
151
|
+
*/
|
|
152
|
+
play(_when?: number, offset?: number, duration?: number): void;
|
|
153
|
+
/**
|
|
154
|
+
* Pause playback.
|
|
155
|
+
*/
|
|
156
|
+
pause(): void;
|
|
157
|
+
/**
|
|
158
|
+
* Stop playback and reset to start.
|
|
159
|
+
*/
|
|
160
|
+
stop(): void;
|
|
161
|
+
/**
|
|
162
|
+
* Seek to a specific time.
|
|
163
|
+
*/
|
|
164
|
+
seekTo(time: number): void;
|
|
165
|
+
/**
|
|
166
|
+
* Get current playback time.
|
|
167
|
+
*/
|
|
168
|
+
getCurrentTime(): number;
|
|
169
|
+
/**
|
|
170
|
+
* Set master volume.
|
|
171
|
+
*/
|
|
172
|
+
setMasterVolume(volume: number): void;
|
|
173
|
+
/**
|
|
174
|
+
* Set playback rate (0.5 to 2.0, pitch preserved).
|
|
175
|
+
*/
|
|
176
|
+
setPlaybackRate(rate: number): void;
|
|
177
|
+
/**
|
|
178
|
+
* Set mute state for a track.
|
|
179
|
+
*/
|
|
180
|
+
setMute(trackId: string, muted: boolean): void;
|
|
181
|
+
/**
|
|
182
|
+
* Set solo state for a track.
|
|
183
|
+
* Note: With single track, solo is effectively the same as unmute.
|
|
184
|
+
*/
|
|
185
|
+
setSolo(_trackId: string, _soloed: boolean): void;
|
|
186
|
+
/**
|
|
187
|
+
* Set callback for when playback completes.
|
|
188
|
+
*/
|
|
189
|
+
setOnPlaybackComplete(callback: () => void): void;
|
|
190
|
+
/**
|
|
191
|
+
* Clean up resources.
|
|
192
|
+
*/
|
|
193
|
+
dispose(): void;
|
|
194
|
+
get isPlaying(): boolean;
|
|
195
|
+
get masterVolume(): number;
|
|
196
|
+
get playbackRate(): number;
|
|
197
|
+
get duration(): number;
|
|
198
|
+
get sampleRate(): number;
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
/**
|
|
202
|
+
* Common interface for playout engines.
|
|
203
|
+
*
|
|
204
|
+
* Both TonePlayout and MediaElementPlayout implement this interface,
|
|
205
|
+
* allowing the browser package to work with either engine.
|
|
206
|
+
*/
|
|
207
|
+
interface PlayoutEngine {
|
|
208
|
+
init(): Promise<void>;
|
|
209
|
+
dispose(): void;
|
|
210
|
+
play(when?: number, offset?: number, duration?: number): void;
|
|
211
|
+
pause(): void;
|
|
212
|
+
stop(): void;
|
|
213
|
+
seekTo(time: number): void;
|
|
214
|
+
getCurrentTime(): number;
|
|
215
|
+
setMasterVolume(volume: number): void;
|
|
216
|
+
setMute?(trackId: string, muted: boolean): void;
|
|
217
|
+
setSolo?(trackId: string, soloed: boolean): void;
|
|
218
|
+
setOnPlaybackComplete(callback: () => void): void;
|
|
219
|
+
readonly isPlaying: boolean;
|
|
220
|
+
readonly duration: number;
|
|
221
|
+
readonly sampleRate: number;
|
|
222
|
+
}
|
|
223
|
+
/**
|
|
224
|
+
* Extended interface for engines that support playback rate.
|
|
225
|
+
*/
|
|
226
|
+
interface PlaybackRateEngine extends PlayoutEngine {
|
|
227
|
+
setPlaybackRate(rate: number): void;
|
|
228
|
+
readonly playbackRate: number;
|
|
229
|
+
}
|
|
230
|
+
/**
|
|
231
|
+
* Type guard to check if an engine supports playback rate.
|
|
232
|
+
*/
|
|
233
|
+
declare function supportsPlaybackRate(engine: PlayoutEngine): engine is PlaybackRateEngine;
|
|
234
|
+
|
|
235
|
+
export { MediaElementPlayout, type MediaElementPlayoutOptions, MediaElementTrack, type MediaElementTrackOptions, type PlaybackRateEngine, type PlayoutEngine, supportsPlaybackRate };
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,235 @@
|
|
|
1
|
+
import { WaveformDataObject } from '@waveform-playlist/core';
|
|
2
|
+
|
|
3
|
+
interface MediaElementTrackOptions {
|
|
4
|
+
/** The audio source - can be a URL, Blob URL, or HTMLAudioElement */
|
|
5
|
+
source: string | HTMLAudioElement;
|
|
6
|
+
/** Pre-computed waveform data for visualization (required - no AudioBuffer decoding) */
|
|
7
|
+
peaks: WaveformDataObject;
|
|
8
|
+
/** Track ID */
|
|
9
|
+
id?: string;
|
|
10
|
+
/** Track name for display */
|
|
11
|
+
name?: string;
|
|
12
|
+
/** Initial volume (0.0 to 1.0) */
|
|
13
|
+
volume?: number;
|
|
14
|
+
/** Initial playback rate (0.5 to 2.0, pitch preserved) */
|
|
15
|
+
playbackRate?: number;
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Single-track playback using HTMLAudioElement.
|
|
19
|
+
*
|
|
20
|
+
* Benefits over AudioBuffer/Tone.js:
|
|
21
|
+
* - Pitch-preserving playback rate (0.5x - 2.0x) via browser's built-in algorithm
|
|
22
|
+
* - No AudioBuffer decoding required (uses pre-computed peaks for visualization)
|
|
23
|
+
* - Simpler, lighter-weight for single-track use cases
|
|
24
|
+
*
|
|
25
|
+
* Limitations:
|
|
26
|
+
* - Single track only (no multi-track mixing)
|
|
27
|
+
* - No clip-level effects or fades (track-level volume only)
|
|
28
|
+
* - Relies on browser's time-stretching quality
|
|
29
|
+
*/
|
|
30
|
+
declare class MediaElementTrack {
|
|
31
|
+
private audioElement;
|
|
32
|
+
private ownsElement;
|
|
33
|
+
private _peaks;
|
|
34
|
+
private _id;
|
|
35
|
+
private _name;
|
|
36
|
+
private _playbackRate;
|
|
37
|
+
private onStopCallback?;
|
|
38
|
+
private onTimeUpdateCallback?;
|
|
39
|
+
constructor(options: MediaElementTrackOptions);
|
|
40
|
+
private handleEnded;
|
|
41
|
+
private handleTimeUpdate;
|
|
42
|
+
/**
|
|
43
|
+
* Start playback from a specific time
|
|
44
|
+
*/
|
|
45
|
+
play(offset?: number): void;
|
|
46
|
+
/**
|
|
47
|
+
* Pause playback
|
|
48
|
+
*/
|
|
49
|
+
pause(): void;
|
|
50
|
+
/**
|
|
51
|
+
* Stop playback and reset to beginning
|
|
52
|
+
*/
|
|
53
|
+
stop(): void;
|
|
54
|
+
/**
|
|
55
|
+
* Seek to a specific time
|
|
56
|
+
*/
|
|
57
|
+
seekTo(time: number): void;
|
|
58
|
+
/**
|
|
59
|
+
* Set volume (0.0 to 1.0)
|
|
60
|
+
*/
|
|
61
|
+
setVolume(volume: number): void;
|
|
62
|
+
/**
|
|
63
|
+
* Set playback rate (0.5 to 2.0, pitch preserved)
|
|
64
|
+
*/
|
|
65
|
+
setPlaybackRate(rate: number): void;
|
|
66
|
+
/**
|
|
67
|
+
* Set muted state
|
|
68
|
+
*/
|
|
69
|
+
setMuted(muted: boolean): void;
|
|
70
|
+
/**
|
|
71
|
+
* Set callback for when playback ends
|
|
72
|
+
*/
|
|
73
|
+
setOnStopCallback(callback: () => void): void;
|
|
74
|
+
/**
|
|
75
|
+
* Set callback for time updates
|
|
76
|
+
*/
|
|
77
|
+
setOnTimeUpdateCallback(callback: (time: number) => void): void;
|
|
78
|
+
/**
|
|
79
|
+
* Clean up resources
|
|
80
|
+
*/
|
|
81
|
+
dispose(): void;
|
|
82
|
+
get id(): string;
|
|
83
|
+
get name(): string;
|
|
84
|
+
get peaks(): WaveformDataObject;
|
|
85
|
+
get currentTime(): number;
|
|
86
|
+
get duration(): number;
|
|
87
|
+
get isPlaying(): boolean;
|
|
88
|
+
get volume(): number;
|
|
89
|
+
get playbackRate(): number;
|
|
90
|
+
get muted(): boolean;
|
|
91
|
+
/**
|
|
92
|
+
* Get the underlying audio element (for advanced use cases)
|
|
93
|
+
*/
|
|
94
|
+
get element(): HTMLAudioElement;
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
interface MediaElementPlayoutOptions {
|
|
98
|
+
/** Initial master volume (0.0 to 1.0) */
|
|
99
|
+
masterVolume?: number;
|
|
100
|
+
/** Initial playback rate (0.5 to 2.0) */
|
|
101
|
+
playbackRate?: number;
|
|
102
|
+
}
|
|
103
|
+
/**
|
|
104
|
+
* Single-track playout engine using HTMLAudioElement.
|
|
105
|
+
*
|
|
106
|
+
* This is a lightweight alternative to TonePlayout for single-track use cases
|
|
107
|
+
* that need pitch-preserving playback rate control.
|
|
108
|
+
*
|
|
109
|
+
* Key features:
|
|
110
|
+
* - Pitch-preserving playback rate (0.5x - 2.0x)
|
|
111
|
+
* - Uses pre-computed peaks (no AudioBuffer required)
|
|
112
|
+
* - Simpler API for single-track playback
|
|
113
|
+
*
|
|
114
|
+
* Limitations:
|
|
115
|
+
* - Single track only - will warn if multiple tracks added
|
|
116
|
+
* - No clip-level effects or crossfades
|
|
117
|
+
* - No multi-track mixing
|
|
118
|
+
*
|
|
119
|
+
* For multi-track editing, use TonePlayout from @waveform-playlist/playout instead.
|
|
120
|
+
*/
|
|
121
|
+
declare class MediaElementPlayout {
|
|
122
|
+
private track;
|
|
123
|
+
private _masterVolume;
|
|
124
|
+
private _playbackRate;
|
|
125
|
+
private _isPlaying;
|
|
126
|
+
private onPlaybackCompleteCallback?;
|
|
127
|
+
constructor(options?: MediaElementPlayoutOptions);
|
|
128
|
+
/**
|
|
129
|
+
* Initialize the playout engine.
|
|
130
|
+
* For MediaElementPlayout this is a no-op (no AudioContext to start).
|
|
131
|
+
*/
|
|
132
|
+
init(): Promise<void>;
|
|
133
|
+
/**
|
|
134
|
+
* Add a track to the playout.
|
|
135
|
+
* Note: Only one track is supported. Adding a second track will dispose the first.
|
|
136
|
+
*/
|
|
137
|
+
addTrack(options: MediaElementTrackOptions): MediaElementTrack;
|
|
138
|
+
/**
|
|
139
|
+
* Remove a track by ID.
|
|
140
|
+
*/
|
|
141
|
+
removeTrack(trackId: string): void;
|
|
142
|
+
/**
|
|
143
|
+
* Get a track by ID.
|
|
144
|
+
*/
|
|
145
|
+
getTrack(trackId: string): MediaElementTrack | undefined;
|
|
146
|
+
/**
|
|
147
|
+
* Start playback.
|
|
148
|
+
* @param _when - Ignored (HTMLAudioElement doesn't support scheduled start)
|
|
149
|
+
* @param offset - Start position in seconds
|
|
150
|
+
* @param duration - Duration to play in seconds (optional)
|
|
151
|
+
*/
|
|
152
|
+
play(_when?: number, offset?: number, duration?: number): void;
|
|
153
|
+
/**
|
|
154
|
+
* Pause playback.
|
|
155
|
+
*/
|
|
156
|
+
pause(): void;
|
|
157
|
+
/**
|
|
158
|
+
* Stop playback and reset to start.
|
|
159
|
+
*/
|
|
160
|
+
stop(): void;
|
|
161
|
+
/**
|
|
162
|
+
* Seek to a specific time.
|
|
163
|
+
*/
|
|
164
|
+
seekTo(time: number): void;
|
|
165
|
+
/**
|
|
166
|
+
* Get current playback time.
|
|
167
|
+
*/
|
|
168
|
+
getCurrentTime(): number;
|
|
169
|
+
/**
|
|
170
|
+
* Set master volume.
|
|
171
|
+
*/
|
|
172
|
+
setMasterVolume(volume: number): void;
|
|
173
|
+
/**
|
|
174
|
+
* Set playback rate (0.5 to 2.0, pitch preserved).
|
|
175
|
+
*/
|
|
176
|
+
setPlaybackRate(rate: number): void;
|
|
177
|
+
/**
|
|
178
|
+
* Set mute state for a track.
|
|
179
|
+
*/
|
|
180
|
+
setMute(trackId: string, muted: boolean): void;
|
|
181
|
+
/**
|
|
182
|
+
* Set solo state for a track.
|
|
183
|
+
* Note: With single track, solo is effectively the same as unmute.
|
|
184
|
+
*/
|
|
185
|
+
setSolo(_trackId: string, _soloed: boolean): void;
|
|
186
|
+
/**
|
|
187
|
+
* Set callback for when playback completes.
|
|
188
|
+
*/
|
|
189
|
+
setOnPlaybackComplete(callback: () => void): void;
|
|
190
|
+
/**
|
|
191
|
+
* Clean up resources.
|
|
192
|
+
*/
|
|
193
|
+
dispose(): void;
|
|
194
|
+
get isPlaying(): boolean;
|
|
195
|
+
get masterVolume(): number;
|
|
196
|
+
get playbackRate(): number;
|
|
197
|
+
get duration(): number;
|
|
198
|
+
get sampleRate(): number;
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
/**
|
|
202
|
+
* Common interface for playout engines.
|
|
203
|
+
*
|
|
204
|
+
* Both TonePlayout and MediaElementPlayout implement this interface,
|
|
205
|
+
* allowing the browser package to work with either engine.
|
|
206
|
+
*/
|
|
207
|
+
interface PlayoutEngine {
|
|
208
|
+
init(): Promise<void>;
|
|
209
|
+
dispose(): void;
|
|
210
|
+
play(when?: number, offset?: number, duration?: number): void;
|
|
211
|
+
pause(): void;
|
|
212
|
+
stop(): void;
|
|
213
|
+
seekTo(time: number): void;
|
|
214
|
+
getCurrentTime(): number;
|
|
215
|
+
setMasterVolume(volume: number): void;
|
|
216
|
+
setMute?(trackId: string, muted: boolean): void;
|
|
217
|
+
setSolo?(trackId: string, soloed: boolean): void;
|
|
218
|
+
setOnPlaybackComplete(callback: () => void): void;
|
|
219
|
+
readonly isPlaying: boolean;
|
|
220
|
+
readonly duration: number;
|
|
221
|
+
readonly sampleRate: number;
|
|
222
|
+
}
|
|
223
|
+
/**
|
|
224
|
+
* Extended interface for engines that support playback rate.
|
|
225
|
+
*/
|
|
226
|
+
interface PlaybackRateEngine extends PlayoutEngine {
|
|
227
|
+
setPlaybackRate(rate: number): void;
|
|
228
|
+
readonly playbackRate: number;
|
|
229
|
+
}
|
|
230
|
+
/**
|
|
231
|
+
* Type guard to check if an engine supports playback rate.
|
|
232
|
+
*/
|
|
233
|
+
declare function supportsPlaybackRate(engine: PlayoutEngine): engine is PlaybackRateEngine;
|
|
234
|
+
|
|
235
|
+
export { MediaElementPlayout, type MediaElementPlayoutOptions, MediaElementTrack, type MediaElementTrackOptions, type PlaybackRateEngine, type PlayoutEngine, supportsPlaybackRate };
|