@mediabunny/server 1.49.0 → 1.50.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 +3 -1
- package/dist/bundles/mediabunny-server.cjs +93 -10
- package/dist/bundles/mediabunny-server.min.cjs +2 -2
- package/dist/bundles/mediabunny-server.min.mjs +2 -2
- package/dist/bundles/mediabunny-server.mjs +93 -10
- package/dist/modules/src/index.d.ts.map +1 -1
- package/dist/modules/src/index.js +2 -0
- package/dist/modules/src/misc.d.ts.map +1 -1
- package/dist/modules/src/misc.js +1 -0
- package/dist/modules/src/video-encoder.d.ts.map +1 -1
- package/dist/modules/src/video-encoder.js +58 -6
- package/dist/modules/tsconfig.tsbuildinfo +1 -1
- package/package.json +3 -2
- package/src/index.ts +2 -0
- package/src/misc.ts +1 -0
- package/src/video-encoder.ts +67 -7
|
@@ -48,6 +48,14 @@ const video_sample_1 = require("./video-sample");
|
|
|
48
48
|
const codec_data_1 = require("../../../src/codec-data");
|
|
49
49
|
const codec_1 = require("../../../src/codec");
|
|
50
50
|
const misc_2 = require("../../../src/misc");
|
|
51
|
+
const PRORES_FOURCC_TO_PROFILE = {
|
|
52
|
+
apco: NodeAv.AV_PROFILE_PRORES_PROXY,
|
|
53
|
+
apcs: NodeAv.AV_PROFILE_PRORES_LT,
|
|
54
|
+
apcn: NodeAv.AV_PROFILE_PRORES_STANDARD,
|
|
55
|
+
apch: NodeAv.AV_PROFILE_PRORES_HQ,
|
|
56
|
+
ap4h: NodeAv.AV_PROFILE_PRORES_4444,
|
|
57
|
+
ap4x: NodeAv.AV_PROFILE_PRORES_XQ,
|
|
58
|
+
};
|
|
51
59
|
class NodeAvVideoEncoder extends mediabunny_1.CustomVideoEncoder {
|
|
52
60
|
constructor() {
|
|
53
61
|
super(...arguments);
|
|
@@ -61,8 +69,8 @@ class NodeAvVideoEncoder extends mediabunny_1.CustomVideoEncoder {
|
|
|
61
69
|
this.preciseTimings = [];
|
|
62
70
|
}
|
|
63
71
|
static supports(codec, config) {
|
|
64
|
-
return (codec === 'avc' || codec === 'hevc' || codec === 'vp8' || codec === 'vp9' || codec === 'av1'
|
|
65
|
-
&& config.bitrateMode !== 'quantizer';
|
|
72
|
+
return (codec === 'avc' || codec === 'hevc' || codec === 'vp8' || codec === 'vp9' || codec === 'av1'
|
|
73
|
+
|| codec === 'prores') && config.bitrateMode !== 'quantizer';
|
|
66
74
|
}
|
|
67
75
|
async init() {
|
|
68
76
|
this.frame = new NodeAv.Frame();
|
|
@@ -72,15 +80,25 @@ class NodeAvVideoEncoder extends mediabunny_1.CustomVideoEncoder {
|
|
|
72
80
|
this.packet.alloc();
|
|
73
81
|
const codecId = misc_1.CODEC_TO_CODEC_ID[this.codec];
|
|
74
82
|
(0, misc_2.assert)(codecId !== undefined);
|
|
83
|
+
const getSoftwareCodec = () => {
|
|
84
|
+
if (this.codec === 'prores') {
|
|
85
|
+
// Prefer prores_ks for ProRes
|
|
86
|
+
const proresKs = NodeAv.Codec.findEncoderByName(NodeAv.FF_ENCODER_PRORES_KS);
|
|
87
|
+
if (proresKs) {
|
|
88
|
+
return proresKs;
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
return NodeAv.Codec.findEncoder(codecId);
|
|
92
|
+
};
|
|
75
93
|
let codec = null;
|
|
76
94
|
if (this.codec === 'vp9' && this.config.alpha === 'keep') {
|
|
77
95
|
codec = NodeAv.Codec.findEncoderByName(NodeAv.FF_ENCODER_LIBVPX_VP9) ?? NodeAv.Codec.findEncoder(codecId);
|
|
78
96
|
}
|
|
79
97
|
else if (this.config.hardwareAcceleration === 'prefer-software') {
|
|
80
|
-
codec =
|
|
98
|
+
codec = getSoftwareCodec();
|
|
81
99
|
}
|
|
82
100
|
else {
|
|
83
|
-
codec = (await (0, misc_1.getHardwareEncoderCodec)(codecId)) ??
|
|
101
|
+
codec = (await (0, misc_1.getHardwareEncoderCodec)(codecId)) ?? getSoftwareCodec();
|
|
84
102
|
}
|
|
85
103
|
if (!codec) {
|
|
86
104
|
throw new Error(`Unable to obtain libav codec for '${this.codec}'.`);
|
|
@@ -97,8 +115,15 @@ class NodeAvVideoEncoder extends mediabunny_1.CustomVideoEncoder {
|
|
|
97
115
|
if (!this.avCodec.pixelFormats.includes(NodeAv.AV_PIX_FMT_YUV420P)) {
|
|
98
116
|
pixelFormat = this.avCodec.pixelFormats[0];
|
|
99
117
|
}
|
|
100
|
-
if (this.config.alpha === 'keep'
|
|
101
|
-
|
|
118
|
+
if (this.config.alpha === 'keep') {
|
|
119
|
+
if (this.avCodec.pixelFormats.includes(NodeAv.AV_PIX_FMT_YUVA420P)) {
|
|
120
|
+
pixelFormat = NodeAv.AV_PIX_FMT_YUVA420P;
|
|
121
|
+
}
|
|
122
|
+
else {
|
|
123
|
+
// Let FFmpeg pick the best alpha-capable format it supports, minimizing data loss versus a
|
|
124
|
+
// high-quality YUVA source
|
|
125
|
+
pixelFormat = NodeAv.avcodecFindBestPixFmtOfList(this.avCodec.pixelFormats, NodeAv.AV_PIX_FMT_YUVA444P12LE);
|
|
126
|
+
}
|
|
102
127
|
}
|
|
103
128
|
}
|
|
104
129
|
const pixelAspectRatio = (0, misc_2.simplifyRational)({
|
|
@@ -157,6 +182,12 @@ class NodeAvVideoEncoder extends mediabunny_1.CustomVideoEncoder {
|
|
|
157
182
|
codecContext.setOption('preset', '12');
|
|
158
183
|
}
|
|
159
184
|
}
|
|
185
|
+
if (this.codec === 'prores') {
|
|
186
|
+
// Pick the encoder profile from the requested ProRes four-character code
|
|
187
|
+
const profile = PRORES_FOURCC_TO_PROFILE[this.config.codec];
|
|
188
|
+
(0, misc_2.assert)(profile !== undefined);
|
|
189
|
+
codecContext.setOption('profile', String(profile));
|
|
190
|
+
}
|
|
160
191
|
const ret = await codecContext.open2();
|
|
161
192
|
NodeAv.FFmpegError.throwIfError(ret, 'Open codec context');
|
|
162
193
|
this.codecContext = codecContext;
|
|
@@ -318,6 +349,7 @@ class NodeAvVideoEncoder extends mediabunny_1.CustomVideoEncoder {
|
|
|
318
349
|
hevcCodecInfo: null,
|
|
319
350
|
vp9CodecInfo: null,
|
|
320
351
|
av1CodecInfo: null,
|
|
352
|
+
proresFormat: null,
|
|
321
353
|
});
|
|
322
354
|
if (!expectsAnnexB) {
|
|
323
355
|
decoderConfigDescription = serializedRecord;
|
|
@@ -377,6 +409,7 @@ class NodeAvVideoEncoder extends mediabunny_1.CustomVideoEncoder {
|
|
|
377
409
|
hevcCodecInfo: null,
|
|
378
410
|
vp9CodecInfo: null,
|
|
379
411
|
av1CodecInfo: null,
|
|
412
|
+
proresFormat: null,
|
|
380
413
|
});
|
|
381
414
|
}
|
|
382
415
|
}
|
|
@@ -394,6 +427,7 @@ class NodeAvVideoEncoder extends mediabunny_1.CustomVideoEncoder {
|
|
|
394
427
|
hevcCodecInfo: null,
|
|
395
428
|
vp9CodecInfo,
|
|
396
429
|
av1CodecInfo: null,
|
|
430
|
+
proresFormat: null,
|
|
397
431
|
});
|
|
398
432
|
}
|
|
399
433
|
}
|
|
@@ -411,6 +445,24 @@ class NodeAvVideoEncoder extends mediabunny_1.CustomVideoEncoder {
|
|
|
411
445
|
hevcCodecInfo: null,
|
|
412
446
|
vp9CodecInfo: null,
|
|
413
447
|
av1CodecInfo,
|
|
448
|
+
proresFormat: null,
|
|
449
|
+
});
|
|
450
|
+
}
|
|
451
|
+
}
|
|
452
|
+
else if (this.codec === 'prores') {
|
|
453
|
+
if (!this.packetEmitted) {
|
|
454
|
+
decoderConfigCodecString = (0, codec_1.extractVideoCodecString)({
|
|
455
|
+
width: this.config.width,
|
|
456
|
+
height: this.config.height,
|
|
457
|
+
codec: 'prores',
|
|
458
|
+
codecDescription: null,
|
|
459
|
+
colorSpace: null,
|
|
460
|
+
avcType: null,
|
|
461
|
+
avcCodecInfo: null,
|
|
462
|
+
hevcCodecInfo: null,
|
|
463
|
+
vp9CodecInfo: null,
|
|
464
|
+
av1CodecInfo: null,
|
|
465
|
+
proresFormat: this.config.codec,
|
|
414
466
|
});
|
|
415
467
|
}
|
|
416
468
|
}
|