@remotion/renderer 4.0.482 → 4.0.484
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/dist/client.d.ts +13 -3
- package/dist/crf.d.ts +2 -1
- package/dist/crf.js +10 -3
- package/dist/esm/client.mjs +71 -9
- package/dist/esm/index.mjs +159 -29
- package/dist/ffmpeg-args.js +3 -1
- package/dist/get-codec-name.js +25 -0
- package/dist/options/index.d.ts +13 -3
- package/dist/options/pixel-format.d.ts +4 -1
- package/dist/options/pixel-format.js +15 -3
- package/dist/options/prores-profile.d.ts +4 -1
- package/dist/options/prores-profile.js +15 -3
- package/dist/options/video-image-format.d.ts +6 -1
- package/dist/options/video-image-format.js +45 -3
- package/dist/prespawn-ffmpeg.js +12 -1
- package/dist/probe-encoder.d.ts +26 -0
- package/dist/probe-encoder.js +95 -0
- package/dist/render-media.js +1 -0
- package/dist/stitch-frames-to-video.js +13 -1
- package/package.json +13 -13
package/dist/client.d.ts
CHANGED
|
@@ -820,7 +820,10 @@ export declare const BrowserSafeApis: {
|
|
|
820
820
|
type: "yuv420p" | "yuv420p10le" | "yuv422p" | "yuv422p10le" | "yuv444p" | "yuv444p10le" | "yuva420p" | "yuva444p10le";
|
|
821
821
|
getValue: ({ commandLine }: {
|
|
822
822
|
commandLine: Record<string, unknown>;
|
|
823
|
-
}
|
|
823
|
+
}, options?: {
|
|
824
|
+
uiPixelFormat: "yuv420p" | "yuv420p10le" | "yuv422p" | "yuv422p10le" | "yuv444p" | "yuv444p10le" | "yuva420p" | "yuva444p10le" | null;
|
|
825
|
+
compositionDefaultPixelFormat: "yuv420p" | "yuv420p10le" | "yuv422p" | "yuv422p10le" | "yuv444p" | "yuv444p10le" | "yuva420p" | "yuva444p10le" | null;
|
|
826
|
+
} | undefined) => {
|
|
824
827
|
source: string;
|
|
825
828
|
value: "yuv420p" | "yuv420p10le" | "yuv422p" | "yuv422p10le" | "yuv444p" | "yuv444p10le" | "yuva420p" | "yuva444p10le";
|
|
826
829
|
};
|
|
@@ -874,7 +877,10 @@ export declare const BrowserSafeApis: {
|
|
|
874
877
|
type: import("./client").ProResProfile | undefined;
|
|
875
878
|
getValue: ({ commandLine }: {
|
|
876
879
|
commandLine: Record<string, unknown>;
|
|
877
|
-
}
|
|
880
|
+
}, options?: {
|
|
881
|
+
uiProResProfile: import("./client").ProResProfile | undefined;
|
|
882
|
+
compositionDefaultProResProfile: import("./client").ProResProfile | null;
|
|
883
|
+
} | undefined) => {
|
|
878
884
|
source: string;
|
|
879
885
|
value: import("./client").ProResProfile;
|
|
880
886
|
} | {
|
|
@@ -1477,7 +1483,11 @@ export declare const BrowserSafeApis: {
|
|
|
1477
1483
|
type: "jpeg" | "none" | "png" | null;
|
|
1478
1484
|
getValue: ({ commandLine }: {
|
|
1479
1485
|
commandLine: Record<string, unknown>;
|
|
1480
|
-
}
|
|
1486
|
+
}, options?: {
|
|
1487
|
+
codec: import("./codec").CodecOrUndefined;
|
|
1488
|
+
uiVideoImageFormat: "jpeg" | "none" | "png" | null;
|
|
1489
|
+
compositionDefaultVideoImageFormat: "jpeg" | "none" | "png" | null;
|
|
1490
|
+
} | undefined) => {
|
|
1481
1491
|
source: string;
|
|
1482
1492
|
value: "jpeg" | "none" | "png";
|
|
1483
1493
|
} | {
|
package/dist/crf.d.ts
CHANGED
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
export type Crf = number | undefined;
|
|
2
2
|
export declare const getDefaultCrfForCodec: (codec: "aac" | "av1" | "gif" | "h264" | "h264-mkv" | "h264-ts" | "h265" | "mp3" | "prores" | "vp8" | "vp9" | "wav") => number | null;
|
|
3
3
|
export declare const getValidCrfRanges: (codec: "aac" | "av1" | "gif" | "h264" | "h264-mkv" | "h264-ts" | "h265" | "mp3" | "prores" | "vp8" | "vp9" | "wav") => [number, number];
|
|
4
|
-
export declare const validateQualitySettings: ({ codec, crf, videoBitrate, encodingMaxRate, encodingBufferSize, hardwareAcceleration, }: {
|
|
4
|
+
export declare const validateQualitySettings: ({ codec, crf, videoBitrate, encodingMaxRate, encodingBufferSize, hardwareAcceleration, hardwareAccelerated, }: {
|
|
5
5
|
crf: unknown;
|
|
6
6
|
codec: "aac" | "av1" | "gif" | "h264" | "h264-mkv" | "h264-ts" | "h265" | "mp3" | "prores" | "vp8" | "vp9" | "wav";
|
|
7
7
|
videoBitrate: string | null;
|
|
8
8
|
encodingMaxRate: string | null;
|
|
9
9
|
encodingBufferSize: string | null;
|
|
10
10
|
hardwareAcceleration: "disable" | "if-possible" | "required";
|
|
11
|
+
hardwareAccelerated: boolean;
|
|
11
12
|
}) => string[];
|
package/dist/crf.js
CHANGED
|
@@ -46,11 +46,15 @@ const getValidCrfRanges = (codec) => {
|
|
|
46
46
|
return val;
|
|
47
47
|
};
|
|
48
48
|
exports.getValidCrfRanges = getValidCrfRanges;
|
|
49
|
-
const validateQualitySettings = ({ codec, crf, videoBitrate, encodingMaxRate, encodingBufferSize, hardwareAcceleration, }) => {
|
|
50
|
-
|
|
49
|
+
const validateQualitySettings = ({ codec, crf, videoBitrate, encodingMaxRate, encodingBufferSize, hardwareAcceleration, hardwareAccelerated, }) => {
|
|
50
|
+
const hasExplicitCrf = crf !== null && typeof crf !== 'undefined';
|
|
51
|
+
if (hasExplicitCrf && videoBitrate) {
|
|
51
52
|
throw new Error('"crf" and "videoBitrate" can not both be set. Choose one of either.');
|
|
52
53
|
}
|
|
53
|
-
if (
|
|
54
|
+
if (hasExplicitCrf && hardwareAcceleration === 'required') {
|
|
55
|
+
throw new Error('"crf" option is not supported with hardware acceleration');
|
|
56
|
+
}
|
|
57
|
+
if (hasExplicitCrf && hardwareAccelerated) {
|
|
54
58
|
throw new Error('"crf" option is not supported with hardware acceleration');
|
|
55
59
|
}
|
|
56
60
|
if (encodingMaxRate && !encodingBufferSize) {
|
|
@@ -72,6 +76,9 @@ const validateQualitySettings = ({ codec, crf, videoBitrate, encodingMaxRate, en
|
|
|
72
76
|
return ['-b:v', videoBitrate, ...bufSizeArray, ...maxRateArray];
|
|
73
77
|
}
|
|
74
78
|
if (crf === null || typeof crf === 'undefined') {
|
|
79
|
+
if (hardwareAccelerated) {
|
|
80
|
+
return [...bufSizeArray, ...maxRateArray];
|
|
81
|
+
}
|
|
75
82
|
const actualCrf = (0, exports.getDefaultCrfForCodec)(codec);
|
|
76
83
|
if (actualCrf === null) {
|
|
77
84
|
return [...bufSizeArray, ...maxRateArray];
|
package/dist/esm/client.mjs
CHANGED
|
@@ -51,6 +51,11 @@ var validCodecs = [
|
|
|
51
51
|
];
|
|
52
52
|
var DEFAULT_CODEC = "h264";
|
|
53
53
|
|
|
54
|
+
// src/is-audio-codec.ts
|
|
55
|
+
var isAudioCodec = (codec) => {
|
|
56
|
+
return codec === "mp3" || codec === "aac" || codec === "wav";
|
|
57
|
+
};
|
|
58
|
+
|
|
54
59
|
// src/crf.ts
|
|
55
60
|
var defaultCrfMap = {
|
|
56
61
|
h264: 18,
|
|
@@ -3652,16 +3657,28 @@ var pixelFormatOption = {
|
|
|
3652
3657
|
ssrName: "pixelFormat",
|
|
3653
3658
|
docLink: "https://www.remotion.dev/docs/config#setpixelformat",
|
|
3654
3659
|
type: DEFAULT_PIXEL_FORMAT,
|
|
3655
|
-
getValue: ({ commandLine }) => {
|
|
3660
|
+
getValue: ({ commandLine }, options) => {
|
|
3661
|
+
if (options?.uiPixelFormat) {
|
|
3662
|
+
return {
|
|
3663
|
+
source: "via UI",
|
|
3664
|
+
value: options.uiPixelFormat
|
|
3665
|
+
};
|
|
3666
|
+
}
|
|
3656
3667
|
if (commandLine[cliFlag65] !== undefined) {
|
|
3657
3668
|
return {
|
|
3658
|
-
source: "
|
|
3669
|
+
source: "from --pixel-format flag",
|
|
3659
3670
|
value: commandLine[cliFlag65]
|
|
3660
3671
|
};
|
|
3661
3672
|
}
|
|
3673
|
+
if (options && options.compositionDefaultPixelFormat !== null) {
|
|
3674
|
+
return {
|
|
3675
|
+
source: "via calculateMetadata",
|
|
3676
|
+
value: options.compositionDefaultPixelFormat
|
|
3677
|
+
};
|
|
3678
|
+
}
|
|
3662
3679
|
if (currentPixelFormat !== DEFAULT_PIXEL_FORMAT) {
|
|
3663
3680
|
return {
|
|
3664
|
-
source: "
|
|
3681
|
+
source: "Config file",
|
|
3665
3682
|
value: currentPixelFormat
|
|
3666
3683
|
};
|
|
3667
3684
|
}
|
|
@@ -3876,16 +3893,28 @@ var proResProfileOption = {
|
|
|
3876
3893
|
ssrName: "proResProfile",
|
|
3877
3894
|
docLink: "https://www.remotion.dev/docs/config#setproresprofile",
|
|
3878
3895
|
type: undefined,
|
|
3879
|
-
getValue: ({ commandLine }) => {
|
|
3896
|
+
getValue: ({ commandLine }, options) => {
|
|
3897
|
+
if (options?.uiProResProfile) {
|
|
3898
|
+
return {
|
|
3899
|
+
source: "via UI",
|
|
3900
|
+
value: options.uiProResProfile
|
|
3901
|
+
};
|
|
3902
|
+
}
|
|
3880
3903
|
if (commandLine[cliFlag70] !== undefined) {
|
|
3881
3904
|
return {
|
|
3882
|
-
source: "
|
|
3905
|
+
source: "from --prores-profile flag",
|
|
3883
3906
|
value: String(commandLine[cliFlag70])
|
|
3884
3907
|
};
|
|
3885
3908
|
}
|
|
3909
|
+
if (options && options.compositionDefaultProResProfile !== null) {
|
|
3910
|
+
return {
|
|
3911
|
+
source: "via calculateMetadata",
|
|
3912
|
+
value: options.compositionDefaultProResProfile
|
|
3913
|
+
};
|
|
3914
|
+
}
|
|
3886
3915
|
if (proResProfile !== undefined) {
|
|
3887
3916
|
return {
|
|
3888
|
-
source: "
|
|
3917
|
+
source: "Config file",
|
|
3889
3918
|
value: proResProfile
|
|
3890
3919
|
};
|
|
3891
3920
|
}
|
|
@@ -4885,23 +4914,56 @@ var videoImageFormatOption = {
|
|
|
4885
4914
|
ssrName: "imageFormat",
|
|
4886
4915
|
docLink: "https://www.remotion.dev/docs/renderer/render-media#imageformat",
|
|
4887
4916
|
type: null,
|
|
4888
|
-
getValue: ({ commandLine }) => {
|
|
4917
|
+
getValue: ({ commandLine }, options) => {
|
|
4918
|
+
if (options?.uiVideoImageFormat) {
|
|
4919
|
+
return {
|
|
4920
|
+
source: "via UI",
|
|
4921
|
+
value: options.uiVideoImageFormat
|
|
4922
|
+
};
|
|
4923
|
+
}
|
|
4889
4924
|
if (commandLine[cliFlag88] !== undefined) {
|
|
4890
4925
|
const value3 = commandLine[cliFlag88];
|
|
4891
4926
|
if (!validVideoImageFormats.includes(value3)) {
|
|
4892
4927
|
throw new Error(`Invalid video image format: ${value3}. Must be one of: ${validVideoImageFormats.join(", ")}`);
|
|
4893
4928
|
}
|
|
4894
4929
|
return {
|
|
4895
|
-
source: "
|
|
4930
|
+
source: "from --image-format flag",
|
|
4896
4931
|
value: value3
|
|
4897
4932
|
};
|
|
4898
4933
|
}
|
|
4934
|
+
if (options && options.compositionDefaultVideoImageFormat !== null) {
|
|
4935
|
+
return {
|
|
4936
|
+
source: "via calculateMetadata",
|
|
4937
|
+
value: options.compositionDefaultVideoImageFormat
|
|
4938
|
+
};
|
|
4939
|
+
}
|
|
4899
4940
|
if (currentVideoImageFormat !== null) {
|
|
4900
4941
|
return {
|
|
4901
|
-
source: "
|
|
4942
|
+
source: "Config file",
|
|
4902
4943
|
value: currentVideoImageFormat
|
|
4903
4944
|
};
|
|
4904
4945
|
}
|
|
4946
|
+
if (options) {
|
|
4947
|
+
if (isAudioCodec(options.codec)) {
|
|
4948
|
+
return {
|
|
4949
|
+
source: "default",
|
|
4950
|
+
value: "none"
|
|
4951
|
+
};
|
|
4952
|
+
}
|
|
4953
|
+
if (options.codec === "h264" || options.codec === "h264-mkv" || options.codec === "h264-ts" || options.codec === "h265" || options.codec === "av1" || options.codec === "vp8" || options.codec === "vp9" || options.codec === "prores" || options.codec === "gif") {
|
|
4954
|
+
return {
|
|
4955
|
+
source: "default",
|
|
4956
|
+
value: "jpeg"
|
|
4957
|
+
};
|
|
4958
|
+
}
|
|
4959
|
+
if (options.codec === undefined) {
|
|
4960
|
+
return {
|
|
4961
|
+
source: "default",
|
|
4962
|
+
value: "png"
|
|
4963
|
+
};
|
|
4964
|
+
}
|
|
4965
|
+
throw new Error("Unrecognized codec " + options.codec);
|
|
4966
|
+
}
|
|
4905
4967
|
return {
|
|
4906
4968
|
source: "default",
|
|
4907
4969
|
value: null
|
package/dist/esm/index.mjs
CHANGED
|
@@ -21265,7 +21265,7 @@ var renderFrames = (options2) => {
|
|
|
21265
21265
|
// src/render-media.ts
|
|
21266
21266
|
import fs18 from "node:fs";
|
|
21267
21267
|
import os9 from "node:os";
|
|
21268
|
-
import
|
|
21268
|
+
import path28 from "node:path";
|
|
21269
21269
|
import { LicensingInternals } from "@remotion/licensing";
|
|
21270
21270
|
import { NoReactInternals as NoReactInternals15 } from "remotion/no-react";
|
|
21271
21271
|
|
|
@@ -21318,12 +21318,17 @@ var validateQualitySettings = ({
|
|
|
21318
21318
|
videoBitrate,
|
|
21319
21319
|
encodingMaxRate,
|
|
21320
21320
|
encodingBufferSize,
|
|
21321
|
-
hardwareAcceleration
|
|
21321
|
+
hardwareAcceleration,
|
|
21322
|
+
hardwareAccelerated
|
|
21322
21323
|
}) => {
|
|
21323
|
-
|
|
21324
|
+
const hasExplicitCrf = crf !== null && typeof crf !== "undefined";
|
|
21325
|
+
if (hasExplicitCrf && videoBitrate) {
|
|
21324
21326
|
throw new Error('"crf" and "videoBitrate" can not both be set. Choose one of either.');
|
|
21325
21327
|
}
|
|
21326
|
-
if (
|
|
21328
|
+
if (hasExplicitCrf && hardwareAcceleration === "required") {
|
|
21329
|
+
throw new Error('"crf" option is not supported with hardware acceleration');
|
|
21330
|
+
}
|
|
21331
|
+
if (hasExplicitCrf && hardwareAccelerated) {
|
|
21327
21332
|
throw new Error('"crf" option is not supported with hardware acceleration');
|
|
21328
21333
|
}
|
|
21329
21334
|
if (encodingMaxRate && !encodingBufferSize) {
|
|
@@ -21343,6 +21348,9 @@ var validateQualitySettings = ({
|
|
|
21343
21348
|
return ["-b:v", videoBitrate, ...bufSizeArray, ...maxRateArray];
|
|
21344
21349
|
}
|
|
21345
21350
|
if (crf === null || typeof crf === "undefined") {
|
|
21351
|
+
if (hardwareAccelerated) {
|
|
21352
|
+
return [...bufSizeArray, ...maxRateArray];
|
|
21353
|
+
}
|
|
21346
21354
|
const actualCrf = getDefaultCrfForCodec(codec);
|
|
21347
21355
|
if (actualCrf === null) {
|
|
21348
21356
|
return [...bufSizeArray, ...maxRateArray];
|
|
@@ -21558,6 +21566,11 @@ var getCodecName = ({
|
|
|
21558
21566
|
if (preferredHwAcceleration && process.platform === "darwin" && !unsupportedQualityOption) {
|
|
21559
21567
|
return { encoderName: "prores_videotoolbox", hardwareAccelerated: true };
|
|
21560
21568
|
}
|
|
21569
|
+
if (preferredHwAcceleration && process.platform !== "darwin" && !unsupportedQualityOption) {
|
|
21570
|
+
if (hardwareAcceleration === "required") {
|
|
21571
|
+
throw new Error(`Codec "prores" does not support hardware acceleration on ${process.platform}, but "hardwareAcceleration" is set to "required"`);
|
|
21572
|
+
}
|
|
21573
|
+
}
|
|
21561
21574
|
warnAboutDisabledHardwareAcceleration();
|
|
21562
21575
|
return { encoderName: "prores_ks", hardwareAccelerated: false };
|
|
21563
21576
|
}
|
|
@@ -21565,6 +21578,9 @@ var getCodecName = ({
|
|
|
21565
21578
|
if (preferredHwAcceleration && process.platform === "darwin" && !unsupportedQualityOption) {
|
|
21566
21579
|
return { encoderName: "h264_videotoolbox", hardwareAccelerated: true };
|
|
21567
21580
|
}
|
|
21581
|
+
if (preferredHwAcceleration && (process.platform === "linux" || process.platform === "win32") && !unsupportedQualityOption) {
|
|
21582
|
+
return { encoderName: "h264_nvenc", hardwareAccelerated: true };
|
|
21583
|
+
}
|
|
21568
21584
|
warnAboutDisabledHardwareAcceleration();
|
|
21569
21585
|
return { encoderName: "libx264", hardwareAccelerated: false };
|
|
21570
21586
|
}
|
|
@@ -21572,6 +21588,9 @@ var getCodecName = ({
|
|
|
21572
21588
|
if (preferredHwAcceleration && process.platform === "darwin" && !unsupportedQualityOption) {
|
|
21573
21589
|
return { encoderName: "hevc_videotoolbox", hardwareAccelerated: true };
|
|
21574
21590
|
}
|
|
21591
|
+
if (preferredHwAcceleration && (process.platform === "linux" || process.platform === "win32") && !unsupportedQualityOption) {
|
|
21592
|
+
return { encoderName: "hevc_nvenc", hardwareAccelerated: true };
|
|
21593
|
+
}
|
|
21575
21594
|
warnAboutDisabledHardwareAcceleration();
|
|
21576
21595
|
return { encoderName: "libx265", hardwareAccelerated: false };
|
|
21577
21596
|
}
|
|
@@ -21598,9 +21617,15 @@ var getCodecName = ({
|
|
|
21598
21617
|
return null;
|
|
21599
21618
|
}
|
|
21600
21619
|
if (codec === "h264-mkv") {
|
|
21620
|
+
if (hardwareAcceleration === "required") {
|
|
21621
|
+
throw new Error(`Codec "h264-mkv" does not support hardware acceleration on ${process.platform}, but "hardwareAcceleration" is set to "required"`);
|
|
21622
|
+
}
|
|
21601
21623
|
return { encoderName: "libx264", hardwareAccelerated: false };
|
|
21602
21624
|
}
|
|
21603
21625
|
if (codec === "h264-ts") {
|
|
21626
|
+
if (hardwareAcceleration === "required") {
|
|
21627
|
+
throw new Error(`Codec "h264-ts" does not support hardware acceleration on ${process.platform}, but "hardwareAcceleration" is set to "required"`);
|
|
21628
|
+
}
|
|
21604
21629
|
return { encoderName: "libx264", hardwareAccelerated: false };
|
|
21605
21630
|
}
|
|
21606
21631
|
throw new Error(`Could not get codec for ${codec}`);
|
|
@@ -21618,7 +21643,8 @@ var firstEncodingStepOnly = ({
|
|
|
21618
21643
|
videoBitrate,
|
|
21619
21644
|
encodingMaxRate,
|
|
21620
21645
|
encodingBufferSize,
|
|
21621
|
-
hardwareAcceleration
|
|
21646
|
+
hardwareAcceleration,
|
|
21647
|
+
hardwareAccelerated
|
|
21622
21648
|
}) => {
|
|
21623
21649
|
if (hasPreencoded || codec === "gif") {
|
|
21624
21650
|
return [];
|
|
@@ -21637,7 +21663,8 @@ var firstEncodingStepOnly = ({
|
|
|
21637
21663
|
codec,
|
|
21638
21664
|
encodingMaxRate,
|
|
21639
21665
|
encodingBufferSize,
|
|
21640
|
-
hardwareAcceleration
|
|
21666
|
+
hardwareAcceleration,
|
|
21667
|
+
hardwareAccelerated
|
|
21641
21668
|
})
|
|
21642
21669
|
].filter(truthy);
|
|
21643
21670
|
};
|
|
@@ -21706,7 +21733,8 @@ var generateFfmpegArgs = ({
|
|
|
21706
21733
|
encodingBufferSize,
|
|
21707
21734
|
x264Preset,
|
|
21708
21735
|
gopSize,
|
|
21709
|
-
hardwareAcceleration
|
|
21736
|
+
hardwareAcceleration,
|
|
21737
|
+
hardwareAccelerated
|
|
21710
21738
|
})
|
|
21711
21739
|
].filter(truthy);
|
|
21712
21740
|
};
|
|
@@ -21734,6 +21762,86 @@ var getProResProfileName = (codec, proResProfile) => {
|
|
|
21734
21762
|
}
|
|
21735
21763
|
};
|
|
21736
21764
|
|
|
21765
|
+
// src/probe-encoder.ts
|
|
21766
|
+
import { execFileSync } from "node:child_process";
|
|
21767
|
+
import path23 from "path";
|
|
21768
|
+
var probeEncoderAvailability = ({
|
|
21769
|
+
encoderName,
|
|
21770
|
+
binariesDirectory,
|
|
21771
|
+
indent,
|
|
21772
|
+
logLevel
|
|
21773
|
+
}) => {
|
|
21774
|
+
try {
|
|
21775
|
+
const executablePath = getExecutablePath({
|
|
21776
|
+
type: "ffmpeg",
|
|
21777
|
+
indent,
|
|
21778
|
+
logLevel,
|
|
21779
|
+
binariesDirectory
|
|
21780
|
+
});
|
|
21781
|
+
makeFileExecutableIfItIsNot(executablePath);
|
|
21782
|
+
const cwd = path23.dirname(executablePath);
|
|
21783
|
+
const result = execFileSync(executablePath, ["-encoders"], {
|
|
21784
|
+
encoding: "utf-8",
|
|
21785
|
+
env: getExplicitEnv(cwd),
|
|
21786
|
+
stdio: ["pipe", "pipe", "pipe"],
|
|
21787
|
+
timeout: 1e4
|
|
21788
|
+
});
|
|
21789
|
+
const escaped = encoderName.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
21790
|
+
const encoderRegex = new RegExp(`\\b${escaped}\\b`);
|
|
21791
|
+
const hasEncoder = encoderRegex.test(result);
|
|
21792
|
+
if (!hasEncoder) {
|
|
21793
|
+
Log.verbose({ indent, logLevel, tag: "probeEncoderAvailability()" }, `Encoder "${encoderName}" not found in FFmpeg build. Falling back to software encoding.`);
|
|
21794
|
+
}
|
|
21795
|
+
return hasEncoder;
|
|
21796
|
+
} catch (err) {
|
|
21797
|
+
Log.verbose({ indent, logLevel, tag: "probeEncoderAvailability()" }, `Failed to probe FFmpeg for encoder "${encoderName}": ${err}. Falling back to software encoding.`);
|
|
21798
|
+
return false;
|
|
21799
|
+
}
|
|
21800
|
+
};
|
|
21801
|
+
var resolveHardwareAcceleration = ({
|
|
21802
|
+
codec,
|
|
21803
|
+
hardwareAcceleration,
|
|
21804
|
+
binariesDirectory,
|
|
21805
|
+
indent,
|
|
21806
|
+
logLevel,
|
|
21807
|
+
crf,
|
|
21808
|
+
encodingMaxRate,
|
|
21809
|
+
encodingBufferSize
|
|
21810
|
+
}) => {
|
|
21811
|
+
if (hardwareAcceleration === "disable") {
|
|
21812
|
+
return "disable";
|
|
21813
|
+
}
|
|
21814
|
+
const preferred = getCodecName({
|
|
21815
|
+
codec,
|
|
21816
|
+
hardwareAcceleration,
|
|
21817
|
+
crf,
|
|
21818
|
+
encodingMaxRate,
|
|
21819
|
+
encodingBufferSize,
|
|
21820
|
+
logLevel,
|
|
21821
|
+
indent
|
|
21822
|
+
});
|
|
21823
|
+
if (preferred === null) {
|
|
21824
|
+
return hardwareAcceleration;
|
|
21825
|
+
}
|
|
21826
|
+
if (!preferred.hardwareAccelerated) {
|
|
21827
|
+
return hardwareAcceleration;
|
|
21828
|
+
}
|
|
21829
|
+
const encoderAvailable = probeEncoderAvailability({
|
|
21830
|
+
encoderName: preferred.encoderName,
|
|
21831
|
+
binariesDirectory,
|
|
21832
|
+
indent,
|
|
21833
|
+
logLevel
|
|
21834
|
+
});
|
|
21835
|
+
if (encoderAvailable) {
|
|
21836
|
+
return hardwareAcceleration;
|
|
21837
|
+
}
|
|
21838
|
+
if (hardwareAcceleration === "if-possible") {
|
|
21839
|
+
Log.verbose({ indent, logLevel, tag: "resolveHardwareAcceleration()" }, `Hardware encoder "${preferred.encoderName}" not available. Falling back to software encoding.`);
|
|
21840
|
+
return "disable";
|
|
21841
|
+
}
|
|
21842
|
+
throw new Error(`Hardware encoder "${preferred.encoderName}" is not available in your FFmpeg build. ` + `Install an FFmpeg with ${preferred.encoderName} support, or use "if-possible" mode instead of "required".`);
|
|
21843
|
+
};
|
|
21844
|
+
|
|
21737
21845
|
// src/validate-even-dimensions-with-codec.ts
|
|
21738
21846
|
var validateEvenDimensionsWithCodec = ({
|
|
21739
21847
|
width,
|
|
@@ -21794,6 +21902,16 @@ var prespawnFfmpeg = (options2) => {
|
|
|
21794
21902
|
const pixelFormat = options2.pixelFormat ?? DEFAULT_PIXEL_FORMAT;
|
|
21795
21903
|
const proResProfileName = getProResProfileName(codec, options2.proResProfile);
|
|
21796
21904
|
validateSelectedPixelFormatAndCodecCombination(pixelFormat, codec);
|
|
21905
|
+
const resolvedHardwareAcceleration = resolveHardwareAcceleration({
|
|
21906
|
+
codec,
|
|
21907
|
+
hardwareAcceleration: options2.hardwareAcceleration,
|
|
21908
|
+
binariesDirectory: options2.binariesDirectory,
|
|
21909
|
+
indent: options2.indent,
|
|
21910
|
+
logLevel: options2.logLevel,
|
|
21911
|
+
crf: options2.crf,
|
|
21912
|
+
encodingMaxRate: options2.encodingMaxRate,
|
|
21913
|
+
encodingBufferSize: options2.encodingBufferSize
|
|
21914
|
+
});
|
|
21797
21915
|
const ffmpegArgs = [
|
|
21798
21916
|
["-r", options2.fps],
|
|
21799
21917
|
...[
|
|
@@ -21814,7 +21932,7 @@ var prespawnFfmpeg = (options2) => {
|
|
|
21814
21932
|
encodingMaxRate: options2.encodingMaxRate,
|
|
21815
21933
|
encodingBufferSize: options2.encodingBufferSize,
|
|
21816
21934
|
colorSpace: options2.colorSpace,
|
|
21817
|
-
hardwareAcceleration:
|
|
21935
|
+
hardwareAcceleration: resolvedHardwareAcceleration,
|
|
21818
21936
|
indent: options2.indent,
|
|
21819
21937
|
logLevel: options2.logLevel
|
|
21820
21938
|
}),
|
|
@@ -21916,7 +22034,7 @@ var validateSelectedCodecAndProResCombination = ({
|
|
|
21916
22034
|
|
|
21917
22035
|
// src/stitch-frames-to-video.ts
|
|
21918
22036
|
import { cpSync as cpSync2, promises as promises3, rmSync as rmSync4 } from "node:fs";
|
|
21919
|
-
import
|
|
22037
|
+
import path27 from "node:path";
|
|
21920
22038
|
|
|
21921
22039
|
// src/convert-number-of-gif-loops-to-ffmpeg.ts
|
|
21922
22040
|
var convertNumberOfGifLoopsToFfmpegSyntax = (loops) => {
|
|
@@ -21930,7 +22048,7 @@ var convertNumberOfGifLoopsToFfmpegSyntax = (loops) => {
|
|
|
21930
22048
|
};
|
|
21931
22049
|
|
|
21932
22050
|
// src/create-audio.ts
|
|
21933
|
-
import
|
|
22051
|
+
import path26 from "path";
|
|
21934
22052
|
|
|
21935
22053
|
// src/resolve-asset-src.ts
|
|
21936
22054
|
import url from "node:url";
|
|
@@ -22131,7 +22249,7 @@ var compressAudio = async ({
|
|
|
22131
22249
|
};
|
|
22132
22250
|
|
|
22133
22251
|
// src/merge-audio-track.ts
|
|
22134
|
-
import
|
|
22252
|
+
import path25 from "node:path";
|
|
22135
22253
|
|
|
22136
22254
|
// src/chunk.ts
|
|
22137
22255
|
var chunk2 = (input, size) => {
|
|
@@ -22163,7 +22281,7 @@ var createFfmpegMergeFilter = ({
|
|
|
22163
22281
|
|
|
22164
22282
|
// src/ffmpeg-filter-file.ts
|
|
22165
22283
|
import fs17, { existsSync as existsSync5 } from "node:fs";
|
|
22166
|
-
import
|
|
22284
|
+
import path24 from "node:path";
|
|
22167
22285
|
var makeFfmpegFilterFile = (complexFilter, downloadMap) => {
|
|
22168
22286
|
if (complexFilter.filter === null) {
|
|
22169
22287
|
return {
|
|
@@ -22177,7 +22295,7 @@ var makeFfmpegFilterFile = (complexFilter, downloadMap) => {
|
|
|
22177
22295
|
};
|
|
22178
22296
|
var makeFfmpegFilterFileStr = async (complexFilter, downloadMap) => {
|
|
22179
22297
|
const random2 = Math.random().toString().replace(".", "");
|
|
22180
|
-
const filterFile =
|
|
22298
|
+
const filterFile = path24.join(downloadMap.complexFilter, "complex-filter-" + random2 + ".txt");
|
|
22181
22299
|
if (!existsSync5(downloadMap.complexFilter)) {
|
|
22182
22300
|
fs17.mkdirSync(downloadMap.complexFilter, { recursive: true });
|
|
22183
22301
|
}
|
|
@@ -22287,7 +22405,7 @@ var mergeAudioTrackUnlimited = async ({
|
|
|
22287
22405
|
onProgress(combinedProgress);
|
|
22288
22406
|
};
|
|
22289
22407
|
const chunkNames = await Promise.all(chunked.map(async (chunkFiles, i) => {
|
|
22290
|
-
const chunkOutname =
|
|
22408
|
+
const chunkOutname = path25.join(tempPath, `chunk-${i}.wav`);
|
|
22291
22409
|
await mergeAudioTrack({
|
|
22292
22410
|
files: chunkFiles,
|
|
22293
22411
|
chunkLengthInSeconds,
|
|
@@ -22749,7 +22867,7 @@ var createAudio = async ({
|
|
|
22749
22867
|
onProgress(totalProgress);
|
|
22750
22868
|
};
|
|
22751
22869
|
const audioTracks = await Promise.all(assetPositions.map(async (asset, index) => {
|
|
22752
|
-
const filterFile =
|
|
22870
|
+
const filterFile = path26.join(downloadMap.audioMixing, `${index}.wav`);
|
|
22753
22871
|
const result = await preprocessAudioTrack({
|
|
22754
22872
|
outName: filterFile,
|
|
22755
22873
|
asset,
|
|
@@ -22793,9 +22911,9 @@ var createAudio = async ({
|
|
|
22793
22911
|
}
|
|
22794
22912
|
}))
|
|
22795
22913
|
];
|
|
22796
|
-
const merged =
|
|
22914
|
+
const merged = path26.join(downloadMap.audioPreprocessing, "merged.wav");
|
|
22797
22915
|
const extension = getExtensionFromAudioCodec(audioCodec);
|
|
22798
|
-
const outName =
|
|
22916
|
+
const outName = path26.join(downloadMap.audioPreprocessing, `audio.${extension}`);
|
|
22799
22917
|
await mergeAudioTrack({
|
|
22800
22918
|
files: preprocessed,
|
|
22801
22919
|
outName: merged,
|
|
@@ -22975,7 +23093,7 @@ var innerStitchFramesToVideo = async ({
|
|
|
22975
23093
|
setting: audioCodecSetting,
|
|
22976
23094
|
separateAudioTo
|
|
22977
23095
|
});
|
|
22978
|
-
const tempFile = outputLocation ? null :
|
|
23096
|
+
const tempFile = outputLocation ? null : path27.join(assetsInfo.downloadMap.stitchFrames, `out.${getFileExtensionFromCodec(codec, resolvedAudioCodec)}`);
|
|
22979
23097
|
Log.verbose({
|
|
22980
23098
|
indent,
|
|
22981
23099
|
logLevel,
|
|
@@ -23007,7 +23125,8 @@ var innerStitchFramesToVideo = async ({
|
|
|
23007
23125
|
videoBitrate,
|
|
23008
23126
|
encodingMaxRate: maxRate,
|
|
23009
23127
|
encodingBufferSize: bufferSize,
|
|
23010
|
-
hardwareAcceleration
|
|
23128
|
+
hardwareAcceleration,
|
|
23129
|
+
hardwareAccelerated: false
|
|
23011
23130
|
});
|
|
23012
23131
|
validateSelectedPixelFormatAndCodecCombination(pixelFormat, codec);
|
|
23013
23132
|
const updateProgress = (muxProgress) => {
|
|
@@ -23050,7 +23169,7 @@ var innerStitchFramesToVideo = async ({
|
|
|
23050
23169
|
}
|
|
23051
23170
|
cpSync2(audio, outputLocation ?? tempFile);
|
|
23052
23171
|
onProgress?.(Math.round(assetsInfo.chunkLengthInSeconds * fps));
|
|
23053
|
-
deleteDirectory(
|
|
23172
|
+
deleteDirectory(path27.dirname(audio));
|
|
23054
23173
|
const file = await new Promise((resolve2, reject) => {
|
|
23055
23174
|
if (tempFile) {
|
|
23056
23175
|
promises3.readFile(tempFile).then((f) => {
|
|
@@ -23064,6 +23183,16 @@ var innerStitchFramesToVideo = async ({
|
|
|
23064
23183
|
assetsInfo.downloadMap.allowCleanup();
|
|
23065
23184
|
return Promise.resolve(file);
|
|
23066
23185
|
}
|
|
23186
|
+
const resolvedHardwareAcceleration = resolveHardwareAcceleration({
|
|
23187
|
+
codec,
|
|
23188
|
+
hardwareAcceleration,
|
|
23189
|
+
binariesDirectory,
|
|
23190
|
+
indent: indent ?? false,
|
|
23191
|
+
logLevel,
|
|
23192
|
+
crf,
|
|
23193
|
+
encodingMaxRate: maxRate,
|
|
23194
|
+
encodingBufferSize: bufferSize
|
|
23195
|
+
});
|
|
23067
23196
|
const ffmpegArgs = [
|
|
23068
23197
|
...preEncodedFileLocation ? [["-i", preEncodedFileLocation]] : [
|
|
23069
23198
|
["-r", String(fps)],
|
|
@@ -23087,7 +23216,7 @@ var innerStitchFramesToVideo = async ({
|
|
|
23087
23216
|
x264Preset,
|
|
23088
23217
|
gopSize,
|
|
23089
23218
|
colorSpace,
|
|
23090
|
-
hardwareAcceleration,
|
|
23219
|
+
hardwareAcceleration: resolvedHardwareAcceleration,
|
|
23091
23220
|
indent,
|
|
23092
23221
|
logLevel
|
|
23093
23222
|
}),
|
|
@@ -23140,7 +23269,7 @@ var innerStitchFramesToVideo = async ({
|
|
|
23140
23269
|
if (!audio) {
|
|
23141
23270
|
throw new Error(`\`separateAudioTo\` was set to ${JSON.stringify(separateAudioTo)}, but this render included no audio`);
|
|
23142
23271
|
}
|
|
23143
|
-
const finalDestination =
|
|
23272
|
+
const finalDestination = path27.resolve(remotionRoot, separateAudioTo);
|
|
23144
23273
|
cpSync2(audio, finalDestination);
|
|
23145
23274
|
rmSync4(audio);
|
|
23146
23275
|
}
|
|
@@ -23448,7 +23577,8 @@ var internalRenderMediaRaw = ({
|
|
|
23448
23577
|
videoBitrate,
|
|
23449
23578
|
encodingMaxRate,
|
|
23450
23579
|
encodingBufferSize,
|
|
23451
|
-
hardwareAcceleration
|
|
23580
|
+
hardwareAcceleration,
|
|
23581
|
+
hardwareAccelerated: false
|
|
23452
23582
|
});
|
|
23453
23583
|
validateGopSize(gopSize);
|
|
23454
23584
|
validateBitrate(audioBitrate, "audioBitrate");
|
|
@@ -23473,7 +23603,7 @@ var internalRenderMediaRaw = ({
|
|
|
23473
23603
|
separateAudioTo
|
|
23474
23604
|
});
|
|
23475
23605
|
}
|
|
23476
|
-
const absoluteOutputLocation = outputLocation ?
|
|
23606
|
+
const absoluteOutputLocation = outputLocation ? path28.resolve(process.cwd(), outputLocation) : null;
|
|
23477
23607
|
validateScale(scale);
|
|
23478
23608
|
validateFfmpegOverride(ffmpegOverride);
|
|
23479
23609
|
validateEveryNthFrame(everyNthFrame);
|
|
@@ -23539,8 +23669,8 @@ var internalRenderMediaRaw = ({
|
|
|
23539
23669
|
}
|
|
23540
23670
|
const imageFormat = isAudioCodec(codec) ? "none" : provisionalImageFormat ?? compositionWithPossibleUnevenDimensions.defaultVideoImageFormat ?? DEFAULT_VIDEO_IMAGE_FORMAT;
|
|
23541
23671
|
validateSelectedPixelFormatAndImageFormatCombination(pixelFormat, imageFormat);
|
|
23542
|
-
const workingDir = fs18.mkdtempSync(
|
|
23543
|
-
const preEncodedFileLocation = parallelEncoding ?
|
|
23672
|
+
const workingDir = fs18.mkdtempSync(path28.join(os9.tmpdir(), "react-motion-render"));
|
|
23673
|
+
const preEncodedFileLocation = parallelEncoding ? path28.join(workingDir, "pre-encode." + getFileExtensionFromCodec(codec, audioCodec)) : null;
|
|
23544
23674
|
if (onCtrlCExit && workingDir) {
|
|
23545
23675
|
onCtrlCExit(`Delete ${workingDir}`, () => deleteDirectory(workingDir));
|
|
23546
23676
|
}
|
|
@@ -23871,7 +24001,7 @@ var internalRenderMediaRaw = ({
|
|
|
23871
24001
|
reject(err);
|
|
23872
24002
|
}).finally(() => {
|
|
23873
24003
|
if (preEncodedFileLocation !== null && fs18.existsSync(preEncodedFileLocation)) {
|
|
23874
|
-
deleteDirectory(
|
|
24004
|
+
deleteDirectory(path28.dirname(preEncodedFileLocation));
|
|
23875
24005
|
}
|
|
23876
24006
|
if (workingDir && fs18.existsSync(workingDir)) {
|
|
23877
24007
|
deleteDirectory(workingDir);
|
|
@@ -24045,7 +24175,7 @@ var renderMedia = ({
|
|
|
24045
24175
|
|
|
24046
24176
|
// src/render-still.ts
|
|
24047
24177
|
import fs19, { statSync as statSync2 } from "node:fs";
|
|
24048
|
-
import
|
|
24178
|
+
import path29 from "node:path";
|
|
24049
24179
|
import { LicensingInternals as LicensingInternals2 } from "@remotion/licensing";
|
|
24050
24180
|
import { NoReactInternals as NoReactInternals16 } from "remotion/no-react";
|
|
24051
24181
|
var innerRenderStill = async ({
|
|
@@ -24096,7 +24226,7 @@ var innerRenderStill = async ({
|
|
|
24096
24226
|
});
|
|
24097
24227
|
validatePuppeteerTimeout(timeoutInMilliseconds);
|
|
24098
24228
|
validateScale(scale);
|
|
24099
|
-
output = typeof output === "string" ?
|
|
24229
|
+
output = typeof output === "string" ? path29.resolve(process.cwd(), output) : null;
|
|
24100
24230
|
validateJpegQuality(jpegQuality);
|
|
24101
24231
|
if (output) {
|
|
24102
24232
|
if (fs19.existsSync(output)) {
|
package/dist/ffmpeg-args.js
CHANGED
|
@@ -7,7 +7,7 @@ const logger_1 = require("./logger");
|
|
|
7
7
|
const color_space_1 = require("./options/color-space");
|
|
8
8
|
const gop_size_1 = require("./options/gop-size");
|
|
9
9
|
const truthy_1 = require("./truthy");
|
|
10
|
-
const firstEncodingStepOnly = ({ hasPreencoded, proResProfileName, pixelFormat, x264Preset, gopSize, codec, crf, videoBitrate, encodingMaxRate, encodingBufferSize, hardwareAcceleration, }) => {
|
|
10
|
+
const firstEncodingStepOnly = ({ hasPreencoded, proResProfileName, pixelFormat, x264Preset, gopSize, codec, crf, videoBitrate, encodingMaxRate, encodingBufferSize, hardwareAcceleration, hardwareAccelerated, }) => {
|
|
11
11
|
if (hasPreencoded || codec === 'gif') {
|
|
12
12
|
return [];
|
|
13
13
|
}
|
|
@@ -30,6 +30,7 @@ const firstEncodingStepOnly = ({ hasPreencoded, proResProfileName, pixelFormat,
|
|
|
30
30
|
encodingMaxRate,
|
|
31
31
|
encodingBufferSize,
|
|
32
32
|
hardwareAcceleration,
|
|
33
|
+
hardwareAccelerated,
|
|
33
34
|
}),
|
|
34
35
|
].filter(truthy_1.truthy);
|
|
35
36
|
};
|
|
@@ -97,6 +98,7 @@ const generateFfmpegArgs = ({ hasPreencoded, proResProfileName, pixelFormat, x26
|
|
|
97
98
|
x264Preset,
|
|
98
99
|
gopSize,
|
|
99
100
|
hardwareAcceleration,
|
|
101
|
+
hardwareAccelerated,
|
|
100
102
|
}),
|
|
101
103
|
].filter(truthy_1.truthy);
|
|
102
104
|
};
|
package/dist/get-codec-name.js
CHANGED
|
@@ -37,6 +37,13 @@ const getCodecName = ({ codec, encodingMaxRate, encodingBufferSize, crf, hardwar
|
|
|
37
37
|
!unsupportedQualityOption) {
|
|
38
38
|
return { encoderName: 'prores_videotoolbox', hardwareAccelerated: true };
|
|
39
39
|
}
|
|
40
|
+
if (preferredHwAcceleration &&
|
|
41
|
+
process.platform !== 'darwin' &&
|
|
42
|
+
!unsupportedQualityOption) {
|
|
43
|
+
if (hardwareAcceleration === 'required') {
|
|
44
|
+
throw new Error(`Codec "prores" does not support hardware acceleration on ${process.platform}, but "hardwareAcceleration" is set to "required"`);
|
|
45
|
+
}
|
|
46
|
+
}
|
|
40
47
|
warnAboutDisabledHardwareAcceleration();
|
|
41
48
|
return { encoderName: 'prores_ks', hardwareAccelerated: false };
|
|
42
49
|
}
|
|
@@ -46,6 +53,12 @@ const getCodecName = ({ codec, encodingMaxRate, encodingBufferSize, crf, hardwar
|
|
|
46
53
|
!unsupportedQualityOption) {
|
|
47
54
|
return { encoderName: 'h264_videotoolbox', hardwareAccelerated: true };
|
|
48
55
|
}
|
|
56
|
+
// NVENC for Linux/Windows
|
|
57
|
+
if (preferredHwAcceleration &&
|
|
58
|
+
(process.platform === 'linux' || process.platform === 'win32') &&
|
|
59
|
+
!unsupportedQualityOption) {
|
|
60
|
+
return { encoderName: 'h264_nvenc', hardwareAccelerated: true };
|
|
61
|
+
}
|
|
49
62
|
warnAboutDisabledHardwareAcceleration();
|
|
50
63
|
return { encoderName: 'libx264', hardwareAccelerated: false };
|
|
51
64
|
}
|
|
@@ -55,6 +68,12 @@ const getCodecName = ({ codec, encodingMaxRate, encodingBufferSize, crf, hardwar
|
|
|
55
68
|
!unsupportedQualityOption) {
|
|
56
69
|
return { encoderName: 'hevc_videotoolbox', hardwareAccelerated: true };
|
|
57
70
|
}
|
|
71
|
+
// NVENC for Linux/Windows
|
|
72
|
+
if (preferredHwAcceleration &&
|
|
73
|
+
(process.platform === 'linux' || process.platform === 'win32') &&
|
|
74
|
+
!unsupportedQualityOption) {
|
|
75
|
+
return { encoderName: 'hevc_nvenc', hardwareAccelerated: true };
|
|
76
|
+
}
|
|
58
77
|
warnAboutDisabledHardwareAcceleration();
|
|
59
78
|
return { encoderName: 'libx265', hardwareAccelerated: false };
|
|
60
79
|
}
|
|
@@ -81,9 +100,15 @@ const getCodecName = ({ codec, encodingMaxRate, encodingBufferSize, crf, hardwar
|
|
|
81
100
|
return null;
|
|
82
101
|
}
|
|
83
102
|
if (codec === 'h264-mkv') {
|
|
103
|
+
if (hardwareAcceleration === 'required') {
|
|
104
|
+
throw new Error(`Codec "h264-mkv" does not support hardware acceleration on ${process.platform}, but "hardwareAcceleration" is set to "required"`);
|
|
105
|
+
}
|
|
84
106
|
return { encoderName: 'libx264', hardwareAccelerated: false };
|
|
85
107
|
}
|
|
86
108
|
if (codec === 'h264-ts') {
|
|
109
|
+
if (hardwareAcceleration === 'required') {
|
|
110
|
+
throw new Error(`Codec "h264-ts" does not support hardware acceleration on ${process.platform}, but "hardwareAcceleration" is set to "required"`);
|
|
111
|
+
}
|
|
87
112
|
return { encoderName: 'libx264', hardwareAccelerated: false };
|
|
88
113
|
}
|
|
89
114
|
throw new Error(`Could not get codec for ${codec}`);
|
package/dist/options/index.d.ts
CHANGED
|
@@ -574,7 +574,10 @@ export declare const allOptions: {
|
|
|
574
574
|
type: "yuv420p" | "yuv420p10le" | "yuv422p" | "yuv422p10le" | "yuv444p" | "yuv444p10le" | "yuva420p" | "yuva444p10le";
|
|
575
575
|
getValue: ({ commandLine }: {
|
|
576
576
|
commandLine: Record<string, unknown>;
|
|
577
|
-
}
|
|
577
|
+
}, options?: {
|
|
578
|
+
uiPixelFormat: "yuv420p" | "yuv420p10le" | "yuv422p" | "yuv422p10le" | "yuv444p" | "yuv444p10le" | "yuva420p" | "yuva444p10le" | null;
|
|
579
|
+
compositionDefaultPixelFormat: "yuv420p" | "yuv420p10le" | "yuv422p" | "yuv422p10le" | "yuv444p" | "yuv444p10le" | "yuva420p" | "yuva444p10le" | null;
|
|
580
|
+
} | undefined) => {
|
|
578
581
|
source: string;
|
|
579
582
|
value: "yuv420p" | "yuv420p10le" | "yuv422p" | "yuv422p10le" | "yuv444p" | "yuv444p10le" | "yuva420p" | "yuva444p10le";
|
|
580
583
|
};
|
|
@@ -628,7 +631,10 @@ export declare const allOptions: {
|
|
|
628
631
|
type: import("./prores-profile").ProResProfile | undefined;
|
|
629
632
|
getValue: ({ commandLine }: {
|
|
630
633
|
commandLine: Record<string, unknown>;
|
|
631
|
-
}
|
|
634
|
+
}, options?: {
|
|
635
|
+
uiProResProfile: import("./prores-profile").ProResProfile | undefined;
|
|
636
|
+
compositionDefaultProResProfile: import("./prores-profile").ProResProfile | null;
|
|
637
|
+
} | undefined) => {
|
|
632
638
|
source: string;
|
|
633
639
|
value: import("./prores-profile").ProResProfile;
|
|
634
640
|
} | {
|
|
@@ -1231,7 +1237,11 @@ export declare const allOptions: {
|
|
|
1231
1237
|
type: "jpeg" | "none" | "png" | null;
|
|
1232
1238
|
getValue: ({ commandLine }: {
|
|
1233
1239
|
commandLine: Record<string, unknown>;
|
|
1234
|
-
}
|
|
1240
|
+
}, options?: {
|
|
1241
|
+
codec: import("..").CodecOrUndefined;
|
|
1242
|
+
uiVideoImageFormat: "jpeg" | "none" | "png" | null;
|
|
1243
|
+
compositionDefaultVideoImageFormat: "jpeg" | "none" | "png" | null;
|
|
1244
|
+
} | undefined) => {
|
|
1235
1245
|
source: string;
|
|
1236
1246
|
value: "jpeg" | "none" | "png";
|
|
1237
1247
|
} | {
|
|
@@ -7,7 +7,10 @@ export declare const pixelFormatOption: {
|
|
|
7
7
|
type: "yuv420p" | "yuv420p10le" | "yuv422p" | "yuv422p10le" | "yuv444p" | "yuv444p10le" | "yuva420p" | "yuva444p10le";
|
|
8
8
|
getValue: ({ commandLine }: {
|
|
9
9
|
commandLine: Record<string, unknown>;
|
|
10
|
-
}
|
|
10
|
+
}, options?: {
|
|
11
|
+
uiPixelFormat: "yuv420p" | "yuv420p10le" | "yuv422p" | "yuv422p10le" | "yuv444p" | "yuv444p10le" | "yuva420p" | "yuva444p10le" | null;
|
|
12
|
+
compositionDefaultPixelFormat: "yuv420p" | "yuv420p10le" | "yuv422p" | "yuv422p10le" | "yuv444p" | "yuv444p10le" | "yuva420p" | "yuva444p10le" | null;
|
|
13
|
+
} | undefined) => {
|
|
11
14
|
source: string;
|
|
12
15
|
value: "yuv420p" | "yuv420p10le" | "yuv422p" | "yuv422p10le" | "yuv444p" | "yuv444p10le" | "yuva420p" | "yuva444p10le";
|
|
13
16
|
};
|
|
@@ -13,16 +13,28 @@ exports.pixelFormatOption = {
|
|
|
13
13
|
ssrName: 'pixelFormat',
|
|
14
14
|
docLink: 'https://www.remotion.dev/docs/config#setpixelformat',
|
|
15
15
|
type: pixel_format_1.DEFAULT_PIXEL_FORMAT,
|
|
16
|
-
getValue: ({ commandLine }) => {
|
|
16
|
+
getValue: ({ commandLine }, options) => {
|
|
17
|
+
if (options === null || options === void 0 ? void 0 : options.uiPixelFormat) {
|
|
18
|
+
return {
|
|
19
|
+
source: 'via UI',
|
|
20
|
+
value: options.uiPixelFormat,
|
|
21
|
+
};
|
|
22
|
+
}
|
|
17
23
|
if (commandLine[cliFlag] !== undefined) {
|
|
18
24
|
return {
|
|
19
|
-
source: '
|
|
25
|
+
source: 'from --pixel-format flag',
|
|
20
26
|
value: commandLine[cliFlag],
|
|
21
27
|
};
|
|
22
28
|
}
|
|
29
|
+
if (options && options.compositionDefaultPixelFormat !== null) {
|
|
30
|
+
return {
|
|
31
|
+
source: 'via calculateMetadata',
|
|
32
|
+
value: options.compositionDefaultPixelFormat,
|
|
33
|
+
};
|
|
34
|
+
}
|
|
23
35
|
if (currentPixelFormat !== pixel_format_1.DEFAULT_PIXEL_FORMAT) {
|
|
24
36
|
return {
|
|
25
|
-
source: '
|
|
37
|
+
source: 'Config file',
|
|
26
38
|
value: currentPixelFormat,
|
|
27
39
|
};
|
|
28
40
|
}
|
|
@@ -8,7 +8,10 @@ export declare const proResProfileOption: {
|
|
|
8
8
|
type: ProResProfile | undefined;
|
|
9
9
|
getValue: ({ commandLine }: {
|
|
10
10
|
commandLine: Record<string, unknown>;
|
|
11
|
-
}
|
|
11
|
+
}, options?: {
|
|
12
|
+
uiProResProfile: ProResProfile | undefined;
|
|
13
|
+
compositionDefaultProResProfile: ProResProfile | null;
|
|
14
|
+
} | undefined) => {
|
|
12
15
|
source: string;
|
|
13
16
|
value: ProResProfile;
|
|
14
17
|
} | {
|
|
@@ -23,16 +23,28 @@ exports.proResProfileOption = {
|
|
|
23
23
|
ssrName: 'proResProfile',
|
|
24
24
|
docLink: 'https://www.remotion.dev/docs/config#setproresprofile',
|
|
25
25
|
type: undefined,
|
|
26
|
-
getValue: ({ commandLine }) => {
|
|
26
|
+
getValue: ({ commandLine }, options) => {
|
|
27
|
+
if (options === null || options === void 0 ? void 0 : options.uiProResProfile) {
|
|
28
|
+
return {
|
|
29
|
+
source: 'via UI',
|
|
30
|
+
value: options.uiProResProfile,
|
|
31
|
+
};
|
|
32
|
+
}
|
|
27
33
|
if (commandLine[cliFlag] !== undefined) {
|
|
28
34
|
return {
|
|
29
|
-
source: '
|
|
35
|
+
source: 'from --prores-profile flag',
|
|
30
36
|
value: String(commandLine[cliFlag]),
|
|
31
37
|
};
|
|
32
38
|
}
|
|
39
|
+
if (options && options.compositionDefaultProResProfile !== null) {
|
|
40
|
+
return {
|
|
41
|
+
source: 'via calculateMetadata',
|
|
42
|
+
value: options.compositionDefaultProResProfile,
|
|
43
|
+
};
|
|
44
|
+
}
|
|
33
45
|
if (proResProfile !== undefined) {
|
|
34
46
|
return {
|
|
35
|
-
source: '
|
|
47
|
+
source: 'Config file',
|
|
36
48
|
value: proResProfile,
|
|
37
49
|
};
|
|
38
50
|
}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { CodecOrUndefined } from '../codec';
|
|
1
2
|
export declare const videoImageFormatOption: {
|
|
2
3
|
name: string;
|
|
3
4
|
cliFlag: "image-format";
|
|
@@ -7,7 +8,11 @@ export declare const videoImageFormatOption: {
|
|
|
7
8
|
type: "jpeg" | "none" | "png" | null;
|
|
8
9
|
getValue: ({ commandLine }: {
|
|
9
10
|
commandLine: Record<string, unknown>;
|
|
10
|
-
}
|
|
11
|
+
}, options?: {
|
|
12
|
+
codec: CodecOrUndefined;
|
|
13
|
+
uiVideoImageFormat: "jpeg" | "none" | "png" | null;
|
|
14
|
+
compositionDefaultVideoImageFormat: "jpeg" | "none" | "png" | null;
|
|
15
|
+
} | undefined) => {
|
|
11
16
|
source: string;
|
|
12
17
|
value: "jpeg" | "none" | "png";
|
|
13
18
|
} | {
|
|
@@ -3,6 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.videoImageFormatOption = void 0;
|
|
4
4
|
const jsx_runtime_1 = require("react/jsx-runtime");
|
|
5
5
|
const image_format_1 = require("../image-format");
|
|
6
|
+
const is_audio_codec_1 = require("../is-audio-codec");
|
|
6
7
|
let currentVideoImageFormat = null;
|
|
7
8
|
const cliFlag = 'image-format';
|
|
8
9
|
exports.videoImageFormatOption = {
|
|
@@ -13,23 +14,64 @@ exports.videoImageFormatOption = {
|
|
|
13
14
|
ssrName: 'imageFormat',
|
|
14
15
|
docLink: 'https://www.remotion.dev/docs/renderer/render-media#imageformat',
|
|
15
16
|
type: null,
|
|
16
|
-
getValue: ({ commandLine }) => {
|
|
17
|
+
getValue: ({ commandLine }, options) => {
|
|
18
|
+
if (options === null || options === void 0 ? void 0 : options.uiVideoImageFormat) {
|
|
19
|
+
return {
|
|
20
|
+
source: 'via UI',
|
|
21
|
+
value: options.uiVideoImageFormat,
|
|
22
|
+
};
|
|
23
|
+
}
|
|
17
24
|
if (commandLine[cliFlag] !== undefined) {
|
|
18
25
|
const value = commandLine[cliFlag];
|
|
19
26
|
if (!image_format_1.validVideoImageFormats.includes(value)) {
|
|
20
27
|
throw new Error(`Invalid video image format: ${value}. Must be one of: ${image_format_1.validVideoImageFormats.join(', ')}`);
|
|
21
28
|
}
|
|
22
29
|
return {
|
|
23
|
-
source: '
|
|
30
|
+
source: 'from --image-format flag',
|
|
24
31
|
value,
|
|
25
32
|
};
|
|
26
33
|
}
|
|
34
|
+
if (options && options.compositionDefaultVideoImageFormat !== null) {
|
|
35
|
+
return {
|
|
36
|
+
source: 'via calculateMetadata',
|
|
37
|
+
value: options.compositionDefaultVideoImageFormat,
|
|
38
|
+
};
|
|
39
|
+
}
|
|
27
40
|
if (currentVideoImageFormat !== null) {
|
|
28
41
|
return {
|
|
29
|
-
source: '
|
|
42
|
+
source: 'Config file',
|
|
30
43
|
value: currentVideoImageFormat,
|
|
31
44
|
};
|
|
32
45
|
}
|
|
46
|
+
if (options) {
|
|
47
|
+
if ((0, is_audio_codec_1.isAudioCodec)(options.codec)) {
|
|
48
|
+
return {
|
|
49
|
+
source: 'default',
|
|
50
|
+
value: 'none',
|
|
51
|
+
};
|
|
52
|
+
}
|
|
53
|
+
if (options.codec === 'h264' ||
|
|
54
|
+
options.codec === 'h264-mkv' ||
|
|
55
|
+
options.codec === 'h264-ts' ||
|
|
56
|
+
options.codec === 'h265' ||
|
|
57
|
+
options.codec === 'av1' ||
|
|
58
|
+
options.codec === 'vp8' ||
|
|
59
|
+
options.codec === 'vp9' ||
|
|
60
|
+
options.codec === 'prores' ||
|
|
61
|
+
options.codec === 'gif') {
|
|
62
|
+
return {
|
|
63
|
+
source: 'default',
|
|
64
|
+
value: 'jpeg',
|
|
65
|
+
};
|
|
66
|
+
}
|
|
67
|
+
if (options.codec === undefined) {
|
|
68
|
+
return {
|
|
69
|
+
source: 'default',
|
|
70
|
+
value: 'png',
|
|
71
|
+
};
|
|
72
|
+
}
|
|
73
|
+
throw new Error('Unrecognized codec ' + options.codec);
|
|
74
|
+
}
|
|
33
75
|
return {
|
|
34
76
|
source: 'default',
|
|
35
77
|
value: null,
|
package/dist/prespawn-ffmpeg.js
CHANGED
|
@@ -8,6 +8,7 @@ const get_prores_profile_name_1 = require("./get-prores-profile-name");
|
|
|
8
8
|
const logger_1 = require("./logger");
|
|
9
9
|
const parse_ffmpeg_progress_1 = require("./parse-ffmpeg-progress");
|
|
10
10
|
const pixel_format_1 = require("./pixel-format");
|
|
11
|
+
const probe_encoder_1 = require("./probe-encoder");
|
|
11
12
|
const validate_1 = require("./validate");
|
|
12
13
|
const validate_even_dimensions_with_codec_1 = require("./validate-even-dimensions-with-codec");
|
|
13
14
|
const prespawnFfmpeg = (options) => {
|
|
@@ -29,6 +30,16 @@ const prespawnFfmpeg = (options) => {
|
|
|
29
30
|
const pixelFormat = (_c = options.pixelFormat) !== null && _c !== void 0 ? _c : pixel_format_1.DEFAULT_PIXEL_FORMAT;
|
|
30
31
|
const proResProfileName = (0, get_prores_profile_name_1.getProResProfileName)(codec, options.proResProfile);
|
|
31
32
|
(0, pixel_format_1.validateSelectedPixelFormatAndCodecCombination)(pixelFormat, codec);
|
|
33
|
+
const resolvedHardwareAcceleration = (0, probe_encoder_1.resolveHardwareAcceleration)({
|
|
34
|
+
codec,
|
|
35
|
+
hardwareAcceleration: options.hardwareAcceleration,
|
|
36
|
+
binariesDirectory: options.binariesDirectory,
|
|
37
|
+
indent: options.indent,
|
|
38
|
+
logLevel: options.logLevel,
|
|
39
|
+
crf: options.crf,
|
|
40
|
+
encodingMaxRate: options.encodingMaxRate,
|
|
41
|
+
encodingBufferSize: options.encodingBufferSize,
|
|
42
|
+
});
|
|
32
43
|
const ffmpegArgs = [
|
|
33
44
|
['-r', options.fps],
|
|
34
45
|
...[
|
|
@@ -51,7 +62,7 @@ const prespawnFfmpeg = (options) => {
|
|
|
51
62
|
encodingMaxRate: options.encodingMaxRate,
|
|
52
63
|
encodingBufferSize: options.encodingBufferSize,
|
|
53
64
|
colorSpace: options.colorSpace,
|
|
54
|
-
hardwareAcceleration:
|
|
65
|
+
hardwareAcceleration: resolvedHardwareAcceleration,
|
|
55
66
|
indent: options.indent,
|
|
56
67
|
logLevel: options.logLevel,
|
|
57
68
|
}),
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Probes FFmpeg to check if a specific encoder is available.
|
|
3
|
+
* Returns true if the encoder is supported, false otherwise.
|
|
4
|
+
*/
|
|
5
|
+
export declare const probeEncoderAvailability: ({ encoderName, binariesDirectory, indent, logLevel, }: {
|
|
6
|
+
encoderName: string;
|
|
7
|
+
binariesDirectory: string | null;
|
|
8
|
+
indent: boolean;
|
|
9
|
+
logLevel: "error" | "info" | "trace" | "verbose" | "warn";
|
|
10
|
+
}) => boolean;
|
|
11
|
+
/**
|
|
12
|
+
* Resolves the effective hardware acceleration setting by probing FFmpeg
|
|
13
|
+
* for encoder availability. If the preferred hw encoder is not available:
|
|
14
|
+
* - `if-possible` mode: falls back to software encoding
|
|
15
|
+
* - `required` mode: throws a clear error
|
|
16
|
+
*/
|
|
17
|
+
export declare const resolveHardwareAcceleration: ({ codec, hardwareAcceleration, binariesDirectory, indent, logLevel, crf, encodingMaxRate, encodingBufferSize, }: {
|
|
18
|
+
codec: "aac" | "av1" | "gif" | "h264" | "h264-mkv" | "h264-ts" | "h265" | "mp3" | "prores" | "vp8" | "vp9" | "wav";
|
|
19
|
+
hardwareAcceleration: "disable" | "if-possible" | "required";
|
|
20
|
+
binariesDirectory: string | null;
|
|
21
|
+
indent: boolean;
|
|
22
|
+
logLevel: "error" | "info" | "trace" | "verbose" | "warn";
|
|
23
|
+
crf: unknown;
|
|
24
|
+
encodingMaxRate: string | null;
|
|
25
|
+
encodingBufferSize: string | null;
|
|
26
|
+
}) => "disable" | "if-possible" | "required";
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.resolveHardwareAcceleration = exports.probeEncoderAvailability = void 0;
|
|
7
|
+
const node_child_process_1 = require("node:child_process");
|
|
8
|
+
const path_1 = __importDefault(require("path"));
|
|
9
|
+
const get_executable_path_1 = require("./compositor/get-executable-path");
|
|
10
|
+
const get_explicit_env_1 = require("./compositor/get-explicit-env");
|
|
11
|
+
const make_file_executable_1 = require("./compositor/make-file-executable");
|
|
12
|
+
const get_codec_name_1 = require("./get-codec-name");
|
|
13
|
+
const logger_1 = require("./logger");
|
|
14
|
+
/**
|
|
15
|
+
* Probes FFmpeg to check if a specific encoder is available.
|
|
16
|
+
* Returns true if the encoder is supported, false otherwise.
|
|
17
|
+
*/
|
|
18
|
+
const probeEncoderAvailability = ({ encoderName, binariesDirectory, indent, logLevel, }) => {
|
|
19
|
+
try {
|
|
20
|
+
const executablePath = (0, get_executable_path_1.getExecutablePath)({
|
|
21
|
+
type: 'ffmpeg',
|
|
22
|
+
indent,
|
|
23
|
+
logLevel,
|
|
24
|
+
binariesDirectory,
|
|
25
|
+
});
|
|
26
|
+
(0, make_file_executable_1.makeFileExecutableIfItIsNot)(executablePath);
|
|
27
|
+
const cwd = path_1.default.dirname(executablePath);
|
|
28
|
+
const result = (0, node_child_process_1.execFileSync)(executablePath, ['-encoders'], {
|
|
29
|
+
encoding: 'utf-8',
|
|
30
|
+
env: (0, get_explicit_env_1.getExplicitEnv)(cwd),
|
|
31
|
+
stdio: ['pipe', 'pipe', 'pipe'],
|
|
32
|
+
timeout: 10000,
|
|
33
|
+
});
|
|
34
|
+
// FFmpeg -encoders output format: " V..... encoder_name"
|
|
35
|
+
// Escape regex metacharacters and use word-boundary to avoid false positives
|
|
36
|
+
const escaped = encoderName.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
|
|
37
|
+
const encoderRegex = new RegExp(`\\b${escaped}\\b`);
|
|
38
|
+
const hasEncoder = encoderRegex.test(result);
|
|
39
|
+
if (!hasEncoder) {
|
|
40
|
+
logger_1.Log.verbose({ indent, logLevel, tag: 'probeEncoderAvailability()' }, `Encoder "${encoderName}" not found in FFmpeg build. Falling back to software encoding.`);
|
|
41
|
+
}
|
|
42
|
+
return hasEncoder;
|
|
43
|
+
}
|
|
44
|
+
catch (err) {
|
|
45
|
+
logger_1.Log.verbose({ indent, logLevel, tag: 'probeEncoderAvailability()' }, `Failed to probe FFmpeg for encoder "${encoderName}": ${err}. Falling back to software encoding.`);
|
|
46
|
+
return false;
|
|
47
|
+
}
|
|
48
|
+
};
|
|
49
|
+
exports.probeEncoderAvailability = probeEncoderAvailability;
|
|
50
|
+
/**
|
|
51
|
+
* Resolves the effective hardware acceleration setting by probing FFmpeg
|
|
52
|
+
* for encoder availability. If the preferred hw encoder is not available:
|
|
53
|
+
* - `if-possible` mode: falls back to software encoding
|
|
54
|
+
* - `required` mode: throws a clear error
|
|
55
|
+
*/
|
|
56
|
+
const resolveHardwareAcceleration = ({ codec, hardwareAcceleration, binariesDirectory, indent, logLevel, crf, encodingMaxRate, encodingBufferSize, }) => {
|
|
57
|
+
if (hardwareAcceleration === 'disable') {
|
|
58
|
+
return 'disable';
|
|
59
|
+
}
|
|
60
|
+
const preferred = (0, get_codec_name_1.getCodecName)({
|
|
61
|
+
codec,
|
|
62
|
+
hardwareAcceleration,
|
|
63
|
+
crf,
|
|
64
|
+
encodingMaxRate,
|
|
65
|
+
encodingBufferSize,
|
|
66
|
+
logLevel,
|
|
67
|
+
indent,
|
|
68
|
+
});
|
|
69
|
+
// Audio codecs return null, no probing needed
|
|
70
|
+
if (preferred === null) {
|
|
71
|
+
return hardwareAcceleration;
|
|
72
|
+
}
|
|
73
|
+
// Only probe if getCodecName selected a hardware-accelerated encoder
|
|
74
|
+
if (!preferred.hardwareAccelerated) {
|
|
75
|
+
return hardwareAcceleration;
|
|
76
|
+
}
|
|
77
|
+
const encoderAvailable = (0, exports.probeEncoderAvailability)({
|
|
78
|
+
encoderName: preferred.encoderName,
|
|
79
|
+
binariesDirectory,
|
|
80
|
+
indent,
|
|
81
|
+
logLevel,
|
|
82
|
+
});
|
|
83
|
+
if (encoderAvailable) {
|
|
84
|
+
return hardwareAcceleration;
|
|
85
|
+
}
|
|
86
|
+
// Encoder not available in FFmpeg
|
|
87
|
+
if (hardwareAcceleration === 'if-possible') {
|
|
88
|
+
logger_1.Log.verbose({ indent, logLevel, tag: 'resolveHardwareAcceleration()' }, `Hardware encoder "${preferred.encoderName}" not available. Falling back to software encoding.`);
|
|
89
|
+
return 'disable';
|
|
90
|
+
}
|
|
91
|
+
// hardwareAcceleration === 'required'
|
|
92
|
+
throw new Error(`Hardware encoder "${preferred.encoderName}" is not available in your FFmpeg build. ` +
|
|
93
|
+
`Install an FFmpeg with ${preferred.encoderName} support, or use "if-possible" mode instead of "required".`);
|
|
94
|
+
};
|
|
95
|
+
exports.resolveHardwareAcceleration = resolveHardwareAcceleration;
|
package/dist/render-media.js
CHANGED
|
@@ -78,6 +78,7 @@ const internalRenderMediaRaw = ({ proResProfile, x264Preset, gopSize, crf, compo
|
|
|
78
78
|
encodingMaxRate,
|
|
79
79
|
encodingBufferSize,
|
|
80
80
|
hardwareAcceleration,
|
|
81
|
+
hardwareAccelerated: false,
|
|
81
82
|
});
|
|
82
83
|
(0, gop_size_1.validateGopSize)(gopSize);
|
|
83
84
|
(0, validate_videobitrate_1.validateBitrate)(audioBitrate, 'audioBitrate');
|
|
@@ -26,6 +26,7 @@ const color_space_1 = require("./options/color-space");
|
|
|
26
26
|
const gop_size_1 = require("./options/gop-size");
|
|
27
27
|
const parse_ffmpeg_progress_1 = require("./parse-ffmpeg-progress");
|
|
28
28
|
const pixel_format_1 = require("./pixel-format");
|
|
29
|
+
const probe_encoder_1 = require("./probe-encoder");
|
|
29
30
|
const prores_profile_1 = require("./prores-profile");
|
|
30
31
|
const render_has_audio_1 = require("./render-has-audio");
|
|
31
32
|
const validate_1 = require("./validate");
|
|
@@ -113,6 +114,7 @@ const innerStitchFramesToVideo = async ({ assetsInfo, audioBitrate, audioCodec:
|
|
|
113
114
|
encodingMaxRate: maxRate,
|
|
114
115
|
encodingBufferSize: bufferSize,
|
|
115
116
|
hardwareAcceleration,
|
|
117
|
+
hardwareAccelerated: false,
|
|
116
118
|
});
|
|
117
119
|
(0, pixel_format_1.validateSelectedPixelFormatAndCodecCombination)(pixelFormat, codec);
|
|
118
120
|
const updateProgress = (muxProgress) => {
|
|
@@ -176,6 +178,16 @@ const innerStitchFramesToVideo = async ({ assetsInfo, audioBitrate, audioCodec:
|
|
|
176
178
|
assetsInfo.downloadMap.allowCleanup();
|
|
177
179
|
return Promise.resolve(file);
|
|
178
180
|
}
|
|
181
|
+
const resolvedHardwareAcceleration = (0, probe_encoder_1.resolveHardwareAcceleration)({
|
|
182
|
+
codec,
|
|
183
|
+
hardwareAcceleration,
|
|
184
|
+
binariesDirectory,
|
|
185
|
+
indent: indent !== null && indent !== void 0 ? indent : false,
|
|
186
|
+
logLevel,
|
|
187
|
+
crf,
|
|
188
|
+
encodingMaxRate: maxRate,
|
|
189
|
+
encodingBufferSize: bufferSize,
|
|
190
|
+
});
|
|
179
191
|
const ffmpegArgs = [
|
|
180
192
|
...(preEncodedFileLocation
|
|
181
193
|
? [['-i', preEncodedFileLocation]]
|
|
@@ -205,7 +217,7 @@ const innerStitchFramesToVideo = async ({ assetsInfo, audioBitrate, audioCodec:
|
|
|
205
217
|
x264Preset,
|
|
206
218
|
gopSize,
|
|
207
219
|
colorSpace,
|
|
208
|
-
hardwareAcceleration,
|
|
220
|
+
hardwareAcceleration: resolvedHardwareAcceleration,
|
|
209
221
|
indent,
|
|
210
222
|
logLevel,
|
|
211
223
|
}),
|
package/package.json
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
"url": "https://github.com/remotion-dev/remotion/tree/main/packages/renderer"
|
|
4
4
|
},
|
|
5
5
|
"name": "@remotion/renderer",
|
|
6
|
-
"version": "4.0.
|
|
6
|
+
"version": "4.0.484",
|
|
7
7
|
"description": "Render Remotion videos using Node.js or Bun",
|
|
8
8
|
"main": "dist/index.js",
|
|
9
9
|
"types": "dist/index.d.ts",
|
|
@@ -22,11 +22,11 @@
|
|
|
22
22
|
},
|
|
23
23
|
"dependencies": {
|
|
24
24
|
"execa": "5.1.1",
|
|
25
|
-
"remotion": "4.0.
|
|
26
|
-
"@remotion/streaming": "4.0.
|
|
25
|
+
"remotion": "4.0.484",
|
|
26
|
+
"@remotion/streaming": "4.0.484",
|
|
27
27
|
"source-map": "0.8.0-beta.0",
|
|
28
28
|
"ws": "8.21.0",
|
|
29
|
-
"@remotion/licensing": "4.0.
|
|
29
|
+
"@remotion/licensing": "4.0.484"
|
|
30
30
|
},
|
|
31
31
|
"peerDependencies": {
|
|
32
32
|
"react": ">=16.8.0",
|
|
@@ -40,19 +40,19 @@
|
|
|
40
40
|
"react-dom": "19.2.3",
|
|
41
41
|
"@typescript/native-preview": "7.0.0-dev.20260217.1",
|
|
42
42
|
"@types/ws": "8.5.10",
|
|
43
|
-
"@remotion/example-videos": "4.0.
|
|
44
|
-
"@remotion/eslint-config-internal": "4.0.
|
|
43
|
+
"@remotion/example-videos": "4.0.484",
|
|
44
|
+
"@remotion/eslint-config-internal": "4.0.484",
|
|
45
45
|
"eslint": "9.19.0",
|
|
46
46
|
"@types/node": "20.12.14"
|
|
47
47
|
},
|
|
48
48
|
"optionalDependencies": {
|
|
49
|
-
"@remotion/compositor-darwin-arm64": "4.0.
|
|
50
|
-
"@remotion/compositor-darwin-x64": "4.0.
|
|
51
|
-
"@remotion/compositor-linux-arm64-gnu": "4.0.
|
|
52
|
-
"@remotion/compositor-linux-arm64-musl": "4.0.
|
|
53
|
-
"@remotion/compositor-linux-x64-gnu": "4.0.
|
|
54
|
-
"@remotion/compositor-linux-x64-musl": "4.0.
|
|
55
|
-
"@remotion/compositor-win32-x64-msvc": "4.0.
|
|
49
|
+
"@remotion/compositor-darwin-arm64": "4.0.484",
|
|
50
|
+
"@remotion/compositor-darwin-x64": "4.0.484",
|
|
51
|
+
"@remotion/compositor-linux-arm64-gnu": "4.0.484",
|
|
52
|
+
"@remotion/compositor-linux-arm64-musl": "4.0.484",
|
|
53
|
+
"@remotion/compositor-linux-x64-gnu": "4.0.484",
|
|
54
|
+
"@remotion/compositor-linux-x64-musl": "4.0.484",
|
|
55
|
+
"@remotion/compositor-win32-x64-msvc": "4.0.484"
|
|
56
56
|
},
|
|
57
57
|
"keywords": [
|
|
58
58
|
"remotion",
|