openaudio-suite 2.5.5 → 2.6.1

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 CHANGED
@@ -2,16 +2,24 @@
2
2
 
3
3
  A family of **zero-dependency, browser-native audio utilities** for web projects. Choose the library that fits your use case.
4
4
 
5
- [![License: GPL-3.0](https://img.shields.io/badge/License-GPL_3.0-blue.svg)](./LICENSE)
6
- [![No Dependencies](https://img.shields.io/badge/Dependencies-None-brightgreen)]()
5
+ [![License: Apache-2.0](https://img.shields.io/badge/License-Apache_2.0-blue.svg)](https://github.com/Rexore/OpenAudio/blob/main/LICENSE)
6
+ [![No Dependencies](https://img.shields.io/badge/Dependencies-None-brightgreen)](https://github.com/Rexore/OpenAudio/blob/main)
7
+ [![npm](https://img.shields.io/npm/v/openaudio-suite)](https://www.npmjs.com/package/openaudio-suite)
8
+ [![npm downloads](https://img.shields.io/npm/dm/openaudio-suite)](https://www.npmjs.com/package/openaudio-suite)
7
9
 
8
- ### npm i openaudio-suite
10
+ ```
11
+ npm i openaudio-suite
12
+ ```
13
+
14
+ > ⚠️ **Alpha Software**
15
+ > The entire OpenAudio suite is currently in public alpha. APIs may change, bugs are expected, and production use is not recommended. `OpenAudio_r.js` is the most tested library; `OpenAudio_s.js` and `OpenAudio.js` have received limited testing. Use at your own risk and please report issues.
9
16
 
10
17
  ---
11
18
 
12
19
  ## Three Libraries in This Suite
13
20
 
14
21
  ### **OpenAudio_r.js** — Randomized Scheduler
22
+
15
23
  *For ambient, looped, or randomized audio playback*
16
24
 
17
25
  ```javascript
@@ -26,24 +34,26 @@ document.addEventListener('click', () => engine.start(), { once: true });
26
34
  ```
27
35
 
28
36
  **Key Features:**
29
- - 🎲 **Shuffle bag algorithm** — Each clip plays exactly once per cycle
30
- - 🔄 **Ambient scheduling** — Random inter-clip delays (customizable)
31
- - 📱 **Mobile-friendly** — Handles autoplay policies automatically
32
- - 🌙 **Background tab resilience** — Detects visibility changes, recalculates timing
33
- - 🎛️ **Lifecycle callbacks** — `onPlay`, `onEnd`, `onCycleReset`
34
37
 
35
- **Version:** 2.4.0 | **File:** `OpenAudio_r.js` (~9 KB, 3 KB gzipped)
38
+ * 🎲 **Shuffle bag algorithm** Each clip plays exactly once per cycle
39
+ * 🔄 **Ambient scheduling** — Random inter-clip delays (customizable)
40
+ * 📱 **Mobile-friendly** — Handles autoplay policies automatically
41
+ * 🌙 **Background tab resilience** — Detects visibility changes, recalculates timing
42
+ * 🎛️ **Lifecycle callbacks** — `onPlay`, `onEnd`, `onCycleReset`
43
+
44
+ **Version:** 2.6.0 | **File:** `OpenAudio_r.js` (~9 KB, 3 KB gzipped)
36
45
 
37
46
  ---
38
47
 
39
48
  ### **OpenAudio_s.js** — Sequential Playlist
49
+
40
50
  *For click-to-advance or auto-play sequential audio*
41
51
 
42
52
  ```javascript
43
53
  const player = new SequentialAudio([
44
- { src: 'intro.mp3', label: 'Introduction' },
45
- { src: 'chapter1.mp3', label: 'Chapter 1' },
46
- { src: 'chapter2.mp3', label: 'Chapter 2' }
54
+ { src: 'intro.mp3', label: 'Introduction' },
55
+ { src: 'chapter1.mp3', label: 'Chapter 1' },
56
+ { src: 'chapter2.mp3', label: 'Chapter 2' }
47
57
  ], {
48
58
  autoAdvance: false // Require click to advance
49
59
  });
@@ -53,57 +63,61 @@ document.getElementById('next-btn').addEventListener('click', () => player.next(
53
63
  ```
54
64
 
55
65
  **Key Features:**
56
- - ▶️ **Sequential playback** — Plays clips in fixed order
57
- - 🖱️ **Manual or auto-advance** — User controls pacing or auto-play
58
- - 🔀 **Jump & navigation** — Goto clip by index or label
59
- - ⏸️ **Play/pause/resume** — Full transport controls
60
- - 📊 **Progress tracking** — Know your current position in sequence
61
66
 
62
- **Version:** 1.0.0 | **File:** `OpenAudio_s.js` (~5 KB, 2 KB gzipped)
67
+ * ▶️ **Sequential playback** Plays clips in fixed order
68
+ * 🖱️ **Manual or auto-advance** — User controls pacing or auto-play
69
+ * 🔀 **Jump & navigation** — Goto clip by index or label
70
+ * ⏸️ **Play/pause/resume** — Full transport controls
71
+ * 📊 **Progress tracking** — Know your current position in sequence
72
+
73
+ **Version:** 1.3.0 | **File:** `OpenAudio_s.js` (~5 KB, 2 KB gzipped)
63
74
 
64
75
  ---
65
76
 
66
77
  ### **OpenAudio.js** — Simple Player
78
+
67
79
  *For single-clip, one-shot audio playback with background tab awareness*
68
80
 
69
81
  ```javascript
70
82
  const player = new OpenAudio('audio/chime.mp3', {
71
- volume: 0.8,
72
- pauseOnHidden: true, // Pause when tab loses focus
73
- onPlay: () => console.log('Playing'),
74
- onEnd: () => console.log('Done'),
75
- onHidden: () => console.log('Tab hidden'),
76
- onVisible: () => console.log('Tab visible')
83
+ volume: 0.8,
84
+ pauseOnHidden: true,
85
+ onPlay: () => console.log('Playing'),
86
+ onEnd: () => console.log('Done'),
87
+ onHidden: () => console.log('Tab hidden'),
88
+ onVisible: () => console.log('Tab visible')
77
89
  });
78
90
 
79
91
  document.getElementById('btn').addEventListener('click', () => player.play());
80
92
  ```
81
93
 
82
94
  **Key Features:**
83
- - ▶️ **One-shot playback** — Plays a single audio file once
84
- - 🔁 **Replayable** — Call `play()` again to replay from start
85
- - ⏹️ **Stop control** — Pause and rewind mid-playback
86
- - 🔍 **Background tab detection** — Detects when tab loses/regains focus
87
- - ⏸️ **Smart pause/resume** — Optional pause on background, resume on return
88
- - 📱 **Same autoplay unlock** — Silent MP3 unlock as others
89
95
 
90
- **Version:** 1.1.0 | **File:** `OpenAudio.js` (~5 KB, 2 KB gzipped)
96
+ * ▶️ **One-shot playback** Plays a single audio file once
97
+ * 🔁 **Replayable** — Call `play()` again to replay from start; preloaded data preserved on replay
98
+ * ⏹️ **Stop control** — Pause and rewind mid-playback
99
+ * 🔍 **Background tab detection** — Detects when tab loses/regains focus
100
+ * ⏸️ **Smart pause/resume** — Optional pause on background, resume on return
101
+ * 📱 **Same autoplay unlock** — Silent MP3 unlock, performed only once per instance
102
+
103
+ **Version:** 1.3.0 | **File:** `OpenAudio.js` (~5 KB, 2 KB gzipped)
91
104
 
92
105
  ---
93
106
 
94
107
  ## Quick Comparison
95
108
 
96
109
  | Feature | OpenAudio_r.js | OpenAudio_s.js | OpenAudio.js |
97
- |---------|---|---|---|
110
+ | --- | --- | --- | --- |
98
111
  | **Clips** | Multiple | Multiple | Single |
99
112
  | **Order** | Random | Sequential | N/A |
100
113
  | **Scheduling** | Delays between clips | Manual or auto-advance | On-demand |
101
114
  | **Shuffle Bag** | ✅ Yes | ❌ No | ❌ N/A |
102
115
  | **Navigation** | ❌ No | ✅ Goto/label jump | ❌ N/A |
103
- | **Volume Control** | ✅ Runtime | Constructor | ✅ Constructor |
116
+ | **Volume Control** | ✅ Runtime | Constructor | ✅ Constructor |
104
117
  | **Callbacks** | onPlay, onEnd, onCycleReset | onPlay, onEnd, onComplete | onPlay, onEnd, onHidden, onVisible |
105
118
  | **Pause/Resume** | ❌ No | ✅ Yes | ✅ Yes (pauseOnHidden) |
106
119
  | **Background Tab Detection** | ✅ Yes | ❌ No | ✅ Yes |
120
+ | **isPlaying / isStarted** | ✅ Read-only | ✅ Read-only | ✅ Read-only |
107
121
  | **File Size** | ~9 KB | ~5 KB | ~5 KB |
108
122
  | **Use Case** | Ambient, randomized | Guided tours, tutorials, stories | UI sounds, notifications, game audio |
109
123
 
@@ -138,6 +152,7 @@ Q4: Do you need frame-perfect scheduling or effects?
138
152
  ## Installation
139
153
 
140
154
  ### Option 1: Direct Script Tags
155
+
141
156
  ```html
142
157
  <!-- Use whichever you need -->
143
158
  <script src="OpenAudio_r.js"></script> <!-- Randomized scheduler -->
@@ -150,19 +165,21 @@ Q4: Do you need frame-perfect scheduling or effects?
150
165
  ```
151
166
 
152
167
  ### Option 2: ES6 Modules
168
+
153
169
  ```javascript
154
- import { AudioEngine } from './OpenAudio_r.js';
170
+ import { AudioEngine } from './OpenAudio_r.js';
155
171
  import { SequentialAudio } from './OpenAudio_s.js';
156
- import { SingleAudio } from './OpenAudio.js';
172
+ import { OpenAudio } from './OpenAudio.js';
157
173
  ```
158
174
 
159
- ### Option 3: npm (when published)
160
- ```bash
161
- npm install openaudio-suite
175
+ ### Option 3: npm
176
+
177
+ ```
178
+ npm i openaudio-suite
162
179
  ```
163
180
 
164
181
  ```javascript
165
- import { AudioEngine, SequentialAudio, SingleAudio } from 'openaudio-suite';
182
+ import { AudioEngine, SequentialAudio, OpenAudio } from 'openaudio-suite';
166
183
  ```
167
184
 
168
185
  ---
@@ -175,11 +192,11 @@ import { AudioEngine, SequentialAudio, SingleAudio } from 'openaudio-suite';
175
192
  // Ambient soundscape
176
193
  const ambience = new AudioEngine([
177
194
  { src: 'forest.mp3' },
178
- { src: 'rain.mp3' }
195
+ { src: 'rain.mp3' }
179
196
  ], { lowTime: 5, maxTime: 15, volume: 0.6 });
180
197
 
181
198
  // UI sounds
182
- const clickSound = new SingleAudio('ui/click.mp3', { volume: 0.8 });
199
+ const clickSound = new OpenAudio('ui/click.mp3', { volume: 0.8 });
183
200
 
184
201
  // Start
185
202
  document.addEventListener('click', () => ambience.start(), { once: true });
@@ -188,8 +205,6 @@ document.querySelectorAll('button').forEach(btn => {
188
205
  });
189
206
  ```
190
207
 
191
- ---
192
-
193
208
  ### Scenario 2: Narrated Story with Pause/Resume
194
209
 
195
210
  ```javascript
@@ -198,46 +213,40 @@ const story = new SequentialAudio([
198
213
  { src: 'chapter2.mp3', label: 'Chapter 2' },
199
214
  { src: 'chapter3.mp3', label: 'Chapter 3' }
200
215
  ], {
201
- autoAdvance: false, // User controls pacing
202
- onPlay: (clip) => updateUI(`Reading: ${clip.label}`),
203
- onComplete: () => showTheEnd()
216
+ autoAdvance: false,
217
+ onPlay: (clip) => updateUI(`Reading: ${clip.label}`),
218
+ onComplete: () => showTheEnd()
204
219
  });
205
220
 
206
221
  document.addEventListener('click', () => story.play(), { once: true });
207
- document.getElementById('next-btn').addEventListener('click', () => story.next());
208
- document.getElementById('pause-btn').addEventListener('click', () => story.pause());
222
+ document.getElementById('next-btn').addEventListener('click', () => story.next());
223
+ document.getElementById('pause-btn').addEventListener('click', () => story.pause());
209
224
  document.getElementById('resume-btn').addEventListener('click', () => story.resume());
210
225
  ```
211
226
 
212
- ---
213
-
214
227
  ### Scenario 3: Tutorial with Auto-Advance
215
228
 
216
229
  ```javascript
217
230
  const tutorial = new SequentialAudio([
218
- { src: 'intro.mp3', label: 'Intro' },
231
+ { src: 'intro.mp3', label: 'Intro' },
219
232
  { src: 'step1.mp3', label: 'Step 1' },
220
233
  { src: 'step2.mp3', label: 'Step 2' }
221
234
  ], {
222
- autoAdvance: true, // Auto-play next step
223
- onPlay: (clip) => highlightStep(clip.label),
224
- onComplete: () => showCertificate()
235
+ autoAdvance: true,
236
+ onPlay: (clip) => highlightStep(clip.label),
237
+ onComplete: () => showCertificate()
225
238
  });
226
239
 
227
- document.getElementById('start-tutorial').addEventListener('click', () => {
228
- tutorial.play();
229
- });
240
+ document.getElementById('start-tutorial').addEventListener('click', () => tutorial.play());
230
241
  ```
231
242
 
232
- ---
233
-
234
243
  ### Scenario 4: Notification System
235
244
 
236
245
  ```javascript
237
246
  const sounds = {
238
- email: new SingleAudio('email.mp3'),
239
- message: new SingleAudio('message.mp3'),
240
- alert: new SingleAudio('alert.mp3')
247
+ email: new OpenAudio('email.mp3'),
248
+ message: new OpenAudio('message.mp3'),
249
+ alert: new OpenAudio('alert.mp3')
241
250
  };
242
251
 
243
252
  function notify(type, message) {
@@ -251,11 +260,12 @@ function notify(type, message) {
251
260
  ## Browser Compatibility
252
261
 
253
262
  All three libraries require:
254
- - **HTML5 Audio element support** (universal)
255
- - **User gesture** for first audio playback (autoplay policy)
263
+
264
+ * **HTML5 Audio element support** (universal)
265
+ * **User gesture** for first audio playback (autoplay policy)
256
266
 
257
267
  | Browser | Version | Status |
258
- |---------|---------|--------|
268
+ | --- | --- | --- |
259
269
  | Chrome | 70+ | ✅ Full support |
260
270
  | Firefox | 65+ | ✅ Full support |
261
271
  | Safari | 12+ | ✅ Full support |
@@ -268,20 +278,25 @@ All three libraries require:
268
278
  ## API Quick Reference
269
279
 
270
280
  ### OpenAudio_r.js (AudioEngine)
281
+
271
282
  ```javascript
272
- engine.start() // Begin playback
273
- engine.stop() // Pause
274
- engine.reset() // Stop & reset cycle
275
- engine.setVolume(0.5) // Set volume
276
- engine.addClip(clip) // Add clip at runtime
277
- engine.destroy() // Cleanup
283
+ engine.start() // Begin playback (no-op after destroy)
284
+ engine.stop() // Pause (no-op after destroy)
285
+ engine.reset() // Stop & reset cycle (no-op after destroy)
286
+ engine.setVolume(0.5) // Set volume (no-op after destroy)
287
+ engine.addClip(clip) // Add clip at runtime (no-op after destroy)
288
+ engine.destroy() // Cleanup — all subsequent calls are safe no-ops
289
+
290
+ engine.isStarted // boolean, read-only
291
+ engine.isPlaying // boolean, read-only
278
292
  ```
279
293
 
280
- See [OPENAUDIO_R.md](./docs/OPENAUDIO_R.md) for full API.
294
+ See [OPENAUDIO_R.md](https://github.com/Rexore/OpenAudio/blob/main/docs/OPENAUDIO_R.md) for full API.
281
295
 
282
296
  ---
283
297
 
284
298
  ### OpenAudio_s.js (SequentialAudio)
299
+
285
300
  ```javascript
286
301
  player.play() // Start playback
287
302
  player.next() // Advance to next clip
@@ -289,29 +304,36 @@ player.goto(index) // Jump to clip by index
289
304
  player.gotoLabel(label) // Jump to clip by label
290
305
  player.pause() // Pause
291
306
  player.resume() // Resume from pause
292
- player.stop() // Stop & rewind
307
+ player.stop() // Stop, rewind, cancel pending auto-advance
293
308
  player.reset() // Reset to start
294
- player.destroy() // Cleanup
309
+ player.destroy() // Cleanup — all subsequent calls are safe no-ops
310
+
311
+ player.isPlaying // boolean, read-only
312
+ player.isStarted // boolean, read-only
295
313
  ```
296
314
 
297
- See [OPENAUDIO_S.md](./docs/OPENAUDIO_S.md) for full API.
315
+ See [OPENAUDIO_S.md](https://github.com/Rexore/OpenAudio/blob/main/docs/OPENAUDIO_S.md) for full API.
298
316
 
299
317
  ---
300
318
 
301
- ### OpenAudio.js (SingleAudio)
319
+ ### OpenAudio.js (OpenAudio)
320
+
302
321
  ```javascript
303
- player.play() // Play the clip
304
- player.stop() // Stop & rewind
305
- player.destroy() // Cleanup
322
+ player.play() // Play the clip (unlock once, direct play on replay)
323
+ player.stop() // Stop, rewind, cancel in-flight unlock
324
+ player.destroy() // Cleanup — all subsequent calls are safe no-ops
325
+
326
+ player.isPlaying // boolean, read-only
306
327
  ```
307
328
 
308
- See [OPENAUDIO.md](./docs/OPENAUDIO.md) for full API.
329
+ See [OPENAUDIO.md](https://github.com/Rexore/OpenAudio/blob/main/docs/OPENAUDIO.md) for full API.
309
330
 
310
331
  ---
311
332
 
312
333
  ## Troubleshooting
313
334
 
314
335
  ### Audio Won't Play
336
+
315
337
  **Cause:** Not called inside a user gesture.
316
338
  **Fix:** Call `play()` or `start()` inside a click, keydown, or touchstart handler.
317
339
 
@@ -323,21 +345,19 @@ document.addEventListener('click', () => player.play());
323
345
  setTimeout(() => player.play(), 1000);
324
346
  ```
325
347
 
326
- ---
327
-
328
348
  ### "NotAllowedError" in Console
349
+
329
350
  **Cause:** Autoplay policy blocked playback.
330
351
  **Fix:** Same as above — use a user gesture.
331
352
 
332
- ---
333
-
334
353
  ### Multiple Libraries in Same Project
335
- **No problem!** They don't conflict.
354
+
355
+ No problem! They don't conflict.
336
356
 
337
357
  ```javascript
338
- const ambience = new AudioEngine([...]); // OpenAudio_r.js
339
- const story = new SequentialAudio([...]); // OpenAudio_s.js
340
- const click = new SingleAudio('sound.mp3'); // OpenAudio.js
358
+ const ambience = new AudioEngine([...]); // OpenAudio_r.js
359
+ const story = new SequentialAudio([...]); // OpenAudio_s.js
360
+ const click = new OpenAudio('sound.mp3'); // OpenAudio.js
341
361
 
342
362
  // All three can run simultaneously
343
363
  ```
@@ -347,7 +367,7 @@ const click = new SingleAudio('sound.mp3'); // OpenAudio.js
347
367
  ## Performance & Sizing
348
368
 
349
369
  | Scenario | Size | Memory |
350
- |----------|------|--------|
370
+ | --- | --- | --- |
351
371
  | OpenAudio_r.js only | 9 KB | < 1 MB |
352
372
  | OpenAudio_s.js only | 5 KB | < 150 KB |
353
373
  | OpenAudio.js only | 4 KB | < 100 KB |
@@ -360,45 +380,45 @@ No external dependencies. Pure HTML5 Audio API.
360
380
 
361
381
  ## Contributing
362
382
 
363
- See [CONTRIBUTING.md](./CONTRIBUTING.md) for:
364
- - Bug reports
365
- - Feature requests
366
- - Code style
367
- - Testing checklist
368
- - PR guidelines
383
+ See [CONTRIBUTING.md](https://github.com/Rexore/OpenAudio/blob/main/CONTRIBUTING.md) for:
384
+
385
+ * Bug reports
386
+ * Feature requests
387
+ * Code style
388
+ * Testing checklist
389
+ * PR guidelines
369
390
 
370
391
  ---
371
392
 
372
393
  ## License
373
394
 
374
- All libraries are licensed under **GNU General Public License v3.0 or later**.
395
+ All libraries are licensed under **Apache-2.0**.
375
396
 
376
- See [LICENSE](./LICENSE) for the full text.
397
+ See [LICENSE](https://github.com/Rexore/OpenAudio/blob/main/LICENSE) for the full text.
377
398
 
378
- **Commercial use permitted** — Include license and copyright notice. Derivative works must also be GPL-3.0-or-later.
399
+ **Commercial use permitted** — Include the licence and copyright notice. Note any changes made to the original.
379
400
 
380
401
  ---
381
402
 
382
403
  ## Changelog
383
404
 
384
- See [CHANGELOG.md](./CHANGELOG.md) for version history.
405
+ See [CHANGELOG.md](https://github.com/Rexore/OpenAudio/blob/main/CHANGELOG.md) for version history.
385
406
 
386
407
  **Current Versions:**
387
- - OpenAudio_r.js: **2.4.0** (March 2025)
388
- - OpenAudio_s.js: **1.0.0** (March 2025)
389
- - OpenAudio.js: **1.0.0** (March 2025)
408
+
409
+ * OpenAudio_r.js: **2.6.0** (March 2026)
410
+ * OpenAudio_s.js: **1.3.0** (March 2026)
411
+ * OpenAudio.js: **1.3.0** (March 2026)
390
412
 
391
413
  ---
392
414
 
393
415
  ## Documentation
394
416
 
395
- - 📖 [OpenAudio_r.js API](./docs/OPENAUDIO_R.md) — Randomized scheduler
396
- - 📖 [OpenAudio_s.js API](./docs/OPENAUDIO_S.md) — Sequential player
397
- - 📖 [OpenAudio.js API](./docs/OPENAUDIO.md) — Single-clip player
398
- - 📊 [Feature Comparison](./docs/COMPARISON.md) — Detailed comparison
399
- - 💻 [Examples](./examples/) — Working demos
400
-
401
- ---
417
+ * 📖 [OpenAudio_r.js API](https://github.com/Rexore/OpenAudio/blob/main/docs/OPENAUDIO_R.md) — Randomized scheduler
418
+ * 📖 [OpenAudio_s.js API](https://github.com/Rexore/OpenAudio/blob/main/docs/OPENAUDIO_S.md) — Sequential player
419
+ * 📖 [OpenAudio.js API](https://github.com/Rexore/OpenAudio/blob/main/docs/OPENAUDIO.md) — Single-clip player
420
+ * 📊 [Feature Comparison](https://github.com/Rexore/OpenAudio/blob/main/docs/COMPARISON.md) — Detailed comparison
421
+ * 💻 [Examples](https://github.com/Rexore/OpenAudio/blob/main/examples) — Working demos
402
422
 
403
423
  Have questions? Open a GitHub Issue or Discussion.
404
424
 
@@ -406,30 +426,30 @@ Have questions? Open a GitHub Issue or Discussion.
406
426
 
407
427
  ## FAQ
408
428
 
409
- **Q: Can I use all three in the same project?**
429
+ **Q: Can I use all three in the same project?**
410
430
  A: Yes! They complement each other and don't conflict.
411
431
 
412
- **Q: Do I need a build system?**
432
+ **Q: Do I need a build system?**
413
433
  A: No. All work as plain `<script>` tags. No bundler needed.
414
434
 
415
- **Q: Can I modify these?**
416
- A: Yes, under GPL-3.0. Include the license and note your changes.
435
+ **Q: Can I modify these?**
436
+ A: Yes, under Apache 2.0. Include the licence and note your changes.
417
437
 
418
- **Q: Commercial use?**
419
- A: Yes. GPL-3.0 allows commercial use. You must provide source code and include the license.
438
+ **Q: Commercial use?**
439
+ A: Yes. Apache 2.0 allows commercial use. You must include the licence and notice of changes.
420
440
 
421
- **Q: What about Web Audio API?**
422
- A: These libraries use HTML5 Audio. Web Audio API is for advanced features (effects, visualization, frame-perfect timing). See [COMPARISON.md](./docs/COMPARISON.md).
441
+ **Q: What about Web Audio API?**
442
+ A: These libraries use HTML5 Audio. Web Audio API is for advanced features (effects, visualisation, frame-perfect timing). See [COMPARISON.md](https://github.com/Rexore/OpenAudio/blob/main/docs/COMPARISON.md).
423
443
 
424
444
  ---
425
445
 
426
446
  ## Resources
427
447
 
428
- - 📖 [HTML5 Audio — MDN](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/audio)
429
- - 🎛️ [Web Audio API — MDN](https://developer.mozilla.org/en-US/docs/Web/API/Web_Audio_API)
430
- - 🎮 [Browser Autoplay Policy — Chrome Blog](https://developer.chrome.com/blog/autoplay/)
431
- - 📱 [Page Visibility API — MDN](https://developer.mozilla.org/en-US/docs/Web/API/Page_Visibility_API)
448
+ * 📖 [HTML5 Audio — MDN](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/audio)
449
+ * 🎛️ [Web Audio API — MDN](https://developer.mozilla.org/en-US/docs/Web/API/Web_Audio_API)
450
+ * 🎮 [Browser Autoplay Policy — Chrome Blog](https://developer.chrome.com/blog/autoplay/)
451
+ * 📱 [Page Visibility API — MDN](https://developer.mozilla.org/en-US/docs/Web/API/Page_Visibility_API)
432
452
 
433
453
  ---
434
454
 
435
- *Last updated: March 2025*
455
+ *Last updated: March 2026*