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
|
@@ -1,21 +1,12 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* FFmpeg-backed VideoDecoder for Mediabunny
|
|
3
3
|
*
|
|
4
|
-
* Implements Mediabunny's CustomVideoDecoder interface using
|
|
4
|
+
* Implements Mediabunny's CustomVideoDecoder interface using node-av native bindings.
|
|
5
5
|
* Supports hardware acceleration via VAAPI, CUDA/CUVID, QSV.
|
|
6
6
|
*/
|
|
7
|
-
import { spawn } from 'child_process';
|
|
8
7
|
import { CustomVideoDecoder, VideoSample, } from 'mediabunny';
|
|
9
|
-
import {
|
|
10
|
-
//
|
|
11
|
-
const FORMAT_MAP = {
|
|
12
|
-
avc: 'h264',
|
|
13
|
-
hevc: 'hevc',
|
|
14
|
-
vp8: 'ivf',
|
|
15
|
-
vp9: 'ivf',
|
|
16
|
-
av1: 'ivf',
|
|
17
|
-
};
|
|
18
|
-
// Map Mediabunny codec to VideoCodecName
|
|
8
|
+
import { NodeAvVideoDecoder } from '../node-av/NodeAvVideoDecoder.js';
|
|
9
|
+
// Map Mediabunny codec to internal codec name
|
|
19
10
|
const CODEC_NAME_MAP = {
|
|
20
11
|
avc: 'h264',
|
|
21
12
|
hevc: 'hevc',
|
|
@@ -24,255 +15,70 @@ const CODEC_NAME_MAP = {
|
|
|
24
15
|
av1: 'av1',
|
|
25
16
|
};
|
|
26
17
|
export class FFmpegVideoDecoder extends CustomVideoDecoder {
|
|
27
|
-
|
|
28
|
-
accumulatedData = Buffer.alloc(0);
|
|
29
|
-
frameSize = 0;
|
|
18
|
+
backend = null;
|
|
30
19
|
frameIndex = 0;
|
|
31
|
-
ivfHeaderSent = false;
|
|
32
20
|
resolveFlush = null;
|
|
33
|
-
useIvf = false;
|
|
34
|
-
useAnnexB = false;
|
|
35
|
-
nalLengthSize = 4; // Default AVC NAL length size
|
|
36
|
-
spsNal = null;
|
|
37
|
-
ppsNal = null;
|
|
38
|
-
paramsSent = false;
|
|
39
21
|
// Track input packet timestamps for output frames
|
|
40
22
|
packetTimestamps = [];
|
|
41
23
|
packetDurations = [];
|
|
42
|
-
usingHardwareAcceleration = false;
|
|
43
|
-
hwaccelMethod = null;
|
|
44
24
|
static supports(codec, _config) {
|
|
45
|
-
return codec in
|
|
25
|
+
return codec in CODEC_NAME_MAP;
|
|
46
26
|
}
|
|
47
27
|
async init() {
|
|
48
|
-
const format = FORMAT_MAP[this.codec];
|
|
49
|
-
this.useIvf = format === 'ivf';
|
|
50
|
-
this.useAnnexB = format === 'h264' || format === 'hevc';
|
|
51
28
|
const width = this.config.codedWidth ?? 1920;
|
|
52
29
|
const height = this.config.codedHeight ?? 1080;
|
|
53
|
-
|
|
54
|
-
// Parse AVC decoder config to get SPS/PPS
|
|
55
|
-
if (this.useAnnexB && this.config.description) {
|
|
56
|
-
this.parseAvcDecoderConfig(this.config.description);
|
|
57
|
-
}
|
|
58
|
-
// Determine hardware acceleration preference from config
|
|
59
|
-
// Default to 'no-preference' which uses software for better compatibility
|
|
60
|
-
// Hardware decoding with pipe input can have issues with format conversion
|
|
30
|
+
// Hardware acceleration preference from config
|
|
61
31
|
const hwPref = this.config.hardwareAcceleration;
|
|
62
|
-
//
|
|
32
|
+
// Create node-av backend
|
|
33
|
+
this.backend = new NodeAvVideoDecoder();
|
|
63
34
|
const codecName = CODEC_NAME_MAP[this.codec];
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
this.usingHardwareAcceleration = best.isHardware;
|
|
70
|
-
this.hwaccelMethod = best.hwaccel;
|
|
71
|
-
if (best.isHardware) {
|
|
72
|
-
console.log(`[FFmpegVideoDecoder] Using hardware decoder: ${best.decoder || best.hwaccel}`);
|
|
73
|
-
}
|
|
35
|
+
// Convert description to Buffer if present
|
|
36
|
+
let description;
|
|
37
|
+
if (this.config.description) {
|
|
38
|
+
if (this.config.description instanceof ArrayBuffer) {
|
|
39
|
+
description = Buffer.from(this.config.description);
|
|
74
40
|
}
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
}
|
|
78
|
-
}
|
|
79
|
-
const args = [
|
|
80
|
-
'-hide_banner',
|
|
81
|
-
'-loglevel', 'error',
|
|
82
|
-
];
|
|
83
|
-
// Add hardware acceleration options
|
|
84
|
-
if (this.hwaccelMethod === 'vaapi') {
|
|
85
|
-
args.push('-hwaccel', 'vaapi');
|
|
86
|
-
args.push('-vaapi_device', '/dev/dri/renderD128');
|
|
87
|
-
}
|
|
88
|
-
else if (this.hwaccelMethod === 'cuda') {
|
|
89
|
-
args.push('-hwaccel', 'cuda');
|
|
90
|
-
if (hwDecoder) {
|
|
91
|
-
args.push('-c:v', hwDecoder);
|
|
41
|
+
else if (ArrayBuffer.isView(this.config.description)) {
|
|
42
|
+
description = Buffer.from(this.config.description.buffer, this.config.description.byteOffset, this.config.description.byteLength);
|
|
92
43
|
}
|
|
93
44
|
}
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
args.push('-f', format);
|
|
102
|
-
args.push('-i', 'pipe:0');
|
|
103
|
-
// Output raw video - need hwdownload for hardware frames
|
|
104
|
-
// VAAPI outputs nv12, so we need to download and convert to rgba
|
|
105
|
-
if (this.hwaccelMethod === 'vaapi') {
|
|
106
|
-
args.push('-vf', 'hwdownload,format=nv12,format=rgba');
|
|
107
|
-
}
|
|
108
|
-
else if (this.hwaccelMethod === 'cuda') {
|
|
109
|
-
args.push('-vf', 'hwdownload,format=nv12,format=rgba');
|
|
110
|
-
}
|
|
111
|
-
else if (this.hwaccelMethod === 'qsv') {
|
|
112
|
-
args.push('-vf', 'hwdownload,format=nv12,format=rgba');
|
|
113
|
-
}
|
|
114
|
-
args.push('-vsync', 'passthrough', '-f', 'rawvideo', '-pix_fmt', 'rgba', 'pipe:1');
|
|
115
|
-
this.process = spawn('ffmpeg', args, {
|
|
116
|
-
stdio: ['pipe', 'pipe', 'pipe'],
|
|
45
|
+
this.backend.startDecoder({
|
|
46
|
+
codec: codecName,
|
|
47
|
+
width,
|
|
48
|
+
height,
|
|
49
|
+
description,
|
|
50
|
+
outputPixelFormat: 'rgba',
|
|
51
|
+
hardwareAcceleration: hwPref,
|
|
117
52
|
});
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
while (this.accumulatedData.length >= this.frameSize) {
|
|
122
|
-
const frameData = this.accumulatedData.subarray(0, this.frameSize);
|
|
123
|
-
this.accumulatedData = this.accumulatedData.subarray(this.frameSize);
|
|
124
|
-
this.emitSample(frameData);
|
|
125
|
-
}
|
|
53
|
+
// Listen for decoded frames
|
|
54
|
+
this.backend.on('frame', (frameData) => {
|
|
55
|
+
this.emitSample(frameData);
|
|
126
56
|
});
|
|
127
|
-
this.
|
|
128
|
-
console.error('
|
|
57
|
+
this.backend.on('error', (err) => {
|
|
58
|
+
console.error('[FFmpegVideoDecoder] Backend error:', err.message);
|
|
129
59
|
});
|
|
130
|
-
this.
|
|
60
|
+
this.backend.on('close', () => {
|
|
131
61
|
if (this.resolveFlush) {
|
|
132
62
|
this.resolveFlush();
|
|
133
63
|
this.resolveFlush = null;
|
|
134
64
|
}
|
|
135
65
|
});
|
|
136
|
-
this.process.stdin?.on('error', () => {
|
|
137
|
-
// Ignore EPIPE errors
|
|
138
|
-
});
|
|
139
66
|
}
|
|
140
67
|
async decode(packet) {
|
|
141
|
-
if (!this.
|
|
68
|
+
if (!this.backend?.isHealthy) {
|
|
142
69
|
throw new Error('Decoder not initialized');
|
|
143
70
|
}
|
|
144
71
|
// Store packet timing info for output frames
|
|
145
72
|
this.packetTimestamps.push(packet.timestamp);
|
|
146
73
|
this.packetDurations.push(packet.duration);
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
this.writeIvfFrame(packet.data, this.frameIndex++);
|
|
150
|
-
}
|
|
151
|
-
else if (this.useAnnexB) {
|
|
152
|
-
// Convert AVC/AVCC format to Annex B and write
|
|
153
|
-
this.writeAnnexBFrame(packet.data, packet.type === 'key');
|
|
154
|
-
this.frameIndex++;
|
|
155
|
-
}
|
|
156
|
-
else {
|
|
157
|
-
// Write raw encoded data
|
|
158
|
-
this.process.stdin.write(Buffer.from(packet.data));
|
|
159
|
-
}
|
|
160
|
-
}
|
|
161
|
-
/**
|
|
162
|
-
* Parse AVCDecoderConfigurationRecord from config.description
|
|
163
|
-
* This extracts SPS and PPS NAL units needed for Annex B stream
|
|
164
|
-
*/
|
|
165
|
-
parseAvcDecoderConfig(description) {
|
|
166
|
-
let data;
|
|
167
|
-
if (description instanceof ArrayBuffer) {
|
|
168
|
-
data = Buffer.from(description);
|
|
169
|
-
}
|
|
170
|
-
else if (ArrayBuffer.isView(description)) {
|
|
171
|
-
data = Buffer.from(description.buffer, description.byteOffset, description.byteLength);
|
|
172
|
-
}
|
|
173
|
-
else {
|
|
174
|
-
return;
|
|
175
|
-
}
|
|
176
|
-
if (data.length < 7)
|
|
177
|
-
return;
|
|
178
|
-
// AVCDecoderConfigurationRecord structure:
|
|
179
|
-
// configurationVersion (1 byte)
|
|
180
|
-
// AVCProfileIndication (1 byte)
|
|
181
|
-
// profile_compatibility (1 byte)
|
|
182
|
-
// AVCLevelIndication (1 byte)
|
|
183
|
-
// lengthSizeMinusOne (1 byte, lower 2 bits) -> NAL length size
|
|
184
|
-
// numOfSequenceParameterSets (1 byte, lower 5 bits)
|
|
185
|
-
// SPS entries...
|
|
186
|
-
// numOfPictureParameterSets (1 byte)
|
|
187
|
-
// PPS entries...
|
|
188
|
-
this.nalLengthSize = (data[4] & 0x03) + 1;
|
|
189
|
-
let offset = 5;
|
|
190
|
-
// Parse SPS
|
|
191
|
-
const numSps = data[offset] & 0x1f;
|
|
192
|
-
offset++;
|
|
193
|
-
for (let i = 0; i < numSps; i++) {
|
|
194
|
-
if (offset + 2 > data.length)
|
|
195
|
-
break;
|
|
196
|
-
const spsLength = data.readUInt16BE(offset);
|
|
197
|
-
offset += 2;
|
|
198
|
-
if (offset + spsLength > data.length)
|
|
199
|
-
break;
|
|
200
|
-
this.spsNal = data.subarray(offset, offset + spsLength);
|
|
201
|
-
offset += spsLength;
|
|
202
|
-
}
|
|
203
|
-
// Parse PPS
|
|
204
|
-
if (offset >= data.length)
|
|
205
|
-
return;
|
|
206
|
-
const numPps = data[offset];
|
|
207
|
-
offset++;
|
|
208
|
-
for (let i = 0; i < numPps; i++) {
|
|
209
|
-
if (offset + 2 > data.length)
|
|
210
|
-
break;
|
|
211
|
-
const ppsLength = data.readUInt16BE(offset);
|
|
212
|
-
offset += 2;
|
|
213
|
-
if (offset + ppsLength > data.length)
|
|
214
|
-
break;
|
|
215
|
-
this.ppsNal = data.subarray(offset, offset + ppsLength);
|
|
216
|
-
offset += ppsLength;
|
|
217
|
-
}
|
|
218
|
-
}
|
|
219
|
-
/**
|
|
220
|
-
* Convert AVC/AVCC format packet to Annex B and write to FFmpeg
|
|
221
|
-
* AVC format: [length][NAL][length][NAL]...
|
|
222
|
-
* Annex B: [start code][NAL][start code][NAL]...
|
|
223
|
-
*/
|
|
224
|
-
writeAnnexBFrame(data, isKeyFrame) {
|
|
225
|
-
if (!this.process?.stdin)
|
|
226
|
-
return;
|
|
227
|
-
const buf = Buffer.from(data);
|
|
228
|
-
const startCode = Buffer.from([0x00, 0x00, 0x00, 0x01]);
|
|
229
|
-
// For keyframes, prepend SPS and PPS
|
|
230
|
-
if (isKeyFrame && !this.paramsSent && this.spsNal && this.ppsNal) {
|
|
231
|
-
this.process.stdin.write(startCode);
|
|
232
|
-
this.process.stdin.write(this.spsNal);
|
|
233
|
-
this.process.stdin.write(startCode);
|
|
234
|
-
this.process.stdin.write(this.ppsNal);
|
|
235
|
-
this.paramsSent = true;
|
|
236
|
-
}
|
|
237
|
-
// Check if data is already in Annex B format (starts with 0x00 0x00 0x01)
|
|
238
|
-
if (this.isAnnexBFormat(buf)) {
|
|
239
|
-
this.process.stdin.write(buf);
|
|
240
|
-
return;
|
|
241
|
-
}
|
|
242
|
-
// Convert AVC format to Annex B
|
|
243
|
-
let offset = 0;
|
|
244
|
-
while (offset + this.nalLengthSize <= buf.length) {
|
|
245
|
-
// Read NAL length
|
|
246
|
-
let nalLength = 0;
|
|
247
|
-
for (let i = 0; i < this.nalLengthSize; i++) {
|
|
248
|
-
nalLength = (nalLength << 8) | buf[offset + i];
|
|
249
|
-
}
|
|
250
|
-
offset += this.nalLengthSize;
|
|
251
|
-
if (offset + nalLength > buf.length) {
|
|
252
|
-
console.error('Invalid NAL length in AVC data');
|
|
253
|
-
break;
|
|
254
|
-
}
|
|
255
|
-
// Write start code + NAL data
|
|
256
|
-
this.process.stdin.write(startCode);
|
|
257
|
-
this.process.stdin.write(buf.subarray(offset, offset + nalLength));
|
|
258
|
-
offset += nalLength;
|
|
259
|
-
}
|
|
260
|
-
}
|
|
261
|
-
/**
|
|
262
|
-
* Check if buffer is already in Annex B format
|
|
263
|
-
*/
|
|
264
|
-
isAnnexBFormat(buf) {
|
|
265
|
-
if (buf.length < 4)
|
|
266
|
-
return false;
|
|
267
|
-
// Check for 3-byte or 4-byte start code
|
|
268
|
-
return ((buf[0] === 0 && buf[1] === 0 && buf[2] === 1) ||
|
|
269
|
-
(buf[0] === 0 && buf[1] === 0 && buf[2] === 0 && buf[3] === 1));
|
|
74
|
+
// Write encoded data to backend
|
|
75
|
+
this.backend.write(Buffer.from(packet.data));
|
|
270
76
|
}
|
|
271
77
|
async flush() {
|
|
272
78
|
return new Promise((resolve) => {
|
|
273
79
|
this.resolveFlush = resolve;
|
|
274
|
-
if (this.
|
|
275
|
-
this.
|
|
80
|
+
if (this.backend) {
|
|
81
|
+
this.backend.end();
|
|
276
82
|
}
|
|
277
83
|
else {
|
|
278
84
|
resolve();
|
|
@@ -280,56 +86,10 @@ export class FFmpegVideoDecoder extends CustomVideoDecoder {
|
|
|
280
86
|
});
|
|
281
87
|
}
|
|
282
88
|
async close() {
|
|
283
|
-
if (this.
|
|
284
|
-
this.
|
|
285
|
-
this.
|
|
286
|
-
}
|
|
287
|
-
}
|
|
288
|
-
/**
|
|
289
|
-
* Write IVF file header (32 bytes)
|
|
290
|
-
*/
|
|
291
|
-
writeIvfHeader() {
|
|
292
|
-
if (!this.process?.stdin)
|
|
293
|
-
return;
|
|
294
|
-
const width = this.config.codedWidth ?? 1920;
|
|
295
|
-
const height = this.config.codedHeight ?? 1080;
|
|
296
|
-
const header = Buffer.alloc(32);
|
|
297
|
-
header.write('DKIF', 0);
|
|
298
|
-
header.writeUInt16LE(0, 4); // Version
|
|
299
|
-
header.writeUInt16LE(32, 6); // Header length
|
|
300
|
-
// FourCC based on codec
|
|
301
|
-
if (this.codec === 'vp8') {
|
|
302
|
-
header.write('VP80', 8);
|
|
303
|
-
}
|
|
304
|
-
else if (this.codec === 'vp9') {
|
|
305
|
-
header.write('VP90', 8);
|
|
306
|
-
}
|
|
307
|
-
else if (this.codec === 'av1') {
|
|
308
|
-
header.write('AV01', 8);
|
|
309
|
-
}
|
|
310
|
-
header.writeUInt16LE(width, 12);
|
|
311
|
-
header.writeUInt16LE(height, 14);
|
|
312
|
-
header.writeUInt32LE(30, 16); // Framerate
|
|
313
|
-
header.writeUInt32LE(1, 20); // Timebase
|
|
314
|
-
header.writeUInt32LE(0, 24); // Frame count (unknown)
|
|
315
|
-
header.writeUInt32LE(0, 28); // Unused
|
|
316
|
-
this.process.stdin.write(header);
|
|
317
|
-
this.ivfHeaderSent = true;
|
|
318
|
-
}
|
|
319
|
-
/**
|
|
320
|
-
* Write an IVF frame (12-byte header + data)
|
|
321
|
-
*/
|
|
322
|
-
writeIvfFrame(data, frameIndex) {
|
|
323
|
-
if (!this.process?.stdin)
|
|
324
|
-
return;
|
|
325
|
-
if (!this.ivfHeaderSent) {
|
|
326
|
-
this.writeIvfHeader();
|
|
89
|
+
if (this.backend) {
|
|
90
|
+
this.backend.kill();
|
|
91
|
+
this.backend = null;
|
|
327
92
|
}
|
|
328
|
-
const frameHeader = Buffer.alloc(12);
|
|
329
|
-
frameHeader.writeUInt32LE(data.length, 0);
|
|
330
|
-
frameHeader.writeBigUInt64LE(BigInt(frameIndex), 4);
|
|
331
|
-
this.process.stdin.write(frameHeader);
|
|
332
|
-
this.process.stdin.write(Buffer.from(data));
|
|
333
93
|
}
|
|
334
94
|
/**
|
|
335
95
|
* Emit a decoded VideoSample via Mediabunny callback
|
|
@@ -350,8 +110,7 @@ export class FFmpegVideoDecoder extends CustomVideoDecoder {
|
|
|
350
110
|
timestampSeconds = this.frameIndex / framerate;
|
|
351
111
|
durationSeconds = 1 / framerate;
|
|
352
112
|
}
|
|
353
|
-
// Create VideoSample from raw pixel data
|
|
354
|
-
// Mediabunny accepts AllowSharedBufferSource with format/dimensions/timestamp
|
|
113
|
+
// Create VideoSample from raw pixel data
|
|
355
114
|
const sample = new VideoSample(new Uint8Array(data), {
|
|
356
115
|
format: 'RGBA',
|
|
357
116
|
codedWidth: width,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"FFmpegVideoDecoder.js","sourceRoot":"","sources":["../../src/mediabunny/FFmpegVideoDecoder.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"FFmpegVideoDecoder.js","sourceRoot":"","sources":["../../src/mediabunny/FFmpegVideoDecoder.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,23 +1,19 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* FFmpeg-backed VideoEncoder for Mediabunny
|
|
3
3
|
*
|
|
4
|
-
* Implements Mediabunny's CustomVideoEncoder interface using
|
|
4
|
+
* Implements Mediabunny's CustomVideoEncoder interface using node-av native bindings.
|
|
5
5
|
* Supports hardware acceleration via VAAPI, NVENC, QSV, VideoToolbox.
|
|
6
6
|
*/
|
|
7
7
|
import { CustomVideoEncoder, VideoSample, VideoCodec } from 'mediabunny';
|
|
8
8
|
export declare class FFmpegVideoEncoder extends CustomVideoEncoder {
|
|
9
|
-
private
|
|
10
|
-
private accumulatedData;
|
|
11
|
-
private ivfHeaderParsed;
|
|
9
|
+
private backend;
|
|
12
10
|
private frameIndex;
|
|
13
|
-
private resolveFlush;
|
|
14
|
-
private useIvf;
|
|
15
|
-
private useAnnexB;
|
|
16
11
|
private codecDescription;
|
|
17
12
|
private metadataEmitted;
|
|
18
|
-
private usingHardwareAcceleration;
|
|
19
|
-
private hwaccelMethod;
|
|
20
13
|
private bitstreamFormat;
|
|
14
|
+
private useAnnexB;
|
|
15
|
+
private resolveFlush;
|
|
16
|
+
private pendingPackets;
|
|
21
17
|
static supports(codec: VideoCodec, _config: VideoEncoderConfig): boolean;
|
|
22
18
|
init(): Promise<void>;
|
|
23
19
|
encode(videoSample: VideoSample, _options: {
|
|
@@ -25,20 +21,11 @@ export declare class FFmpegVideoEncoder extends CustomVideoEncoder {
|
|
|
25
21
|
}): Promise<void>;
|
|
26
22
|
flush(): Promise<void>;
|
|
27
23
|
close(): Promise<void>;
|
|
24
|
+
private processPackets;
|
|
28
25
|
/**
|
|
29
26
|
* Extract raw RGBA pixel data from VideoSample
|
|
30
27
|
*/
|
|
31
28
|
private getFrameData;
|
|
32
|
-
/**
|
|
33
|
-
* Parse IVF container and emit individual encoded packets
|
|
34
|
-
*/
|
|
35
|
-
private parseIvfFrames;
|
|
36
|
-
/**
|
|
37
|
-
* Parse H.264/HEVC Annex B bitstream and emit frames
|
|
38
|
-
* Annex B uses start codes (0x00 0x00 0x01 or 0x00 0x00 0x00 0x01) to delimit NAL units.
|
|
39
|
-
* When AUD (Access Unit Delimiter) is enabled, each frame starts with an AUD NAL.
|
|
40
|
-
*/
|
|
41
|
-
private parseAnnexBFrames;
|
|
42
29
|
/**
|
|
43
30
|
* Find all Annex B start codes in buffer
|
|
44
31
|
*/
|
|
@@ -47,22 +34,6 @@ export declare class FFmpegVideoEncoder extends CustomVideoEncoder {
|
|
|
47
34
|
* Get NAL unit type from first byte after start code
|
|
48
35
|
*/
|
|
49
36
|
private getNalType;
|
|
50
|
-
/**
|
|
51
|
-
* Check if this NAL unit starts a new Access Unit (frame)
|
|
52
|
-
*/
|
|
53
|
-
private isAccessUnitStart;
|
|
54
|
-
/**
|
|
55
|
-
* Emit a complete Annex B frame
|
|
56
|
-
*/
|
|
57
|
-
private emitAnnexBFrame;
|
|
58
|
-
/**
|
|
59
|
-
* Check if H.264/HEVC Annex B frame is a keyframe
|
|
60
|
-
*/
|
|
61
|
-
private isH264KeyFrame;
|
|
62
|
-
/**
|
|
63
|
-
* Check if VP8/VP9/AV1 frame is a keyframe
|
|
64
|
-
*/
|
|
65
|
-
private isKeyFrame;
|
|
66
37
|
/**
|
|
67
38
|
* Emit an encoded packet via Mediabunny callback
|
|
68
39
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"FFmpegVideoEncoder.d.ts","sourceRoot":"","sources":["../../src/mediabunny/FFmpegVideoEncoder.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;
|
|
1
|
+
{"version":3,"file":"FFmpegVideoEncoder.d.ts","sourceRoot":"","sources":["../../src/mediabunny/FFmpegVideoEncoder.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EACL,kBAAkB,EAClB,WAAW,EAEX,UAAU,EACX,MAAM,YAAY,CAAC;AAsBpB,qBAAa,kBAAmB,SAAQ,kBAAkB;IACxD,OAAO,CAAC,OAAO,CAAmC;IAClD,OAAO,CAAC,UAAU,CAAK;IACvB,OAAO,CAAC,gBAAgB,CAA2B;IACnD,OAAO,CAAC,eAAe,CAAS;IAChC,OAAO,CAAC,eAAe,CAA8B;IACrD,OAAO,CAAC,SAAS,CAAS;IAC1B,OAAO,CAAC,YAAY,CAA6B;IACjD,OAAO,CAAC,cAAc,CAAqE;IAE3F,MAAM,CAAC,QAAQ,CAAC,KAAK,EAAE,UAAU,EAAE,OAAO,EAAE,kBAAkB,GAAG,OAAO;IAIlE,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;IAsDrB,MAAM,CAAC,WAAW,EAAE,WAAW,EAAE,QAAQ,EAAE;QAAE,QAAQ,CAAC,EAAE,OAAO,CAAA;KAAE,GAAG,OAAO,CAAC,IAAI,CAAC;IAUjF,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAYtB,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAO5B,OAAO,CAAC,cAAc;IAOtB;;OAEG;YACW,YAAY;IAkC1B;;OAEG;IACH,OAAO,CAAC,cAAc;IAuBtB;;OAEG;IACH,OAAO,CAAC,UAAU;IAQlB;;OAEG;IACH,OAAO,CAAC,UAAU;IA0ClB;;OAEG;IACH,OAAO,CAAC,cAAc;IAsBtB,OAAO,CAAC,qBAAqB;IAsB7B,OAAO,CAAC,kBAAkB;CAU3B"}
|