audio-channel-queue 1.8.0 → 1.9.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/dist/core.js +4 -3
- package/dist/errors.js +27 -17
- package/dist/events.js +21 -14
- package/dist/index.d.ts +5 -5
- package/dist/index.js +3 -2
- package/dist/info.js +8 -7
- package/dist/pause.d.ts +24 -12
- package/dist/pause.js +93 -41
- package/dist/types.d.ts +12 -3
- package/dist/types.js +6 -1
- package/dist/utils.js +4 -3
- package/dist/volume.js +37 -15
- package/package.json +8 -3
- package/src/core.ts +59 -42
- package/src/errors.ts +504 -480
- package/src/events.ts +36 -27
- package/src/index.ts +47 -43
- package/src/info.ts +23 -22
- package/src/pause.ts +168 -85
- package/src/types.ts +12 -2
- package/src/utils.ts +7 -7
- package/src/volume.ts +47 -30
package/src/volume.ts
CHANGED
|
@@ -6,15 +6,27 @@ import { ExtendedAudioQueueChannel, VolumeConfig, FadeType, FadeConfig, EasingTy
|
|
|
6
6
|
import { audioChannels } from './info';
|
|
7
7
|
|
|
8
8
|
// Store active volume transitions to handle interruptions
|
|
9
|
-
const activeTransitions
|
|
9
|
+
const activeTransitions: Map<number, number> = new Map();
|
|
10
10
|
|
|
11
11
|
/**
|
|
12
12
|
* Predefined fade configurations for different transition types
|
|
13
13
|
*/
|
|
14
|
-
const
|
|
15
|
-
[FadeType.Dramatic]: {
|
|
16
|
-
|
|
17
|
-
|
|
14
|
+
const fadeConfigs: Record<FadeType, FadeConfig> = {
|
|
15
|
+
[FadeType.Dramatic]: {
|
|
16
|
+
duration: 800,
|
|
17
|
+
pauseCurve: EasingType.EaseIn,
|
|
18
|
+
resumeCurve: EasingType.EaseOut
|
|
19
|
+
},
|
|
20
|
+
[FadeType.Gentle]: {
|
|
21
|
+
duration: 800,
|
|
22
|
+
pauseCurve: EasingType.EaseOut,
|
|
23
|
+
resumeCurve: EasingType.EaseIn
|
|
24
|
+
},
|
|
25
|
+
[FadeType.Linear]: {
|
|
26
|
+
duration: 800,
|
|
27
|
+
pauseCurve: EasingType.Linear,
|
|
28
|
+
resumeCurve: EasingType.Linear
|
|
29
|
+
}
|
|
18
30
|
};
|
|
19
31
|
|
|
20
32
|
/**
|
|
@@ -28,7 +40,7 @@ const FADE_CONFIGS: Record<FadeType, FadeConfig> = {
|
|
|
28
40
|
* ```
|
|
29
41
|
*/
|
|
30
42
|
export const getFadeConfig = (fadeType: FadeType): FadeConfig => {
|
|
31
|
-
return { ...
|
|
43
|
+
return { ...fadeConfigs[fadeType] };
|
|
32
44
|
};
|
|
33
45
|
|
|
34
46
|
/**
|
|
@@ -38,7 +50,7 @@ const easingFunctions: Record<EasingType, (t: number) => number> = {
|
|
|
38
50
|
[EasingType.Linear]: (t: number): number => t,
|
|
39
51
|
[EasingType.EaseIn]: (t: number): number => t * t,
|
|
40
52
|
[EasingType.EaseOut]: (t: number): number => t * (2 - t),
|
|
41
|
-
[EasingType.EaseInOut]: (t: number): number => t < 0.5 ? 2 * t * t : -1 + (4 - 2 * t) * t
|
|
53
|
+
[EasingType.EaseInOut]: (t: number): number => (t < 0.5 ? 2 * t * t : -1 + (4 - 2 * t) * t)
|
|
42
54
|
};
|
|
43
55
|
|
|
44
56
|
/**
|
|
@@ -65,10 +77,17 @@ export const transitionVolume = async (
|
|
|
65
77
|
const currentAudio: HTMLAudioElement = channel.queue[0];
|
|
66
78
|
const startVolume: number = currentAudio.volume;
|
|
67
79
|
const volumeDelta: number = targetVolume - startVolume;
|
|
68
|
-
|
|
80
|
+
|
|
69
81
|
// Cancel any existing transition for this channel
|
|
70
82
|
if (activeTransitions.has(channelNumber)) {
|
|
71
|
-
|
|
83
|
+
const transitionId = activeTransitions.get(channelNumber);
|
|
84
|
+
if (transitionId) {
|
|
85
|
+
// Handle both requestAnimationFrame and setTimeout IDs
|
|
86
|
+
if (typeof cancelAnimationFrame !== 'undefined') {
|
|
87
|
+
cancelAnimationFrame(transitionId);
|
|
88
|
+
}
|
|
89
|
+
clearTimeout(transitionId);
|
|
90
|
+
}
|
|
72
91
|
activeTransitions.delete(channelNumber);
|
|
73
92
|
}
|
|
74
93
|
|
|
@@ -95,10 +114,10 @@ export const transitionVolume = async (
|
|
|
95
114
|
const elapsed: number = performance.now() - startTime;
|
|
96
115
|
const progress: number = Math.min(elapsed / duration, 1);
|
|
97
116
|
const easedProgress: number = easingFn(progress);
|
|
98
|
-
|
|
99
|
-
const currentVolume: number = startVolume +
|
|
117
|
+
|
|
118
|
+
const currentVolume: number = startVolume + volumeDelta * easedProgress;
|
|
100
119
|
const clampedVolume: number = Math.max(0, Math.min(1, currentVolume));
|
|
101
|
-
|
|
120
|
+
|
|
102
121
|
// Apply volume to both channel config and current audio
|
|
103
122
|
channel.volume = clampedVolume;
|
|
104
123
|
if (channel.queue.length > 0) {
|
|
@@ -139,13 +158,13 @@ export const transitionVolume = async (
|
|
|
139
158
|
* ```
|
|
140
159
|
*/
|
|
141
160
|
export const setChannelVolume = async (
|
|
142
|
-
channelNumber: number,
|
|
161
|
+
channelNumber: number,
|
|
143
162
|
volume: number,
|
|
144
163
|
transitionDuration?: number,
|
|
145
164
|
easing?: EasingType
|
|
146
165
|
): Promise<void> => {
|
|
147
166
|
const clampedVolume: number = Math.max(0, Math.min(1, volume));
|
|
148
|
-
|
|
167
|
+
|
|
149
168
|
if (!audioChannels[channelNumber]) {
|
|
150
169
|
audioChannels[channelNumber] = {
|
|
151
170
|
audioCompleteCallbacks: new Set(),
|
|
@@ -189,7 +208,7 @@ export const setChannelVolume = async (
|
|
|
189
208
|
*/
|
|
190
209
|
export const getChannelVolume = (channelNumber: number = 0): number => {
|
|
191
210
|
const channel: ExtendedAudioQueueChannel = audioChannels[channelNumber];
|
|
192
|
-
return channel?.volume
|
|
211
|
+
return channel?.volume ?? 1.0;
|
|
193
212
|
};
|
|
194
213
|
|
|
195
214
|
/**
|
|
@@ -204,9 +223,7 @@ export const getChannelVolume = (channelNumber: number = 0): number => {
|
|
|
204
223
|
* ```
|
|
205
224
|
*/
|
|
206
225
|
export const getAllChannelsVolume = (): number[] => {
|
|
207
|
-
return audioChannels.map((channel: ExtendedAudioQueueChannel) =>
|
|
208
|
-
channel?.volume || 1.0
|
|
209
|
-
);
|
|
226
|
+
return audioChannels.map((channel: ExtendedAudioQueueChannel) => channel?.volume ?? 1.0);
|
|
210
227
|
};
|
|
211
228
|
|
|
212
229
|
/**
|
|
@@ -302,11 +319,11 @@ export const applyVolumeDucking = async (activeChannelNumber: number): Promise<v
|
|
|
302
319
|
audioChannels.forEach((channel: ExtendedAudioQueueChannel, channelNumber: number) => {
|
|
303
320
|
if (channel?.volumeConfig) {
|
|
304
321
|
const config: VolumeConfig = channel.volumeConfig;
|
|
305
|
-
|
|
322
|
+
|
|
306
323
|
if (activeChannelNumber === config.priorityChannel) {
|
|
307
|
-
const duration = config.duckTransitionDuration
|
|
308
|
-
const easing = config.transitionEasing
|
|
309
|
-
|
|
324
|
+
const duration = config.duckTransitionDuration ?? 250;
|
|
325
|
+
const easing = config.transitionEasing ?? EasingType.EaseOut;
|
|
326
|
+
|
|
310
327
|
// Priority channel is active, duck other channels
|
|
311
328
|
if (channelNumber === config.priorityChannel) {
|
|
312
329
|
transitionPromises.push(
|
|
@@ -321,7 +338,7 @@ export const applyVolumeDucking = async (activeChannelNumber: number): Promise<v
|
|
|
321
338
|
}
|
|
322
339
|
});
|
|
323
340
|
|
|
324
|
-
|
|
341
|
+
// Wait for all transitions to complete
|
|
325
342
|
await Promise.all(transitionPromises);
|
|
326
343
|
};
|
|
327
344
|
|
|
@@ -345,7 +362,7 @@ export const fadeVolume = async (
|
|
|
345
362
|
easing: EasingType = EasingType.EaseOut
|
|
346
363
|
): Promise<void> => {
|
|
347
364
|
return transitionVolume(channelNumber, targetVolume, duration, easing);
|
|
348
|
-
};
|
|
365
|
+
};
|
|
349
366
|
|
|
350
367
|
/**
|
|
351
368
|
* Restores normal volume levels when priority channel stops with smooth transitions
|
|
@@ -358,14 +375,14 @@ export const restoreVolumeLevels = async (stoppedChannelNumber: number): Promise
|
|
|
358
375
|
audioChannels.forEach((channel: ExtendedAudioQueueChannel, channelNumber: number) => {
|
|
359
376
|
if (channel?.volumeConfig) {
|
|
360
377
|
const config: VolumeConfig = channel.volumeConfig;
|
|
361
|
-
|
|
378
|
+
|
|
362
379
|
if (stoppedChannelNumber === config.priorityChannel) {
|
|
363
|
-
const duration = config.restoreTransitionDuration
|
|
364
|
-
const easing = config.transitionEasing
|
|
365
|
-
|
|
380
|
+
const duration = config.restoreTransitionDuration ?? 500;
|
|
381
|
+
const easing = config.transitionEasing ?? EasingType.EaseOut;
|
|
382
|
+
|
|
366
383
|
// Priority channel stopped, restore normal volumes
|
|
367
384
|
transitionPromises.push(
|
|
368
|
-
transitionVolume(channelNumber, channel.volume
|
|
385
|
+
transitionVolume(channelNumber, channel.volume ?? 1.0, duration, easing)
|
|
369
386
|
);
|
|
370
387
|
}
|
|
371
388
|
}
|
|
@@ -373,4 +390,4 @@ export const restoreVolumeLevels = async (stoppedChannelNumber: number): Promise
|
|
|
373
390
|
|
|
374
391
|
// Wait for all transitions to complete
|
|
375
392
|
await Promise.all(transitionPromises);
|
|
376
|
-
};
|
|
393
|
+
};
|