@openclaw/whatsapp 2026.5.31-beta.2 → 2026.5.31-beta.3
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/api.js +7 -7
- package/dist/{channel-DA2BAIo5.js → channel-DigzkmDO.js} +1 -1
- package/dist/channel-plugin-api.js +1 -1
- package/dist/{channel.runtime-Q1LZDB5s.js → channel.runtime-BzDa8nVv.js} +2 -2
- package/dist/{channel.setup-DHXOo4h5.js → channel.setup-BRev7Qpj.js} +1 -1
- package/dist/login-qr-runtime.js +4 -4
- package/dist/{monitor-BVRq04Dt.js → monitor-D-vg4gJF.js} +9 -9
- package/dist/runtime-api.js +1 -1
- package/dist/{setup-core-OvPMaAsx.js → setup-core-D0ncRoh8.js} +5 -5
- package/dist/{setup-finalize-Dk23pfKc.js → setup-finalize-BdztDwTy.js} +1 -1
- package/dist/setup-plugin-api.js +1 -1
- package/dist/{setup-surface-F-jVrH8u.js → setup-surface-DLueEnfx.js} +1 -1
- package/node_modules/audio-buffer/.eslintrc.json +44 -0
- package/node_modules/audio-buffer/.github/workflows/node.js.yml +31 -0
- package/node_modules/audio-buffer/.travis.yml +7 -0
- package/node_modules/{@audio/decode-opus → audio-buffer}/LICENSE +2 -5
- package/node_modules/audio-buffer/index.js +76 -0
- package/node_modules/audio-buffer/package.json +37 -0
- package/node_modules/audio-buffer/readme.md +56 -0
- package/node_modules/audio-decode/.eslintrc.json +43 -0
- package/node_modules/audio-decode/.github/workflows/test.js.yml +20 -11
- package/node_modules/audio-decode/.travis.yml +13 -0
- package/node_modules/audio-decode/audio-decode.d.ts +10 -48
- package/node_modules/audio-decode/audio-decode.js +77 -193
- package/node_modules/audio-decode/package.json +21 -49
- package/node_modules/audio-decode/readme.md +29 -129
- package/node_modules/audio-decode/tea.yaml +6 -0
- package/node_modules/audio-decode/test-case.js +11 -0
- package/node_modules/audio-decode/test.html +10 -29
- package/node_modules/audio-decode/test.js +107 -0
- package/node_modules/node-wav/README.md +35 -0
- package/node_modules/node-wav/file.wav +0 -0
- package/node_modules/node-wav/index.js +291 -0
- package/node_modules/node-wav/package.json +29 -0
- package/node_modules/node-wav/tests/file1.wav +0 -0
- package/node_modules/node-wav/tests/test.js +66 -0
- package/node_modules/node-wav/x.js +12 -0
- package/node_modules/node-wav/x.json +86702 -0
- package/node_modules/node-wav/x.js~ +13 -0
- package/npm-shrinkwrap.json +32 -149
- package/package.json +5 -5
- package/node_modules/@audio/decode-aac/LICENSE +0 -9
- package/node_modules/@audio/decode-aac/README.md +0 -60
- package/node_modules/@audio/decode-aac/decode-aac.d.ts +0 -16
- package/node_modules/@audio/decode-aac/decode-aac.js +0 -391
- package/node_modules/@audio/decode-aac/package.json +0 -47
- package/node_modules/@audio/decode-aac/src/aac.wasm.cjs +0 -0
- package/node_modules/@audio/decode-aiff/LICENSE +0 -21
- package/node_modules/@audio/decode-aiff/README.md +0 -53
- package/node_modules/@audio/decode-aiff/decode-aiff.d.ts +0 -16
- package/node_modules/@audio/decode-aiff/decode-aiff.js +0 -583
- package/node_modules/@audio/decode-aiff/package.json +0 -42
- package/node_modules/@audio/decode-amr/LICENSE +0 -191
- package/node_modules/@audio/decode-amr/README.md +0 -65
- package/node_modules/@audio/decode-amr/decode-amr.d.ts +0 -16
- package/node_modules/@audio/decode-amr/decode-amr.js +0 -159
- package/node_modules/@audio/decode-amr/package.json +0 -48
- package/node_modules/@audio/decode-amr/src/amr.wasm.cjs +0 -0
- package/node_modules/@audio/decode-caf/LICENSE +0 -21
- package/node_modules/@audio/decode-caf/README.md +0 -55
- package/node_modules/@audio/decode-caf/decode-caf.d.ts +0 -16
- package/node_modules/@audio/decode-caf/decode-caf.js +0 -190
- package/node_modules/@audio/decode-caf/package.json +0 -43
- package/node_modules/@audio/decode-flac/LICENSE +0 -25
- package/node_modules/@audio/decode-flac/README.md +0 -23
- package/node_modules/@audio/decode-flac/decode-flac.d.ts +0 -16
- package/node_modules/@audio/decode-flac/decode-flac.js +0 -2994
- package/node_modules/@audio/decode-flac/meta.js +0 -115
- package/node_modules/@audio/decode-flac/package.json +0 -49
- package/node_modules/@audio/decode-mp3/LICENSE +0 -25
- package/node_modules/@audio/decode-mp3/README.md +0 -23
- package/node_modules/@audio/decode-mp3/decode-mp3.d.ts +0 -16
- package/node_modules/@audio/decode-mp3/decode-mp3.js +0 -868
- package/node_modules/@audio/decode-mp3/meta.js +0 -143
- package/node_modules/@audio/decode-mp3/package.json +0 -50
- package/node_modules/@audio/decode-opus/README.md +0 -23
- package/node_modules/@audio/decode-opus/decode-opus.d.ts +0 -16
- package/node_modules/@audio/decode-opus/decode-opus.js +0 -3179
- package/node_modules/@audio/decode-opus/package.json +0 -47
- package/node_modules/@audio/decode-qoa/LICENSE +0 -25
- package/node_modules/@audio/decode-qoa/README.md +0 -21
- package/node_modules/@audio/decode-qoa/decode-qoa.d.ts +0 -16
- package/node_modules/@audio/decode-qoa/decode-qoa.js +0 -278
- package/node_modules/@audio/decode-qoa/package.json +0 -46
- package/node_modules/@audio/decode-vorbis/LICENSE +0 -25
- package/node_modules/@audio/decode-vorbis/README.md +0 -23
- package/node_modules/@audio/decode-vorbis/decode-vorbis.d.ts +0 -16
- package/node_modules/@audio/decode-vorbis/decode-vorbis.js +0 -2984
- package/node_modules/@audio/decode-vorbis/package.json +0 -47
- package/node_modules/@audio/decode-wav/decode-wav.js +0 -104
- package/node_modules/@audio/decode-wav/meta.js +0 -114
- package/node_modules/@audio/decode-wav/package.json +0 -27
- package/node_modules/@audio/decode-webm/LICENSE +0 -21
- package/node_modules/@audio/decode-webm/README.md +0 -57
- package/node_modules/@audio/decode-webm/decode-webm.d.ts +0 -16
- package/node_modules/@audio/decode-webm/decode-webm.js +0 -3964
- package/node_modules/@audio/decode-webm/package.json +0 -51
- package/node_modules/@audio/decode-wma/LICENSE +0 -12
- package/node_modules/@audio/decode-wma/README.md +0 -76
- package/node_modules/@audio/decode-wma/decode-wma.d.ts +0 -33
- package/node_modules/@audio/decode-wma/decode-wma.js +0 -525
- package/node_modules/@audio/decode-wma/package.json +0 -47
- package/node_modules/@audio/decode-wma/src/wma.wasm.cjs +0 -0
- package/node_modules/audio-decode/.claude/settings.json +0 -204
- package/node_modules/audio-decode/.gitmodules +0 -9
- package/node_modules/audio-decode/meta.js +0 -11
- package/node_modules/audio-decode/stream.d.ts +0 -15
- package/node_modules/audio-decode/stream.js +0 -1
|
@@ -1,208 +1,92 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Audio decoder
|
|
3
|
-
* @module
|
|
4
|
-
*
|
|
5
|
-
* let { channelData, sampleRate } = await decode(buf)
|
|
6
|
-
*
|
|
7
|
-
* for await (let pcm of decode.mp3(source)) { ... }
|
|
8
|
-
*
|
|
9
|
-
* let dec = await decode.mp3()
|
|
10
|
-
* let { channelData, sampleRate } = await dec(chunk)
|
|
11
|
-
* await dec() // close
|
|
2
|
+
* Web-Audio-API decoder
|
|
3
|
+
* @module audio-decode
|
|
12
4
|
*/
|
|
13
5
|
|
|
14
6
|
import getType from 'audio-type';
|
|
7
|
+
import AudioBufferShim from 'audio-buffer';
|
|
15
8
|
|
|
16
|
-
const
|
|
9
|
+
const AudioBuffer = globalThis.AudioBuffer || AudioBufferShim;
|
|
17
10
|
|
|
18
11
|
/**
|
|
19
|
-
* Decode audio.
|
|
20
|
-
*
|
|
21
|
-
*
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
if (format) return decodeChunked(src, format)
|
|
25
|
-
return decodeWhole(src)
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
async function decodeWhole(src) {
|
|
29
|
-
if (!src || typeof src === 'string' || !(src.buffer || src.byteLength || src.length))
|
|
30
|
-
throw TypeError('Expected ArrayBuffer or Uint8Array')
|
|
31
|
-
let buf = new Uint8Array(src)
|
|
32
|
-
|
|
33
|
-
let type = getType(buf)
|
|
34
|
-
if (!type) throw Error('Unknown audio format')
|
|
35
|
-
if (!decode[type]) throw Error('No decoder for ' + type)
|
|
36
|
-
|
|
37
|
-
let dec = await decode[type]()
|
|
38
|
-
try {
|
|
39
|
-
let result = await dec(buf)
|
|
40
|
-
let flushed = await dec()
|
|
41
|
-
return merge(result, flushed)
|
|
42
|
-
} catch (e) { dec.free(); throw e }
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
/**
|
|
46
|
-
* Decode a ReadableStream or async iterable of encoded audio chunks.
|
|
47
|
-
* @param {ReadableStream|AsyncIterable} source
|
|
48
|
-
* @param {string} format - codec name
|
|
49
|
-
* @returns {AsyncGenerator<{channelData: Float32Array[], sampleRate: number}>}
|
|
12
|
+
* Decode an audio buffer.
|
|
13
|
+
*
|
|
14
|
+
* @param {ArrayBuffer | Uint8Array} buf - The audio data to decode.
|
|
15
|
+
* @returns {Promise<AudioBuffer>} A promise that resolves to the decoded audio buffer.
|
|
16
|
+
* @throws {Error} Throws an error if the decode target is invalid or if the audio format is not supported.
|
|
50
17
|
*/
|
|
51
|
-
export async function
|
|
52
|
-
if (!
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
18
|
+
export default async function audioDecode(buf) {
|
|
19
|
+
if (!buf && !(buf.length || buf.buffer)) throw Error('Bad decode target')
|
|
20
|
+
buf = new Uint8Array(buf.buffer || buf)
|
|
21
|
+
|
|
22
|
+
let type = getType(buf);
|
|
23
|
+
|
|
24
|
+
if (!type) throw Error('Cannot detect audio format');
|
|
25
|
+
|
|
26
|
+
if (!decoders[type]) throw Error('Missing decoder for ' + type + ' format')
|
|
27
|
+
|
|
28
|
+
return decoders[type](buf)
|
|
29
|
+
};
|
|
30
|
+
|
|
31
|
+
export const decoders = {
|
|
32
|
+
async oga(buf) {
|
|
33
|
+
let { decoder } = decoders.oga
|
|
34
|
+
if (!decoder) {
|
|
35
|
+
let { OggVorbisDecoder } = await import('@wasm-audio-decoders/ogg-vorbis')
|
|
36
|
+
await (decoders.oga.decoder = decoder = new OggVorbisDecoder()).ready;
|
|
37
|
+
} else await decoder.reset()
|
|
38
|
+
return buf && createBuffer(await decoder.decodeFile(buf))
|
|
39
|
+
},
|
|
40
|
+
async mp3(buf) {
|
|
41
|
+
let { decoder } = decoders.mp3
|
|
42
|
+
if (!decoder) {
|
|
43
|
+
const { MPEGDecoder } = await import('mpg123-decoder')
|
|
44
|
+
await (decoders.mp3.decoder = decoder = new MPEGDecoder()).ready;
|
|
68
45
|
}
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
function reg(name, load) {
|
|
79
|
-
decode[name] = fmt(name, async () => {
|
|
80
|
-
let mod = await load()
|
|
81
|
-
// @audio/* packages export { decoder, default }
|
|
82
|
-
if (mod.decoder) {
|
|
83
|
-
let codec = await mod.decoder()
|
|
84
|
-
return streamDecoder(
|
|
85
|
-
chunk => codec.decode(chunk),
|
|
86
|
-
codec.flush ? () => codec.flush() : null,
|
|
87
|
-
codec.free ? () => codec.free() : null
|
|
88
|
-
)
|
|
46
|
+
else await decoder.reset()
|
|
47
|
+
return buf && createBuffer(await decoder.decode(buf))
|
|
48
|
+
},
|
|
49
|
+
async flac(buf) {
|
|
50
|
+
let { decoder } = decoders.flac
|
|
51
|
+
if (!decoder) {
|
|
52
|
+
const { FLACDecoder } = await import('@wasm-audio-decoders/flac')
|
|
53
|
+
await (decoders.flac.decoder = decoder = new FLACDecoder()).ready
|
|
89
54
|
}
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
)
|
|
99
|
-
})
|
|
100
|
-
}
|
|
101
|
-
|
|
102
|
-
function fmt(name, init) {
|
|
103
|
-
let fn = (src) => {
|
|
104
|
-
if (!src) return init()
|
|
105
|
-
// async iterable / ReadableStream → streaming decode
|
|
106
|
-
if (src[Symbol.asyncIterator] || src.getReader) return decodeChunked(src, name)
|
|
107
|
-
// buffer → whole-file decode
|
|
108
|
-
console.warn('decode.' + name + '(data) is deprecated, use decode(data)')
|
|
109
|
-
return (async () => {
|
|
110
|
-
let dec = await init()
|
|
111
|
-
try {
|
|
112
|
-
let result = await dec(src instanceof Uint8Array ? src : new Uint8Array(src.buffer || src))
|
|
113
|
-
let flushed = await dec()
|
|
114
|
-
return merge(result, flushed)
|
|
115
|
-
} catch (e) { dec.free(); throw e }
|
|
116
|
-
})()
|
|
117
|
-
}
|
|
118
|
-
return fn
|
|
119
|
-
}
|
|
120
|
-
|
|
121
|
-
// --- codecs ---
|
|
122
|
-
|
|
123
|
-
reg('mp3', () => import('@audio/decode-mp3'))
|
|
124
|
-
reg('flac', () => import('@audio/decode-flac'))
|
|
125
|
-
reg('opus', () => import('@audio/decode-opus'))
|
|
126
|
-
reg('oga', () => import('@audio/decode-vorbis'))
|
|
127
|
-
|
|
128
|
-
reg('m4a', () => import('@audio/decode-aac'))
|
|
129
|
-
|
|
130
|
-
reg('wav', () => import('@audio/decode-wav'))
|
|
131
|
-
reg('qoa', () => import('@audio/decode-qoa'))
|
|
132
|
-
|
|
133
|
-
reg('aac', () => import('@audio/decode-aac'))
|
|
134
|
-
reg('aiff', () => import('@audio/decode-aiff'))
|
|
135
|
-
reg('caf', () => import('@audio/decode-caf'))
|
|
136
|
-
reg('webm', () => import('@audio/decode-webm'))
|
|
137
|
-
reg('amr', () => import('@audio/decode-amr'))
|
|
138
|
-
reg('wma', () => import('@audio/decode-wma'))
|
|
139
|
-
|
|
140
|
-
/**
|
|
141
|
-
* StreamDecoder — a callable function:
|
|
142
|
-
* dec(chunk) — decode data, returns { channelData, sampleRate }
|
|
143
|
-
* dec() — end of stream: flush remaining samples + free resources
|
|
144
|
-
* dec.flush() — flush without freeing
|
|
145
|
-
* dec.free() — release resources without flushing
|
|
146
|
-
*/
|
|
147
|
-
function streamDecoder(onDecode, onFlush, onFree) {
|
|
148
|
-
let done = false
|
|
149
|
-
let fn = async (chunk) => {
|
|
150
|
-
if (chunk) {
|
|
151
|
-
if (done) throw Error('Decoder already freed')
|
|
152
|
-
try { return norm(await onDecode(chunk instanceof Uint8Array ? chunk : new Uint8Array(chunk))) }
|
|
153
|
-
catch (e) { done = true; onFree?.(); throw e }
|
|
55
|
+
else await decoder.reset()
|
|
56
|
+
return buf && createBuffer(await decoder.decode(buf))
|
|
57
|
+
},
|
|
58
|
+
async opus(buf) {
|
|
59
|
+
let { decoder } = decoders.opus
|
|
60
|
+
if (!decoder) {
|
|
61
|
+
const { OggOpusDecoder } = await import('ogg-opus-decoder')
|
|
62
|
+
await (decoders.opus.decoder = decoder = new OggOpusDecoder()).ready
|
|
154
63
|
}
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
}
|
|
173
|
-
return fn
|
|
174
|
-
}
|
|
175
|
-
|
|
176
|
-
// extract { channelData, sampleRate } from codec result
|
|
177
|
-
function norm(r) {
|
|
178
|
-
if (!r?.channelData?.length) return EMPTY
|
|
179
|
-
let { channelData, sampleRate, samplesDecoded } = r
|
|
180
|
-
if (samplesDecoded != null && samplesDecoded < channelData[0].length)
|
|
181
|
-
channelData = channelData.map(ch => ch.subarray(0, samplesDecoded))
|
|
182
|
-
if (!channelData[0]?.length) return EMPTY
|
|
183
|
-
// collapse duplicate stereo to mono (some decoders always output 2ch for mono sources)
|
|
184
|
-
if (channelData.length === 2) {
|
|
185
|
-
let a = channelData[0], b = channelData[1], same = true
|
|
186
|
-
for (let i = 0; i < a.length; i += 37) { if (a[i] !== b[i]) { same = false; break } }
|
|
187
|
-
if (same) channelData = [a]
|
|
64
|
+
else await decoder.reset()
|
|
65
|
+
return buf && createBuffer(await decoder.decodeFile(buf))
|
|
66
|
+
},
|
|
67
|
+
async wav(buf) {
|
|
68
|
+
let { decode } = decoders.wav
|
|
69
|
+
if (!decode) {
|
|
70
|
+
let module = await import('node-wav')
|
|
71
|
+
decode = decoders.wav.decode = module.default.decode
|
|
72
|
+
}
|
|
73
|
+
return buf && createBuffer(await decode(buf))
|
|
74
|
+
},
|
|
75
|
+
async qoa(buf) {
|
|
76
|
+
let { decode } = decoders.qoa
|
|
77
|
+
if (!decode) {
|
|
78
|
+
decoders.qoa.decode = decode = (await import('qoa-format')).decode
|
|
79
|
+
}
|
|
80
|
+
return buf && createBuffer(await decode(buf))
|
|
188
81
|
}
|
|
189
|
-
return { channelData, sampleRate }
|
|
190
82
|
}
|
|
191
83
|
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
let ac = a.channelData[i % ach], bc = b.channelData[i % bch]
|
|
201
|
-
let merged = new Float32Array(ac.length + bc.length)
|
|
202
|
-
merged.set(ac)
|
|
203
|
-
merged.set(bc, ac.length)
|
|
204
|
-
return merged
|
|
205
|
-
}),
|
|
206
|
-
sampleRate: a.sampleRate
|
|
207
|
-
}
|
|
84
|
+
function createBuffer({ channelData, sampleRate }) {
|
|
85
|
+
let audioBuffer = new AudioBuffer({
|
|
86
|
+
sampleRate,
|
|
87
|
+
length: channelData[0].length,
|
|
88
|
+
numberOfChannels: channelData.length
|
|
89
|
+
})
|
|
90
|
+
for (let ch = 0; ch < channelData.length; ch++) audioBuffer.getChannelData(ch).set(channelData[ch])
|
|
91
|
+
return audioBuffer
|
|
208
92
|
}
|
|
@@ -1,77 +1,49 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "audio-decode",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "2.2.3",
|
|
4
4
|
"description": "Decode audio data in node or browser",
|
|
5
|
-
"type": "module",
|
|
6
|
-
"sideEffects": false,
|
|
7
5
|
"main": "audio-decode.js",
|
|
6
|
+
"module": "audio-decode.js",
|
|
7
|
+
"browser": "audio-decode.js",
|
|
8
|
+
"type": "module",
|
|
8
9
|
"types": "audio-decode.d.ts",
|
|
9
|
-
"exports": {
|
|
10
|
-
".": {
|
|
11
|
-
"browser": "./audio-decode.js",
|
|
12
|
-
"node": "./audio-decode.js",
|
|
13
|
-
"default": "./audio-decode.js"
|
|
14
|
-
},
|
|
15
|
-
"./stream": "./stream.js",
|
|
16
|
-
"./meta": "./meta.js",
|
|
17
|
-
"./package.json": "./package.json"
|
|
18
|
-
},
|
|
19
|
-
"workspaces": [
|
|
20
|
-
"packages/*"
|
|
21
|
-
],
|
|
22
10
|
"dependencies": {
|
|
23
|
-
"@audio/
|
|
24
|
-
"@audio/
|
|
25
|
-
"
|
|
26
|
-
"
|
|
27
|
-
"
|
|
28
|
-
"
|
|
29
|
-
"
|
|
30
|
-
"
|
|
31
|
-
"@audio/decode-vorbis": "^1.0.0",
|
|
32
|
-
"@audio/decode-wav": "^1.2.0",
|
|
33
|
-
"@audio/decode-webm": "^1.0.0",
|
|
34
|
-
"@audio/decode-wma": "^1.0.0",
|
|
35
|
-
"audio-type": "^2.4.0"
|
|
11
|
+
"@wasm-audio-decoders/flac": "^0.2.4",
|
|
12
|
+
"@wasm-audio-decoders/ogg-vorbis": "^0.1.15",
|
|
13
|
+
"audio-buffer": "^5.0.0",
|
|
14
|
+
"audio-type": "^2.2.1",
|
|
15
|
+
"mpg123-decoder": "^1.0.0",
|
|
16
|
+
"node-wav": "^0.0.2",
|
|
17
|
+
"ogg-opus-decoder": "^1.6.12",
|
|
18
|
+
"qoa-format": "^1.0.1"
|
|
36
19
|
},
|
|
37
20
|
"devDependencies": {
|
|
38
|
-
"audio-lena": "^3.0
|
|
21
|
+
"audio-lena": "^2.3.0",
|
|
39
22
|
"base64-arraybuffer": "^1.0.2",
|
|
40
|
-
"
|
|
41
|
-
"playwright": "^1.58.0",
|
|
42
|
-
"tst": "^9.2.2"
|
|
23
|
+
"tst": "^7.3.0"
|
|
43
24
|
},
|
|
44
25
|
"scripts": {
|
|
45
|
-
"test": "node test.js"
|
|
46
|
-
"test:browser": "node test.browser.js",
|
|
47
|
-
"test:all": "node test.js && node test.browser.js",
|
|
48
|
-
"publish:all": "npm publish --workspaces && npm publish"
|
|
26
|
+
"test": "node test.js"
|
|
49
27
|
},
|
|
50
28
|
"repository": {
|
|
51
29
|
"type": "git",
|
|
52
30
|
"url": "git+https://github.com/audiojs/audio-decode.git"
|
|
53
31
|
},
|
|
54
32
|
"keywords": [
|
|
33
|
+
"audiojs",
|
|
55
34
|
"audio",
|
|
35
|
+
"dsp",
|
|
56
36
|
"decode",
|
|
57
|
-
"
|
|
37
|
+
"audio decode",
|
|
38
|
+
"audio decoder",
|
|
39
|
+
"web audio decoder",
|
|
58
40
|
"codec",
|
|
59
41
|
"mp3",
|
|
60
42
|
"wav",
|
|
61
43
|
"ogg",
|
|
62
44
|
"vorbis",
|
|
63
45
|
"opus",
|
|
64
|
-
"
|
|
65
|
-
"aac",
|
|
66
|
-
"m4a",
|
|
67
|
-
"qoa",
|
|
68
|
-
"aiff",
|
|
69
|
-
"caf",
|
|
70
|
-
"webm",
|
|
71
|
-
"amr",
|
|
72
|
-
"wma",
|
|
73
|
-
"pcm",
|
|
74
|
-
"streaming"
|
|
46
|
+
"web-audio"
|
|
75
47
|
],
|
|
76
48
|
"author": "ΔY <dfcreative@gmail.com>",
|
|
77
49
|
"license": "MIT",
|
|
@@ -1,149 +1,49 @@
|
|
|
1
|
-
# audio-decode [](https://github.com/audiojs/audio-decode/actions/workflows/test.js.yml)
|
|
1
|
+
# audio-decode [](https://github.com/audiojs/audio-decode/actions/workflows/test.js.yml) [](http://github.com/badges/stability-badges)
|
|
2
2
|
|
|
3
|
-
Decode
|
|
4
|
-
JS / WASM – no ffmpeg, no native bindings, works in both node and browser.<br>
|
|
5
|
-
Small API, minimal size, near-native performance, lazy-loading, chunked decoding.
|
|
3
|
+
Decode audio data from supported format to [AudioBuffer](https://github.com/audiojs/audio-buffer).
|
|
6
4
|
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
```js
|
|
10
|
-
import decode from 'audio-decode';
|
|
11
|
-
|
|
12
|
-
const { channelData, sampleRate } = await decode(anyAudioBuffer);
|
|
13
|
-
```
|
|
14
|
-
|
|
15
|
-
#### Supported formats
|
|
16
|
-
|
|
17
|
-
| Format | Package | Size | Engine |
|
|
18
|
-
|--------|---------|------|--------|
|
|
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 |
|
|
24
|
-
| M4A / AAC | [@audio/decode-aac](./packages/decode-aac) | 368 KB | WASM |
|
|
25
|
-
| QOA | [@audio/decode-qoa](./packages/decode-qoa) | 8 KB | JS |
|
|
26
|
-
| 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 |
|
|
29
|
-
| AMR | [@audio/decode-amr](./packages/decode-amr) | 241 KB | WASM |
|
|
30
|
-
| WMA | [@audio/decode-wma](./packages/decode-wma) | 91 KB | WASM |
|
|
31
|
-
|
|
32
|
-
### Whole-file
|
|
33
|
-
|
|
34
|
-
Auto-detects format. Input can be _ArrayBuffer_, _Uint8Array_, or _Buffer_.
|
|
35
|
-
|
|
36
|
-
```js
|
|
37
|
-
import decode from 'audio-decode'
|
|
38
|
-
|
|
39
|
-
let { channelData, sampleRate } = await decode(buf)
|
|
40
|
-
```
|
|
41
|
-
|
|
42
|
-
### Chunked
|
|
5
|
+
Supported formats:
|
|
43
6
|
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
7
|
+
* [x] `wav`
|
|
8
|
+
* [x] `mp3`
|
|
9
|
+
* [x] `ogg vorbis`
|
|
10
|
+
* [x] `flac`
|
|
11
|
+
* [x] `opus`
|
|
12
|
+
* [ ] `alac`
|
|
13
|
+
* [ ] `aac`
|
|
14
|
+
* [ ] `m4a`
|
|
15
|
+
* [x] [`qoa`](https://github.com/phoboslab/qoa)
|
|
50
16
|
|
|
51
|
-
|
|
17
|
+
[](https://npmjs.org/package/audio-decode/)
|
|
52
18
|
|
|
53
19
|
```js
|
|
54
|
-
import
|
|
20
|
+
import decodeAudio from 'audio-decode';
|
|
21
|
+
import buffer from 'audio-lena/mp3';
|
|
55
22
|
|
|
56
|
-
|
|
57
|
-
// process chunks
|
|
58
|
-
}
|
|
23
|
+
let audioBuffer = await decode(buffer);
|
|
59
24
|
```
|
|
60
25
|
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
Formats: `mp3`, `flac`, `opus`, `oga`, `m4a`, `wav`, `qoa`, `aac`, `aiff`, `caf`, `webm`, `amr`, `wma`.
|
|
64
|
-
|
|
65
|
-
### Browser
|
|
66
|
-
|
|
67
|
-
Each codec is a self-contained bundle under `@audio/*` — no transitive deps, no import map bloat.
|
|
68
|
-
For selective loading in the browser (avoids bundling all codecs):
|
|
69
|
-
|
|
70
|
-
```html
|
|
71
|
-
<script type="importmap">
|
|
72
|
-
{
|
|
73
|
-
"imports": {
|
|
74
|
-
"audio-decode": "https://esm.sh/audio-decode",
|
|
75
|
-
"audio-type": "https://esm.sh/audio-type",
|
|
76
|
-
"@audio/decode-mp3": "https://esm.sh/@audio/decode-mp3",
|
|
77
|
-
"@audio/decode-wav": "https://esm.sh/@audio/decode-wav",
|
|
78
|
-
"@audio/decode-flac": "https://esm.sh/@audio/decode-flac",
|
|
79
|
-
"@audio/decode-opus": "https://esm.sh/@audio/decode-opus",
|
|
80
|
-
"@audio/decode-vorbis": "https://esm.sh/@audio/decode-vorbis",
|
|
81
|
-
"@audio/decode-aac": "https://esm.sh/@audio/decode-aac",
|
|
82
|
-
"@audio/decode-qoa": "https://esm.sh/@audio/decode-qoa",
|
|
83
|
-
"@audio/decode-aiff": "https://esm.sh/@audio/decode-aiff",
|
|
84
|
-
"@audio/decode-caf": "https://esm.sh/@audio/decode-caf",
|
|
85
|
-
"@audio/decode-webm": "https://esm.sh/@audio/decode-webm",
|
|
86
|
-
"@audio/decode-amr": "https://esm.sh/@audio/decode-amr",
|
|
87
|
-
"@audio/decode-wma": "https://esm.sh/@audio/decode-wma"
|
|
88
|
-
}
|
|
89
|
-
}
|
|
90
|
-
</script>
|
|
91
|
-
<script type="module">
|
|
92
|
-
import decode from 'audio-decode'
|
|
93
|
-
let { channelData, sampleRate } = await decode(buf)
|
|
94
|
-
</script>
|
|
95
|
-
```
|
|
26
|
+
`buffer` type can be: _ArrayBuffer_, _Uint8Array_ or _Buffer_.
|
|
96
27
|
|
|
97
|
-
|
|
28
|
+
`decode` is lazy: first call prepares decoder.
|
|
98
29
|
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
Read tags, pictures, markers and regions without decoding samples. Available for `wav`, `mp3`, `flac`.
|
|
30
|
+
To get more granular control over individual decoders, use `decoders`:
|
|
102
31
|
|
|
103
32
|
```js
|
|
104
|
-
import
|
|
105
|
-
|
|
106
|
-
let { meta, sampleRate, markers, regions } = mp3(bytes)
|
|
107
|
-
// meta: { title, artist, album, year, bpm, key, comment, pictures, raw, ... }
|
|
108
|
-
// markers: [{ sample, label }]
|
|
109
|
-
// regions: [{ sample, length, label }]
|
|
110
|
-
```
|
|
33
|
+
import decode, {decoders} from 'audio-decode';
|
|
111
34
|
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
```js
|
|
115
|
-
import { parseMeta } from '@audio/decode-wav/meta'
|
|
116
|
-
let info = parseMeta(wavBytes)
|
|
35
|
+
await decoders.mp3(); // load & compile decoder
|
|
36
|
+
const audioBuffer = await decoders.mp3(mp3buf); // decode
|
|
117
37
|
```
|
|
118
38
|
|
|
119
|
-
|
|
39
|
+
## See also
|
|
120
40
|
|
|
121
|
-
|
|
41
|
+
* [wasm-audio-decoders](https://github.com/eshaz/wasm-audio-decoders) – best in class compact & fast WASM audio decoders.
|
|
42
|
+
* [Web Audio Decoders](https://developer.mozilla.org/en-US/docs/Web/API/AudioDecoder) – native decoders API, hope one day will be fixed or alternatively polyfilled.
|
|
43
|
+
* [decodeAudioData](https://github.com/eshaz/wasm-audio-decoders) – default in-browser decoding method.
|
|
44
|
+
* [ffmpeg.wasm](https://github.com/ffmpegwasm/ffmpeg.wasm) – ultimate encoding/decoding library (8.5Mb of code).
|
|
122
45
|
|
|
123
|
-
|
|
124
|
-
// decode-worker.js
|
|
125
|
-
import decode from '@audio/decode-mp3'
|
|
126
|
-
|
|
127
|
-
self.onmessage = async ({ data }) => {
|
|
128
|
-
let pcm = await decode(data)
|
|
129
|
-
self.postMessage(pcm, pcm.channelData.map(ch => ch.buffer))
|
|
130
|
-
}
|
|
131
|
-
|
|
132
|
-
// main.js
|
|
133
|
-
let worker = new Worker('./decode-worker.js', { type: 'module' })
|
|
134
|
-
worker.postMessage(mp3buf, [mp3buf])
|
|
135
|
-
worker.onmessage = ({ data }) => { /* { channelData, sampleRate } */ }
|
|
136
|
-
```
|
|
137
|
-
|
|
138
|
-
## See also
|
|
46
|
+
## License
|
|
139
47
|
|
|
140
|
-
|
|
141
|
-
* [audio-type](https://github.com/audiojs/audio-type) – detect audio format from buffer.
|
|
142
|
-
<!--
|
|
143
|
-
* [wasm-audio-decoders](https://github.com/eshaz/wasm-audio-decoders) – compact & fast WASM audio decoders.
|
|
144
|
-
* [AudioDecoder](https://developer.mozilla.org/en-US/docs/Web/API/AudioDecoder) – native WebCodecs decoder API.
|
|
145
|
-
* [decodeAudioData](https://developer.mozilla.org/en-US/docs/Web/API/BaseAudioContext/decodeAudioData) – built-in browser decoding method.
|
|
146
|
-
* [ffmpeg.wasm](https://github.com/ffmpegwasm/ffmpeg.wasm) – full encoding/decoding library.
|
|
147
|
-
-->
|
|
48
|
+
[MIT](LICENSE) • <a href="https://github.com/krishnized/license/">🕉</a>
|
|
148
49
|
|
|
149
|
-
<p align="center"><a href="./LICENSE">MIT</a> • <a href="https://github.com/krishnized/license/">ॐ</a>
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import fs from 'fs/promises'
|
|
2
|
+
|
|
3
|
+
async function main(options) {
|
|
4
|
+
const audioDecode = await import('./audio-decode.js');
|
|
5
|
+
const decode = audioDecode.default;
|
|
6
|
+
await audioDecode.decoders.mp3();
|
|
7
|
+
const buffer = await fs.readFile('test.mp3');
|
|
8
|
+
const decodedBuffer = await decode(buffer);
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
main().catch(console.error)
|
|
@@ -1,34 +1,15 @@
|
|
|
1
|
-
<!
|
|
2
|
-
<title>audio-decode tests</title>
|
|
1
|
+
<!DOCTYPE html>
|
|
3
2
|
<script type="importmap">
|
|
4
|
-
{
|
|
3
|
+
{
|
|
5
4
|
"imports": {
|
|
6
|
-
"./audio-decode.js": "./audio-decode.js",
|
|
7
|
-
"audio-lena/wav": "./node_modules/audio-lena/wav.js",
|
|
8
|
-
"audio-lena/mp3": "./node_modules/audio-lena/mp3.js",
|
|
9
|
-
"audio-lena/ogg": "./node_modules/audio-lena/ogg.js",
|
|
10
|
-
"audio-lena/flac": "./node_modules/audio-lena/flac.js",
|
|
11
|
-
"audio-lena/opus": "./node_modules/audio-lena/opus.js",
|
|
12
|
-
"audio-lena/aiff": "./node_modules/audio-lena/aiff.js",
|
|
13
|
-
"audio-lena/caf": "./node_modules/audio-lena/caf.js",
|
|
14
|
-
"audio-lena/webm": "./node_modules/audio-lena/webm.js",
|
|
15
|
-
"audio-lena/aac": "./node_modules/audio-lena/aac.js",
|
|
16
|
-
"audio-lena/m4a": "./node_modules/audio-lena/m4a.js",
|
|
17
|
-
"audio-type": "./node_modules/audio-type/audio-type.js",
|
|
18
5
|
"tst": "./node_modules/tst/tst.js",
|
|
19
|
-
"
|
|
20
|
-
"
|
|
21
|
-
"
|
|
22
|
-
"
|
|
23
|
-
"
|
|
24
|
-
"
|
|
25
|
-
"@audio/decode-qoa": "./packages/decode-qoa/decode-qoa.js",
|
|
26
|
-
"@audio/decode-aiff": "./packages/decode-aiff/decode-aiff.js",
|
|
27
|
-
"@audio/decode-caf": "./packages/decode-caf/decode-caf.js",
|
|
28
|
-
"@audio/decode-webm": "./packages/decode-webm/decode-webm.js",
|
|
29
|
-
"@audio/decode-amr": "./packages/decode-amr/decode-amr.js",
|
|
30
|
-
"@audio/decode-wma": "./packages/decode-wma/decode-wma.js"
|
|
6
|
+
"audio-type": "./node_modules/audio-type/audio-type.js",
|
|
7
|
+
"audio-buffer": "./node_modules/audio-buffer/index.js",
|
|
8
|
+
"audio-lena/wav.js": "./node_modules/audio-lena/wav.js",
|
|
9
|
+
"audio-lena/mp3.js": "./node_modules/audio-lena/mp3.js",
|
|
10
|
+
"audio-lena/ogg.js": "./node_modules/audio-lena/ogg.js",
|
|
11
|
+
"audio-lena/flac.js": "./node_modules/audio-lena/flac.js"
|
|
31
12
|
}
|
|
32
|
-
}
|
|
13
|
+
}
|
|
33
14
|
</script>
|
|
34
|
-
<script
|
|
15
|
+
<script src="./test.js" type="module"></script>
|