audio-channel-queue 1.9.0 → 1.11.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 +207 -311
- package/dist/core.d.ts +61 -3
- package/dist/core.js +344 -50
- package/dist/errors.d.ts +1 -0
- package/dist/errors.js +10 -1
- package/dist/index.d.ts +7 -6
- package/dist/index.js +23 -2
- package/dist/info.d.ts +58 -6
- package/dist/info.js +172 -10
- package/dist/pause.js +1 -1
- package/dist/queue-manipulation.d.ts +104 -0
- package/dist/queue-manipulation.js +319 -0
- package/dist/types.d.ts +46 -8
- package/dist/types.js +13 -1
- package/dist/utils.d.ts +25 -0
- package/dist/utils.js +98 -10
- package/dist/volume.d.ts +14 -1
- package/dist/volume.js +173 -54
- package/package.json +12 -2
- package/src/core.ts +403 -60
- package/src/errors.ts +14 -2
- package/src/index.ts +28 -5
- package/src/info.ts +204 -9
- package/src/pause.ts +4 -6
- package/src/queue-manipulation.ts +378 -0
- package/src/types.ts +51 -9
- package/src/utils.ts +110 -9
- package/src/volume.ts +214 -62
package/src/index.ts
CHANGED
|
@@ -11,9 +11,24 @@ export {
|
|
|
11
11
|
stopCurrentAudioInChannel,
|
|
12
12
|
stopAllAudioInChannel,
|
|
13
13
|
stopAllAudio,
|
|
14
|
-
playAudioQueue
|
|
14
|
+
playAudioQueue,
|
|
15
|
+
destroyChannel,
|
|
16
|
+
destroyAllChannels,
|
|
17
|
+
setQueueConfig,
|
|
18
|
+
getQueueConfig,
|
|
19
|
+
setChannelQueueLimit
|
|
15
20
|
} from './core';
|
|
16
21
|
|
|
22
|
+
// Queue manipulation functions
|
|
23
|
+
export {
|
|
24
|
+
clearQueueAfterCurrent,
|
|
25
|
+
getQueueItemInfo,
|
|
26
|
+
getQueueLength,
|
|
27
|
+
removeQueuedItem,
|
|
28
|
+
reorderQueue,
|
|
29
|
+
swapQueueItems
|
|
30
|
+
} from './queue-manipulation';
|
|
31
|
+
|
|
17
32
|
// Error handling and recovery functions
|
|
18
33
|
export {
|
|
19
34
|
getErrorRecovery,
|
|
@@ -53,7 +68,9 @@ export {
|
|
|
53
68
|
setAllChannelsVolume,
|
|
54
69
|
setChannelVolume,
|
|
55
70
|
setVolumeDucking,
|
|
56
|
-
transitionVolume
|
|
71
|
+
transitionVolume,
|
|
72
|
+
cancelVolumeTransition,
|
|
73
|
+
cancelAllVolumeTransitions
|
|
57
74
|
} from './volume';
|
|
58
75
|
|
|
59
76
|
// Audio information and progress tracking functions
|
|
@@ -61,9 +78,11 @@ export {
|
|
|
61
78
|
getAllChannelsInfo,
|
|
62
79
|
getCurrentAudioInfo,
|
|
63
80
|
getQueueSnapshot,
|
|
81
|
+
offAudioComplete,
|
|
64
82
|
offAudioPause,
|
|
65
83
|
offAudioProgress,
|
|
66
84
|
offAudioResume,
|
|
85
|
+
offAudioStart,
|
|
67
86
|
offQueueChange,
|
|
68
87
|
onAudioComplete,
|
|
69
88
|
onAudioPause,
|
|
@@ -81,7 +100,9 @@ export {
|
|
|
81
100
|
cleanWebpackFilename,
|
|
82
101
|
createQueueSnapshot,
|
|
83
102
|
extractFileName,
|
|
84
|
-
getAudioInfoFromElement
|
|
103
|
+
getAudioInfoFromElement,
|
|
104
|
+
sanitizeForDisplay,
|
|
105
|
+
validateAudioUrl
|
|
85
106
|
} from './utils';
|
|
86
107
|
|
|
87
108
|
// TypeScript type definitions and interfaces
|
|
@@ -103,10 +124,12 @@ export type {
|
|
|
103
124
|
ProgressCallback,
|
|
104
125
|
QueueChangeCallback,
|
|
105
126
|
QueueItem,
|
|
127
|
+
QueueManipulationResult,
|
|
106
128
|
QueueSnapshot,
|
|
107
129
|
RetryConfig,
|
|
108
|
-
VolumeConfig
|
|
130
|
+
VolumeConfig,
|
|
131
|
+
QueueConfig
|
|
109
132
|
} from './types';
|
|
110
133
|
|
|
111
134
|
// Enums and constants
|
|
112
|
-
export { EasingType, FadeType, GLOBAL_PROGRESS_KEY } from './types';
|
|
135
|
+
export { EasingType, FadeType, MAX_CHANNELS, TimerType, GLOBAL_PROGRESS_KEY } from './types';
|
package/src/info.ts
CHANGED
|
@@ -12,16 +12,161 @@ import {
|
|
|
12
12
|
AudioPauseCallback,
|
|
13
13
|
AudioResumeCallback,
|
|
14
14
|
ExtendedAudioQueueChannel,
|
|
15
|
-
GLOBAL_PROGRESS_KEY
|
|
15
|
+
GLOBAL_PROGRESS_KEY,
|
|
16
|
+
MAX_CHANNELS
|
|
16
17
|
} from './types';
|
|
17
18
|
import { getAudioInfoFromElement, createQueueSnapshot } from './utils';
|
|
18
19
|
import { setupProgressTracking, cleanupProgressTracking } from './events';
|
|
19
20
|
|
|
21
|
+
/**
|
|
22
|
+
* Gets the current list of whitelisted channel properties
|
|
23
|
+
* This is automatically derived from the ExtendedAudioQueueChannel interface
|
|
24
|
+
* @returns Array of whitelisted property names
|
|
25
|
+
* @internal
|
|
26
|
+
*/
|
|
27
|
+
export const getWhitelistedChannelProperties = (): string[] => {
|
|
28
|
+
// Create a sample channel object to extract property names
|
|
29
|
+
const sampleChannel: ExtendedAudioQueueChannel = {
|
|
30
|
+
audioCompleteCallbacks: new Set(),
|
|
31
|
+
audioErrorCallbacks: new Set(),
|
|
32
|
+
audioPauseCallbacks: new Set(),
|
|
33
|
+
audioResumeCallbacks: new Set(),
|
|
34
|
+
audioStartCallbacks: new Set(),
|
|
35
|
+
isPaused: false,
|
|
36
|
+
progressCallbacks: new Map(),
|
|
37
|
+
queue: [],
|
|
38
|
+
queueChangeCallbacks: new Set(),
|
|
39
|
+
volume: 1.0
|
|
40
|
+
};
|
|
41
|
+
|
|
42
|
+
// Get all property names from the interface (including optional ones)
|
|
43
|
+
const propertyNames = [
|
|
44
|
+
...Object.getOwnPropertyNames(sampleChannel),
|
|
45
|
+
// Add optional properties that might not be present on the sample
|
|
46
|
+
'fadeState',
|
|
47
|
+
'isLocked',
|
|
48
|
+
'maxQueueSize',
|
|
49
|
+
'retryConfig',
|
|
50
|
+
'volumeConfig' // Legacy property that might still be used
|
|
51
|
+
];
|
|
52
|
+
|
|
53
|
+
return [...new Set(propertyNames)]; // Remove duplicates
|
|
54
|
+
};
|
|
55
|
+
|
|
56
|
+
/**
|
|
57
|
+
* Returns the list of non-whitelisted properties found on a specific channel
|
|
58
|
+
* These are properties that will trigger warnings when modified directly
|
|
59
|
+
* @param channelNumber - The channel number to inspect (defaults to 0)
|
|
60
|
+
* @returns Array of property names that are not in the whitelist, or empty array if channel doesn't exist
|
|
61
|
+
* @example
|
|
62
|
+
* ```typescript
|
|
63
|
+
* // Add some custom property to a channel
|
|
64
|
+
* (audioChannels[0] as any).customProperty = 'test';
|
|
65
|
+
*
|
|
66
|
+
* const nonWhitelisted = getNonWhitelistedChannelProperties(0);
|
|
67
|
+
* console.log(nonWhitelisted); // ['customProperty']
|
|
68
|
+
* ```
|
|
69
|
+
* @internal
|
|
70
|
+
*/
|
|
71
|
+
export const getNonWhitelistedChannelProperties = (channelNumber: number = 0): string[] => {
|
|
72
|
+
const channel: ExtendedAudioQueueChannel = audioChannels[channelNumber];
|
|
73
|
+
if (!channel) {
|
|
74
|
+
return [];
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
const whitelistedProperties: string[] = getWhitelistedChannelProperties();
|
|
78
|
+
const allChannelProperties: string[] = Object.getOwnPropertyNames(channel);
|
|
79
|
+
|
|
80
|
+
// Filter out properties that are in the whitelist
|
|
81
|
+
const nonWhitelistedProperties: string[] = allChannelProperties.filter(
|
|
82
|
+
(property: string) => !whitelistedProperties.includes(property)
|
|
83
|
+
);
|
|
84
|
+
|
|
85
|
+
return nonWhitelistedProperties;
|
|
86
|
+
};
|
|
87
|
+
|
|
20
88
|
/**
|
|
21
89
|
* Global array to store audio channels with their queues and callback management
|
|
22
90
|
* Each channel maintains its own audio queue and event callback sets
|
|
91
|
+
*
|
|
92
|
+
* Note: While you can inspect this array for debugging, direct modification is discouraged.
|
|
93
|
+
* Use the provided API functions for safe channel management.
|
|
94
|
+
*/
|
|
95
|
+
export const audioChannels: ExtendedAudioQueueChannel[] = new Proxy(
|
|
96
|
+
[] as ExtendedAudioQueueChannel[],
|
|
97
|
+
{
|
|
98
|
+
deleteProperty(target: ExtendedAudioQueueChannel[], prop: string | symbol): boolean {
|
|
99
|
+
if (typeof prop === 'string' && !isNaN(Number(prop))) {
|
|
100
|
+
// eslint-disable-next-line no-console
|
|
101
|
+
console.warn(
|
|
102
|
+
'Warning: Direct deletion from audioChannels detected. ' +
|
|
103
|
+
'Consider using stopAllAudioInChannel() for proper cleanup.'
|
|
104
|
+
);
|
|
105
|
+
}
|
|
106
|
+
delete (target as unknown as Record<string, unknown>)[prop as string];
|
|
107
|
+
return true;
|
|
108
|
+
},
|
|
109
|
+
get(target: ExtendedAudioQueueChannel[], prop: string | symbol): unknown {
|
|
110
|
+
const value = (target as unknown as Record<string, unknown>)[prop as string];
|
|
111
|
+
|
|
112
|
+
// Return channel objects with warnings on modification attempts
|
|
113
|
+
if (
|
|
114
|
+
typeof value === 'object' &&
|
|
115
|
+
value !== null &&
|
|
116
|
+
typeof prop === 'string' &&
|
|
117
|
+
!isNaN(Number(prop))
|
|
118
|
+
) {
|
|
119
|
+
return new Proxy(value as ExtendedAudioQueueChannel, {
|
|
120
|
+
set(
|
|
121
|
+
channelTarget: ExtendedAudioQueueChannel,
|
|
122
|
+
channelProp: string | symbol,
|
|
123
|
+
channelValue: unknown
|
|
124
|
+
): boolean {
|
|
125
|
+
// Allow internal modifications but warn about direct property changes
|
|
126
|
+
// Use the automatically-derived whitelist from the interface
|
|
127
|
+
const whitelistedProperties = getWhitelistedChannelProperties();
|
|
128
|
+
|
|
129
|
+
if (typeof channelProp === 'string' && !whitelistedProperties.includes(channelProp)) {
|
|
130
|
+
// eslint-disable-next-line no-console
|
|
131
|
+
console.warn(
|
|
132
|
+
`Warning: Direct modification of channel.${channelProp} detected. ` +
|
|
133
|
+
'Use API functions for safer channel management.'
|
|
134
|
+
);
|
|
135
|
+
}
|
|
136
|
+
const key = typeof channelProp === 'symbol' ? channelProp.toString() : channelProp;
|
|
137
|
+
(channelTarget as unknown as Record<string, unknown>)[key] = channelValue;
|
|
138
|
+
return true;
|
|
139
|
+
}
|
|
140
|
+
});
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
return value;
|
|
144
|
+
},
|
|
145
|
+
set(target: ExtendedAudioQueueChannel[], prop: string | symbol, value: unknown): boolean {
|
|
146
|
+
// Allow normal array operations
|
|
147
|
+
const key = typeof prop === 'symbol' ? prop.toString() : prop;
|
|
148
|
+
(target as unknown as Record<string, unknown>)[key] = value;
|
|
149
|
+
return true;
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
);
|
|
153
|
+
|
|
154
|
+
/**
|
|
155
|
+
* Validates a channel number against MAX_CHANNELS limit
|
|
156
|
+
* @param channelNumber - The channel number to validate
|
|
157
|
+
* @throws Error if the channel number is invalid
|
|
158
|
+
* @internal
|
|
23
159
|
*/
|
|
24
|
-
|
|
160
|
+
const validateChannelNumber = (channelNumber: number): void => {
|
|
161
|
+
if (channelNumber < 0) {
|
|
162
|
+
throw new Error('Channel number must be non-negative');
|
|
163
|
+
}
|
|
164
|
+
if (channelNumber >= MAX_CHANNELS) {
|
|
165
|
+
throw new Error(
|
|
166
|
+
`Channel number ${channelNumber} exceeds maximum allowed channels (${MAX_CHANNELS})`
|
|
167
|
+
);
|
|
168
|
+
}
|
|
169
|
+
};
|
|
25
170
|
|
|
26
171
|
/**
|
|
27
172
|
* Gets current audio information for a specific channel
|
|
@@ -71,18 +216,19 @@ export const getAllChannelsInfo = (): (AudioInfo | null)[] => {
|
|
|
71
216
|
|
|
72
217
|
/**
|
|
73
218
|
* Gets a complete snapshot of the queue state for a specific channel
|
|
74
|
-
* @param channelNumber - The channel number
|
|
219
|
+
* @param channelNumber - The channel number (defaults to 0)
|
|
75
220
|
* @returns QueueSnapshot object or null if channel doesn't exist
|
|
76
221
|
* @example
|
|
77
222
|
* ```typescript
|
|
78
|
-
* const snapshot = getQueueSnapshot(
|
|
223
|
+
* const snapshot = getQueueSnapshot();
|
|
79
224
|
* if (snapshot) {
|
|
80
225
|
* console.log(`Queue has ${snapshot.totalItems} items`);
|
|
81
226
|
* console.log(`Currently playing: ${snapshot.items[0]?.fileName}`);
|
|
82
227
|
* }
|
|
228
|
+
* const channelSnapshot = getQueueSnapshot(2);
|
|
83
229
|
* ```
|
|
84
230
|
*/
|
|
85
|
-
export const getQueueSnapshot = (channelNumber: number): QueueSnapshot | null => {
|
|
231
|
+
export const getQueueSnapshot = (channelNumber: number = 0): QueueSnapshot | null => {
|
|
86
232
|
return createQueueSnapshot(channelNumber, audioChannels);
|
|
87
233
|
};
|
|
88
234
|
|
|
@@ -90,6 +236,7 @@ export const getQueueSnapshot = (channelNumber: number): QueueSnapshot | null =>
|
|
|
90
236
|
* Subscribes to real-time progress updates for a specific channel
|
|
91
237
|
* @param channelNumber - The channel number
|
|
92
238
|
* @param callback - Function to call with audio info updates
|
|
239
|
+
* @throws Error if the channel number exceeds the maximum allowed channels
|
|
93
240
|
* @example
|
|
94
241
|
* ```typescript
|
|
95
242
|
* onAudioProgress(0, (info) => {
|
|
@@ -99,6 +246,8 @@ export const getQueueSnapshot = (channelNumber: number): QueueSnapshot | null =>
|
|
|
99
246
|
* ```
|
|
100
247
|
*/
|
|
101
248
|
export const onAudioProgress = (channelNumber: number, callback: ProgressCallback): void => {
|
|
249
|
+
validateChannelNumber(channelNumber);
|
|
250
|
+
|
|
102
251
|
if (!audioChannels[channelNumber]) {
|
|
103
252
|
audioChannels[channelNumber] = {
|
|
104
253
|
audioCompleteCallbacks: new Set(),
|
|
@@ -140,13 +289,14 @@ export const onAudioProgress = (channelNumber: number, callback: ProgressCallbac
|
|
|
140
289
|
|
|
141
290
|
/**
|
|
142
291
|
* Removes progress listeners for a specific channel
|
|
143
|
-
* @param channelNumber - The channel number
|
|
292
|
+
* @param channelNumber - The channel number (defaults to 0)
|
|
144
293
|
* @example
|
|
145
294
|
* ```typescript
|
|
146
|
-
* offAudioProgress(
|
|
295
|
+
* offAudioProgress();
|
|
296
|
+
* offAudioProgress(1); // Stop receiving progress updates for channel 1
|
|
147
297
|
* ```
|
|
148
298
|
*/
|
|
149
|
-
export
|
|
299
|
+
export function offAudioProgress(channelNumber: number = 0): void {
|
|
150
300
|
const channel: ExtendedAudioQueueChannel = audioChannels[channelNumber];
|
|
151
301
|
if (!channel?.progressCallbacks) return;
|
|
152
302
|
|
|
@@ -158,12 +308,13 @@ export const offAudioProgress = (channelNumber: number): void => {
|
|
|
158
308
|
|
|
159
309
|
// Clear all callbacks for this channel
|
|
160
310
|
channel.progressCallbacks.clear();
|
|
161
|
-
}
|
|
311
|
+
}
|
|
162
312
|
|
|
163
313
|
/**
|
|
164
314
|
* Subscribes to queue change events for a specific channel
|
|
165
315
|
* @param channelNumber - The channel number to monitor
|
|
166
316
|
* @param callback - Function to call when queue changes
|
|
317
|
+
* @throws Error if the channel number exceeds the maximum allowed channels
|
|
167
318
|
* @example
|
|
168
319
|
* ```typescript
|
|
169
320
|
* onQueueChange(0, (snapshot) => {
|
|
@@ -173,6 +324,8 @@ export const offAudioProgress = (channelNumber: number): void => {
|
|
|
173
324
|
* ```
|
|
174
325
|
*/
|
|
175
326
|
export const onQueueChange = (channelNumber: number, callback: QueueChangeCallback): void => {
|
|
327
|
+
validateChannelNumber(channelNumber);
|
|
328
|
+
|
|
176
329
|
if (!audioChannels[channelNumber]) {
|
|
177
330
|
audioChannels[channelNumber] = {
|
|
178
331
|
audioCompleteCallbacks: new Set(),
|
|
@@ -215,6 +368,7 @@ export const offQueueChange = (channelNumber: number): void => {
|
|
|
215
368
|
* Subscribes to audio start events for a specific channel
|
|
216
369
|
* @param channelNumber - The channel number to monitor
|
|
217
370
|
* @param callback - Function to call when audio starts playing
|
|
371
|
+
* @throws Error if the channel number exceeds the maximum allowed channels
|
|
218
372
|
* @example
|
|
219
373
|
* ```typescript
|
|
220
374
|
* onAudioStart(0, (info) => {
|
|
@@ -224,6 +378,8 @@ export const offQueueChange = (channelNumber: number): void => {
|
|
|
224
378
|
* ```
|
|
225
379
|
*/
|
|
226
380
|
export const onAudioStart = (channelNumber: number, callback: AudioStartCallback): void => {
|
|
381
|
+
validateChannelNumber(channelNumber);
|
|
382
|
+
|
|
227
383
|
if (!audioChannels[channelNumber]) {
|
|
228
384
|
audioChannels[channelNumber] = {
|
|
229
385
|
audioCompleteCallbacks: new Set(),
|
|
@@ -251,6 +407,7 @@ export const onAudioStart = (channelNumber: number, callback: AudioStartCallback
|
|
|
251
407
|
* Subscribes to audio complete events for a specific channel
|
|
252
408
|
* @param channelNumber - The channel number to monitor
|
|
253
409
|
* @param callback - Function to call when audio completes
|
|
410
|
+
* @throws Error if the channel number exceeds the maximum allowed channels
|
|
254
411
|
* @example
|
|
255
412
|
* ```typescript
|
|
256
413
|
* onAudioComplete(0, (info) => {
|
|
@@ -262,6 +419,8 @@ export const onAudioStart = (channelNumber: number, callback: AudioStartCallback
|
|
|
262
419
|
* ```
|
|
263
420
|
*/
|
|
264
421
|
export const onAudioComplete = (channelNumber: number, callback: AudioCompleteCallback): void => {
|
|
422
|
+
validateChannelNumber(channelNumber);
|
|
423
|
+
|
|
265
424
|
if (!audioChannels[channelNumber]) {
|
|
266
425
|
audioChannels[channelNumber] = {
|
|
267
426
|
audioCompleteCallbacks: new Set(),
|
|
@@ -289,6 +448,7 @@ export const onAudioComplete = (channelNumber: number, callback: AudioCompleteCa
|
|
|
289
448
|
* Subscribes to audio pause events for a specific channel
|
|
290
449
|
* @param channelNumber - The channel number to monitor
|
|
291
450
|
* @param callback - Function to call when audio is paused
|
|
451
|
+
* @throws Error if the channel number exceeds the maximum allowed channels
|
|
292
452
|
* @example
|
|
293
453
|
* ```typescript
|
|
294
454
|
* onAudioPause(0, (channelNumber, info) => {
|
|
@@ -298,6 +458,8 @@ export const onAudioComplete = (channelNumber: number, callback: AudioCompleteCa
|
|
|
298
458
|
* ```
|
|
299
459
|
*/
|
|
300
460
|
export const onAudioPause = (channelNumber: number, callback: AudioPauseCallback): void => {
|
|
461
|
+
validateChannelNumber(channelNumber);
|
|
462
|
+
|
|
301
463
|
if (!audioChannels[channelNumber]) {
|
|
302
464
|
audioChannels[channelNumber] = {
|
|
303
465
|
audioCompleteCallbacks: new Set(),
|
|
@@ -325,6 +487,7 @@ export const onAudioPause = (channelNumber: number, callback: AudioPauseCallback
|
|
|
325
487
|
* Subscribes to audio resume events for a specific channel
|
|
326
488
|
* @param channelNumber - The channel number to monitor
|
|
327
489
|
* @param callback - Function to call when audio is resumed
|
|
490
|
+
* @throws Error if the channel number exceeds the maximum allowed channels
|
|
328
491
|
* @example
|
|
329
492
|
* ```typescript
|
|
330
493
|
* onAudioResume(0, (channelNumber, info) => {
|
|
@@ -334,6 +497,8 @@ export const onAudioPause = (channelNumber: number, callback: AudioPauseCallback
|
|
|
334
497
|
* ```
|
|
335
498
|
*/
|
|
336
499
|
export const onAudioResume = (channelNumber: number, callback: AudioResumeCallback): void => {
|
|
500
|
+
validateChannelNumber(channelNumber);
|
|
501
|
+
|
|
337
502
|
if (!audioChannels[channelNumber]) {
|
|
338
503
|
audioChannels[channelNumber] = {
|
|
339
504
|
audioCompleteCallbacks: new Set(),
|
|
@@ -386,3 +551,33 @@ export const offAudioResume = (channelNumber: number): void => {
|
|
|
386
551
|
|
|
387
552
|
channel.audioResumeCallbacks.clear();
|
|
388
553
|
};
|
|
554
|
+
|
|
555
|
+
/**
|
|
556
|
+
* Removes audio start event listeners for a specific channel
|
|
557
|
+
* @param channelNumber - The channel number
|
|
558
|
+
* @example
|
|
559
|
+
* ```typescript
|
|
560
|
+
* offAudioStart(0); // Stop receiving start notifications for channel 0
|
|
561
|
+
* ```
|
|
562
|
+
*/
|
|
563
|
+
export const offAudioStart = (channelNumber: number): void => {
|
|
564
|
+
const channel: ExtendedAudioQueueChannel = audioChannels[channelNumber];
|
|
565
|
+
if (!channel?.audioStartCallbacks) return;
|
|
566
|
+
|
|
567
|
+
channel.audioStartCallbacks.clear();
|
|
568
|
+
};
|
|
569
|
+
|
|
570
|
+
/**
|
|
571
|
+
* Removes audio complete event listeners for a specific channel
|
|
572
|
+
* @param channelNumber - The channel number
|
|
573
|
+
* @example
|
|
574
|
+
* ```typescript
|
|
575
|
+
* offAudioComplete(0); // Stop receiving completion notifications for channel 0
|
|
576
|
+
* ```
|
|
577
|
+
*/
|
|
578
|
+
export const offAudioComplete = (channelNumber: number): void => {
|
|
579
|
+
const channel: ExtendedAudioQueueChannel = audioChannels[channelNumber];
|
|
580
|
+
if (!channel?.audioCompleteCallbacks) return;
|
|
581
|
+
|
|
582
|
+
channel.audioCompleteCallbacks.clear();
|
|
583
|
+
};
|
package/src/pause.ts
CHANGED
|
@@ -14,8 +14,6 @@ import { getAudioInfoFromElement } from './utils';
|
|
|
14
14
|
import { emitAudioPause, emitAudioResume } from './events';
|
|
15
15
|
import { transitionVolume, getFadeConfig } from './volume';
|
|
16
16
|
|
|
17
|
-
|
|
18
|
-
|
|
19
17
|
/**
|
|
20
18
|
* Gets the current volume for a channel, accounting for synchronous state
|
|
21
19
|
* @param channelNumber - The channel number
|
|
@@ -81,7 +79,7 @@ export const pauseWithFade = async (
|
|
|
81
79
|
// First fade or no transition in progress, capture current volume
|
|
82
80
|
// But ensure we don't capture a volume of 0 during a transition
|
|
83
81
|
const currentVolume = getChannelVolumeSync(channelNumber);
|
|
84
|
-
originalVolume = currentVolume > 0 ? currentVolume : channel.fadeState?.originalVolume ?? 1.0;
|
|
82
|
+
originalVolume = currentVolume > 0 ? currentVolume : (channel.fadeState?.originalVolume ?? 1.0);
|
|
85
83
|
}
|
|
86
84
|
|
|
87
85
|
// Store fade state for resumeWithFade to use (including custom duration)
|
|
@@ -111,7 +109,7 @@ export const pauseWithFade = async (
|
|
|
111
109
|
|
|
112
110
|
// Reset volume to original for resume (synchronously to avoid state issues)
|
|
113
111
|
setChannelVolumeSync(channelNumber, originalVolume);
|
|
114
|
-
|
|
112
|
+
|
|
115
113
|
// Mark transition as complete
|
|
116
114
|
if (channel.fadeState) {
|
|
117
115
|
channel.fadeState.isTransitioning = false;
|
|
@@ -258,11 +256,11 @@ export const pauseAllWithFade = async (
|
|
|
258
256
|
*/
|
|
259
257
|
export const resumeAllWithFade = async (fadeType?: FadeType, duration?: number): Promise<void> => {
|
|
260
258
|
const resumePromises: Promise<void>[] = [];
|
|
261
|
-
|
|
259
|
+
|
|
262
260
|
audioChannels.forEach((_channel: ExtendedAudioQueueChannel, index: number) => {
|
|
263
261
|
resumePromises.push(resumeWithFade(fadeType, index, duration));
|
|
264
262
|
});
|
|
265
|
-
|
|
263
|
+
|
|
266
264
|
await Promise.all(resumePromises);
|
|
267
265
|
};
|
|
268
266
|
|