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/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;
@@ -0,0 +1,183 @@
1
+ /**
2
+ * @fileoverview Type definitions for the audio-channel-queue package
3
+ */
4
+ /**
5
+ * Array of HTMLAudioElement objects representing an audio queue
6
+ */
7
+ export type AudioQueue = HTMLAudioElement[];
8
+ /**
9
+ * Basic audio queue channel structure
10
+ */
11
+ export type AudioQueueChannel = {
12
+ queue: AudioQueue;
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
+ }
44
+ /**
45
+ * Comprehensive audio information interface providing metadata about currently playing audio
46
+ */
47
+ export interface AudioInfo {
48
+ /** Current playback position in milliseconds */
49
+ currentTime: number;
50
+ /** Total audio duration in milliseconds */
51
+ duration: number;
52
+ /** Extracted filename from the source URL */
53
+ fileName: string;
54
+ /** Whether the audio is set to loop */
55
+ isLooping: boolean;
56
+ /** Whether the audio is currently paused */
57
+ isPaused: boolean;
58
+ /** Whether the audio is currently playing */
59
+ isPlaying: boolean;
60
+ /** Playback progress as a decimal (0-1) */
61
+ progress: number;
62
+ /** Number of audio files remaining in the queue after current */
63
+ remainingInQueue: number;
64
+ /** Audio file source URL */
65
+ src: string;
66
+ /** Current volume level (0-1) */
67
+ volume: number;
68
+ }
69
+ /**
70
+ * Information provided when an audio file completes playback
71
+ */
72
+ export interface AudioCompleteInfo {
73
+ /** Channel number where the audio completed */
74
+ channelNumber: number;
75
+ /** Extracted filename from the source URL */
76
+ fileName: string;
77
+ /** Number of audio files remaining in the queue after completion */
78
+ remainingInQueue: number;
79
+ /** Audio file source URL */
80
+ src: string;
81
+ }
82
+ /**
83
+ * Information provided when an audio file starts playing
84
+ */
85
+ export interface AudioStartInfo {
86
+ /** Channel number where the audio is starting */
87
+ channelNumber: number;
88
+ /** Total audio duration in milliseconds */
89
+ duration: number;
90
+ /** Extracted filename from the source URL */
91
+ fileName: string;
92
+ /** Audio file source URL */
93
+ src: string;
94
+ }
95
+ /**
96
+ * Information about a single item in an audio queue
97
+ */
98
+ export interface QueueItem {
99
+ /** Total audio duration in milliseconds */
100
+ duration: number;
101
+ /** Extracted filename from the source URL */
102
+ fileName: string;
103
+ /** Whether this item is currently playing */
104
+ isCurrentlyPlaying: boolean;
105
+ /** Whether this item is set to loop */
106
+ isLooping: boolean;
107
+ /** Audio file source URL */
108
+ src: string;
109
+ /** Volume level for this item (0-1) */
110
+ volume: number;
111
+ }
112
+ /**
113
+ * Complete snapshot of a queue's current state
114
+ */
115
+ export interface QueueSnapshot {
116
+ /** Channel number this snapshot represents */
117
+ channelNumber: number;
118
+ /** Zero-based index of the currently playing item */
119
+ currentIndex: number;
120
+ /** Whether the current audio is paused */
121
+ isPaused: boolean;
122
+ /** Array of audio items in the queue with their metadata */
123
+ items: QueueItem[];
124
+ /** Total number of items in the queue */
125
+ totalItems: number;
126
+ /** Current volume level for the channel (0-1) */
127
+ volume: number;
128
+ }
129
+ /**
130
+ * Callback function type for audio progress updates
131
+ * @param info Current audio information
132
+ */
133
+ export type ProgressCallback = (info: AudioInfo) => void;
134
+ /**
135
+ * Callback function type for queue change notifications
136
+ * @param queueSnapshot Current state of the queue
137
+ */
138
+ export type QueueChangeCallback = (queueSnapshot: QueueSnapshot) => void;
139
+ /**
140
+ * Callback function type for audio start notifications
141
+ * @param audioInfo Information about the audio that started
142
+ */
143
+ export type AudioStartCallback = (audioInfo: AudioStartInfo) => void;
144
+ /**
145
+ * Callback function type for audio complete notifications
146
+ * @param audioInfo Information about the audio that completed
147
+ */
148
+ export type AudioCompleteCallback = (audioInfo: AudioCompleteInfo) => void;
149
+ /**
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
163
+ */
164
+ export type ExtendedAudioQueueChannel = AudioQueueChannel & {
165
+ /** Set of callbacks for audio completion events */
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>;
171
+ /** Set of callbacks for audio start events */
172
+ audioStartCallbacks?: Set<AudioStartCallback>;
173
+ /** Whether the current audio in this channel is paused */
174
+ isPaused?: boolean;
175
+ /** Map of audio elements to their progress callback sets */
176
+ progressCallbacks?: Map<HTMLAudioElement, Set<ProgressCallback>>;
177
+ /** Set of callbacks for queue change events */
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;
183
+ };
package/dist/types.js ADDED
@@ -0,0 +1,5 @@
1
+ "use strict";
2
+ /**
3
+ * @fileoverview Type definitions for the audio-channel-queue package
4
+ */
5
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -0,0 +1,58 @@
1
+ /**
2
+ * @fileoverview Utility functions for the audio-channel-queue package
3
+ */
4
+ import { AudioInfo, QueueSnapshot, ExtendedAudioQueueChannel } from './types';
5
+ /**
6
+ * Extracts the filename from a URL string
7
+ * @param url - The URL to extract the filename from
8
+ * @returns The extracted filename or 'unknown' if extraction fails
9
+ * @example
10
+ * ```typescript
11
+ * extractFileName('https://example.com/audio/song.mp3') // Returns: 'song.mp3'
12
+ * extractFileName('/path/to/audio.wav') // Returns: 'audio.wav'
13
+ * ```
14
+ */
15
+ export declare const extractFileName: (url: string) => string;
16
+ /**
17
+ * Extracts comprehensive audio information from an HTMLAudioElement
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
21
+ * @returns AudioInfo object with current playback state or null if audio is invalid
22
+ * @example
23
+ * ```typescript
24
+ * const audioElement = new Audio('song.mp3');
25
+ * const info = getAudioInfoFromElement(audioElement);
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
31
+ * ```
32
+ */
33
+ export declare const getAudioInfoFromElement: (audio: HTMLAudioElement, channelNumber?: number, audioChannels?: ExtendedAudioQueueChannel[]) => AudioInfo | null;
34
+ /**
35
+ * Creates a complete snapshot of a queue's current state
36
+ * @param channelNumber - The channel number to create a snapshot for
37
+ * @param audioChannels - Array of audio channels
38
+ * @returns QueueSnapshot object or null if channel doesn't exist
39
+ * @example
40
+ * ```typescript
41
+ * const snapshot = createQueueSnapshot(0, audioChannels);
42
+ * console.log(`Queue has ${snapshot?.totalItems} items`);
43
+ * ```
44
+ */
45
+ export declare const createQueueSnapshot: (channelNumber: number, audioChannels: ExtendedAudioQueueChannel[]) => QueueSnapshot | null;
46
+ /**
47
+ * Removes webpack hash patterns from filenames to get clean, readable names
48
+ * @param fileName - The filename that may contain webpack hashes
49
+ * @returns The cleaned filename with webpack hashes removed
50
+ * @example
51
+ * ```typescript
52
+ * cleanWebpackFilename('song.a1b2c3d4.mp3') // Returns: 'song.mp3'
53
+ * cleanWebpackFilename('notification.1a2b3c4d5e6f7890.wav') // Returns: 'notification.wav'
54
+ * cleanWebpackFilename('music.12345678.ogg') // Returns: 'music.ogg'
55
+ * cleanWebpackFilename('clean-file.mp3') // Returns: 'clean-file.mp3' (unchanged)
56
+ * ```
57
+ */
58
+ export declare const cleanWebpackFilename: (fileName: string) => string;
package/dist/utils.js ADDED
@@ -0,0 +1,126 @@
1
+ "use strict";
2
+ /**
3
+ * @fileoverview Utility functions for the audio-channel-queue package
4
+ */
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.cleanWebpackFilename = exports.createQueueSnapshot = exports.getAudioInfoFromElement = exports.extractFileName = void 0;
7
+ /**
8
+ * Extracts the filename from a URL string
9
+ * @param url - The URL to extract the filename from
10
+ * @returns The extracted filename or 'unknown' if extraction fails
11
+ * @example
12
+ * ```typescript
13
+ * extractFileName('https://example.com/audio/song.mp3') // Returns: 'song.mp3'
14
+ * extractFileName('/path/to/audio.wav') // Returns: 'audio.wav'
15
+ * ```
16
+ */
17
+ const extractFileName = (url) => {
18
+ try {
19
+ const urlObj = new URL(url);
20
+ const pathname = urlObj.pathname;
21
+ const segments = pathname.split('/');
22
+ const fileName = segments[segments.length - 1];
23
+ return fileName || 'unknown';
24
+ }
25
+ catch (_a) {
26
+ // If URL parsing fails, try simple string manipulation
27
+ const segments = url.split('/');
28
+ const fileName = segments[segments.length - 1];
29
+ return fileName || 'unknown';
30
+ }
31
+ };
32
+ exports.extractFileName = extractFileName;
33
+ /**
34
+ * Extracts comprehensive audio information from an HTMLAudioElement
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
38
+ * @returns AudioInfo object with current playback state or null if audio is invalid
39
+ * @example
40
+ * ```typescript
41
+ * const audioElement = new Audio('song.mp3');
42
+ * const info = getAudioInfoFromElement(audioElement);
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
48
+ * ```
49
+ */
50
+ const getAudioInfoFromElement = (audio, channelNumber, audioChannels) => {
51
+ if (!audio)
52
+ return null;
53
+ const duration = isNaN(audio.duration) ? 0 : audio.duration * 1000; // Convert to milliseconds
54
+ const currentTime = isNaN(audio.currentTime) ? 0 : audio.currentTime * 1000; // Convert to milliseconds
55
+ const progress = duration > 0 ? Math.min(currentTime / duration, 1) : 0;
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
+ }
63
+ return {
64
+ currentTime,
65
+ duration,
66
+ fileName: (0, exports.extractFileName)(audio.src),
67
+ isLooping: audio.loop,
68
+ isPaused: audio.paused && !audio.ended,
69
+ isPlaying,
70
+ progress,
71
+ remainingInQueue,
72
+ src: audio.src,
73
+ volume: audio.volume
74
+ };
75
+ };
76
+ exports.getAudioInfoFromElement = getAudioInfoFromElement;
77
+ /**
78
+ * Creates a complete snapshot of a queue's current state
79
+ * @param channelNumber - The channel number to create a snapshot for
80
+ * @param audioChannels - Array of audio channels
81
+ * @returns QueueSnapshot object or null if channel doesn't exist
82
+ * @example
83
+ * ```typescript
84
+ * const snapshot = createQueueSnapshot(0, audioChannels);
85
+ * console.log(`Queue has ${snapshot?.totalItems} items`);
86
+ * ```
87
+ */
88
+ const createQueueSnapshot = (channelNumber, audioChannels) => {
89
+ const channel = audioChannels[channelNumber];
90
+ if (!channel)
91
+ return null;
92
+ const items = channel.queue.map((audio, index) => ({
93
+ duration: isNaN(audio.duration) ? 0 : audio.duration * 1000,
94
+ fileName: (0, exports.extractFileName)(audio.src),
95
+ isCurrentlyPlaying: index === 0 && !audio.paused && !audio.ended,
96
+ isLooping: audio.loop,
97
+ src: audio.src,
98
+ volume: audio.volume
99
+ }));
100
+ return {
101
+ channelNumber,
102
+ currentIndex: 0, // Current playing is always index 0 in our queue structure
103
+ isPaused: channel.isPaused || false,
104
+ items,
105
+ totalItems: channel.queue.length,
106
+ volume: channel.volume || 1.0
107
+ };
108
+ };
109
+ exports.createQueueSnapshot = createQueueSnapshot;
110
+ /**
111
+ * Removes webpack hash patterns from filenames to get clean, readable names
112
+ * @param fileName - The filename that may contain webpack hashes
113
+ * @returns The cleaned filename with webpack hashes removed
114
+ * @example
115
+ * ```typescript
116
+ * cleanWebpackFilename('song.a1b2c3d4.mp3') // Returns: 'song.mp3'
117
+ * cleanWebpackFilename('notification.1a2b3c4d5e6f7890.wav') // Returns: 'notification.wav'
118
+ * cleanWebpackFilename('music.12345678.ogg') // Returns: 'music.ogg'
119
+ * cleanWebpackFilename('clean-file.mp3') // Returns: 'clean-file.mp3' (unchanged)
120
+ * ```
121
+ */
122
+ const cleanWebpackFilename = (fileName) => {
123
+ // Remove webpack hash pattern: filename.hash.ext → filename.ext
124
+ return fileName.replace(/\.[a-f0-9]{8,}\./i, '.');
125
+ };
126
+ exports.cleanWebpackFilename = cleanWebpackFilename;
@@ -0,0 +1,98 @@
1
+ /**
2
+ * @fileoverview Volume management functions for the audio-channel-queue package
3
+ */
4
+ import { VolumeConfig } from './types';
5
+ /**
6
+ * Smoothly transitions volume for a specific channel over time
7
+ * @param channelNumber - The channel number to transition
8
+ * @param targetVolume - Target volume level (0-1)
9
+ * @param duration - Transition duration in milliseconds
10
+ * @param easing - Easing function type
11
+ * @returns Promise that resolves when transition completes
12
+ * @example
13
+ * ```typescript
14
+ * await transitionVolume(0, 0.2, 500, 'ease-out'); // Duck to 20% over 500ms
15
+ * ```
16
+ */
17
+ export declare const transitionVolume: (channelNumber: number, targetVolume: number, duration?: number, easing?: "linear" | "ease-in" | "ease-out" | "ease-in-out") => Promise<void>;
18
+ /**
19
+ * Sets the volume for a specific channel with optional smooth transition
20
+ * @param channelNumber - The channel number to set volume for
21
+ * @param volume - Volume level (0-1)
22
+ * @param transitionDuration - Optional transition duration in milliseconds
23
+ * @param easing - Optional easing function
24
+ * @example
25
+ * ```typescript
26
+ * setChannelVolume(0, 0.5); // Set channel 0 to 50%
27
+ * setChannelVolume(0, 0.5, 300, 'ease-out'); // Smooth transition over 300ms
28
+ * ```
29
+ */
30
+ export declare const setChannelVolume: (channelNumber: number, volume: number, transitionDuration?: number, easing?: "linear" | "ease-in" | "ease-out" | "ease-in-out") => Promise<void>;
31
+ /**
32
+ * Gets the current volume for a specific channel
33
+ * @param channelNumber - The channel number to get volume for (defaults to 0)
34
+ * @returns Current volume level (0-1) or 1.0 if channel doesn't exist
35
+ * @example
36
+ * ```typescript
37
+ * const volume = getChannelVolume(0);
38
+ * const defaultChannelVolume = getChannelVolume(); // Gets channel 0
39
+ * console.log(`Channel 0 volume: ${volume * 100}%`);
40
+ * ```
41
+ */
42
+ export declare const getChannelVolume: (channelNumber?: number) => number;
43
+ /**
44
+ * Gets the volume levels for all channels
45
+ * @returns Array of volume levels (0-1) for each channel
46
+ * @example
47
+ * ```typescript
48
+ * const volumes = getAllChannelsVolume();
49
+ * volumes.forEach((volume, index) => {
50
+ * console.log(`Channel ${index}: ${volume * 100}%`);
51
+ * });
52
+ * ```
53
+ */
54
+ export declare const getAllChannelsVolume: () => number[];
55
+ /**
56
+ * Sets volume for all channels to the same level
57
+ * @param volume - Volume level (0-1) to apply to all channels
58
+ * @example
59
+ * ```typescript
60
+ * await setAllChannelsVolume(0.6); // Set all channels to 60% volume
61
+ * ```
62
+ */
63
+ export declare const setAllChannelsVolume: (volume: number) => Promise<void>;
64
+ /**
65
+ * Configures volume ducking for channels. When the priority channel plays audio,
66
+ * all other channels will be automatically reduced to the ducking volume level
67
+ * @param config - Volume ducking configuration
68
+ * @example
69
+ * ```typescript
70
+ * // When channel 1 plays, reduce all other channels to 20% volume
71
+ * setVolumeDucking({
72
+ * priorityChannel: 1,
73
+ * priorityVolume: 1.0,
74
+ * duckingVolume: 0.2
75
+ * });
76
+ * ```
77
+ */
78
+ export declare const setVolumeDucking: (config: VolumeConfig) => void;
79
+ /**
80
+ * Removes volume ducking configuration from all channels
81
+ * @example
82
+ * ```typescript
83
+ * clearVolumeDucking(); // Remove all volume ducking effects
84
+ * ```
85
+ */
86
+ export declare const clearVolumeDucking: () => void;
87
+ /**
88
+ * Applies volume ducking effects based on current playback state with smooth transitions
89
+ * @param activeChannelNumber - The channel that just started playing
90
+ * @internal
91
+ */
92
+ export declare const applyVolumeDucking: (activeChannelNumber: number) => Promise<void>;
93
+ /**
94
+ * Restores normal volume levels when priority channel stops with smooth transitions
95
+ * @param stoppedChannelNumber - The channel that just stopped playing
96
+ * @internal
97
+ */
98
+ export declare const restoreVolumeLevels: (stoppedChannelNumber: number) => Promise<void>;