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.
Files changed (121) hide show
  1. package/README.md +4 -0
  2. package/dist/__tests__/AudioDecoder.test.js +3 -3
  3. package/dist/__tests__/AudioDecoder.test.js.map +1 -1
  4. package/dist/__tests__/ImageDecoder.wpt.test.d.ts +8 -0
  5. package/dist/__tests__/ImageDecoder.wpt.test.d.ts.map +1 -0
  6. package/dist/__tests__/ImageDecoder.wpt.test.js +135 -0
  7. package/dist/__tests__/ImageDecoder.wpt.test.js.map +1 -0
  8. package/dist/__tests__/NodeAvDecoder.test.d.ts +2 -0
  9. package/dist/__tests__/NodeAvDecoder.test.d.ts.map +1 -0
  10. package/dist/__tests__/NodeAvDecoder.test.js +199 -0
  11. package/dist/__tests__/NodeAvDecoder.test.js.map +1 -0
  12. package/dist/__tests__/NodeAvEncoder.test.d.ts +2 -0
  13. package/dist/__tests__/NodeAvEncoder.test.d.ts.map +1 -0
  14. package/dist/__tests__/NodeAvEncoder.test.js +176 -0
  15. package/dist/__tests__/NodeAvEncoder.test.js.map +1 -0
  16. package/dist/__tests__/VideoFrame.test.js.map +1 -1
  17. package/dist/backends/index.d.ts +3 -0
  18. package/dist/backends/index.d.ts.map +1 -0
  19. package/dist/backends/index.js +2 -0
  20. package/dist/backends/index.js.map +1 -0
  21. package/dist/backends/types.d.ts +165 -0
  22. package/dist/backends/types.d.ts.map +1 -0
  23. package/dist/backends/types.js +25 -0
  24. package/dist/backends/types.js.map +1 -0
  25. package/dist/core/AudioData.d.ts +1 -1
  26. package/dist/core/AudioData.d.ts.map +1 -1
  27. package/dist/core/AudioData.js +13 -9
  28. package/dist/core/AudioData.js.map +1 -1
  29. package/dist/core/VideoFrame.d.ts +25 -10
  30. package/dist/core/VideoFrame.d.ts.map +1 -1
  31. package/dist/core/VideoFrame.js +115 -65
  32. package/dist/core/VideoFrame.js.map +1 -1
  33. package/dist/decoders/AudioDecoder.d.ts +6 -12
  34. package/dist/decoders/AudioDecoder.d.ts.map +1 -1
  35. package/dist/decoders/AudioDecoder.js +57 -147
  36. package/dist/decoders/AudioDecoder.js.map +1 -1
  37. package/dist/decoders/ImageDecoder.d.ts +1 -0
  38. package/dist/decoders/ImageDecoder.d.ts.map +1 -1
  39. package/dist/decoders/ImageDecoder.js +59 -0
  40. package/dist/decoders/ImageDecoder.js.map +1 -1
  41. package/dist/decoders/VideoDecoder.d.ts +6 -13
  42. package/dist/decoders/VideoDecoder.d.ts.map +1 -1
  43. package/dist/decoders/VideoDecoder.js +49 -130
  44. package/dist/decoders/VideoDecoder.js.map +1 -1
  45. package/dist/demos/demo-conversion.js +2 -2
  46. package/dist/demos/demo-conversion.js.map +1 -1
  47. package/dist/demos/demo-four-corners.d.ts +6 -0
  48. package/dist/demos/demo-four-corners.d.ts.map +1 -0
  49. package/dist/demos/demo-four-corners.js +218 -0
  50. package/dist/demos/demo-four-corners.js.map +1 -0
  51. package/dist/demos/demo-samples.js +228 -64
  52. package/dist/demos/demo-samples.js.map +1 -1
  53. package/dist/encoders/AudioEncoder.d.ts +6 -13
  54. package/dist/encoders/AudioEncoder.d.ts.map +1 -1
  55. package/dist/encoders/AudioEncoder.js +81 -213
  56. package/dist/encoders/AudioEncoder.js.map +1 -1
  57. package/dist/encoders/VideoEncoder.d.ts +5 -14
  58. package/dist/encoders/VideoEncoder.d.ts.map +1 -1
  59. package/dist/encoders/VideoEncoder.js +39 -159
  60. package/dist/encoders/VideoEncoder.js.map +1 -1
  61. package/dist/formats/conversions/frame-converter.d.ts +17 -0
  62. package/dist/formats/conversions/frame-converter.d.ts.map +1 -1
  63. package/dist/formats/conversions/frame-converter.js +127 -0
  64. package/dist/formats/conversions/frame-converter.js.map +1 -1
  65. package/dist/formats/conversions/index.d.ts +1 -0
  66. package/dist/formats/conversions/index.d.ts.map +1 -1
  67. package/dist/formats/conversions/index.js +2 -0
  68. package/dist/formats/conversions/index.js.map +1 -1
  69. package/dist/hardware/detection.d.ts +1 -1
  70. package/dist/hardware/detection.d.ts.map +1 -1
  71. package/dist/hardware/detection.js +54 -27
  72. package/dist/hardware/detection.js.map +1 -1
  73. package/dist/mediabunny/FFmpegAudioDecoder.d.ts +2 -16
  74. package/dist/mediabunny/FFmpegAudioDecoder.d.ts.map +1 -1
  75. package/dist/mediabunny/FFmpegAudioDecoder.js +59 -184
  76. package/dist/mediabunny/FFmpegAudioDecoder.js.map +1 -1
  77. package/dist/mediabunny/FFmpegAudioEncoder.d.ts +4 -38
  78. package/dist/mediabunny/FFmpegAudioEncoder.d.ts.map +1 -1
  79. package/dist/mediabunny/FFmpegAudioEncoder.js +64 -328
  80. package/dist/mediabunny/FFmpegAudioEncoder.js.map +1 -1
  81. package/dist/mediabunny/FFmpegVideoDecoder.d.ts +2 -36
  82. package/dist/mediabunny/FFmpegVideoDecoder.d.ts.map +1 -1
  83. package/dist/mediabunny/FFmpegVideoDecoder.js +37 -278
  84. package/dist/mediabunny/FFmpegVideoDecoder.js.map +1 -1
  85. package/dist/mediabunny/FFmpegVideoEncoder.d.ts +6 -35
  86. package/dist/mediabunny/FFmpegVideoEncoder.d.ts.map +1 -1
  87. package/dist/mediabunny/FFmpegVideoEncoder.js +46 -334
  88. package/dist/mediabunny/FFmpegVideoEncoder.js.map +1 -1
  89. package/dist/node-av/HardwarePipeline.d.ts +36 -0
  90. package/dist/node-av/HardwarePipeline.d.ts.map +1 -0
  91. package/dist/node-av/HardwarePipeline.js +243 -0
  92. package/dist/node-av/HardwarePipeline.js.map +1 -0
  93. package/dist/node-av/NodeAvAudioDecoder.d.ts +46 -0
  94. package/dist/node-av/NodeAvAudioDecoder.d.ts.map +1 -0
  95. package/dist/node-av/NodeAvAudioDecoder.js +343 -0
  96. package/dist/node-av/NodeAvAudioDecoder.js.map +1 -0
  97. package/dist/node-av/NodeAvAudioEncoder.d.ts +44 -0
  98. package/dist/node-av/NodeAvAudioEncoder.d.ts.map +1 -0
  99. package/dist/node-av/NodeAvAudioEncoder.js +385 -0
  100. package/dist/node-av/NodeAvAudioEncoder.js.map +1 -0
  101. package/dist/node-av/NodeAvImageDecoder.d.ts +95 -0
  102. package/dist/node-av/NodeAvImageDecoder.d.ts.map +1 -0
  103. package/dist/node-av/NodeAvImageDecoder.js +287 -0
  104. package/dist/node-av/NodeAvImageDecoder.js.map +1 -0
  105. package/dist/node-av/NodeAvVideoDecoder.d.ts +43 -0
  106. package/dist/node-av/NodeAvVideoDecoder.d.ts.map +1 -0
  107. package/dist/node-av/NodeAvVideoDecoder.js +361 -0
  108. package/dist/node-av/NodeAvVideoDecoder.js.map +1 -0
  109. package/dist/node-av/NodeAvVideoEncoder.d.ts +44 -0
  110. package/dist/node-av/NodeAvVideoEncoder.d.ts.map +1 -0
  111. package/dist/node-av/NodeAvVideoEncoder.js +397 -0
  112. package/dist/node-av/NodeAvVideoEncoder.js.map +1 -0
  113. package/dist/utils/event-target.d.ts +42 -0
  114. package/dist/utils/event-target.d.ts.map +1 -0
  115. package/dist/utils/event-target.js +96 -0
  116. package/dist/utils/event-target.js.map +1 -0
  117. package/dist/utils/index.d.ts +1 -0
  118. package/dist/utils/index.d.ts.map +1 -1
  119. package/dist/utils/index.js +2 -0
  120. package/dist/utils/index.js.map +1 -1
  121. 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"}