@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.
Files changed (103) hide show
  1. package/dist/assets/download-and-map-assets-to-file.d.ts +6 -4
  2. package/dist/assets/download-and-map-assets-to-file.js +30 -6
  3. package/dist/assets/download-file.d.ts +2 -2
  4. package/dist/assets/download-map.d.ts +3 -3
  5. package/dist/assets/ffmpeg-volume-expression.d.ts +2 -2
  6. package/dist/assets/get-audio-channels.d.ts +1 -0
  7. package/dist/assets/get-audio-channels.js +10 -5
  8. package/dist/assets/read-file.js +1 -1
  9. package/dist/assets/types.d.ts +4 -4
  10. package/dist/audio-codec.d.ts +2 -2
  11. package/dist/browser/Browser.d.ts +9 -9
  12. package/dist/browser/Browser.js +26 -32
  13. package/dist/browser/BrowserFetcher.d.ts +1 -1
  14. package/dist/browser/BrowserPage.d.ts +11 -2
  15. package/dist/browser/BrowserPage.js +47 -12
  16. package/dist/browser/BrowserRunner.js +19 -2
  17. package/dist/browser/ConsoleMessage.d.ts +1 -1
  18. package/dist/browser/DOMWorld.js +8 -8
  19. package/dist/browser/EvalTypes.d.ts +7 -7
  20. package/dist/browser/FrameManager.js +11 -11
  21. package/dist/browser/JSHandle.js +14 -14
  22. package/dist/browser/LaunchOptions.d.ts +1 -1
  23. package/dist/browser/Launcher.js +0 -1
  24. package/dist/browser/LifecycleWatcher.d.ts +1 -1
  25. package/dist/browser/NetworkEventManager.d.ts +4 -4
  26. package/dist/browser/NodeWebSocketTransport.js +16 -16
  27. package/dist/browser/Product.d.ts +1 -1
  28. package/dist/browser/Target.d.ts +2 -1
  29. package/dist/browser/Target.js +8 -2
  30. package/dist/browser/devtools-types.d.ts +10 -10
  31. package/dist/browser/mitt/index.d.ts +6 -6
  32. package/dist/browser/revisions.d.ts +1 -1
  33. package/dist/browser/should-log-message.d.ts +24 -0
  34. package/dist/browser/should-log-message.js +72 -0
  35. package/dist/browser-executable.d.ts +1 -1
  36. package/dist/browser-log.d.ts +1 -1
  37. package/dist/browser.d.ts +1 -1
  38. package/dist/chalk/index.d.ts +4 -4
  39. package/dist/codec-supports-media.d.ts +1 -1
  40. package/dist/codec.d.ts +2 -2
  41. package/dist/combine-videos.d.ts +1 -1
  42. package/dist/compositor/compose.d.ts +11 -2
  43. package/dist/compositor/compose.js +15 -4
  44. package/dist/compositor/compositor.d.ts +1 -1
  45. package/dist/compositor/compositor.js +19 -7
  46. package/dist/compositor/payloads.d.ts +5 -5
  47. package/dist/crf.d.ts +1 -1
  48. package/dist/error-handling/symbolicate-error.js +4 -2
  49. package/dist/ffmpeg-override.d.ts +1 -1
  50. package/dist/file-extensions.d.ts +1 -1
  51. package/dist/frame-range.d.ts +1 -1
  52. package/dist/get-browser-instance.d.ts +6 -1
  53. package/dist/get-browser-instance.js +9 -4
  54. package/dist/get-compositions.d.ts +18 -11
  55. package/dist/get-compositions.js +66 -49
  56. package/dist/get-frame-padded-index.d.ts +1 -1
  57. package/dist/image-format.d.ts +3 -3
  58. package/dist/index.d.ts +106 -16
  59. package/dist/index.js +25 -13
  60. package/dist/jpeg-quality.d.ts +1 -0
  61. package/dist/jpeg-quality.js +2 -1
  62. package/dist/log-level.d.ts +1 -1
  63. package/dist/logger.d.ts +5 -3
  64. package/dist/logger.js +12 -5
  65. package/dist/make-cancel-signal.d.ts +2 -2
  66. package/dist/merge-audio-track.d.ts +1 -1
  67. package/dist/mime-types.js +1 -1
  68. package/dist/offthread-video-server.d.ts +36 -4
  69. package/dist/offthread-video-server.js +48 -4
  70. package/dist/open-browser.d.ts +19 -10
  71. package/dist/open-browser.js +34 -21
  72. package/dist/options/option.d.ts +1 -1
  73. package/dist/parse-browser-error-stack.d.ts +1 -1
  74. package/dist/perf.d.ts +1 -1
  75. package/dist/pixel-format.d.ts +1 -1
  76. package/dist/prepare-server.d.ts +20 -8
  77. package/dist/prepare-server.js +52 -8
  78. package/dist/preprocess-audio-track.d.ts +2 -2
  79. package/dist/prespawn-ffmpeg.d.ts +1 -1
  80. package/dist/prespawn-ffmpeg.js +7 -7
  81. package/dist/prores-profile.d.ts +1 -1
  82. package/dist/puppeteer-screenshot.js +1 -2
  83. package/dist/render-frames.d.ts +32 -11
  84. package/dist/render-frames.js +112 -77
  85. package/dist/render-media.d.ts +50 -21
  86. package/dist/render-media.js +249 -197
  87. package/dist/render-still.d.ts +33 -18
  88. package/dist/render-still.js +71 -43
  89. package/dist/replace-browser.d.ts +1 -1
  90. package/dist/select-composition.d.ts +19 -11
  91. package/dist/select-composition.js +79 -42
  92. package/dist/serve-static.d.ts +2 -3
  93. package/dist/serve-static.js +2 -4
  94. package/dist/set-props-and-env.d.ts +1 -1
  95. package/dist/stitch-frames-to-video.d.ts +32 -10
  96. package/dist/stitch-frames-to-video.js +121 -99
  97. package/dist/stringify-ffmpeg-filter.d.ts +2 -2
  98. package/dist/symbolicate-stacktrace.d.ts +16 -3
  99. package/dist/symbolicate-stacktrace.js +49 -24
  100. package/dist/truthy.d.ts +1 -1
  101. package/dist/types.d.ts +2 -2
  102. package/dist/validate-opengl-renderer.d.ts +1 -1
  103. package/package.json +11 -11
@@ -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 download_map_1 = require("./assets/download-map");
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: audioCodec !== null && audioCodec !== void 0 ? audioCodec : null,
59
+ audioCodec,
66
60
  extension: (0, get_extension_of_filename_1.getExtensionOfFilename)(outputLocation),
67
- preferLossless: (_a = options.preferLossless) !== null && _a !== void 0 ? _a : false,
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 = !options.disallowParallelEncoding &&
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: (_g = (_f = options.internal) === null || _f === void 0 ? void 0 : _f.indent) !== null && _g !== void 0 ? _g : false,
98
- logLevel: options.verbose ? 'verbose' : 'info',
99
- tag: 'PARALLEL ENCODING',
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: (_j = (_h = options.internal) === null || _h === void 0 ? void 0 : _h.indent) !== null && _j !== void 0 ? _j : false,
103
- logLevel: options.verbose ? 'verbose' : 'info',
104
- tag: 'PARALLEL ENCODING',
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: (_l = (_k = options.internal) === null || _k === void 0 ? void 0 : _k.indent) !== null && _l !== void 0 ? _l : false,
108
- logLevel: options.verbose ? 'verbose' : 'info',
109
- tag: 'PARALLEL ENCODING',
110
- }, 'User disallowed parallel encoding:', Boolean(options.disallowParallelEncoding));
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: (_o = (_m = options.internal) === null || _m === void 0 ? void 0 : _m.indent) !== null && _o !== void 0 ? _o : false,
114
- logLevel: options.verbose ? 'verbose' : 'info',
115
- tag: 'PARALLEL ENCODING',
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: (_q = (_p = options.internal) === null || _p === void 0 ? void 0 : _p.indent) !== null && _q !== void 0 ? _q : false,
121
- logLevel: options.verbose ? 'verbose' : 'info',
122
- tag: 'PARALLEL ENCODING',
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
- : (_r = options.imageFormat) !== null && _r !== void 0 ? _r : 'jpeg';
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(downloadMap.preEncode, 'pre-encode.' + (0, get_extension_from_codec_1.getFileExtensionFromCodec)(codec, audioCodec !== null && audioCodec !== void 0 ? audioCodec : null))
122
+ ? node_path_1.default.join(workingDir, 'pre-encode.' + (0, get_extension_from_codec_1.getFileExtensionFromCodec)(codec, audioCodec))
132
123
  : null;
133
- const outputDir = parallelEncoding
134
- ? null
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: scale !== null && scale !== void 0 ? scale : 1,
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 !== null && frameRange !== void 0 ? frameRange : null);
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 / (everyNthFrame !== null && everyNthFrame !== void 0 ? everyNthFrame : 1);
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 * (scale !== null && scale !== void 0 ? scale : 1),
172
- height: composition.height * (scale !== null && scale !== void 0 ? scale : 1),
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: (_a = options.verbose) !== null && _a !== void 0 ? _a : false,
170
+ verbose,
184
171
  imageFormat,
185
172
  signal: cancelPrestitcher.cancelSignal,
186
173
  ffmpegOverride: ffmpegOverride !== null && ffmpegOverride !== void 0 ? ffmpegOverride : (({ args }) => args),
187
- videoBitrate: videoBitrate !== null && videoBitrate !== void 0 ? videoBitrate : null,
188
- indent: (_c = (_b = options.internal) === null || _b === void 0 ? void 0 : _b.indent) !== null && _c !== void 0 ? _c : false,
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
- const happyPath = Promise.resolve(createPrestitcherIfNecessary())
233
- .then(() => {
234
- var _a, _b, _c;
235
- const renderFramesProc = (0, render_frames_1.renderFrames)({
236
- composition,
237
- onFrameUpdate: (frame, frameIndex, timeToRenderInMilliseconds) => {
238
- renderedFrames = frame;
239
- callUpdate();
240
- recordFrameTime(frameIndex, timeToRenderInMilliseconds);
241
- },
242
- concurrency: options.concurrency,
243
- outputDir,
244
- onStart: (data) => {
245
- renderedFrames = 0;
246
- callUpdate();
247
- onStart === null || onStart === void 0 ? void 0 : onStart(data);
248
- },
249
- inputProps: inputProps !== null && inputProps !== void 0 ? inputProps : {},
250
- envVariables,
251
- imageFormat,
252
- jpegQuality,
253
- frameRange: frameRange !== null && frameRange !== void 0 ? frameRange : null,
254
- puppeteerInstance,
255
- everyNthFrame,
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
- force: overwrite !== null && overwrite !== void 0 ? overwrite : overwrite_1.DEFAULT_OVERWRITE,
310
- pixelFormat,
311
- codec,
312
- proResProfile,
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
- numberOfGifLoops,
322
- verbose: options.verbose,
323
- dir: outputDir !== null && outputDir !== void 0 ? outputDir : undefined,
324
- cancelSignal: cancelStitcher.cancelSignal,
275
+ timeoutInMilliseconds,
276
+ chromiumOptions,
277
+ scale,
278
+ browserExecutable,
279
+ port,
280
+ cancelSignal: cancelRenderFrames.cancelSignal,
325
281
  muted: disableAudio,
326
- enforceAudioTrack,
327
- ffmpegOverride,
328
- audioBitrate,
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
- throw err;
368
- })
369
- .finally(() => {
370
- var _a;
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 download map if it was not passed in
376
- if (!((_a = options.internal) === null || _a === void 0 ? void 0 : _a.downloadMap)) {
377
- (0, download_map_1.cleanDownloadMap)(downloadMap);
378
- }
379
- // Clean temporary image frames when rendering ends or fails
380
- if (outputDir && node_fs_1.default.existsSync(outputDir)) {
381
- (0, delete_directory_1.deleteDirectory)(outputDir);
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;
@@ -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
- declare type InnerStillOptions = {
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 Only for Remotion internal usage
35
- */
36
- downloadMap?: DownloadMap;
37
- /**
38
- * @deprecated Only for Remotion internal usage
57
+ * @deprecated Renamed to `jpegQuality`
39
58
  */
40
- indent?: boolean;
41
- verbose?: boolean;
59
+ quality?: never;
42
60
  };
43
- declare type RenderStillReturnValue = {
61
+ type RenderStillReturnValue = {
44
62
  buffer: Buffer | null;
45
63
  };
46
- export declare type RenderStillOptions = InnerStillOptions & {
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