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/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 = new Map<number, number>();
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 FADE_CONFIGS: Record<FadeType, FadeConfig> = {
15
- [FadeType.Dramatic]: { duration: 800, pauseCurve: EasingType.EaseIn, resumeCurve: EasingType.EaseOut },
16
- [FadeType.Gentle]: { duration: 800, pauseCurve: EasingType.EaseOut, resumeCurve: EasingType.EaseIn },
17
- [FadeType.Linear]: { duration: 800, pauseCurve: EasingType.Linear, resumeCurve: EasingType.Linear }
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 { ...FADE_CONFIGS[fadeType] };
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
- clearTimeout(activeTransitions.get(channelNumber));
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 + (volumeDelta * easedProgress);
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 || 1.0;
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 || 250;
308
- const easing = config.transitionEasing || EasingType.EaseOut;
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
- // Wait for all transitions to complete
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 || 500;
364
- const easing = config.transitionEasing || EasingType.EaseOut;
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 || 1.0, duration, easing)
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
+ };