audioq 2.0.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/LICENSE +21 -0
- package/README.md +486 -0
- package/dist/core.d.ts +129 -0
- package/dist/core.js +591 -0
- package/dist/errors.d.ts +138 -0
- package/dist/errors.js +441 -0
- package/dist/events.d.ts +81 -0
- package/dist/events.js +217 -0
- package/dist/index.d.ts +16 -0
- package/dist/index.js +119 -0
- package/dist/info.d.ts +224 -0
- package/dist/info.js +529 -0
- package/dist/pause.d.ts +170 -0
- package/dist/pause.js +467 -0
- package/dist/queue-manipulation.d.ts +104 -0
- package/dist/queue-manipulation.js +319 -0
- package/dist/types.d.ts +382 -0
- package/dist/types.js +55 -0
- package/dist/utils.d.ts +83 -0
- package/dist/utils.js +215 -0
- package/dist/volume.d.ts +162 -0
- package/dist/volume.js +644 -0
- package/dist/web-audio.d.ts +156 -0
- package/dist/web-audio.js +327 -0
- package/package.json +63 -0
- package/src/core.ts +698 -0
- package/src/errors.ts +467 -0
- package/src/events.ts +252 -0
- package/src/index.ts +162 -0
- package/src/info.ts +590 -0
- package/src/pause.ts +523 -0
- package/src/queue-manipulation.ts +378 -0
- package/src/types.ts +415 -0
- package/src/utils.ts +235 -0
- package/src/volume.ts +735 -0
- package/src/web-audio.ts +331 -0
package/dist/types.js
ADDED
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* @fileoverview Type definitions for the audioq package
|
|
4
|
+
*/
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.TimerType = exports.FadeType = exports.EasingType = exports.AudioErrorType = exports.GLOBAL_PROGRESS_KEY = exports.MAX_CHANNELS = void 0;
|
|
7
|
+
/**
|
|
8
|
+
* Maximum number of audio channels allowed to prevent memory exhaustion
|
|
9
|
+
*/
|
|
10
|
+
exports.MAX_CHANNELS = 64;
|
|
11
|
+
/**
|
|
12
|
+
* Symbol used as a key for global (channel-wide) progress callbacks
|
|
13
|
+
* This avoids the need for `null as any` type assertions
|
|
14
|
+
*/
|
|
15
|
+
exports.GLOBAL_PROGRESS_KEY = Symbol('global-progress-callbacks');
|
|
16
|
+
/**
|
|
17
|
+
* Types of audio errors that can occur during playback
|
|
18
|
+
*/
|
|
19
|
+
var AudioErrorType;
|
|
20
|
+
(function (AudioErrorType) {
|
|
21
|
+
AudioErrorType["Abort"] = "abort";
|
|
22
|
+
AudioErrorType["Decode"] = "decode";
|
|
23
|
+
AudioErrorType["Network"] = "network";
|
|
24
|
+
AudioErrorType["Permission"] = "permission";
|
|
25
|
+
AudioErrorType["Timeout"] = "timeout";
|
|
26
|
+
AudioErrorType["Unknown"] = "unknown";
|
|
27
|
+
AudioErrorType["Unsupported"] = "unsupported";
|
|
28
|
+
})(AudioErrorType || (exports.AudioErrorType = AudioErrorType = {}));
|
|
29
|
+
/**
|
|
30
|
+
* Easing function types for smooth volume transitions and animations
|
|
31
|
+
*/
|
|
32
|
+
var EasingType;
|
|
33
|
+
(function (EasingType) {
|
|
34
|
+
EasingType["Linear"] = "linear";
|
|
35
|
+
EasingType["EaseIn"] = "ease-in";
|
|
36
|
+
EasingType["EaseOut"] = "ease-out";
|
|
37
|
+
EasingType["EaseInOut"] = "ease-in-out";
|
|
38
|
+
})(EasingType || (exports.EasingType = EasingType = {}));
|
|
39
|
+
/**
|
|
40
|
+
* Predefined fade types for pause/resume operations with different transition characteristics
|
|
41
|
+
*/
|
|
42
|
+
var FadeType;
|
|
43
|
+
(function (FadeType) {
|
|
44
|
+
FadeType["Linear"] = "linear";
|
|
45
|
+
FadeType["Gentle"] = "gentle";
|
|
46
|
+
FadeType["Dramatic"] = "dramatic";
|
|
47
|
+
})(FadeType || (exports.FadeType = FadeType = {}));
|
|
48
|
+
/**
|
|
49
|
+
* Timer implementation types used for volume transitions to ensure proper cleanup
|
|
50
|
+
*/
|
|
51
|
+
var TimerType;
|
|
52
|
+
(function (TimerType) {
|
|
53
|
+
TimerType["RequestAnimationFrame"] = "raf";
|
|
54
|
+
TimerType["Timeout"] = "timeout";
|
|
55
|
+
})(TimerType || (exports.TimerType = TimerType = {}));
|
package/dist/utils.d.ts
ADDED
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Utility functions for the audioq package
|
|
3
|
+
*/
|
|
4
|
+
import { AudioInfo, QueueSnapshot, ExtendedAudioQueueChannel } from './types';
|
|
5
|
+
/**
|
|
6
|
+
* Validates an audio URL for security and correctness
|
|
7
|
+
* @param url - The URL to validate
|
|
8
|
+
* @returns The validated URL
|
|
9
|
+
* @throws Error if the URL is invalid or potentially malicious
|
|
10
|
+
* @example
|
|
11
|
+
* ```typescript
|
|
12
|
+
* validateAudioUrl('https://example.com/audio.mp3'); // Valid
|
|
13
|
+
* validateAudioUrl('./sounds/local.wav'); // Valid relative path
|
|
14
|
+
* validateAudioUrl('javascript:alert("XSS")'); // Throws error
|
|
15
|
+
* validateAudioUrl('data:text/html,<script>alert("XSS")</script>'); // Throws error
|
|
16
|
+
* ```
|
|
17
|
+
*/
|
|
18
|
+
export declare const validateAudioUrl: (url: string) => string;
|
|
19
|
+
/**
|
|
20
|
+
* Sanitizes a string for safe display in HTML contexts
|
|
21
|
+
* @param text - The text to sanitize
|
|
22
|
+
* @returns The sanitized text safe for display
|
|
23
|
+
* @example
|
|
24
|
+
* ```typescript
|
|
25
|
+
* sanitizeForDisplay('<script>alert("XSS")</script>'); // Returns: '<script>alert("XSS")</script>'
|
|
26
|
+
* sanitizeForDisplay('normal-file.mp3'); // Returns: 'normal-file.mp3'
|
|
27
|
+
* ```
|
|
28
|
+
*/
|
|
29
|
+
export declare const sanitizeForDisplay: (text: string) => string;
|
|
30
|
+
/**
|
|
31
|
+
* Extracts the filename from a URL string
|
|
32
|
+
* @param url - The URL to extract the filename from
|
|
33
|
+
* @returns The extracted filename or 'unknown' if extraction fails
|
|
34
|
+
* @example
|
|
35
|
+
* ```typescript
|
|
36
|
+
* extractFileName('https://example.com/audio/song.mp3') // Returns: 'song.mp3'
|
|
37
|
+
* extractFileName('/path/to/audio.wav') // Returns: 'audio.wav'
|
|
38
|
+
* ```
|
|
39
|
+
*/
|
|
40
|
+
export declare const extractFileName: (url: string) => string;
|
|
41
|
+
/**
|
|
42
|
+
* Extracts comprehensive audio information from an HTMLAudioElement
|
|
43
|
+
* @param audio - The HTML audio element to extract information from
|
|
44
|
+
* @param channelNumber - Optional channel number to include remaining queue info
|
|
45
|
+
* @param audioChannels - Optional audio channels array to calculate remainingInQueue
|
|
46
|
+
* @returns AudioInfo object with current playback state or null if audio is invalid
|
|
47
|
+
* @example
|
|
48
|
+
* ```typescript
|
|
49
|
+
* const audioElement = new Audio('song.mp3');
|
|
50
|
+
* const info = getAudioInfoFromElement(audioElement);
|
|
51
|
+
* console.log(info?.progress); // Current progress as decimal (0-1)
|
|
52
|
+
*
|
|
53
|
+
* // With channel context for remainingInQueue
|
|
54
|
+
* const infoWithQueue = getAudioInfoFromElement(audioElement, 0, audioChannels);
|
|
55
|
+
* console.log(infoWithQueue?.remainingInQueue); // Number of items left in queue
|
|
56
|
+
* ```
|
|
57
|
+
*/
|
|
58
|
+
export declare const getAudioInfoFromElement: (audio: HTMLAudioElement, channelNumber?: number, audioChannels?: ExtendedAudioQueueChannel[]) => AudioInfo | null;
|
|
59
|
+
/**
|
|
60
|
+
* Creates a complete snapshot of a queue's current state
|
|
61
|
+
* @param channelNumber - The channel number to create a snapshot for
|
|
62
|
+
* @param audioChannels - Array of audio channels
|
|
63
|
+
* @returns QueueSnapshot object or null if channel doesn't exist
|
|
64
|
+
* @example
|
|
65
|
+
* ```typescript
|
|
66
|
+
* const snapshot = createQueueSnapshot(0, audioChannels);
|
|
67
|
+
* console.log(`Queue has ${snapshot?.totalItems} items`);
|
|
68
|
+
* ```
|
|
69
|
+
*/
|
|
70
|
+
export declare const createQueueSnapshot: (channelNumber: number, audioChannels: ExtendedAudioQueueChannel[]) => QueueSnapshot | null;
|
|
71
|
+
/**
|
|
72
|
+
* Removes webpack hash patterns from filenames to get clean, readable names
|
|
73
|
+
* @param fileName - The filename that may contain webpack hashes
|
|
74
|
+
* @returns The cleaned filename with webpack hashes removed
|
|
75
|
+
* @example
|
|
76
|
+
* ```typescript
|
|
77
|
+
* cleanWebpackFilename('song.a1b2c3d4.mp3') // Returns: 'song.mp3'
|
|
78
|
+
* cleanWebpackFilename('notification.1a2b3c4d5e6f7890.wav') // Returns: 'notification.wav'
|
|
79
|
+
* cleanWebpackFilename('music.12345678.ogg') // Returns: 'music.ogg'
|
|
80
|
+
* cleanWebpackFilename('clean-file.mp3') // Returns: 'clean-file.mp3' (unchanged)
|
|
81
|
+
* ```
|
|
82
|
+
*/
|
|
83
|
+
export declare const cleanWebpackFilename: (fileName: string) => string;
|
package/dist/utils.js
ADDED
|
@@ -0,0 +1,215 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* @fileoverview Utility functions for the audioq package
|
|
4
|
+
*/
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.cleanWebpackFilename = exports.createQueueSnapshot = exports.getAudioInfoFromElement = exports.extractFileName = exports.sanitizeForDisplay = exports.validateAudioUrl = void 0;
|
|
7
|
+
/**
|
|
8
|
+
* Validates an audio URL for security and correctness
|
|
9
|
+
* @param url - The URL to validate
|
|
10
|
+
* @returns The validated URL
|
|
11
|
+
* @throws Error if the URL is invalid or potentially malicious
|
|
12
|
+
* @example
|
|
13
|
+
* ```typescript
|
|
14
|
+
* validateAudioUrl('https://example.com/audio.mp3'); // Valid
|
|
15
|
+
* validateAudioUrl('./sounds/local.wav'); // Valid relative path
|
|
16
|
+
* validateAudioUrl('javascript:alert("XSS")'); // Throws error
|
|
17
|
+
* validateAudioUrl('data:text/html,<script>alert("XSS")</script>'); // Throws error
|
|
18
|
+
* ```
|
|
19
|
+
*/
|
|
20
|
+
const validateAudioUrl = (url) => {
|
|
21
|
+
if (!url || typeof url !== 'string') {
|
|
22
|
+
throw new Error('Audio URL must be a non-empty string');
|
|
23
|
+
}
|
|
24
|
+
// Trim whitespace
|
|
25
|
+
const trimmedUrl = url.trim();
|
|
26
|
+
// Check for dangerous protocols
|
|
27
|
+
const dangerousProtocols = [
|
|
28
|
+
'javascript:',
|
|
29
|
+
'data:',
|
|
30
|
+
'vbscript:',
|
|
31
|
+
'file:',
|
|
32
|
+
'about:',
|
|
33
|
+
'chrome:',
|
|
34
|
+
'chrome-extension:'
|
|
35
|
+
];
|
|
36
|
+
const lowerUrl = trimmedUrl.toLowerCase();
|
|
37
|
+
for (const protocol of dangerousProtocols) {
|
|
38
|
+
if (lowerUrl.startsWith(protocol)) {
|
|
39
|
+
throw new Error(`Invalid audio URL: dangerous protocol "${protocol}" is not allowed`);
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
// Check for path traversal attempts
|
|
43
|
+
if (trimmedUrl.includes('../') || trimmedUrl.includes('..\\')) {
|
|
44
|
+
throw new Error('Invalid audio URL: path traversal attempts are not allowed');
|
|
45
|
+
}
|
|
46
|
+
// For relative URLs, ensure they don't start with dangerous characters
|
|
47
|
+
if (!trimmedUrl.startsWith('http://') && !trimmedUrl.startsWith('https://')) {
|
|
48
|
+
// Check for protocol-less URLs that might be interpreted as protocols
|
|
49
|
+
if (trimmedUrl.includes(':') && !trimmedUrl.startsWith('//')) {
|
|
50
|
+
const colonIndex = trimmedUrl.indexOf(':');
|
|
51
|
+
const beforeColon = trimmedUrl.substring(0, colonIndex);
|
|
52
|
+
// Allow only if it looks like a Windows drive letter (e.g., C:)
|
|
53
|
+
if (!/^[a-zA-Z]$/.test(beforeColon)) {
|
|
54
|
+
throw new Error('Invalid audio URL: suspicious protocol-like pattern detected');
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
// Validate common audio file extensions (warning, not error)
|
|
59
|
+
const hasAudioExtension = /\.(mp3|wav|ogg|m4a|webm|aac|flac|opus|weba|mp4)$/i.test(trimmedUrl);
|
|
60
|
+
if (!hasAudioExtension && !trimmedUrl.includes('?')) {
|
|
61
|
+
// Log warning but don't throw - some valid URLs might not have extensions
|
|
62
|
+
// eslint-disable-next-line no-console
|
|
63
|
+
console.warn(`Audio URL "${trimmedUrl}" does not have a recognized audio file extension`);
|
|
64
|
+
}
|
|
65
|
+
return trimmedUrl;
|
|
66
|
+
};
|
|
67
|
+
exports.validateAudioUrl = validateAudioUrl;
|
|
68
|
+
/**
|
|
69
|
+
* Sanitizes a string for safe display in HTML contexts
|
|
70
|
+
* @param text - The text to sanitize
|
|
71
|
+
* @returns The sanitized text safe for display
|
|
72
|
+
* @example
|
|
73
|
+
* ```typescript
|
|
74
|
+
* sanitizeForDisplay('<script>alert("XSS")</script>'); // Returns: '<script>alert("XSS")</script>'
|
|
75
|
+
* sanitizeForDisplay('normal-file.mp3'); // Returns: 'normal-file.mp3'
|
|
76
|
+
* ```
|
|
77
|
+
*/
|
|
78
|
+
const sanitizeForDisplay = (text) => {
|
|
79
|
+
if (!text || typeof text !== 'string') {
|
|
80
|
+
return '';
|
|
81
|
+
}
|
|
82
|
+
// Replace HTML special characters
|
|
83
|
+
return text
|
|
84
|
+
.replace(/&/g, '&')
|
|
85
|
+
.replace(/</g, '<')
|
|
86
|
+
.replace(/>/g, '>')
|
|
87
|
+
.replace(/"/g, '"')
|
|
88
|
+
.replace(/'/g, ''')
|
|
89
|
+
.replace(/\//g, '/');
|
|
90
|
+
};
|
|
91
|
+
exports.sanitizeForDisplay = sanitizeForDisplay;
|
|
92
|
+
/**
|
|
93
|
+
* Extracts the filename from a URL string
|
|
94
|
+
* @param url - The URL to extract the filename from
|
|
95
|
+
* @returns The extracted filename or 'unknown' if extraction fails
|
|
96
|
+
* @example
|
|
97
|
+
* ```typescript
|
|
98
|
+
* extractFileName('https://example.com/audio/song.mp3') // Returns: 'song.mp3'
|
|
99
|
+
* extractFileName('/path/to/audio.wav') // Returns: 'audio.wav'
|
|
100
|
+
* ```
|
|
101
|
+
*/
|
|
102
|
+
const extractFileName = (url) => {
|
|
103
|
+
if (!url || typeof url !== 'string') {
|
|
104
|
+
return (0, exports.sanitizeForDisplay)('unknown');
|
|
105
|
+
}
|
|
106
|
+
// Always use simple string manipulation for consistency
|
|
107
|
+
const segments = url.split('/');
|
|
108
|
+
const lastSegment = segments[segments.length - 1] || '';
|
|
109
|
+
// Remove query parameters and hash
|
|
110
|
+
const fileName = lastSegment.split('?')[0].split('#')[0];
|
|
111
|
+
// Decode URI components and sanitize
|
|
112
|
+
try {
|
|
113
|
+
return (0, exports.sanitizeForDisplay)(decodeURIComponent(fileName || 'unknown'));
|
|
114
|
+
}
|
|
115
|
+
catch (_a) {
|
|
116
|
+
// If decoding fails, return the sanitized raw filename
|
|
117
|
+
return (0, exports.sanitizeForDisplay)(fileName || 'unknown');
|
|
118
|
+
}
|
|
119
|
+
};
|
|
120
|
+
exports.extractFileName = extractFileName;
|
|
121
|
+
/**
|
|
122
|
+
* Extracts comprehensive audio information from an HTMLAudioElement
|
|
123
|
+
* @param audio - The HTML audio element to extract information from
|
|
124
|
+
* @param channelNumber - Optional channel number to include remaining queue info
|
|
125
|
+
* @param audioChannels - Optional audio channels array to calculate remainingInQueue
|
|
126
|
+
* @returns AudioInfo object with current playback state or null if audio is invalid
|
|
127
|
+
* @example
|
|
128
|
+
* ```typescript
|
|
129
|
+
* const audioElement = new Audio('song.mp3');
|
|
130
|
+
* const info = getAudioInfoFromElement(audioElement);
|
|
131
|
+
* console.log(info?.progress); // Current progress as decimal (0-1)
|
|
132
|
+
*
|
|
133
|
+
* // With channel context for remainingInQueue
|
|
134
|
+
* const infoWithQueue = getAudioInfoFromElement(audioElement, 0, audioChannels);
|
|
135
|
+
* console.log(infoWithQueue?.remainingInQueue); // Number of items left in queue
|
|
136
|
+
* ```
|
|
137
|
+
*/
|
|
138
|
+
const getAudioInfoFromElement = (audio, channelNumber, audioChannels) => {
|
|
139
|
+
if (!audio)
|
|
140
|
+
return null;
|
|
141
|
+
const duration = isNaN(audio.duration) ? 0 : audio.duration * 1000; // Convert to milliseconds
|
|
142
|
+
const currentTime = isNaN(audio.currentTime) ? 0 : audio.currentTime * 1000; // Convert to milliseconds
|
|
143
|
+
const progress = duration > 0 ? Math.min(currentTime / duration, 1) : 0;
|
|
144
|
+
const isPlaying = !audio.paused && !audio.ended && audio.readyState > 2;
|
|
145
|
+
// Calculate remainingInQueue if channel context is provided
|
|
146
|
+
let remainingInQueue = 0;
|
|
147
|
+
if (channelNumber !== undefined && (audioChannels === null || audioChannels === void 0 ? void 0 : audioChannels[channelNumber])) {
|
|
148
|
+
const channel = audioChannels[channelNumber];
|
|
149
|
+
remainingInQueue = Math.max(0, channel.queue.length - 1); // Exclude current playing audio
|
|
150
|
+
}
|
|
151
|
+
return {
|
|
152
|
+
currentTime,
|
|
153
|
+
duration,
|
|
154
|
+
fileName: (0, exports.extractFileName)(audio.src),
|
|
155
|
+
isLooping: audio.loop,
|
|
156
|
+
isPaused: audio.paused && !audio.ended,
|
|
157
|
+
isPlaying,
|
|
158
|
+
progress,
|
|
159
|
+
remainingInQueue,
|
|
160
|
+
src: audio.src,
|
|
161
|
+
volume: audio.volume
|
|
162
|
+
};
|
|
163
|
+
};
|
|
164
|
+
exports.getAudioInfoFromElement = getAudioInfoFromElement;
|
|
165
|
+
/**
|
|
166
|
+
* Creates a complete snapshot of a queue's current state
|
|
167
|
+
* @param channelNumber - The channel number to create a snapshot for
|
|
168
|
+
* @param audioChannels - Array of audio channels
|
|
169
|
+
* @returns QueueSnapshot object or null if channel doesn't exist
|
|
170
|
+
* @example
|
|
171
|
+
* ```typescript
|
|
172
|
+
* const snapshot = createQueueSnapshot(0, audioChannels);
|
|
173
|
+
* console.log(`Queue has ${snapshot?.totalItems} items`);
|
|
174
|
+
* ```
|
|
175
|
+
*/
|
|
176
|
+
const createQueueSnapshot = (channelNumber, audioChannels) => {
|
|
177
|
+
var _a, _b;
|
|
178
|
+
const channel = audioChannels[channelNumber];
|
|
179
|
+
if (!channel)
|
|
180
|
+
return null;
|
|
181
|
+
const items = channel.queue.map((audio, index) => ({
|
|
182
|
+
duration: isNaN(audio.duration) ? 0 : audio.duration * 1000,
|
|
183
|
+
fileName: (0, exports.extractFileName)(audio.src),
|
|
184
|
+
isCurrentlyPlaying: index === 0 && !audio.paused && !audio.ended,
|
|
185
|
+
isLooping: audio.loop,
|
|
186
|
+
src: audio.src,
|
|
187
|
+
volume: audio.volume
|
|
188
|
+
}));
|
|
189
|
+
return {
|
|
190
|
+
channelNumber,
|
|
191
|
+
currentIndex: 0, // Current playing is always index 0 in our queue structure
|
|
192
|
+
isPaused: (_a = channel.isPaused) !== null && _a !== void 0 ? _a : false,
|
|
193
|
+
items,
|
|
194
|
+
totalItems: channel.queue.length,
|
|
195
|
+
volume: (_b = channel.volume) !== null && _b !== void 0 ? _b : 1.0
|
|
196
|
+
};
|
|
197
|
+
};
|
|
198
|
+
exports.createQueueSnapshot = createQueueSnapshot;
|
|
199
|
+
/**
|
|
200
|
+
* Removes webpack hash patterns from filenames to get clean, readable names
|
|
201
|
+
* @param fileName - The filename that may contain webpack hashes
|
|
202
|
+
* @returns The cleaned filename with webpack hashes removed
|
|
203
|
+
* @example
|
|
204
|
+
* ```typescript
|
|
205
|
+
* cleanWebpackFilename('song.a1b2c3d4.mp3') // Returns: 'song.mp3'
|
|
206
|
+
* cleanWebpackFilename('notification.1a2b3c4d5e6f7890.wav') // Returns: 'notification.wav'
|
|
207
|
+
* cleanWebpackFilename('music.12345678.ogg') // Returns: 'music.ogg'
|
|
208
|
+
* cleanWebpackFilename('clean-file.mp3') // Returns: 'clean-file.mp3' (unchanged)
|
|
209
|
+
* ```
|
|
210
|
+
*/
|
|
211
|
+
const cleanWebpackFilename = (fileName) => {
|
|
212
|
+
// Remove webpack hash pattern: filename.hash.ext → filename.ext
|
|
213
|
+
return fileName.replace(/\.[a-f0-9]{8,}\./i, '.');
|
|
214
|
+
};
|
|
215
|
+
exports.cleanWebpackFilename = cleanWebpackFilename;
|
package/dist/volume.d.ts
ADDED
|
@@ -0,0 +1,162 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Volume management functions for the audioq package
|
|
3
|
+
*/
|
|
4
|
+
import { VolumeConfig, FadeType, FadeConfig, EasingType } from './types';
|
|
5
|
+
/**
|
|
6
|
+
* Gets the fade configuration for a specific fade type
|
|
7
|
+
* @param fadeType - The fade type to get configuration for
|
|
8
|
+
* @returns Fade configuration object
|
|
9
|
+
* @example
|
|
10
|
+
* ```typescript
|
|
11
|
+
* const config = getFadeConfig('gentle');
|
|
12
|
+
* console.log(`Gentle fade duration: ${config.duration}ms`);
|
|
13
|
+
* ```
|
|
14
|
+
*/
|
|
15
|
+
export declare const getFadeConfig: (fadeType: FadeType) => FadeConfig;
|
|
16
|
+
/**
|
|
17
|
+
* Smoothly transitions volume for a specific channel over time
|
|
18
|
+
* @param channelNumber - The channel number to transition
|
|
19
|
+
* @param targetVolume - Target volume level (0-1)
|
|
20
|
+
* @param duration - Transition duration in milliseconds
|
|
21
|
+
* @param easing - Easing function type
|
|
22
|
+
* @returns Promise that resolves when transition completes
|
|
23
|
+
* @example
|
|
24
|
+
* ```typescript
|
|
25
|
+
* await transitionVolume(0, 0.2, 500, 'ease-out'); // Duck to 20% over 500ms
|
|
26
|
+
* ```
|
|
27
|
+
*/
|
|
28
|
+
export declare const transitionVolume: (channelNumber: number, targetVolume: number, duration?: number, easing?: EasingType) => Promise<void>;
|
|
29
|
+
/**
|
|
30
|
+
* Sets the volume for a specific channel with optional smooth transition
|
|
31
|
+
* Automatically uses Web Audio API on iOS devices for enhanced volume control
|
|
32
|
+
* @param channelNumber - The channel number to set volume for
|
|
33
|
+
* @param volume - Volume level (0-1)
|
|
34
|
+
* @param transitionDuration - Optional transition duration in milliseconds
|
|
35
|
+
* @param easing - Optional easing function
|
|
36
|
+
* @throws Error if the channel number exceeds the maximum allowed channels
|
|
37
|
+
* @example
|
|
38
|
+
* ```typescript
|
|
39
|
+
* setChannelVolume(0, 0.5); // Set channel 0 to 50%
|
|
40
|
+
* setChannelVolume(0, 0.5, 300, 'ease-out'); // Smooth transition over 300ms
|
|
41
|
+
* ```
|
|
42
|
+
*/
|
|
43
|
+
export declare const setChannelVolume: (channelNumber: number, volume: number, transitionDuration?: number, easing?: EasingType) => Promise<void>;
|
|
44
|
+
/**
|
|
45
|
+
* Gets the current volume for a specific channel
|
|
46
|
+
* @param channelNumber - The channel number to get volume for (defaults to 0)
|
|
47
|
+
* @returns Current volume level (0-1) or 1.0 if channel doesn't exist
|
|
48
|
+
* @example
|
|
49
|
+
* ```typescript
|
|
50
|
+
* const volume = getChannelVolume(0);
|
|
51
|
+
* const defaultChannelVolume = getChannelVolume(); // Gets channel 0
|
|
52
|
+
* console.log(`Channel 0 volume: ${volume * 100}%`);
|
|
53
|
+
* ```
|
|
54
|
+
*/
|
|
55
|
+
export declare const getChannelVolume: (channelNumber?: number) => number;
|
|
56
|
+
/**
|
|
57
|
+
* Gets the volume levels for all channels
|
|
58
|
+
* @returns Array of volume levels (0-1) for each channel
|
|
59
|
+
* @example
|
|
60
|
+
* ```typescript
|
|
61
|
+
* const volumes = getAllChannelsVolume();
|
|
62
|
+
* volumes.forEach((volume, index) => {
|
|
63
|
+
* console.log(`Channel ${index}: ${volume * 100}%`);
|
|
64
|
+
* });
|
|
65
|
+
* ```
|
|
66
|
+
*/
|
|
67
|
+
export declare const getAllChannelsVolume: () => number[];
|
|
68
|
+
/**
|
|
69
|
+
* Sets volume for all channels to the same level
|
|
70
|
+
* @param volume - Volume level (0-1) to apply to all channels
|
|
71
|
+
* @example
|
|
72
|
+
* ```typescript
|
|
73
|
+
* await setAllChannelsVolume(0.6); // Set all channels to 60% volume
|
|
74
|
+
* ```
|
|
75
|
+
*/
|
|
76
|
+
export declare const setAllChannelsVolume: (volume: number) => Promise<void>;
|
|
77
|
+
/**
|
|
78
|
+
* Sets the global volume multiplier that affects all channels
|
|
79
|
+
* This acts as a global volume control - individual channel volumes are multiplied by this value
|
|
80
|
+
* @param volume - Global volume level (0-1, will be clamped to this range)
|
|
81
|
+
* @example
|
|
82
|
+
* ```typescript
|
|
83
|
+
* // Set channel-specific volumes
|
|
84
|
+
* await setChannelVolume(0, 0.8); // SFX at 80%
|
|
85
|
+
* await setChannelVolume(1, 0.6); // Music at 60%
|
|
86
|
+
*
|
|
87
|
+
* // Apply global volume of 50% - all channels play at half their set volume
|
|
88
|
+
* await setGlobalVolume(0.5); // SFX now plays at 40%, music at 30%
|
|
89
|
+
* ```
|
|
90
|
+
*/
|
|
91
|
+
export declare const setGlobalVolume: (volume: number) => Promise<void>;
|
|
92
|
+
/**
|
|
93
|
+
* Gets the current global volume multiplier
|
|
94
|
+
* @returns Current global volume level (0-1), defaults to 1.0
|
|
95
|
+
* @example
|
|
96
|
+
* ```typescript
|
|
97
|
+
* const globalVol = getGlobalVolume();
|
|
98
|
+
* console.log(`Global volume is ${globalVol * 100}%`);
|
|
99
|
+
* ```
|
|
100
|
+
*/
|
|
101
|
+
export declare const getGlobalVolume: () => number;
|
|
102
|
+
/**
|
|
103
|
+
* Configures volume ducking for channels. When the priority channel plays audio,
|
|
104
|
+
* all other channels will be automatically reduced to the ducking volume level
|
|
105
|
+
* @param config - Volume ducking configuration
|
|
106
|
+
* @throws Error if the priority channel number exceeds the maximum allowed channels
|
|
107
|
+
* @example
|
|
108
|
+
* ```typescript
|
|
109
|
+
* // When channel 1 plays, reduce all other channels to 20% volume
|
|
110
|
+
* setVolumeDucking({
|
|
111
|
+
* priorityChannel: 1,
|
|
112
|
+
* priorityVolume: 1.0,
|
|
113
|
+
* duckingVolume: 0.2
|
|
114
|
+
* });
|
|
115
|
+
* ```
|
|
116
|
+
*/
|
|
117
|
+
export declare const setVolumeDucking: (config: VolumeConfig) => void;
|
|
118
|
+
/**
|
|
119
|
+
* Removes volume ducking configuration from all channels
|
|
120
|
+
* @example
|
|
121
|
+
* ```typescript
|
|
122
|
+
* clearVolumeDucking(); // Remove all volume ducking effects
|
|
123
|
+
* ```
|
|
124
|
+
*/
|
|
125
|
+
export declare const clearVolumeDucking: () => void;
|
|
126
|
+
/**
|
|
127
|
+
* Applies volume ducking effects based on current playback state with smooth transitions
|
|
128
|
+
* @param activeChannelNumber - The channel that just started playing
|
|
129
|
+
* @internal
|
|
130
|
+
*/
|
|
131
|
+
export declare const applyVolumeDucking: (activeChannelNumber: number) => Promise<void>;
|
|
132
|
+
/**
|
|
133
|
+
* Restores normal volume levels when priority channel queue becomes empty
|
|
134
|
+
* @param stoppedChannelNumber - The channel that just stopped playing
|
|
135
|
+
* @internal
|
|
136
|
+
*/
|
|
137
|
+
export declare const restoreVolumeLevels: (stoppedChannelNumber: number) => Promise<void>;
|
|
138
|
+
/**
|
|
139
|
+
* Cancels any active volume transition for a specific channel
|
|
140
|
+
* @param channelNumber - The channel number to cancel transitions for
|
|
141
|
+
* @internal
|
|
142
|
+
*/
|
|
143
|
+
export declare const cancelVolumeTransition: (channelNumber: number) => void;
|
|
144
|
+
/**
|
|
145
|
+
* Cancels all active volume transitions across all channels
|
|
146
|
+
* @internal
|
|
147
|
+
*/
|
|
148
|
+
export declare const cancelAllVolumeTransitions: () => void;
|
|
149
|
+
/**
|
|
150
|
+
* Initializes Web Audio API nodes for a new audio element
|
|
151
|
+
* @param audio - The audio element to initialize nodes for
|
|
152
|
+
* @param channelNumber - The channel number this audio belongs to
|
|
153
|
+
* @internal
|
|
154
|
+
*/
|
|
155
|
+
export declare const initializeWebAudioForAudio: (audio: HTMLAudioElement, channelNumber: number) => Promise<void>;
|
|
156
|
+
/**
|
|
157
|
+
* Cleans up Web Audio API nodes for an audio element
|
|
158
|
+
* @param audio - The audio element to clean up nodes for
|
|
159
|
+
* @param channelNumber - The channel number this audio belongs to
|
|
160
|
+
* @internal
|
|
161
|
+
*/
|
|
162
|
+
export declare const cleanupWebAudioForAudio: (audio: HTMLAudioElement, channelNumber: number) => void;
|