audio-channel-queue 1.11.0 → 1.12.1-beta.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/README.md +48 -25
- package/dist/core.js +6 -3
- package/dist/errors.d.ts +4 -4
- package/dist/errors.js +12 -51
- package/dist/index.d.ts +4 -3
- package/dist/index.js +19 -5
- package/dist/info.d.ts +20 -15
- package/dist/info.js +20 -15
- package/dist/types.d.ts +103 -24
- package/dist/types.js +17 -4
- package/dist/volume.d.ts +15 -14
- package/dist/volume.js +131 -33
- package/dist/web-audio.d.ts +156 -0
- package/dist/web-audio.js +327 -0
- package/package.json +1 -1
- package/src/core.ts +14 -4
- package/src/errors.ts +15 -64
- package/src/index.ts +31 -6
- package/src/info.ts +20 -15
- package/src/types.ts +107 -24
- package/src/volume.ts +158 -36
- package/src/web-audio.ts +331 -0
package/README.md
CHANGED
|
@@ -75,8 +75,8 @@ Install this package by running either of these commands (typescript packages ar
|
|
|
75
75
|
```typescript
|
|
76
76
|
// Add an audio file to the queue and start playing it automatically.
|
|
77
77
|
queueAudio(audioUrl, channelNumber?, options?);
|
|
78
|
-
queueAudio('hello.mp3'); // Add to default channel 0
|
|
79
|
-
queueAudio('laser.mp3', 1, { loop: true, volume: 0.8 }); // Add to channel 1 with options
|
|
78
|
+
await queueAudio('hello.mp3'); // Add to default channel 0
|
|
79
|
+
await queueAudio('laser.mp3', 1, { loop: true, volume: 0.8 }); // Add to channel 1 with options
|
|
80
80
|
```
|
|
81
81
|
|
|
82
82
|
|
|
@@ -84,8 +84,8 @@ queueAudio('laser.mp3', 1, { loop: true, volume: 0.8 }); // Add to channel 1 wit
|
|
|
84
84
|
```typescript
|
|
85
85
|
// Add a file to the front of the queue (plays after current audio finishes).
|
|
86
86
|
queueAudioPriority(audioUrl, channelNumber?, options?);
|
|
87
|
-
queueAudioPriority('urgent.mp3'); // Add to front of default channel 0
|
|
88
|
-
queueAudioPriority('announcement.mp3', 1, { volume: 1.0 }); // Add to front of channel 1
|
|
87
|
+
await queueAudioPriority('urgent.mp3'); // Add to front of default channel 0
|
|
88
|
+
await queueAudioPriority('announcement.mp3', 1, { volume: 1.0 }); // Add to front of channel 1
|
|
89
89
|
```
|
|
90
90
|
|
|
91
91
|
|
|
@@ -93,8 +93,8 @@ queueAudioPriority('announcement.mp3', 1, { volume: 1.0 }); // Add to front of c
|
|
|
93
93
|
```typescript
|
|
94
94
|
// Stop the current audio and automatically start playing the next one in queue.
|
|
95
95
|
stopCurrentAudioInChannel(channelNumber?);
|
|
96
|
-
stopCurrentAudioInChannel(); // Stop current audio in default channel (0)
|
|
97
|
-
stopCurrentAudioInChannel(2); // Stop current audio in channel 2
|
|
96
|
+
await stopCurrentAudioInChannel(); // Stop current audio in default channel (0)
|
|
97
|
+
await stopCurrentAudioInChannel(2); // Stop current audio in channel 2
|
|
98
98
|
```
|
|
99
99
|
|
|
100
100
|
|
|
@@ -102,14 +102,14 @@ stopCurrentAudioInChannel(2); // Stop current audio in channel 2
|
|
|
102
102
|
```typescript
|
|
103
103
|
// Stop all audio in a channel and remove all enqueued files.
|
|
104
104
|
stopAllAudioInChannel(channelNumber?);
|
|
105
|
-
stopAllAudioInChannel(); // Stop and clear all audio in default channel (0)
|
|
106
|
-
stopAllAudioInChannel(1); // Stop and clear all audio in channel 1
|
|
105
|
+
await stopAllAudioInChannel(); // Stop and clear all audio in default channel (0)
|
|
106
|
+
await stopAllAudioInChannel(1); // Stop and clear all audio in channel 1
|
|
107
107
|
```
|
|
108
108
|
|
|
109
109
|
### Stop All Audio
|
|
110
110
|
```typescript
|
|
111
111
|
// Stop all audio in all channels and remove all enqueued files.
|
|
112
|
-
stopAllAudio();
|
|
112
|
+
await stopAllAudio();
|
|
113
113
|
```
|
|
114
114
|
|
|
115
115
|
## 🔄 Advanced Queue Manipulation:
|
|
@@ -118,32 +118,32 @@ stopAllAudio();
|
|
|
118
118
|
```typescript
|
|
119
119
|
// Remove a specific item from the queue by its position (cannot remove currently playing item at index 0).
|
|
120
120
|
removeQueuedItem(queuedSlotNumber, channelNumber?);
|
|
121
|
-
const result = removeQueuedItem(2); // Remove item at index 2 from default channel (0)
|
|
122
|
-
const result = removeQueuedItem(1, 1); // Remove item at index 1 from channel 1
|
|
121
|
+
const result = await removeQueuedItem(2); // Remove item at index 2 from default channel (0)
|
|
122
|
+
const result = await removeQueuedItem(1, 1); // Remove item at index 1 from channel 1
|
|
123
123
|
```
|
|
124
124
|
|
|
125
125
|
### Reorder Queue Items
|
|
126
126
|
```typescript
|
|
127
127
|
// Move a queue item from one position to another (cannot move currently playing item at index 0).
|
|
128
128
|
reorderQueue(currentQueuedSlotNumber, newQueuedSlotNumber, channelNumber?);
|
|
129
|
-
const result = reorderQueue(3, 1); // Move item from index 3 to index 1 in default channel (0)
|
|
130
|
-
const result = reorderQueue(2, 4, 1); // Move item from index 2 to index 4 in channel 1
|
|
129
|
+
const result = await reorderQueue(3, 1); // Move item from index 3 to index 1 in default channel (0)
|
|
130
|
+
const result = await reorderQueue(2, 4, 1); // Move item from index 2 to index 4 in channel 1
|
|
131
131
|
```
|
|
132
132
|
|
|
133
133
|
### Clear Queue After Current
|
|
134
134
|
```typescript
|
|
135
135
|
// Remove all items from the queue except the currently playing audio.
|
|
136
136
|
clearQueueAfterCurrent(channelNumber?);
|
|
137
|
-
const result = clearQueueAfterCurrent(); // Clear queue after current in default channel (0)
|
|
138
|
-
const result = clearQueueAfterCurrent(2); // Clear queue after current in channel 2
|
|
137
|
+
const result = await clearQueueAfterCurrent(); // Clear queue after current in default channel (0)
|
|
138
|
+
const result = await clearQueueAfterCurrent(2); // Clear queue after current in channel 2
|
|
139
139
|
```
|
|
140
140
|
|
|
141
141
|
### Swap Queue Items
|
|
142
142
|
```typescript
|
|
143
143
|
// Swap the positions of two items in the queue (cannot involve currently playing item at index 0).
|
|
144
144
|
swapQueueItems(firstQueuedSlotNumber, secondQueuedSlotNumber, channelNumber?);
|
|
145
|
-
const result = swapQueueItems(1, 3); // Swap items at index 1 and 3 in default channel (0)
|
|
146
|
-
const result = swapQueueItems(2, 4, 1); // Swap items at index 2 and 4 in channel 1
|
|
145
|
+
const result = await swapQueueItems(1, 3); // Swap items at index 1 and 3 in default channel (0)
|
|
146
|
+
const result = await swapQueueItems(2, 4, 1); // Swap items at index 2 and 4 in channel 1
|
|
147
147
|
```
|
|
148
148
|
|
|
149
149
|
### Get Queue Item Info
|
|
@@ -177,8 +177,8 @@ interface QueueManipulationResult {
|
|
|
177
177
|
```typescript
|
|
178
178
|
// Set the volume for a specific channel (0-1 range).
|
|
179
179
|
setChannelVolume(channelNumber, volume);
|
|
180
|
-
setChannelVolume(0, 0.5); // Set channel 0 to 50% volume
|
|
181
|
-
setChannelVolume(1, 0.8); // Set channel 1 to 80% volume
|
|
180
|
+
await setChannelVolume(0, 0.5); // Set channel 0 to 50% volume
|
|
181
|
+
await setChannelVolume(1, 0.8); // Set channel 1 to 80% volume
|
|
182
182
|
```
|
|
183
183
|
|
|
184
184
|
### Get Channel Volume
|
|
@@ -193,8 +193,8 @@ console.log(`Channel volume: ${(getChannelVolume(2) * 100).toFixed(0)}%`); // Ge
|
|
|
193
193
|
```typescript
|
|
194
194
|
// Set the same volume level for all channels.
|
|
195
195
|
setAllChannelsVolume(volume);
|
|
196
|
-
setAllChannelsVolume(0.6); // Set all channels to 60% volume
|
|
197
|
-
setAllChannelsVolume(0.0); // Mute all channels
|
|
196
|
+
await setAllChannelsVolume(0.6); // Set all channels to 60% volume
|
|
197
|
+
await setAllChannelsVolume(0.0); // Mute all channels
|
|
198
198
|
```
|
|
199
199
|
|
|
200
200
|
### Volume Ducking (Background Audio Reduction)
|
|
@@ -356,6 +356,13 @@ onQueueChange(channelNumber, callback);
|
|
|
356
356
|
onQueueChange(0, (snapshot) => updateQueueDisplay(snapshot)); // Update UI on queue changes
|
|
357
357
|
```
|
|
358
358
|
|
|
359
|
+
```typescript
|
|
360
|
+
// Unsubscribe from queue change events (removes ALL queue change callbacks for the channel)
|
|
361
|
+
offQueueChange(channelNumber?);
|
|
362
|
+
offQueueChange(); // Stop receiving all queue change notifications for default channel (0)
|
|
363
|
+
offQueueChange(1); // Stop receiving all queue change notifications for channel 1
|
|
364
|
+
```
|
|
365
|
+
|
|
359
366
|
```typescript
|
|
360
367
|
// Subscribe to audio start events.
|
|
361
368
|
onAudioStart(channelNumber, callback);
|
|
@@ -364,8 +371,9 @@ onAudioStart(0, (info) => console.log(`Started: ${info.fileName}`)); // Log audi
|
|
|
364
371
|
|
|
365
372
|
```typescript
|
|
366
373
|
// Unsubscribe from audio start events (removes ALL start callbacks for the channel)
|
|
367
|
-
offAudioStart(channelNumber);
|
|
368
|
-
offAudioStart(
|
|
374
|
+
offAudioStart(channelNumber?);
|
|
375
|
+
offAudioStart(); // Stop receiving all start notifications for default channel (0)
|
|
376
|
+
offAudioStart(1); // Stop receiving all start notifications for channel 1
|
|
369
377
|
```
|
|
370
378
|
|
|
371
379
|
```typescript
|
|
@@ -376,8 +384,9 @@ onAudioComplete(0, (info) => logPlayHistory(info)); // Track completed audio
|
|
|
376
384
|
|
|
377
385
|
```typescript
|
|
378
386
|
// Unsubscribe from audio completion events (removes ALL complete callbacks for the channel)
|
|
379
|
-
offAudioComplete(channelNumber);
|
|
380
|
-
offAudioComplete(
|
|
387
|
+
offAudioComplete(channelNumber?);
|
|
388
|
+
offAudioComplete(); // Stop receiving all completion notifications for default channel (0)
|
|
389
|
+
offAudioComplete(1); // Stop receiving all completion notifications for channel 1
|
|
381
390
|
```
|
|
382
391
|
|
|
383
392
|
```typescript
|
|
@@ -386,12 +395,26 @@ onAudioPause(channelNumber, callback);
|
|
|
386
395
|
onAudioPause(0, (info) => showPauseIcon(info)); // Show pause state in UI
|
|
387
396
|
```
|
|
388
397
|
|
|
398
|
+
```typescript
|
|
399
|
+
// Unsubscribe from audio pause events (removes ALL pause callbacks for the channel)
|
|
400
|
+
offAudioPause(channelNumber?);
|
|
401
|
+
offAudioPause(); // Stop receiving all pause notifications for default channel (0)
|
|
402
|
+
offAudioPause(1); // Stop receiving all pause notifications for channel 1
|
|
403
|
+
```
|
|
404
|
+
|
|
389
405
|
```typescript
|
|
390
406
|
// Subscribe to audio resume events.
|
|
391
407
|
onAudioResume(channelNumber, callback);
|
|
392
408
|
onAudioResume(0, (info) => showPlayIcon(info)); // Show play state in UI
|
|
393
409
|
```
|
|
394
410
|
|
|
411
|
+
```typescript
|
|
412
|
+
// Unsubscribe from audio resume events (removes ALL resume callbacks for the channel)
|
|
413
|
+
offAudioResume(channelNumber?);
|
|
414
|
+
offAudioResume(); // Stop receiving all resume notifications for default channel (0)
|
|
415
|
+
offAudioResume(1); // Stop receiving all resume notifications for channel 1
|
|
416
|
+
```
|
|
417
|
+
|
|
395
418
|
### TypeScript Support
|
|
396
419
|
If you cannot import audio files into your app, you may need a `custom.d.ts` file in the root directory. An example of one is shown here:
|
|
397
420
|
|
package/dist/core.js
CHANGED
|
@@ -244,6 +244,8 @@ const queueAudio = (audioUrl_1, ...args_1) => __awaiter(void 0, [audioUrl_1, ...
|
|
|
244
244
|
(0, errors_1.setupAudioErrorHandling)(audio, channelNumber, validatedUrl, (error) => __awaiter(void 0, void 0, void 0, function* () {
|
|
245
245
|
yield (0, errors_1.handleAudioError)(audio, channelNumber, validatedUrl, error);
|
|
246
246
|
}));
|
|
247
|
+
// Initialize Web Audio API support if needed
|
|
248
|
+
yield (0, volume_1.initializeWebAudioForAudio)(audio, channelNumber);
|
|
247
249
|
// Apply options if provided
|
|
248
250
|
if (options) {
|
|
249
251
|
if (typeof options.loop === 'boolean') {
|
|
@@ -260,9 +262,9 @@ const queueAudio = (audioUrl_1, ...args_1) => __awaiter(void 0, [audioUrl_1, ...
|
|
|
260
262
|
channel.maxQueueSize = options.maxQueueSize;
|
|
261
263
|
}
|
|
262
264
|
}
|
|
263
|
-
// Handle
|
|
264
|
-
const shouldAddToFront =
|
|
265
|
-
// Add to queue based on
|
|
265
|
+
// Handle addToFront option
|
|
266
|
+
const shouldAddToFront = options === null || options === void 0 ? void 0 : options.addToFront;
|
|
267
|
+
// Add to queue based on addToFront option
|
|
266
268
|
if (shouldAddToFront && channel.queue.length > 0) {
|
|
267
269
|
// Insert after currently playing track (at index 1)
|
|
268
270
|
channel.queue.splice(1, 0, audio);
|
|
@@ -378,6 +380,7 @@ const playAudioQueue = (channelNumber) => __awaiter(void 0, void 0, void 0, func
|
|
|
378
380
|
// For non-looping audio, remove from queue and play next
|
|
379
381
|
currentAudio.pause();
|
|
380
382
|
(0, events_1.cleanupProgressTracking)(currentAudio, channelNumber, info_1.audioChannels);
|
|
383
|
+
(0, volume_1.cleanupWebAudioForAudio)(currentAudio, channelNumber);
|
|
381
384
|
channel.queue.shift();
|
|
382
385
|
channel.isPaused = false; // Reset pause state
|
|
383
386
|
// Restore volume levels AFTER removing audio from queue
|
package/dist/errors.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* @fileoverview Error handling, retry logic, and recovery mechanisms for the audio-channel-queue package
|
|
3
3
|
*/
|
|
4
|
-
import { AudioErrorInfo, AudioErrorCallback, RetryConfig, ErrorRecoveryOptions, ExtendedAudioQueueChannel } from './types';
|
|
4
|
+
import { AudioErrorInfo, AudioErrorCallback, AudioErrorType, RetryConfig, ErrorRecoveryOptions, ExtendedAudioQueueChannel } from './types';
|
|
5
5
|
/**
|
|
6
6
|
* Subscribes to audio error events for a specific channel
|
|
7
7
|
* @param channelNumber - The channel number to listen to (defaults to 0)
|
|
@@ -61,10 +61,10 @@ export declare const getRetryConfig: () => RetryConfig;
|
|
|
61
61
|
* ```typescript
|
|
62
62
|
* setErrorRecovery({
|
|
63
63
|
* autoRetry: true,
|
|
64
|
-
*
|
|
64
|
+
* fallbackToNextTrack: true,
|
|
65
65
|
* logErrorsToAnalytics: true,
|
|
66
66
|
* preserveQueueOnError: true,
|
|
67
|
-
*
|
|
67
|
+
* showUserFeedback: true
|
|
68
68
|
* });
|
|
69
69
|
* ```
|
|
70
70
|
*/
|
|
@@ -109,7 +109,7 @@ export declare const emitAudioError: (channelNumber: number, errorInfo: AudioErr
|
|
|
109
109
|
* @returns The categorized error type
|
|
110
110
|
* @internal
|
|
111
111
|
*/
|
|
112
|
-
export declare const categorizeError: (error: Error, audio: HTMLAudioElement) =>
|
|
112
|
+
export declare const categorizeError: (error: Error, audio: HTMLAudioElement) => AudioErrorType;
|
|
113
113
|
/**
|
|
114
114
|
* Sets up comprehensive error handling for an audio element
|
|
115
115
|
* @param audio - The audio element to set up error handling for
|
package/dist/errors.js
CHANGED
|
@@ -43,6 +43,7 @@ let globalRetryConfig = {
|
|
|
43
43
|
baseDelay: 1000,
|
|
44
44
|
enabled: true,
|
|
45
45
|
exponentialBackoff: true,
|
|
46
|
+
fallbackUrls: [],
|
|
46
47
|
maxRetries: 3,
|
|
47
48
|
skipOnFailure: false,
|
|
48
49
|
timeoutMs: 10000
|
|
@@ -55,7 +56,6 @@ let globalErrorRecovery = {
|
|
|
55
56
|
showUserFeedback: false
|
|
56
57
|
};
|
|
57
58
|
const retryAttempts = new WeakMap();
|
|
58
|
-
const loadTimeouts = new WeakMap();
|
|
59
59
|
/**
|
|
60
60
|
* Subscribes to audio error events for a specific channel
|
|
61
61
|
* @param channelNumber - The channel number to listen to (defaults to 0)
|
|
@@ -161,10 +161,10 @@ exports.getRetryConfig = getRetryConfig;
|
|
|
161
161
|
* ```typescript
|
|
162
162
|
* setErrorRecovery({
|
|
163
163
|
* autoRetry: true,
|
|
164
|
-
*
|
|
164
|
+
* fallbackToNextTrack: true,
|
|
165
165
|
* logErrorsToAnalytics: true,
|
|
166
166
|
* preserveQueueOnError: true,
|
|
167
|
-
*
|
|
167
|
+
* showUserFeedback: true
|
|
168
168
|
* });
|
|
169
169
|
* ```
|
|
170
170
|
*/
|
|
@@ -263,34 +263,34 @@ exports.emitAudioError = emitAudioError;
|
|
|
263
263
|
const categorizeError = (error, audio) => {
|
|
264
264
|
const errorMessage = error.message.toLowerCase();
|
|
265
265
|
if (errorMessage.includes('network') || errorMessage.includes('fetch')) {
|
|
266
|
-
return
|
|
266
|
+
return types_1.AudioErrorType.Network;
|
|
267
267
|
}
|
|
268
268
|
// Check for unsupported format first (more specific than decode)
|
|
269
269
|
if (errorMessage.includes('not supported') ||
|
|
270
270
|
errorMessage.includes('unsupported') ||
|
|
271
271
|
errorMessage.includes('format not supported')) {
|
|
272
|
-
return
|
|
272
|
+
return types_1.AudioErrorType.Unsupported;
|
|
273
273
|
}
|
|
274
274
|
if (errorMessage.includes('decode') || errorMessage.includes('format')) {
|
|
275
|
-
return
|
|
275
|
+
return types_1.AudioErrorType.Decode;
|
|
276
276
|
}
|
|
277
277
|
if (errorMessage.includes('permission') || errorMessage.includes('blocked')) {
|
|
278
|
-
return
|
|
278
|
+
return types_1.AudioErrorType.Permission;
|
|
279
279
|
}
|
|
280
280
|
if (errorMessage.includes('abort')) {
|
|
281
|
-
return
|
|
281
|
+
return types_1.AudioErrorType.Abort;
|
|
282
282
|
}
|
|
283
283
|
if (errorMessage.includes('timeout')) {
|
|
284
|
-
return
|
|
284
|
+
return types_1.AudioErrorType.Timeout;
|
|
285
285
|
}
|
|
286
286
|
// Check audio element network state for more context
|
|
287
287
|
if (audio.networkState === HTMLMediaElement.NETWORK_NO_SOURCE) {
|
|
288
|
-
return
|
|
288
|
+
return types_1.AudioErrorType.Network;
|
|
289
289
|
}
|
|
290
290
|
if (audio.networkState === HTMLMediaElement.NETWORK_LOADING) {
|
|
291
|
-
return
|
|
291
|
+
return types_1.AudioErrorType.Timeout;
|
|
292
292
|
}
|
|
293
|
-
return
|
|
293
|
+
return types_1.AudioErrorType.Unknown;
|
|
294
294
|
};
|
|
295
295
|
exports.categorizeError = categorizeError;
|
|
296
296
|
/**
|
|
@@ -305,37 +305,9 @@ const setupAudioErrorHandling = (audio, channelNumber, originalUrl, onError) =>
|
|
|
305
305
|
const channel = info_1.audioChannels[channelNumber];
|
|
306
306
|
if (!channel)
|
|
307
307
|
return;
|
|
308
|
-
// Set up loading timeout with test environment compatibility
|
|
309
|
-
let timeoutId;
|
|
310
|
-
if (typeof setTimeout !== 'undefined') {
|
|
311
|
-
timeoutId = setTimeout(() => {
|
|
312
|
-
if (audio.networkState === HTMLMediaElement.NETWORK_LOADING) {
|
|
313
|
-
const timeoutError = new Error(`Audio loading timeout after ${globalRetryConfig.timeoutMs}ms`);
|
|
314
|
-
(0, exports.handleAudioError)(audio, channelNumber, originalUrl, timeoutError);
|
|
315
|
-
}
|
|
316
|
-
}, globalRetryConfig.timeoutMs);
|
|
317
|
-
loadTimeouts.set(audio, timeoutId);
|
|
318
|
-
}
|
|
319
|
-
// Clear timeout when metadata loads successfully
|
|
320
|
-
const handleLoadSuccess = () => {
|
|
321
|
-
if (typeof setTimeout !== 'undefined') {
|
|
322
|
-
const timeoutId = loadTimeouts.get(audio);
|
|
323
|
-
if (timeoutId) {
|
|
324
|
-
clearTimeout(timeoutId);
|
|
325
|
-
loadTimeouts.delete(audio);
|
|
326
|
-
}
|
|
327
|
-
}
|
|
328
|
-
};
|
|
329
308
|
// Handle various error events
|
|
330
309
|
const handleError = (_event) => {
|
|
331
310
|
var _a;
|
|
332
|
-
if (typeof setTimeout !== 'undefined') {
|
|
333
|
-
const timeoutId = loadTimeouts.get(audio);
|
|
334
|
-
if (timeoutId) {
|
|
335
|
-
clearTimeout(timeoutId);
|
|
336
|
-
loadTimeouts.delete(audio);
|
|
337
|
-
}
|
|
338
|
-
}
|
|
339
311
|
const error = new Error(`Audio loading failed: ${((_a = audio.error) === null || _a === void 0 ? void 0 : _a.message) || 'Unknown error'}`);
|
|
340
312
|
(0, exports.handleAudioError)(audio, channelNumber, originalUrl, error);
|
|
341
313
|
};
|
|
@@ -351,8 +323,6 @@ const setupAudioErrorHandling = (audio, channelNumber, originalUrl, onError) =>
|
|
|
351
323
|
audio.addEventListener('error', handleError);
|
|
352
324
|
audio.addEventListener('abort', handleAbort);
|
|
353
325
|
audio.addEventListener('stalled', handleStall);
|
|
354
|
-
audio.addEventListener('loadedmetadata', handleLoadSuccess);
|
|
355
|
-
audio.addEventListener('canplay', handleLoadSuccess);
|
|
356
326
|
// Custom play error handling
|
|
357
327
|
if (onError) {
|
|
358
328
|
const originalPlay = audio.play.bind(audio);
|
|
@@ -450,19 +420,10 @@ exports.handleAudioError = handleAudioError;
|
|
|
450
420
|
const createProtectedAudioElement = (url, channelNumber) => __awaiter(void 0, void 0, void 0, function* () {
|
|
451
421
|
const audio = new Audio();
|
|
452
422
|
return new Promise((resolve, reject) => {
|
|
453
|
-
const cleanup = () => {
|
|
454
|
-
const timeoutId = loadTimeouts.get(audio);
|
|
455
|
-
if (timeoutId) {
|
|
456
|
-
clearTimeout(timeoutId);
|
|
457
|
-
loadTimeouts.delete(audio);
|
|
458
|
-
}
|
|
459
|
-
};
|
|
460
423
|
const handleSuccess = () => {
|
|
461
|
-
cleanup();
|
|
462
424
|
resolve(audio);
|
|
463
425
|
};
|
|
464
426
|
const handleError = (error) => {
|
|
465
|
-
cleanup();
|
|
466
427
|
reject(error);
|
|
467
428
|
};
|
|
468
429
|
// Set up error handling
|
package/dist/index.d.ts
CHANGED
|
@@ -7,9 +7,10 @@ export { queueAudio, queueAudioPriority, stopCurrentAudioInChannel, stopAllAudio
|
|
|
7
7
|
export { clearQueueAfterCurrent, getQueueItemInfo, getQueueLength, removeQueuedItem, reorderQueue, swapQueueItems } from './queue-manipulation';
|
|
8
8
|
export { getErrorRecovery, getRetryConfig, offAudioError, onAudioError, retryFailedAudio, setErrorRecovery, setRetryConfig } from './errors';
|
|
9
9
|
export { getAllChannelsPauseState, isChannelPaused, pauseAllChannels, pauseAllWithFade, pauseChannel, pauseWithFade, resumeAllChannels, resumeAllWithFade, resumeChannel, resumeWithFade, togglePauseAllChannels, togglePauseAllWithFade, togglePauseChannel, togglePauseWithFade } from './pause';
|
|
10
|
-
export {
|
|
10
|
+
export { cancelAllVolumeTransitions, cancelVolumeTransition, clearVolumeDucking, getAllChannelsVolume, getChannelVolume, getFadeConfig, setAllChannelsVolume, setChannelVolume, setVolumeDucking, transitionVolume } from './volume';
|
|
11
|
+
export { cleanupWebAudioNodes, createWebAudioNodes, getAudioContext, getWebAudioConfig, getWebAudioSupport, getWebAudioVolume, isIOSDevice, isWebAudioSupported, resumeAudioContext, setWebAudioConfig, setWebAudioVolume, shouldUseWebAudio } from './web-audio';
|
|
11
12
|
export { getAllChannelsInfo, getCurrentAudioInfo, getQueueSnapshot, offAudioComplete, offAudioPause, offAudioProgress, offAudioResume, offAudioStart, offQueueChange, onAudioComplete, onAudioPause, onAudioProgress, onAudioResume, onAudioStart, onQueueChange } from './info';
|
|
12
13
|
export { audioChannels } from './info';
|
|
13
14
|
export { cleanWebpackFilename, createQueueSnapshot, extractFileName, getAudioInfoFromElement, sanitizeForDisplay, validateAudioUrl } from './utils';
|
|
14
|
-
export type { AudioCompleteCallback, AudioCompleteInfo, AudioErrorCallback, AudioErrorInfo, AudioInfo, AudioPauseCallback, AudioQueueOptions, AudioResumeCallback, AudioStartCallback, AudioStartInfo, ChannelFadeState, ErrorRecoveryOptions, ExtendedAudioQueueChannel, FadeConfig, ProgressCallback, QueueChangeCallback, QueueItem, QueueManipulationResult, QueueSnapshot, RetryConfig, VolumeConfig,
|
|
15
|
-
export { EasingType, FadeType, MAX_CHANNELS, TimerType, GLOBAL_PROGRESS_KEY } from './types';
|
|
15
|
+
export type { AudioCompleteCallback, AudioCompleteInfo, AudioErrorCallback, AudioErrorInfo, AudioInfo, AudioPauseCallback, AudioQueueOptions, AudioResumeCallback, AudioStartCallback, AudioStartInfo, ChannelFadeState, ErrorRecoveryOptions, ExtendedAudioQueueChannel, FadeConfig, ProgressCallback, QueueChangeCallback, QueueConfig, QueueItem, QueueManipulationResult, QueueSnapshot, RetryConfig, VolumeConfig, WebAudioConfig, WebAudioNodeSet, WebAudioSupport } from './types';
|
|
16
|
+
export { AudioErrorType, EasingType, FadeType, MAX_CHANNELS, TimerType, GLOBAL_PROGRESS_KEY } from './types';
|
package/dist/index.js
CHANGED
|
@@ -5,8 +5,8 @@
|
|
|
5
5
|
* volume management with ducking, progress tracking, and comprehensive event system
|
|
6
6
|
*/
|
|
7
7
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
8
|
-
exports.
|
|
9
|
-
exports.GLOBAL_PROGRESS_KEY = exports.TimerType = exports.MAX_CHANNELS = exports.FadeType = exports.EasingType = exports.validateAudioUrl = exports.sanitizeForDisplay = exports.getAudioInfoFromElement = exports.extractFileName = exports.createQueueSnapshot = exports.cleanWebpackFilename = exports.audioChannels = exports.onQueueChange = exports.onAudioStart = exports.onAudioResume = exports.onAudioProgress = exports.onAudioPause = exports.onAudioComplete = exports.offQueueChange = exports.offAudioStart = exports.offAudioResume = exports.offAudioProgress = exports.offAudioPause = exports.offAudioComplete = exports.getQueueSnapshot = exports.getCurrentAudioInfo = void 0;
|
|
8
|
+
exports.createWebAudioNodes = exports.cleanupWebAudioNodes = exports.transitionVolume = exports.setVolumeDucking = exports.setChannelVolume = exports.setAllChannelsVolume = exports.getFadeConfig = exports.getChannelVolume = exports.getAllChannelsVolume = exports.clearVolumeDucking = exports.cancelVolumeTransition = exports.cancelAllVolumeTransitions = exports.togglePauseWithFade = exports.togglePauseChannel = exports.togglePauseAllWithFade = exports.togglePauseAllChannels = exports.resumeWithFade = exports.resumeChannel = exports.resumeAllWithFade = exports.resumeAllChannels = exports.pauseWithFade = exports.pauseChannel = exports.pauseAllWithFade = exports.pauseAllChannels = exports.isChannelPaused = exports.getAllChannelsPauseState = exports.setRetryConfig = exports.setErrorRecovery = exports.retryFailedAudio = exports.onAudioError = exports.offAudioError = exports.getRetryConfig = exports.getErrorRecovery = exports.swapQueueItems = exports.reorderQueue = exports.removeQueuedItem = exports.getQueueLength = exports.getQueueItemInfo = exports.clearQueueAfterCurrent = exports.setChannelQueueLimit = exports.getQueueConfig = exports.setQueueConfig = exports.destroyAllChannels = exports.destroyChannel = exports.playAudioQueue = exports.stopAllAudio = exports.stopAllAudioInChannel = exports.stopCurrentAudioInChannel = exports.queueAudioPriority = exports.queueAudio = void 0;
|
|
9
|
+
exports.GLOBAL_PROGRESS_KEY = exports.TimerType = exports.MAX_CHANNELS = exports.FadeType = exports.EasingType = exports.AudioErrorType = exports.validateAudioUrl = exports.sanitizeForDisplay = exports.getAudioInfoFromElement = exports.extractFileName = exports.createQueueSnapshot = exports.cleanWebpackFilename = exports.audioChannels = exports.onQueueChange = exports.onAudioStart = exports.onAudioResume = exports.onAudioProgress = exports.onAudioPause = exports.onAudioComplete = exports.offQueueChange = exports.offAudioStart = exports.offAudioResume = exports.offAudioProgress = exports.offAudioPause = exports.offAudioComplete = exports.getQueueSnapshot = exports.getCurrentAudioInfo = exports.getAllChannelsInfo = exports.shouldUseWebAudio = exports.setWebAudioVolume = exports.setWebAudioConfig = exports.resumeAudioContext = exports.isWebAudioSupported = exports.isIOSDevice = exports.getWebAudioVolume = exports.getWebAudioSupport = exports.getWebAudioConfig = exports.getAudioContext = void 0;
|
|
10
10
|
// Core queue management functions
|
|
11
11
|
var core_1 = require("./core");
|
|
12
12
|
Object.defineProperty(exports, "queueAudio", { enumerable: true, get: function () { return core_1.queueAudio; } });
|
|
@@ -55,8 +55,9 @@ Object.defineProperty(exports, "togglePauseChannel", { enumerable: true, get: fu
|
|
|
55
55
|
Object.defineProperty(exports, "togglePauseWithFade", { enumerable: true, get: function () { return pause_1.togglePauseWithFade; } });
|
|
56
56
|
// Volume control and ducking functions
|
|
57
57
|
var volume_1 = require("./volume");
|
|
58
|
+
Object.defineProperty(exports, "cancelAllVolumeTransitions", { enumerable: true, get: function () { return volume_1.cancelAllVolumeTransitions; } });
|
|
59
|
+
Object.defineProperty(exports, "cancelVolumeTransition", { enumerable: true, get: function () { return volume_1.cancelVolumeTransition; } });
|
|
58
60
|
Object.defineProperty(exports, "clearVolumeDucking", { enumerable: true, get: function () { return volume_1.clearVolumeDucking; } });
|
|
59
|
-
Object.defineProperty(exports, "fadeVolume", { enumerable: true, get: function () { return volume_1.fadeVolume; } });
|
|
60
61
|
Object.defineProperty(exports, "getAllChannelsVolume", { enumerable: true, get: function () { return volume_1.getAllChannelsVolume; } });
|
|
61
62
|
Object.defineProperty(exports, "getChannelVolume", { enumerable: true, get: function () { return volume_1.getChannelVolume; } });
|
|
62
63
|
Object.defineProperty(exports, "getFadeConfig", { enumerable: true, get: function () { return volume_1.getFadeConfig; } });
|
|
@@ -64,8 +65,20 @@ Object.defineProperty(exports, "setAllChannelsVolume", { enumerable: true, get:
|
|
|
64
65
|
Object.defineProperty(exports, "setChannelVolume", { enumerable: true, get: function () { return volume_1.setChannelVolume; } });
|
|
65
66
|
Object.defineProperty(exports, "setVolumeDucking", { enumerable: true, get: function () { return volume_1.setVolumeDucking; } });
|
|
66
67
|
Object.defineProperty(exports, "transitionVolume", { enumerable: true, get: function () { return volume_1.transitionVolume; } });
|
|
67
|
-
|
|
68
|
-
|
|
68
|
+
// Web Audio API support functions
|
|
69
|
+
var web_audio_1 = require("./web-audio");
|
|
70
|
+
Object.defineProperty(exports, "cleanupWebAudioNodes", { enumerable: true, get: function () { return web_audio_1.cleanupWebAudioNodes; } });
|
|
71
|
+
Object.defineProperty(exports, "createWebAudioNodes", { enumerable: true, get: function () { return web_audio_1.createWebAudioNodes; } });
|
|
72
|
+
Object.defineProperty(exports, "getAudioContext", { enumerable: true, get: function () { return web_audio_1.getAudioContext; } });
|
|
73
|
+
Object.defineProperty(exports, "getWebAudioConfig", { enumerable: true, get: function () { return web_audio_1.getWebAudioConfig; } });
|
|
74
|
+
Object.defineProperty(exports, "getWebAudioSupport", { enumerable: true, get: function () { return web_audio_1.getWebAudioSupport; } });
|
|
75
|
+
Object.defineProperty(exports, "getWebAudioVolume", { enumerable: true, get: function () { return web_audio_1.getWebAudioVolume; } });
|
|
76
|
+
Object.defineProperty(exports, "isIOSDevice", { enumerable: true, get: function () { return web_audio_1.isIOSDevice; } });
|
|
77
|
+
Object.defineProperty(exports, "isWebAudioSupported", { enumerable: true, get: function () { return web_audio_1.isWebAudioSupported; } });
|
|
78
|
+
Object.defineProperty(exports, "resumeAudioContext", { enumerable: true, get: function () { return web_audio_1.resumeAudioContext; } });
|
|
79
|
+
Object.defineProperty(exports, "setWebAudioConfig", { enumerable: true, get: function () { return web_audio_1.setWebAudioConfig; } });
|
|
80
|
+
Object.defineProperty(exports, "setWebAudioVolume", { enumerable: true, get: function () { return web_audio_1.setWebAudioVolume; } });
|
|
81
|
+
Object.defineProperty(exports, "shouldUseWebAudio", { enumerable: true, get: function () { return web_audio_1.shouldUseWebAudio; } });
|
|
69
82
|
// Audio information and progress tracking functions
|
|
70
83
|
var info_1 = require("./info");
|
|
71
84
|
Object.defineProperty(exports, "getAllChannelsInfo", { enumerable: true, get: function () { return info_1.getAllChannelsInfo; } });
|
|
@@ -96,6 +109,7 @@ Object.defineProperty(exports, "sanitizeForDisplay", { enumerable: true, get: fu
|
|
|
96
109
|
Object.defineProperty(exports, "validateAudioUrl", { enumerable: true, get: function () { return utils_1.validateAudioUrl; } });
|
|
97
110
|
// Enums and constants
|
|
98
111
|
var types_1 = require("./types");
|
|
112
|
+
Object.defineProperty(exports, "AudioErrorType", { enumerable: true, get: function () { return types_1.AudioErrorType; } });
|
|
99
113
|
Object.defineProperty(exports, "EasingType", { enumerable: true, get: function () { return types_1.EasingType; } });
|
|
100
114
|
Object.defineProperty(exports, "FadeType", { enumerable: true, get: function () { return types_1.FadeType; } });
|
|
101
115
|
Object.defineProperty(exports, "MAX_CHANNELS", { enumerable: true, get: function () { return types_1.MAX_CHANNELS; } });
|
package/dist/info.d.ts
CHANGED
|
@@ -116,13 +116,14 @@ export declare function offAudioProgress(channelNumber?: number): void;
|
|
|
116
116
|
export declare const onQueueChange: (channelNumber: number, callback: QueueChangeCallback) => void;
|
|
117
117
|
/**
|
|
118
118
|
* Removes queue change listeners for a specific channel
|
|
119
|
-
* @param channelNumber - The channel number
|
|
119
|
+
* @param channelNumber - The channel number (defaults to 0)
|
|
120
120
|
* @example
|
|
121
121
|
* ```typescript
|
|
122
|
-
* offQueueChange(
|
|
122
|
+
* offQueueChange(); // Stop receiving queue change notifications for default channel (0)
|
|
123
|
+
* offQueueChange(1); // Stop receiving queue change notifications for channel 1
|
|
123
124
|
* ```
|
|
124
125
|
*/
|
|
125
|
-
export declare const offQueueChange: (channelNumber
|
|
126
|
+
export declare const offQueueChange: (channelNumber?: number) => void;
|
|
126
127
|
/**
|
|
127
128
|
* Subscribes to audio start events for a specific channel
|
|
128
129
|
* @param channelNumber - The channel number to monitor
|
|
@@ -183,37 +184,41 @@ export declare const onAudioPause: (channelNumber: number, callback: AudioPauseC
|
|
|
183
184
|
export declare const onAudioResume: (channelNumber: number, callback: AudioResumeCallback) => void;
|
|
184
185
|
/**
|
|
185
186
|
* Removes pause event listeners for a specific channel
|
|
186
|
-
* @param channelNumber - The channel number
|
|
187
|
+
* @param channelNumber - The channel number (defaults to 0)
|
|
187
188
|
* @example
|
|
188
189
|
* ```typescript
|
|
189
|
-
* offAudioPause(
|
|
190
|
+
* offAudioPause(); // Stop receiving pause notifications for default channel (0)
|
|
191
|
+
* offAudioPause(1); // Stop receiving pause notifications for channel 1
|
|
190
192
|
* ```
|
|
191
193
|
*/
|
|
192
|
-
export declare const offAudioPause: (channelNumber
|
|
194
|
+
export declare const offAudioPause: (channelNumber?: number) => void;
|
|
193
195
|
/**
|
|
194
196
|
* Removes resume event listeners for a specific channel
|
|
195
|
-
* @param channelNumber - The channel number
|
|
197
|
+
* @param channelNumber - The channel number (defaults to 0)
|
|
196
198
|
* @example
|
|
197
199
|
* ```typescript
|
|
198
|
-
* offAudioResume(
|
|
200
|
+
* offAudioResume(); // Stop receiving resume notifications for default channel (0)
|
|
201
|
+
* offAudioResume(1); // Stop receiving resume notifications for channel 1
|
|
199
202
|
* ```
|
|
200
203
|
*/
|
|
201
|
-
export declare const offAudioResume: (channelNumber
|
|
204
|
+
export declare const offAudioResume: (channelNumber?: number) => void;
|
|
202
205
|
/**
|
|
203
206
|
* Removes audio start event listeners for a specific channel
|
|
204
|
-
* @param channelNumber - The channel number
|
|
207
|
+
* @param channelNumber - The channel number (defaults to 0)
|
|
205
208
|
* @example
|
|
206
209
|
* ```typescript
|
|
207
|
-
* offAudioStart(
|
|
210
|
+
* offAudioStart(); // Stop receiving start notifications for default channel (0)
|
|
211
|
+
* offAudioStart(1); // Stop receiving start notifications for channel 1
|
|
208
212
|
* ```
|
|
209
213
|
*/
|
|
210
|
-
export declare const offAudioStart: (channelNumber
|
|
214
|
+
export declare const offAudioStart: (channelNumber?: number) => void;
|
|
211
215
|
/**
|
|
212
216
|
* Removes audio complete event listeners for a specific channel
|
|
213
|
-
* @param channelNumber - The channel number
|
|
217
|
+
* @param channelNumber - The channel number (defaults to 0)
|
|
214
218
|
* @example
|
|
215
219
|
* ```typescript
|
|
216
|
-
* offAudioComplete(
|
|
220
|
+
* offAudioComplete(); // Stop receiving completion notifications for default channel (0)
|
|
221
|
+
* offAudioComplete(1); // Stop receiving completion notifications for channel 1
|
|
217
222
|
* ```
|
|
218
223
|
*/
|
|
219
|
-
export declare const offAudioComplete: (channelNumber
|
|
224
|
+
export declare const offAudioComplete: (channelNumber?: number) => void;
|
package/dist/info.js
CHANGED
|
@@ -301,13 +301,14 @@ const onQueueChange = (channelNumber, callback) => {
|
|
|
301
301
|
exports.onQueueChange = onQueueChange;
|
|
302
302
|
/**
|
|
303
303
|
* Removes queue change listeners for a specific channel
|
|
304
|
-
* @param channelNumber - The channel number
|
|
304
|
+
* @param channelNumber - The channel number (defaults to 0)
|
|
305
305
|
* @example
|
|
306
306
|
* ```typescript
|
|
307
|
-
* offQueueChange(
|
|
307
|
+
* offQueueChange(); // Stop receiving queue change notifications for default channel (0)
|
|
308
|
+
* offQueueChange(1); // Stop receiving queue change notifications for channel 1
|
|
308
309
|
* ```
|
|
309
310
|
*/
|
|
310
|
-
const offQueueChange = (channelNumber) => {
|
|
311
|
+
const offQueueChange = (channelNumber = 0) => {
|
|
311
312
|
const channel = exports.audioChannels[channelNumber];
|
|
312
313
|
if (!(channel === null || channel === void 0 ? void 0 : channel.queueChangeCallbacks))
|
|
313
314
|
return;
|
|
@@ -462,13 +463,14 @@ const onAudioResume = (channelNumber, callback) => {
|
|
|
462
463
|
exports.onAudioResume = onAudioResume;
|
|
463
464
|
/**
|
|
464
465
|
* Removes pause event listeners for a specific channel
|
|
465
|
-
* @param channelNumber - The channel number
|
|
466
|
+
* @param channelNumber - The channel number (defaults to 0)
|
|
466
467
|
* @example
|
|
467
468
|
* ```typescript
|
|
468
|
-
* offAudioPause(
|
|
469
|
+
* offAudioPause(); // Stop receiving pause notifications for default channel (0)
|
|
470
|
+
* offAudioPause(1); // Stop receiving pause notifications for channel 1
|
|
469
471
|
* ```
|
|
470
472
|
*/
|
|
471
|
-
const offAudioPause = (channelNumber) => {
|
|
473
|
+
const offAudioPause = (channelNumber = 0) => {
|
|
472
474
|
const channel = exports.audioChannels[channelNumber];
|
|
473
475
|
if (!(channel === null || channel === void 0 ? void 0 : channel.audioPauseCallbacks))
|
|
474
476
|
return;
|
|
@@ -477,13 +479,14 @@ const offAudioPause = (channelNumber) => {
|
|
|
477
479
|
exports.offAudioPause = offAudioPause;
|
|
478
480
|
/**
|
|
479
481
|
* Removes resume event listeners for a specific channel
|
|
480
|
-
* @param channelNumber - The channel number
|
|
482
|
+
* @param channelNumber - The channel number (defaults to 0)
|
|
481
483
|
* @example
|
|
482
484
|
* ```typescript
|
|
483
|
-
* offAudioResume(
|
|
485
|
+
* offAudioResume(); // Stop receiving resume notifications for default channel (0)
|
|
486
|
+
* offAudioResume(1); // Stop receiving resume notifications for channel 1
|
|
484
487
|
* ```
|
|
485
488
|
*/
|
|
486
|
-
const offAudioResume = (channelNumber) => {
|
|
489
|
+
const offAudioResume = (channelNumber = 0) => {
|
|
487
490
|
const channel = exports.audioChannels[channelNumber];
|
|
488
491
|
if (!(channel === null || channel === void 0 ? void 0 : channel.audioResumeCallbacks))
|
|
489
492
|
return;
|
|
@@ -492,13 +495,14 @@ const offAudioResume = (channelNumber) => {
|
|
|
492
495
|
exports.offAudioResume = offAudioResume;
|
|
493
496
|
/**
|
|
494
497
|
* Removes audio start event listeners for a specific channel
|
|
495
|
-
* @param channelNumber - The channel number
|
|
498
|
+
* @param channelNumber - The channel number (defaults to 0)
|
|
496
499
|
* @example
|
|
497
500
|
* ```typescript
|
|
498
|
-
* offAudioStart(
|
|
501
|
+
* offAudioStart(); // Stop receiving start notifications for default channel (0)
|
|
502
|
+
* offAudioStart(1); // Stop receiving start notifications for channel 1
|
|
499
503
|
* ```
|
|
500
504
|
*/
|
|
501
|
-
const offAudioStart = (channelNumber) => {
|
|
505
|
+
const offAudioStart = (channelNumber = 0) => {
|
|
502
506
|
const channel = exports.audioChannels[channelNumber];
|
|
503
507
|
if (!(channel === null || channel === void 0 ? void 0 : channel.audioStartCallbacks))
|
|
504
508
|
return;
|
|
@@ -507,13 +511,14 @@ const offAudioStart = (channelNumber) => {
|
|
|
507
511
|
exports.offAudioStart = offAudioStart;
|
|
508
512
|
/**
|
|
509
513
|
* Removes audio complete event listeners for a specific channel
|
|
510
|
-
* @param channelNumber - The channel number
|
|
514
|
+
* @param channelNumber - The channel number (defaults to 0)
|
|
511
515
|
* @example
|
|
512
516
|
* ```typescript
|
|
513
|
-
* offAudioComplete(
|
|
517
|
+
* offAudioComplete(); // Stop receiving completion notifications for default channel (0)
|
|
518
|
+
* offAudioComplete(1); // Stop receiving completion notifications for channel 1
|
|
514
519
|
* ```
|
|
515
520
|
*/
|
|
516
|
-
const offAudioComplete = (channelNumber) => {
|
|
521
|
+
const offAudioComplete = (channelNumber = 0) => {
|
|
517
522
|
const channel = exports.audioChannels[channelNumber];
|
|
518
523
|
if (!(channel === null || channel === void 0 ? void 0 : channel.audioCompleteCallbacks))
|
|
519
524
|
return;
|