@remotion/renderer 4.0.0-alpha13 → 4.0.0-alpha16
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/assets/download-and-map-assets-to-file.d.ts +6 -4
- package/dist/assets/download-and-map-assets-to-file.js +30 -6
- package/dist/assets/download-file.d.ts +2 -2
- package/dist/assets/download-map.d.ts +3 -3
- package/dist/assets/ffmpeg-volume-expression.d.ts +2 -2
- package/dist/assets/get-audio-channels.d.ts +1 -0
- package/dist/assets/get-audio-channels.js +10 -5
- package/dist/assets/read-file.js +1 -1
- package/dist/assets/types.d.ts +4 -4
- package/dist/audio-codec.d.ts +2 -2
- package/dist/browser/Browser.d.ts +9 -9
- package/dist/browser/Browser.js +26 -32
- package/dist/browser/BrowserFetcher.d.ts +1 -1
- package/dist/browser/BrowserPage.d.ts +11 -2
- package/dist/browser/BrowserPage.js +47 -12
- package/dist/browser/BrowserRunner.js +19 -2
- package/dist/browser/ConsoleMessage.d.ts +1 -1
- package/dist/browser/DOMWorld.js +8 -8
- package/dist/browser/EvalTypes.d.ts +7 -7
- package/dist/browser/FrameManager.js +11 -11
- package/dist/browser/JSHandle.js +14 -14
- package/dist/browser/LaunchOptions.d.ts +1 -1
- package/dist/browser/Launcher.js +0 -1
- package/dist/browser/LifecycleWatcher.d.ts +1 -1
- package/dist/browser/NetworkEventManager.d.ts +4 -4
- package/dist/browser/NodeWebSocketTransport.js +16 -16
- package/dist/browser/Product.d.ts +1 -1
- package/dist/browser/Target.d.ts +2 -1
- package/dist/browser/Target.js +8 -2
- package/dist/browser/devtools-types.d.ts +10 -10
- package/dist/browser/mitt/index.d.ts +6 -6
- package/dist/browser/revisions.d.ts +1 -1
- package/dist/browser/should-log-message.d.ts +24 -0
- package/dist/browser/should-log-message.js +72 -0
- package/dist/browser-executable.d.ts +1 -1
- package/dist/browser-log.d.ts +1 -1
- package/dist/browser.d.ts +1 -1
- package/dist/chalk/index.d.ts +4 -4
- package/dist/codec-supports-media.d.ts +1 -1
- package/dist/codec.d.ts +2 -2
- package/dist/combine-videos.d.ts +1 -1
- package/dist/compositor/compose.d.ts +11 -2
- package/dist/compositor/compose.js +15 -4
- package/dist/compositor/compositor.d.ts +1 -1
- package/dist/compositor/compositor.js +19 -7
- package/dist/compositor/payloads.d.ts +5 -5
- package/dist/crf.d.ts +1 -1
- package/dist/error-handling/symbolicate-error.js +4 -2
- package/dist/ffmpeg-override.d.ts +1 -1
- package/dist/file-extensions.d.ts +1 -1
- package/dist/frame-range.d.ts +1 -1
- package/dist/get-browser-instance.d.ts +6 -1
- package/dist/get-browser-instance.js +9 -4
- package/dist/get-compositions.d.ts +18 -11
- package/dist/get-compositions.js +66 -49
- package/dist/get-frame-padded-index.d.ts +1 -1
- package/dist/image-format.d.ts +3 -3
- package/dist/index.d.ts +106 -16
- package/dist/index.js +25 -13
- package/dist/jpeg-quality.d.ts +1 -0
- package/dist/jpeg-quality.js +2 -1
- package/dist/log-level.d.ts +1 -1
- package/dist/logger.d.ts +5 -3
- package/dist/logger.js +12 -5
- package/dist/make-cancel-signal.d.ts +2 -2
- package/dist/merge-audio-track.d.ts +1 -1
- package/dist/mime-types.js +1 -1
- package/dist/offthread-video-server.d.ts +36 -4
- package/dist/offthread-video-server.js +48 -4
- package/dist/open-browser.d.ts +19 -10
- package/dist/open-browser.js +34 -21
- package/dist/options/option.d.ts +1 -1
- package/dist/parse-browser-error-stack.d.ts +1 -1
- package/dist/perf.d.ts +1 -1
- package/dist/pixel-format.d.ts +1 -1
- package/dist/prepare-server.d.ts +20 -8
- package/dist/prepare-server.js +52 -8
- package/dist/preprocess-audio-track.d.ts +2 -2
- package/dist/prespawn-ffmpeg.d.ts +1 -1
- package/dist/prespawn-ffmpeg.js +7 -7
- package/dist/prores-profile.d.ts +1 -1
- package/dist/puppeteer-screenshot.js +1 -2
- package/dist/render-frames.d.ts +32 -11
- package/dist/render-frames.js +112 -77
- package/dist/render-media.d.ts +50 -21
- package/dist/render-media.js +249 -197
- package/dist/render-still.d.ts +33 -18
- package/dist/render-still.js +71 -43
- package/dist/replace-browser.d.ts +1 -1
- package/dist/select-composition.d.ts +19 -11
- package/dist/select-composition.js +79 -42
- package/dist/serve-static.d.ts +2 -3
- package/dist/serve-static.js +2 -4
- package/dist/set-props-and-env.d.ts +1 -1
- package/dist/stitch-frames-to-video.d.ts +32 -10
- package/dist/stitch-frames-to-video.js +121 -99
- package/dist/stringify-ffmpeg-filter.d.ts +2 -2
- package/dist/symbolicate-stacktrace.d.ts +16 -3
- package/dist/symbolicate-stacktrace.js +49 -24
- package/dist/truthy.d.ts +1 -1
- package/dist/types.d.ts +2 -2
- package/dist/validate-opengl-renderer.d.ts +1 -1
- package/package.json +11 -11
package/dist/render-media.js
CHANGED
|
@@ -3,18 +3,20 @@ 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.renderMedia = void 0;
|
|
6
|
+
exports.renderMedia = exports.internalRenderMedia = void 0;
|
|
7
7
|
const node_fs_1 = __importDefault(require("node:fs"));
|
|
8
8
|
const node_os_1 = __importDefault(require("node:os"));
|
|
9
9
|
const node_path_1 = __importDefault(require("node:path"));
|
|
10
10
|
const remotion_1 = require("remotion");
|
|
11
|
-
const
|
|
11
|
+
const TimeoutSettings_1 = require("./browser/TimeoutSettings");
|
|
12
12
|
const can_use_parallel_encoding_1 = require("./can-use-parallel-encoding");
|
|
13
13
|
const codec_supports_media_1 = require("./codec-supports-media");
|
|
14
14
|
const crf_1 = require("./crf");
|
|
15
15
|
const delete_directory_1 = require("./delete-directory");
|
|
16
16
|
const ensure_frames_in_order_1 = require("./ensure-frames-in-order");
|
|
17
17
|
const ensure_output_directory_1 = require("./ensure-output-directory");
|
|
18
|
+
const find_closest_package_json_1 = require("./find-closest-package-json");
|
|
19
|
+
const get_concurrency_1 = require("./get-concurrency");
|
|
18
20
|
const get_duration_from_frame_range_1 = require("./get-duration-from-frame-range");
|
|
19
21
|
const get_extension_from_codec_1 = require("./get-extension-from-codec");
|
|
20
22
|
const get_extension_of_filename_1 = require("./get-extension-of-filename");
|
|
@@ -27,6 +29,7 @@ const make_cancel_signal_1 = require("./make-cancel-signal");
|
|
|
27
29
|
const overwrite_1 = require("./overwrite");
|
|
28
30
|
const perf_1 = require("./perf");
|
|
29
31
|
const pixel_format_1 = require("./pixel-format");
|
|
32
|
+
const prepare_server_1 = require("./prepare-server");
|
|
30
33
|
const prespawn_ffmpeg_1 = require("./prespawn-ffmpeg");
|
|
31
34
|
const prestitcher_memory_usage_1 = require("./prestitcher-memory-usage");
|
|
32
35
|
const prores_profile_1 = require("./prores-profile");
|
|
@@ -40,17 +43,8 @@ const validate_output_filename_1 = require("./validate-output-filename");
|
|
|
40
43
|
const validate_scale_1 = require("./validate-scale");
|
|
41
44
|
const validate_videobitrate_1 = require("./validate-videobitrate");
|
|
42
45
|
const SLOWEST_FRAME_COUNT = 10;
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
* @description Render a video from a composition
|
|
46
|
-
* @see [Documentation](https://www.remotion.dev/docs/renderer/render-media)
|
|
47
|
-
*/
|
|
48
|
-
const renderMedia = ({ proResProfile, crf, composition, inputProps, pixelFormat, codec, envVariables, frameRange, puppeteerInstance, outputLocation, onProgress, overwrite, onDownload, dumpBrowserLogs, onBrowserLog, onStart, timeoutInMilliseconds, chromiumOptions, scale, browserExecutable, port, cancelSignal, muted, enforceAudioTrack, ffmpegOverride, audioBitrate, videoBitrate, audioCodec, ...options }) => {
|
|
49
|
-
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s;
|
|
50
|
-
if (options.quality) {
|
|
51
|
-
throw new Error(`The "quality" option has been renamed. Please use "jpegQuality" instead.`);
|
|
52
|
-
}
|
|
53
|
-
(0, jpeg_quality_1.validateJpegQuality)(options.jpegQuality);
|
|
46
|
+
const internalRenderMedia = ({ proResProfile, crf, composition, inputProps, pixelFormat, codec, envVariables, frameRange, puppeteerInstance, outputLocation, onProgress, overwrite, onDownload, dumpBrowserLogs, onBrowserLog, onStart, timeoutInMilliseconds, chromiumOptions, scale, browserExecutable, port, cancelSignal, muted, enforceAudioTrack, ffmpegOverride, audioBitrate, videoBitrate, audioCodec, concurrency, disallowParallelEncoding, everyNthFrame, imageFormat: provisionalImageFormat, indent, jpegQuality, numberOfGifLoops, onCtrlCExit, preferLossless, serveUrl, server: reusedServer, verbose, }) => {
|
|
47
|
+
(0, jpeg_quality_1.validateJpegQuality)(jpegQuality);
|
|
54
48
|
(0, crf_1.validateQualitySettings)({ crf, codec, videoBitrate });
|
|
55
49
|
(0, validate_videobitrate_1.validateBitrate)(audioBitrate, 'audioBitrate');
|
|
56
50
|
(0, validate_videobitrate_1.validateBitrate)(videoBitrate, 'videoBitrate');
|
|
@@ -62,9 +56,9 @@ const renderMedia = ({ proResProfile, crf, composition, inputProps, pixelFormat,
|
|
|
62
56
|
if (outputLocation) {
|
|
63
57
|
(0, validate_output_filename_1.validateOutputFilename)({
|
|
64
58
|
codec,
|
|
65
|
-
audioCodec
|
|
59
|
+
audioCodec,
|
|
66
60
|
extension: (0, get_extension_of_filename_1.getExtensionOfFilename)(outputLocation),
|
|
67
|
-
preferLossless
|
|
61
|
+
preferLossless,
|
|
68
62
|
});
|
|
69
63
|
}
|
|
70
64
|
const absoluteOutputLocation = outputLocation
|
|
@@ -72,9 +66,7 @@ const renderMedia = ({ proResProfile, crf, composition, inputProps, pixelFormat,
|
|
|
72
66
|
: null;
|
|
73
67
|
(0, validate_scale_1.validateScale)(scale);
|
|
74
68
|
(0, validate_ffmpeg_override_1.validateFfmpegOverride)(ffmpegOverride);
|
|
75
|
-
const everyNthFrame = (_b = options.everyNthFrame) !== null && _b !== void 0 ? _b : 1;
|
|
76
69
|
(0, validate_every_nth_frame_1.validateEveryNthFrame)(everyNthFrame, codec);
|
|
77
|
-
const numberOfGifLoops = (_c = options.numberOfGifLoops) !== null && _c !== void 0 ? _c : null;
|
|
78
70
|
(0, validate_number_of_gif_loops_1.validateNumberOfGifLoops)(numberOfGifLoops, codec);
|
|
79
71
|
let stitchStage = 'encoding';
|
|
80
72
|
let stitcherFfmpeg;
|
|
@@ -85,61 +77,57 @@ const renderMedia = ({ proResProfile, crf, composition, inputProps, pixelFormat,
|
|
|
85
77
|
let encodedDoneIn = null;
|
|
86
78
|
let cancelled = false;
|
|
87
79
|
const renderStart = Date.now();
|
|
88
|
-
const downloadMap = (_e = (_d = options.internal) === null || _d === void 0 ? void 0 : _d.downloadMap) !== null && _e !== void 0 ? _e : (0, download_map_1.makeDownloadMap)();
|
|
89
80
|
const { estimatedUsage, freeMemory, hasEnoughMemory } = (0, prestitcher_memory_usage_1.shouldUseParallelEncoding)({
|
|
90
81
|
height: composition.height,
|
|
91
82
|
width: composition.width,
|
|
92
83
|
});
|
|
93
|
-
const parallelEncoding = !
|
|
84
|
+
const parallelEncoding = !disallowParallelEncoding &&
|
|
94
85
|
hasEnoughMemory &&
|
|
95
86
|
(0, can_use_parallel_encoding_1.canUseParallelEncoding)(codec);
|
|
96
87
|
logger_1.Log.verboseAdvanced({
|
|
97
|
-
indent
|
|
98
|
-
logLevel:
|
|
99
|
-
tag: '
|
|
88
|
+
indent,
|
|
89
|
+
logLevel: verbose ? 'verbose' : 'info',
|
|
90
|
+
tag: 'renderMedia()',
|
|
100
91
|
}, 'Free memory:', freeMemory, 'Estimated usage parallel encoding', estimatedUsage);
|
|
101
92
|
logger_1.Log.verboseAdvanced({
|
|
102
|
-
indent
|
|
103
|
-
logLevel:
|
|
104
|
-
tag: '
|
|
93
|
+
indent,
|
|
94
|
+
logLevel: verbose ? 'verbose' : 'info',
|
|
95
|
+
tag: 'renderMedia()',
|
|
105
96
|
}, 'Codec supports parallel rendering:', (0, can_use_parallel_encoding_1.canUseParallelEncoding)(codec));
|
|
106
97
|
logger_1.Log.verboseAdvanced({
|
|
107
|
-
indent
|
|
108
|
-
logLevel:
|
|
109
|
-
tag: '
|
|
110
|
-
}, 'User disallowed parallel encoding:', Boolean(
|
|
98
|
+
indent,
|
|
99
|
+
logLevel: verbose ? 'verbose' : 'info',
|
|
100
|
+
tag: 'renderMedia()',
|
|
101
|
+
}, 'User disallowed parallel encoding:', Boolean(disallowParallelEncoding));
|
|
111
102
|
if (parallelEncoding) {
|
|
112
103
|
logger_1.Log.verboseAdvanced({
|
|
113
|
-
indent
|
|
114
|
-
logLevel:
|
|
115
|
-
tag: '
|
|
104
|
+
indent,
|
|
105
|
+
logLevel: verbose ? 'verbose' : 'info',
|
|
106
|
+
tag: 'renderMedia()',
|
|
116
107
|
}, 'Parallel encoding is enabled.');
|
|
117
108
|
}
|
|
118
109
|
else {
|
|
119
110
|
logger_1.Log.verboseAdvanced({
|
|
120
|
-
indent
|
|
121
|
-
logLevel:
|
|
122
|
-
tag: '
|
|
111
|
+
indent,
|
|
112
|
+
logLevel: verbose ? 'verbose' : 'info',
|
|
113
|
+
tag: 'renderMedia()',
|
|
123
114
|
}, 'Parallel encoding is disabled.');
|
|
124
115
|
}
|
|
125
116
|
const imageFormat = (0, is_audio_codec_1.isAudioCodec)(codec)
|
|
126
117
|
? 'none'
|
|
127
|
-
:
|
|
128
|
-
const jpegQuality = imageFormat === 'jpeg' ? options.jpegQuality : undefined;
|
|
118
|
+
: provisionalImageFormat;
|
|
129
119
|
(0, image_format_1.validateSelectedPixelFormatAndImageFormatCombination)(pixelFormat, imageFormat);
|
|
120
|
+
const workingDir = node_fs_1.default.mkdtempSync(node_path_1.default.join(node_os_1.default.tmpdir(), 'react-motion-render'));
|
|
130
121
|
const preEncodedFileLocation = parallelEncoding
|
|
131
|
-
? node_path_1.default.join(
|
|
122
|
+
? node_path_1.default.join(workingDir, 'pre-encode.' + (0, get_extension_from_codec_1.getFileExtensionFromCodec)(codec, audioCodec))
|
|
132
123
|
: null;
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
: node_fs_1.default.mkdtempSync(node_path_1.default.join(node_os_1.default.tmpdir(), 'react-motion-render'));
|
|
136
|
-
if (((_s = options.internal) === null || _s === void 0 ? void 0 : _s.onCtrlCExit) && outputDir) {
|
|
137
|
-
options.internal.onCtrlCExit(() => (0, delete_directory_1.deleteDirectory)(outputDir));
|
|
124
|
+
if (onCtrlCExit && workingDir) {
|
|
125
|
+
onCtrlCExit(() => (0, delete_directory_1.deleteDirectory)(workingDir));
|
|
138
126
|
}
|
|
139
127
|
(0, validate_even_dimensions_with_codec_1.validateEvenDimensionsWithCodec)({
|
|
140
128
|
codec,
|
|
141
129
|
height: composition.height,
|
|
142
|
-
scale
|
|
130
|
+
scale,
|
|
143
131
|
width: composition.width,
|
|
144
132
|
});
|
|
145
133
|
const callUpdate = () => {
|
|
@@ -154,7 +142,7 @@ const renderMedia = ({ proResProfile, crf, composition, inputProps, pixelFormat,
|
|
|
154
142
|
100) / 100,
|
|
155
143
|
});
|
|
156
144
|
};
|
|
157
|
-
const realFrameRange = (0, get_frame_to_render_1.getRealFrameRange)(composition.durationInFrames, frameRange
|
|
145
|
+
const realFrameRange = (0, get_frame_to_render_1.getRealFrameRange)(composition.durationInFrames, frameRange);
|
|
158
146
|
const cancelRenderFrames = (0, make_cancel_signal_1.makeCancelSignal)();
|
|
159
147
|
const cancelPrestitcher = (0, make_cancel_signal_1.makeCancelSignal)();
|
|
160
148
|
const cancelStitcher = (0, make_cancel_signal_1.makeCancelSignal)();
|
|
@@ -162,14 +150,13 @@ const renderMedia = ({ proResProfile, crf, composition, inputProps, pixelFormat,
|
|
|
162
150
|
cancelRenderFrames.cancel();
|
|
163
151
|
});
|
|
164
152
|
const { waitForRightTimeOfFrameToBeInserted, setFrameToStitch, waitForFinish } = (0, ensure_frames_in_order_1.ensureFramesInOrder)(realFrameRange);
|
|
165
|
-
const fps = composition.fps /
|
|
153
|
+
const fps = composition.fps / everyNthFrame;
|
|
166
154
|
remotion_1.Internals.validateFps(fps, 'in "renderMedia()"', codec === 'gif');
|
|
167
155
|
const createPrestitcherIfNecessary = () => {
|
|
168
|
-
var _a, _b, _c;
|
|
169
156
|
if (preEncodedFileLocation) {
|
|
170
157
|
preStitcher = (0, prespawn_ffmpeg_1.prespawnFfmpeg)({
|
|
171
|
-
width: composition.width *
|
|
172
|
-
height: composition.height *
|
|
158
|
+
width: composition.width * scale,
|
|
159
|
+
height: composition.height * scale,
|
|
173
160
|
fps,
|
|
174
161
|
outputLocation: preEncodedFileLocation,
|
|
175
162
|
pixelFormat,
|
|
@@ -180,12 +167,12 @@ const renderMedia = ({ proResProfile, crf, composition, inputProps, pixelFormat,
|
|
|
180
167
|
encodedFrames = frame;
|
|
181
168
|
callUpdate();
|
|
182
169
|
},
|
|
183
|
-
verbose
|
|
170
|
+
verbose,
|
|
184
171
|
imageFormat,
|
|
185
172
|
signal: cancelPrestitcher.cancelSignal,
|
|
186
173
|
ffmpegOverride: ffmpegOverride !== null && ffmpegOverride !== void 0 ? ffmpegOverride : (({ args }) => args),
|
|
187
|
-
videoBitrate
|
|
188
|
-
indent
|
|
174
|
+
videoBitrate,
|
|
175
|
+
indent,
|
|
189
176
|
});
|
|
190
177
|
stitcherFfmpeg = preStitcher.task;
|
|
191
178
|
}
|
|
@@ -229,157 +216,168 @@ const renderMedia = ({ proResProfile, crf, composition, inputProps, pixelFormat,
|
|
|
229
216
|
}
|
|
230
217
|
minTime = (_b = (_a = slowestFrames[slowestFrames.length - 1]) === null || _a === void 0 ? void 0 : _a.time) !== null && _b !== void 0 ? _b : minTime;
|
|
231
218
|
};
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
}
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
onFrameBuffer: parallelEncoding
|
|
257
|
-
? async (buffer, frame) => {
|
|
258
|
-
var _a;
|
|
259
|
-
await waitForRightTimeOfFrameToBeInserted(frame);
|
|
260
|
-
if (cancelled) {
|
|
261
|
-
return;
|
|
262
|
-
}
|
|
263
|
-
const id = (0, perf_1.startPerfMeasure)('piping');
|
|
264
|
-
(_a = stitcherFfmpeg === null || stitcherFfmpeg === void 0 ? void 0 : stitcherFfmpeg.stdin) === null || _a === void 0 ? void 0 : _a.write(buffer);
|
|
265
|
-
(0, perf_1.stopPerfMeasure)(id);
|
|
266
|
-
setFrameToStitch(Math.min(realFrameRange[1] + 1, frame + everyNthFrame));
|
|
267
|
-
}
|
|
268
|
-
: undefined,
|
|
269
|
-
serveUrl: options.serveUrl,
|
|
270
|
-
dumpBrowserLogs,
|
|
271
|
-
onBrowserLog,
|
|
272
|
-
onDownload,
|
|
273
|
-
timeoutInMilliseconds,
|
|
274
|
-
chromiumOptions,
|
|
275
|
-
scale,
|
|
276
|
-
browserExecutable,
|
|
277
|
-
port,
|
|
278
|
-
cancelSignal: cancelRenderFrames.cancelSignal,
|
|
279
|
-
downloadMap,
|
|
280
|
-
muted: disableAudio,
|
|
281
|
-
verbose: (_a = options.verbose) !== null && _a !== void 0 ? _a : false,
|
|
282
|
-
indent: (_c = (_b = options.internal) === null || _b === void 0 ? void 0 : _b.indent) !== null && _c !== void 0 ? _c : false,
|
|
283
|
-
});
|
|
284
|
-
return renderFramesProc;
|
|
285
|
-
})
|
|
286
|
-
.then((renderFramesReturn) => {
|
|
287
|
-
return Promise.all([renderFramesReturn, waitForPrestitcherIfNecessary()]);
|
|
288
|
-
})
|
|
289
|
-
.then(([{ assetsInfo }]) => {
|
|
290
|
-
var _a, _b, _c;
|
|
291
|
-
renderedDoneIn = Date.now() - renderStart;
|
|
292
|
-
callUpdate();
|
|
293
|
-
if (absoluteOutputLocation) {
|
|
294
|
-
(0, ensure_output_directory_1.ensureOutputDirectory)(absoluteOutputLocation);
|
|
295
|
-
}
|
|
296
|
-
const stitchStart = Date.now();
|
|
297
|
-
return Promise.all([
|
|
298
|
-
(0, stitch_frames_to_video_1.stitchFramesToVideo)({
|
|
299
|
-
width: composition.width * (scale !== null && scale !== void 0 ? scale : 1),
|
|
300
|
-
height: composition.height * (scale !== null && scale !== void 0 ? scale : 1),
|
|
301
|
-
fps,
|
|
302
|
-
outputLocation: absoluteOutputLocation,
|
|
303
|
-
internalOptions: {
|
|
304
|
-
preEncodedFileLocation,
|
|
305
|
-
imageFormat,
|
|
306
|
-
preferLossless: (_a = options.preferLossless) !== null && _a !== void 0 ? _a : false,
|
|
307
|
-
indent: (_c = (_b = options.internal) === null || _b === void 0 ? void 0 : _b.indent) !== null && _c !== void 0 ? _c : false,
|
|
219
|
+
let cleanupServerFn = () => Promise.resolve(undefined);
|
|
220
|
+
const happyPath = new Promise((resolve, reject) => {
|
|
221
|
+
Promise.resolve(createPrestitcherIfNecessary())
|
|
222
|
+
.then(() => {
|
|
223
|
+
return (0, prepare_server_1.makeOrReuseServer)(reusedServer, {
|
|
224
|
+
concurrency: (0, get_concurrency_1.getActualConcurrency)(concurrency),
|
|
225
|
+
indent,
|
|
226
|
+
port,
|
|
227
|
+
remotionRoot: (0, find_closest_package_json_1.findRemotionRoot)(),
|
|
228
|
+
verbose,
|
|
229
|
+
webpackConfigOrServeUrl: serveUrl,
|
|
230
|
+
}, {
|
|
231
|
+
onDownload,
|
|
232
|
+
onError: (err) => reject(err),
|
|
233
|
+
});
|
|
234
|
+
})
|
|
235
|
+
.then(({ server, cleanupServer }) => {
|
|
236
|
+
cleanupServerFn = cleanupServer;
|
|
237
|
+
const renderFramesProc = (0, render_frames_1.internalRenderFrames)({
|
|
238
|
+
composition,
|
|
239
|
+
onFrameUpdate: (frame, frameIndex, timeToRenderInMilliseconds) => {
|
|
240
|
+
renderedFrames = frame;
|
|
241
|
+
callUpdate();
|
|
242
|
+
recordFrameTime(frameIndex, timeToRenderInMilliseconds);
|
|
308
243
|
},
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
crf,
|
|
314
|
-
assetsInfo,
|
|
315
|
-
onProgress: (frame) => {
|
|
316
|
-
stitchStage = 'muxing';
|
|
317
|
-
encodedFrames = frame;
|
|
244
|
+
concurrency,
|
|
245
|
+
outputDir: parallelEncoding ? null : workingDir,
|
|
246
|
+
onStart: (data) => {
|
|
247
|
+
renderedFrames = 0;
|
|
318
248
|
callUpdate();
|
|
249
|
+
onStart === null || onStart === void 0 ? void 0 : onStart(data);
|
|
319
250
|
},
|
|
251
|
+
inputProps,
|
|
252
|
+
envVariables,
|
|
253
|
+
imageFormat,
|
|
254
|
+
jpegQuality,
|
|
255
|
+
frameRange,
|
|
256
|
+
puppeteerInstance,
|
|
257
|
+
everyNthFrame,
|
|
258
|
+
onFrameBuffer: parallelEncoding
|
|
259
|
+
? async (buffer, frame) => {
|
|
260
|
+
var _a;
|
|
261
|
+
await waitForRightTimeOfFrameToBeInserted(frame);
|
|
262
|
+
if (cancelled) {
|
|
263
|
+
return;
|
|
264
|
+
}
|
|
265
|
+
const id = (0, perf_1.startPerfMeasure)('piping');
|
|
266
|
+
(_a = stitcherFfmpeg === null || stitcherFfmpeg === void 0 ? void 0 : stitcherFfmpeg.stdin) === null || _a === void 0 ? void 0 : _a.write(buffer);
|
|
267
|
+
(0, perf_1.stopPerfMeasure)(id);
|
|
268
|
+
setFrameToStitch(Math.min(realFrameRange[1] + 1, frame + everyNthFrame));
|
|
269
|
+
}
|
|
270
|
+
: null,
|
|
271
|
+
webpackBundleOrServeUrl: serveUrl,
|
|
272
|
+
dumpBrowserLogs,
|
|
273
|
+
onBrowserLog,
|
|
320
274
|
onDownload,
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
275
|
+
timeoutInMilliseconds,
|
|
276
|
+
chromiumOptions,
|
|
277
|
+
scale,
|
|
278
|
+
browserExecutable,
|
|
279
|
+
port,
|
|
280
|
+
cancelSignal: cancelRenderFrames.cancelSignal,
|
|
325
281
|
muted: disableAudio,
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
videoBitrate,
|
|
330
|
-
audioCodec: audioCodec !== null && audioCodec !== void 0 ? audioCodec : null,
|
|
331
|
-
}),
|
|
332
|
-
stitchStart,
|
|
333
|
-
]);
|
|
334
|
-
})
|
|
335
|
-
.then(([buffer, stitchStart]) => {
|
|
336
|
-
encodedFrames = (0, get_duration_from_frame_range_1.getFramesToRender)(realFrameRange, everyNthFrame).length;
|
|
337
|
-
encodedDoneIn = Date.now() - stitchStart;
|
|
338
|
-
callUpdate();
|
|
339
|
-
slowestFrames.sort((a, b) => b.time - a.time);
|
|
340
|
-
const result = {
|
|
341
|
-
buffer,
|
|
342
|
-
slowestFrames,
|
|
343
|
-
};
|
|
344
|
-
return result;
|
|
345
|
-
})
|
|
346
|
-
.catch((err) => {
|
|
347
|
-
/**
|
|
348
|
-
* When an error is thrown in renderFrames(...) (e.g., when delayRender() is used incorrectly), fs.unlinkSync(...) throws an error that the file is locked because ffmpeg is still running, and renderMedia returns it.
|
|
349
|
-
* Therefore we first kill the FFMPEG process before deleting the file
|
|
350
|
-
*/
|
|
351
|
-
cancelled = true;
|
|
352
|
-
cancelRenderFrames.cancel();
|
|
353
|
-
cancelStitcher.cancel();
|
|
354
|
-
cancelPrestitcher.cancel();
|
|
355
|
-
if (stitcherFfmpeg !== undefined && stitcherFfmpeg.exitCode === null) {
|
|
356
|
-
const promise = new Promise((resolve) => {
|
|
357
|
-
setTimeout(() => {
|
|
358
|
-
resolve();
|
|
359
|
-
}, 2000);
|
|
360
|
-
stitcherFfmpeg.on('close', resolve);
|
|
361
|
-
});
|
|
362
|
-
stitcherFfmpeg.kill();
|
|
363
|
-
return promise.then(() => {
|
|
364
|
-
throw err;
|
|
282
|
+
verbose,
|
|
283
|
+
indent,
|
|
284
|
+
server,
|
|
365
285
|
});
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
286
|
+
return renderFramesProc;
|
|
287
|
+
})
|
|
288
|
+
.then((renderFramesReturn) => {
|
|
289
|
+
return Promise.all([
|
|
290
|
+
renderFramesReturn,
|
|
291
|
+
waitForPrestitcherIfNecessary(),
|
|
292
|
+
]);
|
|
293
|
+
})
|
|
294
|
+
.then(([{ assetsInfo }]) => {
|
|
295
|
+
renderedDoneIn = Date.now() - renderStart;
|
|
296
|
+
callUpdate();
|
|
297
|
+
if (absoluteOutputLocation) {
|
|
298
|
+
(0, ensure_output_directory_1.ensureOutputDirectory)(absoluteOutputLocation);
|
|
299
|
+
}
|
|
300
|
+
const stitchStart = Date.now();
|
|
301
|
+
return Promise.all([
|
|
302
|
+
(0, stitch_frames_to_video_1.internalStitchFramesToVideo)({
|
|
303
|
+
width: composition.width * scale,
|
|
304
|
+
height: composition.height * scale,
|
|
305
|
+
fps,
|
|
306
|
+
outputLocation: absoluteOutputLocation,
|
|
307
|
+
preEncodedFileLocation,
|
|
308
|
+
preferLossless,
|
|
309
|
+
indent,
|
|
310
|
+
force: overwrite,
|
|
311
|
+
pixelFormat,
|
|
312
|
+
codec,
|
|
313
|
+
proResProfile,
|
|
314
|
+
crf,
|
|
315
|
+
assetsInfo,
|
|
316
|
+
onProgress: (frame) => {
|
|
317
|
+
stitchStage = 'muxing';
|
|
318
|
+
encodedFrames = frame;
|
|
319
|
+
callUpdate();
|
|
320
|
+
},
|
|
321
|
+
onDownload,
|
|
322
|
+
numberOfGifLoops,
|
|
323
|
+
verbose,
|
|
324
|
+
dir: workingDir,
|
|
325
|
+
cancelSignal: cancelStitcher.cancelSignal,
|
|
326
|
+
muted: disableAudio,
|
|
327
|
+
enforceAudioTrack,
|
|
328
|
+
ffmpegOverride: ffmpegOverride !== null && ffmpegOverride !== void 0 ? ffmpegOverride : null,
|
|
329
|
+
audioBitrate,
|
|
330
|
+
videoBitrate,
|
|
331
|
+
audioCodec,
|
|
332
|
+
}),
|
|
333
|
+
stitchStart,
|
|
334
|
+
]);
|
|
335
|
+
})
|
|
336
|
+
.then(([buffer, stitchStart]) => {
|
|
337
|
+
encodedFrames = (0, get_duration_from_frame_range_1.getFramesToRender)(realFrameRange, everyNthFrame).length;
|
|
338
|
+
encodedDoneIn = Date.now() - stitchStart;
|
|
339
|
+
callUpdate();
|
|
340
|
+
slowestFrames.sort((a, b) => b.time - a.time);
|
|
341
|
+
const result = {
|
|
342
|
+
buffer,
|
|
343
|
+
slowestFrames,
|
|
344
|
+
};
|
|
345
|
+
resolve(result);
|
|
346
|
+
})
|
|
347
|
+
.catch((err) => {
|
|
348
|
+
/**
|
|
349
|
+
* When an error is thrown in renderFrames(...) (e.g., when delayRender() is used incorrectly), fs.unlinkSync(...) throws an error that the file is locked because ffmpeg is still running, and renderMedia returns it.
|
|
350
|
+
* Therefore we first kill the FFMPEG process before deleting the file
|
|
351
|
+
*/
|
|
352
|
+
cancelled = true;
|
|
353
|
+
cancelRenderFrames.cancel();
|
|
354
|
+
cancelStitcher.cancel();
|
|
355
|
+
cancelPrestitcher.cancel();
|
|
356
|
+
if (stitcherFfmpeg !== undefined && stitcherFfmpeg.exitCode === null) {
|
|
357
|
+
const promise = new Promise((res) => {
|
|
358
|
+
setTimeout(() => {
|
|
359
|
+
res();
|
|
360
|
+
}, 2000);
|
|
361
|
+
stitcherFfmpeg.on('close', res);
|
|
362
|
+
});
|
|
363
|
+
stitcherFfmpeg.kill();
|
|
364
|
+
return promise.then(() => {
|
|
365
|
+
reject(err);
|
|
366
|
+
});
|
|
367
|
+
}
|
|
368
|
+
reject(err);
|
|
369
|
+
})
|
|
370
|
+
.finally(() => {
|
|
371
|
+
if (preEncodedFileLocation !== null &&
|
|
372
|
+
node_fs_1.default.existsSync(preEncodedFileLocation)) {
|
|
373
|
+
(0, delete_directory_1.deleteDirectory)(node_path_1.default.dirname(preEncodedFileLocation));
|
|
374
|
+
}
|
|
375
|
+
// Clean temporary image frames when rendering ends or fails
|
|
376
|
+
if (workingDir && node_fs_1.default.existsSync(workingDir)) {
|
|
377
|
+
(0, delete_directory_1.deleteDirectory)(workingDir);
|
|
378
|
+
}
|
|
379
|
+
cleanupServerFn === null || cleanupServerFn === void 0 ? void 0 : cleanupServerFn(false);
|
|
380
|
+
});
|
|
383
381
|
});
|
|
384
382
|
return Promise.race([
|
|
385
383
|
happyPath,
|
|
@@ -390,4 +388,58 @@ const renderMedia = ({ proResProfile, crf, composition, inputProps, pixelFormat,
|
|
|
390
388
|
}),
|
|
391
389
|
]);
|
|
392
390
|
};
|
|
391
|
+
exports.internalRenderMedia = internalRenderMedia;
|
|
392
|
+
/**
|
|
393
|
+
*
|
|
394
|
+
* @description Render a video from a composition
|
|
395
|
+
* @see [Documentation](https://www.remotion.dev/docs/renderer/render-media)
|
|
396
|
+
*/
|
|
397
|
+
const renderMedia = ({ proResProfile, crf, composition, inputProps, pixelFormat, codec, envVariables, frameRange, puppeteerInstance, outputLocation, onProgress, overwrite, onDownload, dumpBrowserLogs, onBrowserLog, onStart, timeoutInMilliseconds, chromiumOptions, scale, browserExecutable, port, cancelSignal, muted, enforceAudioTrack, ffmpegOverride, audioBitrate, videoBitrate, audioCodec, jpegQuality, concurrency, serveUrl, disallowParallelEncoding, everyNthFrame, imageFormat, numberOfGifLoops, preferLossless, verbose, quality, }) => {
|
|
398
|
+
var _a;
|
|
399
|
+
if (quality !== undefined) {
|
|
400
|
+
console.warn(`The "quality" option has been renamed. Please use "jpegQuality" instead.`);
|
|
401
|
+
}
|
|
402
|
+
return (0, exports.internalRenderMedia)({
|
|
403
|
+
proResProfile: proResProfile !== null && proResProfile !== void 0 ? proResProfile : undefined,
|
|
404
|
+
codec,
|
|
405
|
+
composition,
|
|
406
|
+
serveUrl,
|
|
407
|
+
audioBitrate: audioBitrate !== null && audioBitrate !== void 0 ? audioBitrate : null,
|
|
408
|
+
audioCodec: audioCodec !== null && audioCodec !== void 0 ? audioCodec : null,
|
|
409
|
+
browserExecutable: browserExecutable !== null && browserExecutable !== void 0 ? browserExecutable : null,
|
|
410
|
+
cancelSignal,
|
|
411
|
+
chromiumOptions: chromiumOptions !== null && chromiumOptions !== void 0 ? chromiumOptions : {},
|
|
412
|
+
concurrency: concurrency !== null && concurrency !== void 0 ? concurrency : null,
|
|
413
|
+
crf: crf !== null && crf !== void 0 ? crf : null,
|
|
414
|
+
disallowParallelEncoding: disallowParallelEncoding !== null && disallowParallelEncoding !== void 0 ? disallowParallelEncoding : false,
|
|
415
|
+
dumpBrowserLogs: dumpBrowserLogs !== null && dumpBrowserLogs !== void 0 ? dumpBrowserLogs : false,
|
|
416
|
+
enforceAudioTrack: enforceAudioTrack !== null && enforceAudioTrack !== void 0 ? enforceAudioTrack : false,
|
|
417
|
+
envVariables: envVariables !== null && envVariables !== void 0 ? envVariables : {},
|
|
418
|
+
everyNthFrame: everyNthFrame !== null && everyNthFrame !== void 0 ? everyNthFrame : 1,
|
|
419
|
+
ffmpegOverride: ffmpegOverride !== null && ffmpegOverride !== void 0 ? ffmpegOverride : undefined,
|
|
420
|
+
frameRange: frameRange !== null && frameRange !== void 0 ? frameRange : null,
|
|
421
|
+
imageFormat: imageFormat !== null && imageFormat !== void 0 ? imageFormat : image_format_1.DEFAULT_VIDEO_IMAGE_FORMAT,
|
|
422
|
+
inputProps: inputProps !== null && inputProps !== void 0 ? inputProps : {},
|
|
423
|
+
jpegQuality: (_a = jpegQuality !== null && jpegQuality !== void 0 ? jpegQuality : quality) !== null && _a !== void 0 ? _a : jpeg_quality_1.DEFAULT_JPEG_QUALITY,
|
|
424
|
+
muted: muted !== null && muted !== void 0 ? muted : false,
|
|
425
|
+
numberOfGifLoops: numberOfGifLoops !== null && numberOfGifLoops !== void 0 ? numberOfGifLoops : null,
|
|
426
|
+
onBrowserLog: onBrowserLog !== null && onBrowserLog !== void 0 ? onBrowserLog : null,
|
|
427
|
+
onDownload: onDownload !== null && onDownload !== void 0 ? onDownload : (() => undefined),
|
|
428
|
+
onProgress: onProgress !== null && onProgress !== void 0 ? onProgress : (() => undefined),
|
|
429
|
+
onStart: onStart !== null && onStart !== void 0 ? onStart : (() => undefined),
|
|
430
|
+
outputLocation: outputLocation !== null && outputLocation !== void 0 ? outputLocation : null,
|
|
431
|
+
overwrite: overwrite !== null && overwrite !== void 0 ? overwrite : overwrite_1.DEFAULT_OVERWRITE,
|
|
432
|
+
pixelFormat: pixelFormat !== null && pixelFormat !== void 0 ? pixelFormat : pixel_format_1.DEFAULT_PIXEL_FORMAT,
|
|
433
|
+
port: port !== null && port !== void 0 ? port : null,
|
|
434
|
+
puppeteerInstance: puppeteerInstance !== null && puppeteerInstance !== void 0 ? puppeteerInstance : undefined,
|
|
435
|
+
scale: scale !== null && scale !== void 0 ? scale : 1,
|
|
436
|
+
timeoutInMilliseconds: timeoutInMilliseconds !== null && timeoutInMilliseconds !== void 0 ? timeoutInMilliseconds : TimeoutSettings_1.DEFAULT_TIMEOUT,
|
|
437
|
+
videoBitrate: videoBitrate !== null && videoBitrate !== void 0 ? videoBitrate : null,
|
|
438
|
+
verbose: verbose !== null && verbose !== void 0 ? verbose : false,
|
|
439
|
+
preferLossless: preferLossless !== null && preferLossless !== void 0 ? preferLossless : false,
|
|
440
|
+
indent: false,
|
|
441
|
+
onCtrlCExit: () => undefined,
|
|
442
|
+
server: undefined,
|
|
443
|
+
});
|
|
444
|
+
};
|
|
393
445
|
exports.renderMedia = renderMedia;
|
package/dist/render-still.d.ts
CHANGED
|
@@ -1,23 +1,44 @@
|
|
|
1
1
|
/// <reference types="node" />
|
|
2
2
|
import type { AnySmallCompMetadata } from 'remotion';
|
|
3
3
|
import type { RenderMediaOnDownload } from './assets/download-and-map-assets-to-file';
|
|
4
|
-
import type { DownloadMap } from './assets/download-map';
|
|
5
4
|
import type { BrowserExecutable } from './browser-executable';
|
|
6
5
|
import type { BrowserLog } from './browser-log';
|
|
7
6
|
import type { HeadlessBrowser } from './browser/Browser';
|
|
8
7
|
import type { StillImageFormat } from './image-format';
|
|
9
8
|
import type { CancelSignal } from './make-cancel-signal';
|
|
10
9
|
import type { ChromiumOptions } from './open-browser';
|
|
11
|
-
|
|
10
|
+
import type { RemotionServer } from './prepare-server';
|
|
11
|
+
type InternalRenderStillOptions = {
|
|
12
|
+
composition: AnySmallCompMetadata;
|
|
13
|
+
output: string | null;
|
|
14
|
+
frame: number;
|
|
15
|
+
inputProps: Record<string, unknown>;
|
|
16
|
+
imageFormat: StillImageFormat;
|
|
17
|
+
jpegQuality: number;
|
|
18
|
+
puppeteerInstance: HeadlessBrowser | null;
|
|
19
|
+
dumpBrowserLogs: boolean;
|
|
20
|
+
envVariables: Record<string, string>;
|
|
21
|
+
overwrite: boolean;
|
|
22
|
+
browserExecutable: BrowserExecutable;
|
|
23
|
+
onBrowserLog: null | ((log: BrowserLog) => void);
|
|
24
|
+
timeoutInMilliseconds: number;
|
|
25
|
+
chromiumOptions: ChromiumOptions;
|
|
26
|
+
scale: number;
|
|
27
|
+
onDownload: RenderMediaOnDownload | null;
|
|
28
|
+
cancelSignal: CancelSignal | null;
|
|
29
|
+
indent: boolean;
|
|
30
|
+
server: RemotionServer | undefined;
|
|
31
|
+
verbose: boolean;
|
|
32
|
+
serveUrl: string;
|
|
33
|
+
port: number | null;
|
|
34
|
+
};
|
|
35
|
+
export type RenderStillOptions = {
|
|
36
|
+
port?: number | null;
|
|
12
37
|
composition: AnySmallCompMetadata;
|
|
13
38
|
output?: string | null;
|
|
14
39
|
frame?: number;
|
|
15
40
|
inputProps?: Record<string, unknown>;
|
|
16
41
|
imageFormat?: StillImageFormat;
|
|
17
|
-
/**
|
|
18
|
-
* @deprecated Renamed to `jpegQuality`
|
|
19
|
-
*/
|
|
20
|
-
quality?: never;
|
|
21
42
|
jpegQuality?: number;
|
|
22
43
|
puppeteerInstance?: HeadlessBrowser;
|
|
23
44
|
dumpBrowserLogs?: boolean;
|
|
@@ -30,23 +51,17 @@ declare type InnerStillOptions = {
|
|
|
30
51
|
scale?: number;
|
|
31
52
|
onDownload?: RenderMediaOnDownload;
|
|
32
53
|
cancelSignal?: CancelSignal;
|
|
54
|
+
verbose?: boolean;
|
|
55
|
+
serveUrl: string;
|
|
33
56
|
/**
|
|
34
|
-
* @deprecated
|
|
35
|
-
*/
|
|
36
|
-
downloadMap?: DownloadMap;
|
|
37
|
-
/**
|
|
38
|
-
* @deprecated Only for Remotion internal usage
|
|
57
|
+
* @deprecated Renamed to `jpegQuality`
|
|
39
58
|
*/
|
|
40
|
-
|
|
41
|
-
verbose?: boolean;
|
|
59
|
+
quality?: never;
|
|
42
60
|
};
|
|
43
|
-
|
|
61
|
+
type RenderStillReturnValue = {
|
|
44
62
|
buffer: Buffer | null;
|
|
45
63
|
};
|
|
46
|
-
export declare
|
|
47
|
-
serveUrl: string;
|
|
48
|
-
port?: number | null;
|
|
49
|
-
};
|
|
64
|
+
export declare const internalRenderStill: (options: InternalRenderStillOptions) => Promise<RenderStillReturnValue>;
|
|
50
65
|
/**
|
|
51
66
|
*
|
|
52
67
|
* @description Render a still frame from a composition
|