audio-channel-queue 1.5.0 → 1.7.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 CHANGED
@@ -1,5 +1,18 @@
1
1
  # Audio Channel Queue
2
- The purpose of this package is to help queue audio files so they do not play on top of each other. You can also enqueue audio files to different queues. This allows you to play sounds concurrently, but not have them overlap in their given audio queue. The package also supports real-time audio progress tracking, duration information, and playback metadata! 🎵📊
2
+ The purpose of this package is to help manage the playback of audio files.
3
+
4
+ ## 🌟 Key Features
5
+
6
+ - ✅ **Multi-channel queue management** - Independent audio queues for concurrent playback
7
+ - ✅ **Pause/Resume functionality** - Full playback control for individual channels or all channels
8
+ - ✅ **Volume control with ducking** - Dynamic volume management and automatic background audio reduction
9
+ - ✅ **Loop support** - Seamless audio looping for background music and ambient sounds
10
+ - ✅ **Priority queueing** - Add urgent audio to the front of any queue
11
+ - ✅ **Real-time progress tracking** - Comprehensive playback monitoring and metadata
12
+ - ✅ **Event-driven architecture** - Extensive callback system for UI integration
13
+ - ✅ **TypeScript support** - Full type definitions and IntelliSense support
14
+ - ✅ **Zero dependencies** - Lightweight and self-contained
15
+ - ✅ **Backward compatible** - All existing APIs continue to work
3
16
 
4
17
  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 🐓.
5
18
 
@@ -9,6 +22,26 @@ NPM package can be found [here](https://www.npmjs.com/package/audio-channel-queu
9
22
 
10
23
  GitHub Repo can be found [here](https://github.com/tonycarpenter21/audio-channel-queue).
11
24
 
25
+ ## 🌐 Browser Compatibility
26
+
27
+ This package is designed for **browser environments** and uses the Web Audio API (`HTMLAudioElement`). It is **not** intended for Node.js server-side use.
28
+
29
+ ### ✅ **Supported Browsers:**
30
+ - **Chrome 51+** (June 2016)
31
+ - **Firefox 54+** (June 2017)
32
+ - **Safari 10+** (September 2016)
33
+ - **Edge 15+** (April 2017)
34
+ - **Mobile browsers** with HTML5 audio support
35
+
36
+ ### 🛠️ **Development Requirements:**
37
+ - **Node.js 14+** (for building and testing only)
38
+ - **TypeScript 4.5+** (included in devDependencies)
39
+
40
+ ### ⚠️ **Not Supported:**
41
+ - Node.js server environments (no HTMLAudioElement)
42
+ - Internet Explorer (lacks ES6 support)
43
+ - Web Workers (no DOM access)
44
+
12
45
  ## Architecture & Code Organization 🏗️
13
46
 
14
47
  Modular architecture for maintainability and extensibility:
@@ -18,6 +51,8 @@ src/
18
51
  ├── index.ts # Main entry point with organized exports
19
52
  ├── types.ts # TypeScript interfaces and type definitions
20
53
  ├── core.ts # Core queue management functions
54
+ ├── pause.ts # Pause and resume functionality
55
+ ├── volume.ts # Volume control and ducking management
21
56
  ├── info.ts # Audio information and progress tracking
22
57
  ├── events.ts # Event handling and emission logic
23
58
  └── utils.ts # Helper functions and utilities
@@ -31,51 +66,139 @@ Install this package by running either of these commands (typescript packages ar
31
66
  ## Basic Queue Management Functions:
32
67
 
33
68
  ### Queue Audio
34
- ```queueAudio(audioFileGoesHere, channelNumber);```
35
- Use the `queueAudio()` function to add a file to the queue and start playing it automatically. It takes two arguments:
69
+ ```queueAudio(audioFileGoesHere, channelNumber, options);```
70
+ Use the `queueAudio()` function to add a file to the queue and start playing it automatically. It takes three arguments:
36
71
  - The first argument is an imported sound file.
37
- - The second argument is optional and it allows you to choose a different queue channel.
72
+ - The second argument is optional and it allows you to choose a different queue channel.
73
+ - The third argument is optional configuration for loop, volume, and priority.
74
+
75
+ ### Queue Audio with Priority
76
+ ```queueAudioPriority(audioFileGoesHere, channelNumber, options);```
77
+ Use the `queueAudioPriority()` function to add a file to the front of the queue (plays after current audio finishes). Perfect for urgent announcements!
38
78
 
39
79
  ### Stop Current Audio
40
80
  ```stopCurrentAudioInChannel(queueChannelNumberGoesHere);```
41
- Use the `stopCurrentAudioInChannel()` function to stop the current playback of a file in a queue and start playing the next one automatically. It takes one argument:
42
- - The first argument is optional and it allows you to choose a different queue channel. If you are only using the default channel, just use `stopCurrentAudioInChannel()`.
81
+ Use the `stopCurrentAudioInChannel()` function to stop the current playback of a file in a queue and start playing the next one automatically.
43
82
 
44
83
  ### Stop All Audio in Channel
45
84
  ```stopAllAudioInChannel(queueChannelNumberGoesHere);```
46
- Use the `stopAllAudioInChannel()` function to stop the current playback of all files in a queue and removes all enqueued files. It takes one argument:
47
- - The first argument is optional and it allows you to choose a different queue channel. If you are only using the default channel, just use `stopAllAudioInChannel()`.
85
+ Use the `stopAllAudioInChannel()` function to stop the current playback of all files in a queue and removes all enqueued files.
48
86
 
49
87
  ### Stop All Audio
50
88
  ```stopAllAudio();```
51
89
  Use the `stopAllAudio()` function to stop the current playback of all files in all queues. It takes no arguments.
52
90
 
91
+ ## 🎛️ Volume Control Functions:
92
+
93
+ ### Set Channel Volume
94
+ ```setChannelVolume(channelNumber, volume);```
95
+ Set the volume for a specific channel (0-1 range).
96
+ ```typescript
97
+ setChannelVolume(0, 0.5); // Set channel 0 to 50% volume
98
+ setChannelVolume(1, 0.8); // Set channel 1 to 80% volume
99
+ ```
100
+
101
+ ### Get Channel Volume
102
+ ```getChannelVolume(channelNumber);```
103
+ Get the current volume level for a specific channel.
104
+ ```typescript
105
+ const volume = getChannelVolume(0);
106
+ console.log(`Channel 0 volume: ${volume * 100}%`);
107
+ ```
108
+
109
+ ### Set All Channels Volume
110
+ ```setAllChannelsVolume(volume);```
111
+ Set the same volume level for all channels.
112
+ ```typescript
113
+ setAllChannelsVolume(0.6); // Set all channels to 60% volume
114
+ ```
115
+
116
+ ### Volume Ducking (Background Audio Reduction)
117
+ ```setVolumeDucking(config);```
118
+ Automatically reduce other channels' volume when priority audio plays - perfect for voice announcements over background music!
119
+ ```typescript
120
+ // When channel 1 plays, reduce all other channels to 20% volume
121
+ setVolumeDucking({
122
+ priorityChannel: 1,
123
+ priorityVolume: 1.0,
124
+ duckingVolume: 0.2
125
+ });
126
+ ```
127
+
128
+ ```clearVolumeDucking();```
129
+ Remove volume ducking configuration from all channels.
130
+
131
+ ## ⏯️ Pause/Resume Functions:
132
+
133
+ ### Pause Channel
134
+ ```pauseChannel(channelNumber);```
135
+ Pause audio playback in a specific channel.
136
+ ```typescript
137
+ await pauseChannel(0); // Pause audio in channel 0
138
+ await pauseChannel(); // Pause audio in default channel
139
+ ```
140
+
141
+ ### Resume Channel
142
+ ```resumeChannel(channelNumber);```
143
+ Resume audio playback in a specific channel.
144
+ ```typescript
145
+ await resumeChannel(0); // Resume audio in channel 0
146
+ ```
147
+
148
+ ### Toggle Pause
149
+ ```togglePauseChannel(channelNumber);```
150
+ Toggle between pause and resume states.
151
+ ```typescript
152
+ await togglePauseChannel(0); // Pause if playing, resume if paused
153
+ ```
154
+
155
+ ### Pause/Resume All Channels
156
+ ```pauseAllChannels();``` and ```resumeAllChannels();```
157
+ Control all channels simultaneously.
158
+ ```typescript
159
+ await pauseAllChannels(); // Emergency pause - everything stops
160
+ await resumeAllChannels(); // Resume everything that was paused
161
+ ```
162
+
163
+ ### Global Toggle Pause/Resume
164
+ ```togglePauseAllChannels();```
165
+ Smart toggle that pauses all channels if any are playing, or resumes all if all are paused.
166
+ ```typescript
167
+ await togglePauseAllChannels(); // Pause all if any playing, resume all if all paused
168
+ ```
169
+
170
+ ### Check Pause State
171
+ ```isChannelPaused(channelNumber);``` and ```getAllChannelsPauseState();```
172
+ ```typescript
173
+ const isPaused = isChannelPaused(0);
174
+ const allPauseStates = getAllChannelsPauseState();
175
+ ```
176
+
53
177
  ## Audio Information and Progress Tracking:
54
178
 
55
179
  ### AudioInfo Interface
56
- The package now provides detailed information about audio playback through the `AudioInfo` interface:
180
+ The package provides detailed information about audio playback through the enhanced `AudioInfo` interface:
57
181
  ```typescript
58
182
  interface AudioInfo {
59
183
  currentTime: number; // Current position in milliseconds
60
184
  duration: number; // Total duration in milliseconds
61
185
  fileName: string; // Extracted filename from URL
186
+ isLooping: boolean; // Whether audio is set to loop
187
+ isPaused: boolean; // Whether audio is currently paused
62
188
  isPlaying: boolean; // Whether audio is currently playing
63
189
  progress: number; // Progress as percentage (0-1)
64
190
  src: string; // Audio file source URL
191
+ volume: number; // Current volume level (0-1)
65
192
  }
66
193
  ```
67
194
 
68
195
  ### Get Current Audio Info
69
196
  ```getCurrentAudioInfo(channelNumber);```
70
197
  Get information about the currently playing audio in a specific channel. Returns `AudioInfo | null`.
71
- - `channelNumber` (optional): The channel number (defaults to 0)
72
- - Returns `null` if no audio is currently playing in the channel
73
198
 
74
199
  ### Get All Channels Info
75
200
  ```getAllChannelsInfo();```
76
201
  Get audio information for all channels. Returns an array of `AudioInfo | null` objects.
77
- - Returns an array where each index corresponds to a channel number
78
- - `null` values indicate channels with no currently playing audio
79
202
 
80
203
  ### Queue State Management
81
204
  ```getQueueSnapshot(channelNumber);```
@@ -84,61 +207,63 @@ Get a complete snapshot of the queue state for a specific channel. Returns `Queu
84
207
  ```typescript
85
208
  interface QueueSnapshot {
86
209
  channelNumber: number; // Channel this snapshot represents
87
- totalItems: number; // Total items in queue
88
210
  currentIndex: number; // Index of currently playing item
211
+ isPaused: boolean; // Whether current audio is paused
89
212
  items: Array<{ // Array of queue items with metadata
90
- src: string;
91
- fileName: string;
92
213
  duration: number;
214
+ fileName: string;
93
215
  isCurrentlyPlaying: boolean;
216
+ isLooping: boolean;
217
+ src: string;
218
+ volume: number;
94
219
  }>;
220
+ totalItems: number; // Total items in queue
221
+ volume: number; // Current channel volume (0-1)
95
222
  }
96
223
  ```
97
224
 
98
225
  ### Real-time Progress Tracking
99
226
  ```onAudioProgress(channelNumber, callback);```
100
227
  Subscribe to real-time progress updates for a specific channel.
101
- - `channelNumber`: The channel number to monitor
102
- - `callback`: Function that receives `AudioInfo` updates
103
228
 
104
229
  ```offAudioProgress(channelNumber);```
105
230
  Remove all progress listeners for a specific channel.
106
- - `channelNumber`: The channel number to stop monitoring
107
231
 
108
- ### Queue Change Events
232
+ ### Enhanced Event System
109
233
  ```onQueueChange(channelNumber, callback);```
110
234
  Subscribe to queue change events for visual updates.
111
- - Triggered when items are added, removed, or when playback moves to next item
112
- - Perfect for updating UI queue displays
113
235
 
114
- ```offQueueChange(channelNumber);```
115
- Remove queue change listeners for a specific channel.
116
-
117
- ### Audio Lifecycle Events
118
236
  ```onAudioStart(channelNumber, callback);```
119
237
  Subscribe to audio start events.
120
- - Triggered when audio begins playing (after metadata loads)
121
- - Provides duration, filename, and source information
122
238
 
123
239
  ```onAudioComplete(channelNumber, callback);```
124
240
  Subscribe to audio completion events.
125
- - Triggered when audio finishes or is stopped
126
- - Includes remaining queue count information
127
241
 
128
- ### Example Usage with Progress Tracking:
242
+ ```onAudioPause(channelNumber, callback);```
243
+ Subscribe to audio pause events.
244
+
245
+ ```onAudioResume(channelNumber, callback);```
246
+ Subscribe to audio resume events.
247
+
248
+ ### Example Usage with All New Features:
129
249
 
130
250
  `App.tsx`
131
251
  ```typescript
132
- import redTeamWins from './audio/red_team_wins.mp3';
252
+ import backgroundMusic from './audio/background.mp3';
253
+ import announcement from './audio/announcement.wav';
133
254
  import {
134
255
  queueAudio,
135
- getCurrentAudioInfo,
136
- onAudioProgress,
137
- offAudioProgress,
256
+ queueAudioPriority,
257
+ getCurrentAudioInfo,
258
+ pauseChannel,
259
+ resumeChannel,
260
+ togglePauseAllChannels,
261
+ setChannelVolume,
262
+ setVolumeDucking,
263
+ onAudioProgress,
264
+ onAudioPause,
265
+ onAudioResume,
138
266
  onQueueChange,
139
- onAudioStart,
140
- onAudioComplete,
141
- getQueueSnapshot,
142
267
  AudioInfo,
143
268
  QueueSnapshot
144
269
  } from 'audio-channel-queue';
@@ -147,89 +272,145 @@ import { useState, useEffect } from 'react';
147
272
  function App(): JSX.Element {
148
273
  const [currentInfo, setCurrentInfo] = useState<AudioInfo | null>(null);
149
274
  const [queueSnapshot, setQueueSnapshot] = useState<QueueSnapshot | null>(null);
150
- const [isTracking, setIsTracking] = useState(false);
151
-
152
- const playSound = () => {
153
- queueAudio(redTeamWins);
154
-
155
- // Get initial audio info
156
- setTimeout(() => {
157
- const info = getCurrentAudioInfo();
158
- setCurrentInfo(info);
159
- }, 100);
160
- };
275
+ const [isPaused, setIsPaused] = useState(false);
276
+
277
+ useEffect(() => {
278
+ // Set up background music with looping
279
+ const setupBackgroundMusic = async () => {
280
+ await queueAudio(backgroundMusic, 0, {
281
+ loop: true,
282
+ volume: 0.3
283
+ });
284
+ setChannelVolume(0, 0.3); // 30% volume for background
285
+ };
286
+
287
+ // Configure volume ducking for announcements
288
+ setVolumeDucking({
289
+ priorityChannel: 1, // Announcements on channel 1
290
+ priorityVolume: 1.0, // Full volume for announcements
291
+ duckingVolume: 0.1 // Reduce background to 10% during announcements
292
+ });
161
293
 
162
- const startTracking = () => {
163
- setIsTracking(true);
164
-
165
- // Track real-time progress
294
+ // Set up event listeners
166
295
  onAudioProgress(0, (info: AudioInfo) => {
167
296
  setCurrentInfo(info);
168
- console.log(`Progress: ${(info.progress * 100).toFixed(1)}%`);
169
297
  });
170
298
 
171
- // Track queue changes
172
299
  onQueueChange(0, (snapshot: QueueSnapshot) => {
173
300
  setQueueSnapshot(snapshot);
174
- console.log(`Queue updated: ${snapshot.totalItems} items`);
175
301
  });
176
302
 
177
- // Track audio lifecycle
178
- onAudioStart(0, (info) => {
179
- console.log(`Started playing: ${info.fileName}`);
303
+ onAudioPause(0, (channelNumber, info) => {
304
+ setIsPaused(true);
305
+ console.log(`Channel ${channelNumber} paused: ${info.fileName}`);
180
306
  });
181
307
 
182
- onAudioComplete(0, (info) => {
183
- console.log(`Completed: ${info.fileName}, ${info.remainingInQueue} remaining`);
308
+ onAudioResume(0, (channelNumber, info) => {
309
+ setIsPaused(false);
310
+ console.log(`Channel ${channelNumber} resumed: ${info.fileName}`);
184
311
  });
312
+
313
+ setupBackgroundMusic();
314
+ }, []);
315
+
316
+ const playAnnouncement = async () => {
317
+ // Priority queue - plays next, automatically ducks background music
318
+ await queueAudioPriority(announcement, 1);
185
319
  };
186
320
 
187
- const stopTracking = () => {
188
- setIsTracking(false);
189
- offAudioProgress(0);
190
- offQueueChange(0);
321
+ const toggleBackgroundMusic = async () => {
322
+ if (isPaused) {
323
+ await resumeChannel(0);
324
+ } else {
325
+ await pauseChannel(0);
326
+ }
191
327
  };
192
328
 
193
- const addMoreAudio = () => {
194
- queueAudio('./sounds/notification.wav');
195
- queueAudio('./sounds/alert.mp3');
329
+ const adjustBackgroundVolume = (volume: number) => {
330
+ setChannelVolume(0, volume);
331
+ };
332
+
333
+ const emergencyToggleAll = async () => {
334
+ await togglePauseAllChannels(); // Smart toggle - pause all if any playing, resume all if all paused
196
335
  };
197
336
 
198
337
  return (
199
338
  <div className="App">
200
- <button onClick={playSound}>Play Sound</button>
201
- <button onClick={addMoreAudio}>Add More to Queue</button>
202
- <button onClick={startTracking} disabled={isTracking}>
203
- Start Progress Tracking
204
- </button>
205
- <button onClick={stopTracking} disabled={!isTracking}>
206
- Stop Progress Tracking
207
- </button>
339
+ <h2>Audio Control Center</h2>
208
340
 
341
+ {/* Background Music Controls */}
342
+ <div className="background-controls">
343
+ <h3>Background Music</h3>
344
+ <button onClick={toggleBackgroundMusic}>
345
+ {isPaused ? '▶️ Resume' : '⏸️ Pause'}
346
+ </button>
347
+ <label>
348
+ Volume:
349
+ <input
350
+ type="range"
351
+ min="0"
352
+ max="1"
353
+ step="0.1"
354
+ onChange={(e) => adjustBackgroundVolume(Number(e.target.value))}
355
+ />
356
+ </label>
357
+ </div>
358
+
359
+ {/* Announcement Controls */}
360
+ <div className="announcement-controls">
361
+ <h3>Announcements</h3>
362
+ <button onClick={playAnnouncement}>
363
+ 📢 Play Announcement (Auto-ducks background)
364
+ </button>
365
+ </div>
366
+
367
+ {/* Emergency Controls */}
368
+ <div className="emergency-controls">
369
+ <h3>Emergency Controls</h3>
370
+ <button onClick={emergencyToggleAll}>
371
+ 🚨 Toggle All Audio (Smart Pause/Resume)
372
+ </button>
373
+ </div>
374
+
375
+ {/* Current Audio Info */}
209
376
  {currentInfo && (
210
- <div>
377
+ <div className="current-info">
211
378
  <h3>Now Playing:</h3>
212
- <p>File: {currentInfo.fileName}</p>
213
- <p>Duration: {(currentInfo.duration / 1000).toFixed(1)}s</p>
214
- <p>Current Time: {(currentInfo.currentTime / 1000).toFixed(1)}s</p>
215
- <p>Progress: {(currentInfo.progress * 100).toFixed(1)}%</p>
216
- <p>Playing: {currentInfo.isPlaying ? 'Yes' : 'No'}</p>
379
+ <p>🎵 {currentInfo.fileName}</p>
380
+ <p>⏱️ {(currentInfo.currentTime / 1000).toFixed(1)}s / {(currentInfo.duration / 1000).toFixed(1)}s</p>
381
+ <p>📊 Progress: {(currentInfo.progress * 100).toFixed(1)}%</p>
382
+ <p>🔊 Volume: {(currentInfo.volume * 100).toFixed(0)}%</p>
383
+ <p>🔄 Looping: {currentInfo.isLooping ? 'Yes' : 'No'}</p>
384
+ <p>⏸️ Paused: {currentInfo.isPaused ? 'Yes' : 'No'}</p>
385
+
386
+ {/* Progress Bar */}
387
+ <div className="progress-bar">
388
+ <div
389
+ className="progress-fill"
390
+ style={{ width: `${currentInfo.progress * 100}%` }}
391
+ />
392
+ </div>
217
393
  </div>
218
394
  )}
219
395
 
396
+ {/* Queue Status */}
220
397
  {queueSnapshot && (
221
- <div>
222
- <h3>Queue Status:</h3>
223
- <p>Channel: {queueSnapshot.channelNumber}</p>
224
- <p>Total Items: {queueSnapshot.totalItems}</p>
225
- <p>Current Index: {queueSnapshot.currentIndex}</p>
398
+ <div className="queue-status">
399
+ <h3>Queue Status (Channel {queueSnapshot.channelNumber}):</h3>
400
+ <p>📋 Total Items: {queueSnapshot.totalItems}</p>
401
+ <p>🔊 Channel Volume: {(queueSnapshot.volume * 100).toFixed(0)}%</p>
402
+ <p>⏸️ Channel Paused: {queueSnapshot.isPaused ? 'Yes' : 'No'}</p>
403
+
404
+ <h4>Queue Items:</h4>
226
405
  <ul>
227
406
  {queueSnapshot.items.map((item, index) => (
228
407
  <li key={index} style={{
229
- fontWeight: item.isCurrentlyPlaying ? 'bold' : 'normal'
408
+ fontWeight: item.isCurrentlyPlaying ? 'bold' : 'normal',
409
+ color: item.isCurrentlyPlaying ? '#007bff' : 'inherit'
230
410
  }}>
231
411
  {item.fileName} ({(item.duration / 1000).toFixed(1)}s)
232
- {item.isCurrentlyPlaying && ' ▶️'}
412
+ {item.isCurrentlyPlaying && ' ▶️ PLAYING'}
413
+ {item.isLooping && ' 🔄 LOOP'}
233
414
  </li>
234
415
  ))}
235
416
  </ul>
@@ -242,6 +423,45 @@ function App(): JSX.Element {
242
423
  export default App;
243
424
  ```
244
425
 
426
+ ### Advanced Usage Examples:
427
+
428
+ #### Gaming Audio System
429
+ ```typescript
430
+ // Background music (channel 0)
431
+ await queueAudio('./music/background.mp3', 0, { loop: true, volume: 0.4 });
432
+
433
+ // Sound effects (channel 1)
434
+ await queueAudio('./sfx/explosion.wav', 1);
435
+
436
+ // Voice chat (channel 2) - ducks other audio
437
+ setVolumeDucking({
438
+ priorityChannel: 2,
439
+ priorityVolume: 1.0,
440
+ duckingVolume: 0.2
441
+ });
442
+
443
+ // Critical game announcements (priority)
444
+ await queueAudioPriority('./voice/game-over.wav', 2);
445
+ ```
446
+
447
+ #### Podcast/Radio App
448
+ ```typescript
449
+ // Main content (channel 0)
450
+ await queueAudio('./podcast/episode1.mp3', 0);
451
+
452
+ // Jingles and ads (channel 1) - interrupt at natural breaks
453
+ await queueAudioPriority('./ads/sponsor.mp3', 0);
454
+
455
+ // Background ambient (channel 2)
456
+ await queueAudio('./ambient/coffee-shop.mp3', 2, {
457
+ loop: true,
458
+ volume: 0.1
459
+ });
460
+
461
+ // Pause everything for phone calls
462
+ onPhoneCall(() => pauseAllChannels());
463
+ ```
464
+
245
465
  ### Legacy Access
246
466
  If you need to expose the queue array for logging or other purposes, it is available to you as well: `audioChannels`.
247
467
 
@@ -258,17 +478,22 @@ declare module '*.mp3' {
258
478
 
259
479
  ## Features:
260
480
  - ✅ Queue management across multiple channels
261
- - ✅ Real-time audio progress tracking
262
- - ✅ Audio duration and metadata extraction
481
+ - ✅ Pause and resume functionality for individual channels and all channels
482
+ - ✅ Volume control with per-channel precision (0-1 range)
483
+ - ✅ Volume ducking for priority audio (automatic background reduction)
484
+ - ✅ Audio looping capabilities for background music and ambient sounds
485
+ - ✅ Priority queueing system for urgent audio playback
486
+ - ✅ Real-time audio progress tracking with enhanced metadata
487
+ - ✅ Comprehensive event system (start, complete, pause, resume, queue changes)
488
+ - ✅ Audio duration and metadata extraction with loop and volume info
263
489
  - ✅ Automatic filename extraction from URLs
264
- - ✅ Queue state snapshots and change events
265
- - ✅ Audio lifecycle events (start/complete)
490
+ - ✅ Queue state snapshots with pause and volume information
266
491
  - ✅ TypeScript support with full type definitions
267
492
  - ✅ Modular architecture with clean separation of concerns
268
493
  - ✅ Comprehensive JSDoc documentation with examples
269
494
  - ✅ Zero dependencies
270
495
  - ✅ Backward compatible with existing implementations
271
- - ✅ Comprehensive error handling
496
+ - ✅ Comprehensive error handling with graceful degradation
272
497
 
273
498
  ## Development & Contributing 🛠️
274
499
 
@@ -276,14 +501,16 @@ The package uses a modular TypeScript architecture that makes it easy to contrib
276
501
 
277
502
  ### File Structure:
278
503
  - **`src/types.ts`** - Interface definitions and type exports
279
- - **`src/core.ts`** - Main queue management logic
504
+ - **`src/core.ts`** - Main queue management logic and priority queueing
505
+ - **`src/pause.ts`** - Pause and resume functionality
506
+ - **`src/volume.ts`** - Volume control and ducking management
280
507
  - **`src/info.ts`** - Audio information and progress tracking
281
508
  - **`src/events.ts`** - Event system and callback management
282
509
  - **`src/utils.ts`** - Helper functions and utilities
283
510
  - **`src/index.ts`** - Public API exports
284
511
 
285
512
  ### Testing:
286
- The package includes a comprehensive test suite with 64+ tests covering all functionality:
513
+ The package includes a comprehensive test suite with 74+ tests covering all functionality:
287
514
 
288
515
  ```bash
289
516
  # Run tests once
package/dist/core.d.ts CHANGED
@@ -1,18 +1,36 @@
1
1
  /**
2
2
  * @fileoverview Core queue management functions for the audio-channel-queue package
3
3
  */
4
+ import { AudioQueueOptions } from './types';
4
5
  /**
5
6
  * Queues an audio file to a specific channel and starts playing if it's the first in queue
6
7
  * @param audioUrl - The URL of the audio file to queue
7
8
  * @param channelNumber - The channel number to queue the audio to (defaults to 0)
9
+ * @param options - Optional configuration for the audio file
8
10
  * @returns Promise that resolves when the audio is queued and starts playing (if first in queue)
9
11
  * @example
10
12
  * ```typescript
11
13
  * await queueAudio('https://example.com/song.mp3', 0);
12
14
  * await queueAudio('./sounds/notification.wav'); // Uses default channel 0
15
+ * await queueAudio('./music/loop.mp3', 1, { loop: true }); // Loop the audio
16
+ * await queueAudio('./urgent.wav', 0, { addToFront: true }); // Add to front of queue
13
17
  * ```
14
18
  */
15
- export declare const queueAudio: (audioUrl: string, channelNumber?: number) => Promise<void>;
19
+ export declare const queueAudio: (audioUrl: string, channelNumber?: number, options?: AudioQueueOptions) => Promise<void>;
20
+ /**
21
+ * Adds an audio file to the front of the queue in a specific channel
22
+ * This is a convenience function that places the audio right after the currently playing track
23
+ * @param audioUrl - The URL of the audio file to queue
24
+ * @param channelNumber - The channel number to queue the audio to (defaults to 0)
25
+ * @param options - Optional configuration for the audio file
26
+ * @returns Promise that resolves when the audio is queued
27
+ * @example
28
+ * ```typescript
29
+ * await queueAudioPriority('./urgent-announcement.wav', 0);
30
+ * await queueAudioPriority('./priority-sound.mp3', 1, { loop: true });
31
+ * ```
32
+ */
33
+ export declare const queueAudioPriority: (audioUrl: string, channelNumber?: number, options?: AudioQueueOptions) => Promise<void>;
16
34
  /**
17
35
  * Plays the audio queue for a specific channel
18
36
  * @param channelNumber - The channel number to play
@@ -28,26 +46,26 @@ export declare const playAudioQueue: (channelNumber: number) => Promise<void>;
28
46
  * @param channelNumber - The channel number (defaults to 0)
29
47
  * @example
30
48
  * ```typescript
31
- * stopCurrentAudioInChannel(0); // Stop current audio in channel 0
32
- * stopCurrentAudioInChannel(); // Stop current audio in default channel
49
+ * await stopCurrentAudioInChannel(); // Stop current audio in default channel (0)
50
+ * await stopCurrentAudioInChannel(1); // Stop current audio in channel 1
33
51
  * ```
34
52
  */
35
- export declare const stopCurrentAudioInChannel: (channelNumber?: number) => void;
53
+ export declare const stopCurrentAudioInChannel: (channelNumber?: number) => Promise<void>;
36
54
  /**
37
55
  * Stops all audio in a specific channel and clears the entire queue
38
56
  * @param channelNumber - The channel number (defaults to 0)
39
57
  * @example
40
58
  * ```typescript
41
- * stopAllAudioInChannel(0); // Clear all audio in channel 0
42
- * stopAllAudioInChannel(); // Clear all audio in default channel
59
+ * await stopAllAudioInChannel(); // Clear all audio in default channel (0)
60
+ * await stopAllAudioInChannel(1); // Clear all audio in channel 1
43
61
  * ```
44
62
  */
45
- export declare const stopAllAudioInChannel: (channelNumber?: number) => void;
63
+ export declare const stopAllAudioInChannel: (channelNumber?: number) => Promise<void>;
46
64
  /**
47
65
  * Stops all audio across all channels and clears all queues
48
66
  * @example
49
67
  * ```typescript
50
- * stopAllAudio(); // Emergency stop - clears everything
68
+ * await stopAllAudio(); // Emergency stop - clears everything
51
69
  * ```
52
70
  */
53
- export declare const stopAllAudio: () => void;
71
+ export declare const stopAllAudio: () => Promise<void>;