@students-dev/audify-js 1.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/README.md +396 -0
- package/dist/cjs/index.js +1494 -0
- package/dist/cjs/index.js.map +1 -0
- package/dist/esm/index.js +1477 -0
- package/dist/esm/index.js.map +1 -0
- package/dist/types/constants/Modes.d.ts +31 -0
- package/dist/types/engine/AudioEngine.d.ts +100 -0
- package/dist/types/engine/Filters.d.ts +48 -0
- package/dist/types/engine/Player.d.ts +62 -0
- package/dist/types/events/EventBus.d.ts +35 -0
- package/dist/types/index.d.ts +13 -0
- package/dist/types/plugins/Plugin.d.ts +49 -0
- package/dist/types/plugins/PluginManager.d.ts +51 -0
- package/dist/types/providers/LocalProvider.d.ts +23 -0
- package/dist/types/providers/SoundCloudProvider.d.ts +23 -0
- package/dist/types/providers/YouTubeProvider.d.ts +29 -0
- package/dist/types/queue/Queue.d.ts +72 -0
- package/dist/types/queue/Track.d.ts +32 -0
- package/dist/types/utils/Logger.d.ts +39 -0
- package/dist/types/utils/Metadata.d.ts +35 -0
- package/dist/types/utils/Probe.d.ts +23 -0
- package/dist/types/utils/Time.d.ts +29 -0
- package/package.json +60 -0
package/README.md
ADDED
|
@@ -0,0 +1,396 @@
|
|
|
1
|
+
# audify-js
|
|
2
|
+
|
|
3
|
+
[](https://badge.fury.io/js/%40students-dev%2Faudify-js)
|
|
4
|
+
[](https://opensource.org/licenses/MIT)
|
|
5
|
+
|
|
6
|
+
A lightweight, modern, modular audio engine that provides playback, filters, queue management, events, and extensibility through plugins. Works in both **Node.js** and **browser** environments.
|
|
7
|
+
|
|
8
|
+
## Features
|
|
9
|
+
|
|
10
|
+
- 🎵 **Unified Audio Engine**: Cross-environment abstraction using Web Audio API
|
|
11
|
+
- 📋 **Queue Management**: Add, remove, shuffle, jump, and loop modes
|
|
12
|
+
- 🎛️ **Audio Filters**: Bassboost, nightcore, vaporwave, 8D rotate, pitch/speed adjustment, reverb
|
|
13
|
+
- 🔌 **Plugin System**: Extensible architecture with lifecycle hooks
|
|
14
|
+
- 📡 **Event-Driven**: Comprehensive event system for all operations
|
|
15
|
+
- 🌐 **Multi-Source Support**: Local files, remote URLs, YouTube, SoundCloud
|
|
16
|
+
- 🛠️ **Developer-Friendly**: TypeScript declarations, ESM/CJS builds
|
|
17
|
+
|
|
18
|
+
## Installation
|
|
19
|
+
|
|
20
|
+
```bash
|
|
21
|
+
npm install @students-dev/audify-js
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
## Quick Start
|
|
25
|
+
|
|
26
|
+
### Browser
|
|
27
|
+
|
|
28
|
+
```html
|
|
29
|
+
<!DOCTYPE html>
|
|
30
|
+
<html>
|
|
31
|
+
<head>
|
|
32
|
+
<title>audify-js Demo</title>
|
|
33
|
+
</head>
|
|
34
|
+
<body>
|
|
35
|
+
<script type="module">
|
|
36
|
+
import { AudioEngine } from '@students-dev/audify-js';
|
|
37
|
+
|
|
38
|
+
const engine = new AudioEngine();
|
|
39
|
+
|
|
40
|
+
engine.on('ready', () => {
|
|
41
|
+
console.log('Audio engine ready!');
|
|
42
|
+
engine.add('https://example.com/audio.mp3');
|
|
43
|
+
engine.play();
|
|
44
|
+
});
|
|
45
|
+
|
|
46
|
+
engine.on('trackStart', (track) => {
|
|
47
|
+
console.log('Now playing:', track.title);
|
|
48
|
+
});
|
|
49
|
+
</script>
|
|
50
|
+
</body>
|
|
51
|
+
</html>
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
### Node.js
|
|
55
|
+
|
|
56
|
+
```javascript
|
|
57
|
+
import { AudioEngine } from '@students-dev/audify-js';
|
|
58
|
+
|
|
59
|
+
const engine = new AudioEngine();
|
|
60
|
+
|
|
61
|
+
engine.on('ready', () => {
|
|
62
|
+
engine.add('/path/to/audio.mp3');
|
|
63
|
+
engine.play();
|
|
64
|
+
});
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
## API Reference
|
|
68
|
+
|
|
69
|
+
### AudioEngine
|
|
70
|
+
|
|
71
|
+
The main class that orchestrates all audio functionality.
|
|
72
|
+
|
|
73
|
+
#### Constructor
|
|
74
|
+
|
|
75
|
+
```javascript
|
|
76
|
+
const engine = new AudioEngine(options);
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
#### Methods
|
|
80
|
+
|
|
81
|
+
##### Playback Controls
|
|
82
|
+
|
|
83
|
+
- `play(track?)`: Play a track or resume current playback
|
|
84
|
+
- `pause()`: Pause playback
|
|
85
|
+
- `stop()`: Stop playback
|
|
86
|
+
- `seek(time)`: Seek to specific time (seconds)
|
|
87
|
+
- `setVolume(volume)`: Set volume (0-1)
|
|
88
|
+
|
|
89
|
+
##### Queue Management
|
|
90
|
+
|
|
91
|
+
- `add(tracks)`: Add track(s) to queue
|
|
92
|
+
- `remove(identifier)`: Remove track by index or ID
|
|
93
|
+
- `next()`: Skip to next track
|
|
94
|
+
- `previous()`: Go to previous track
|
|
95
|
+
- `shuffle()`: Shuffle the queue
|
|
96
|
+
- `clear()`: Clear the queue
|
|
97
|
+
- `jump(index)`: Jump to track at index
|
|
98
|
+
|
|
99
|
+
##### Filters
|
|
100
|
+
|
|
101
|
+
- `applyFilter(type, options)`: Apply audio filter
|
|
102
|
+
- `removeFilter(type)`: Remove audio filter
|
|
103
|
+
|
|
104
|
+
##### Loop Modes
|
|
105
|
+
|
|
106
|
+
- `setLoopMode(mode)`: Set loop mode (`LOOP_MODES.OFF`, `LOOP_MODES.TRACK`, `LOOP_MODES.QUEUE`)
|
|
107
|
+
|
|
108
|
+
##### State
|
|
109
|
+
|
|
110
|
+
- `getState()`: Get current engine state
|
|
111
|
+
|
|
112
|
+
#### Events
|
|
113
|
+
|
|
114
|
+
- `ready`: Engine initialized
|
|
115
|
+
- `play`: Playback started
|
|
116
|
+
- `pause`: Playback paused
|
|
117
|
+
- `stop`: Playback stopped
|
|
118
|
+
- `error`: Error occurred
|
|
119
|
+
- `queueEmpty`: Queue became empty
|
|
120
|
+
- `trackStart`: Track started playing
|
|
121
|
+
- `trackEnd`: Track ended
|
|
122
|
+
- `filterApplied`: Filter applied
|
|
123
|
+
- `trackAdd`: Track added to queue
|
|
124
|
+
- `trackRemove`: Track removed from queue
|
|
125
|
+
- `shuffle`: Queue shuffled
|
|
126
|
+
- `clear`: Queue cleared
|
|
127
|
+
|
|
128
|
+
### Queue
|
|
129
|
+
|
|
130
|
+
Manages the audio playback queue.
|
|
131
|
+
|
|
132
|
+
```javascript
|
|
133
|
+
const queue = engine.queue;
|
|
134
|
+
|
|
135
|
+
// Add tracks
|
|
136
|
+
queue.add('track.mp3');
|
|
137
|
+
queue.add(['track1.mp3', 'track2.mp3']);
|
|
138
|
+
|
|
139
|
+
// Navigate
|
|
140
|
+
queue.next();
|
|
141
|
+
queue.previous();
|
|
142
|
+
queue.jump(5);
|
|
143
|
+
|
|
144
|
+
// Modify
|
|
145
|
+
queue.shuffle();
|
|
146
|
+
queue.clear();
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
### Track
|
|
150
|
+
|
|
151
|
+
Represents an audio track.
|
|
152
|
+
|
|
153
|
+
```javascript
|
|
154
|
+
import { Track } from '@students-dev/audify-js';
|
|
155
|
+
|
|
156
|
+
const track = new Track('https://example.com/audio.mp3', {
|
|
157
|
+
title: 'My Song',
|
|
158
|
+
artist: 'Artist Name',
|
|
159
|
+
duration: 180
|
|
160
|
+
});
|
|
161
|
+
```
|
|
162
|
+
|
|
163
|
+
### Filters
|
|
164
|
+
|
|
165
|
+
Apply audio effects.
|
|
166
|
+
|
|
167
|
+
```javascript
|
|
168
|
+
// Bass boost
|
|
169
|
+
engine.applyFilter('bassboost', { gain: 1.5 });
|
|
170
|
+
|
|
171
|
+
// Nightcore
|
|
172
|
+
engine.applyFilter('nightcore', { rate: 1.2 });
|
|
173
|
+
|
|
174
|
+
// 8D Audio
|
|
175
|
+
engine.applyFilter('8d');
|
|
176
|
+
|
|
177
|
+
// Remove filter
|
|
178
|
+
engine.removeFilter('bassboost');
|
|
179
|
+
```
|
|
180
|
+
|
|
181
|
+
Available filters:
|
|
182
|
+
- `bassboost`: Boost low frequencies
|
|
183
|
+
- `nightcore`: Speed up and pitch up
|
|
184
|
+
- `vaporwave`: Slow down and pitch down
|
|
185
|
+
- `8d`: 8D audio rotation effect
|
|
186
|
+
- `pitch`: Adjust pitch
|
|
187
|
+
- `speed`: Adjust playback speed
|
|
188
|
+
- `reverb`: Add reverb effect
|
|
189
|
+
|
|
190
|
+
### Plugins
|
|
191
|
+
|
|
192
|
+
Extend functionality with plugins.
|
|
193
|
+
|
|
194
|
+
```javascript
|
|
195
|
+
import { Plugin } from '@students-dev/audify-js';
|
|
196
|
+
|
|
197
|
+
class MyPlugin extends Plugin {
|
|
198
|
+
constructor() {
|
|
199
|
+
super('my-plugin', '1.0.0');
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
onLoad(engine) {
|
|
203
|
+
console.log('Plugin loaded!');
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
beforePlay(track) {
|
|
207
|
+
console.log('About to play:', track.title);
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
// Load plugin
|
|
212
|
+
const plugin = new MyPlugin();
|
|
213
|
+
engine.pluginManager.load(plugin);
|
|
214
|
+
engine.pluginManager.enable('my-plugin');
|
|
215
|
+
```
|
|
216
|
+
|
|
217
|
+
### Providers
|
|
218
|
+
|
|
219
|
+
Fetch metadata from different sources.
|
|
220
|
+
|
|
221
|
+
```javascript
|
|
222
|
+
import { YouTubeProvider, SoundCloudProvider, LocalProvider } from '@students-dev/audify-js';
|
|
223
|
+
|
|
224
|
+
// YouTube
|
|
225
|
+
const ytInfo = await YouTubeProvider.getInfo('https://youtube.com/watch?v=VIDEO_ID');
|
|
226
|
+
|
|
227
|
+
// SoundCloud
|
|
228
|
+
const scInfo = await SoundCloudProvider.getInfo('https://soundcloud.com/artist/track');
|
|
229
|
+
|
|
230
|
+
// Local file (Node.js only)
|
|
231
|
+
const localInfo = await LocalProvider.getInfo('/path/to/file.mp3');
|
|
232
|
+
```
|
|
233
|
+
|
|
234
|
+
### Utils
|
|
235
|
+
|
|
236
|
+
Utility functions for common tasks.
|
|
237
|
+
|
|
238
|
+
```javascript
|
|
239
|
+
import { TimeUtils, MetadataUtils, ProbeUtils } from '@students-dev/audify-js';
|
|
240
|
+
|
|
241
|
+
// Time formatting
|
|
242
|
+
TimeUtils.format(125); // "02:05"
|
|
243
|
+
|
|
244
|
+
// Metadata extraction
|
|
245
|
+
const metadata = MetadataUtils.extract('https://example.com/song.mp3');
|
|
246
|
+
|
|
247
|
+
// Audio probing
|
|
248
|
+
const probe = await ProbeUtils.probe(audioBuffer);
|
|
249
|
+
```
|
|
250
|
+
|
|
251
|
+
## Examples
|
|
252
|
+
|
|
253
|
+
### Basic Playback
|
|
254
|
+
|
|
255
|
+
```javascript
|
|
256
|
+
import { AudioEngine } from '@students-dev/audify-js';
|
|
257
|
+
|
|
258
|
+
const engine = new AudioEngine();
|
|
259
|
+
|
|
260
|
+
engine.on('ready', async () => {
|
|
261
|
+
// Add tracks
|
|
262
|
+
engine.add([
|
|
263
|
+
'track1.mp3',
|
|
264
|
+
'track2.mp3',
|
|
265
|
+
'https://example.com/track3.mp3'
|
|
266
|
+
]);
|
|
267
|
+
|
|
268
|
+
// Start playing
|
|
269
|
+
await engine.play();
|
|
270
|
+
|
|
271
|
+
// Apply filter
|
|
272
|
+
engine.applyFilter('bassboost');
|
|
273
|
+
});
|
|
274
|
+
|
|
275
|
+
// Handle events
|
|
276
|
+
engine.on('trackStart', (track) => {
|
|
277
|
+
console.log(`Playing: ${track.title}`);
|
|
278
|
+
});
|
|
279
|
+
|
|
280
|
+
engine.on('error', (error) => {
|
|
281
|
+
console.error('Playback error:', error);
|
|
282
|
+
});
|
|
283
|
+
```
|
|
284
|
+
|
|
285
|
+
### Queue Management
|
|
286
|
+
|
|
287
|
+
```javascript
|
|
288
|
+
// Add multiple tracks
|
|
289
|
+
engine.add([
|
|
290
|
+
{ url: 'song1.mp3', title: 'Song One' },
|
|
291
|
+
{ url: 'song2.mp3', title: 'Song Two' }
|
|
292
|
+
]);
|
|
293
|
+
|
|
294
|
+
// Skip to next
|
|
295
|
+
engine.next();
|
|
296
|
+
|
|
297
|
+
// Shuffle queue
|
|
298
|
+
engine.shuffle();
|
|
299
|
+
|
|
300
|
+
// Clear and add new tracks
|
|
301
|
+
engine.clear();
|
|
302
|
+
engine.add('new-song.mp3');
|
|
303
|
+
```
|
|
304
|
+
|
|
305
|
+
### Custom Plugin
|
|
306
|
+
|
|
307
|
+
```javascript
|
|
308
|
+
import { Plugin } from '@students-dev/audify-js';
|
|
309
|
+
|
|
310
|
+
class LoggerPlugin extends Plugin {
|
|
311
|
+
constructor() {
|
|
312
|
+
super('logger');
|
|
313
|
+
}
|
|
314
|
+
|
|
315
|
+
beforePlay(track) {
|
|
316
|
+
console.log(`[Logger] Starting playback: ${track.title}`);
|
|
317
|
+
}
|
|
318
|
+
|
|
319
|
+
afterPlay(track) {
|
|
320
|
+
console.log(`[Logger] Finished playback: ${track.title}`);
|
|
321
|
+
}
|
|
322
|
+
|
|
323
|
+
trackEnd(track) {
|
|
324
|
+
console.log(`[Logger] Track ended: ${track.title}`);
|
|
325
|
+
}
|
|
326
|
+
}
|
|
327
|
+
|
|
328
|
+
// Register plugin
|
|
329
|
+
const loggerPlugin = new LoggerPlugin();
|
|
330
|
+
engine.pluginManager.load(loggerPlugin);
|
|
331
|
+
engine.pluginManager.enable('logger');
|
|
332
|
+
```
|
|
333
|
+
|
|
334
|
+
## Browser Compatibility
|
|
335
|
+
|
|
336
|
+
- Chrome 14+
|
|
337
|
+
- Firefox 25+
|
|
338
|
+
- Safari 6+
|
|
339
|
+
- Edge 12+
|
|
340
|
+
|
|
341
|
+
## Node.js Compatibility
|
|
342
|
+
|
|
343
|
+
- Node.js 14+
|
|
344
|
+
|
|
345
|
+
For audio playback in Node.js, additional setup may be required for actual audio output.
|
|
346
|
+
|
|
347
|
+
## Contributing
|
|
348
|
+
|
|
349
|
+
1. Fork the repository
|
|
350
|
+
2. Create your feature branch (`git checkout -b feature/amazing-feature`)
|
|
351
|
+
3. Commit your changes (`git commit -m 'Add amazing feature'`)
|
|
352
|
+
4. Push to the branch (`git push origin feature/amazing-feature`)
|
|
353
|
+
5. Open a Pull Request
|
|
354
|
+
|
|
355
|
+
## License
|
|
356
|
+
|
|
357
|
+
MIT License - see the [LICENSE](LICENSE) file for details.
|
|
358
|
+
|
|
359
|
+
## Troubleshooting
|
|
360
|
+
|
|
361
|
+
### Audio not playing in browser
|
|
362
|
+
|
|
363
|
+
Ensure you're handling user interaction requirements for Web Audio API:
|
|
364
|
+
|
|
365
|
+
```javascript
|
|
366
|
+
// Resume AudioContext on user interaction
|
|
367
|
+
document.addEventListener('click', () => {
|
|
368
|
+
if (engine.audioContext.state === 'suspended') {
|
|
369
|
+
engine.audioContext.resume();
|
|
370
|
+
}
|
|
371
|
+
});
|
|
372
|
+
```
|
|
373
|
+
|
|
374
|
+
### CORS issues with remote audio
|
|
375
|
+
|
|
376
|
+
When loading audio from different domains, ensure proper CORS headers are set on the server.
|
|
377
|
+
|
|
378
|
+
### Node.js audio output
|
|
379
|
+
|
|
380
|
+
For actual audio playback in Node.js, you may need additional packages like `speaker` or `node-speaker`.
|
|
381
|
+
|
|
382
|
+
### Filter not working
|
|
383
|
+
|
|
384
|
+
Some filters require AudioWorklet support in modern browsers. Check browser compatibility.
|
|
385
|
+
|
|
386
|
+
## Changelog
|
|
387
|
+
|
|
388
|
+
### v1.0.0
|
|
389
|
+
- Initial release
|
|
390
|
+
- Core audio engine
|
|
391
|
+
- Queue management
|
|
392
|
+
- Audio filters
|
|
393
|
+
- Plugin system
|
|
394
|
+
- Event system
|
|
395
|
+
- Provider abstractions
|
|
396
|
+
- Utility functions
|