audio-channel-queue 1.12.0 → 1.13.2

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 CHANGED
@@ -1,3 +1,15 @@
1
+ # ⚠️ DEPRECATED - This package has been renamed
2
+
3
+ This package is deprecated and will no longer receive updates.
4
+
5
+ **Please use [`AudioQ`](https://www.npmjs.com/package/audioq) instead:**
6
+
7
+ \`\`\`bash
8
+ npm install audioq
9
+ \`\`\`
10
+
11
+ All future development will happen in the new package.
12
+
1
13
  # Audio Channel Queue
2
14
  The purpose of this package is to help manage the playback of audio files.
3
15
 
@@ -5,20 +17,20 @@ The purpose of this package is to help manage the playback of audio files.
5
17
 
6
18
  📚 [Docs](https://tonycarpenter21.github.io/audio-queue-docs/)
7
19
 
8
- ## 🌟 Key Features
20
+ ## Key Features
9
21
 
10
- - **Multi-channel queue management** - Independent audio queues for concurrent playback
11
- - **Pause/Resume functionality** - Full playback control for individual channels or all channels
12
- - **Volume control with ducking** - Dynamic volume management and automatic background audio reduction
13
- - **Loop support** - Seamless audio looping for background music and ambient sounds
14
- - **Priority queueing** - Add urgent audio to the front of any queue
15
- - **Real-time progress tracking** - Comprehensive playback monitoring and metadata
16
- - **Event-driven architecture** - Extensive callback system for UI integration
17
- - **TypeScript support** - Full type definitions and IntelliSense support
18
- - **Zero dependencies** - Lightweight and self-contained
19
- - **Backward compatible** - All existing APIs continue to work
22
+ - **Multi-channel queue management** - Independent audio queues for concurrent playback
23
+ - **Pause/Resume functionality** - Full playback control for individual channels or all channels
24
+ - **Volume control with ducking** - Dynamic volume management, global volume control, and automatic background audio reduction
25
+ - **Loop support** - Seamless audio looping for background music and ambient sounds
26
+ - **Priority queueing** - Add urgent audio to the front of any queue
27
+ - **Real-time progress tracking** - Comprehensive playback monitoring and metadata
28
+ - **Event-driven architecture** - Extensive callback system for UI integration
29
+ - **TypeScript support** - Full type definitions and IntelliSense support
30
+ - **Zero dependencies** - Lightweight and self-contained
31
+ - **Backward compatible** - All existing APIs continue to work
20
32
 
21
- This package offers TypeScript support 📘, boasts zero dependencies 🚫, and is released under the MIT license 📜. As an added bonus, it's NON-GMO 🌱 and 100% Free Range Organic 🐓.
33
+ This package offers TypeScript support, has zero dependencies, and is released under the MIT license.
22
34
 
23
35
  To preview this package and see how it works with visualized code examples, check out the demo that can be found here: [Audio Channel Queue Demo](https://tonycarpenter21.github.io/audio-queue-demo/). (A link to the demo repo can be found here: [Audio Channel Queue Demo Repo](https://github.com/tonycarpenter21/audio-queue-demo).)
24
36
 
@@ -32,18 +44,18 @@ Documentation can be found [here](https://tonycarpenter21.github.io/audio-queue-
32
44
 
33
45
  This package is designed for **browser environments** and uses the Web Audio API (`HTMLAudioElement`). It is **not** intended for Node.js server-side use.
34
46
 
35
- ### **Supported Browsers:**
47
+ ### **Supported Browsers:**
36
48
  - **Chrome 51+** (June 2016)
37
49
  - **Firefox 54+** (June 2017)
38
50
  - **Safari 10+** (September 2016)
39
51
  - **Edge 15+** (April 2017)
40
52
  - **Mobile browsers** with HTML5 audio support
41
53
 
42
- ### 🛠️ **Development Requirements:**
54
+ ### **Development Requirements:**
43
55
  - **Node.js 14+** (for building and testing only)
44
56
  - **TypeScript 4.5+** (included in devDependencies)
45
57
 
46
- ### ⚠️ **Not Supported:**
58
+ ### **Not Supported:**
47
59
  - Node.js server environments (no HTMLAudioElement)
48
60
  - Internet Explorer (lacks ES6 support)
49
61
  - Web Workers (no DOM access)
@@ -197,6 +209,47 @@ await setAllChannelsVolume(0.6); // Set all channels to 60% volume
197
209
  await setAllChannelsVolume(0.0); // Mute all channels
198
210
  ```
199
211
 
212
+ ### Global Volume Control
213
+ ```typescript
214
+ // Set a global volume multiplier that affects all channels while preserving their relative levels.
215
+ setGlobalVolume(volume);
216
+ await setGlobalVolume(0.5); // Set global volume to 50%
217
+ ```
218
+
219
+ ```typescript
220
+ // Get the current global volume level.
221
+ getGlobalVolume();
222
+ const globalVol = getGlobalVolume(); // Returns current global volume (0-1)
223
+ console.log(`Global volume: ${(getGlobalVolume() * 100).toFixed(0)}%`);
224
+ ```
225
+
226
+ **How Global Volume Works:**
227
+ The global volume acts as a **global volume multiplier** - it scales all channel volumes proportionally while preserving their individual settings. This is perfect for implementing a global volume slider in your UI.
228
+
229
+ ```typescript
230
+ // Example: Setting up different audio types with a global volume control
231
+ await setChannelVolume(0, 0.3); // SFX channel at 30%
232
+ await setChannelVolume(1, 0.7); // Music channel at 70%
233
+ await setChannelVolume(2, 0.5); // Voice channel at 50%
234
+
235
+ // User adjusts global volume slider to 50%
236
+ await setGlobalVolume(0.5);
237
+
238
+ // Actual playback volumes become:
239
+ // - SFX: 30% × 50% = 15%
240
+ // - Music: 70% × 50% = 35%
241
+ // - Voice: 50% × 50% = 25%
242
+
243
+ // Channel volumes remain at their original settings (0.3, 0.7, 0.5)
244
+ // So when global volume is increased, ratios are preserved
245
+ await setGlobalVolume(1.0); // Back to full volume
246
+ // - SFX: 30% × 100% = 30%
247
+ // - Music: 70% × 100% = 70%
248
+ // - Voice: 50% × 100% = 50%
249
+ ```
250
+
251
+ **Note:** `setAllChannelsVolume()` sets all channels to the **same** volume, while `setGlobalVolume()` **multiplies** all channels by the same amount, preserving their relative differences.
252
+
200
253
  ### Volume Ducking (Background Audio Reduction)
201
254
  ```typescript
202
255
  // Automatically reduce other channels' volume when priority audio plays.
package/dist/core.d.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  /**
2
- * @fileoverview Core queue management functions for the audio-channel-queue package
2
+ * @fileoverview Core queue management functions for the audioq package
3
3
  */
4
4
  import { AudioQueueOptions, QueueConfig } from './types';
5
5
  /**
package/dist/core.js CHANGED
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  /**
3
- * @fileoverview Core queue management functions for the audio-channel-queue package
3
+ * @fileoverview Core queue management functions for the audioq package
4
4
  */
5
5
  var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
6
6
  function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
@@ -183,7 +183,7 @@ const checkQueueLimit = (channel, channelNumber, maxQueueSize) => {
183
183
  (0, events_1.cleanupProgressTracking)(removedAudio, channelNumber, info_1.audioChannels);
184
184
  if (globalQueueConfig.showQueueWarnings) {
185
185
  // eslint-disable-next-line no-console
186
- console.info(`Dropped oldest queued item to make room for new audio`);
186
+ console.warn(`Dropped oldest queued item to make room for new audio`);
187
187
  }
188
188
  return true;
189
189
  }
@@ -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') {
@@ -316,9 +318,10 @@ const playAudioQueue = (channelNumber) => __awaiter(void 0, void 0, void 0, func
316
318
  if (!channel || channel.queue.length === 0)
317
319
  return;
318
320
  const currentAudio = channel.queue[0];
319
- // Apply channel volume if not already set
321
+ // Apply channel volume with global volume multiplier if not already set
320
322
  if (currentAudio.volume === 1.0 && channel.volume !== undefined) {
321
- currentAudio.volume = channel.volume;
323
+ const globalVolume = (0, volume_1.getGlobalVolume)();
324
+ currentAudio.volume = channel.volume * globalVolume;
322
325
  }
323
326
  (0, events_1.setupProgressTracking)(currentAudio, channelNumber, info_1.audioChannels);
324
327
  // Apply volume ducking when audio starts
@@ -378,6 +381,7 @@ const playAudioQueue = (channelNumber) => __awaiter(void 0, void 0, void 0, func
378
381
  // For non-looping audio, remove from queue and play next
379
382
  currentAudio.pause();
380
383
  (0, events_1.cleanupProgressTracking)(currentAudio, channelNumber, info_1.audioChannels);
384
+ (0, volume_1.cleanupWebAudioForAudio)(currentAudio, channelNumber);
381
385
  channel.queue.shift();
382
386
  channel.isPaused = false; // Reset pause state
383
387
  // Restore volume levels AFTER removing audio from queue
package/dist/errors.d.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  /**
2
- * @fileoverview Error handling, retry logic, and recovery mechanisms for the audio-channel-queue package
2
+ * @fileoverview Error handling, retry logic, and recovery mechanisms for the audioq package
3
3
  */
4
4
  import { AudioErrorInfo, AudioErrorCallback, AudioErrorType, RetryConfig, ErrorRecoveryOptions, ExtendedAudioQueueChannel } from './types';
5
5
  /**
package/dist/errors.js CHANGED
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  /**
3
- * @fileoverview Error handling, retry logic, and recovery mechanisms for the audio-channel-queue package
3
+ * @fileoverview Error handling, retry logic, and recovery mechanisms for the audioq package
4
4
  */
5
5
  var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
6
6
  if (k2 === undefined) k2 = k;
@@ -56,7 +56,6 @@ let globalErrorRecovery = {
56
56
  showUserFeedback: false
57
57
  };
58
58
  const retryAttempts = new WeakMap();
59
- const loadTimeouts = new WeakMap();
60
59
  /**
61
60
  * Subscribes to audio error events for a specific channel
62
61
  * @param channelNumber - The channel number to listen to (defaults to 0)
@@ -241,7 +240,7 @@ const emitAudioError = (channelNumber, errorInfo, audioChannels) => {
241
240
  // Log to analytics if enabled
242
241
  if (globalErrorRecovery.logErrorsToAnalytics) {
243
242
  // eslint-disable-next-line no-console
244
- console.warn('Audio Error Analytics:', errorInfo);
243
+ console.error('Audio Error Analytics:', errorInfo);
245
244
  }
246
245
  channel.audioErrorCallbacks.forEach((callback) => {
247
246
  try {
@@ -306,37 +305,9 @@ const setupAudioErrorHandling = (audio, channelNumber, originalUrl, onError) =>
306
305
  const channel = info_1.audioChannels[channelNumber];
307
306
  if (!channel)
308
307
  return;
309
- // Set up loading timeout with test environment compatibility
310
- let timeoutId;
311
- if (typeof setTimeout !== 'undefined') {
312
- timeoutId = setTimeout(() => {
313
- if (audio.networkState === HTMLMediaElement.NETWORK_LOADING) {
314
- const timeoutError = new Error(`Audio loading timeout after ${globalRetryConfig.timeoutMs}ms`);
315
- (0, exports.handleAudioError)(audio, channelNumber, originalUrl, timeoutError);
316
- }
317
- }, globalRetryConfig.timeoutMs);
318
- loadTimeouts.set(audio, timeoutId);
319
- }
320
- // Clear timeout when metadata loads successfully
321
- const handleLoadSuccess = () => {
322
- if (typeof setTimeout !== 'undefined') {
323
- const timeoutId = loadTimeouts.get(audio);
324
- if (timeoutId) {
325
- clearTimeout(timeoutId);
326
- loadTimeouts.delete(audio);
327
- }
328
- }
329
- };
330
308
  // Handle various error events
331
309
  const handleError = (_event) => {
332
310
  var _a;
333
- if (typeof setTimeout !== 'undefined') {
334
- const timeoutId = loadTimeouts.get(audio);
335
- if (timeoutId) {
336
- clearTimeout(timeoutId);
337
- loadTimeouts.delete(audio);
338
- }
339
- }
340
311
  const error = new Error(`Audio loading failed: ${((_a = audio.error) === null || _a === void 0 ? void 0 : _a.message) || 'Unknown error'}`);
341
312
  (0, exports.handleAudioError)(audio, channelNumber, originalUrl, error);
342
313
  };
@@ -352,8 +323,6 @@ const setupAudioErrorHandling = (audio, channelNumber, originalUrl, onError) =>
352
323
  audio.addEventListener('error', handleError);
353
324
  audio.addEventListener('abort', handleAbort);
354
325
  audio.addEventListener('stalled', handleStall);
355
- audio.addEventListener('loadedmetadata', handleLoadSuccess);
356
- audio.addEventListener('canplay', handleLoadSuccess);
357
326
  // Custom play error handling
358
327
  if (onError) {
359
328
  const originalPlay = audio.play.bind(audio);
@@ -451,19 +420,10 @@ exports.handleAudioError = handleAudioError;
451
420
  const createProtectedAudioElement = (url, channelNumber) => __awaiter(void 0, void 0, void 0, function* () {
452
421
  const audio = new Audio();
453
422
  return new Promise((resolve, reject) => {
454
- const cleanup = () => {
455
- const timeoutId = loadTimeouts.get(audio);
456
- if (timeoutId) {
457
- clearTimeout(timeoutId);
458
- loadTimeouts.delete(audio);
459
- }
460
- };
461
423
  const handleSuccess = () => {
462
- cleanup();
463
424
  resolve(audio);
464
425
  };
465
426
  const handleError = (error) => {
466
- cleanup();
467
427
  reject(error);
468
428
  };
469
429
  // Set up error handling
package/dist/events.d.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  /**
2
- * @fileoverview Event handling and emission for the audio-channel-queue package
2
+ * @fileoverview Event handling and emission for the audioq package
3
3
  */
4
4
  import { AudioStartInfo, AudioCompleteInfo, ExtendedAudioQueueChannel, AudioInfo } from './types';
5
5
  /**
package/dist/events.js CHANGED
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  /**
3
- * @fileoverview Event handling and emission for the audio-channel-queue package
3
+ * @fileoverview Event handling and emission for the audioq package
4
4
  */
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
6
  exports.cleanupProgressTracking = exports.setupProgressTracking = exports.emitAudioResume = exports.emitAudioPause = exports.emitAudioComplete = exports.emitAudioStart = exports.emitQueueChange = void 0;
package/dist/index.d.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  /**
2
- * @fileoverview Main entry point for the audio-channel-queue package
2
+ * @fileoverview Main entry point for the audioq package
3
3
  * Exports all public functions and types for audio queue management, pause/resume controls,
4
4
  * volume management with ducking, progress tracking, and comprehensive event system
5
5
  */
@@ -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 { cancelAllVolumeTransitions, cancelVolumeTransition, clearVolumeDucking, getAllChannelsVolume, getChannelVolume, getFadeConfig, setAllChannelsVolume, setChannelVolume, setVolumeDucking, transitionVolume } from './volume';
10
+ export { cancelAllVolumeTransitions, cancelVolumeTransition, clearVolumeDucking, getAllChannelsVolume, getChannelVolume, getFadeConfig, getGlobalVolume, setAllChannelsVolume, setChannelVolume, setGlobalVolume, 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, QueueConfig } 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';
15
16
  export { AudioErrorType, EasingType, FadeType, MAX_CHANNELS, TimerType, GLOBAL_PROGRESS_KEY } from './types';
package/dist/index.js CHANGED
@@ -1,12 +1,12 @@
1
1
  "use strict";
2
2
  /**
3
- * @fileoverview Main entry point for the audio-channel-queue package
3
+ * @fileoverview Main entry point for the audioq package
4
4
  * Exports all public functions and types for audio queue management, pause/resume controls,
5
5
  * volume management with ducking, progress tracking, and comprehensive event system
6
6
  */
7
7
  Object.defineProperty(exports, "__esModule", { value: true });
8
- exports.getCurrentAudioInfo = exports.getAllChannelsInfo = 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 = void 0;
8
+ exports.transitionVolume = exports.setVolumeDucking = exports.setGlobalVolume = exports.setChannelVolume = exports.setAllChannelsVolume = exports.getGlobalVolume = 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 = exports.createWebAudioNodes = exports.cleanupWebAudioNodes = 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; } });
@@ -61,10 +61,26 @@ Object.defineProperty(exports, "clearVolumeDucking", { enumerable: true, get: fu
61
61
  Object.defineProperty(exports, "getAllChannelsVolume", { enumerable: true, get: function () { return volume_1.getAllChannelsVolume; } });
62
62
  Object.defineProperty(exports, "getChannelVolume", { enumerable: true, get: function () { return volume_1.getChannelVolume; } });
63
63
  Object.defineProperty(exports, "getFadeConfig", { enumerable: true, get: function () { return volume_1.getFadeConfig; } });
64
+ Object.defineProperty(exports, "getGlobalVolume", { enumerable: true, get: function () { return volume_1.getGlobalVolume; } });
64
65
  Object.defineProperty(exports, "setAllChannelsVolume", { enumerable: true, get: function () { return volume_1.setAllChannelsVolume; } });
65
66
  Object.defineProperty(exports, "setChannelVolume", { enumerable: true, get: function () { return volume_1.setChannelVolume; } });
67
+ Object.defineProperty(exports, "setGlobalVolume", { enumerable: true, get: function () { return volume_1.setGlobalVolume; } });
66
68
  Object.defineProperty(exports, "setVolumeDucking", { enumerable: true, get: function () { return volume_1.setVolumeDucking; } });
67
69
  Object.defineProperty(exports, "transitionVolume", { enumerable: true, get: function () { return volume_1.transitionVolume; } });
70
+ // Web Audio API support functions
71
+ var web_audio_1 = require("./web-audio");
72
+ Object.defineProperty(exports, "cleanupWebAudioNodes", { enumerable: true, get: function () { return web_audio_1.cleanupWebAudioNodes; } });
73
+ Object.defineProperty(exports, "createWebAudioNodes", { enumerable: true, get: function () { return web_audio_1.createWebAudioNodes; } });
74
+ Object.defineProperty(exports, "getAudioContext", { enumerable: true, get: function () { return web_audio_1.getAudioContext; } });
75
+ Object.defineProperty(exports, "getWebAudioConfig", { enumerable: true, get: function () { return web_audio_1.getWebAudioConfig; } });
76
+ Object.defineProperty(exports, "getWebAudioSupport", { enumerable: true, get: function () { return web_audio_1.getWebAudioSupport; } });
77
+ Object.defineProperty(exports, "getWebAudioVolume", { enumerable: true, get: function () { return web_audio_1.getWebAudioVolume; } });
78
+ Object.defineProperty(exports, "isIOSDevice", { enumerable: true, get: function () { return web_audio_1.isIOSDevice; } });
79
+ Object.defineProperty(exports, "isWebAudioSupported", { enumerable: true, get: function () { return web_audio_1.isWebAudioSupported; } });
80
+ Object.defineProperty(exports, "resumeAudioContext", { enumerable: true, get: function () { return web_audio_1.resumeAudioContext; } });
81
+ Object.defineProperty(exports, "setWebAudioConfig", { enumerable: true, get: function () { return web_audio_1.setWebAudioConfig; } });
82
+ Object.defineProperty(exports, "setWebAudioVolume", { enumerable: true, get: function () { return web_audio_1.setWebAudioVolume; } });
83
+ Object.defineProperty(exports, "shouldUseWebAudio", { enumerable: true, get: function () { return web_audio_1.shouldUseWebAudio; } });
68
84
  // Audio information and progress tracking functions
69
85
  var info_1 = require("./info");
70
86
  Object.defineProperty(exports, "getAllChannelsInfo", { enumerable: true, get: function () { return info_1.getAllChannelsInfo; } });
package/dist/info.d.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  /**
2
- * @fileoverview Audio information and progress tracking functions for the audio-channel-queue package
2
+ * @fileoverview Audio information and progress tracking functions for the audioq package
3
3
  */
4
4
  import { AudioInfo, QueueSnapshot, ProgressCallback, QueueChangeCallback, AudioStartCallback, AudioCompleteCallback, AudioPauseCallback, AudioResumeCallback, ExtendedAudioQueueChannel } from './types';
5
5
  /**
package/dist/info.js CHANGED
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  /**
3
- * @fileoverview Audio information and progress tracking functions for the audio-channel-queue package
3
+ * @fileoverview Audio information and progress tracking functions for the audioq package
4
4
  */
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
6
  exports.offAudioComplete = exports.offAudioStart = exports.offAudioResume = exports.offAudioPause = exports.onAudioResume = exports.onAudioPause = exports.onAudioComplete = exports.onAudioStart = exports.offQueueChange = exports.onQueueChange = exports.onAudioProgress = exports.getQueueSnapshot = exports.getAllChannelsInfo = exports.getCurrentAudioInfo = exports.audioChannels = exports.getNonWhitelistedChannelProperties = exports.getWhitelistedChannelProperties = void 0;
@@ -36,7 +36,9 @@ const getWhitelistedChannelProperties = () => {
36
36
  'isLocked',
37
37
  'maxQueueSize',
38
38
  'retryConfig',
39
- 'volumeConfig' // Legacy property that might still be used
39
+ 'volumeConfig', // Legacy property that might still be used
40
+ 'webAudioContext', // Web Audio API context
41
+ 'webAudioNodes' // Web Audio API nodes map
40
42
  ];
41
43
  return [...new Set(propertyNames)]; // Remove duplicates
42
44
  };
package/dist/pause.d.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  /**
2
- * @fileoverview Pause and resume management functions for the audio-channel-queue package
2
+ * @fileoverview Pause and resume management functions for the audioq package
3
3
  */
4
4
  import { FadeType } from './types';
5
5
  /**
package/dist/pause.js CHANGED
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  /**
3
- * @fileoverview Pause and resume management functions for the audio-channel-queue package
3
+ * @fileoverview Pause and resume management functions for the audioq package
4
4
  */
5
5
  var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
6
6
  function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
@@ -18,6 +18,7 @@ const info_1 = require("./info");
18
18
  const utils_1 = require("./utils");
19
19
  const events_1 = require("./events");
20
20
  const volume_1 = require("./volume");
21
+ const web_audio_1 = require("./web-audio");
21
22
  /**
22
23
  * Gets the current volume for a channel, accounting for synchronous state
23
24
  * @param channelNumber - The channel number
@@ -38,7 +39,15 @@ const setChannelVolumeSync = (channelNumber, volume) => {
38
39
  if (channel) {
39
40
  channel.volume = volume;
40
41
  if (channel.queue.length > 0) {
41
- channel.queue[0].volume = volume;
42
+ const audio = channel.queue[0];
43
+ if (channel.webAudioNodes) {
44
+ const nodes = channel.webAudioNodes.get(audio);
45
+ if (nodes) {
46
+ // Update the gain node when Web Audio is active
47
+ (0, web_audio_1.setWebAudioVolume)(nodes.gainNode, volume);
48
+ }
49
+ }
50
+ audio.volume = volume;
42
51
  }
43
52
  }
44
53
  };
@@ -58,12 +67,14 @@ const setChannelVolumeSync = (channelNumber, volume) => {
58
67
  const pauseWithFade = (...args_1) => __awaiter(void 0, [...args_1], void 0, function* (fadeType = types_1.FadeType.Gentle, channelNumber = 0, duration) {
59
68
  var _a, _b, _c;
60
69
  const channel = info_1.audioChannels[channelNumber];
61
- if (!channel || channel.queue.length === 0)
70
+ if (!channel || channel.queue.length === 0) {
62
71
  return;
72
+ }
63
73
  const currentAudio = channel.queue[0];
64
74
  // Don't pause if already paused or ended
65
- if (currentAudio.paused || currentAudio.ended)
75
+ if (currentAudio.paused || currentAudio.ended) {
66
76
  return;
77
+ }
67
78
  const config = (0, volume_1.getFadeConfig)(fadeType);
68
79
  const effectiveDuration = duration !== null && duration !== void 0 ? duration : config.duration;
69
80
  // Race condition fix: Use existing fadeState originalVolume if already transitioning,
@@ -100,9 +111,11 @@ const pauseWithFade = (...args_1) => __awaiter(void 0, [...args_1], void 0, func
100
111
  }
101
112
  // Fade to 0 with pause curve, then pause
102
113
  yield (0, volume_1.transitionVolume)(channelNumber, 0, effectiveDuration, config.pauseCurve);
114
+ // Pause the audio
103
115
  yield (0, exports.pauseChannel)(channelNumber);
104
- // Reset volume to original for resume (synchronously to avoid state issues)
105
- setChannelVolumeSync(channelNumber, originalVolume);
116
+ // Restore channel.volume for resume, but DON'T restore gain node to prevent blip
117
+ // The gain node will be restored during the resume fade
118
+ channel.volume = originalVolume;
106
119
  // Mark transition as complete
107
120
  if (channel.fadeState) {
108
121
  channel.fadeState.isTransitioning = false;
@@ -125,8 +138,10 @@ exports.pauseWithFade = pauseWithFade;
125
138
  */
126
139
  const resumeWithFade = (fadeType_1, ...args_1) => __awaiter(void 0, [fadeType_1, ...args_1], void 0, function* (fadeType, channelNumber = 0, duration) {
127
140
  const channel = info_1.audioChannels[channelNumber];
128
- if (!channel || channel.queue.length === 0)
141
+ if (!channel || channel.queue.length === 0) {
129
142
  return;
143
+ }
144
+ const audio = channel.queue[0];
130
145
  const fadeState = channel.fadeState;
131
146
  if (!(fadeState === null || fadeState === void 0 ? void 0 : fadeState.isPaused)) {
132
147
  // Fall back to regular resume if no fade state
@@ -160,8 +175,19 @@ const resumeWithFade = (fadeType_1, ...args_1) => __awaiter(void 0, [fadeType_1,
160
175
  const targetVolume = fadeState.originalVolume > 0 ? fadeState.originalVolume : 1.0;
161
176
  // Mark as transitioning to prevent volume capture during rapid toggles
162
177
  fadeState.isTransitioning = true;
163
- // Set volume to 0, resume, then fade to original with resume curve
164
- setChannelVolumeSync(channelNumber, 0);
178
+ // Ensure gain node is at 0 before resuming (should already be from pause)
179
+ // Don't touch audio.volume when Web Audio is active - iOS may reset it
180
+ // Don't touch channel.volume - it should stay at originalVolume
181
+ if (channel.webAudioNodes) {
182
+ const nodes = channel.webAudioNodes.get(audio);
183
+ if (nodes) {
184
+ (0, web_audio_1.setWebAudioVolume)(nodes.gainNode, 0);
185
+ }
186
+ }
187
+ else {
188
+ // Fallback for non-Web Audio: set audio.volume directly
189
+ audio.volume = 0;
190
+ }
165
191
  yield (0, exports.resumeChannel)(channelNumber);
166
192
  // Use the stored original volume, not current volume, to prevent race conditions
167
193
  yield (0, volume_1.transitionVolume)(channelNumber, targetVolume, effectiveDuration, config.resumeCurve);
@@ -1,5 +1,5 @@
1
1
  /**
2
- * @fileoverview Queue manipulation functions for the audio-channel-queue package
2
+ * @fileoverview Queue manipulation functions for the audioq package
3
3
  * Provides advanced queue management including item removal, reordering, and clearing
4
4
  */
5
5
  import { QueueManipulationResult, QueueItem } from './types';
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  /**
3
- * @fileoverview Queue manipulation functions for the audio-channel-queue package
3
+ * @fileoverview Queue manipulation functions for the audioq package
4
4
  * Provides advanced queue management including item removal, reordering, and clearing
5
5
  */
6
6
  var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
package/dist/types.d.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  /**
2
- * @fileoverview Type definitions for the audio-channel-queue package
2
+ * @fileoverview Type definitions for the audioq package
3
3
  */
4
4
  /**
5
5
  * Maximum number of audio channels allowed to prevent memory exhaustion
@@ -260,6 +260,39 @@ export interface ErrorRecoveryOptions {
260
260
  * Callback function type for audio error events
261
261
  */
262
262
  export type AudioErrorCallback = (errorInfo: AudioErrorInfo) => void;
263
+ /**
264
+ * Web Audio API configuration options
265
+ */
266
+ export interface WebAudioConfig {
267
+ /** Whether to automatically use Web Audio API on iOS devices */
268
+ autoDetectIOS: boolean;
269
+ /** Whether Web Audio API support is enabled */
270
+ enabled: boolean;
271
+ /** Whether to force Web Audio API usage on all devices */
272
+ forceWebAudio: boolean;
273
+ }
274
+ /**
275
+ * Web Audio API support information
276
+ */
277
+ export interface WebAudioSupport {
278
+ /** Whether Web Audio API is available in the current environment */
279
+ available: boolean;
280
+ /** Whether the current device is iOS */
281
+ isIOS: boolean;
282
+ /** Whether Web Audio API is currently being used */
283
+ usingWebAudio: boolean;
284
+ /** Reason for current Web Audio API usage state */
285
+ reason: string;
286
+ }
287
+ /**
288
+ * Web Audio API node set for audio element control
289
+ */
290
+ export interface WebAudioNodeSet {
291
+ /** Gain node for volume control */
292
+ gainNode: GainNode;
293
+ /** Media element source node */
294
+ sourceNode: MediaElementAudioSourceNode;
295
+ }
263
296
  /**
264
297
  * Extended audio channel with comprehensive queue management, callback support, and state tracking
265
298
  */
@@ -292,6 +325,10 @@ export interface ExtendedAudioQueueChannel {
292
325
  retryConfig?: RetryConfig;
293
326
  /** Current volume level for the channel (0-1) */
294
327
  volume: number;
328
+ /** Web Audio API context for this channel */
329
+ webAudioContext?: AudioContext;
330
+ /** Map of Web Audio API nodes for each audio element */
331
+ webAudioNodes?: Map<HTMLAudioElement, WebAudioNodeSet>;
295
332
  }
296
333
  /**
297
334
  * Easing function types for smooth volume transitions and animations
package/dist/types.js CHANGED
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  /**
3
- * @fileoverview Type definitions for the audio-channel-queue package
3
+ * @fileoverview Type definitions for the audioq package
4
4
  */
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
6
  exports.TimerType = exports.FadeType = exports.EasingType = exports.AudioErrorType = exports.GLOBAL_PROGRESS_KEY = exports.MAX_CHANNELS = void 0;
package/dist/utils.d.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  /**
2
- * @fileoverview Utility functions for the audio-channel-queue package
2
+ * @fileoverview Utility functions for the audioq package
3
3
  */
4
4
  import { AudioInfo, QueueSnapshot, ExtendedAudioQueueChannel } from './types';
5
5
  /**
package/dist/utils.js CHANGED
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  /**
3
- * @fileoverview Utility functions for the audio-channel-queue package
3
+ * @fileoverview Utility functions for the audioq package
4
4
  */
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
6
  exports.cleanWebpackFilename = exports.createQueueSnapshot = exports.getAudioInfoFromElement = exports.extractFileName = exports.sanitizeForDisplay = exports.validateAudioUrl = void 0;