audio-channel-queue 1.4.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/README.md +483 -20
- package/dist/core.d.ts +71 -0
- package/dist/core.js +273 -0
- package/dist/events.d.ts +81 -0
- package/dist/events.js +210 -0
- package/dist/index.d.ts +29 -0
- package/dist/index.js +77 -0
- package/dist/info.d.ts +166 -0
- package/dist/info.js +352 -0
- package/dist/pause.d.ts +87 -0
- package/dist/pause.js +186 -0
- package/dist/types.d.ts +183 -0
- package/dist/types.js +5 -0
- package/dist/utils.d.ts +58 -0
- package/dist/utils.js +126 -0
- package/dist/volume.d.ts +98 -0
- package/dist/volume.js +302 -0
- package/package.json +10 -4
- package/src/core.ts +306 -0
- package/src/events.ts +243 -0
- package/src/index.ts +104 -0
- package/src/info.ts +380 -0
- package/src/pause.ts +190 -0
- package/src/types.ts +199 -0
- package/src/utils.ts +134 -0
- package/src/volume.ts +328 -0
- package/dist/audio.d.ts +0 -10
- package/dist/audio.js +0 -66
package/dist/core.js
ADDED
|
@@ -0,0 +1,273 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* @fileoverview Core queue 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.stopAllAudio = exports.stopAllAudioInChannel = exports.stopCurrentAudioInChannel = exports.playAudioQueue = exports.queueAudioPriority = exports.queueAudio = void 0;
|
|
16
|
+
const info_1 = require("./info");
|
|
17
|
+
const utils_1 = require("./utils");
|
|
18
|
+
const events_1 = require("./events");
|
|
19
|
+
const volume_1 = require("./volume");
|
|
20
|
+
/**
|
|
21
|
+
* Queues an audio file to a specific channel and starts playing if it's the first in queue
|
|
22
|
+
* @param audioUrl - The URL of the audio file to queue
|
|
23
|
+
* @param channelNumber - The channel number to queue the audio to (defaults to 0)
|
|
24
|
+
* @param options - Optional configuration for the audio file
|
|
25
|
+
* @returns Promise that resolves when the audio is queued and starts playing (if first in queue)
|
|
26
|
+
* @example
|
|
27
|
+
* ```typescript
|
|
28
|
+
* await queueAudio('https://example.com/song.mp3', 0);
|
|
29
|
+
* await queueAudio('./sounds/notification.wav'); // Uses default channel 0
|
|
30
|
+
* await queueAudio('./music/loop.mp3', 1, { loop: true }); // Loop the audio
|
|
31
|
+
* await queueAudio('./urgent.wav', 0, { addToFront: true }); // Add to front of queue
|
|
32
|
+
* ```
|
|
33
|
+
*/
|
|
34
|
+
const queueAudio = (audioUrl_1, ...args_1) => __awaiter(void 0, [audioUrl_1, ...args_1], void 0, function* (audioUrl, channelNumber = 0, options) {
|
|
35
|
+
if (!info_1.audioChannels[channelNumber]) {
|
|
36
|
+
info_1.audioChannels[channelNumber] = {
|
|
37
|
+
audioCompleteCallbacks: new Set(),
|
|
38
|
+
audioPauseCallbacks: new Set(),
|
|
39
|
+
audioResumeCallbacks: new Set(),
|
|
40
|
+
audioStartCallbacks: new Set(),
|
|
41
|
+
isPaused: false,
|
|
42
|
+
progressCallbacks: new Map(),
|
|
43
|
+
queue: [],
|
|
44
|
+
queueChangeCallbacks: new Set(),
|
|
45
|
+
volume: 1.0
|
|
46
|
+
};
|
|
47
|
+
}
|
|
48
|
+
const audio = new Audio(audioUrl);
|
|
49
|
+
// Apply audio configuration from options
|
|
50
|
+
if (options === null || options === void 0 ? void 0 : options.loop) {
|
|
51
|
+
audio.loop = true;
|
|
52
|
+
}
|
|
53
|
+
if ((options === null || options === void 0 ? void 0 : options.volume) !== undefined) {
|
|
54
|
+
const clampedVolume = Math.max(0, Math.min(1, options.volume));
|
|
55
|
+
// Handle NaN case - default to channel volume or 1.0
|
|
56
|
+
const safeVolume = isNaN(clampedVolume) ? (info_1.audioChannels[channelNumber].volume || 1.0) : clampedVolume;
|
|
57
|
+
audio.volume = safeVolume;
|
|
58
|
+
// Also update the channel volume
|
|
59
|
+
info_1.audioChannels[channelNumber].volume = safeVolume;
|
|
60
|
+
}
|
|
61
|
+
else {
|
|
62
|
+
// Use channel volume if no specific volume is set
|
|
63
|
+
const channelVolume = info_1.audioChannels[channelNumber].volume || 1.0;
|
|
64
|
+
audio.volume = channelVolume;
|
|
65
|
+
}
|
|
66
|
+
// Add to front or back of queue based on options
|
|
67
|
+
if (((options === null || options === void 0 ? void 0 : options.addToFront) || (options === null || options === void 0 ? void 0 : options.priority)) && info_1.audioChannels[channelNumber].queue.length > 0) {
|
|
68
|
+
// Insert after the currently playing audio (index 1)
|
|
69
|
+
info_1.audioChannels[channelNumber].queue.splice(1, 0, audio);
|
|
70
|
+
}
|
|
71
|
+
else if (((options === null || options === void 0 ? void 0 : options.addToFront) || (options === null || options === void 0 ? void 0 : options.priority)) && info_1.audioChannels[channelNumber].queue.length === 0) {
|
|
72
|
+
// If queue is empty, just add normally
|
|
73
|
+
info_1.audioChannels[channelNumber].queue.push(audio);
|
|
74
|
+
}
|
|
75
|
+
else {
|
|
76
|
+
// Default behavior - add to back of queue
|
|
77
|
+
info_1.audioChannels[channelNumber].queue.push(audio);
|
|
78
|
+
}
|
|
79
|
+
(0, events_1.emitQueueChange)(channelNumber, info_1.audioChannels);
|
|
80
|
+
if (info_1.audioChannels[channelNumber].queue.length === 1) {
|
|
81
|
+
// Don't await - let playback happen asynchronously
|
|
82
|
+
(0, exports.playAudioQueue)(channelNumber).catch(console.error);
|
|
83
|
+
}
|
|
84
|
+
});
|
|
85
|
+
exports.queueAudio = queueAudio;
|
|
86
|
+
/**
|
|
87
|
+
* Adds an audio file to the front of the queue in a specific channel
|
|
88
|
+
* This is a convenience function that places the audio right after the currently playing track
|
|
89
|
+
* @param audioUrl - The URL of the audio file to queue
|
|
90
|
+
* @param channelNumber - The channel number to queue the audio to (defaults to 0)
|
|
91
|
+
* @param options - Optional configuration for the audio file
|
|
92
|
+
* @returns Promise that resolves when the audio is queued
|
|
93
|
+
* @example
|
|
94
|
+
* ```typescript
|
|
95
|
+
* await queueAudioPriority('./urgent-announcement.wav', 0);
|
|
96
|
+
* await queueAudioPriority('./priority-sound.mp3', 1, { loop: true });
|
|
97
|
+
* ```
|
|
98
|
+
*/
|
|
99
|
+
const queueAudioPriority = (audioUrl_1, ...args_1) => __awaiter(void 0, [audioUrl_1, ...args_1], void 0, function* (audioUrl, channelNumber = 0, options) {
|
|
100
|
+
const priorityOptions = Object.assign(Object.assign({}, options), { addToFront: true });
|
|
101
|
+
return (0, exports.queueAudio)(audioUrl, channelNumber, priorityOptions);
|
|
102
|
+
});
|
|
103
|
+
exports.queueAudioPriority = queueAudioPriority;
|
|
104
|
+
/**
|
|
105
|
+
* Plays the audio queue for a specific channel
|
|
106
|
+
* @param channelNumber - The channel number to play
|
|
107
|
+
* @returns Promise that resolves when the current audio finishes playing
|
|
108
|
+
* @example
|
|
109
|
+
* ```typescript
|
|
110
|
+
* await playAudioQueue(0); // Play queue for channel 0
|
|
111
|
+
* ```
|
|
112
|
+
*/
|
|
113
|
+
const playAudioQueue = (channelNumber) => __awaiter(void 0, void 0, void 0, function* () {
|
|
114
|
+
const channel = info_1.audioChannels[channelNumber];
|
|
115
|
+
if (!channel || channel.queue.length === 0)
|
|
116
|
+
return;
|
|
117
|
+
const currentAudio = channel.queue[0];
|
|
118
|
+
// Apply channel volume if not already set
|
|
119
|
+
if (currentAudio.volume === 1.0 && channel.volume !== undefined) {
|
|
120
|
+
currentAudio.volume = channel.volume;
|
|
121
|
+
}
|
|
122
|
+
(0, events_1.setupProgressTracking)(currentAudio, channelNumber, info_1.audioChannels);
|
|
123
|
+
// Apply volume ducking when audio starts
|
|
124
|
+
yield (0, volume_1.applyVolumeDucking)(channelNumber);
|
|
125
|
+
return new Promise((resolve) => {
|
|
126
|
+
let hasStarted = false;
|
|
127
|
+
let metadataLoaded = false;
|
|
128
|
+
let playStarted = false;
|
|
129
|
+
// Check if we should fire onAudioStart (both conditions met)
|
|
130
|
+
const tryFireAudioStart = () => {
|
|
131
|
+
if (!hasStarted && metadataLoaded && playStarted) {
|
|
132
|
+
hasStarted = true;
|
|
133
|
+
(0, events_1.emitAudioStart)(channelNumber, {
|
|
134
|
+
channelNumber,
|
|
135
|
+
duration: currentAudio.duration * 1000, // Now guaranteed to have valid duration
|
|
136
|
+
fileName: (0, utils_1.extractFileName)(currentAudio.src),
|
|
137
|
+
src: currentAudio.src
|
|
138
|
+
}, info_1.audioChannels);
|
|
139
|
+
}
|
|
140
|
+
};
|
|
141
|
+
// Event handler for when metadata loads (duration becomes available)
|
|
142
|
+
const handleLoadedMetadata = () => {
|
|
143
|
+
metadataLoaded = true;
|
|
144
|
+
tryFireAudioStart();
|
|
145
|
+
};
|
|
146
|
+
// Event handler for when audio actually starts playing
|
|
147
|
+
const handlePlay = () => {
|
|
148
|
+
playStarted = true;
|
|
149
|
+
tryFireAudioStart();
|
|
150
|
+
};
|
|
151
|
+
// Event handler for when audio ends
|
|
152
|
+
const handleEnded = () => __awaiter(void 0, void 0, void 0, function* () {
|
|
153
|
+
(0, events_1.emitAudioComplete)(channelNumber, {
|
|
154
|
+
channelNumber,
|
|
155
|
+
fileName: (0, utils_1.extractFileName)(currentAudio.src),
|
|
156
|
+
remainingInQueue: channel.queue.length - 1,
|
|
157
|
+
src: currentAudio.src
|
|
158
|
+
}, info_1.audioChannels);
|
|
159
|
+
// Restore volume levels when priority channel stops
|
|
160
|
+
yield (0, volume_1.restoreVolumeLevels)(channelNumber);
|
|
161
|
+
// Clean up event listeners
|
|
162
|
+
currentAudio.removeEventListener('loadedmetadata', handleLoadedMetadata);
|
|
163
|
+
currentAudio.removeEventListener('play', handlePlay);
|
|
164
|
+
currentAudio.removeEventListener('ended', handleEnded);
|
|
165
|
+
(0, events_1.cleanupProgressTracking)(currentAudio, channelNumber, info_1.audioChannels);
|
|
166
|
+
// Handle looping vs non-looping audio
|
|
167
|
+
if (currentAudio.loop) {
|
|
168
|
+
// For looping audio, reset current time and continue playing
|
|
169
|
+
currentAudio.currentTime = 0;
|
|
170
|
+
yield currentAudio.play();
|
|
171
|
+
// Don't remove from queue, but resolve the promise so tests don't hang
|
|
172
|
+
resolve();
|
|
173
|
+
}
|
|
174
|
+
else {
|
|
175
|
+
// For non-looping audio, remove from queue and play next
|
|
176
|
+
channel.queue.shift();
|
|
177
|
+
// Emit queue change after completion
|
|
178
|
+
setTimeout(() => (0, events_1.emitQueueChange)(channelNumber, info_1.audioChannels), 10);
|
|
179
|
+
yield (0, exports.playAudioQueue)(channelNumber);
|
|
180
|
+
resolve();
|
|
181
|
+
}
|
|
182
|
+
});
|
|
183
|
+
// Add event listeners
|
|
184
|
+
currentAudio.addEventListener('loadedmetadata', handleLoadedMetadata);
|
|
185
|
+
currentAudio.addEventListener('play', handlePlay);
|
|
186
|
+
currentAudio.addEventListener('ended', handleEnded);
|
|
187
|
+
// Check if metadata is already loaded (in case it loads before we add the listener)
|
|
188
|
+
if (currentAudio.readyState >= 1) { // HAVE_METADATA or higher
|
|
189
|
+
metadataLoaded = true;
|
|
190
|
+
}
|
|
191
|
+
currentAudio.play();
|
|
192
|
+
});
|
|
193
|
+
});
|
|
194
|
+
exports.playAudioQueue = playAudioQueue;
|
|
195
|
+
/**
|
|
196
|
+
* Stops the currently playing audio in a specific channel and plays the next audio in queue
|
|
197
|
+
* @param channelNumber - The channel number (defaults to 0)
|
|
198
|
+
* @example
|
|
199
|
+
* ```typescript
|
|
200
|
+
* await stopCurrentAudioInChannel(); // Stop current audio in default channel (0)
|
|
201
|
+
* await stopCurrentAudioInChannel(1); // Stop current audio in channel 1
|
|
202
|
+
* ```
|
|
203
|
+
*/
|
|
204
|
+
const stopCurrentAudioInChannel = (...args_1) => __awaiter(void 0, [...args_1], void 0, function* (channelNumber = 0) {
|
|
205
|
+
const channel = info_1.audioChannels[channelNumber];
|
|
206
|
+
if (channel && channel.queue.length > 0) {
|
|
207
|
+
const currentAudio = channel.queue[0];
|
|
208
|
+
(0, events_1.emitAudioComplete)(channelNumber, {
|
|
209
|
+
channelNumber,
|
|
210
|
+
fileName: (0, utils_1.extractFileName)(currentAudio.src),
|
|
211
|
+
remainingInQueue: channel.queue.length - 1,
|
|
212
|
+
src: currentAudio.src
|
|
213
|
+
}, info_1.audioChannels);
|
|
214
|
+
// Restore volume levels when stopping
|
|
215
|
+
yield (0, volume_1.restoreVolumeLevels)(channelNumber);
|
|
216
|
+
currentAudio.pause();
|
|
217
|
+
(0, events_1.cleanupProgressTracking)(currentAudio, channelNumber, info_1.audioChannels);
|
|
218
|
+
channel.queue.shift();
|
|
219
|
+
channel.isPaused = false; // Reset pause state
|
|
220
|
+
(0, events_1.emitQueueChange)(channelNumber, info_1.audioChannels);
|
|
221
|
+
// Start next audio without waiting for it to complete
|
|
222
|
+
(0, exports.playAudioQueue)(channelNumber).catch(console.error);
|
|
223
|
+
}
|
|
224
|
+
});
|
|
225
|
+
exports.stopCurrentAudioInChannel = stopCurrentAudioInChannel;
|
|
226
|
+
/**
|
|
227
|
+
* Stops all audio in a specific channel and clears the entire queue
|
|
228
|
+
* @param channelNumber - The channel number (defaults to 0)
|
|
229
|
+
* @example
|
|
230
|
+
* ```typescript
|
|
231
|
+
* await stopAllAudioInChannel(); // Clear all audio in default channel (0)
|
|
232
|
+
* await stopAllAudioInChannel(1); // Clear all audio in channel 1
|
|
233
|
+
* ```
|
|
234
|
+
*/
|
|
235
|
+
const stopAllAudioInChannel = (...args_1) => __awaiter(void 0, [...args_1], void 0, function* (channelNumber = 0) {
|
|
236
|
+
const channel = info_1.audioChannels[channelNumber];
|
|
237
|
+
if (channel) {
|
|
238
|
+
if (channel.queue.length > 0) {
|
|
239
|
+
const currentAudio = channel.queue[0];
|
|
240
|
+
(0, events_1.emitAudioComplete)(channelNumber, {
|
|
241
|
+
channelNumber,
|
|
242
|
+
fileName: (0, utils_1.extractFileName)(currentAudio.src),
|
|
243
|
+
remainingInQueue: 0, // Will be 0 since we're clearing the queue
|
|
244
|
+
src: currentAudio.src
|
|
245
|
+
}, info_1.audioChannels);
|
|
246
|
+
// Restore volume levels when stopping
|
|
247
|
+
yield (0, volume_1.restoreVolumeLevels)(channelNumber);
|
|
248
|
+
currentAudio.pause();
|
|
249
|
+
(0, events_1.cleanupProgressTracking)(currentAudio, channelNumber, info_1.audioChannels);
|
|
250
|
+
}
|
|
251
|
+
// Clean up all progress tracking for this channel
|
|
252
|
+
channel.queue.forEach(audio => (0, events_1.cleanupProgressTracking)(audio, channelNumber, info_1.audioChannels));
|
|
253
|
+
channel.queue = [];
|
|
254
|
+
channel.isPaused = false; // Reset pause state
|
|
255
|
+
(0, events_1.emitQueueChange)(channelNumber, info_1.audioChannels);
|
|
256
|
+
}
|
|
257
|
+
});
|
|
258
|
+
exports.stopAllAudioInChannel = stopAllAudioInChannel;
|
|
259
|
+
/**
|
|
260
|
+
* Stops all audio across all channels and clears all queues
|
|
261
|
+
* @example
|
|
262
|
+
* ```typescript
|
|
263
|
+
* await stopAllAudio(); // Emergency stop - clears everything
|
|
264
|
+
* ```
|
|
265
|
+
*/
|
|
266
|
+
const stopAllAudio = () => __awaiter(void 0, void 0, void 0, function* () {
|
|
267
|
+
const stopPromises = [];
|
|
268
|
+
info_1.audioChannels.forEach((_channel, index) => {
|
|
269
|
+
stopPromises.push((0, exports.stopAllAudioInChannel)(index));
|
|
270
|
+
});
|
|
271
|
+
yield Promise.all(stopPromises);
|
|
272
|
+
});
|
|
273
|
+
exports.stopAllAudio = stopAllAudio;
|
package/dist/events.d.ts
ADDED
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Event handling and emission for the audio-channel-queue package
|
|
3
|
+
*/
|
|
4
|
+
import { AudioStartInfo, AudioCompleteInfo, ExtendedAudioQueueChannel, AudioInfo } from './types';
|
|
5
|
+
/**
|
|
6
|
+
* Emits a queue change event to all registered listeners for a specific channel
|
|
7
|
+
* @param channelNumber - The channel number that experienced a queue change
|
|
8
|
+
* @param audioChannels - Array of audio channels
|
|
9
|
+
* @example
|
|
10
|
+
* ```typescript
|
|
11
|
+
* emitQueueChange(0, audioChannels); // Notifies all queue change listeners
|
|
12
|
+
* ```
|
|
13
|
+
*/
|
|
14
|
+
export declare const emitQueueChange: (channelNumber: number, audioChannels: ExtendedAudioQueueChannel[]) => void;
|
|
15
|
+
/**
|
|
16
|
+
* Emits an audio start event to all registered listeners for a specific channel
|
|
17
|
+
* @param channelNumber - The channel number where audio started
|
|
18
|
+
* @param audioInfo - Information about the audio that started
|
|
19
|
+
* @param audioChannels - Array of audio channels
|
|
20
|
+
* @example
|
|
21
|
+
* ```typescript
|
|
22
|
+
* emitAudioStart(0, { src: 'song.mp3', fileName: 'song.mp3', duration: 180000, channelNumber: 0 }, audioChannels);
|
|
23
|
+
* ```
|
|
24
|
+
*/
|
|
25
|
+
export declare const emitAudioStart: (channelNumber: number, audioInfo: AudioStartInfo, audioChannels: ExtendedAudioQueueChannel[]) => void;
|
|
26
|
+
/**
|
|
27
|
+
* Emits an audio complete event to all registered listeners for a specific channel
|
|
28
|
+
* @param channelNumber - The channel number where audio completed
|
|
29
|
+
* @param audioInfo - Information about the audio that completed
|
|
30
|
+
* @param audioChannels - Array of audio channels
|
|
31
|
+
* @example
|
|
32
|
+
* ```typescript
|
|
33
|
+
* emitAudioComplete(0, { src: 'song.mp3', fileName: 'song.mp3', channelNumber: 0, remainingInQueue: 2 }, audioChannels);
|
|
34
|
+
* ```
|
|
35
|
+
*/
|
|
36
|
+
export declare const emitAudioComplete: (channelNumber: number, audioInfo: AudioCompleteInfo, audioChannels: ExtendedAudioQueueChannel[]) => void;
|
|
37
|
+
/**
|
|
38
|
+
* Emits an audio pause event to all registered listeners for a specific channel
|
|
39
|
+
* @param channelNumber - The channel number where audio was paused
|
|
40
|
+
* @param audioInfo - Information about the audio that was paused
|
|
41
|
+
* @param audioChannels - Array of audio channels
|
|
42
|
+
* @example
|
|
43
|
+
* ```typescript
|
|
44
|
+
* emitAudioPause(0, audioInfo, audioChannels);
|
|
45
|
+
* ```
|
|
46
|
+
*/
|
|
47
|
+
export declare const emitAudioPause: (channelNumber: number, audioInfo: AudioInfo, audioChannels: ExtendedAudioQueueChannel[]) => void;
|
|
48
|
+
/**
|
|
49
|
+
* Emits an audio resume event to all registered listeners for a specific channel
|
|
50
|
+
* @param channelNumber - The channel number where audio was resumed
|
|
51
|
+
* @param audioInfo - Information about the audio that was resumed
|
|
52
|
+
* @param audioChannels - Array of audio channels
|
|
53
|
+
* @example
|
|
54
|
+
* ```typescript
|
|
55
|
+
* emitAudioResume(0, audioInfo, audioChannels);
|
|
56
|
+
* ```
|
|
57
|
+
*/
|
|
58
|
+
export declare const emitAudioResume: (channelNumber: number, audioInfo: AudioInfo, audioChannels: ExtendedAudioQueueChannel[]) => void;
|
|
59
|
+
/**
|
|
60
|
+
* Sets up comprehensive progress tracking for an audio element
|
|
61
|
+
* @param audio - The HTML audio element to track
|
|
62
|
+
* @param channelNumber - The channel number this audio belongs to
|
|
63
|
+
* @param audioChannels - Array of audio channels
|
|
64
|
+
* @example
|
|
65
|
+
* ```typescript
|
|
66
|
+
* const audioElement = new Audio('song.mp3');
|
|
67
|
+
* setupProgressTracking(audioElement, 0, audioChannels);
|
|
68
|
+
* ```
|
|
69
|
+
*/
|
|
70
|
+
export declare const setupProgressTracking: (audio: HTMLAudioElement, channelNumber: number, audioChannels: ExtendedAudioQueueChannel[]) => void;
|
|
71
|
+
/**
|
|
72
|
+
* Cleans up progress tracking for an audio element to prevent memory leaks
|
|
73
|
+
* @param audio - The HTML audio element to clean up
|
|
74
|
+
* @param channelNumber - The channel number this audio belongs to
|
|
75
|
+
* @param audioChannels - Array of audio channels
|
|
76
|
+
* @example
|
|
77
|
+
* ```typescript
|
|
78
|
+
* cleanupProgressTracking(audioElement, 0, audioChannels);
|
|
79
|
+
* ```
|
|
80
|
+
*/
|
|
81
|
+
export declare const cleanupProgressTracking: (audio: HTMLAudioElement, channelNumber: number, audioChannels: ExtendedAudioQueueChannel[]) => void;
|
package/dist/events.js
ADDED
|
@@ -0,0 +1,210 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* @fileoverview Event handling and emission for the audio-channel-queue package
|
|
4
|
+
*/
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.cleanupProgressTracking = exports.setupProgressTracking = exports.emitAudioResume = exports.emitAudioPause = exports.emitAudioComplete = exports.emitAudioStart = exports.emitQueueChange = void 0;
|
|
7
|
+
const utils_1 = require("./utils");
|
|
8
|
+
/**
|
|
9
|
+
* Emits a queue change event to all registered listeners for a specific channel
|
|
10
|
+
* @param channelNumber - The channel number that experienced a queue change
|
|
11
|
+
* @param audioChannels - Array of audio channels
|
|
12
|
+
* @example
|
|
13
|
+
* ```typescript
|
|
14
|
+
* emitQueueChange(0, audioChannels); // Notifies all queue change listeners
|
|
15
|
+
* ```
|
|
16
|
+
*/
|
|
17
|
+
const emitQueueChange = (channelNumber, audioChannels) => {
|
|
18
|
+
const channel = audioChannels[channelNumber];
|
|
19
|
+
if (!channel || !channel.queueChangeCallbacks)
|
|
20
|
+
return;
|
|
21
|
+
const snapshot = (0, utils_1.createQueueSnapshot)(channelNumber, audioChannels);
|
|
22
|
+
if (!snapshot)
|
|
23
|
+
return;
|
|
24
|
+
channel.queueChangeCallbacks.forEach(callback => {
|
|
25
|
+
try {
|
|
26
|
+
callback(snapshot);
|
|
27
|
+
}
|
|
28
|
+
catch (error) {
|
|
29
|
+
console.error('Error in queue change callback:', error);
|
|
30
|
+
}
|
|
31
|
+
});
|
|
32
|
+
};
|
|
33
|
+
exports.emitQueueChange = emitQueueChange;
|
|
34
|
+
/**
|
|
35
|
+
* Emits an audio start event to all registered listeners for a specific channel
|
|
36
|
+
* @param channelNumber - The channel number where audio started
|
|
37
|
+
* @param audioInfo - Information about the audio that started
|
|
38
|
+
* @param audioChannels - Array of audio channels
|
|
39
|
+
* @example
|
|
40
|
+
* ```typescript
|
|
41
|
+
* emitAudioStart(0, { src: 'song.mp3', fileName: 'song.mp3', duration: 180000, channelNumber: 0 }, audioChannels);
|
|
42
|
+
* ```
|
|
43
|
+
*/
|
|
44
|
+
const emitAudioStart = (channelNumber, audioInfo, audioChannels) => {
|
|
45
|
+
const channel = audioChannels[channelNumber];
|
|
46
|
+
if (!channel || !channel.audioStartCallbacks)
|
|
47
|
+
return;
|
|
48
|
+
channel.audioStartCallbacks.forEach(callback => {
|
|
49
|
+
try {
|
|
50
|
+
callback(audioInfo);
|
|
51
|
+
}
|
|
52
|
+
catch (error) {
|
|
53
|
+
console.error('Error in audio start callback:', error);
|
|
54
|
+
}
|
|
55
|
+
});
|
|
56
|
+
};
|
|
57
|
+
exports.emitAudioStart = emitAudioStart;
|
|
58
|
+
/**
|
|
59
|
+
* Emits an audio complete event to all registered listeners for a specific channel
|
|
60
|
+
* @param channelNumber - The channel number where audio completed
|
|
61
|
+
* @param audioInfo - Information about the audio that completed
|
|
62
|
+
* @param audioChannels - Array of audio channels
|
|
63
|
+
* @example
|
|
64
|
+
* ```typescript
|
|
65
|
+
* emitAudioComplete(0, { src: 'song.mp3', fileName: 'song.mp3', channelNumber: 0, remainingInQueue: 2 }, audioChannels);
|
|
66
|
+
* ```
|
|
67
|
+
*/
|
|
68
|
+
const emitAudioComplete = (channelNumber, audioInfo, audioChannels) => {
|
|
69
|
+
const channel = audioChannels[channelNumber];
|
|
70
|
+
if (!channel || !channel.audioCompleteCallbacks)
|
|
71
|
+
return;
|
|
72
|
+
channel.audioCompleteCallbacks.forEach(callback => {
|
|
73
|
+
try {
|
|
74
|
+
callback(audioInfo);
|
|
75
|
+
}
|
|
76
|
+
catch (error) {
|
|
77
|
+
console.error('Error in audio complete callback:', error);
|
|
78
|
+
}
|
|
79
|
+
});
|
|
80
|
+
};
|
|
81
|
+
exports.emitAudioComplete = emitAudioComplete;
|
|
82
|
+
/**
|
|
83
|
+
* Emits an audio pause event to all registered listeners for a specific channel
|
|
84
|
+
* @param channelNumber - The channel number where audio was paused
|
|
85
|
+
* @param audioInfo - Information about the audio that was paused
|
|
86
|
+
* @param audioChannels - Array of audio channels
|
|
87
|
+
* @example
|
|
88
|
+
* ```typescript
|
|
89
|
+
* emitAudioPause(0, audioInfo, audioChannels);
|
|
90
|
+
* ```
|
|
91
|
+
*/
|
|
92
|
+
const emitAudioPause = (channelNumber, audioInfo, audioChannels) => {
|
|
93
|
+
const channel = audioChannels[channelNumber];
|
|
94
|
+
if (!channel || !channel.audioPauseCallbacks)
|
|
95
|
+
return;
|
|
96
|
+
channel.audioPauseCallbacks.forEach(callback => {
|
|
97
|
+
try {
|
|
98
|
+
callback(channelNumber, audioInfo);
|
|
99
|
+
}
|
|
100
|
+
catch (error) {
|
|
101
|
+
console.error('Error in audio pause callback:', error);
|
|
102
|
+
}
|
|
103
|
+
});
|
|
104
|
+
};
|
|
105
|
+
exports.emitAudioPause = emitAudioPause;
|
|
106
|
+
/**
|
|
107
|
+
* Emits an audio resume event to all registered listeners for a specific channel
|
|
108
|
+
* @param channelNumber - The channel number where audio was resumed
|
|
109
|
+
* @param audioInfo - Information about the audio that was resumed
|
|
110
|
+
* @param audioChannels - Array of audio channels
|
|
111
|
+
* @example
|
|
112
|
+
* ```typescript
|
|
113
|
+
* emitAudioResume(0, audioInfo, audioChannels);
|
|
114
|
+
* ```
|
|
115
|
+
*/
|
|
116
|
+
const emitAudioResume = (channelNumber, audioInfo, audioChannels) => {
|
|
117
|
+
const channel = audioChannels[channelNumber];
|
|
118
|
+
if (!channel || !channel.audioResumeCallbacks)
|
|
119
|
+
return;
|
|
120
|
+
channel.audioResumeCallbacks.forEach(callback => {
|
|
121
|
+
try {
|
|
122
|
+
callback(channelNumber, audioInfo);
|
|
123
|
+
}
|
|
124
|
+
catch (error) {
|
|
125
|
+
console.error('Error in audio resume callback:', error);
|
|
126
|
+
}
|
|
127
|
+
});
|
|
128
|
+
};
|
|
129
|
+
exports.emitAudioResume = emitAudioResume;
|
|
130
|
+
// Store listener functions for cleanup
|
|
131
|
+
const progressListeners = new WeakMap();
|
|
132
|
+
/**
|
|
133
|
+
* Sets up comprehensive progress tracking for an audio element
|
|
134
|
+
* @param audio - The HTML audio element to track
|
|
135
|
+
* @param channelNumber - The channel number this audio belongs to
|
|
136
|
+
* @param audioChannels - Array of audio channels
|
|
137
|
+
* @example
|
|
138
|
+
* ```typescript
|
|
139
|
+
* const audioElement = new Audio('song.mp3');
|
|
140
|
+
* setupProgressTracking(audioElement, 0, audioChannels);
|
|
141
|
+
* ```
|
|
142
|
+
*/
|
|
143
|
+
const setupProgressTracking = (audio, channelNumber, audioChannels) => {
|
|
144
|
+
const channel = audioChannels[channelNumber];
|
|
145
|
+
if (!channel)
|
|
146
|
+
return;
|
|
147
|
+
if (!channel.progressCallbacks) {
|
|
148
|
+
channel.progressCallbacks = new Map();
|
|
149
|
+
}
|
|
150
|
+
// Don't set up tracking if already exists
|
|
151
|
+
if (progressListeners.has(audio))
|
|
152
|
+
return;
|
|
153
|
+
const updateProgress = () => {
|
|
154
|
+
var _a, _b;
|
|
155
|
+
// Get callbacks for this specific audio element AND the channel-wide callbacks
|
|
156
|
+
const audioCallbacks = ((_a = channel.progressCallbacks) === null || _a === void 0 ? void 0 : _a.get(audio)) || new Set();
|
|
157
|
+
const channelCallbacks = ((_b = channel.progressCallbacks) === null || _b === void 0 ? void 0 : _b.get(null)) || new Set();
|
|
158
|
+
// Combine both sets of callbacks
|
|
159
|
+
const allCallbacks = new Set([...audioCallbacks, ...channelCallbacks]);
|
|
160
|
+
if (allCallbacks.size === 0)
|
|
161
|
+
return;
|
|
162
|
+
const info = (0, utils_1.getAudioInfoFromElement)(audio, channelNumber, audioChannels);
|
|
163
|
+
if (info) {
|
|
164
|
+
allCallbacks.forEach((callback) => {
|
|
165
|
+
try {
|
|
166
|
+
callback(info);
|
|
167
|
+
}
|
|
168
|
+
catch (error) {
|
|
169
|
+
console.error('Error in progress callback:', error);
|
|
170
|
+
}
|
|
171
|
+
});
|
|
172
|
+
}
|
|
173
|
+
};
|
|
174
|
+
// Store the listener function for cleanup
|
|
175
|
+
progressListeners.set(audio, updateProgress);
|
|
176
|
+
// Set up comprehensive event listeners for progress tracking
|
|
177
|
+
audio.addEventListener('timeupdate', updateProgress);
|
|
178
|
+
audio.addEventListener('loadedmetadata', updateProgress);
|
|
179
|
+
audio.addEventListener('play', updateProgress);
|
|
180
|
+
audio.addEventListener('pause', updateProgress);
|
|
181
|
+
audio.addEventListener('ended', updateProgress);
|
|
182
|
+
};
|
|
183
|
+
exports.setupProgressTracking = setupProgressTracking;
|
|
184
|
+
/**
|
|
185
|
+
* Cleans up progress tracking for an audio element to prevent memory leaks
|
|
186
|
+
* @param audio - The HTML audio element to clean up
|
|
187
|
+
* @param channelNumber - The channel number this audio belongs to
|
|
188
|
+
* @param audioChannels - Array of audio channels
|
|
189
|
+
* @example
|
|
190
|
+
* ```typescript
|
|
191
|
+
* cleanupProgressTracking(audioElement, 0, audioChannels);
|
|
192
|
+
* ```
|
|
193
|
+
*/
|
|
194
|
+
const cleanupProgressTracking = (audio, channelNumber, audioChannels) => {
|
|
195
|
+
const channel = audioChannels[channelNumber];
|
|
196
|
+
if (!channel || !channel.progressCallbacks)
|
|
197
|
+
return;
|
|
198
|
+
// Remove event listeners
|
|
199
|
+
const updateProgress = progressListeners.get(audio);
|
|
200
|
+
if (updateProgress) {
|
|
201
|
+
audio.removeEventListener('timeupdate', updateProgress);
|
|
202
|
+
audio.removeEventListener('loadedmetadata', updateProgress);
|
|
203
|
+
audio.removeEventListener('play', updateProgress);
|
|
204
|
+
audio.removeEventListener('pause', updateProgress);
|
|
205
|
+
audio.removeEventListener('ended', updateProgress);
|
|
206
|
+
progressListeners.delete(audio);
|
|
207
|
+
}
|
|
208
|
+
channel.progressCallbacks.delete(audio);
|
|
209
|
+
};
|
|
210
|
+
exports.cleanupProgressTracking = cleanupProgressTracking;
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Main entry point for the audio-channel-queue package
|
|
3
|
+
*
|
|
4
|
+
* A comprehensive audio queue management system with real-time progress tracking,
|
|
5
|
+
* multi-channel support, pause/resume functionality, volume control with ducking,
|
|
6
|
+
* looping capabilities, and extensive event handling.
|
|
7
|
+
*
|
|
8
|
+
* @example Basic Usage
|
|
9
|
+
* ```typescript
|
|
10
|
+
* import { queueAudio, onAudioProgress, pauseChannel } from 'audio-channel-queue';
|
|
11
|
+
*
|
|
12
|
+
* // Queue an audio file
|
|
13
|
+
* await queueAudio('song.mp3');
|
|
14
|
+
*
|
|
15
|
+
* // Track progress
|
|
16
|
+
* onAudioProgress(0, (info) => {
|
|
17
|
+
* console.log(`Progress: ${info.progress * 100}%`);
|
|
18
|
+
* });
|
|
19
|
+
*
|
|
20
|
+
* // Pause playback
|
|
21
|
+
* await pauseChannel(0);
|
|
22
|
+
* ```
|
|
23
|
+
*/
|
|
24
|
+
export type { AudioCompleteCallback, AudioCompleteInfo, AudioInfo, AudioPauseCallback, AudioQueue, AudioQueueChannel, AudioQueueOptions, AudioResumeCallback, AudioStartCallback, AudioStartInfo, ExtendedAudioQueueChannel, ProgressCallback, QueueChangeCallback, QueueItem, QueueSnapshot, VolumeConfig } from './types';
|
|
25
|
+
export { playAudioQueue, queueAudio, queueAudioPriority, stopAllAudio, stopAllAudioInChannel, stopCurrentAudioInChannel } from './core';
|
|
26
|
+
export { getAllChannelsPauseState, isChannelPaused, pauseAllChannels, pauseChannel, resumeAllChannels, resumeChannel, togglePauseAllChannels, togglePauseChannel } from './pause';
|
|
27
|
+
export { applyVolumeDucking, clearVolumeDucking, getAllChannelsVolume, getChannelVolume, restoreVolumeLevels, setAllChannelsVolume, setChannelVolume, setVolumeDucking, transitionVolume } from './volume';
|
|
28
|
+
export { audioChannels, getAllChannelsInfo, getCurrentAudioInfo, getQueueSnapshot, offAudioPause, offAudioProgress, offAudioResume, offQueueChange, onAudioComplete, onAudioPause, onAudioProgress, onAudioResume, onAudioStart, onQueueChange } from './info';
|
|
29
|
+
export { cleanWebpackFilename, createQueueSnapshot, extractFileName, getAudioInfoFromElement } from './utils';
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* @fileoverview Main entry point for the audio-channel-queue package
|
|
4
|
+
*
|
|
5
|
+
* A comprehensive audio queue management system with real-time progress tracking,
|
|
6
|
+
* multi-channel support, pause/resume functionality, volume control with ducking,
|
|
7
|
+
* looping capabilities, and extensive event handling.
|
|
8
|
+
*
|
|
9
|
+
* @example Basic Usage
|
|
10
|
+
* ```typescript
|
|
11
|
+
* import { queueAudio, onAudioProgress, pauseChannel } from 'audio-channel-queue';
|
|
12
|
+
*
|
|
13
|
+
* // Queue an audio file
|
|
14
|
+
* await queueAudio('song.mp3');
|
|
15
|
+
*
|
|
16
|
+
* // Track progress
|
|
17
|
+
* onAudioProgress(0, (info) => {
|
|
18
|
+
* console.log(`Progress: ${info.progress * 100}%`);
|
|
19
|
+
* });
|
|
20
|
+
*
|
|
21
|
+
* // Pause playback
|
|
22
|
+
* await pauseChannel(0);
|
|
23
|
+
* ```
|
|
24
|
+
*/
|
|
25
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
26
|
+
exports.getAudioInfoFromElement = exports.extractFileName = exports.createQueueSnapshot = exports.cleanWebpackFilename = exports.onQueueChange = exports.onAudioStart = exports.onAudioResume = exports.onAudioProgress = exports.onAudioPause = exports.onAudioComplete = exports.offQueueChange = exports.offAudioResume = exports.offAudioProgress = exports.offAudioPause = exports.getQueueSnapshot = exports.getCurrentAudioInfo = exports.getAllChannelsInfo = exports.audioChannels = exports.transitionVolume = exports.setVolumeDucking = exports.setChannelVolume = exports.setAllChannelsVolume = exports.restoreVolumeLevels = exports.getChannelVolume = exports.getAllChannelsVolume = exports.clearVolumeDucking = exports.applyVolumeDucking = exports.togglePauseChannel = exports.togglePauseAllChannels = exports.resumeChannel = exports.resumeAllChannels = exports.pauseChannel = exports.pauseAllChannels = exports.isChannelPaused = exports.getAllChannelsPauseState = exports.stopCurrentAudioInChannel = exports.stopAllAudioInChannel = exports.stopAllAudio = exports.queueAudioPriority = exports.queueAudio = exports.playAudioQueue = void 0;
|
|
27
|
+
// Export core queue management functions
|
|
28
|
+
var core_1 = require("./core");
|
|
29
|
+
Object.defineProperty(exports, "playAudioQueue", { enumerable: true, get: function () { return core_1.playAudioQueue; } });
|
|
30
|
+
Object.defineProperty(exports, "queueAudio", { enumerable: true, get: function () { return core_1.queueAudio; } });
|
|
31
|
+
Object.defineProperty(exports, "queueAudioPriority", { enumerable: true, get: function () { return core_1.queueAudioPriority; } });
|
|
32
|
+
Object.defineProperty(exports, "stopAllAudio", { enumerable: true, get: function () { return core_1.stopAllAudio; } });
|
|
33
|
+
Object.defineProperty(exports, "stopAllAudioInChannel", { enumerable: true, get: function () { return core_1.stopAllAudioInChannel; } });
|
|
34
|
+
Object.defineProperty(exports, "stopCurrentAudioInChannel", { enumerable: true, get: function () { return core_1.stopCurrentAudioInChannel; } });
|
|
35
|
+
// Export pause and resume functionality
|
|
36
|
+
var pause_1 = require("./pause");
|
|
37
|
+
Object.defineProperty(exports, "getAllChannelsPauseState", { enumerable: true, get: function () { return pause_1.getAllChannelsPauseState; } });
|
|
38
|
+
Object.defineProperty(exports, "isChannelPaused", { enumerable: true, get: function () { return pause_1.isChannelPaused; } });
|
|
39
|
+
Object.defineProperty(exports, "pauseAllChannels", { enumerable: true, get: function () { return pause_1.pauseAllChannels; } });
|
|
40
|
+
Object.defineProperty(exports, "pauseChannel", { enumerable: true, get: function () { return pause_1.pauseChannel; } });
|
|
41
|
+
Object.defineProperty(exports, "resumeAllChannels", { enumerable: true, get: function () { return pause_1.resumeAllChannels; } });
|
|
42
|
+
Object.defineProperty(exports, "resumeChannel", { enumerable: true, get: function () { return pause_1.resumeChannel; } });
|
|
43
|
+
Object.defineProperty(exports, "togglePauseAllChannels", { enumerable: true, get: function () { return pause_1.togglePauseAllChannels; } });
|
|
44
|
+
Object.defineProperty(exports, "togglePauseChannel", { enumerable: true, get: function () { return pause_1.togglePauseChannel; } });
|
|
45
|
+
// Export volume control functions
|
|
46
|
+
var volume_1 = require("./volume");
|
|
47
|
+
Object.defineProperty(exports, "applyVolumeDucking", { enumerable: true, get: function () { return volume_1.applyVolumeDucking; } });
|
|
48
|
+
Object.defineProperty(exports, "clearVolumeDucking", { enumerable: true, get: function () { return volume_1.clearVolumeDucking; } });
|
|
49
|
+
Object.defineProperty(exports, "getAllChannelsVolume", { enumerable: true, get: function () { return volume_1.getAllChannelsVolume; } });
|
|
50
|
+
Object.defineProperty(exports, "getChannelVolume", { enumerable: true, get: function () { return volume_1.getChannelVolume; } });
|
|
51
|
+
Object.defineProperty(exports, "restoreVolumeLevels", { enumerable: true, get: function () { return volume_1.restoreVolumeLevels; } });
|
|
52
|
+
Object.defineProperty(exports, "setAllChannelsVolume", { enumerable: true, get: function () { return volume_1.setAllChannelsVolume; } });
|
|
53
|
+
Object.defineProperty(exports, "setChannelVolume", { enumerable: true, get: function () { return volume_1.setChannelVolume; } });
|
|
54
|
+
Object.defineProperty(exports, "setVolumeDucking", { enumerable: true, get: function () { return volume_1.setVolumeDucking; } });
|
|
55
|
+
Object.defineProperty(exports, "transitionVolume", { enumerable: true, get: function () { return volume_1.transitionVolume; } });
|
|
56
|
+
// Export audio information and progress tracking functions
|
|
57
|
+
var info_1 = require("./info");
|
|
58
|
+
Object.defineProperty(exports, "audioChannels", { enumerable: true, get: function () { return info_1.audioChannels; } });
|
|
59
|
+
Object.defineProperty(exports, "getAllChannelsInfo", { enumerable: true, get: function () { return info_1.getAllChannelsInfo; } });
|
|
60
|
+
Object.defineProperty(exports, "getCurrentAudioInfo", { enumerable: true, get: function () { return info_1.getCurrentAudioInfo; } });
|
|
61
|
+
Object.defineProperty(exports, "getQueueSnapshot", { enumerable: true, get: function () { return info_1.getQueueSnapshot; } });
|
|
62
|
+
Object.defineProperty(exports, "offAudioPause", { enumerable: true, get: function () { return info_1.offAudioPause; } });
|
|
63
|
+
Object.defineProperty(exports, "offAudioProgress", { enumerable: true, get: function () { return info_1.offAudioProgress; } });
|
|
64
|
+
Object.defineProperty(exports, "offAudioResume", { enumerable: true, get: function () { return info_1.offAudioResume; } });
|
|
65
|
+
Object.defineProperty(exports, "offQueueChange", { enumerable: true, get: function () { return info_1.offQueueChange; } });
|
|
66
|
+
Object.defineProperty(exports, "onAudioComplete", { enumerable: true, get: function () { return info_1.onAudioComplete; } });
|
|
67
|
+
Object.defineProperty(exports, "onAudioPause", { enumerable: true, get: function () { return info_1.onAudioPause; } });
|
|
68
|
+
Object.defineProperty(exports, "onAudioProgress", { enumerable: true, get: function () { return info_1.onAudioProgress; } });
|
|
69
|
+
Object.defineProperty(exports, "onAudioResume", { enumerable: true, get: function () { return info_1.onAudioResume; } });
|
|
70
|
+
Object.defineProperty(exports, "onAudioStart", { enumerable: true, get: function () { return info_1.onAudioStart; } });
|
|
71
|
+
Object.defineProperty(exports, "onQueueChange", { enumerable: true, get: function () { return info_1.onQueueChange; } });
|
|
72
|
+
// Export utility functions (for advanced usage)
|
|
73
|
+
var utils_1 = require("./utils");
|
|
74
|
+
Object.defineProperty(exports, "cleanWebpackFilename", { enumerable: true, get: function () { return utils_1.cleanWebpackFilename; } });
|
|
75
|
+
Object.defineProperty(exports, "createQueueSnapshot", { enumerable: true, get: function () { return utils_1.createQueueSnapshot; } });
|
|
76
|
+
Object.defineProperty(exports, "extractFileName", { enumerable: true, get: function () { return utils_1.extractFileName; } });
|
|
77
|
+
Object.defineProperty(exports, "getAudioInfoFromElement", { enumerable: true, get: function () { return utils_1.getAudioInfoFromElement; } });
|