@audio/decode 3.11.3 → 3.13.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/audio-decode.js CHANGED
@@ -124,14 +124,17 @@ function fmt(name, init) {
124
124
 
125
125
  // --- codecs ---
126
126
  // dedupe (3rd arg): decoder upmixes mono sources to duplicate stereo (verified for mp3;
127
- // aac/wma flagged conservatively — same lossy-wasm family). Exact containers never dedupe.
127
+ // aac/wma flagged conservatively — same lossy-wasm family). Exact containers never dedupe;
128
+ // video containers that may carry AAC or MP3 (mp4/mov, mkv, avi) do.
128
129
 
129
130
  reg('mp3', () => import('@audio/decode-mp3'), true)
130
131
  reg('flac', () => import('@audio/decode-flac'))
131
132
  reg('opus', () => import('@audio/decode-opus'))
132
133
  reg('oga', () => import('@audio/decode-vorbis'))
133
134
 
134
- reg('m4a', () => import('@audio/decode-aac'), true)
135
+ reg('m4a', () => import('@audio/decode-mp4'), true)
136
+ reg('mp4', () => import('@audio/decode-mp4'), true)
137
+ reg('mov', () => import('@audio/decode-mp4'), true)
135
138
 
136
139
  reg('wav', () => import('@audio/decode-wav'))
137
140
  reg('qoa', () => import('@audio/decode-qoa'))
@@ -140,6 +143,8 @@ reg('aac', () => import('@audio/decode-aac'), true)
140
143
  reg('aiff', () => import('@audio/decode-aiff'))
141
144
  reg('caf', () => import('@audio/decode-caf'))
142
145
  reg('webm', () => import('@audio/decode-webm'))
146
+ reg('mkv', () => import('@audio/decode-webm'), true)
147
+ reg('avi', () => import('@audio/decode-avi'), true)
143
148
  reg('amr', () => import('@audio/decode-amr'))
144
149
  reg('wma', () => import('@audio/decode-wma'), true)
145
150
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@audio/decode",
3
- "version": "3.11.3",
3
+ "version": "3.13.0",
4
4
  "description": "Decode audio data in node or browser",
5
5
  "type": "module",
6
6
  "sideEffects": false,
@@ -28,19 +28,21 @@
28
28
  "packages/*"
29
29
  ],
30
30
  "dependencies": {
31
- "@audio/decode-aac": "^1.2.0",
32
- "@audio/decode-aiff": "^1.1.3",
33
- "@audio/decode-amr": "^1.0.0",
34
- "@audio/decode-caf": "^1.2.0",
35
- "@audio/decode-flac": "^1.1.0",
36
- "@audio/decode-mp3": "^1.1.0",
37
- "@audio/decode-opus": "^1.1.0",
38
- "@audio/decode-qoa": "^1.0.0",
39
- "@audio/decode-vorbis": "^1.1.0",
40
- "@audio/decode-wav": "^1.3.0",
41
- "@audio/decode-webm": "^1.0.0",
42
- "@audio/decode-wma": "^1.0.0",
43
- "audio-type": "^2.4.0"
31
+ "@audio/decode-aac": "^1.5.0",
32
+ "@audio/decode-aiff": "^1.3.0",
33
+ "@audio/decode-amr": "^1.3.0",
34
+ "@audio/decode-avi": "^1.0.0",
35
+ "@audio/decode-caf": "^1.4.0",
36
+ "@audio/decode-flac": "^1.3.0",
37
+ "@audio/decode-mp3": "^1.3.0",
38
+ "@audio/decode-mp4": "^1.0.0",
39
+ "@audio/decode-opus": "^1.3.0",
40
+ "@audio/decode-qoa": "^1.2.0",
41
+ "@audio/decode-vorbis": "^1.3.0",
42
+ "@audio/decode-wav": "^1.5.0",
43
+ "@audio/decode-webm": "^1.5.0",
44
+ "@audio/decode-wma": "^1.3.0",
45
+ "audio-type": "^2.5.0"
44
46
  },
45
47
  "devDependencies": {
46
48
  "audio-lena": "^3.0.0",
@@ -79,7 +81,13 @@
79
81
  "amr",
80
82
  "wma",
81
83
  "pcm",
82
- "streaming"
84
+ "streaming",
85
+ "mp4",
86
+ "mov",
87
+ "mkv",
88
+ "avi",
89
+ "video",
90
+ "extract"
83
91
  ],
84
92
  "author": "Dmitry Iv. <dfcreative@gmail.com>",
85
93
  "license": "MIT",
package/readme.md CHANGED
@@ -1,10 +1,10 @@
1
1
  # @audio/decode [![test](https://github.com/audiojs/decode/actions/workflows/test.js.yml/badge.svg)](https://github.com/audiojs/decode/actions/workflows/test.js.yml)
2
2
 
3
3
  Decode any audio format to raw samples.<br>
4
- JS / WASM – no ffmpeg, no native bindings, works in both node and browser.<br>
4
+ JS / WASM with no ffmpeg or native bindings; works in Node.js and browsers.<br>
5
5
  Small API, minimal size, near-native performance, lazy-loading, chunked decoding.
6
6
 
7
- [![npm install @audio/decode](https://nodei.co/npm/audio-decode.png?mini=true)](https://npmjs.org/package/@audio/decode/)
7
+ [![npm install @audio/decode](https://nodei.co/npm/@audio/decode.png?mini=true)](https://npmjs.org/package/@audio/decode/)
8
8
 
9
9
  ```js
10
10
  import decode from '@audio/decode';
@@ -17,22 +17,24 @@ const { channelData, sampleRate } = await decode(anyAudioBuffer);
17
17
  | Format | Package | Size | Engine |
18
18
  |--------|---------|------|--------|
19
19
  | MP3 | [@audio/decode-mp3](./packages/decode-mp3) | 92 KB | WASM |
20
- | WAV | [@audio/decode-wav](./packages/decode-wav) | 4 KB | JS |
21
- | OGG Vorbis | [@audio/decode-vorbis](./packages/decode-vorbis) | 164 KB | WASM |
22
- | FLAC | [@audio/decode-flac](./packages/decode-flac) | 133 KB | WASM |
23
- | Opus | [@audio/decode-opus](./packages/decode-opus) | 178 KB | WASM |
20
+ | WAV | [@audio/decode-wav](./packages/decode-wav) | 11 KB | JS |
21
+ | OGG Vorbis | [@audio/decode-vorbis](./packages/decode-vorbis) | 166 KB | WASM |
22
+ | FLAC | [@audio/decode-flac](./packages/decode-flac) | 135 KB | WASM |
23
+ | Opus | [@audio/decode-opus](./packages/decode-opus) | 166 KB | WASM |
24
24
  | M4A / AAC / ALAC | [@audio/decode-aac](./packages/decode-aac) | 368 KB | WASM + JS |
25
+ | MP4 / MOV / M4V / 3GP video | [@audio/decode-mp4](./packages/decode-mp4) | 12 KB + codec | JS demux |
25
26
  | QOA | [@audio/decode-qoa](./packages/decode-qoa) | 8 KB | JS |
26
27
  | AIFF | [@audio/decode-aiff](./packages/decode-aiff) | 20 KB | JS |
27
- | CAF | [@audio/decode-caf](./packages/decode-caf) | 7 KB | JS |
28
- | WebM | [@audio/decode-webm](./packages/decode-webm) | 263 KB | WASM |
28
+ | CAF | [@audio/decode-caf](./packages/decode-caf) | 9 KB | JS |
29
+ | WebM / MKV video | [@audio/decode-webm](./packages/decode-webm) | 250 KB | WASM |
30
+ | AVI video | [@audio/decode-avi](./packages/decode-avi) | 8 KB + codec | JS demux |
29
31
  | AMR | [@audio/decode-amr](./packages/decode-amr) | 241 KB | WASM |
30
32
  | WMA | [@audio/decode-wma](./packages/decode-wma) | 91 KB | WASM |
31
33
 
32
34
  ### Whole-file
33
35
 
34
36
  Auto-detects format. Input can be _ArrayBuffer_, _Uint8Array_, _Buffer_, or anything
35
- that materializes to bytes — a _Blob_/_File_ (browser file input, drag-drop) or a fetch _Response_.
37
+ that materializes to bytes, including a _Blob_/_File_ or fetch _Response_.
36
38
 
37
39
  ```js
38
40
  import decode from '@audio/decode'
@@ -42,7 +44,6 @@ let fromFile = await decode(fileInput.files[0]) // File
42
44
  let fromUrl = await decode(await fetch(url)) // Response
43
45
  ```
44
46
 
45
-
46
47
  ### Chunked
47
48
 
48
49
  ```js
@@ -64,41 +65,62 @@ for await (let { channelData, sampleRate } of decode.mp3(response.body)) {
64
65
 
65
66
  Works with `ReadableStream`, `fetch` body, Node stream, or any async iterable.
66
67
 
67
- Formats: `mp3`, `flac`, `opus`, `oga`, `m4a`, `wav`, `qoa`, `aac`, `aiff`, `caf`, `webm`, `amr`, `wma`.
68
+ Formats: `mp3`, `flac`, `opus`, `oga`, `m4a`, `mp4`, `mov`, `wav`, `qoa`, `aac`, `aiff`, `caf`, `webm`, `mkv`, `avi`, `amr`, `wma`.
69
+
70
+ ### Video files
71
+
72
+ Video containers decode straight to their audio track — the video stream is skipped, no ffmpeg involved:
73
+
74
+ ```js
75
+ let { channelData, sampleRate } = await decode(await fetch('trailer.mp4'))
76
+ ```
77
+
78
+ | Container | Package | Audio codecs |
79
+ |---|---|---|
80
+ | MP4, MOV, M4V, 3GP | [@audio/decode-mp4](./packages/decode-mp4) | AAC, ALAC, MP3, FLAC, Opus, AMR, PCM, G.711 |
81
+ | WebM, MKV | [@audio/decode-webm](./packages/decode-webm) | Opus, Vorbis, AAC, ALAC, MP3, FLAC, PCM |
82
+ | AVI | [@audio/decode-avi](./packages/decode-avi) | PCM, MP3, AAC, G.711 |
83
+
84
+ AC-3, E-AC-3 and DTS tracks throw an error naming the codec.
68
85
 
69
86
  ### Browser
70
87
 
71
- Each codec is a self-contained bundle under `@audio/*` — no transitive deps, no import map bloat.
72
- For selective loading in the browser (avoids bundling all codecs):
88
+ Works from a CDN without a bundler. Codecs load on demand via dynamic import, only for formats you decode:
73
89
 
74
90
  ```html
75
- <script type="importmap">
76
- {
77
- "imports": {
78
- "@audio/decode": "https://esm.sh/audio-decode",
79
- "audio-type": "https://esm.sh/audio-type",
80
- "@audio/decode-mp3": "https://esm.sh/@audio/decode-mp3",
81
- "@audio/decode-wav": "https://esm.sh/@audio/decode-wav",
82
- "@audio/decode-flac": "https://esm.sh/@audio/decode-flac",
83
- "@audio/decode-opus": "https://esm.sh/@audio/decode-opus",
84
- "@audio/decode-vorbis": "https://esm.sh/@audio/decode-vorbis",
85
- "@audio/decode-aac": "https://esm.sh/@audio/decode-aac",
86
- "@audio/decode-qoa": "https://esm.sh/@audio/decode-qoa",
87
- "@audio/decode-aiff": "https://esm.sh/@audio/decode-aiff",
88
- "@audio/decode-caf": "https://esm.sh/@audio/decode-caf",
89
- "@audio/decode-webm": "https://esm.sh/@audio/decode-webm",
90
- "@audio/decode-amr": "https://esm.sh/@audio/decode-amr",
91
- "@audio/decode-wma": "https://esm.sh/@audio/decode-wma"
92
- }
93
- }
94
- </script>
95
91
  <script type="module">
96
- import decode from '@audio/decode'
92
+ import decode from 'https://esm.sh/@audio/decode'
97
93
  let { channelData, sampleRate } = await decode(buf)
98
94
  </script>
99
95
  ```
100
96
 
101
- Only list the codecs you need — each `@audio/decode-*` package bundles all its WASM/JS deps internally.
97
+ For self-hosting, use an import map to point `@audio/decode` and each needed `@audio/decode-*` package to local files. Codec-internal files load by relative path.
98
+
99
+ Each codec package's main export works in an `AudioWorklet` without `Blob`, `TextDecoder`, `Worker`, or `fetch`. Import codec packages directly because `@audio/decode` uses dynamic imports.
100
+
101
+ Initialize WASM before rendering. Decoding runs on the worklet thread and can interrupt audio output.
102
+
103
+ ### Synchronous codecs
104
+
105
+ The umbrella remains async for detection, lazy imports, and `Blob`/`Response` inputs.
106
+ Import a codec package directly for synchronous calls.
107
+
108
+ `wav`, `qoa`, `aiff`, and `caf` are synchronous:
109
+
110
+ ```js
111
+ import decode from '@audio/decode-wav'
112
+ let pcm = decode(wavBytes)
113
+ ```
114
+
115
+ WASM codecs initialize asynchronously, then decode synchronously:
116
+
117
+ ```js
118
+ import { decoder } from '@audio/decode-flac'
119
+ let dec = await decoder()
120
+ let pcm = dec.decode(bytes)
121
+ let tail = dec.flush()
122
+ dec.free()
123
+ ```
102
124
 
103
125
  ### Metadata
104
126
 
@@ -123,7 +145,7 @@ let info = parseMeta(wavBytes)
123
145
 
124
146
  ### WebWorker
125
147
 
126
- Each `@audio/decode-*` package is a self-contained ESM module — import directly in a worker:
148
+ Each `@audio/decode-*` package is a self-contained ESM module that can run in a worker:
127
149
 
128
150
  ```js
129
151
  // decode-worker.js
@@ -151,6 +173,8 @@ worker.onmessage = ({ data }) => { /* { channelData, sampleRate } */ }
151
173
  * [ffmpeg.wasm](https://github.com/ffmpegwasm/ffmpeg.wasm) – full encoding/decoding library.
152
174
  -->
153
175
 
154
- <p align="center">Licensing: the umbrella and most codec atoms are MIT; three atoms inherit their upstream codec implementation's license — <a href="./packages/decode-aac">@audio/decode-aac</a> GPL-2.0, <a href="./packages/decode-wma">@audio/decode-wma</a> GPL-2.0-or-later, <a href="./packages/decode-amr">@audio/decode-amr</a> Apache-2.0. Install only the codecs whose licenses fit your project — the umbrella loads them on demand.</p>
176
+ ## Licensing
177
+
178
+ The umbrella and most codec packages are MIT. Three codecs use another license: <a href="./packages/decode-aac">@audio/decode-aac</a> GPL-2.0, <a href="./packages/decode-wma">@audio/decode-wma</a> GPL-2.0-or-later, and <a href="./packages/decode-amr">@audio/decode-amr</a> Apache-2.0. Install only the codecs whose licenses fit your project. The umbrella loads them on demand.
155
179
 
156
- <p align="center"><a href="./LICENSE">MIT</a> • <a href="https://github.com/krishnized/license/">ॐ</a>
180
+ <p align="center"><a href="https://github.com/krishnized/license/">ॐ</a> · <a href="./LICENSE">MIT</a>
package/test.html CHANGED
@@ -17,15 +17,24 @@
17
17
  "audio-type": "./node_modules/audio-type/audio-type.js",
18
18
  "tst": "./node_modules/tst/tst.js",
19
19
  "@audio/decode-mp3": "./packages/decode-mp3/decode-mp3.js",
20
+ "@audio/decode-mp3/meta": "./packages/decode-mp3/meta.js",
20
21
  "@audio/decode-wav": "./packages/decode-wav/decode-wav.js",
22
+ "@audio/decode-wav/meta": "./packages/decode-wav/meta.js",
21
23
  "@audio/decode-flac": "./packages/decode-flac/decode-flac.js",
24
+ "@audio/decode-flac/meta": "./packages/decode-flac/meta.js",
22
25
  "@audio/decode-opus": "./packages/decode-opus/decode-opus.js",
26
+ "@audio/decode-opus/meta": "./packages/decode-opus/meta.js",
23
27
  "@audio/decode-vorbis": "./packages/decode-vorbis/decode-vorbis.js",
28
+ "@audio/decode-vorbis/meta": "./packages/decode-vorbis/meta.js",
24
29
  "@audio/decode-aac": "./packages/decode-aac/decode-aac.js",
30
+ "@audio/decode-aac/meta": "./packages/decode-aac/meta.js",
25
31
  "@audio/decode-qoa": "./packages/decode-qoa/decode-qoa.js",
26
32
  "@audio/decode-aiff": "./packages/decode-aiff/decode-aiff.js",
27
33
  "@audio/decode-caf": "./packages/decode-caf/decode-caf.js",
28
34
  "@audio/decode-webm": "./packages/decode-webm/decode-webm.js",
35
+ "@audio/decode-mp4": "./packages/decode-mp4/decode-mp4.js",
36
+ "@audio/decode-avi": "./packages/decode-avi/decode-avi.js",
37
+ "@audio/decode-opus/core": "./packages/decode-opus/core.js",
29
38
  "@audio/decode-amr": "./packages/decode-amr/decode-amr.js",
30
39
  "@audio/decode-wma": "./packages/decode-wma/decode-wma.js"
31
40
  }