@mediabunny/mp3-encoder 1.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/LICENSE +373 -0
- package/README.md +154 -0
- package/dist/bundles/mediabunny-mp3-encoder.js +334 -0
- package/dist/bundles/mediabunny-mp3-encoder.min.js +9 -0
- package/dist/bundles/mediabunny-mp3-encoder.min.mjs +8 -0
- package/dist/bundles/mediabunny-mp3-encoder.mjs +291 -0
- package/dist/mediabunny-mp3-encoder.d.ts +21 -0
- package/dist/modules/build/lame.d.ts +3 -0
- package/dist/modules/build/lame.d.ts.map +1 -0
- package/dist/modules/build/lame.js +311 -0
- package/dist/modules/src/encode.worker.d.ts +9 -0
- package/dist/modules/src/encode.worker.d.ts.map +1 -0
- package/dist/modules/src/encode.worker.js +152 -0
- package/dist/modules/src/index.d.ts +26 -0
- package/dist/modules/src/index.d.ts.map +1 -0
- package/dist/modules/src/index.js +185 -0
- package/dist/modules/src/shared.d.ts +40 -0
- package/dist/modules/src/shared.d.ts.map +1 -0
- package/dist/modules/src/shared.js +9 -0
- package/package.json +51 -0
- package/src/encode.worker.ts +212 -0
- package/src/index.ts +213 -0
- package/src/lame-bridge.c +40 -0
- package/src/shared.ts +42 -0
- package/src/tsconfig.json +23 -0
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/*!
|
|
2
|
+
* Copyright (c) 2025-present, Vanilagy and contributors
|
|
3
|
+
*
|
|
4
|
+
* This Source Code Form is subject to the terms of the Mozilla Public
|
|
5
|
+
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
6
|
+
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
|
7
|
+
*/
|
|
8
|
+
export {};
|
|
9
|
+
//# sourceMappingURL=encode.worker.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"encode.worker.d.ts","sourceRoot":"","sources":["../../../src/encode.worker.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG"}
|
|
@@ -0,0 +1,152 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/*!
|
|
3
|
+
* Copyright (c) 2025-present, Vanilagy and contributors
|
|
4
|
+
*
|
|
5
|
+
* This Source Code Form is subject to the terms of the Mozilla Public
|
|
6
|
+
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
7
|
+
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
|
8
|
+
*/
|
|
9
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
10
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
11
|
+
};
|
|
12
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
13
|
+
const lame_1 = __importDefault(require("../build/lame"));
|
|
14
|
+
let module;
|
|
15
|
+
let lamePtr;
|
|
16
|
+
let storedNumberOfChannels;
|
|
17
|
+
let storedSampleRate;
|
|
18
|
+
let storedBitrate;
|
|
19
|
+
let needsReset = false;
|
|
20
|
+
let initLame;
|
|
21
|
+
let encodeSamples;
|
|
22
|
+
let flushLame;
|
|
23
|
+
let closeLame;
|
|
24
|
+
let inputSlice = null;
|
|
25
|
+
let outputSlice = null;
|
|
26
|
+
const init = async (numberOfChannels, sampleRate, bitrate) => {
|
|
27
|
+
storedNumberOfChannels = numberOfChannels;
|
|
28
|
+
storedSampleRate = sampleRate;
|
|
29
|
+
storedBitrate = bitrate;
|
|
30
|
+
module = (await (0, lame_1.default)());
|
|
31
|
+
// Set up the functions
|
|
32
|
+
initLame = module.cwrap('init_lame', 'number', ['number', 'number', 'number']);
|
|
33
|
+
encodeSamples = module.cwrap('encode_samples', 'number', ['number', 'number', 'number', 'number', 'number', 'number']);
|
|
34
|
+
flushLame = module.cwrap('flush_lame', 'number', ['number', 'number', 'number']);
|
|
35
|
+
closeLame = module.cwrap('close_lame', null, ['number']);
|
|
36
|
+
lamePtr = initLame(numberOfChannels, sampleRate, bitrate);
|
|
37
|
+
};
|
|
38
|
+
const reset = () => {
|
|
39
|
+
closeLame(lamePtr);
|
|
40
|
+
lamePtr = initLame(storedNumberOfChannels, storedSampleRate, storedBitrate);
|
|
41
|
+
};
|
|
42
|
+
const encode = (audioData, numberOfFrames) => {
|
|
43
|
+
if (needsReset) {
|
|
44
|
+
reset();
|
|
45
|
+
needsReset = false;
|
|
46
|
+
}
|
|
47
|
+
const audioBytes = new Uint8Array(audioData);
|
|
48
|
+
const sizePerChannel = audioBytes.length / storedNumberOfChannels;
|
|
49
|
+
inputSlice = maybeGrowSlice(inputSlice, audioBytes.length);
|
|
50
|
+
module.HEAPU8.set(audioBytes, inputSlice.ptr);
|
|
51
|
+
const requiredOutputSize = Math.ceil(1.25 * numberOfFrames + 7200);
|
|
52
|
+
outputSlice = maybeGrowSlice(outputSlice, requiredOutputSize);
|
|
53
|
+
const bytesWritten = encodeSamples(lamePtr, inputSlice.ptr, inputSlice.ptr + (storedNumberOfChannels - 1) * sizePerChannel, numberOfFrames, outputSlice.ptr, requiredOutputSize);
|
|
54
|
+
const result = module.HEAPU8.slice(outputSlice.ptr, outputSlice.ptr + bytesWritten);
|
|
55
|
+
return result.buffer;
|
|
56
|
+
};
|
|
57
|
+
const flush = () => {
|
|
58
|
+
if (needsReset) {
|
|
59
|
+
reset();
|
|
60
|
+
needsReset = false;
|
|
61
|
+
}
|
|
62
|
+
const requiredOutputSize = 7200;
|
|
63
|
+
outputSlice = maybeGrowSlice(outputSlice, requiredOutputSize);
|
|
64
|
+
const bytesWritten = flushLame(lamePtr, outputSlice.ptr, requiredOutputSize);
|
|
65
|
+
const result = module.HEAPU8.slice(outputSlice.ptr, outputSlice.ptr + bytesWritten);
|
|
66
|
+
needsReset = true; // After a flush, the encoder must be prepared to start a new encoding process
|
|
67
|
+
return result.buffer;
|
|
68
|
+
};
|
|
69
|
+
/** Either returns the existing slice, or allocates a new one if there's no existing slice or it was too small. */
|
|
70
|
+
const maybeGrowSlice = (slice, requiredSize) => {
|
|
71
|
+
if (!slice || slice.size < requiredSize) {
|
|
72
|
+
if (slice) {
|
|
73
|
+
module._free(slice.ptr);
|
|
74
|
+
}
|
|
75
|
+
return {
|
|
76
|
+
ptr: module._malloc(requiredSize),
|
|
77
|
+
size: requiredSize,
|
|
78
|
+
};
|
|
79
|
+
}
|
|
80
|
+
return slice;
|
|
81
|
+
};
|
|
82
|
+
const onMessage = (data) => {
|
|
83
|
+
const { id, command } = data;
|
|
84
|
+
const handleCommand = async () => {
|
|
85
|
+
try {
|
|
86
|
+
let result;
|
|
87
|
+
const transferables = [];
|
|
88
|
+
switch (command.type) {
|
|
89
|
+
case 'init':
|
|
90
|
+
{
|
|
91
|
+
await init(command.data.numberOfChannels, command.data.sampleRate, command.data.bitrate);
|
|
92
|
+
result = { success: true };
|
|
93
|
+
}
|
|
94
|
+
;
|
|
95
|
+
break;
|
|
96
|
+
case 'encode':
|
|
97
|
+
{
|
|
98
|
+
const encodedData = encode(command.data.audioData, command.data.numberOfFrames);
|
|
99
|
+
result = { encodedData };
|
|
100
|
+
transferables.push(encodedData);
|
|
101
|
+
}
|
|
102
|
+
;
|
|
103
|
+
break;
|
|
104
|
+
case 'flush':
|
|
105
|
+
{
|
|
106
|
+
const flushedData = flush();
|
|
107
|
+
result = { flushedData };
|
|
108
|
+
transferables.push(flushedData);
|
|
109
|
+
}
|
|
110
|
+
;
|
|
111
|
+
break;
|
|
112
|
+
}
|
|
113
|
+
const response = {
|
|
114
|
+
id,
|
|
115
|
+
success: true,
|
|
116
|
+
data: result,
|
|
117
|
+
};
|
|
118
|
+
sendMessage(response, transferables);
|
|
119
|
+
}
|
|
120
|
+
catch (error) {
|
|
121
|
+
const response = {
|
|
122
|
+
id,
|
|
123
|
+
success: false,
|
|
124
|
+
error,
|
|
125
|
+
};
|
|
126
|
+
sendMessage(response);
|
|
127
|
+
}
|
|
128
|
+
};
|
|
129
|
+
void handleCommand();
|
|
130
|
+
};
|
|
131
|
+
const sendMessage = (data, transferables) => {
|
|
132
|
+
if (parentPort) {
|
|
133
|
+
parentPort.postMessage(data, transferables ?? []);
|
|
134
|
+
}
|
|
135
|
+
else {
|
|
136
|
+
self.postMessage(data, { transfer: transferables ?? [] });
|
|
137
|
+
}
|
|
138
|
+
};
|
|
139
|
+
let parentPort = null;
|
|
140
|
+
if (typeof self === 'undefined') {
|
|
141
|
+
// We're in Node.js (or a runtime that mimics it)
|
|
142
|
+
const workerModule = 'worker_threads';
|
|
143
|
+
// eslint-disable-next-line @stylistic/max-len
|
|
144
|
+
// eslint-disable-next-line @typescript-eslint/no-require-imports, @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-unsafe-member-access
|
|
145
|
+
parentPort = require(workerModule).parentPort;
|
|
146
|
+
}
|
|
147
|
+
if (parentPort) {
|
|
148
|
+
parentPort.on('message', onMessage);
|
|
149
|
+
}
|
|
150
|
+
else {
|
|
151
|
+
self.addEventListener('message', event => onMessage(event.data));
|
|
152
|
+
}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/*!
|
|
2
|
+
* Copyright (c) 2025-present, Vanilagy and contributors
|
|
3
|
+
*
|
|
4
|
+
* This Source Code Form is subject to the terms of the Mozilla Public
|
|
5
|
+
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
6
|
+
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
|
7
|
+
*/
|
|
8
|
+
/**
|
|
9
|
+
* Registers the LAME MP3 encoder, which Mediabunny will then use automatically when applicable. Make sure to call this
|
|
10
|
+
* function before starting any encoding task.
|
|
11
|
+
*
|
|
12
|
+
* Preferably, wrap the call in a condition to avoid overriding any native MP3 encoder:
|
|
13
|
+
*
|
|
14
|
+
* ```ts
|
|
15
|
+
* import { canEncodeAudio } from 'mediabunny';
|
|
16
|
+
* import { registerMp3Encoder } from '@mediabunny/mp3-encoder';
|
|
17
|
+
*
|
|
18
|
+
* if (!(await canEncodeAudio('mp3'))) {
|
|
19
|
+
* registerMp3Encoder();
|
|
20
|
+
* }
|
|
21
|
+
* ```
|
|
22
|
+
*
|
|
23
|
+
* @public
|
|
24
|
+
*/
|
|
25
|
+
export declare const registerMp3Encoder: () => void;
|
|
26
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAqLH;;;;;;;;;;;;;;;;GAgBG;AACH,eAAO,MAAM,kBAAkB,YAE9B,CAAC"}
|
|
@@ -0,0 +1,185 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/*!
|
|
3
|
+
* Copyright (c) 2025-present, Vanilagy and contributors
|
|
4
|
+
*
|
|
5
|
+
* This Source Code Form is subject to the terms of the Mozilla Public
|
|
6
|
+
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
7
|
+
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
|
8
|
+
*/
|
|
9
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
10
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
11
|
+
};
|
|
12
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
13
|
+
exports.registerMp3Encoder = void 0;
|
|
14
|
+
const mediabunny_1 = require("mediabunny");
|
|
15
|
+
const mp3_misc_1 = require("../../../shared/mp3-misc");
|
|
16
|
+
// @ts-expect-error An esbuild plugin handles this, TypeScript doesn't need to understand
|
|
17
|
+
const encode_worker_1 = __importDefault(require("./encode.worker"));
|
|
18
|
+
class Mp3Encoder extends mediabunny_1.CustomAudioEncoder {
|
|
19
|
+
constructor() {
|
|
20
|
+
super(...arguments);
|
|
21
|
+
this.worker = null;
|
|
22
|
+
this.nextMessageId = 0;
|
|
23
|
+
this.pendingMessages = new Map();
|
|
24
|
+
this.buffer = new Uint8Array(2 ** 16);
|
|
25
|
+
this.currentBufferOffset = 0;
|
|
26
|
+
this.currentTimestamp = 0;
|
|
27
|
+
this.chunkMetadata = {};
|
|
28
|
+
}
|
|
29
|
+
static supports(codec, config) {
|
|
30
|
+
return codec === 'mp3'
|
|
31
|
+
&& (config.numberOfChannels === 1 || config.numberOfChannels === 2)
|
|
32
|
+
&& (config.sampleRate === 32000 || config.sampleRate === 44100 || config.sampleRate === 48000);
|
|
33
|
+
}
|
|
34
|
+
async init() {
|
|
35
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-call
|
|
36
|
+
this.worker = (await (0, encode_worker_1.default)()); // The actual encoding takes place in this worker
|
|
37
|
+
const onMessage = (data) => {
|
|
38
|
+
const pending = this.pendingMessages.get(data.id);
|
|
39
|
+
assert(pending !== undefined);
|
|
40
|
+
this.pendingMessages.delete(data.id);
|
|
41
|
+
if (data.success) {
|
|
42
|
+
pending.resolve(data.data);
|
|
43
|
+
}
|
|
44
|
+
else {
|
|
45
|
+
pending.reject(data.error);
|
|
46
|
+
}
|
|
47
|
+
};
|
|
48
|
+
if (this.worker.addEventListener) {
|
|
49
|
+
this.worker.addEventListener('message', event => onMessage(event.data));
|
|
50
|
+
}
|
|
51
|
+
else {
|
|
52
|
+
const nodeWorker = this.worker;
|
|
53
|
+
nodeWorker.on('message', onMessage);
|
|
54
|
+
}
|
|
55
|
+
assert(this.config.bitrate);
|
|
56
|
+
await this.sendCommand({
|
|
57
|
+
type: 'init',
|
|
58
|
+
data: {
|
|
59
|
+
numberOfChannels: this.config.numberOfChannels,
|
|
60
|
+
sampleRate: this.config.sampleRate,
|
|
61
|
+
bitrate: this.config.bitrate,
|
|
62
|
+
},
|
|
63
|
+
});
|
|
64
|
+
this.chunkMetadata = {
|
|
65
|
+
decoderConfig: {
|
|
66
|
+
codec: 'mp3',
|
|
67
|
+
numberOfChannels: this.config.numberOfChannels,
|
|
68
|
+
sampleRate: this.config.sampleRate,
|
|
69
|
+
},
|
|
70
|
+
};
|
|
71
|
+
}
|
|
72
|
+
async encode(audioSample) {
|
|
73
|
+
const sizePerChannel = audioSample.allocationSize({
|
|
74
|
+
format: 's16-planar',
|
|
75
|
+
planeIndex: 0,
|
|
76
|
+
});
|
|
77
|
+
const requiredBytes = audioSample.numberOfChannels * sizePerChannel;
|
|
78
|
+
const audioData = new ArrayBuffer(requiredBytes);
|
|
79
|
+
const audioBytes = new Uint8Array(audioData);
|
|
80
|
+
for (let i = 0; i < audioSample.numberOfChannels; i++) {
|
|
81
|
+
audioSample.copyTo(audioBytes.subarray(i * sizePerChannel), {
|
|
82
|
+
format: 's16-planar', // LAME wants it in this format
|
|
83
|
+
planeIndex: i,
|
|
84
|
+
});
|
|
85
|
+
}
|
|
86
|
+
const result = await this.sendCommand({
|
|
87
|
+
type: 'encode',
|
|
88
|
+
data: {
|
|
89
|
+
audioData,
|
|
90
|
+
numberOfFrames: audioSample.numberOfFrames,
|
|
91
|
+
},
|
|
92
|
+
}, [audioData]);
|
|
93
|
+
assert('encodedData' in result);
|
|
94
|
+
this.digestOutput(new Uint8Array(result.encodedData));
|
|
95
|
+
}
|
|
96
|
+
async flush() {
|
|
97
|
+
const result = await this.sendCommand({ type: 'flush' });
|
|
98
|
+
assert('flushedData' in result);
|
|
99
|
+
this.digestOutput(new Uint8Array(result.flushedData));
|
|
100
|
+
}
|
|
101
|
+
close() {
|
|
102
|
+
this.worker?.terminate();
|
|
103
|
+
}
|
|
104
|
+
/**
|
|
105
|
+
* LAME returns data in chunks, but a chunk doesn't need to contain a full MP3 frame. Therefore, we must accumulate
|
|
106
|
+
* these chunks and extract the MP3 frames only when they're complete.
|
|
107
|
+
*/
|
|
108
|
+
digestOutput(bytes) {
|
|
109
|
+
const requiredBufferSize = this.currentBufferOffset + bytes.length;
|
|
110
|
+
if (requiredBufferSize > this.buffer.length) {
|
|
111
|
+
// Grow the buffer to the required size
|
|
112
|
+
const newSize = 1 << Math.ceil(Math.log2(requiredBufferSize));
|
|
113
|
+
const newBuffer = new Uint8Array(newSize);
|
|
114
|
+
newBuffer.set(this.buffer);
|
|
115
|
+
this.buffer = newBuffer;
|
|
116
|
+
}
|
|
117
|
+
this.buffer.set(bytes, this.currentBufferOffset);
|
|
118
|
+
this.currentBufferOffset = requiredBufferSize;
|
|
119
|
+
let pos = 0;
|
|
120
|
+
while (pos <= this.currentBufferOffset - mp3_misc_1.FRAME_HEADER_SIZE) {
|
|
121
|
+
const word = new DataView(this.buffer.buffer).getUint32(pos, false);
|
|
122
|
+
const header = (0, mp3_misc_1.readFrameHeader)(word, { pos, fileSize: null });
|
|
123
|
+
if (!header) {
|
|
124
|
+
break;
|
|
125
|
+
}
|
|
126
|
+
const fits = header.totalSize <= this.currentBufferOffset - pos;
|
|
127
|
+
if (!fits) {
|
|
128
|
+
// The frame isn't complete yet
|
|
129
|
+
break;
|
|
130
|
+
}
|
|
131
|
+
const data = this.buffer.slice(pos, pos + header.totalSize);
|
|
132
|
+
const duration = header.audioSamplesInFrame / header.sampleRate;
|
|
133
|
+
this.onPacket(new mediabunny_1.EncodedPacket(data, 'key', this.currentTimestamp, duration), this.chunkMetadata);
|
|
134
|
+
if (this.currentTimestamp === 0) {
|
|
135
|
+
this.chunkMetadata = {}; // Mimic WebCodecs-like behavior
|
|
136
|
+
}
|
|
137
|
+
this.currentTimestamp += duration;
|
|
138
|
+
pos += header.totalSize;
|
|
139
|
+
}
|
|
140
|
+
if (pos > 0) {
|
|
141
|
+
// Shift the data
|
|
142
|
+
this.buffer.set(this.buffer.subarray(pos, this.currentBufferOffset), 0);
|
|
143
|
+
this.currentBufferOffset -= pos;
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
sendCommand(command, transferables) {
|
|
147
|
+
return new Promise((resolve, reject) => {
|
|
148
|
+
const id = this.nextMessageId++;
|
|
149
|
+
this.pendingMessages.set(id, { resolve, reject });
|
|
150
|
+
assert(this.worker);
|
|
151
|
+
if (transferables) {
|
|
152
|
+
this.worker.postMessage({ id, command }, transferables);
|
|
153
|
+
}
|
|
154
|
+
else {
|
|
155
|
+
this.worker.postMessage({ id, command });
|
|
156
|
+
}
|
|
157
|
+
});
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
/**
|
|
161
|
+
* Registers the LAME MP3 encoder, which Mediabunny will then use automatically when applicable. Make sure to call this
|
|
162
|
+
* function before starting any encoding task.
|
|
163
|
+
*
|
|
164
|
+
* Preferably, wrap the call in a condition to avoid overriding any native MP3 encoder:
|
|
165
|
+
*
|
|
166
|
+
* ```ts
|
|
167
|
+
* import { canEncodeAudio } from 'mediabunny';
|
|
168
|
+
* import { registerMp3Encoder } from '@mediabunny/mp3-encoder';
|
|
169
|
+
*
|
|
170
|
+
* if (!(await canEncodeAudio('mp3'))) {
|
|
171
|
+
* registerMp3Encoder();
|
|
172
|
+
* }
|
|
173
|
+
* ```
|
|
174
|
+
*
|
|
175
|
+
* @public
|
|
176
|
+
*/
|
|
177
|
+
const registerMp3Encoder = () => {
|
|
178
|
+
(0, mediabunny_1.registerEncoder)(Mp3Encoder);
|
|
179
|
+
};
|
|
180
|
+
exports.registerMp3Encoder = registerMp3Encoder;
|
|
181
|
+
function assert(x) {
|
|
182
|
+
if (!x) {
|
|
183
|
+
throw new Error('Assertion failed.');
|
|
184
|
+
}
|
|
185
|
+
}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
/*!
|
|
2
|
+
* Copyright (c) 2025-present, Vanilagy and contributors
|
|
3
|
+
*
|
|
4
|
+
* This Source Code Form is subject to the terms of the Mozilla Public
|
|
5
|
+
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
6
|
+
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
|
7
|
+
*/
|
|
8
|
+
export type WorkerCommand = {
|
|
9
|
+
type: 'init';
|
|
10
|
+
data: {
|
|
11
|
+
numberOfChannels: number;
|
|
12
|
+
sampleRate: number;
|
|
13
|
+
bitrate: number;
|
|
14
|
+
};
|
|
15
|
+
} | {
|
|
16
|
+
type: 'encode';
|
|
17
|
+
data: {
|
|
18
|
+
audioData: ArrayBuffer;
|
|
19
|
+
numberOfFrames: number;
|
|
20
|
+
};
|
|
21
|
+
} | {
|
|
22
|
+
type: 'flush';
|
|
23
|
+
};
|
|
24
|
+
export type WorkerResponseData = {
|
|
25
|
+
success: boolean;
|
|
26
|
+
} | {
|
|
27
|
+
encodedData: ArrayBuffer;
|
|
28
|
+
} | {
|
|
29
|
+
flushedData: ArrayBuffer;
|
|
30
|
+
};
|
|
31
|
+
export type WorkerResponse = {
|
|
32
|
+
id: number;
|
|
33
|
+
} & ({
|
|
34
|
+
success: true;
|
|
35
|
+
data: WorkerResponseData;
|
|
36
|
+
} | {
|
|
37
|
+
success: false;
|
|
38
|
+
error: unknown;
|
|
39
|
+
});
|
|
40
|
+
//# sourceMappingURL=shared.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"shared.d.ts","sourceRoot":"","sources":["../../../src/shared.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,MAAM,MAAM,aAAa,GAAG;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE;QACL,gBAAgB,EAAE,MAAM,CAAC;QACzB,UAAU,EAAE,MAAM,CAAC;QACnB,OAAO,EAAE,MAAM,CAAC;KAChB,CAAC;CACF,GAAG;IACH,IAAI,EAAE,QAAQ,CAAC;IACf,IAAI,EAAE;QACL,SAAS,EAAE,WAAW,CAAC;QACvB,cAAc,EAAE,MAAM,CAAC;KACvB,CAAC;CACF,GAAG;IACH,IAAI,EAAE,OAAO,CAAC;CACd,CAAC;AAEF,MAAM,MAAM,kBAAkB,GAAG;IAChC,OAAO,EAAE,OAAO,CAAC;CACjB,GAAG;IACH,WAAW,EAAE,WAAW,CAAC;CACzB,GAAG;IACH,WAAW,EAAE,WAAW,CAAC;CACzB,CAAC;AAEF,MAAM,MAAM,cAAc,GAAG;IAC5B,EAAE,EAAE,MAAM,CAAC;CACX,GAAG,CAAC;IACJ,OAAO,EAAE,IAAI,CAAC;IACd,IAAI,EAAE,kBAAkB,CAAC;CACzB,GAAG;IACH,OAAO,EAAE,KAAK,CAAC;IACf,KAAK,EAAE,OAAO,CAAC;CACf,CAAC,CAAC"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/*!
|
|
3
|
+
* Copyright (c) 2025-present, Vanilagy and contributors
|
|
4
|
+
*
|
|
5
|
+
* This Source Code Form is subject to the terms of the Mozilla Public
|
|
6
|
+
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
7
|
+
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
|
8
|
+
*/
|
|
9
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
package/package.json
ADDED
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@mediabunny/mp3-encoder",
|
|
3
|
+
"author": "Vanilagy",
|
|
4
|
+
"version": "1.6.1",
|
|
5
|
+
"description": "MP3 encoder extension for Mediabunny, based on LAME.",
|
|
6
|
+
"main": "./dist/bundles/mediabunny-mp3-encoder.mjs",
|
|
7
|
+
"module": "./dist/bundles/mediabunny-mp3-encoder.mjs",
|
|
8
|
+
"types": "./dist/modules/src/index.d.ts",
|
|
9
|
+
"exports": {
|
|
10
|
+
"types": "./dist/modules/src/index.d.ts",
|
|
11
|
+
"import": "./dist/bundles/mediabunny-mp3-encoder.mjs",
|
|
12
|
+
"require": "./dist/bundles/mediabunny-mp3-encoder.mjs"
|
|
13
|
+
},
|
|
14
|
+
"files": [
|
|
15
|
+
"README.md",
|
|
16
|
+
"package.json",
|
|
17
|
+
"LICENSE",
|
|
18
|
+
"dist",
|
|
19
|
+
"src"
|
|
20
|
+
],
|
|
21
|
+
"sideEffects": false,
|
|
22
|
+
"license": "MPL-2.0",
|
|
23
|
+
"repository": {
|
|
24
|
+
"type": "git",
|
|
25
|
+
"url": "git+https://github.com/Vanilagy/mediabunny.git"
|
|
26
|
+
},
|
|
27
|
+
"bugs": {
|
|
28
|
+
"url": "https://github.com/Vanilagy/mediabunny/issues"
|
|
29
|
+
},
|
|
30
|
+
"homepage": "https://mediabunny.dev/",
|
|
31
|
+
"funding": {
|
|
32
|
+
"type": "individual",
|
|
33
|
+
"url": "https://github.com/sponsors/Vanilagy"
|
|
34
|
+
},
|
|
35
|
+
"peerDependencies": {
|
|
36
|
+
"mediabunny": "^1.0.0"
|
|
37
|
+
},
|
|
38
|
+
"devDependencies": {
|
|
39
|
+
"@types/emscripten": "^1.40.1"
|
|
40
|
+
},
|
|
41
|
+
"keywords": [
|
|
42
|
+
"mp3",
|
|
43
|
+
"encoding",
|
|
44
|
+
"codec",
|
|
45
|
+
"mediabunny",
|
|
46
|
+
"lame",
|
|
47
|
+
"browser",
|
|
48
|
+
"wasm",
|
|
49
|
+
"polyfill"
|
|
50
|
+
]
|
|
51
|
+
}
|