audio-channel-queue 1.5.0 → 1.6.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/info.js CHANGED
@@ -3,7 +3,7 @@
3
3
  * @fileoverview Audio information and progress tracking functions for the audio-channel-queue package
4
4
  */
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.onAudioComplete = exports.onAudioStart = exports.offQueueChange = exports.onQueueChange = exports.offAudioProgress = exports.onAudioProgress = exports.getQueueSnapshot = exports.getAllChannelsInfo = exports.getCurrentAudioInfo = exports.audioChannels = void 0;
6
+ exports.offAudioResume = exports.offAudioPause = exports.onAudioResume = exports.onAudioPause = exports.onAudioComplete = exports.onAudioStart = exports.offQueueChange = exports.onQueueChange = exports.offAudioProgress = exports.onAudioProgress = exports.getQueueSnapshot = exports.getAllChannelsInfo = exports.getCurrentAudioInfo = exports.audioChannels = void 0;
7
7
  const utils_1 = require("./utils");
8
8
  const events_1 = require("./events");
9
9
  /**
@@ -29,7 +29,7 @@ const getCurrentAudioInfo = (channelNumber = 0) => {
29
29
  return null;
30
30
  }
31
31
  const currentAudio = channel.queue[0];
32
- return (0, utils_1.getAudioInfoFromElement)(currentAudio);
32
+ return (0, utils_1.getAudioInfoFromElement)(currentAudio, channelNumber, exports.audioChannels);
33
33
  };
34
34
  exports.getCurrentAudioInfo = getCurrentAudioInfo;
35
35
  /**
@@ -86,10 +86,14 @@ const onAudioProgress = (channelNumber, callback) => {
86
86
  if (!exports.audioChannels[channelNumber]) {
87
87
  exports.audioChannels[channelNumber] = {
88
88
  audioCompleteCallbacks: new Set(),
89
+ audioPauseCallbacks: new Set(),
90
+ audioResumeCallbacks: new Set(),
89
91
  audioStartCallbacks: new Set(),
92
+ isPaused: false,
90
93
  progressCallbacks: new Map(),
91
94
  queue: [],
92
- queueChangeCallbacks: new Set()
95
+ queueChangeCallbacks: new Set(),
96
+ volume: 1.0
93
97
  };
94
98
  }
95
99
  const channel = exports.audioChannels[channelNumber];
@@ -150,10 +154,14 @@ const onQueueChange = (channelNumber, callback) => {
150
154
  if (!exports.audioChannels[channelNumber]) {
151
155
  exports.audioChannels[channelNumber] = {
152
156
  audioCompleteCallbacks: new Set(),
157
+ audioPauseCallbacks: new Set(),
158
+ audioResumeCallbacks: new Set(),
153
159
  audioStartCallbacks: new Set(),
160
+ isPaused: false,
154
161
  progressCallbacks: new Map(),
155
162
  queue: [],
156
- queueChangeCallbacks: new Set()
163
+ queueChangeCallbacks: new Set(),
164
+ volume: 1.0
157
165
  };
158
166
  }
159
167
  const channel = exports.audioChannels[channelNumber];
@@ -194,10 +202,14 @@ const onAudioStart = (channelNumber, callback) => {
194
202
  if (!exports.audioChannels[channelNumber]) {
195
203
  exports.audioChannels[channelNumber] = {
196
204
  audioCompleteCallbacks: new Set(),
205
+ audioPauseCallbacks: new Set(),
206
+ audioResumeCallbacks: new Set(),
197
207
  audioStartCallbacks: new Set(),
208
+ isPaused: false,
198
209
  progressCallbacks: new Map(),
199
210
  queue: [],
200
- queueChangeCallbacks: new Set()
211
+ queueChangeCallbacks: new Set(),
212
+ volume: 1.0
201
213
  };
202
214
  }
203
215
  const channel = exports.audioChannels[channelNumber];
@@ -225,10 +237,14 @@ const onAudioComplete = (channelNumber, callback) => {
225
237
  if (!exports.audioChannels[channelNumber]) {
226
238
  exports.audioChannels[channelNumber] = {
227
239
  audioCompleteCallbacks: new Set(),
240
+ audioPauseCallbacks: new Set(),
241
+ audioResumeCallbacks: new Set(),
228
242
  audioStartCallbacks: new Set(),
243
+ isPaused: false,
229
244
  progressCallbacks: new Map(),
230
245
  queue: [],
231
- queueChangeCallbacks: new Set()
246
+ queueChangeCallbacks: new Set(),
247
+ volume: 1.0
232
248
  };
233
249
  }
234
250
  const channel = exports.audioChannels[channelNumber];
@@ -238,3 +254,99 @@ const onAudioComplete = (channelNumber, callback) => {
238
254
  channel.audioCompleteCallbacks.add(callback);
239
255
  };
240
256
  exports.onAudioComplete = onAudioComplete;
257
+ /**
258
+ * Subscribes to audio pause events for a specific channel
259
+ * @param channelNumber - The channel number to monitor
260
+ * @param callback - Function to call when audio is paused
261
+ * @example
262
+ * ```typescript
263
+ * onAudioPause(0, (channelNumber, info) => {
264
+ * showPauseIndicator();
265
+ * logPauseEvent(info.fileName, info.currentTime);
266
+ * });
267
+ * ```
268
+ */
269
+ const onAudioPause = (channelNumber, callback) => {
270
+ if (!exports.audioChannels[channelNumber]) {
271
+ exports.audioChannels[channelNumber] = {
272
+ audioCompleteCallbacks: new Set(),
273
+ audioPauseCallbacks: new Set(),
274
+ audioResumeCallbacks: new Set(),
275
+ audioStartCallbacks: new Set(),
276
+ isPaused: false,
277
+ progressCallbacks: new Map(),
278
+ queue: [],
279
+ queueChangeCallbacks: new Set(),
280
+ volume: 1.0
281
+ };
282
+ }
283
+ const channel = exports.audioChannels[channelNumber];
284
+ if (!channel.audioPauseCallbacks) {
285
+ channel.audioPauseCallbacks = new Set();
286
+ }
287
+ channel.audioPauseCallbacks.add(callback);
288
+ };
289
+ exports.onAudioPause = onAudioPause;
290
+ /**
291
+ * Subscribes to audio resume events for a specific channel
292
+ * @param channelNumber - The channel number to monitor
293
+ * @param callback - Function to call when audio is resumed
294
+ * @example
295
+ * ```typescript
296
+ * onAudioResume(0, (channelNumber, info) => {
297
+ * hidePauseIndicator();
298
+ * logResumeEvent(info.fileName, info.currentTime);
299
+ * });
300
+ * ```
301
+ */
302
+ const onAudioResume = (channelNumber, callback) => {
303
+ if (!exports.audioChannels[channelNumber]) {
304
+ exports.audioChannels[channelNumber] = {
305
+ audioCompleteCallbacks: new Set(),
306
+ audioPauseCallbacks: new Set(),
307
+ audioResumeCallbacks: new Set(),
308
+ audioStartCallbacks: new Set(),
309
+ isPaused: false,
310
+ progressCallbacks: new Map(),
311
+ queue: [],
312
+ queueChangeCallbacks: new Set(),
313
+ volume: 1.0
314
+ };
315
+ }
316
+ const channel = exports.audioChannels[channelNumber];
317
+ if (!channel.audioResumeCallbacks) {
318
+ channel.audioResumeCallbacks = new Set();
319
+ }
320
+ channel.audioResumeCallbacks.add(callback);
321
+ };
322
+ exports.onAudioResume = onAudioResume;
323
+ /**
324
+ * Removes pause event listeners for a specific channel
325
+ * @param channelNumber - The channel number
326
+ * @example
327
+ * ```typescript
328
+ * offAudioPause(0); // Stop receiving pause notifications for channel 0
329
+ * ```
330
+ */
331
+ const offAudioPause = (channelNumber) => {
332
+ const channel = exports.audioChannels[channelNumber];
333
+ if (!channel || !channel.audioPauseCallbacks)
334
+ return;
335
+ channel.audioPauseCallbacks.clear();
336
+ };
337
+ exports.offAudioPause = offAudioPause;
338
+ /**
339
+ * Removes resume event listeners for a specific channel
340
+ * @param channelNumber - The channel number
341
+ * @example
342
+ * ```typescript
343
+ * offAudioResume(0); // Stop receiving resume notifications for channel 0
344
+ * ```
345
+ */
346
+ const offAudioResume = (channelNumber) => {
347
+ const channel = exports.audioChannels[channelNumber];
348
+ if (!channel || !channel.audioResumeCallbacks)
349
+ return;
350
+ channel.audioResumeCallbacks.clear();
351
+ };
352
+ exports.offAudioResume = offAudioResume;
@@ -0,0 +1,87 @@
1
+ /**
2
+ * @fileoverview Pause and resume management functions for the audio-channel-queue package
3
+ */
4
+ /**
5
+ * Pauses the currently playing audio in a specific channel
6
+ * @param channelNumber - The channel number to pause (defaults to 0)
7
+ * @returns Promise that resolves when the audio is paused
8
+ * @example
9
+ * ```typescript
10
+ * await pauseChannel(0); // Pause audio in channel 0
11
+ * await pauseChannel(); // Pause audio in default channel
12
+ * ```
13
+ */
14
+ export declare const pauseChannel: (channelNumber?: number) => Promise<void>;
15
+ /**
16
+ * Resumes the currently paused audio in a specific channel
17
+ * @param channelNumber - The channel number to resume (defaults to 0)
18
+ * @returns Promise that resolves when the audio starts playing
19
+ * @example
20
+ * ```typescript
21
+ * await resumeChannel(0); // Resume audio in channel 0
22
+ * await resumeChannel(); // Resume audio in default channel
23
+ * ```
24
+ */
25
+ export declare const resumeChannel: (channelNumber?: number) => Promise<void>;
26
+ /**
27
+ * Toggles pause/resume state for a specific channel
28
+ * @param channelNumber - The channel number to toggle (defaults to 0)
29
+ * @returns Promise that resolves when the toggle is complete
30
+ * @example
31
+ * ```typescript
32
+ * await togglePauseChannel(0); // Toggle pause state for channel 0
33
+ * ```
34
+ */
35
+ export declare const togglePauseChannel: (channelNumber?: number) => Promise<void>;
36
+ /**
37
+ * Pauses all currently playing audio across all channels
38
+ * @returns Promise that resolves when all audio is paused
39
+ * @example
40
+ * ```typescript
41
+ * await pauseAllChannels(); // Pause everything
42
+ * ```
43
+ */
44
+ export declare const pauseAllChannels: () => Promise<void>;
45
+ /**
46
+ * Resumes all currently paused audio across all channels
47
+ * @returns Promise that resolves when all audio is resumed
48
+ * @example
49
+ * ```typescript
50
+ * await resumeAllChannels(); // Resume everything that was paused
51
+ * ```
52
+ */
53
+ export declare const resumeAllChannels: () => Promise<void>;
54
+ /**
55
+ * Checks if a specific channel is currently paused
56
+ * @param channelNumber - The channel number to check (defaults to 0)
57
+ * @returns True if the channel is paused, false otherwise
58
+ * @example
59
+ * ```typescript
60
+ * const isPaused = isChannelPaused(0);
61
+ * console.log(`Channel 0 is ${isPaused ? 'paused' : 'playing'}`);
62
+ * ```
63
+ */
64
+ export declare const isChannelPaused: (channelNumber?: number) => boolean;
65
+ /**
66
+ * Gets the pause state of all channels
67
+ * @returns Array of boolean values indicating pause state for each channel
68
+ * @example
69
+ * ```typescript
70
+ * const pauseStates = getAllChannelsPauseState();
71
+ * pauseStates.forEach((isPaused, index) => {
72
+ * console.log(`Channel ${index}: ${isPaused ? 'paused' : 'playing'}`);
73
+ * });
74
+ * ```
75
+ */
76
+ export declare const getAllChannelsPauseState: () => boolean[];
77
+ /**
78
+ * Toggles pause/resume state for all channels globally
79
+ * If any channels are currently playing, all channels will be paused
80
+ * If all channels are paused, all channels will be resumed
81
+ * @returns Promise that resolves when the toggle is complete
82
+ * @example
83
+ * ```typescript
84
+ * await togglePauseAllChannels(); // Pause all if any are playing, resume all if all are paused
85
+ * ```
86
+ */
87
+ export declare const togglePauseAllChannels: () => Promise<void>;
package/dist/pause.js ADDED
@@ -0,0 +1,186 @@
1
+ "use strict";
2
+ /**
3
+ * @fileoverview Pause and resume management functions for the audio-channel-queue package
4
+ */
5
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
6
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
7
+ return new (P || (P = Promise))(function (resolve, reject) {
8
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
9
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
10
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
11
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
12
+ });
13
+ };
14
+ Object.defineProperty(exports, "__esModule", { value: true });
15
+ exports.togglePauseAllChannels = exports.getAllChannelsPauseState = exports.isChannelPaused = exports.resumeAllChannels = exports.pauseAllChannels = exports.togglePauseChannel = exports.resumeChannel = exports.pauseChannel = void 0;
16
+ const info_1 = require("./info");
17
+ const utils_1 = require("./utils");
18
+ const events_1 = require("./events");
19
+ /**
20
+ * Pauses the currently playing audio in a specific channel
21
+ * @param channelNumber - The channel number to pause (defaults to 0)
22
+ * @returns Promise that resolves when the audio is paused
23
+ * @example
24
+ * ```typescript
25
+ * await pauseChannel(0); // Pause audio in channel 0
26
+ * await pauseChannel(); // Pause audio in default channel
27
+ * ```
28
+ */
29
+ const pauseChannel = (...args_1) => __awaiter(void 0, [...args_1], void 0, function* (channelNumber = 0) {
30
+ const channel = info_1.audioChannels[channelNumber];
31
+ if (channel && channel.queue.length > 0) {
32
+ const currentAudio = channel.queue[0];
33
+ if (!currentAudio.paused && !currentAudio.ended) {
34
+ currentAudio.pause();
35
+ channel.isPaused = true;
36
+ const audioInfo = (0, utils_1.getAudioInfoFromElement)(currentAudio, channelNumber, info_1.audioChannels);
37
+ if (audioInfo) {
38
+ (0, events_1.emitAudioPause)(channelNumber, audioInfo, info_1.audioChannels);
39
+ }
40
+ }
41
+ }
42
+ });
43
+ exports.pauseChannel = pauseChannel;
44
+ /**
45
+ * Resumes the currently paused audio in a specific channel
46
+ * @param channelNumber - The channel number to resume (defaults to 0)
47
+ * @returns Promise that resolves when the audio starts playing
48
+ * @example
49
+ * ```typescript
50
+ * await resumeChannel(0); // Resume audio in channel 0
51
+ * await resumeChannel(); // Resume audio in default channel
52
+ * ```
53
+ */
54
+ const resumeChannel = (...args_1) => __awaiter(void 0, [...args_1], void 0, function* (channelNumber = 0) {
55
+ const channel = info_1.audioChannels[channelNumber];
56
+ if (channel && channel.queue.length > 0) {
57
+ const currentAudio = channel.queue[0];
58
+ // Only resume if both the channel is marked as paused AND the audio element is actually paused
59
+ if (channel.isPaused && currentAudio.paused && !currentAudio.ended) {
60
+ yield currentAudio.play();
61
+ channel.isPaused = false;
62
+ const audioInfo = (0, utils_1.getAudioInfoFromElement)(currentAudio, channelNumber, info_1.audioChannels);
63
+ if (audioInfo) {
64
+ (0, events_1.emitAudioResume)(channelNumber, audioInfo, info_1.audioChannels);
65
+ }
66
+ }
67
+ }
68
+ });
69
+ exports.resumeChannel = resumeChannel;
70
+ /**
71
+ * Toggles pause/resume state for a specific channel
72
+ * @param channelNumber - The channel number to toggle (defaults to 0)
73
+ * @returns Promise that resolves when the toggle is complete
74
+ * @example
75
+ * ```typescript
76
+ * await togglePauseChannel(0); // Toggle pause state for channel 0
77
+ * ```
78
+ */
79
+ const togglePauseChannel = (...args_1) => __awaiter(void 0, [...args_1], void 0, function* (channelNumber = 0) {
80
+ const channel = info_1.audioChannels[channelNumber];
81
+ if (channel && channel.queue.length > 0) {
82
+ const currentAudio = channel.queue[0];
83
+ if (currentAudio.paused) {
84
+ yield (0, exports.resumeChannel)(channelNumber);
85
+ }
86
+ else {
87
+ yield (0, exports.pauseChannel)(channelNumber);
88
+ }
89
+ }
90
+ });
91
+ exports.togglePauseChannel = togglePauseChannel;
92
+ /**
93
+ * Pauses all currently playing audio across all channels
94
+ * @returns Promise that resolves when all audio is paused
95
+ * @example
96
+ * ```typescript
97
+ * await pauseAllChannels(); // Pause everything
98
+ * ```
99
+ */
100
+ const pauseAllChannels = () => __awaiter(void 0, void 0, void 0, function* () {
101
+ const pausePromises = [];
102
+ info_1.audioChannels.forEach((_channel, index) => {
103
+ pausePromises.push((0, exports.pauseChannel)(index));
104
+ });
105
+ yield Promise.all(pausePromises);
106
+ });
107
+ exports.pauseAllChannels = pauseAllChannels;
108
+ /**
109
+ * Resumes all currently paused audio across all channels
110
+ * @returns Promise that resolves when all audio is resumed
111
+ * @example
112
+ * ```typescript
113
+ * await resumeAllChannels(); // Resume everything that was paused
114
+ * ```
115
+ */
116
+ const resumeAllChannels = () => __awaiter(void 0, void 0, void 0, function* () {
117
+ const resumePromises = [];
118
+ info_1.audioChannels.forEach((_channel, index) => {
119
+ resumePromises.push((0, exports.resumeChannel)(index));
120
+ });
121
+ yield Promise.all(resumePromises);
122
+ });
123
+ exports.resumeAllChannels = resumeAllChannels;
124
+ /**
125
+ * Checks if a specific channel is currently paused
126
+ * @param channelNumber - The channel number to check (defaults to 0)
127
+ * @returns True if the channel is paused, false otherwise
128
+ * @example
129
+ * ```typescript
130
+ * const isPaused = isChannelPaused(0);
131
+ * console.log(`Channel 0 is ${isPaused ? 'paused' : 'playing'}`);
132
+ * ```
133
+ */
134
+ const isChannelPaused = (channelNumber = 0) => {
135
+ const channel = info_1.audioChannels[channelNumber];
136
+ return (channel === null || channel === void 0 ? void 0 : channel.isPaused) || false;
137
+ };
138
+ exports.isChannelPaused = isChannelPaused;
139
+ /**
140
+ * Gets the pause state of all channels
141
+ * @returns Array of boolean values indicating pause state for each channel
142
+ * @example
143
+ * ```typescript
144
+ * const pauseStates = getAllChannelsPauseState();
145
+ * pauseStates.forEach((isPaused, index) => {
146
+ * console.log(`Channel ${index}: ${isPaused ? 'paused' : 'playing'}`);
147
+ * });
148
+ * ```
149
+ */
150
+ const getAllChannelsPauseState = () => {
151
+ return info_1.audioChannels.map((channel) => (channel === null || channel === void 0 ? void 0 : channel.isPaused) || false);
152
+ };
153
+ exports.getAllChannelsPauseState = getAllChannelsPauseState;
154
+ /**
155
+ * Toggles pause/resume state for all channels globally
156
+ * If any channels are currently playing, all channels will be paused
157
+ * If all channels are paused, all channels will be resumed
158
+ * @returns Promise that resolves when the toggle is complete
159
+ * @example
160
+ * ```typescript
161
+ * await togglePauseAllChannels(); // Pause all if any are playing, resume all if all are paused
162
+ * ```
163
+ */
164
+ const togglePauseAllChannels = () => __awaiter(void 0, void 0, void 0, function* () {
165
+ let hasPlayingChannel = false;
166
+ // Check if any channel is currently playing
167
+ for (let i = 0; i < info_1.audioChannels.length; i++) {
168
+ const channel = info_1.audioChannels[i];
169
+ if (channel && channel.queue.length > 0) {
170
+ const currentAudio = channel.queue[0];
171
+ if (!currentAudio.paused && !currentAudio.ended) {
172
+ hasPlayingChannel = true;
173
+ break;
174
+ }
175
+ }
176
+ }
177
+ // If any channel is playing, pause all channels
178
+ // If no channels are playing, resume all channels
179
+ if (hasPlayingChannel) {
180
+ yield (0, exports.pauseAllChannels)();
181
+ }
182
+ else {
183
+ yield (0, exports.resumeAllChannels)();
184
+ }
185
+ });
186
+ exports.togglePauseAllChannels = togglePauseAllChannels;
package/dist/types.d.ts CHANGED
@@ -11,6 +11,36 @@ export type AudioQueue = HTMLAudioElement[];
11
11
  export type AudioQueueChannel = {
12
12
  queue: AudioQueue;
13
13
  };
14
+ /**
15
+ * Volume ducking configuration for channels
16
+ */
17
+ export interface VolumeConfig {
18
+ /** The channel number that should have priority */
19
+ priorityChannel: number;
20
+ /** Volume level for the priority channel (0-1) */
21
+ priorityVolume: number;
22
+ /** Volume level for all other channels when priority channel is active (0-1) */
23
+ duckingVolume: number;
24
+ /** Duration in milliseconds for volume duck transition (defaults to 250ms) */
25
+ duckTransitionDuration?: number;
26
+ /** Duration in milliseconds for volume restore transition (defaults to 500ms) */
27
+ restoreTransitionDuration?: number;
28
+ /** Easing function for volume transitions (defaults to 'ease-out') */
29
+ transitionEasing?: 'linear' | 'ease-in' | 'ease-out' | 'ease-in-out';
30
+ }
31
+ /**
32
+ * Audio file configuration for queueing
33
+ */
34
+ export interface AudioQueueOptions {
35
+ /** Whether to add the audio to the front of the queue (defaults to false) */
36
+ addToFront?: boolean;
37
+ /** Whether the audio should loop when it finishes */
38
+ loop?: boolean;
39
+ /** Whether to add the audio with priority (same as addToFront) */
40
+ priority?: boolean;
41
+ /** Volume level for this specific audio file (0-1, defaults to channel volume) */
42
+ volume?: number;
43
+ }
14
44
  /**
15
45
  * Comprehensive audio information interface providing metadata about currently playing audio
16
46
  */
@@ -21,12 +51,20 @@ export interface AudioInfo {
21
51
  duration: number;
22
52
  /** Extracted filename from the source URL */
23
53
  fileName: string;
54
+ /** Whether the audio is set to loop */
55
+ isLooping: boolean;
56
+ /** Whether the audio is currently paused */
57
+ isPaused: boolean;
24
58
  /** Whether the audio is currently playing */
25
59
  isPlaying: boolean;
26
60
  /** Playback progress as a decimal (0-1) */
27
61
  progress: number;
62
+ /** Number of audio files remaining in the queue after current */
63
+ remainingInQueue: number;
28
64
  /** Audio file source URL */
29
65
  src: string;
66
+ /** Current volume level (0-1) */
67
+ volume: number;
30
68
  }
31
69
  /**
32
70
  * Information provided when an audio file completes playback
@@ -64,8 +102,12 @@ export interface QueueItem {
64
102
  fileName: string;
65
103
  /** Whether this item is currently playing */
66
104
  isCurrentlyPlaying: boolean;
105
+ /** Whether this item is set to loop */
106
+ isLooping: boolean;
67
107
  /** Audio file source URL */
68
108
  src: string;
109
+ /** Volume level for this item (0-1) */
110
+ volume: number;
69
111
  }
70
112
  /**
71
113
  * Complete snapshot of a queue's current state
@@ -75,10 +117,14 @@ export interface QueueSnapshot {
75
117
  channelNumber: number;
76
118
  /** Zero-based index of the currently playing item */
77
119
  currentIndex: number;
120
+ /** Whether the current audio is paused */
121
+ isPaused: boolean;
78
122
  /** Array of audio items in the queue with their metadata */
79
123
  items: QueueItem[];
80
124
  /** Total number of items in the queue */
81
125
  totalItems: number;
126
+ /** Current volume level for the channel (0-1) */
127
+ volume: number;
82
128
  }
83
129
  /**
84
130
  * Callback function type for audio progress updates
@@ -101,15 +147,37 @@ export type AudioStartCallback = (audioInfo: AudioStartInfo) => void;
101
147
  */
102
148
  export type AudioCompleteCallback = (audioInfo: AudioCompleteInfo) => void;
103
149
  /**
104
- * Extended audio queue channel with event callback management
150
+ * Callback function type for audio pause notifications
151
+ * @param channelNumber Channel that was paused
152
+ * @param audioInfo Information about the audio that was paused
153
+ */
154
+ export type AudioPauseCallback = (channelNumber: number, audioInfo: AudioInfo) => void;
155
+ /**
156
+ * Callback function type for audio resume notifications
157
+ * @param channelNumber Channel that was resumed
158
+ * @param audioInfo Information about the audio that was resumed
159
+ */
160
+ export type AudioResumeCallback = (channelNumber: number, audioInfo: AudioInfo) => void;
161
+ /**
162
+ * Extended audio queue channel with event callback management and additional features
105
163
  */
106
164
  export type ExtendedAudioQueueChannel = AudioQueueChannel & {
107
165
  /** Set of callbacks for audio completion events */
108
166
  audioCompleteCallbacks?: Set<AudioCompleteCallback>;
167
+ /** Set of callbacks for audio pause events */
168
+ audioPauseCallbacks?: Set<AudioPauseCallback>;
169
+ /** Set of callbacks for audio resume events */
170
+ audioResumeCallbacks?: Set<AudioResumeCallback>;
109
171
  /** Set of callbacks for audio start events */
110
172
  audioStartCallbacks?: Set<AudioStartCallback>;
173
+ /** Whether the current audio in this channel is paused */
174
+ isPaused?: boolean;
111
175
  /** Map of audio elements to their progress callback sets */
112
176
  progressCallbacks?: Map<HTMLAudioElement, Set<ProgressCallback>>;
113
177
  /** Set of callbacks for queue change events */
114
178
  queueChangeCallbacks?: Set<QueueChangeCallback>;
179
+ /** Current volume level for this channel (0-1) */
180
+ volume?: number;
181
+ /** Volume ducking configuration for this channel */
182
+ volumeConfig?: VolumeConfig;
115
183
  };
package/dist/utils.d.ts CHANGED
@@ -16,15 +16,21 @@ export declare const extractFileName: (url: string) => string;
16
16
  /**
17
17
  * Extracts comprehensive audio information from an HTMLAudioElement
18
18
  * @param audio - The HTML audio element to extract information from
19
+ * @param channelNumber - Optional channel number to include remaining queue info
20
+ * @param audioChannels - Optional audio channels array to calculate remainingInQueue
19
21
  * @returns AudioInfo object with current playback state or null if audio is invalid
20
22
  * @example
21
23
  * ```typescript
22
24
  * const audioElement = new Audio('song.mp3');
23
25
  * const info = getAudioInfoFromElement(audioElement);
24
26
  * console.log(info?.progress); // Current progress as decimal (0-1)
27
+ *
28
+ * // With channel context for remainingInQueue
29
+ * const infoWithQueue = getAudioInfoFromElement(audioElement, 0, audioChannels);
30
+ * console.log(infoWithQueue?.remainingInQueue); // Number of items left in queue
25
31
  * ```
26
32
  */
27
- export declare const getAudioInfoFromElement: (audio: HTMLAudioElement) => AudioInfo | null;
33
+ export declare const getAudioInfoFromElement: (audio: HTMLAudioElement, channelNumber?: number, audioChannels?: ExtendedAudioQueueChannel[]) => AudioInfo | null;
28
34
  /**
29
35
  * Creates a complete snapshot of a queue's current state
30
36
  * @param channelNumber - The channel number to create a snapshot for
package/dist/utils.js CHANGED
@@ -33,28 +33,44 @@ exports.extractFileName = extractFileName;
33
33
  /**
34
34
  * Extracts comprehensive audio information from an HTMLAudioElement
35
35
  * @param audio - The HTML audio element to extract information from
36
+ * @param channelNumber - Optional channel number to include remaining queue info
37
+ * @param audioChannels - Optional audio channels array to calculate remainingInQueue
36
38
  * @returns AudioInfo object with current playback state or null if audio is invalid
37
39
  * @example
38
40
  * ```typescript
39
41
  * const audioElement = new Audio('song.mp3');
40
42
  * const info = getAudioInfoFromElement(audioElement);
41
43
  * console.log(info?.progress); // Current progress as decimal (0-1)
44
+ *
45
+ * // With channel context for remainingInQueue
46
+ * const infoWithQueue = getAudioInfoFromElement(audioElement, 0, audioChannels);
47
+ * console.log(infoWithQueue?.remainingInQueue); // Number of items left in queue
42
48
  * ```
43
49
  */
44
- const getAudioInfoFromElement = (audio) => {
50
+ const getAudioInfoFromElement = (audio, channelNumber, audioChannels) => {
45
51
  if (!audio)
46
52
  return null;
47
53
  const duration = isNaN(audio.duration) ? 0 : audio.duration * 1000; // Convert to milliseconds
48
54
  const currentTime = isNaN(audio.currentTime) ? 0 : audio.currentTime * 1000; // Convert to milliseconds
49
55
  const progress = duration > 0 ? Math.min(currentTime / duration, 1) : 0;
50
56
  const isPlaying = !audio.paused && !audio.ended && audio.readyState > 2;
57
+ // Calculate remainingInQueue if channel context is provided
58
+ let remainingInQueue = 0;
59
+ if (channelNumber !== undefined && audioChannels && audioChannels[channelNumber]) {
60
+ const channel = audioChannels[channelNumber];
61
+ remainingInQueue = Math.max(0, channel.queue.length - 1); // Exclude current playing audio
62
+ }
51
63
  return {
52
64
  currentTime,
53
65
  duration,
54
66
  fileName: (0, exports.extractFileName)(audio.src),
67
+ isLooping: audio.loop,
68
+ isPaused: audio.paused && !audio.ended,
55
69
  isPlaying,
56
70
  progress,
57
- src: audio.src
71
+ remainingInQueue,
72
+ src: audio.src,
73
+ volume: audio.volume
58
74
  };
59
75
  };
60
76
  exports.getAudioInfoFromElement = getAudioInfoFromElement;
@@ -77,13 +93,17 @@ const createQueueSnapshot = (channelNumber, audioChannels) => {
77
93
  duration: isNaN(audio.duration) ? 0 : audio.duration * 1000,
78
94
  fileName: (0, exports.extractFileName)(audio.src),
79
95
  isCurrentlyPlaying: index === 0 && !audio.paused && !audio.ended,
80
- src: audio.src
96
+ isLooping: audio.loop,
97
+ src: audio.src,
98
+ volume: audio.volume
81
99
  }));
82
100
  return {
83
101
  channelNumber,
84
102
  currentIndex: 0, // Current playing is always index 0 in our queue structure
103
+ isPaused: channel.isPaused || false,
85
104
  items,
86
- totalItems: channel.queue.length
105
+ totalItems: channel.queue.length,
106
+ volume: channel.volume || 1.0
87
107
  };
88
108
  };
89
109
  exports.createQueueSnapshot = createQueueSnapshot;