audio-channel-queue 1.4.0 → 1.5.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 +249 -13
- package/dist/core.d.ts +53 -0
- package/dist/core.js +189 -0
- package/dist/events.d.ts +59 -0
- package/dist/events.js +162 -0
- package/dist/index.d.ts +23 -0
- package/dist/index.js +47 -0
- package/dist/info.d.ts +122 -0
- package/dist/info.js +240 -0
- package/dist/types.d.ts +115 -0
- package/dist/types.js +5 -0
- package/dist/utils.d.ts +52 -0
- package/dist/utils.js +106 -0
- package/package.json +7 -4
- package/src/core.ts +209 -0
- package/src/events.ts +189 -0
- package/src/index.ts +66 -0
- package/src/info.ts +262 -0
- package/src/types.ts +127 -0
- package/src/utils.ts +109 -0
- package/dist/audio.d.ts +0 -10
- package/dist/audio.js +0 -66
package/dist/events.js
ADDED
|
@@ -0,0 +1,162 @@
|
|
|
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.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
|
+
// Store listener functions for cleanup
|
|
83
|
+
const progressListeners = new WeakMap();
|
|
84
|
+
/**
|
|
85
|
+
* Sets up comprehensive progress tracking for an audio element
|
|
86
|
+
* @param audio - The HTML audio element to track
|
|
87
|
+
* @param channelNumber - The channel number this audio belongs to
|
|
88
|
+
* @param audioChannels - Array of audio channels
|
|
89
|
+
* @example
|
|
90
|
+
* ```typescript
|
|
91
|
+
* const audioElement = new Audio('song.mp3');
|
|
92
|
+
* setupProgressTracking(audioElement, 0, audioChannels);
|
|
93
|
+
* ```
|
|
94
|
+
*/
|
|
95
|
+
const setupProgressTracking = (audio, channelNumber, audioChannels) => {
|
|
96
|
+
const channel = audioChannels[channelNumber];
|
|
97
|
+
if (!channel)
|
|
98
|
+
return;
|
|
99
|
+
if (!channel.progressCallbacks) {
|
|
100
|
+
channel.progressCallbacks = new Map();
|
|
101
|
+
}
|
|
102
|
+
// Don't set up tracking if already exists
|
|
103
|
+
if (progressListeners.has(audio))
|
|
104
|
+
return;
|
|
105
|
+
const updateProgress = () => {
|
|
106
|
+
var _a, _b;
|
|
107
|
+
// Get callbacks for this specific audio element AND the channel-wide callbacks
|
|
108
|
+
const audioCallbacks = ((_a = channel.progressCallbacks) === null || _a === void 0 ? void 0 : _a.get(audio)) || new Set();
|
|
109
|
+
const channelCallbacks = ((_b = channel.progressCallbacks) === null || _b === void 0 ? void 0 : _b.get(null)) || new Set();
|
|
110
|
+
// Combine both sets of callbacks
|
|
111
|
+
const allCallbacks = new Set([...audioCallbacks, ...channelCallbacks]);
|
|
112
|
+
if (allCallbacks.size === 0)
|
|
113
|
+
return;
|
|
114
|
+
const info = (0, utils_1.getAudioInfoFromElement)(audio);
|
|
115
|
+
if (info) {
|
|
116
|
+
allCallbacks.forEach((callback) => {
|
|
117
|
+
try {
|
|
118
|
+
callback(info);
|
|
119
|
+
}
|
|
120
|
+
catch (error) {
|
|
121
|
+
console.error('Error in progress callback:', error);
|
|
122
|
+
}
|
|
123
|
+
});
|
|
124
|
+
}
|
|
125
|
+
};
|
|
126
|
+
// Store the listener function for cleanup
|
|
127
|
+
progressListeners.set(audio, updateProgress);
|
|
128
|
+
// Set up comprehensive event listeners for progress tracking
|
|
129
|
+
audio.addEventListener('timeupdate', updateProgress);
|
|
130
|
+
audio.addEventListener('loadedmetadata', updateProgress);
|
|
131
|
+
audio.addEventListener('play', updateProgress);
|
|
132
|
+
audio.addEventListener('pause', updateProgress);
|
|
133
|
+
audio.addEventListener('ended', updateProgress);
|
|
134
|
+
};
|
|
135
|
+
exports.setupProgressTracking = setupProgressTracking;
|
|
136
|
+
/**
|
|
137
|
+
* Cleans up progress tracking for an audio element to prevent memory leaks
|
|
138
|
+
* @param audio - The HTML audio element to clean up
|
|
139
|
+
* @param channelNumber - The channel number this audio belongs to
|
|
140
|
+
* @param audioChannels - Array of audio channels
|
|
141
|
+
* @example
|
|
142
|
+
* ```typescript
|
|
143
|
+
* cleanupProgressTracking(audioElement, 0, audioChannels);
|
|
144
|
+
* ```
|
|
145
|
+
*/
|
|
146
|
+
const cleanupProgressTracking = (audio, channelNumber, audioChannels) => {
|
|
147
|
+
const channel = audioChannels[channelNumber];
|
|
148
|
+
if (!channel || !channel.progressCallbacks)
|
|
149
|
+
return;
|
|
150
|
+
// Remove event listeners
|
|
151
|
+
const updateProgress = progressListeners.get(audio);
|
|
152
|
+
if (updateProgress) {
|
|
153
|
+
audio.removeEventListener('timeupdate', updateProgress);
|
|
154
|
+
audio.removeEventListener('loadedmetadata', updateProgress);
|
|
155
|
+
audio.removeEventListener('play', updateProgress);
|
|
156
|
+
audio.removeEventListener('pause', updateProgress);
|
|
157
|
+
audio.removeEventListener('ended', updateProgress);
|
|
158
|
+
progressListeners.delete(audio);
|
|
159
|
+
}
|
|
160
|
+
channel.progressCallbacks.delete(audio);
|
|
161
|
+
};
|
|
162
|
+
exports.cleanupProgressTracking = cleanupProgressTracking;
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,23 @@
|
|
|
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, and extensive event handling capabilities.
|
|
6
|
+
*
|
|
7
|
+
* @example Basic Usage
|
|
8
|
+
* ```typescript
|
|
9
|
+
* import { queueAudio, onAudioProgress } from 'audio-channel-queue';
|
|
10
|
+
*
|
|
11
|
+
* // Queue an audio file
|
|
12
|
+
* await queueAudio('song.mp3');
|
|
13
|
+
*
|
|
14
|
+
* // Track progress
|
|
15
|
+
* onAudioProgress(0, (info) => {
|
|
16
|
+
* console.log(`Progress: ${info.progress * 100}%`);
|
|
17
|
+
* });
|
|
18
|
+
* ```
|
|
19
|
+
*/
|
|
20
|
+
export type { AudioCompleteCallback, AudioCompleteInfo, AudioInfo, AudioQueue, AudioQueueChannel, AudioStartCallback, AudioStartInfo, ExtendedAudioQueueChannel, ProgressCallback, QueueChangeCallback, QueueItem, QueueSnapshot } from './types';
|
|
21
|
+
export { playAudioQueue, queueAudio, stopAllAudio, stopAllAudioInChannel, stopCurrentAudioInChannel } from './core';
|
|
22
|
+
export { audioChannels, getAllChannelsInfo, getCurrentAudioInfo, getQueueSnapshot, offAudioProgress, onAudioComplete, onAudioProgress, onAudioStart, onQueueChange, offQueueChange } from './info';
|
|
23
|
+
export { cleanWebpackFilename, createQueueSnapshot, extractFileName, getAudioInfoFromElement } from './utils';
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,47 @@
|
|
|
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, and extensive event handling capabilities.
|
|
7
|
+
*
|
|
8
|
+
* @example Basic Usage
|
|
9
|
+
* ```typescript
|
|
10
|
+
* import { queueAudio, onAudioProgress } 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
|
+
*/
|
|
21
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
22
|
+
exports.getAudioInfoFromElement = exports.extractFileName = exports.createQueueSnapshot = exports.cleanWebpackFilename = exports.offQueueChange = exports.onQueueChange = exports.onAudioStart = exports.onAudioProgress = exports.onAudioComplete = exports.offAudioProgress = exports.getQueueSnapshot = exports.getCurrentAudioInfo = exports.getAllChannelsInfo = exports.audioChannels = exports.stopCurrentAudioInChannel = exports.stopAllAudioInChannel = exports.stopAllAudio = exports.queueAudio = exports.playAudioQueue = void 0;
|
|
23
|
+
// Export core queue management functions
|
|
24
|
+
var core_1 = require("./core");
|
|
25
|
+
Object.defineProperty(exports, "playAudioQueue", { enumerable: true, get: function () { return core_1.playAudioQueue; } });
|
|
26
|
+
Object.defineProperty(exports, "queueAudio", { enumerable: true, get: function () { return core_1.queueAudio; } });
|
|
27
|
+
Object.defineProperty(exports, "stopAllAudio", { enumerable: true, get: function () { return core_1.stopAllAudio; } });
|
|
28
|
+
Object.defineProperty(exports, "stopAllAudioInChannel", { enumerable: true, get: function () { return core_1.stopAllAudioInChannel; } });
|
|
29
|
+
Object.defineProperty(exports, "stopCurrentAudioInChannel", { enumerable: true, get: function () { return core_1.stopCurrentAudioInChannel; } });
|
|
30
|
+
// Export audio information and progress tracking functions
|
|
31
|
+
var info_1 = require("./info");
|
|
32
|
+
Object.defineProperty(exports, "audioChannels", { enumerable: true, get: function () { return info_1.audioChannels; } });
|
|
33
|
+
Object.defineProperty(exports, "getAllChannelsInfo", { enumerable: true, get: function () { return info_1.getAllChannelsInfo; } });
|
|
34
|
+
Object.defineProperty(exports, "getCurrentAudioInfo", { enumerable: true, get: function () { return info_1.getCurrentAudioInfo; } });
|
|
35
|
+
Object.defineProperty(exports, "getQueueSnapshot", { enumerable: true, get: function () { return info_1.getQueueSnapshot; } });
|
|
36
|
+
Object.defineProperty(exports, "offAudioProgress", { enumerable: true, get: function () { return info_1.offAudioProgress; } });
|
|
37
|
+
Object.defineProperty(exports, "onAudioComplete", { enumerable: true, get: function () { return info_1.onAudioComplete; } });
|
|
38
|
+
Object.defineProperty(exports, "onAudioProgress", { enumerable: true, get: function () { return info_1.onAudioProgress; } });
|
|
39
|
+
Object.defineProperty(exports, "onAudioStart", { enumerable: true, get: function () { return info_1.onAudioStart; } });
|
|
40
|
+
Object.defineProperty(exports, "onQueueChange", { enumerable: true, get: function () { return info_1.onQueueChange; } });
|
|
41
|
+
Object.defineProperty(exports, "offQueueChange", { enumerable: true, get: function () { return info_1.offQueueChange; } });
|
|
42
|
+
// Export utility functions (for advanced usage)
|
|
43
|
+
var utils_1 = require("./utils");
|
|
44
|
+
Object.defineProperty(exports, "cleanWebpackFilename", { enumerable: true, get: function () { return utils_1.cleanWebpackFilename; } });
|
|
45
|
+
Object.defineProperty(exports, "createQueueSnapshot", { enumerable: true, get: function () { return utils_1.createQueueSnapshot; } });
|
|
46
|
+
Object.defineProperty(exports, "extractFileName", { enumerable: true, get: function () { return utils_1.extractFileName; } });
|
|
47
|
+
Object.defineProperty(exports, "getAudioInfoFromElement", { enumerable: true, get: function () { return utils_1.getAudioInfoFromElement; } });
|
package/dist/info.d.ts
ADDED
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Audio information and progress tracking functions for the audio-channel-queue package
|
|
3
|
+
*/
|
|
4
|
+
import { AudioInfo, QueueSnapshot, ProgressCallback, QueueChangeCallback, AudioStartCallback, AudioCompleteCallback, ExtendedAudioQueueChannel } from './types';
|
|
5
|
+
/**
|
|
6
|
+
* Global array of extended audio queue channels
|
|
7
|
+
*/
|
|
8
|
+
export declare const audioChannels: ExtendedAudioQueueChannel[];
|
|
9
|
+
/**
|
|
10
|
+
* Gets current audio information for a specific channel
|
|
11
|
+
* @param channelNumber - The channel number (defaults to 0)
|
|
12
|
+
* @returns AudioInfo object or null if no audio is playing
|
|
13
|
+
* @example
|
|
14
|
+
* ```typescript
|
|
15
|
+
* const info = getCurrentAudioInfo(0);
|
|
16
|
+
* if (info) {
|
|
17
|
+
* console.log(`Currently playing: ${info.fileName}`);
|
|
18
|
+
* console.log(`Progress: ${(info.progress * 100).toFixed(1)}%`);
|
|
19
|
+
* }
|
|
20
|
+
* ```
|
|
21
|
+
*/
|
|
22
|
+
export declare const getCurrentAudioInfo: (channelNumber?: number) => AudioInfo | null;
|
|
23
|
+
/**
|
|
24
|
+
* Gets audio information for all channels
|
|
25
|
+
* @returns Array of AudioInfo objects (null for channels with no audio)
|
|
26
|
+
* @example
|
|
27
|
+
* ```typescript
|
|
28
|
+
* const allInfo = getAllChannelsInfo();
|
|
29
|
+
* allInfo.forEach((info, channel) => {
|
|
30
|
+
* if (info) {
|
|
31
|
+
* console.log(`Channel ${channel}: ${info.fileName}`);
|
|
32
|
+
* }
|
|
33
|
+
* });
|
|
34
|
+
* ```
|
|
35
|
+
*/
|
|
36
|
+
export declare const getAllChannelsInfo: () => (AudioInfo | null)[];
|
|
37
|
+
/**
|
|
38
|
+
* Gets a complete snapshot of the queue state for a specific channel
|
|
39
|
+
* @param channelNumber - The channel number
|
|
40
|
+
* @returns QueueSnapshot object or null if channel doesn't exist
|
|
41
|
+
* @example
|
|
42
|
+
* ```typescript
|
|
43
|
+
* const snapshot = getQueueSnapshot(0);
|
|
44
|
+
* if (snapshot) {
|
|
45
|
+
* console.log(`Queue has ${snapshot.totalItems} items`);
|
|
46
|
+
* console.log(`Currently playing: ${snapshot.items[0]?.fileName}`);
|
|
47
|
+
* }
|
|
48
|
+
* ```
|
|
49
|
+
*/
|
|
50
|
+
export declare const getQueueSnapshot: (channelNumber: number) => QueueSnapshot | null;
|
|
51
|
+
/**
|
|
52
|
+
* Subscribes to real-time progress updates for a specific channel
|
|
53
|
+
* @param channelNumber - The channel number
|
|
54
|
+
* @param callback - Function to call with audio info updates
|
|
55
|
+
* @example
|
|
56
|
+
* ```typescript
|
|
57
|
+
* onAudioProgress(0, (info) => {
|
|
58
|
+
* updateProgressBar(info.progress);
|
|
59
|
+
* updateTimeDisplay(info.currentTime, info.duration);
|
|
60
|
+
* });
|
|
61
|
+
* ```
|
|
62
|
+
*/
|
|
63
|
+
export declare const onAudioProgress: (channelNumber: number, callback: ProgressCallback) => void;
|
|
64
|
+
/**
|
|
65
|
+
* Removes progress listeners for a specific channel
|
|
66
|
+
* @param channelNumber - The channel number
|
|
67
|
+
* @example
|
|
68
|
+
* ```typescript
|
|
69
|
+
* offAudioProgress(0); // Stop receiving progress updates for channel 0
|
|
70
|
+
* ```
|
|
71
|
+
*/
|
|
72
|
+
export declare const offAudioProgress: (channelNumber: number) => void;
|
|
73
|
+
/**
|
|
74
|
+
* Subscribes to queue change events for a specific channel
|
|
75
|
+
* @param channelNumber - The channel number to monitor
|
|
76
|
+
* @param callback - Function to call when queue changes
|
|
77
|
+
* @example
|
|
78
|
+
* ```typescript
|
|
79
|
+
* onQueueChange(0, (snapshot) => {
|
|
80
|
+
* updateQueueDisplay(snapshot.items);
|
|
81
|
+
* updateQueueCount(snapshot.totalItems);
|
|
82
|
+
* });
|
|
83
|
+
* ```
|
|
84
|
+
*/
|
|
85
|
+
export declare const onQueueChange: (channelNumber: number, callback: QueueChangeCallback) => void;
|
|
86
|
+
/**
|
|
87
|
+
* Removes queue change listeners for a specific channel
|
|
88
|
+
* @param channelNumber - The channel number
|
|
89
|
+
* @example
|
|
90
|
+
* ```typescript
|
|
91
|
+
* offQueueChange(0); // Stop receiving queue change notifications for channel 0
|
|
92
|
+
* ```
|
|
93
|
+
*/
|
|
94
|
+
export declare const offQueueChange: (channelNumber: number) => void;
|
|
95
|
+
/**
|
|
96
|
+
* Subscribes to audio start events for a specific channel
|
|
97
|
+
* @param channelNumber - The channel number to monitor
|
|
98
|
+
* @param callback - Function to call when audio starts playing
|
|
99
|
+
* @example
|
|
100
|
+
* ```typescript
|
|
101
|
+
* onAudioStart(0, (info) => {
|
|
102
|
+
* showNowPlaying(info.fileName);
|
|
103
|
+
* setTotalDuration(info.duration);
|
|
104
|
+
* });
|
|
105
|
+
* ```
|
|
106
|
+
*/
|
|
107
|
+
export declare const onAudioStart: (channelNumber: number, callback: AudioStartCallback) => void;
|
|
108
|
+
/**
|
|
109
|
+
* Subscribes to audio complete events for a specific channel
|
|
110
|
+
* @param channelNumber - The channel number to monitor
|
|
111
|
+
* @param callback - Function to call when audio completes
|
|
112
|
+
* @example
|
|
113
|
+
* ```typescript
|
|
114
|
+
* onAudioComplete(0, (info) => {
|
|
115
|
+
* logPlaybackComplete(info.fileName);
|
|
116
|
+
* if (info.remainingInQueue === 0) {
|
|
117
|
+
* showQueueComplete();
|
|
118
|
+
* }
|
|
119
|
+
* });
|
|
120
|
+
* ```
|
|
121
|
+
*/
|
|
122
|
+
export declare const onAudioComplete: (channelNumber: number, callback: AudioCompleteCallback) => void;
|
package/dist/info.js
ADDED
|
@@ -0,0 +1,240 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* @fileoverview Audio information and progress tracking functions for the audio-channel-queue package
|
|
4
|
+
*/
|
|
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;
|
|
7
|
+
const utils_1 = require("./utils");
|
|
8
|
+
const events_1 = require("./events");
|
|
9
|
+
/**
|
|
10
|
+
* Global array of extended audio queue channels
|
|
11
|
+
*/
|
|
12
|
+
exports.audioChannels = [];
|
|
13
|
+
/**
|
|
14
|
+
* Gets current audio information for a specific channel
|
|
15
|
+
* @param channelNumber - The channel number (defaults to 0)
|
|
16
|
+
* @returns AudioInfo object or null if no audio is playing
|
|
17
|
+
* @example
|
|
18
|
+
* ```typescript
|
|
19
|
+
* const info = getCurrentAudioInfo(0);
|
|
20
|
+
* if (info) {
|
|
21
|
+
* console.log(`Currently playing: ${info.fileName}`);
|
|
22
|
+
* console.log(`Progress: ${(info.progress * 100).toFixed(1)}%`);
|
|
23
|
+
* }
|
|
24
|
+
* ```
|
|
25
|
+
*/
|
|
26
|
+
const getCurrentAudioInfo = (channelNumber = 0) => {
|
|
27
|
+
const channel = exports.audioChannels[channelNumber];
|
|
28
|
+
if (!channel || channel.queue.length === 0) {
|
|
29
|
+
return null;
|
|
30
|
+
}
|
|
31
|
+
const currentAudio = channel.queue[0];
|
|
32
|
+
return (0, utils_1.getAudioInfoFromElement)(currentAudio);
|
|
33
|
+
};
|
|
34
|
+
exports.getCurrentAudioInfo = getCurrentAudioInfo;
|
|
35
|
+
/**
|
|
36
|
+
* Gets audio information for all channels
|
|
37
|
+
* @returns Array of AudioInfo objects (null for channels with no audio)
|
|
38
|
+
* @example
|
|
39
|
+
* ```typescript
|
|
40
|
+
* const allInfo = getAllChannelsInfo();
|
|
41
|
+
* allInfo.forEach((info, channel) => {
|
|
42
|
+
* if (info) {
|
|
43
|
+
* console.log(`Channel ${channel}: ${info.fileName}`);
|
|
44
|
+
* }
|
|
45
|
+
* });
|
|
46
|
+
* ```
|
|
47
|
+
*/
|
|
48
|
+
const getAllChannelsInfo = () => {
|
|
49
|
+
const allChannelsInfo = [];
|
|
50
|
+
for (let i = 0; i < exports.audioChannels.length; i++) {
|
|
51
|
+
allChannelsInfo.push((0, exports.getCurrentAudioInfo)(i));
|
|
52
|
+
}
|
|
53
|
+
return allChannelsInfo;
|
|
54
|
+
};
|
|
55
|
+
exports.getAllChannelsInfo = getAllChannelsInfo;
|
|
56
|
+
/**
|
|
57
|
+
* Gets a complete snapshot of the queue state for a specific channel
|
|
58
|
+
* @param channelNumber - The channel number
|
|
59
|
+
* @returns QueueSnapshot object or null if channel doesn't exist
|
|
60
|
+
* @example
|
|
61
|
+
* ```typescript
|
|
62
|
+
* const snapshot = getQueueSnapshot(0);
|
|
63
|
+
* if (snapshot) {
|
|
64
|
+
* console.log(`Queue has ${snapshot.totalItems} items`);
|
|
65
|
+
* console.log(`Currently playing: ${snapshot.items[0]?.fileName}`);
|
|
66
|
+
* }
|
|
67
|
+
* ```
|
|
68
|
+
*/
|
|
69
|
+
const getQueueSnapshot = (channelNumber) => {
|
|
70
|
+
return (0, utils_1.createQueueSnapshot)(channelNumber, exports.audioChannels);
|
|
71
|
+
};
|
|
72
|
+
exports.getQueueSnapshot = getQueueSnapshot;
|
|
73
|
+
/**
|
|
74
|
+
* Subscribes to real-time progress updates for a specific channel
|
|
75
|
+
* @param channelNumber - The channel number
|
|
76
|
+
* @param callback - Function to call with audio info updates
|
|
77
|
+
* @example
|
|
78
|
+
* ```typescript
|
|
79
|
+
* onAudioProgress(0, (info) => {
|
|
80
|
+
* updateProgressBar(info.progress);
|
|
81
|
+
* updateTimeDisplay(info.currentTime, info.duration);
|
|
82
|
+
* });
|
|
83
|
+
* ```
|
|
84
|
+
*/
|
|
85
|
+
const onAudioProgress = (channelNumber, callback) => {
|
|
86
|
+
if (!exports.audioChannels[channelNumber]) {
|
|
87
|
+
exports.audioChannels[channelNumber] = {
|
|
88
|
+
audioCompleteCallbacks: new Set(),
|
|
89
|
+
audioStartCallbacks: new Set(),
|
|
90
|
+
progressCallbacks: new Map(),
|
|
91
|
+
queue: [],
|
|
92
|
+
queueChangeCallbacks: new Set()
|
|
93
|
+
};
|
|
94
|
+
}
|
|
95
|
+
const channel = exports.audioChannels[channelNumber];
|
|
96
|
+
if (!channel.progressCallbacks) {
|
|
97
|
+
channel.progressCallbacks = new Map();
|
|
98
|
+
}
|
|
99
|
+
// Add callback for current audio if exists
|
|
100
|
+
if (channel.queue.length > 0) {
|
|
101
|
+
const currentAudio = channel.queue[0];
|
|
102
|
+
if (!channel.progressCallbacks.has(currentAudio)) {
|
|
103
|
+
channel.progressCallbacks.set(currentAudio, new Set());
|
|
104
|
+
}
|
|
105
|
+
channel.progressCallbacks.get(currentAudio).add(callback);
|
|
106
|
+
// Set up tracking if not already done
|
|
107
|
+
(0, events_1.setupProgressTracking)(currentAudio, channelNumber, exports.audioChannels);
|
|
108
|
+
}
|
|
109
|
+
// Store callback for future audio elements in this channel
|
|
110
|
+
if (!channel.progressCallbacks.has(null)) {
|
|
111
|
+
channel.progressCallbacks.set(null, new Set());
|
|
112
|
+
}
|
|
113
|
+
channel.progressCallbacks.get(null).add(callback);
|
|
114
|
+
};
|
|
115
|
+
exports.onAudioProgress = onAudioProgress;
|
|
116
|
+
/**
|
|
117
|
+
* Removes progress listeners for a specific channel
|
|
118
|
+
* @param channelNumber - The channel number
|
|
119
|
+
* @example
|
|
120
|
+
* ```typescript
|
|
121
|
+
* offAudioProgress(0); // Stop receiving progress updates for channel 0
|
|
122
|
+
* ```
|
|
123
|
+
*/
|
|
124
|
+
const offAudioProgress = (channelNumber) => {
|
|
125
|
+
const channel = exports.audioChannels[channelNumber];
|
|
126
|
+
if (!channel || !channel.progressCallbacks)
|
|
127
|
+
return;
|
|
128
|
+
// Clean up event listeners for current audio if exists
|
|
129
|
+
if (channel.queue.length > 0) {
|
|
130
|
+
const currentAudio = channel.queue[0];
|
|
131
|
+
(0, events_1.cleanupProgressTracking)(currentAudio, channelNumber, exports.audioChannels);
|
|
132
|
+
}
|
|
133
|
+
// Clear all callbacks for this channel
|
|
134
|
+
channel.progressCallbacks.clear();
|
|
135
|
+
};
|
|
136
|
+
exports.offAudioProgress = offAudioProgress;
|
|
137
|
+
/**
|
|
138
|
+
* Subscribes to queue change events for a specific channel
|
|
139
|
+
* @param channelNumber - The channel number to monitor
|
|
140
|
+
* @param callback - Function to call when queue changes
|
|
141
|
+
* @example
|
|
142
|
+
* ```typescript
|
|
143
|
+
* onQueueChange(0, (snapshot) => {
|
|
144
|
+
* updateQueueDisplay(snapshot.items);
|
|
145
|
+
* updateQueueCount(snapshot.totalItems);
|
|
146
|
+
* });
|
|
147
|
+
* ```
|
|
148
|
+
*/
|
|
149
|
+
const onQueueChange = (channelNumber, callback) => {
|
|
150
|
+
if (!exports.audioChannels[channelNumber]) {
|
|
151
|
+
exports.audioChannels[channelNumber] = {
|
|
152
|
+
audioCompleteCallbacks: new Set(),
|
|
153
|
+
audioStartCallbacks: new Set(),
|
|
154
|
+
progressCallbacks: new Map(),
|
|
155
|
+
queue: [],
|
|
156
|
+
queueChangeCallbacks: new Set()
|
|
157
|
+
};
|
|
158
|
+
}
|
|
159
|
+
const channel = exports.audioChannels[channelNumber];
|
|
160
|
+
if (!channel.queueChangeCallbacks) {
|
|
161
|
+
channel.queueChangeCallbacks = new Set();
|
|
162
|
+
}
|
|
163
|
+
channel.queueChangeCallbacks.add(callback);
|
|
164
|
+
};
|
|
165
|
+
exports.onQueueChange = onQueueChange;
|
|
166
|
+
/**
|
|
167
|
+
* Removes queue change listeners for a specific channel
|
|
168
|
+
* @param channelNumber - The channel number
|
|
169
|
+
* @example
|
|
170
|
+
* ```typescript
|
|
171
|
+
* offQueueChange(0); // Stop receiving queue change notifications for channel 0
|
|
172
|
+
* ```
|
|
173
|
+
*/
|
|
174
|
+
const offQueueChange = (channelNumber) => {
|
|
175
|
+
const channel = exports.audioChannels[channelNumber];
|
|
176
|
+
if (!channel || !channel.queueChangeCallbacks)
|
|
177
|
+
return;
|
|
178
|
+
channel.queueChangeCallbacks.clear();
|
|
179
|
+
};
|
|
180
|
+
exports.offQueueChange = offQueueChange;
|
|
181
|
+
/**
|
|
182
|
+
* Subscribes to audio start events for a specific channel
|
|
183
|
+
* @param channelNumber - The channel number to monitor
|
|
184
|
+
* @param callback - Function to call when audio starts playing
|
|
185
|
+
* @example
|
|
186
|
+
* ```typescript
|
|
187
|
+
* onAudioStart(0, (info) => {
|
|
188
|
+
* showNowPlaying(info.fileName);
|
|
189
|
+
* setTotalDuration(info.duration);
|
|
190
|
+
* });
|
|
191
|
+
* ```
|
|
192
|
+
*/
|
|
193
|
+
const onAudioStart = (channelNumber, callback) => {
|
|
194
|
+
if (!exports.audioChannels[channelNumber]) {
|
|
195
|
+
exports.audioChannels[channelNumber] = {
|
|
196
|
+
audioCompleteCallbacks: new Set(),
|
|
197
|
+
audioStartCallbacks: new Set(),
|
|
198
|
+
progressCallbacks: new Map(),
|
|
199
|
+
queue: [],
|
|
200
|
+
queueChangeCallbacks: new Set()
|
|
201
|
+
};
|
|
202
|
+
}
|
|
203
|
+
const channel = exports.audioChannels[channelNumber];
|
|
204
|
+
if (!channel.audioStartCallbacks) {
|
|
205
|
+
channel.audioStartCallbacks = new Set();
|
|
206
|
+
}
|
|
207
|
+
channel.audioStartCallbacks.add(callback);
|
|
208
|
+
};
|
|
209
|
+
exports.onAudioStart = onAudioStart;
|
|
210
|
+
/**
|
|
211
|
+
* Subscribes to audio complete events for a specific channel
|
|
212
|
+
* @param channelNumber - The channel number to monitor
|
|
213
|
+
* @param callback - Function to call when audio completes
|
|
214
|
+
* @example
|
|
215
|
+
* ```typescript
|
|
216
|
+
* onAudioComplete(0, (info) => {
|
|
217
|
+
* logPlaybackComplete(info.fileName);
|
|
218
|
+
* if (info.remainingInQueue === 0) {
|
|
219
|
+
* showQueueComplete();
|
|
220
|
+
* }
|
|
221
|
+
* });
|
|
222
|
+
* ```
|
|
223
|
+
*/
|
|
224
|
+
const onAudioComplete = (channelNumber, callback) => {
|
|
225
|
+
if (!exports.audioChannels[channelNumber]) {
|
|
226
|
+
exports.audioChannels[channelNumber] = {
|
|
227
|
+
audioCompleteCallbacks: new Set(),
|
|
228
|
+
audioStartCallbacks: new Set(),
|
|
229
|
+
progressCallbacks: new Map(),
|
|
230
|
+
queue: [],
|
|
231
|
+
queueChangeCallbacks: new Set()
|
|
232
|
+
};
|
|
233
|
+
}
|
|
234
|
+
const channel = exports.audioChannels[channelNumber];
|
|
235
|
+
if (!channel.audioCompleteCallbacks) {
|
|
236
|
+
channel.audioCompleteCallbacks = new Set();
|
|
237
|
+
}
|
|
238
|
+
channel.audioCompleteCallbacks.add(callback);
|
|
239
|
+
};
|
|
240
|
+
exports.onAudioComplete = onAudioComplete;
|