webcodecs-node 0.2.2 → 0.3.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 +4 -0
- package/dist/__tests__/AudioDecoder.test.js +3 -3
- package/dist/__tests__/AudioDecoder.test.js.map +1 -1
- package/dist/__tests__/ImageDecoder.wpt.test.d.ts +8 -0
- package/dist/__tests__/ImageDecoder.wpt.test.d.ts.map +1 -0
- package/dist/__tests__/ImageDecoder.wpt.test.js +135 -0
- package/dist/__tests__/ImageDecoder.wpt.test.js.map +1 -0
- package/dist/__tests__/NodeAvDecoder.test.d.ts +2 -0
- package/dist/__tests__/NodeAvDecoder.test.d.ts.map +1 -0
- package/dist/__tests__/NodeAvDecoder.test.js +199 -0
- package/dist/__tests__/NodeAvDecoder.test.js.map +1 -0
- package/dist/__tests__/NodeAvEncoder.test.d.ts +2 -0
- package/dist/__tests__/NodeAvEncoder.test.d.ts.map +1 -0
- package/dist/__tests__/NodeAvEncoder.test.js +176 -0
- package/dist/__tests__/NodeAvEncoder.test.js.map +1 -0
- package/dist/__tests__/VideoFrame.test.js.map +1 -1
- package/dist/backends/index.d.ts +3 -0
- package/dist/backends/index.d.ts.map +1 -0
- package/dist/backends/index.js +2 -0
- package/dist/backends/index.js.map +1 -0
- package/dist/backends/types.d.ts +165 -0
- package/dist/backends/types.d.ts.map +1 -0
- package/dist/backends/types.js +25 -0
- package/dist/backends/types.js.map +1 -0
- package/dist/core/AudioData.d.ts +1 -1
- package/dist/core/AudioData.d.ts.map +1 -1
- package/dist/core/AudioData.js +13 -9
- package/dist/core/AudioData.js.map +1 -1
- package/dist/core/VideoFrame.d.ts +25 -10
- package/dist/core/VideoFrame.d.ts.map +1 -1
- package/dist/core/VideoFrame.js +115 -65
- package/dist/core/VideoFrame.js.map +1 -1
- package/dist/decoders/AudioDecoder.d.ts +6 -12
- package/dist/decoders/AudioDecoder.d.ts.map +1 -1
- package/dist/decoders/AudioDecoder.js +57 -147
- package/dist/decoders/AudioDecoder.js.map +1 -1
- package/dist/decoders/ImageDecoder.d.ts +1 -0
- package/dist/decoders/ImageDecoder.d.ts.map +1 -1
- package/dist/decoders/ImageDecoder.js +59 -0
- package/dist/decoders/ImageDecoder.js.map +1 -1
- package/dist/decoders/VideoDecoder.d.ts +6 -13
- package/dist/decoders/VideoDecoder.d.ts.map +1 -1
- package/dist/decoders/VideoDecoder.js +49 -130
- package/dist/decoders/VideoDecoder.js.map +1 -1
- package/dist/demos/demo-conversion.js +2 -2
- package/dist/demos/demo-conversion.js.map +1 -1
- package/dist/demos/demo-four-corners.d.ts +6 -0
- package/dist/demos/demo-four-corners.d.ts.map +1 -0
- package/dist/demos/demo-four-corners.js +218 -0
- package/dist/demos/demo-four-corners.js.map +1 -0
- package/dist/demos/demo-samples.js +228 -64
- package/dist/demos/demo-samples.js.map +1 -1
- package/dist/encoders/AudioEncoder.d.ts +6 -13
- package/dist/encoders/AudioEncoder.d.ts.map +1 -1
- package/dist/encoders/AudioEncoder.js +81 -213
- package/dist/encoders/AudioEncoder.js.map +1 -1
- package/dist/encoders/VideoEncoder.d.ts +5 -14
- package/dist/encoders/VideoEncoder.d.ts.map +1 -1
- package/dist/encoders/VideoEncoder.js +39 -159
- package/dist/encoders/VideoEncoder.js.map +1 -1
- package/dist/formats/conversions/frame-converter.d.ts +17 -0
- package/dist/formats/conversions/frame-converter.d.ts.map +1 -1
- package/dist/formats/conversions/frame-converter.js +127 -0
- package/dist/formats/conversions/frame-converter.js.map +1 -1
- package/dist/formats/conversions/index.d.ts +1 -0
- package/dist/formats/conversions/index.d.ts.map +1 -1
- package/dist/formats/conversions/index.js +2 -0
- package/dist/formats/conversions/index.js.map +1 -1
- package/dist/hardware/detection.d.ts +1 -1
- package/dist/hardware/detection.d.ts.map +1 -1
- package/dist/hardware/detection.js +54 -27
- package/dist/hardware/detection.js.map +1 -1
- package/dist/mediabunny/FFmpegAudioDecoder.d.ts +2 -16
- package/dist/mediabunny/FFmpegAudioDecoder.d.ts.map +1 -1
- package/dist/mediabunny/FFmpegAudioDecoder.js +59 -184
- package/dist/mediabunny/FFmpegAudioDecoder.js.map +1 -1
- package/dist/mediabunny/FFmpegAudioEncoder.d.ts +4 -38
- package/dist/mediabunny/FFmpegAudioEncoder.d.ts.map +1 -1
- package/dist/mediabunny/FFmpegAudioEncoder.js +64 -328
- package/dist/mediabunny/FFmpegAudioEncoder.js.map +1 -1
- package/dist/mediabunny/FFmpegVideoDecoder.d.ts +2 -36
- package/dist/mediabunny/FFmpegVideoDecoder.d.ts.map +1 -1
- package/dist/mediabunny/FFmpegVideoDecoder.js +37 -278
- package/dist/mediabunny/FFmpegVideoDecoder.js.map +1 -1
- package/dist/mediabunny/FFmpegVideoEncoder.d.ts +6 -35
- package/dist/mediabunny/FFmpegVideoEncoder.d.ts.map +1 -1
- package/dist/mediabunny/FFmpegVideoEncoder.js +46 -334
- package/dist/mediabunny/FFmpegVideoEncoder.js.map +1 -1
- package/dist/node-av/HardwarePipeline.d.ts +36 -0
- package/dist/node-av/HardwarePipeline.d.ts.map +1 -0
- package/dist/node-av/HardwarePipeline.js +243 -0
- package/dist/node-av/HardwarePipeline.js.map +1 -0
- package/dist/node-av/NodeAvAudioDecoder.d.ts +46 -0
- package/dist/node-av/NodeAvAudioDecoder.d.ts.map +1 -0
- package/dist/node-av/NodeAvAudioDecoder.js +343 -0
- package/dist/node-av/NodeAvAudioDecoder.js.map +1 -0
- package/dist/node-av/NodeAvAudioEncoder.d.ts +44 -0
- package/dist/node-av/NodeAvAudioEncoder.d.ts.map +1 -0
- package/dist/node-av/NodeAvAudioEncoder.js +385 -0
- package/dist/node-av/NodeAvAudioEncoder.js.map +1 -0
- package/dist/node-av/NodeAvImageDecoder.d.ts +95 -0
- package/dist/node-av/NodeAvImageDecoder.d.ts.map +1 -0
- package/dist/node-av/NodeAvImageDecoder.js +287 -0
- package/dist/node-av/NodeAvImageDecoder.js.map +1 -0
- package/dist/node-av/NodeAvVideoDecoder.d.ts +43 -0
- package/dist/node-av/NodeAvVideoDecoder.d.ts.map +1 -0
- package/dist/node-av/NodeAvVideoDecoder.js +361 -0
- package/dist/node-av/NodeAvVideoDecoder.js.map +1 -0
- package/dist/node-av/NodeAvVideoEncoder.d.ts +44 -0
- package/dist/node-av/NodeAvVideoEncoder.d.ts.map +1 -0
- package/dist/node-av/NodeAvVideoEncoder.js +397 -0
- package/dist/node-av/NodeAvVideoEncoder.js.map +1 -0
- package/dist/utils/event-target.d.ts +42 -0
- package/dist/utils/event-target.d.ts.map +1 -0
- package/dist/utils/event-target.js +96 -0
- package/dist/utils/event-target.js.map +1 -0
- package/dist/utils/index.d.ts +1 -0
- package/dist/utils/index.d.ts.map +1 -1
- package/dist/utils/index.js +2 -0
- package/dist/utils/index.js.map +1 -1
- package/package.json +14 -6
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* NodeAvAudioEncoder - Audio encoder using node-av native bindings
|
|
3
|
+
*
|
|
4
|
+
* Implements the AudioEncoderBackend interface for encoding audio samples
|
|
5
|
+
* using FFmpeg's libav* libraries via node-av.
|
|
6
|
+
*/
|
|
7
|
+
import { EventEmitter } from 'events';
|
|
8
|
+
import type { AudioEncoderBackend, AudioEncoderBackendConfig } from '../backends/types.js';
|
|
9
|
+
/**
|
|
10
|
+
* NodeAV-backed audio encoder implementing AudioEncoderBackend interface
|
|
11
|
+
*/
|
|
12
|
+
export declare class NodeAvAudioEncoder extends EventEmitter implements AudioEncoderBackend {
|
|
13
|
+
private encoder;
|
|
14
|
+
private config;
|
|
15
|
+
private frameIndex;
|
|
16
|
+
private queue;
|
|
17
|
+
private processing;
|
|
18
|
+
private processingPromise;
|
|
19
|
+
private shuttingDown;
|
|
20
|
+
private sampleFormat;
|
|
21
|
+
private encoderSampleFormat;
|
|
22
|
+
private timeBase;
|
|
23
|
+
private codecDescription;
|
|
24
|
+
private firstFrame;
|
|
25
|
+
get isHealthy(): boolean;
|
|
26
|
+
startEncoder(config: AudioEncoderBackendConfig): void;
|
|
27
|
+
write(data: Buffer | Uint8Array): boolean;
|
|
28
|
+
end(): void;
|
|
29
|
+
kill(): void;
|
|
30
|
+
shutdown(): Promise<void>;
|
|
31
|
+
private processQueue;
|
|
32
|
+
private ensureEncoder;
|
|
33
|
+
private extractCodecDescription;
|
|
34
|
+
private getEncoderCodec;
|
|
35
|
+
private buildEncoderOptions;
|
|
36
|
+
private getChannelLayout;
|
|
37
|
+
private encodeBuffer;
|
|
38
|
+
private convertToPlanar;
|
|
39
|
+
private convertToS16Interleaved;
|
|
40
|
+
private convertToS16Planar;
|
|
41
|
+
private finish;
|
|
42
|
+
private cleanup;
|
|
43
|
+
}
|
|
44
|
+
//# sourceMappingURL=NodeAvAudioEncoder.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"NodeAvAudioEncoder.d.ts","sourceRoot":"","sources":["../../src/node-av/NodeAvAudioEncoder.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,YAAY,EAAE,MAAM,QAAQ,CAAC;AAmBtC,OAAO,KAAK,EACV,mBAAmB,EACnB,yBAAyB,EAE1B,MAAM,sBAAsB,CAAC;AAQ9B;;GAEG;AACH,qBAAa,kBAAmB,SAAQ,YAAa,YAAW,mBAAmB;IACjF,OAAO,CAAC,OAAO,CAAwB;IACvC,OAAO,CAAC,MAAM,CAA0C;IACxD,OAAO,CAAC,UAAU,CAAK;IACvB,OAAO,CAAC,KAAK,CAAgB;IAC7B,OAAO,CAAC,UAAU,CAAS;IAC3B,OAAO,CAAC,iBAAiB,CAA8B;IACvD,OAAO,CAAC,YAAY,CAAS;IAC7B,OAAO,CAAC,YAAY,CAAqC;IACzD,OAAO,CAAC,mBAAmB,CAAsC;IACjE,OAAO,CAAC,QAAQ,CAA+C;IAC/D,OAAO,CAAC,gBAAgB,CAAuB;IAC/C,OAAO,CAAC,UAAU,CAAQ;IAE1B,IAAI,SAAS,IAAI,OAAO,CAEvB;IAED,YAAY,CAAC,MAAM,EAAE,yBAAyB,GAAG,IAAI;IAOrD,KAAK,CAAC,IAAI,EAAE,MAAM,GAAG,UAAU,GAAG,OAAO;IAUzC,GAAG,IAAI,IAAI;IAMX,IAAI,IAAI,IAAI;IAMN,QAAQ,IAAI,OAAO,CAAC,IAAI,CAAC;YAIjB,YAAY;YA2BZ,aAAa;IAmB3B,OAAO,CAAC,uBAAuB;IAiC/B,OAAO,CAAC,eAAe;IAwBvB,OAAO,CAAC,mBAAmB;IA2D3B,OAAO,CAAC,gBAAgB;YAiBV,YAAY;IA8E1B,OAAO,CAAC,eAAe;IAmBvB,OAAO,CAAC,uBAAuB;IAgB/B,OAAO,CAAC,kBAAkB;YAqBZ,MAAM;IAsCpB,OAAO,CAAC,OAAO;CAKhB"}
|
|
@@ -0,0 +1,385 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* NodeAvAudioEncoder - Audio encoder using node-av native bindings
|
|
3
|
+
*
|
|
4
|
+
* Implements the AudioEncoderBackend interface for encoding audio samples
|
|
5
|
+
* using FFmpeg's libav* libraries via node-av.
|
|
6
|
+
*/
|
|
7
|
+
import { EventEmitter } from 'events';
|
|
8
|
+
import { Encoder } from 'node-av/api';
|
|
9
|
+
import { Frame, Rational } from 'node-av/lib';
|
|
10
|
+
import { AV_SAMPLE_FMT_FLTP, AV_SAMPLE_FMT_S16P, AV_SAMPLE_FMT_S16, AV_SAMPLE_FMT_FLT, AV_PKT_FLAG_KEY, AV_CHANNEL_ORDER_NATIVE, AV_CH_LAYOUT_MONO, AV_CH_LAYOUT_STEREO, AV_CH_LAYOUT_5POINT1, AV_CH_LAYOUT_7POINT1, } from 'node-av/constants';
|
|
11
|
+
import { createLogger } from '../utils/logger.js';
|
|
12
|
+
const logger = createLogger('NodeAvAudioEncoder');
|
|
13
|
+
/** Default sample rate for Opus codec */
|
|
14
|
+
const OPUS_SAMPLE_RATE = 48000;
|
|
15
|
+
/**
|
|
16
|
+
* NodeAV-backed audio encoder implementing AudioEncoderBackend interface
|
|
17
|
+
*/
|
|
18
|
+
export class NodeAvAudioEncoder extends EventEmitter {
|
|
19
|
+
encoder = null;
|
|
20
|
+
config = null;
|
|
21
|
+
frameIndex = 0;
|
|
22
|
+
queue = [];
|
|
23
|
+
processing = false;
|
|
24
|
+
processingPromise = null;
|
|
25
|
+
shuttingDown = false;
|
|
26
|
+
sampleFormat = AV_SAMPLE_FMT_FLT;
|
|
27
|
+
encoderSampleFormat = AV_SAMPLE_FMT_FLTP;
|
|
28
|
+
timeBase = new Rational(1, OPUS_SAMPLE_RATE);
|
|
29
|
+
codecDescription = null;
|
|
30
|
+
firstFrame = true;
|
|
31
|
+
get isHealthy() {
|
|
32
|
+
return !this.shuttingDown;
|
|
33
|
+
}
|
|
34
|
+
startEncoder(config) {
|
|
35
|
+
this.config = { ...config };
|
|
36
|
+
this.timeBase = new Rational(1, config.sampleRate);
|
|
37
|
+
// Input is always float32 interleaved from AudioData conversion
|
|
38
|
+
this.sampleFormat = AV_SAMPLE_FMT_FLT;
|
|
39
|
+
}
|
|
40
|
+
write(data) {
|
|
41
|
+
if (!this.config || this.shuttingDown) {
|
|
42
|
+
return false;
|
|
43
|
+
}
|
|
44
|
+
this.queue.push(Buffer.from(data));
|
|
45
|
+
void this.processQueue();
|
|
46
|
+
return true;
|
|
47
|
+
}
|
|
48
|
+
end() {
|
|
49
|
+
if (this.shuttingDown)
|
|
50
|
+
return;
|
|
51
|
+
this.shuttingDown = true;
|
|
52
|
+
void this.finish().catch((err) => this.emit('error', err));
|
|
53
|
+
}
|
|
54
|
+
kill() {
|
|
55
|
+
this.shuttingDown = true;
|
|
56
|
+
this.cleanup();
|
|
57
|
+
this.emit('close', null);
|
|
58
|
+
}
|
|
59
|
+
async shutdown() {
|
|
60
|
+
this.end();
|
|
61
|
+
}
|
|
62
|
+
async processQueue() {
|
|
63
|
+
if (this.processingPromise) {
|
|
64
|
+
return this.processingPromise;
|
|
65
|
+
}
|
|
66
|
+
this.processingPromise = (async () => {
|
|
67
|
+
if (this.processing)
|
|
68
|
+
return;
|
|
69
|
+
this.processing = true;
|
|
70
|
+
try {
|
|
71
|
+
while (this.queue.length > 0) {
|
|
72
|
+
const data = this.queue.shift();
|
|
73
|
+
// Emit frameAccepted when frame starts processing (for dequeue event)
|
|
74
|
+
setImmediate(() => this.emit('frameAccepted'));
|
|
75
|
+
await this.encodeBuffer(data);
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
catch (err) {
|
|
79
|
+
this.emit('error', err instanceof Error ? err : new Error(String(err)));
|
|
80
|
+
}
|
|
81
|
+
finally {
|
|
82
|
+
this.processing = false;
|
|
83
|
+
this.processingPromise = null;
|
|
84
|
+
}
|
|
85
|
+
})();
|
|
86
|
+
return this.processingPromise;
|
|
87
|
+
}
|
|
88
|
+
async ensureEncoder() {
|
|
89
|
+
if (this.encoder || !this.config) {
|
|
90
|
+
return;
|
|
91
|
+
}
|
|
92
|
+
const encoderCodec = this.getEncoderCodec(this.config.codec);
|
|
93
|
+
const options = this.buildEncoderOptions();
|
|
94
|
+
// Store the encoder's required sample format
|
|
95
|
+
this.encoderSampleFormat = options.sampleFormat;
|
|
96
|
+
logger.info(`Using encoder: ${encoderCodec}, format: ${options.sampleFormat}`);
|
|
97
|
+
this.encoder = await Encoder.create(encoderCodec, options);
|
|
98
|
+
// Extract codec description (extradata) for codecs that require it
|
|
99
|
+
this.extractCodecDescription();
|
|
100
|
+
}
|
|
101
|
+
extractCodecDescription() {
|
|
102
|
+
if (!this.encoder || !this.config)
|
|
103
|
+
return;
|
|
104
|
+
if (this.codecDescription)
|
|
105
|
+
return; // Already extracted
|
|
106
|
+
const codecBase = this.config.codec.split('.')[0].toLowerCase();
|
|
107
|
+
try {
|
|
108
|
+
const ctx = this.encoder.getCodecContext();
|
|
109
|
+
if (!ctx)
|
|
110
|
+
return;
|
|
111
|
+
const extraData = ctx.extraData;
|
|
112
|
+
if (!extraData || extraData.length === 0)
|
|
113
|
+
return;
|
|
114
|
+
if (codecBase === 'flac') {
|
|
115
|
+
// FLAC description: 'fLaC' magic + STREAMINFO block
|
|
116
|
+
// The extradata from FFmpeg is just the STREAMINFO, we need to prepend magic
|
|
117
|
+
const magic = Buffer.from('fLaC');
|
|
118
|
+
// STREAMINFO block header: type (0x00 for STREAMINFO) | last-block flag (0x80 if last)
|
|
119
|
+
// followed by 3-byte length
|
|
120
|
+
const blockHeader = Buffer.from([0x80, 0x00, 0x00, extraData.length]);
|
|
121
|
+
this.codecDescription = Buffer.concat([magic, blockHeader, extraData]);
|
|
122
|
+
logger.debug(`FLAC description: ${this.codecDescription.length} bytes`);
|
|
123
|
+
}
|
|
124
|
+
else if (codecBase === 'vorbis') {
|
|
125
|
+
// Vorbis description is the identification + comment + setup headers
|
|
126
|
+
// The extradata from FFmpeg should contain all three headers
|
|
127
|
+
this.codecDescription = Buffer.from(extraData);
|
|
128
|
+
logger.debug(`Vorbis description: ${this.codecDescription.length} bytes`);
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
catch (err) {
|
|
132
|
+
logger.debug(`Failed to extract codec description: ${err}`);
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
getEncoderCodec(codec) {
|
|
136
|
+
const codecBase = codec.split('.')[0].toLowerCase();
|
|
137
|
+
switch (codecBase) {
|
|
138
|
+
case 'opus':
|
|
139
|
+
return 'libopus';
|
|
140
|
+
case 'mp3':
|
|
141
|
+
return 'libmp3lame';
|
|
142
|
+
case 'flac':
|
|
143
|
+
return 'flac';
|
|
144
|
+
case 'mp4a':
|
|
145
|
+
case 'aac':
|
|
146
|
+
return 'aac';
|
|
147
|
+
case 'vorbis':
|
|
148
|
+
return 'libvorbis';
|
|
149
|
+
case 'pcm-s16':
|
|
150
|
+
return 'pcm_s16le';
|
|
151
|
+
case 'pcm-f32':
|
|
152
|
+
return 'pcm_f32le';
|
|
153
|
+
default:
|
|
154
|
+
return 'aac';
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
buildEncoderOptions() {
|
|
158
|
+
if (!this.config) {
|
|
159
|
+
throw new Error('Config not set');
|
|
160
|
+
}
|
|
161
|
+
const codecBase = this.config.codec.split('.')[0].toLowerCase();
|
|
162
|
+
const isOpus = codecBase === 'opus';
|
|
163
|
+
const isVorbis = codecBase === 'vorbis';
|
|
164
|
+
const isFlac = codecBase === 'flac';
|
|
165
|
+
const isRealtime = this.config.latencyMode === 'realtime';
|
|
166
|
+
// Determine output sample format based on codec requirements
|
|
167
|
+
// Each codec has specific format requirements:
|
|
168
|
+
// - libopus: s16 or flt (interleaved only)
|
|
169
|
+
// - libvorbis: fltp (planar float)
|
|
170
|
+
// - aac: fltp (planar float)
|
|
171
|
+
// - flac: s16, s32 (interleaved signed)
|
|
172
|
+
let sampleFormat;
|
|
173
|
+
if (isOpus) {
|
|
174
|
+
// libopus only supports s16 or flt (interleaved)
|
|
175
|
+
sampleFormat = AV_SAMPLE_FMT_FLT;
|
|
176
|
+
}
|
|
177
|
+
else if (isVorbis) {
|
|
178
|
+
sampleFormat = AV_SAMPLE_FMT_FLTP;
|
|
179
|
+
}
|
|
180
|
+
else if (isFlac || codecBase === 'pcm-s16') {
|
|
181
|
+
// flac encoder requires interleaved s16 or s32
|
|
182
|
+
sampleFormat = AV_SAMPLE_FMT_S16;
|
|
183
|
+
}
|
|
184
|
+
else {
|
|
185
|
+
// Most codecs work with float planar (aac, etc.)
|
|
186
|
+
sampleFormat = AV_SAMPLE_FMT_FLTP;
|
|
187
|
+
}
|
|
188
|
+
const options = {};
|
|
189
|
+
// Codec-specific options
|
|
190
|
+
if (isOpus) {
|
|
191
|
+
options.application = isRealtime ? 'voip' : 'audio';
|
|
192
|
+
if (isRealtime) {
|
|
193
|
+
options.frame_duration = '10';
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
// Frame size configuration for specific codecs
|
|
197
|
+
if (isFlac) {
|
|
198
|
+
// FLAC default block size is 4608 samples, which is too large for small inputs
|
|
199
|
+
// Use a smaller frame size to allow encoding of smaller buffers
|
|
200
|
+
options.frame_size = '1024';
|
|
201
|
+
}
|
|
202
|
+
return {
|
|
203
|
+
type: 'audio',
|
|
204
|
+
sampleRate: isOpus ? OPUS_SAMPLE_RATE : this.config.sampleRate,
|
|
205
|
+
channelLayout: this.getChannelLayout(this.config.numberOfChannels),
|
|
206
|
+
sampleFormat,
|
|
207
|
+
timeBase: this.timeBase,
|
|
208
|
+
bitrate: this.config.bitrate,
|
|
209
|
+
options,
|
|
210
|
+
};
|
|
211
|
+
}
|
|
212
|
+
getChannelLayout(numChannels) {
|
|
213
|
+
// Standard channel layouts as ChannelLayout objects
|
|
214
|
+
// Order 1 = AV_CHANNEL_ORDER_NATIVE (required for FFmpeg)
|
|
215
|
+
switch (numChannels) {
|
|
216
|
+
case 1:
|
|
217
|
+
return { nbChannels: 1, order: AV_CHANNEL_ORDER_NATIVE, mask: AV_CH_LAYOUT_MONO };
|
|
218
|
+
case 2:
|
|
219
|
+
return { nbChannels: 2, order: AV_CHANNEL_ORDER_NATIVE, mask: AV_CH_LAYOUT_STEREO };
|
|
220
|
+
case 6:
|
|
221
|
+
return { nbChannels: 6, order: AV_CHANNEL_ORDER_NATIVE, mask: AV_CH_LAYOUT_5POINT1 };
|
|
222
|
+
case 8:
|
|
223
|
+
return { nbChannels: 8, order: AV_CHANNEL_ORDER_NATIVE, mask: AV_CH_LAYOUT_7POINT1 };
|
|
224
|
+
default:
|
|
225
|
+
return { nbChannels: numChannels, order: AV_CHANNEL_ORDER_NATIVE, mask: BigInt((1 << numChannels) - 1) };
|
|
226
|
+
}
|
|
227
|
+
}
|
|
228
|
+
async encodeBuffer(buffer) {
|
|
229
|
+
await this.ensureEncoder();
|
|
230
|
+
if (!this.encoder || !this.config) {
|
|
231
|
+
throw new Error('Encoder not initialized');
|
|
232
|
+
}
|
|
233
|
+
// Buffer is f32le interleaved, we need to convert to the encoder's expected format
|
|
234
|
+
// Calculate number of samples (each sample is 4 bytes for f32)
|
|
235
|
+
const bytesPerSample = 4;
|
|
236
|
+
const totalSamples = buffer.length / bytesPerSample;
|
|
237
|
+
const samplesPerChannel = Math.floor(totalSamples / this.config.numberOfChannels);
|
|
238
|
+
if (samplesPerChannel === 0) {
|
|
239
|
+
return;
|
|
240
|
+
}
|
|
241
|
+
// Prepare audio data based on encoder's expected format
|
|
242
|
+
let audioData;
|
|
243
|
+
let frameFormat;
|
|
244
|
+
if (this.encoderSampleFormat === AV_SAMPLE_FMT_FLT) {
|
|
245
|
+
// Encoder needs interleaved float - use input buffer directly
|
|
246
|
+
audioData = buffer;
|
|
247
|
+
frameFormat = AV_SAMPLE_FMT_FLT;
|
|
248
|
+
}
|
|
249
|
+
else if (this.encoderSampleFormat === AV_SAMPLE_FMT_S16) {
|
|
250
|
+
// Encoder needs interleaved s16 - convert from f32 interleaved to s16 interleaved
|
|
251
|
+
audioData = Buffer.from(this.convertToS16Interleaved(buffer, samplesPerChannel, this.config.numberOfChannels));
|
|
252
|
+
frameFormat = AV_SAMPLE_FMT_S16;
|
|
253
|
+
}
|
|
254
|
+
else if (this.encoderSampleFormat === AV_SAMPLE_FMT_S16P) {
|
|
255
|
+
// Encoder needs planar s16 - convert from f32 interleaved to s16 planar
|
|
256
|
+
audioData = Buffer.from(this.convertToS16Planar(buffer, samplesPerChannel, this.config.numberOfChannels));
|
|
257
|
+
frameFormat = AV_SAMPLE_FMT_S16P;
|
|
258
|
+
}
|
|
259
|
+
else {
|
|
260
|
+
// Default: encoder needs planar float - convert from f32 interleaved to f32 planar
|
|
261
|
+
audioData = Buffer.from(this.convertToPlanar(buffer, samplesPerChannel, this.config.numberOfChannels));
|
|
262
|
+
frameFormat = AV_SAMPLE_FMT_FLTP;
|
|
263
|
+
}
|
|
264
|
+
const frame = Frame.fromAudioBuffer(audioData, {
|
|
265
|
+
sampleRate: this.config.sampleRate,
|
|
266
|
+
channelLayout: this.getChannelLayout(this.config.numberOfChannels),
|
|
267
|
+
format: frameFormat,
|
|
268
|
+
nbSamples: samplesPerChannel,
|
|
269
|
+
timeBase: this.timeBase,
|
|
270
|
+
});
|
|
271
|
+
frame.pts = BigInt(this.frameIndex);
|
|
272
|
+
await this.encoder.encode(frame);
|
|
273
|
+
frame.unref();
|
|
274
|
+
// Try to extract codec description after first encode (some codecs like FLAC
|
|
275
|
+
// don't populate extradata until after encoding starts)
|
|
276
|
+
this.extractCodecDescription();
|
|
277
|
+
let packet = await this.encoder.receive();
|
|
278
|
+
while (packet) {
|
|
279
|
+
if (packet.data) {
|
|
280
|
+
const timestamp = packet.pts !== undefined ? Number(packet.pts) : this.frameIndex;
|
|
281
|
+
const keyFrame = (packet.flags & AV_PKT_FLAG_KEY) === AV_PKT_FLAG_KEY || packet.isKeyframe;
|
|
282
|
+
const frameData = {
|
|
283
|
+
data: Buffer.from(packet.data),
|
|
284
|
+
timestamp,
|
|
285
|
+
keyFrame,
|
|
286
|
+
};
|
|
287
|
+
// Include codec description on the first frame
|
|
288
|
+
if (this.firstFrame && this.codecDescription) {
|
|
289
|
+
frameData.description = this.codecDescription;
|
|
290
|
+
this.firstFrame = false;
|
|
291
|
+
}
|
|
292
|
+
this.emit('encodedFrame', frameData);
|
|
293
|
+
}
|
|
294
|
+
packet.unref();
|
|
295
|
+
packet = await this.encoder.receive();
|
|
296
|
+
}
|
|
297
|
+
this.frameIndex += samplesPerChannel;
|
|
298
|
+
}
|
|
299
|
+
convertToPlanar(data, samplesPerChannel, numChannels) {
|
|
300
|
+
const bytesPerSample = 4; // f32
|
|
301
|
+
const planeSize = samplesPerChannel * bytesPerSample;
|
|
302
|
+
const result = new Uint8Array(planeSize * numChannels);
|
|
303
|
+
const input = new Float32Array(data.buffer, data.byteOffset, data.byteLength / 4);
|
|
304
|
+
const output = new Float32Array(result.buffer);
|
|
305
|
+
for (let s = 0; s < samplesPerChannel; s++) {
|
|
306
|
+
for (let ch = 0; ch < numChannels; ch++) {
|
|
307
|
+
const srcIdx = s * numChannels + ch;
|
|
308
|
+
const dstIdx = ch * samplesPerChannel + s;
|
|
309
|
+
output[dstIdx] = input[srcIdx];
|
|
310
|
+
}
|
|
311
|
+
}
|
|
312
|
+
return result;
|
|
313
|
+
}
|
|
314
|
+
convertToS16Interleaved(data, samplesPerChannel, numChannels) {
|
|
315
|
+
const totalSamples = samplesPerChannel * numChannels;
|
|
316
|
+
const result = new Uint8Array(totalSamples * 2); // 2 bytes per s16 sample
|
|
317
|
+
const input = new Float32Array(data.buffer, data.byteOffset, data.byteLength / 4);
|
|
318
|
+
const output = new Int16Array(result.buffer);
|
|
319
|
+
for (let i = 0; i < totalSamples; i++) {
|
|
320
|
+
// Convert f32 [-1.0, 1.0] to s16 [-32768, 32767]
|
|
321
|
+
const clamped = Math.max(-1.0, Math.min(1.0, input[i]));
|
|
322
|
+
output[i] = Math.round(clamped * 32767);
|
|
323
|
+
}
|
|
324
|
+
return result;
|
|
325
|
+
}
|
|
326
|
+
convertToS16Planar(data, samplesPerChannel, numChannels) {
|
|
327
|
+
const bytesPerSample = 2; // s16
|
|
328
|
+
const planeSize = samplesPerChannel * bytesPerSample;
|
|
329
|
+
const result = new Uint8Array(planeSize * numChannels);
|
|
330
|
+
const input = new Float32Array(data.buffer, data.byteOffset, data.byteLength / 4);
|
|
331
|
+
const output = new Int16Array(result.buffer);
|
|
332
|
+
for (let s = 0; s < samplesPerChannel; s++) {
|
|
333
|
+
for (let ch = 0; ch < numChannels; ch++) {
|
|
334
|
+
const srcIdx = s * numChannels + ch;
|
|
335
|
+
const dstIdx = ch * samplesPerChannel + s;
|
|
336
|
+
// Convert f32 [-1.0, 1.0] to s16 [-32768, 32767]
|
|
337
|
+
const clamped = Math.max(-1.0, Math.min(1.0, input[srcIdx]));
|
|
338
|
+
output[dstIdx] = Math.round(clamped * 32767);
|
|
339
|
+
}
|
|
340
|
+
}
|
|
341
|
+
return result;
|
|
342
|
+
}
|
|
343
|
+
async finish() {
|
|
344
|
+
await this.processQueue();
|
|
345
|
+
if (this.processingPromise) {
|
|
346
|
+
await this.processingPromise;
|
|
347
|
+
}
|
|
348
|
+
if (this.encoder) {
|
|
349
|
+
try {
|
|
350
|
+
await this.encoder.flush();
|
|
351
|
+
let packet = await this.encoder.receive();
|
|
352
|
+
while (packet) {
|
|
353
|
+
if (packet.data) {
|
|
354
|
+
const timestamp = packet.pts !== undefined ? Number(packet.pts) : this.frameIndex;
|
|
355
|
+
const keyFrame = (packet.flags & AV_PKT_FLAG_KEY) === AV_PKT_FLAG_KEY || packet.isKeyframe;
|
|
356
|
+
const frameData = {
|
|
357
|
+
data: Buffer.from(packet.data),
|
|
358
|
+
timestamp,
|
|
359
|
+
keyFrame,
|
|
360
|
+
};
|
|
361
|
+
// Include codec description on the first frame
|
|
362
|
+
if (this.firstFrame && this.codecDescription) {
|
|
363
|
+
frameData.description = this.codecDescription;
|
|
364
|
+
this.firstFrame = false;
|
|
365
|
+
}
|
|
366
|
+
this.emit('encodedFrame', frameData);
|
|
367
|
+
}
|
|
368
|
+
packet.unref();
|
|
369
|
+
packet = await this.encoder.receive();
|
|
370
|
+
}
|
|
371
|
+
}
|
|
372
|
+
catch (err) {
|
|
373
|
+
this.emit('error', err instanceof Error ? err : new Error(String(err)));
|
|
374
|
+
}
|
|
375
|
+
}
|
|
376
|
+
this.emit('close', 0);
|
|
377
|
+
this.cleanup();
|
|
378
|
+
}
|
|
379
|
+
cleanup() {
|
|
380
|
+
this.encoder?.close();
|
|
381
|
+
this.encoder = null;
|
|
382
|
+
this.queue = [];
|
|
383
|
+
}
|
|
384
|
+
}
|
|
385
|
+
//# sourceMappingURL=NodeAvAudioEncoder.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"NodeAvAudioEncoder.js","sourceRoot":"","sources":["../../src/node-av/NodeAvAudioEncoder.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* NodeAvImageDecoder - Node-av based image decoder
|
|
3
|
+
*
|
|
4
|
+
* Decodes still images and animated images (GIF, APNG, WebP) using node-av
|
|
5
|
+
* native bindings instead of spawning FFmpeg CLI processes.
|
|
6
|
+
*/
|
|
7
|
+
import type { VideoColorSpaceInit } from '../formats/index.js';
|
|
8
|
+
export interface DecodedImageFrame {
|
|
9
|
+
data: Uint8Array;
|
|
10
|
+
width: number;
|
|
11
|
+
height: number;
|
|
12
|
+
timestamp: number;
|
|
13
|
+
duration: number;
|
|
14
|
+
complete: boolean;
|
|
15
|
+
colorSpace?: VideoColorSpaceInit;
|
|
16
|
+
}
|
|
17
|
+
export interface ImageDecoderConfig {
|
|
18
|
+
mimeType: string;
|
|
19
|
+
data: Uint8Array;
|
|
20
|
+
desiredWidth?: number;
|
|
21
|
+
desiredHeight?: number;
|
|
22
|
+
colorSpace?: VideoColorSpaceInit;
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Decode images using node-av native bindings
|
|
26
|
+
*/
|
|
27
|
+
export declare class NodeAvImageDecoder {
|
|
28
|
+
private decoder;
|
|
29
|
+
private formatContext;
|
|
30
|
+
private stream;
|
|
31
|
+
private filter;
|
|
32
|
+
private config;
|
|
33
|
+
private frames;
|
|
34
|
+
private closed;
|
|
35
|
+
private static readonly DUMMY_TIME_BASE;
|
|
36
|
+
private static readonly DEFAULT_FRAME_DURATION;
|
|
37
|
+
constructor(config: ImageDecoderConfig);
|
|
38
|
+
/**
|
|
39
|
+
* Decode all frames from the image data
|
|
40
|
+
*/
|
|
41
|
+
decode(): Promise<DecodedImageFrame[]>;
|
|
42
|
+
/**
|
|
43
|
+
* Get the codec ID for the MIME type
|
|
44
|
+
*/
|
|
45
|
+
private getCodecId;
|
|
46
|
+
/**
|
|
47
|
+
* Initialize the decoder with the given codec
|
|
48
|
+
*/
|
|
49
|
+
private initializeDecoder;
|
|
50
|
+
/**
|
|
51
|
+
* Decode the image data
|
|
52
|
+
*/
|
|
53
|
+
private decodeData;
|
|
54
|
+
/**
|
|
55
|
+
* Check if this is an animated format
|
|
56
|
+
*/
|
|
57
|
+
private isAnimatedFormat;
|
|
58
|
+
/**
|
|
59
|
+
* Send a packet to the decoder
|
|
60
|
+
*/
|
|
61
|
+
private sendPacket;
|
|
62
|
+
/**
|
|
63
|
+
* Drain decoded frames from the decoder
|
|
64
|
+
*/
|
|
65
|
+
private drainFrames;
|
|
66
|
+
/**
|
|
67
|
+
* Convert a decoded frame to RGBA
|
|
68
|
+
*/
|
|
69
|
+
private convertFrame;
|
|
70
|
+
/**
|
|
71
|
+
* Flush the decoder to get any remaining frames
|
|
72
|
+
*/
|
|
73
|
+
private flush;
|
|
74
|
+
/**
|
|
75
|
+
* Clean up resources
|
|
76
|
+
*/
|
|
77
|
+
private cleanup;
|
|
78
|
+
/**
|
|
79
|
+
* Close the decoder
|
|
80
|
+
*/
|
|
81
|
+
close(): void;
|
|
82
|
+
/**
|
|
83
|
+
* Check if a MIME type is supported
|
|
84
|
+
*/
|
|
85
|
+
static isTypeSupported(mimeType: string): boolean;
|
|
86
|
+
}
|
|
87
|
+
/**
|
|
88
|
+
* Probe image dimensions using node-av
|
|
89
|
+
* Returns { width, height } or { width: 0, height: 0 } if probing fails
|
|
90
|
+
*/
|
|
91
|
+
export declare function probeImageDimensions(data: Uint8Array, mimeType: string): Promise<{
|
|
92
|
+
width: number;
|
|
93
|
+
height: number;
|
|
94
|
+
}>;
|
|
95
|
+
//# sourceMappingURL=NodeAvImageDecoder.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"NodeAvImageDecoder.d.ts","sourceRoot":"","sources":["../../src/node-av/NodeAvImageDecoder.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAgBH,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,qBAAqB,CAAC;AAE/D,MAAM,WAAW,iBAAiB;IAChC,IAAI,EAAE,UAAU,CAAC;IACjB,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,OAAO,CAAC;IAClB,UAAU,CAAC,EAAE,mBAAmB,CAAC;CAClC;AAED,MAAM,WAAW,kBAAkB;IACjC,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,EAAE,UAAU,CAAC;IACjB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,UAAU,CAAC,EAAE,mBAAmB,CAAC;CAClC;AAeD;;GAEG;AACH,qBAAa,kBAAkB;IAC7B,OAAO,CAAC,OAAO,CAAwB;IACvC,OAAO,CAAC,aAAa,CAA8B;IACnD,OAAO,CAAC,MAAM,CAAuB;IACrC,OAAO,CAAC,MAAM,CAA0B;IACxC,OAAO,CAAC,MAAM,CAAqB;IACnC,OAAO,CAAC,MAAM,CAA2B;IACzC,OAAO,CAAC,MAAM,CAAS;IAGvB,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,eAAe,CAAuB;IAC9D,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,sBAAsB,CAAU;gBAE5C,MAAM,EAAE,kBAAkB;IAItC;;OAEG;IACG,MAAM,IAAI,OAAO,CAAC,iBAAiB,EAAE,CAAC;IAqB5C;;OAEG;IACH,OAAO,CAAC,UAAU;IAIlB;;OAEG;YACW,iBAAiB;IAkB/B;;OAEG;YACW,UAAU;IAoBxB;;OAEG;IACH,OAAO,CAAC,gBAAgB;IAKxB;;OAEG;YACW,UAAU;IAgBxB;;OAEG;YACW,WAAW;IAgBzB;;OAEG;YACW,YAAY;IAwD1B;;OAEG;YACW,KAAK;IAWnB;;OAEG;IACH,OAAO,CAAC,OAAO;IASf;;OAEG;IACH,KAAK,IAAI,IAAI;IAOb;;OAEG;IACH,MAAM,CAAC,eAAe,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO;CAGlD;AAED;;;GAGG;AACH,wBAAsB,oBAAoB,CACxC,IAAI,EAAE,UAAU,EAChB,QAAQ,EAAE,MAAM,GACf,OAAO,CAAC;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC,CAoD5C"}
|