@remotion/cli 3.2.27 → 3.2.28
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/benchmark.d.ts +1 -0
- package/dist/benchmark.js +180 -0
- package/dist/compositions.js +1 -0
- package/dist/config/image-format.js +8 -1
- package/dist/config/log.d.ts +1 -1
- package/dist/determine-image-format.d.ts +11 -0
- package/dist/determine-image-format.js +48 -0
- package/dist/event-source-events.d.ts +3 -0
- package/dist/event-source.js +1 -1
- package/dist/get-cli-options.d.ts +11 -3
- package/dist/get-cli-options.js +22 -28
- package/dist/get-env.d.ts +1 -1
- package/dist/get-env.js +58 -6
- package/dist/get-final-output-codec.d.ts +9 -5
- package/dist/get-final-output-codec.js +56 -56
- package/dist/get-render-media-options.d.ts +7 -0
- package/dist/get-render-media-options.js +44 -0
- package/dist/index.d.ts +19 -2
- package/dist/index.js +10 -1
- package/dist/parse-command-line.js +0 -3
- package/dist/preview-server/routes.d.ts +2 -1
- package/dist/preview-server/routes.js +4 -2
- package/dist/preview-server/start-server.d.ts +1 -1
- package/dist/preview-server/start-server.js +2 -1
- package/dist/preview.js +10 -2
- package/dist/print-help.js +6 -3
- package/dist/progress-bar.js +3 -1
- package/dist/render.js +18 -30
- package/dist/still.js +12 -24
- package/dist/validate-image-format.d.ts +2 -0
- package/dist/validate-image-format.js +15 -0
- package/package.json +7 -7
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare const benchmarkCommand: (remotionRoot: string, args: string[]) => Promise<void>;
|
|
@@ -0,0 +1,180 @@
|
|
|
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.benchmarkCommand = void 0;
|
|
7
|
+
const renderer_1 = require("@remotion/renderer");
|
|
8
|
+
const path_1 = __importDefault(require("path"));
|
|
9
|
+
const chalk_1 = require("./chalk");
|
|
10
|
+
const config_1 = require("./config");
|
|
11
|
+
const get_cli_options_1 = require("./get-cli-options");
|
|
12
|
+
const get_render_media_options_1 = require("./get-render-media-options");
|
|
13
|
+
const log_1 = require("./log");
|
|
14
|
+
const make_progress_bar_1 = require("./make-progress-bar");
|
|
15
|
+
const parse_command_line_1 = require("./parse-command-line");
|
|
16
|
+
const progress_bar_1 = require("./progress-bar");
|
|
17
|
+
const setup_cache_1 = require("./setup-cache");
|
|
18
|
+
const truthy_1 = require("./truthy");
|
|
19
|
+
const DEFAULT_RUNS = 3;
|
|
20
|
+
const getValidConcurrency = (renderMediaOptions) => {
|
|
21
|
+
var _a;
|
|
22
|
+
const concurrency = 'concurrency' in renderMediaOptions
|
|
23
|
+
? (_a = renderMediaOptions.concurrency) !== null && _a !== void 0 ? _a : null
|
|
24
|
+
: null;
|
|
25
|
+
const { concurrencies } = parse_command_line_1.parsedCli;
|
|
26
|
+
if (!concurrencies) {
|
|
27
|
+
return [renderer_1.RenderInternals.getActualConcurrency(concurrency)];
|
|
28
|
+
}
|
|
29
|
+
return concurrencies
|
|
30
|
+
.split(',')
|
|
31
|
+
.map((c) => parseInt(c.trim(), 10));
|
|
32
|
+
};
|
|
33
|
+
const runBenchmark = async (runs, options, onProgress) => {
|
|
34
|
+
const timeTaken = [];
|
|
35
|
+
for (let run = 0; run < runs; ++run) {
|
|
36
|
+
const startTime = performance.now();
|
|
37
|
+
await (0, renderer_1.renderMedia)({
|
|
38
|
+
...options,
|
|
39
|
+
onProgress: ({ progress }) => onProgress === null || onProgress === void 0 ? void 0 : onProgress(run, progress),
|
|
40
|
+
});
|
|
41
|
+
const endTime = performance.now();
|
|
42
|
+
timeTaken.push(endTime - startTime);
|
|
43
|
+
}
|
|
44
|
+
return timeTaken;
|
|
45
|
+
};
|
|
46
|
+
const formatTime = (time) => {
|
|
47
|
+
let ret = '';
|
|
48
|
+
const hours = Math.floor(time / (60 * 60 * 1000));
|
|
49
|
+
if (hours) {
|
|
50
|
+
ret = `${hours}h`;
|
|
51
|
+
}
|
|
52
|
+
time %= 60 * 60 * 1000;
|
|
53
|
+
const minutes = Math.floor(time / (60 * 1000));
|
|
54
|
+
if (minutes) {
|
|
55
|
+
ret = `${ret}${minutes}m`;
|
|
56
|
+
}
|
|
57
|
+
time %= 60 * 1000;
|
|
58
|
+
const seconds = (time / 1000).toFixed(5);
|
|
59
|
+
if (seconds) {
|
|
60
|
+
ret = `${ret}${seconds}s`;
|
|
61
|
+
}
|
|
62
|
+
return ret;
|
|
63
|
+
};
|
|
64
|
+
const avg = (time) => time.reduce((prev, curr) => prev + curr) / time.length;
|
|
65
|
+
const stdDev = (time) => {
|
|
66
|
+
const mean = avg(time);
|
|
67
|
+
return Math.sqrt(time.map((x) => (x - mean) ** 2).reduce((a, b) => a + b) / time.length);
|
|
68
|
+
};
|
|
69
|
+
const getResults = (results, runs) => {
|
|
70
|
+
const mean = avg(results);
|
|
71
|
+
const dev = stdDev(results);
|
|
72
|
+
const max = Math.max(...results);
|
|
73
|
+
const min = Math.min(...results);
|
|
74
|
+
return ` Time (${chalk_1.chalk.green('mean')} ± ${chalk_1.chalk.green('σ')}): ${chalk_1.chalk.green(formatTime(mean))} ± ${chalk_1.chalk.green(formatTime(dev))}\n Range (${chalk_1.chalk.blue('min')} ... ${chalk_1.chalk.red('max')}): ${chalk_1.chalk.blue(formatTime(min))} ... ${chalk_1.chalk.red(formatTime(max))} \t ${chalk_1.chalk.gray(`${runs} runs`)}
|
|
75
|
+
`;
|
|
76
|
+
};
|
|
77
|
+
const makeBenchmarkProgressBar = ({ totalRuns, run, progress, doneIn, }) => {
|
|
78
|
+
const totalProgress = (run + progress) / totalRuns;
|
|
79
|
+
return [
|
|
80
|
+
`Rendering (${run + 1} out of ${totalRuns} runs)`,
|
|
81
|
+
(0, make_progress_bar_1.makeProgressBar)(totalProgress),
|
|
82
|
+
doneIn === null
|
|
83
|
+
? `${(totalProgress * 100).toFixed(2)}% `
|
|
84
|
+
: chalk_1.chalk.gray(doneIn),
|
|
85
|
+
].join(' ');
|
|
86
|
+
};
|
|
87
|
+
const benchmarkCommand = async (remotionRoot, args) => {
|
|
88
|
+
var _a, _b;
|
|
89
|
+
const runs = (_a = parse_command_line_1.parsedCli.runs) !== null && _a !== void 0 ? _a : DEFAULT_RUNS;
|
|
90
|
+
const filePath = args[0];
|
|
91
|
+
if (!filePath) {
|
|
92
|
+
log_1.Log.error('No entry file passed.');
|
|
93
|
+
log_1.Log.info('Pass an additional argument specifying the entry file');
|
|
94
|
+
log_1.Log.info();
|
|
95
|
+
log_1.Log.info(`$ remotion benchmark <entry file>`);
|
|
96
|
+
process.exit(1);
|
|
97
|
+
}
|
|
98
|
+
const fullPath = path_1.default.join(process.cwd(), filePath);
|
|
99
|
+
const { inputProps, envVariables, browserExecutable, ffmpegExecutable, ffprobeExecutable, chromiumOptions, port, puppeteerTimeout, browser, scale, publicDir, } = await (0, get_cli_options_1.getCliOptions)({
|
|
100
|
+
isLambda: false,
|
|
101
|
+
type: 'series',
|
|
102
|
+
codec: 'h264',
|
|
103
|
+
});
|
|
104
|
+
const browserInstance = (0, renderer_1.openBrowser)(browser, {
|
|
105
|
+
browserExecutable,
|
|
106
|
+
shouldDumpIo: renderer_1.RenderInternals.isEqualOrBelowLogLevel(config_1.ConfigInternals.Logging.getLogLevel(), 'verbose'),
|
|
107
|
+
chromiumOptions,
|
|
108
|
+
forceDeviceScaleFactor: scale,
|
|
109
|
+
});
|
|
110
|
+
const { urlOrBundle: bundleLocation, cleanup: cleanupBundle } = await (0, setup_cache_1.bundleOnCliOrTakeServeUrl)({
|
|
111
|
+
fullPath,
|
|
112
|
+
publicDir,
|
|
113
|
+
remotionRoot,
|
|
114
|
+
steps: ['bundling'],
|
|
115
|
+
});
|
|
116
|
+
const puppeteerInstance = await browserInstance;
|
|
117
|
+
const comps = await (0, renderer_1.getCompositions)(bundleLocation, {
|
|
118
|
+
inputProps,
|
|
119
|
+
envVariables,
|
|
120
|
+
chromiumOptions,
|
|
121
|
+
timeoutInMilliseconds: puppeteerTimeout,
|
|
122
|
+
ffmpegExecutable,
|
|
123
|
+
ffprobeExecutable,
|
|
124
|
+
port,
|
|
125
|
+
puppeteerInstance,
|
|
126
|
+
});
|
|
127
|
+
const ids = ((_b = args[1]) !== null && _b !== void 0 ? _b : '')
|
|
128
|
+
.split(',')
|
|
129
|
+
.map((c) => c.trim())
|
|
130
|
+
.filter(truthy_1.truthy);
|
|
131
|
+
const compositions = ids.map((compId) => {
|
|
132
|
+
const composition = comps.find((c) => c.id === compId);
|
|
133
|
+
if (!composition) {
|
|
134
|
+
throw new Error(`No composition with the ID "${compId}" found.`);
|
|
135
|
+
}
|
|
136
|
+
return composition;
|
|
137
|
+
});
|
|
138
|
+
if (compositions.length === 0) {
|
|
139
|
+
log_1.Log.error('No composition IDs passed. Add another argument to the command specifying at least 1 composition ID.');
|
|
140
|
+
}
|
|
141
|
+
const benchmark = {};
|
|
142
|
+
let count = 1;
|
|
143
|
+
const { codec, reason: codecReason } = (0, get_cli_options_1.getFinalCodec)({
|
|
144
|
+
downloadName: null,
|
|
145
|
+
outName: null,
|
|
146
|
+
});
|
|
147
|
+
for (const composition of compositions) {
|
|
148
|
+
const renderMediaOptions = await (0, get_render_media_options_1.getRenderMediaOptions)({
|
|
149
|
+
config: composition,
|
|
150
|
+
outputLocation: undefined,
|
|
151
|
+
serveUrl: bundleLocation,
|
|
152
|
+
codec,
|
|
153
|
+
});
|
|
154
|
+
const concurrency = getValidConcurrency(renderMediaOptions);
|
|
155
|
+
benchmark[composition.id] = {};
|
|
156
|
+
for (const con of concurrency) {
|
|
157
|
+
const benchmarkProgress = (0, progress_bar_1.createOverwriteableCliOutput)((0, parse_command_line_1.quietFlagProvided)());
|
|
158
|
+
log_1.Log.info();
|
|
159
|
+
log_1.Log.info(`${chalk_1.chalk.bold(`Benchmark #${count++}:`)} ${chalk_1.chalk.gray(`composition=${composition.id} concurrency=${con} codec=${codec} (${codecReason})`)}`);
|
|
160
|
+
const timeTaken = await runBenchmark(runs, {
|
|
161
|
+
...renderMediaOptions,
|
|
162
|
+
puppeteerInstance,
|
|
163
|
+
concurrency: con,
|
|
164
|
+
}, (run, progress) => {
|
|
165
|
+
benchmarkProgress.update(makeBenchmarkProgressBar({
|
|
166
|
+
totalRuns: runs,
|
|
167
|
+
run,
|
|
168
|
+
doneIn: null,
|
|
169
|
+
progress,
|
|
170
|
+
}));
|
|
171
|
+
});
|
|
172
|
+
benchmarkProgress.update('');
|
|
173
|
+
benchmarkProgress.update(getResults(timeTaken, runs));
|
|
174
|
+
benchmark[composition.id][`${con}`] = timeTaken;
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
log_1.Log.info();
|
|
178
|
+
await cleanupBundle();
|
|
179
|
+
};
|
|
180
|
+
exports.benchmarkCommand = benchmarkCommand;
|
package/dist/compositions.js
CHANGED
|
@@ -38,6 +38,7 @@ const listCompositionsCommand = async (remotionRoot) => {
|
|
|
38
38
|
const { browserExecutable, ffmpegExecutable, ffprobeExecutable, chromiumOptions, envVariables, inputProps, puppeteerTimeout, port, publicDir, } = await (0, get_cli_options_1.getCliOptions)({
|
|
39
39
|
isLambda: false,
|
|
40
40
|
type: 'get-compositions',
|
|
41
|
+
codec: 'h264',
|
|
41
42
|
});
|
|
42
43
|
const { urlOrBundle: bundled, cleanup: cleanupBundle } = await (0, setup_cache_1.bundleOnCliOrTakeServeUrl)({
|
|
43
44
|
remotionRoot,
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.getUserPreferredImageFormat = exports.setImageFormat = void 0;
|
|
4
4
|
const renderer_1 = require("@remotion/renderer");
|
|
5
|
+
const truthy_1 = require("../truthy");
|
|
5
6
|
let currentImageFormat;
|
|
6
7
|
const setImageFormat = (format) => {
|
|
7
8
|
if (typeof format === 'undefined') {
|
|
@@ -9,7 +10,13 @@ const setImageFormat = (format) => {
|
|
|
9
10
|
return;
|
|
10
11
|
}
|
|
11
12
|
if (!renderer_1.RenderInternals.validImageFormats.includes(format)) {
|
|
12
|
-
throw new TypeError(
|
|
13
|
+
throw new TypeError([
|
|
14
|
+
`Value ${format} is not valid as an image format.`,
|
|
15
|
+
// @ts-expect-error
|
|
16
|
+
format === 'jpg' ? 'Did you mean "jpeg"?' : null,
|
|
17
|
+
]
|
|
18
|
+
.filter(truthy_1.truthy)
|
|
19
|
+
.join(' '));
|
|
13
20
|
}
|
|
14
21
|
currentImageFormat = format;
|
|
15
22
|
};
|
package/dist/config/log.d.ts
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
import type { LogLevel } from '@remotion/renderer';
|
|
2
|
-
export declare const getLogLevel: () => "
|
|
2
|
+
export declare const getLogLevel: () => "error" | "verbose" | "info" | "warn";
|
|
3
3
|
export declare const setLogLevel: (newLogLevel: LogLevel) => void;
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { ImageFormat, StillImageFormat } from '@remotion/renderer';
|
|
2
|
+
export declare const determineFinalImageFormat: ({ downloadName, outName, configImageFormat, cliFlag, isLambda, }: {
|
|
3
|
+
downloadName: string | null;
|
|
4
|
+
outName: string | null;
|
|
5
|
+
configImageFormat: ImageFormat | null;
|
|
6
|
+
cliFlag: ImageFormat | null;
|
|
7
|
+
isLambda: boolean;
|
|
8
|
+
}) => {
|
|
9
|
+
format: StillImageFormat;
|
|
10
|
+
source: string;
|
|
11
|
+
};
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.determineFinalImageFormat = void 0;
|
|
4
|
+
const deriveExtensionFromFilename = (filename) => {
|
|
5
|
+
if (filename === null || filename === void 0 ? void 0 : filename.endsWith('.png')) {
|
|
6
|
+
return 'png';
|
|
7
|
+
}
|
|
8
|
+
if (filename === null || filename === void 0 ? void 0 : filename.endsWith('.jpg')) {
|
|
9
|
+
return 'jpeg';
|
|
10
|
+
}
|
|
11
|
+
if (filename === null || filename === void 0 ? void 0 : filename.endsWith('.jpeg')) {
|
|
12
|
+
return 'jpeg';
|
|
13
|
+
}
|
|
14
|
+
return null;
|
|
15
|
+
};
|
|
16
|
+
const determineFinalImageFormat = ({ downloadName, outName, configImageFormat, cliFlag, isLambda, }) => {
|
|
17
|
+
const outNameExtension = deriveExtensionFromFilename(outName);
|
|
18
|
+
const downloadNameExtension = deriveExtensionFromFilename(downloadName);
|
|
19
|
+
const outNameDescription = isLambda ? 'S3 output key' : 'out name';
|
|
20
|
+
if (outNameExtension &&
|
|
21
|
+
downloadNameExtension &&
|
|
22
|
+
outNameExtension !== downloadNameExtension) {
|
|
23
|
+
throw new TypeError(`Image format mismatch: ${outName} was given as the ${outNameDescription} and ${downloadName} was given as the download name, but the extensions don't match.`);
|
|
24
|
+
}
|
|
25
|
+
if (downloadNameExtension) {
|
|
26
|
+
if (cliFlag && downloadNameExtension !== cliFlag) {
|
|
27
|
+
throw new TypeError(`Image format mismatch: ${downloadName} was given as the download name, but --image-format=${cliFlag} was passed. The image formats must match.`);
|
|
28
|
+
}
|
|
29
|
+
return { format: downloadNameExtension, source: 'Download name extension' };
|
|
30
|
+
}
|
|
31
|
+
if (outNameExtension) {
|
|
32
|
+
if (cliFlag && outNameExtension !== cliFlag) {
|
|
33
|
+
throw new TypeError(`Image format mismatch: ${outName} was given as the ${outNameDescription}, but --image-format=${cliFlag} was passed. The image formats must match.`);
|
|
34
|
+
}
|
|
35
|
+
return { format: outNameExtension, source: 'Out name extension' };
|
|
36
|
+
}
|
|
37
|
+
if (cliFlag === 'none') {
|
|
38
|
+
throw new TypeError('The --image-format flag must not be "none" for stills.');
|
|
39
|
+
}
|
|
40
|
+
if (cliFlag !== null) {
|
|
41
|
+
return { format: cliFlag, source: '--image-format flag' };
|
|
42
|
+
}
|
|
43
|
+
if (configImageFormat !== null && configImageFormat !== 'none') {
|
|
44
|
+
return { format: configImageFormat, source: 'Config file' };
|
|
45
|
+
}
|
|
46
|
+
return { format: 'png', source: 'Default' };
|
|
47
|
+
};
|
|
48
|
+
exports.determineFinalImageFormat = determineFinalImageFormat;
|
package/dist/event-source.js
CHANGED
|
@@ -7,7 +7,7 @@ const openEventSource = () => {
|
|
|
7
7
|
source = new EventSource('/events');
|
|
8
8
|
source.addEventListener('message', (event) => {
|
|
9
9
|
const newEvent = JSON.parse(event.data);
|
|
10
|
-
if (newEvent.type === 'new-input-props') {
|
|
10
|
+
if (newEvent.type === 'new-input-props' || newEvent.type === 'new-env-variables') {
|
|
11
11
|
window.location.reload();
|
|
12
12
|
}
|
|
13
13
|
});
|
|
@@ -1,14 +1,22 @@
|
|
|
1
|
-
import type { BrowserExecutable, ChromiumOptions, FrameRange } from '@remotion/renderer';
|
|
1
|
+
import type { BrowserExecutable, ChromiumOptions, Codec, FrameRange } from '@remotion/renderer';
|
|
2
|
+
export declare const validateFfmpegCanUseCodec: (codec: Codec) => Promise<void>;
|
|
3
|
+
export declare const getFinalCodec: (options: {
|
|
4
|
+
downloadName: string | null;
|
|
5
|
+
outName: string | null;
|
|
6
|
+
}) => {
|
|
7
|
+
codec: Codec;
|
|
8
|
+
reason: string;
|
|
9
|
+
};
|
|
2
10
|
export declare const getAndValidateAbsoluteOutputFile: (relativeOutputLocation: string, overwrite: boolean) => string;
|
|
3
11
|
export declare const getCliOptions: (options: {
|
|
4
12
|
isLambda: boolean;
|
|
5
13
|
type: 'still' | 'series' | 'get-compositions';
|
|
14
|
+
codec: Codec;
|
|
6
15
|
}) => Promise<{
|
|
7
16
|
puppeteerTimeout: number;
|
|
8
17
|
concurrency: number | null;
|
|
9
18
|
frameRange: FrameRange | null;
|
|
10
19
|
shouldOutputImageSequence: boolean;
|
|
11
|
-
codec: "h264" | "h265" | "vp8" | "vp9" | "mp3" | "aac" | "wav" | "prores" | "h264-mkv" | "gif";
|
|
12
20
|
inputProps: object;
|
|
13
21
|
envVariables: Record<string, string>;
|
|
14
22
|
quality: number | undefined;
|
|
@@ -23,7 +31,7 @@ export declare const getCliOptions: (options: {
|
|
|
23
31
|
browserExecutable: BrowserExecutable;
|
|
24
32
|
ffmpegExecutable: import("@remotion/renderer").FfmpegExecutable;
|
|
25
33
|
ffprobeExecutable: import("@remotion/renderer").FfmpegExecutable;
|
|
26
|
-
logLevel: "
|
|
34
|
+
logLevel: "error" | "verbose" | "info" | "warn";
|
|
27
35
|
scale: number;
|
|
28
36
|
chromiumOptions: ChromiumOptions;
|
|
29
37
|
overwrite: boolean;
|
package/dist/get-cli-options.js
CHANGED
|
@@ -3,7 +3,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
3
3
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
4
|
};
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
exports.getCliOptions = exports.getAndValidateAbsoluteOutputFile = void 0;
|
|
6
|
+
exports.getCliOptions = exports.getAndValidateAbsoluteOutputFile = exports.getFinalCodec = exports.validateFfmpegCanUseCodec = void 0;
|
|
7
7
|
const renderer_1 = require("@remotion/renderer");
|
|
8
8
|
const fs_1 = __importDefault(require("fs"));
|
|
9
9
|
const path_1 = __importDefault(require("path"));
|
|
@@ -13,7 +13,7 @@ const get_final_output_codec_1 = require("./get-final-output-codec");
|
|
|
13
13
|
const get_input_props_1 = require("./get-input-props");
|
|
14
14
|
const image_formats_1 = require("./image-formats");
|
|
15
15
|
const log_1 = require("./log");
|
|
16
|
-
const
|
|
16
|
+
const parse_command_line_1 = require("./parse-command-line");
|
|
17
17
|
const getAndValidateFrameRange = () => {
|
|
18
18
|
const frameRange = config_1.ConfigInternals.getRange();
|
|
19
19
|
if (typeof frameRange === 'number') {
|
|
@@ -23,20 +23,11 @@ const getAndValidateFrameRange = () => {
|
|
|
23
23
|
}
|
|
24
24
|
return frameRange;
|
|
25
25
|
};
|
|
26
|
-
const
|
|
27
|
-
const userCodec = config_1.ConfigInternals.getOutputCodecOrUndefined();
|
|
28
|
-
const codec = (0, get_final_output_codec_1.getFinalOutputCodec)({
|
|
29
|
-
codec: userCodec,
|
|
30
|
-
fileExtension: options.isLambda
|
|
31
|
-
? null
|
|
32
|
-
: renderer_1.RenderInternals.getExtensionOfFilename((0, user_passed_output_location_1.getUserPassedOutputLocation)()),
|
|
33
|
-
emitWarning: true,
|
|
34
|
-
});
|
|
26
|
+
const validateFfmpegCanUseCodec = async (codec) => {
|
|
35
27
|
const ffmpegExecutable = config_1.ConfigInternals.getCustomFfmpegExecutable();
|
|
36
28
|
if (codec === 'vp8' &&
|
|
37
29
|
!(await renderer_1.RenderInternals.ffmpegHasFeature({
|
|
38
30
|
feature: 'enable-libvpx',
|
|
39
|
-
isLambda: options.isLambda,
|
|
40
31
|
ffmpegExecutable,
|
|
41
32
|
}))) {
|
|
42
33
|
log_1.Log.error("The Vp8 codec has been selected, but your FFMPEG binary wasn't compiled with the --enable-lipvpx flag.");
|
|
@@ -45,7 +36,6 @@ const getFinalCodec = async (options) => {
|
|
|
45
36
|
if (codec === 'h265' &&
|
|
46
37
|
!(await renderer_1.RenderInternals.ffmpegHasFeature({
|
|
47
38
|
feature: 'enable-gpl',
|
|
48
|
-
isLambda: options.isLambda,
|
|
49
39
|
ffmpegExecutable,
|
|
50
40
|
}))) {
|
|
51
41
|
log_1.Log.error("The H265 codec has been selected, but your FFMPEG binary wasn't compiled with the --enable-gpl flag.");
|
|
@@ -54,14 +44,24 @@ const getFinalCodec = async (options) => {
|
|
|
54
44
|
if (codec === 'h265' &&
|
|
55
45
|
!(await renderer_1.RenderInternals.ffmpegHasFeature({
|
|
56
46
|
feature: 'enable-libx265',
|
|
57
|
-
isLambda: options.isLambda,
|
|
58
47
|
ffmpegExecutable,
|
|
59
48
|
}))) {
|
|
60
49
|
log_1.Log.error("The H265 codec has been selected, but your FFMPEG binary wasn't compiled with the --enable-libx265 flag.");
|
|
61
50
|
log_1.Log.error('This does not work, please recompile your FFMPEG binary with --enable-gpl --enable-libx265 or choose a different codec.');
|
|
62
51
|
}
|
|
63
|
-
return codec;
|
|
64
52
|
};
|
|
53
|
+
exports.validateFfmpegCanUseCodec = validateFfmpegCanUseCodec;
|
|
54
|
+
const getFinalCodec = (options) => {
|
|
55
|
+
var _a;
|
|
56
|
+
const { codec, reason } = (0, get_final_output_codec_1.getFinalOutputCodec)({
|
|
57
|
+
cliFlag: parse_command_line_1.parsedCli.codec,
|
|
58
|
+
configFile: (_a = config_1.ConfigInternals.getOutputCodecOrUndefined()) !== null && _a !== void 0 ? _a : null,
|
|
59
|
+
downloadName: options.downloadName,
|
|
60
|
+
outName: options.outName,
|
|
61
|
+
});
|
|
62
|
+
return { codec, reason };
|
|
63
|
+
};
|
|
64
|
+
exports.getFinalCodec = getFinalCodec;
|
|
65
65
|
const getBrowser = () => { var _a; return (_a = config_1.ConfigInternals.getBrowser()) !== null && _a !== void 0 ? _a : renderer_1.RenderInternals.DEFAULT_BROWSER; };
|
|
66
66
|
const getAndValidateAbsoluteOutputFile = (relativeOutputLocation, overwrite) => {
|
|
67
67
|
const absoluteOutputFile = path_1.default.resolve(process.cwd(), relativeOutputLocation);
|
|
@@ -119,11 +119,6 @@ const getAndValidateBrowser = async (browserExecutable) => {
|
|
|
119
119
|
const getCliOptions = async (options) => {
|
|
120
120
|
var _a;
|
|
121
121
|
const frameRange = getAndValidateFrameRange();
|
|
122
|
-
const codec = options.type === 'get-compositions'
|
|
123
|
-
? 'h264'
|
|
124
|
-
: await getFinalCodec({
|
|
125
|
-
isLambda: options.isLambda,
|
|
126
|
-
});
|
|
127
122
|
const shouldOutputImageSequence = options.type === 'still'
|
|
128
123
|
? true
|
|
129
124
|
: await getAndValidateShouldOutputImageSequence({
|
|
@@ -133,14 +128,14 @@ const getCliOptions = async (options) => {
|
|
|
133
128
|
const overwrite = config_1.ConfigInternals.getShouldOverwrite({
|
|
134
129
|
defaultValue: !options.isLambda,
|
|
135
130
|
});
|
|
136
|
-
const crf = getAndValidateCrf(shouldOutputImageSequence, codec);
|
|
137
|
-
const pixelFormat = getAndValidatePixelFormat(codec);
|
|
131
|
+
const crf = getAndValidateCrf(shouldOutputImageSequence, options.codec);
|
|
132
|
+
const pixelFormat = getAndValidatePixelFormat(options.codec);
|
|
138
133
|
const imageFormat = getAndValidateImageFormat({
|
|
139
134
|
shouldOutputImageSequence,
|
|
140
|
-
codec,
|
|
135
|
+
codec: options.codec,
|
|
141
136
|
pixelFormat,
|
|
142
137
|
});
|
|
143
|
-
const proResProfile = getAndValidateProResProfile(codec);
|
|
138
|
+
const proResProfile = getAndValidateProResProfile(options.codec);
|
|
144
139
|
const browserExecutable = config_1.ConfigInternals.getBrowserExecutable();
|
|
145
140
|
const ffmpegExecutable = config_1.ConfigInternals.getCustomFfmpegExecutable();
|
|
146
141
|
const ffprobeExecutable = config_1.ConfigInternals.getCustomFfprobeExecutable();
|
|
@@ -152,8 +147,8 @@ const getCliOptions = async (options) => {
|
|
|
152
147
|
headless: config_1.ConfigInternals.getChromiumHeadlessMode(),
|
|
153
148
|
gl: (_a = config_1.ConfigInternals.getChromiumOpenGlRenderer()) !== null && _a !== void 0 ? _a : renderer_1.RenderInternals.DEFAULT_OPENGL_RENDERER,
|
|
154
149
|
};
|
|
155
|
-
const everyNthFrame = config_1.ConfigInternals.getAndValidateEveryNthFrame(codec);
|
|
156
|
-
const numberOfGifLoops = config_1.ConfigInternals.getAndValidateNumberOfGifLoops(codec);
|
|
150
|
+
const everyNthFrame = config_1.ConfigInternals.getAndValidateEveryNthFrame(options.codec);
|
|
151
|
+
const numberOfGifLoops = config_1.ConfigInternals.getAndValidateNumberOfGifLoops(options.codec);
|
|
157
152
|
const concurrency = config_1.ConfigInternals.getConcurrency();
|
|
158
153
|
renderer_1.RenderInternals.validateConcurrency(concurrency, 'concurrency');
|
|
159
154
|
return {
|
|
@@ -161,9 +156,8 @@ const getCliOptions = async (options) => {
|
|
|
161
156
|
concurrency,
|
|
162
157
|
frameRange,
|
|
163
158
|
shouldOutputImageSequence,
|
|
164
|
-
codec,
|
|
165
159
|
inputProps: (0, get_input_props_1.getInputProps)(() => undefined),
|
|
166
|
-
envVariables: await (0, get_env_1.getEnvironmentVariables)(),
|
|
160
|
+
envVariables: await (0, get_env_1.getEnvironmentVariables)(() => undefined),
|
|
167
161
|
quality: config_1.ConfigInternals.getQuality(),
|
|
168
162
|
browser: await getAndValidateBrowser(browserExecutable),
|
|
169
163
|
crf,
|
package/dist/get-env.d.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export declare const getEnvironmentVariables: () => Promise<Record<string, string>>;
|
|
1
|
+
export declare const getEnvironmentVariables: (onUpdate: (newProps: Record<string, string>) => void) => Promise<Record<string, string>>;
|
package/dist/get-env.js
CHANGED
|
@@ -7,6 +7,7 @@ exports.getEnvironmentVariables = void 0;
|
|
|
7
7
|
const dotenv_1 = __importDefault(require("dotenv"));
|
|
8
8
|
const fs_1 = __importDefault(require("fs"));
|
|
9
9
|
const path_1 = __importDefault(require("path"));
|
|
10
|
+
const chalk_1 = require("./chalk");
|
|
10
11
|
const config_1 = require("./config");
|
|
11
12
|
const find_closest_package_json_1 = require("./find-closest-package-json");
|
|
12
13
|
const log_1 = require("./log");
|
|
@@ -19,9 +20,54 @@ function getProcessEnv() {
|
|
|
19
20
|
}
|
|
20
21
|
return env;
|
|
21
22
|
}
|
|
22
|
-
const
|
|
23
|
+
const watchEnvFile = ({ processEnv, envFile, onUpdate, existedBefore, }) => {
|
|
24
|
+
const listener = async () => {
|
|
25
|
+
try {
|
|
26
|
+
const file = await fs_1.default.promises.readFile(envFile, 'utf-8');
|
|
27
|
+
onUpdate({
|
|
28
|
+
...processEnv,
|
|
29
|
+
...dotenv_1.default.parse(file),
|
|
30
|
+
});
|
|
31
|
+
if (existedBefore) {
|
|
32
|
+
log_1.Log.info(chalk_1.chalk.blueBright(`Updated env file ${envFile}`));
|
|
33
|
+
}
|
|
34
|
+
else {
|
|
35
|
+
log_1.Log.info(chalk_1.chalk.blueBright(`Added env file ${envFile}`));
|
|
36
|
+
}
|
|
37
|
+
fs_1.default.unwatchFile(envFile, listener);
|
|
38
|
+
watchEnvFile({
|
|
39
|
+
envFile,
|
|
40
|
+
existedBefore: true,
|
|
41
|
+
onUpdate,
|
|
42
|
+
processEnv,
|
|
43
|
+
});
|
|
44
|
+
}
|
|
45
|
+
catch (err) {
|
|
46
|
+
// No error message if user did not have a .env file from the beginning
|
|
47
|
+
if (!existedBefore && !fs_1.default.existsSync(envFile)) {
|
|
48
|
+
return;
|
|
49
|
+
}
|
|
50
|
+
if (fs_1.default.existsSync(envFile) && existedBefore) {
|
|
51
|
+
log_1.Log.error(`${envFile} update failed with error ${err}`);
|
|
52
|
+
}
|
|
53
|
+
else {
|
|
54
|
+
log_1.Log.warn(`${envFile} was deleted.`);
|
|
55
|
+
fs_1.default.unwatchFile(envFile, listener);
|
|
56
|
+
watchEnvFile({
|
|
57
|
+
envFile,
|
|
58
|
+
existedBefore: false,
|
|
59
|
+
onUpdate,
|
|
60
|
+
processEnv,
|
|
61
|
+
});
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
};
|
|
65
|
+
fs_1.default.watchFile(envFile, { interval: 100 }, listener);
|
|
66
|
+
};
|
|
67
|
+
const getEnvForEnvFile = async (processEnv, envFile, onUpdate) => {
|
|
23
68
|
try {
|
|
24
69
|
const envFileData = await fs_1.default.promises.readFile(envFile);
|
|
70
|
+
watchEnvFile({ processEnv, envFile, onUpdate, existedBefore: true });
|
|
25
71
|
return {
|
|
26
72
|
...processEnv,
|
|
27
73
|
...dotenv_1.default.parse(envFileData),
|
|
@@ -33,7 +79,7 @@ const getEnvForEnvFile = async (processEnv, envFile) => {
|
|
|
33
79
|
process.exit(1);
|
|
34
80
|
}
|
|
35
81
|
};
|
|
36
|
-
const getEnvironmentVariables = () => {
|
|
82
|
+
const getEnvironmentVariables = (onUpdate) => {
|
|
37
83
|
const processEnv = getProcessEnv();
|
|
38
84
|
if (parse_command_line_1.parsedCli['env-file']) {
|
|
39
85
|
const envFile = path_1.default.resolve(process.cwd(), parse_command_line_1.parsedCli['env-file']);
|
|
@@ -43,24 +89,30 @@ const getEnvironmentVariables = () => {
|
|
|
43
89
|
log_1.Log.error('Check that your path is correct and try again.');
|
|
44
90
|
process.exit(1);
|
|
45
91
|
}
|
|
46
|
-
return getEnvForEnvFile(processEnv, envFile);
|
|
92
|
+
return getEnvForEnvFile(processEnv, envFile, onUpdate);
|
|
47
93
|
}
|
|
48
94
|
const remotionRoot = (0, find_closest_package_json_1.findRemotionRoot)();
|
|
49
95
|
const configFileSetting = config_1.ConfigInternals.getDotEnvLocation();
|
|
50
96
|
if (configFileSetting) {
|
|
51
97
|
const envFile = path_1.default.resolve(remotionRoot, configFileSetting);
|
|
52
98
|
if (!fs_1.default.existsSync(envFile)) {
|
|
53
|
-
log_1.Log.error('You
|
|
99
|
+
log_1.Log.error('You specified a custom .env file using `Config.Rendering.setDotEnvLocation()` in the config file but it could not be found');
|
|
54
100
|
log_1.Log.error('We looked for the file at:', envFile);
|
|
55
101
|
log_1.Log.error('Check that your path is correct and try again.');
|
|
56
102
|
process.exit(1);
|
|
57
103
|
}
|
|
58
|
-
return getEnvForEnvFile(processEnv, envFile);
|
|
104
|
+
return getEnvForEnvFile(processEnv, envFile, onUpdate);
|
|
59
105
|
}
|
|
60
106
|
const defaultEnvFile = path_1.default.resolve(remotionRoot, '.env');
|
|
61
107
|
if (!fs_1.default.existsSync(defaultEnvFile)) {
|
|
108
|
+
watchEnvFile({
|
|
109
|
+
processEnv,
|
|
110
|
+
envFile: defaultEnvFile,
|
|
111
|
+
onUpdate,
|
|
112
|
+
existedBefore: false,
|
|
113
|
+
});
|
|
62
114
|
return Promise.resolve(processEnv);
|
|
63
115
|
}
|
|
64
|
-
return getEnvForEnvFile(processEnv, defaultEnvFile);
|
|
116
|
+
return getEnvForEnvFile(processEnv, defaultEnvFile, onUpdate);
|
|
65
117
|
};
|
|
66
118
|
exports.getEnvironmentVariables = getEnvironmentVariables;
|
|
@@ -1,6 +1,10 @@
|
|
|
1
1
|
import type { Codec, CodecOrUndefined } from '@remotion/renderer';
|
|
2
|
-
export declare const getFinalOutputCodec: ({
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
2
|
+
export declare const getFinalOutputCodec: ({ cliFlag, configFile, downloadName, outName, }: {
|
|
3
|
+
cliFlag: CodecOrUndefined;
|
|
4
|
+
outName: string | null;
|
|
5
|
+
downloadName: string | null;
|
|
6
|
+
configFile: Codec | null;
|
|
7
|
+
}) => {
|
|
8
|
+
codec: Codec;
|
|
9
|
+
reason: string;
|
|
10
|
+
};
|
|
@@ -2,62 +2,62 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.getFinalOutputCodec = void 0;
|
|
4
4
|
const renderer_1 = require("@remotion/renderer");
|
|
5
|
-
const
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
if (
|
|
20
|
-
|
|
21
|
-
log_1.Log.info('You have specified a .mp3 extension, using the MP3 encoder.');
|
|
22
|
-
}
|
|
23
|
-
return 'mp3';
|
|
24
|
-
}
|
|
25
|
-
if (inputCodec === undefined && fileExtension === 'mov') {
|
|
26
|
-
if (emitWarning) {
|
|
27
|
-
log_1.Log.info('You have specified a .mov extension, using the Apple ProRes encoder.');
|
|
28
|
-
}
|
|
29
|
-
return 'prores';
|
|
30
|
-
}
|
|
31
|
-
if (inputCodec === undefined && fileExtension === 'wav') {
|
|
32
|
-
if (emitWarning) {
|
|
33
|
-
log_1.Log.info('You have specified a .wav extension, using the WAV encoder.');
|
|
34
|
-
}
|
|
35
|
-
return 'wav';
|
|
36
|
-
}
|
|
37
|
-
if (inputCodec === undefined && fileExtension === 'aac') {
|
|
38
|
-
if (emitWarning) {
|
|
39
|
-
log_1.Log.info('You have specified a .aac extension, using the AAC encoder.');
|
|
40
|
-
}
|
|
41
|
-
return 'aac';
|
|
42
|
-
}
|
|
43
|
-
if (inputCodec === undefined && fileExtension === 'm4a') {
|
|
44
|
-
if (emitWarning) {
|
|
45
|
-
log_1.Log.info('You have specified a .m4a extension, using the AAC encoder.');
|
|
46
|
-
}
|
|
47
|
-
return 'aac';
|
|
48
|
-
}
|
|
49
|
-
if (inputCodec === undefined && fileExtension === 'mkv') {
|
|
50
|
-
if (emitWarning) {
|
|
51
|
-
log_1.Log.info('You have specified a .mkv extension, using the H264 encoder and WAV audio format.');
|
|
52
|
-
}
|
|
53
|
-
return 'h264-mkv';
|
|
54
|
-
}
|
|
55
|
-
if (inputCodec === undefined && fileExtension === 'gif') {
|
|
56
|
-
if (emitWarning) {
|
|
57
|
-
log_1.Log.info('You have specified a .gif extension, rendering a GIF');
|
|
58
|
-
}
|
|
59
|
-
return 'gif';
|
|
5
|
+
const fileExtensions = {
|
|
6
|
+
webm: 'vp8',
|
|
7
|
+
hevc: 'h265',
|
|
8
|
+
mp3: 'mp3',
|
|
9
|
+
mov: 'prores',
|
|
10
|
+
wav: 'wav',
|
|
11
|
+
aac: 'aac',
|
|
12
|
+
mkv: 'h264-mkv',
|
|
13
|
+
gif: 'gif',
|
|
14
|
+
mp4: 'h264',
|
|
15
|
+
m4a: 'aac',
|
|
16
|
+
};
|
|
17
|
+
const deriveExtensionFromFilename = (extension) => {
|
|
18
|
+
var _a;
|
|
19
|
+
if (extension === null) {
|
|
20
|
+
return null;
|
|
60
21
|
}
|
|
61
|
-
return
|
|
22
|
+
return (_a = fileExtensions[extension]) !== null && _a !== void 0 ? _a : null;
|
|
23
|
+
};
|
|
24
|
+
const getFinalOutputCodec = ({ cliFlag, configFile, downloadName, outName, }) => {
|
|
25
|
+
const downloadNameExtension = renderer_1.RenderInternals.getExtensionOfFilename(downloadName);
|
|
26
|
+
const outNameExtension = renderer_1.RenderInternals.getExtensionOfFilename(outName);
|
|
27
|
+
const derivedDownloadCodec = deriveExtensionFromFilename(downloadNameExtension);
|
|
28
|
+
const derivedOutNameCodec = deriveExtensionFromFilename(outNameExtension);
|
|
29
|
+
if (derivedDownloadCodec &&
|
|
30
|
+
derivedOutNameCodec &&
|
|
31
|
+
derivedDownloadCodec !== derivedOutNameCodec) {
|
|
32
|
+
throw new TypeError(`The download name is ${downloadName} but the output name is ${outName}. The file extensions must match`);
|
|
33
|
+
}
|
|
34
|
+
if (derivedDownloadCodec) {
|
|
35
|
+
if (cliFlag && derivedDownloadCodec !== cliFlag) {
|
|
36
|
+
throw new TypeError(`The download name is ${downloadName} but --codec=${cliFlag} was passed. The download name implies a codec of ${derivedDownloadCodec} which does not align with the --codec flag.`);
|
|
37
|
+
}
|
|
38
|
+
return {
|
|
39
|
+
codec: derivedDownloadCodec,
|
|
40
|
+
reason: 'derived from download name',
|
|
41
|
+
};
|
|
42
|
+
}
|
|
43
|
+
if (derivedOutNameCodec) {
|
|
44
|
+
if (cliFlag && derivedOutNameCodec !== cliFlag) {
|
|
45
|
+
throw new TypeError(`The out name is ${outName} but --codec=${cliFlag} was passed. The out name implies a codec of ${derivedOutNameCodec} which does not align with the --codec flag.`);
|
|
46
|
+
}
|
|
47
|
+
return {
|
|
48
|
+
codec: derivedOutNameCodec,
|
|
49
|
+
reason: 'derived from out name',
|
|
50
|
+
};
|
|
51
|
+
}
|
|
52
|
+
if (cliFlag) {
|
|
53
|
+
return { codec: cliFlag, reason: 'from --codec flag' };
|
|
54
|
+
}
|
|
55
|
+
if (configFile) {
|
|
56
|
+
return {
|
|
57
|
+
codec: configFile,
|
|
58
|
+
reason: 'Config file',
|
|
59
|
+
};
|
|
60
|
+
}
|
|
61
|
+
return { codec: renderer_1.RenderInternals.DEFAULT_CODEC, reason: 'default' };
|
|
62
62
|
};
|
|
63
63
|
exports.getFinalOutputCodec = getFinalOutputCodec;
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { Codec, RenderMediaOptions } from '@remotion/renderer';
|
|
2
|
+
export declare const getRenderMediaOptions: ({ outputLocation, config, serveUrl, codec, }: {
|
|
3
|
+
outputLocation: RenderMediaOptions['outputLocation'];
|
|
4
|
+
config: RenderMediaOptions['composition'];
|
|
5
|
+
serveUrl: string;
|
|
6
|
+
codec: Codec;
|
|
7
|
+
}) => Promise<RenderMediaOptions>;
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.getRenderMediaOptions = void 0;
|
|
4
|
+
const renderer_1 = require("@remotion/renderer");
|
|
5
|
+
const config_1 = require("./config");
|
|
6
|
+
const get_cli_options_1 = require("./get-cli-options");
|
|
7
|
+
const getRenderMediaOptions = async ({ outputLocation, config, serveUrl, codec, }) => {
|
|
8
|
+
const { proResProfile, concurrency, frameRange, overwrite, inputProps, envVariables, quality, crf, pixelFormat, imageFormat, browserExecutable, ffmpegExecutable, ffprobeExecutable, scale, chromiumOptions, port, numberOfGifLoops, everyNthFrame, muted, enforceAudioTrack, ffmpegOverride, } = await (0, get_cli_options_1.getCliOptions)({
|
|
9
|
+
isLambda: false,
|
|
10
|
+
type: 'series',
|
|
11
|
+
codec,
|
|
12
|
+
});
|
|
13
|
+
return {
|
|
14
|
+
outputLocation,
|
|
15
|
+
composition: config,
|
|
16
|
+
crf,
|
|
17
|
+
envVariables,
|
|
18
|
+
ffmpegExecutable,
|
|
19
|
+
ffprobeExecutable,
|
|
20
|
+
frameRange,
|
|
21
|
+
imageFormat,
|
|
22
|
+
inputProps,
|
|
23
|
+
overwrite,
|
|
24
|
+
pixelFormat,
|
|
25
|
+
proResProfile,
|
|
26
|
+
quality,
|
|
27
|
+
dumpBrowserLogs: renderer_1.RenderInternals.isEqualOrBelowLogLevel(config_1.ConfigInternals.Logging.getLogLevel(), 'verbose'),
|
|
28
|
+
chromiumOptions,
|
|
29
|
+
timeoutInMilliseconds: config_1.ConfigInternals.getCurrentPuppeteerTimeout(),
|
|
30
|
+
scale,
|
|
31
|
+
port,
|
|
32
|
+
numberOfGifLoops,
|
|
33
|
+
everyNthFrame,
|
|
34
|
+
verbose: renderer_1.RenderInternals.isEqualOrBelowLogLevel(config_1.ConfigInternals.Logging.getLogLevel(), 'verbose'),
|
|
35
|
+
muted,
|
|
36
|
+
enforceAudioTrack,
|
|
37
|
+
browserExecutable,
|
|
38
|
+
ffmpegOverride,
|
|
39
|
+
concurrency,
|
|
40
|
+
serveUrl,
|
|
41
|
+
codec,
|
|
42
|
+
};
|
|
43
|
+
};
|
|
44
|
+
exports.getRenderMediaOptions = getRenderMediaOptions;
|
package/dist/index.d.ts
CHANGED
|
@@ -70,12 +70,12 @@ export declare const CliInternals: {
|
|
|
70
70
|
getCliOptions: (options: {
|
|
71
71
|
isLambda: boolean;
|
|
72
72
|
type: "still" | "series" | "get-compositions";
|
|
73
|
+
codec: "h264" | "h265" | "vp8" | "vp9" | "mp3" | "aac" | "wav" | "prores" | "h264-mkv" | "gif";
|
|
73
74
|
}) => Promise<{
|
|
74
75
|
puppeteerTimeout: number;
|
|
75
76
|
concurrency: number | null;
|
|
76
77
|
frameRange: import("@remotion/renderer").FrameRange | null;
|
|
77
78
|
shouldOutputImageSequence: boolean;
|
|
78
|
-
codec: "h264" | "h265" | "vp8" | "vp9" | "mp3" | "aac" | "wav" | "prores" | "h264-mkv" | "gif";
|
|
79
79
|
inputProps: object;
|
|
80
80
|
envVariables: Record<string, string>;
|
|
81
81
|
quality: number | undefined;
|
|
@@ -90,7 +90,7 @@ export declare const CliInternals: {
|
|
|
90
90
|
browserExecutable: import("@remotion/renderer").BrowserExecutable;
|
|
91
91
|
ffmpegExecutable: import("@remotion/renderer").FfmpegExecutable;
|
|
92
92
|
ffprobeExecutable: import("@remotion/renderer").FfmpegExecutable;
|
|
93
|
-
logLevel: "
|
|
93
|
+
logLevel: "error" | "verbose" | "info" | "warn";
|
|
94
94
|
scale: number;
|
|
95
95
|
chromiumOptions: import("@remotion/renderer").ChromiumOptions;
|
|
96
96
|
overwrite: boolean;
|
|
@@ -115,4 +115,21 @@ export declare const CliInternals: {
|
|
|
115
115
|
}) => string;
|
|
116
116
|
getFileSizeDownloadBar: (downloaded: number) => string;
|
|
117
117
|
findRemotionRoot: () => string;
|
|
118
|
+
getFinalCodec: (options: {
|
|
119
|
+
downloadName: string | null;
|
|
120
|
+
outName: string | null;
|
|
121
|
+
}) => {
|
|
122
|
+
codec: "h264" | "h265" | "vp8" | "vp9" | "mp3" | "aac" | "wav" | "prores" | "h264-mkv" | "gif";
|
|
123
|
+
reason: string;
|
|
124
|
+
};
|
|
125
|
+
determineFinalImageFormat: ({ downloadName, outName, configImageFormat, cliFlag, isLambda, }: {
|
|
126
|
+
downloadName: string | null;
|
|
127
|
+
outName: string | null;
|
|
128
|
+
configImageFormat: "png" | "jpeg" | "none" | null;
|
|
129
|
+
cliFlag: "png" | "jpeg" | "none" | null;
|
|
130
|
+
isLambda: boolean;
|
|
131
|
+
}) => {
|
|
132
|
+
format: import("@remotion/renderer").StillImageFormat;
|
|
133
|
+
source: string;
|
|
134
|
+
};
|
|
118
135
|
};
|
package/dist/index.js
CHANGED
|
@@ -16,10 +16,12 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
|
16
16
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
17
|
exports.CliInternals = exports.overrideRemotion = exports.ConfigInternals = exports.cli = void 0;
|
|
18
18
|
const renderer_1 = require("@remotion/renderer");
|
|
19
|
+
const benchmark_1 = require("./benchmark");
|
|
19
20
|
const chalk_1 = require("./chalk");
|
|
20
21
|
const check_version_1 = require("./check-version");
|
|
21
22
|
const compositions_1 = require("./compositions");
|
|
22
23
|
const index_1 = require("./config/index");
|
|
24
|
+
const determine_image_format_1 = require("./determine-image-format");
|
|
23
25
|
const download_progress_1 = require("./download-progress");
|
|
24
26
|
const find_closest_package_json_1 = require("./find-closest-package-json");
|
|
25
27
|
const format_bytes_1 = require("./format-bytes");
|
|
@@ -77,12 +79,17 @@ const cli = async () => {
|
|
|
77
79
|
else if (command === versions_1.VERSIONS_COMMAND) {
|
|
78
80
|
await (0, versions_1.versionsCommand)(remotionRoot);
|
|
79
81
|
}
|
|
82
|
+
else if (command === 'benchmark') {
|
|
83
|
+
await (0, benchmark_1.benchmarkCommand)(remotionRoot, parse_command_line_1.parsedCli._.slice(1));
|
|
84
|
+
}
|
|
80
85
|
else if (command === 'help') {
|
|
81
86
|
(0, print_help_1.printHelp)();
|
|
82
87
|
process.exit(0);
|
|
83
88
|
}
|
|
84
89
|
else {
|
|
85
|
-
|
|
90
|
+
if (command) {
|
|
91
|
+
log_1.Log.error(`Command ${command} not found.`);
|
|
92
|
+
}
|
|
86
93
|
(0, print_help_1.printHelp)();
|
|
87
94
|
process.exit(1);
|
|
88
95
|
}
|
|
@@ -118,4 +125,6 @@ exports.CliInternals = {
|
|
|
118
125
|
formatBytes: format_bytes_1.formatBytes,
|
|
119
126
|
getFileSizeDownloadBar: download_progress_1.getFileSizeDownloadBar,
|
|
120
127
|
findRemotionRoot: find_closest_package_json_1.findRemotionRoot,
|
|
128
|
+
getFinalCodec: get_cli_options_1.getFinalCodec,
|
|
129
|
+
determineFinalImageFormat: determine_image_format_1.determineFinalImageFormat,
|
|
121
130
|
};
|
|
@@ -97,9 +97,6 @@ const parseCommandLine = () => {
|
|
|
97
97
|
if (typeof exports.parsedCli.crf !== 'undefined') {
|
|
98
98
|
config_1.Config.Output.setCrf(exports.parsedCli.crf);
|
|
99
99
|
}
|
|
100
|
-
if (exports.parsedCli.codec) {
|
|
101
|
-
config_1.Config.Output.setCodec(exports.parsedCli.codec);
|
|
102
|
-
}
|
|
103
100
|
if (exports.parsedCli['every-nth-frame']) {
|
|
104
101
|
config_1.Config.Rendering.setEveryNthFrame(exports.parsedCli['every-nth-frame']);
|
|
105
102
|
}
|
|
@@ -1,12 +1,13 @@
|
|
|
1
1
|
import type { IncomingMessage, ServerResponse } from 'http';
|
|
2
2
|
import type { LiveEventsServer } from './live-events';
|
|
3
|
-
export declare const handleRoutes: ({ hash, hashPrefix, request, response, liveEventsServer, getCurrentInputProps, remotionRoot, userPassedPublicDir, }: {
|
|
3
|
+
export declare const handleRoutes: ({ hash, hashPrefix, request, response, liveEventsServer, getCurrentInputProps, getEnvVariables, remotionRoot, userPassedPublicDir, }: {
|
|
4
4
|
hash: string;
|
|
5
5
|
hashPrefix: string;
|
|
6
6
|
request: IncomingMessage;
|
|
7
7
|
response: ServerResponse;
|
|
8
8
|
liveEventsServer: LiveEventsServer;
|
|
9
9
|
getCurrentInputProps: () => object;
|
|
10
|
+
getEnvVariables: () => Record<string, string>;
|
|
10
11
|
remotionRoot: string;
|
|
11
12
|
userPassedPublicDir: string | null;
|
|
12
13
|
}) => void | Promise<void>;
|
|
@@ -25,7 +25,7 @@ const static404 = (response) => {
|
|
|
25
25
|
response.writeHead(404);
|
|
26
26
|
response.end('The static/ prefix has been changed, this URL is no longer valid.');
|
|
27
27
|
};
|
|
28
|
-
const handleFallback = async ({ remotionRoot, hash, response, getCurrentInputProps, }) => {
|
|
28
|
+
const handleFallback = async ({ remotionRoot, hash, response, getCurrentInputProps, getEnvVariables, }) => {
|
|
29
29
|
const [edit] = await editorGuess;
|
|
30
30
|
const displayName = (0, open_in_editor_1.getDisplayNameForEditor)(edit ? edit.command : null);
|
|
31
31
|
response.setHeader('content-type', 'text/html');
|
|
@@ -35,6 +35,7 @@ const handleFallback = async ({ remotionRoot, hash, response, getCurrentInputPro
|
|
|
35
35
|
staticHash: hash,
|
|
36
36
|
baseDir: '/',
|
|
37
37
|
editorName: displayName,
|
|
38
|
+
envVariables: getEnvVariables(),
|
|
38
39
|
inputProps: getCurrentInputProps(),
|
|
39
40
|
remotionRoot,
|
|
40
41
|
previewServerCommand: packageManager === 'unknown' ? null : packageManager.startCommand,
|
|
@@ -117,7 +118,7 @@ const handleFavicon = (_, response) => {
|
|
|
117
118
|
const readStream = (0, fs_1.createReadStream)(filePath);
|
|
118
119
|
readStream.pipe(response);
|
|
119
120
|
};
|
|
120
|
-
const handleRoutes = ({ hash, hashPrefix, request, response, liveEventsServer, getCurrentInputProps, remotionRoot, userPassedPublicDir, }) => {
|
|
121
|
+
const handleRoutes = ({ hash, hashPrefix, request, response, liveEventsServer, getCurrentInputProps, getEnvVariables, remotionRoot, userPassedPublicDir, }) => {
|
|
121
122
|
const url = new URL(request.url, 'http://localhost');
|
|
122
123
|
if (url.pathname === '/api/update') {
|
|
123
124
|
return handleUpdate(remotionRoot, request, response);
|
|
@@ -156,6 +157,7 @@ const handleRoutes = ({ hash, hashPrefix, request, response, liveEventsServer, g
|
|
|
156
157
|
hash,
|
|
157
158
|
response,
|
|
158
159
|
getCurrentInputProps,
|
|
160
|
+
getEnvVariables,
|
|
159
161
|
});
|
|
160
162
|
};
|
|
161
163
|
exports.handleRoutes = handleRoutes;
|
|
@@ -3,7 +3,7 @@ import type { LiveEventsServer } from './live-events';
|
|
|
3
3
|
export declare const startServer: (entry: string, userDefinedComponent: string, options: {
|
|
4
4
|
webpackOverride: WebpackOverrideFn;
|
|
5
5
|
getCurrentInputProps: () => object;
|
|
6
|
-
|
|
6
|
+
getEnvVariables: () => Record<string, string>;
|
|
7
7
|
port: number | null;
|
|
8
8
|
maxTimelineTracks?: number;
|
|
9
9
|
remotionRoot: string;
|
|
@@ -26,7 +26,7 @@ const startServer = async (entry, userDefinedComponent, options) => {
|
|
|
26
26
|
outDir: tmpDir,
|
|
27
27
|
environment: 'development',
|
|
28
28
|
webpackOverride: (_a = options === null || options === void 0 ? void 0 : options.webpackOverride) !== null && _a !== void 0 ? _a : config_1.ConfigInternals.getWebpackOverrideFn(),
|
|
29
|
-
envVariables: (_b = options === null || options === void 0 ? void 0 : options.
|
|
29
|
+
envVariables: (_b = options === null || options === void 0 ? void 0 : options.getEnvVariables()) !== null && _b !== void 0 ? _b : {},
|
|
30
30
|
maxTimelineTracks: (_c = options === null || options === void 0 ? void 0 : options.maxTimelineTracks) !== null && _c !== void 0 ? _c : 15,
|
|
31
31
|
entryPoints: [
|
|
32
32
|
require.resolve('./hot-middleware/client'),
|
|
@@ -62,6 +62,7 @@ const startServer = async (entry, userDefinedComponent, options) => {
|
|
|
62
62
|
response,
|
|
63
63
|
liveEventsServer,
|
|
64
64
|
getCurrentInputProps: options.getCurrentInputProps,
|
|
65
|
+
getEnvVariables: options.getEnvVariables,
|
|
65
66
|
remotionRoot: options.remotionRoot,
|
|
66
67
|
userPassedPublicDir: options.userPassedPublicDir,
|
|
67
68
|
});
|
package/dist/preview.js
CHANGED
|
@@ -48,10 +48,18 @@ const previewCommand = async (remotionRoot) => {
|
|
|
48
48
|
});
|
|
49
49
|
});
|
|
50
50
|
});
|
|
51
|
-
|
|
51
|
+
let envVariables = await (0, get_env_1.getEnvironmentVariables)((newEnvVariables) => {
|
|
52
|
+
waitForLiveEventsListener().then((listener) => {
|
|
53
|
+
envVariables = newEnvVariables;
|
|
54
|
+
listener.sendEventToClient({
|
|
55
|
+
type: 'new-env-variables',
|
|
56
|
+
newEnvVariables,
|
|
57
|
+
});
|
|
58
|
+
});
|
|
59
|
+
});
|
|
52
60
|
const { port, liveEventsServer } = await (0, start_server_1.startServer)(path_1.default.resolve(__dirname, 'previewEntry.js'), fullPath, {
|
|
53
61
|
getCurrentInputProps: () => inputProps,
|
|
54
|
-
envVariables,
|
|
62
|
+
getEnvVariables: () => envVariables,
|
|
55
63
|
port: desiredPort,
|
|
56
64
|
maxTimelineTracks: config_1.ConfigInternals.getMaxTimelineTracks(),
|
|
57
65
|
remotionRoot,
|
package/dist/print-help.js
CHANGED
|
@@ -11,7 +11,7 @@ const printFlags = (flags) => {
|
|
|
11
11
|
});
|
|
12
12
|
};
|
|
13
13
|
const printHelp = () => {
|
|
14
|
-
log_1.Log.info(`@remotion/cli ${packagejson.version} © ${new Date().getFullYear()}
|
|
14
|
+
log_1.Log.info(`@remotion/cli ${packagejson.version} © ${new Date().getFullYear()} The Remotion developers`);
|
|
15
15
|
log_1.Log.info();
|
|
16
16
|
log_1.Log.info('Available commands:');
|
|
17
17
|
log_1.Log.info('');
|
|
@@ -19,7 +19,7 @@ const printHelp = () => {
|
|
|
19
19
|
log_1.Log.info(chalk_1.chalk.gray('Start the preview server.'));
|
|
20
20
|
printFlags([['--props', 'Pass input props as filename or as JSON']]);
|
|
21
21
|
log_1.Log.info();
|
|
22
|
-
log_1.Log.info('remotion render <entry-point.ts> <comp-
|
|
22
|
+
log_1.Log.info('remotion render <entry-point.ts> <comp-id> <output-file.mp4>');
|
|
23
23
|
log_1.Log.info(chalk_1.chalk.gray('Render video, audio or an image sequence.'));
|
|
24
24
|
printFlags([
|
|
25
25
|
['--props', 'Pass input props as filename or as JSON'],
|
|
@@ -40,7 +40,7 @@ const printHelp = () => {
|
|
|
40
40
|
['--env-file', 'Specify a location for a dotenv file'],
|
|
41
41
|
]);
|
|
42
42
|
log_1.Log.info();
|
|
43
|
-
log_1.Log.info('remotion still <entry-point.ts> <comp-
|
|
43
|
+
log_1.Log.info('remotion still <entry-point.ts> <comp-id> <still.png>');
|
|
44
44
|
log_1.Log.info(chalk_1.chalk.gray('Render a still frame and save it as an image.'));
|
|
45
45
|
printFlags([
|
|
46
46
|
['--frame', 'Which frame to render (default 0)'],
|
|
@@ -59,6 +59,9 @@ const printHelp = () => {
|
|
|
59
59
|
log_1.Log.info('remotion compositions <index-file.ts>');
|
|
60
60
|
log_1.Log.info(chalk_1.chalk.gray('Prints the available compositions.'));
|
|
61
61
|
log_1.Log.info();
|
|
62
|
+
log_1.Log.info('remotion benchmark <index-file.ts> <list-of-compositions>');
|
|
63
|
+
log_1.Log.info(chalk_1.chalk.gray('Benchmarks rendering a composition. Same options as for render.'));
|
|
64
|
+
log_1.Log.info();
|
|
62
65
|
log_1.Log.info('remotion ' + versions_1.VERSIONS_COMMAND);
|
|
63
66
|
log_1.Log.info(chalk_1.chalk.gray('Prints and validates versions of all Remotion packages.'));
|
|
64
67
|
log_1.Log.info();
|
package/dist/progress-bar.js
CHANGED
|
@@ -34,7 +34,9 @@ const makeBundlingProgress = ({ progress, steps, doneIn, }) => [
|
|
|
34
34
|
doneIn === null
|
|
35
35
|
? (progress * 100).toFixed(0) + '%'
|
|
36
36
|
: chalk_1.chalk.gray(`${doneIn}ms`),
|
|
37
|
-
]
|
|
37
|
+
]
|
|
38
|
+
.filter(truthy_1.truthy)
|
|
39
|
+
.join(' ');
|
|
38
40
|
exports.makeBundlingProgress = makeBundlingProgress;
|
|
39
41
|
const makeRenderingProgress = ({ frames, totalFrames, steps, concurrency, doneIn, }) => {
|
|
40
42
|
const progress = frames / totalFrames;
|
package/dist/render.js
CHANGED
|
@@ -15,10 +15,12 @@ const config_1 = require("./config");
|
|
|
15
15
|
const get_cli_options_1 = require("./get-cli-options");
|
|
16
16
|
const get_composition_id_1 = require("./get-composition-id");
|
|
17
17
|
const get_filename_1 = require("./get-filename");
|
|
18
|
+
const get_render_media_options_1 = require("./get-render-media-options");
|
|
18
19
|
const log_1 = require("./log");
|
|
19
20
|
const parse_command_line_1 = require("./parse-command-line");
|
|
20
21
|
const progress_bar_1 = require("./progress-bar");
|
|
21
22
|
const setup_cache_1 = require("./setup-cache");
|
|
23
|
+
const user_passed_output_location_1 = require("./user-passed-output-location");
|
|
22
24
|
const validate_ffmpeg_version_1 = require("./validate-ffmpeg-version");
|
|
23
25
|
const render = async (remotionRoot) => {
|
|
24
26
|
const startTime = Date.now();
|
|
@@ -38,9 +40,15 @@ const render = async (remotionRoot) => {
|
|
|
38
40
|
process.exit(1);
|
|
39
41
|
}
|
|
40
42
|
log_1.Log.verbose('Asset dirs', downloadMap.assetDir);
|
|
41
|
-
const { codec,
|
|
43
|
+
const { codec, reason: codecReason } = (0, get_cli_options_1.getFinalCodec)({
|
|
44
|
+
downloadName: null,
|
|
45
|
+
outName: (0, user_passed_output_location_1.getUserPassedOutputLocation)(),
|
|
46
|
+
});
|
|
47
|
+
(0, get_cli_options_1.validateFfmpegCanUseCodec)(codec);
|
|
48
|
+
const { concurrency, frameRange, shouldOutputImageSequence, overwrite, inputProps, envVariables, quality, browser, imageFormat, browserExecutable, ffmpegExecutable, ffprobeExecutable, scale, chromiumOptions, port, everyNthFrame, puppeteerTimeout, publicDir, } = await (0, get_cli_options_1.getCliOptions)({
|
|
42
49
|
isLambda: false,
|
|
43
50
|
type: 'series',
|
|
51
|
+
codec,
|
|
44
52
|
});
|
|
45
53
|
const relativeOutputLocation = (0, get_filename_1.getOutputFilename)({
|
|
46
54
|
codec,
|
|
@@ -50,7 +58,7 @@ const render = async (remotionRoot) => {
|
|
|
50
58
|
});
|
|
51
59
|
const absoluteOutputFile = (0, get_cli_options_1.getAndValidateAbsoluteOutputFile)(relativeOutputLocation, overwrite);
|
|
52
60
|
const compositionId = (0, get_composition_id_1.getCompositionId)();
|
|
53
|
-
log_1.Log.info(chalk_1.chalk.gray(`Composition = ${compositionId}, Codec = ${codec}, Output = ${relativeOutputLocation}`));
|
|
61
|
+
log_1.Log.info(chalk_1.chalk.gray(`Composition = ${compositionId}, Codec = ${codec} (${codecReason}), Output = ${relativeOutputLocation}`));
|
|
54
62
|
log_1.Log.verbose('Browser executable: ', browserExecutable);
|
|
55
63
|
await (0, validate_ffmpeg_version_1.checkAndValidateFfmpegVersion)({
|
|
56
64
|
ffmpegExecutable,
|
|
@@ -95,10 +103,11 @@ const render = async (remotionRoot) => {
|
|
|
95
103
|
inputProps,
|
|
96
104
|
puppeteerInstance,
|
|
97
105
|
envVariables,
|
|
98
|
-
timeoutInMilliseconds:
|
|
106
|
+
timeoutInMilliseconds: puppeteerTimeout,
|
|
99
107
|
chromiumOptions,
|
|
100
108
|
browserExecutable,
|
|
101
109
|
downloadMap,
|
|
110
|
+
port,
|
|
102
111
|
});
|
|
103
112
|
const config = comps.find((c) => c.id === compositionId);
|
|
104
113
|
if (!config) {
|
|
@@ -199,17 +208,14 @@ const render = async (remotionRoot) => {
|
|
|
199
208
|
log_1.Log.info(chalk_1.chalk.green('\nYour image sequence is ready!'));
|
|
200
209
|
return;
|
|
201
210
|
}
|
|
202
|
-
await (0,
|
|
211
|
+
const options = await (0, get_render_media_options_1.getRenderMediaOptions)({
|
|
212
|
+
config,
|
|
203
213
|
outputLocation: absoluteOutputFile,
|
|
214
|
+
serveUrl: urlOrBundle,
|
|
204
215
|
codec,
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
ffmpegExecutable,
|
|
209
|
-
ffprobeExecutable,
|
|
210
|
-
frameRange,
|
|
211
|
-
imageFormat,
|
|
212
|
-
inputProps,
|
|
216
|
+
});
|
|
217
|
+
await (0, renderer_1.renderMedia)({
|
|
218
|
+
...options,
|
|
213
219
|
onProgress: (update) => {
|
|
214
220
|
encodedDoneIn = update.encodedDoneIn;
|
|
215
221
|
encodedFrames = update.encodedFrames;
|
|
@@ -219,26 +225,8 @@ const render = async (remotionRoot) => {
|
|
|
219
225
|
updateRenderProgress();
|
|
220
226
|
},
|
|
221
227
|
puppeteerInstance,
|
|
222
|
-
overwrite,
|
|
223
|
-
concurrency,
|
|
224
|
-
pixelFormat,
|
|
225
|
-
proResProfile,
|
|
226
|
-
quality,
|
|
227
|
-
serveUrl: urlOrBundle,
|
|
228
228
|
onDownload,
|
|
229
|
-
dumpBrowserLogs: renderer_1.RenderInternals.isEqualOrBelowLogLevel(config_1.ConfigInternals.Logging.getLogLevel(), 'verbose'),
|
|
230
|
-
chromiumOptions,
|
|
231
|
-
timeoutInMilliseconds: config_1.ConfigInternals.getCurrentPuppeteerTimeout(),
|
|
232
|
-
scale,
|
|
233
|
-
port,
|
|
234
|
-
numberOfGifLoops,
|
|
235
|
-
everyNthFrame,
|
|
236
|
-
verbose: renderer_1.RenderInternals.isEqualOrBelowLogLevel(config_1.ConfigInternals.Logging.getLogLevel(), 'verbose'),
|
|
237
229
|
downloadMap,
|
|
238
|
-
muted,
|
|
239
|
-
enforceAudioTrack,
|
|
240
|
-
browserExecutable,
|
|
241
|
-
ffmpegOverride,
|
|
242
230
|
});
|
|
243
231
|
log_1.Log.info();
|
|
244
232
|
log_1.Log.info();
|
package/dist/still.js
CHANGED
|
@@ -9,6 +9,7 @@ const fs_1 = require("fs");
|
|
|
9
9
|
const path_1 = __importDefault(require("path"));
|
|
10
10
|
const chalk_1 = require("./chalk");
|
|
11
11
|
const config_1 = require("./config");
|
|
12
|
+
const determine_image_format_1 = require("./determine-image-format");
|
|
12
13
|
const get_cli_options_1 = require("./get-cli-options");
|
|
13
14
|
const get_composition_id_1 = require("./get-composition-id");
|
|
14
15
|
const log_1 = require("./log");
|
|
@@ -18,6 +19,7 @@ const setup_cache_1 = require("./setup-cache");
|
|
|
18
19
|
const truthy_1 = require("./truthy");
|
|
19
20
|
const user_passed_output_location_1 = require("./user-passed-output-location");
|
|
20
21
|
const still = async (remotionRoot) => {
|
|
22
|
+
var _a, _b;
|
|
21
23
|
const startTime = Date.now();
|
|
22
24
|
const file = parse_command_line_1.parsedCli._[1];
|
|
23
25
|
const fullPath = renderer_1.RenderInternals.isServeUrl(file)
|
|
@@ -27,40 +29,26 @@ const still = async (remotionRoot) => {
|
|
|
27
29
|
log_1.Log.error('--frames flag was passed to the `still` command. This flag only works with the `render` command. Did you mean `--frame`? See reference: https://www.remotion.dev/docs/cli/');
|
|
28
30
|
process.exit(1);
|
|
29
31
|
}
|
|
30
|
-
const
|
|
31
|
-
if ((userPassedOutput === null || userPassedOutput === void 0 ? void 0 : userPassedOutput.endsWith('.jpeg')) ||
|
|
32
|
-
(userPassedOutput === null || userPassedOutput === void 0 ? void 0 : userPassedOutput.endsWith('.jpg'))) {
|
|
33
|
-
log_1.Log.verbose('Output file has a JPEG extension, setting the image format to JPEG.');
|
|
34
|
-
config_1.Config.Rendering.setImageFormat('jpeg');
|
|
35
|
-
}
|
|
36
|
-
if (userPassedOutput === null || userPassedOutput === void 0 ? void 0 : userPassedOutput.endsWith('.png')) {
|
|
37
|
-
log_1.Log.verbose('Output file has a PNG extension, setting the image format to PNG.');
|
|
38
|
-
config_1.Config.Rendering.setImageFormat('png');
|
|
39
|
-
}
|
|
40
|
-
const { inputProps, envVariables, quality, browser, imageFormat, stillFrame, browserExecutable, chromiumOptions, scale, ffmpegExecutable, ffprobeExecutable, overwrite, puppeteerTimeout, port, publicDir, } = await (0, get_cli_options_1.getCliOptions)({
|
|
32
|
+
const { inputProps, envVariables, quality, browser, stillFrame, browserExecutable, chromiumOptions, scale, ffmpegExecutable, ffprobeExecutable, overwrite, puppeteerTimeout, port, publicDir, } = await (0, get_cli_options_1.getCliOptions)({
|
|
41
33
|
isLambda: false,
|
|
42
34
|
type: 'still',
|
|
35
|
+
codec: 'h264',
|
|
43
36
|
});
|
|
44
37
|
log_1.Log.verbose('Browser executable: ', browserExecutable);
|
|
45
38
|
const compositionId = (0, get_composition_id_1.getCompositionId)();
|
|
39
|
+
const { format: imageFormat, source } = (0, determine_image_format_1.determineFinalImageFormat)({
|
|
40
|
+
cliFlag: (_a = parse_command_line_1.parsedCli['image-format']) !== null && _a !== void 0 ? _a : null,
|
|
41
|
+
configImageFormat: (_b = config_1.ConfigInternals.getUserPreferredImageFormat()) !== null && _b !== void 0 ? _b : null,
|
|
42
|
+
downloadName: null,
|
|
43
|
+
outName: (0, user_passed_output_location_1.getUserPassedOutputLocation)(),
|
|
44
|
+
isLambda: false,
|
|
45
|
+
});
|
|
46
46
|
const relativeOutputLocation = (0, user_passed_output_location_1.getOutputLocation)({
|
|
47
47
|
compositionId,
|
|
48
48
|
defaultExtension: imageFormat,
|
|
49
49
|
});
|
|
50
50
|
const absoluteOutputLocation = (0, get_cli_options_1.getAndValidateAbsoluteOutputFile)(relativeOutputLocation, overwrite);
|
|
51
|
-
log_1.Log.info(chalk_1.chalk.gray(`Output = ${relativeOutputLocation}, Format = ${imageFormat}, Composition = ${compositionId}`));
|
|
52
|
-
if (imageFormat === 'none') {
|
|
53
|
-
log_1.Log.error('No image format was selected - this is probably an error in Remotion - please post your command on Github Issues for help.');
|
|
54
|
-
process.exit(1);
|
|
55
|
-
}
|
|
56
|
-
if (imageFormat === 'png' && !absoluteOutputLocation.endsWith('.png')) {
|
|
57
|
-
log_1.Log.warn(`Rendering a PNG, expected a .png extension but got ${absoluteOutputLocation}`);
|
|
58
|
-
}
|
|
59
|
-
if (imageFormat === 'jpeg' &&
|
|
60
|
-
!absoluteOutputLocation.endsWith('.jpg') &&
|
|
61
|
-
!absoluteOutputLocation.endsWith('.jpeg')) {
|
|
62
|
-
log_1.Log.warn(`Rendering a JPEG, expected a .jpg or .jpeg extension but got ${absoluteOutputLocation}`);
|
|
63
|
-
}
|
|
51
|
+
log_1.Log.info(chalk_1.chalk.gray(`Output = ${relativeOutputLocation}, Format = ${imageFormat} (${source}), Composition = ${compositionId}`));
|
|
64
52
|
const browserInstance = (0, renderer_1.openBrowser)(browser, {
|
|
65
53
|
browserExecutable,
|
|
66
54
|
chromiumOptions,
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.validateImageFormat = void 0;
|
|
4
|
+
const log_1 = require("./log");
|
|
5
|
+
const validateImageFormat = (imageFormat, outName) => {
|
|
6
|
+
if (imageFormat === 'png' && !(outName === null || outName === void 0 ? void 0 : outName.endsWith('.png'))) {
|
|
7
|
+
log_1.Log.warn(`Rendering a PNG, expected a .png extension but got ${outName}`);
|
|
8
|
+
}
|
|
9
|
+
if (imageFormat === 'jpeg' &&
|
|
10
|
+
!(outName === null || outName === void 0 ? void 0 : outName.endsWith('.jpg')) &&
|
|
11
|
+
!(outName === null || outName === void 0 ? void 0 : outName.endsWith('.jpeg'))) {
|
|
12
|
+
log_1.Log.warn(`Rendering a JPEG, expected a .jpg or .jpeg extension but got ${outName}`);
|
|
13
|
+
}
|
|
14
|
+
};
|
|
15
|
+
exports.validateImageFormat = validateImageFormat;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@remotion/cli",
|
|
3
|
-
"version": "3.2.
|
|
3
|
+
"version": "3.2.28",
|
|
4
4
|
"description": "CLI for Remotion",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"sideEffects": false,
|
|
@@ -23,15 +23,15 @@
|
|
|
23
23
|
"author": "Jonny Burger <jonny@remotion.dev>",
|
|
24
24
|
"license": "SEE LICENSE IN LICENSE.md",
|
|
25
25
|
"dependencies": {
|
|
26
|
-
"@remotion/bundler": "3.2.
|
|
27
|
-
"@remotion/media-utils": "3.2.
|
|
28
|
-
"@remotion/player": "3.2.
|
|
29
|
-
"@remotion/renderer": "3.2.
|
|
26
|
+
"@remotion/bundler": "3.2.28",
|
|
27
|
+
"@remotion/media-utils": "3.2.28",
|
|
28
|
+
"@remotion/player": "3.2.28",
|
|
29
|
+
"@remotion/renderer": "3.2.28",
|
|
30
30
|
"better-opn": "2.1.1",
|
|
31
31
|
"dotenv": "9.0.2",
|
|
32
32
|
"memfs": "3.4.3",
|
|
33
33
|
"minimist": "1.2.6",
|
|
34
|
-
"remotion": "3.2.
|
|
34
|
+
"remotion": "3.2.28",
|
|
35
35
|
"semver": "7.3.5",
|
|
36
36
|
"source-map": "0.6.1"
|
|
37
37
|
},
|
|
@@ -71,5 +71,5 @@
|
|
|
71
71
|
"publishConfig": {
|
|
72
72
|
"access": "public"
|
|
73
73
|
},
|
|
74
|
-
"gitHead": "
|
|
74
|
+
"gitHead": "49bb70afa503bfb0c89ee51d8bf3386ad1b91ac4"
|
|
75
75
|
}
|