@remotion/renderer 3.3.26 → 3.3.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.
@@ -244,7 +244,7 @@ _Page_client = new WeakMap(), _Page_target = new WeakMap(), _Page_timeoutSetting
244
244
  expression = (0, util_1.pageBindingDeliverErrorValueString)(name, seq, _error);
245
245
  }
246
246
  }
247
- __classPrivateFieldGet(this, _Page_client, "f").send('Runtime.evaluate', {
247
+ await __classPrivateFieldGet(this, _Page_client, "f").send('Runtime.evaluate', {
248
248
  expression,
249
249
  contextId: event.executionContextId,
250
250
  });
@@ -31,11 +31,9 @@ const startCompositor = () => {
31
31
  const _stderrChunks = [];
32
32
  const stdoutChunks = [];
33
33
  child.stderr.on('data', (d) => {
34
- console.log(d.toString('utf-8'));
35
34
  _stderrChunks.push(d);
36
35
  });
37
36
  child.stdout.on('data', (d) => {
38
- console.log(d.toString('utf-8'));
39
37
  stdoutChunks.push(d);
40
38
  });
41
39
  let nonce = 0;
@@ -1,5 +1,8 @@
1
1
  import type { DownloadMap } from './assets/download-map';
2
2
  export declare const createFfmpegComplexFilter: (filters: number, downloadMap: DownloadMap) => Promise<{
3
- complexFilterFlag: [string, string] | null;
3
+ complexFilterFlag: [
4
+ string,
5
+ string
6
+ ] | null;
4
7
  cleanup: () => void;
5
8
  }>;
@@ -1 +1,4 @@
1
- export declare const determineResizeParams: (needsResize: [number, number] | null) => string[];
1
+ export declare const determineResizeParams: (needsResize: [
2
+ number,
3
+ number
4
+ ] | null) => string[];
@@ -0,0 +1,2 @@
1
+ import type { SpecialVCodecForTransparency } from './assets/download-map';
2
+ export declare const determineVcodecFfmpegFlags: (vcodecFlag: SpecialVCodecForTransparency) => string[];
@@ -0,0 +1,13 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.determineVcodecFfmpegFlags = void 0;
4
+ const truthy_1 = require("./truthy");
5
+ const determineVcodecFfmpegFlags = (vcodecFlag) => {
6
+ return [
7
+ vcodecFlag === 'vp9' ? '-vcodec' : null,
8
+ vcodecFlag === 'vp9' ? 'libvpx-vp9' : null,
9
+ vcodecFlag === 'vp8' ? '-vcodec' : null,
10
+ vcodecFlag === 'vp8' ? 'libvpx' : null,
11
+ ].filter(truthy_1.truthy);
12
+ };
13
+ exports.determineVcodecFfmpegFlags = determineVcodecFfmpegFlags;
@@ -7,7 +7,7 @@ exports.extractFrameFromVideo = exports.getLastFrameOfVideo = void 0;
7
7
  const execa_1 = __importDefault(require("execa"));
8
8
  const get_video_stream_duration_1 = require("./assets/get-video-stream-duration");
9
9
  const determine_resize_params_1 = require("./determine-resize-params");
10
- const determine_vcodec_ffmepg_flags_1 = require("./determine-vcodec-ffmepg-flags");
10
+ const determine_vcodec_ffmpeg_flags_1 = require("./determine-vcodec-ffmpeg-flags");
11
11
  const ensure_presentation_timestamp_1 = require("./ensure-presentation-timestamp");
12
12
  const ffmpeg_flags_1 = require("./ffmpeg-flags");
13
13
  const frame_to_ffmpeg_timestamp_1 = require("./frame-to-ffmpeg-timestamp");
@@ -124,7 +124,7 @@ const extractFrameFromVideoFn = async ({ time, ffmpegExecutable, ffprobeExecutab
124
124
  const { stdout, stderr } = (0, execa_1.default)(await (0, ffmpeg_flags_1.getExecutableBinary)(ffmpegExecutable, remotionRoot, 'ffmpeg'), [
125
125
  '-ss',
126
126
  ffmpegTimestamp,
127
- ...(0, determine_vcodec_ffmepg_flags_1.determineVcodecFfmepgFlags)(specialVcodec),
127
+ ...(0, determine_vcodec_ffmpeg_flags_1.determineVcodecFfmpegFlags)(specialVcodec),
128
128
  '-i',
129
129
  src,
130
130
  '-frames:v',
@@ -0,0 +1,2 @@
1
+ import type { GetCompositionsConfig } from './get-compositions';
2
+ export declare const getCompositionsFromBundle: (bundle: string, options: GetCompositionsConfig) => import("remotion/src").TCompMetadata[];
@@ -0,0 +1,55 @@
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.getCompositionsFromBundle = void 0;
7
+ const fs_1 = __importDefault(require("fs"));
8
+ const path_1 = __importDefault(require("path"));
9
+ const remotion_1 = require("remotion");
10
+ const vm_1 = __importDefault(require("vm"));
11
+ const is_serve_url_1 = require("./is-serve-url");
12
+ const getCompositionsFromBundle = (bundle, options) => {
13
+ const bundleFile = path_1.default.join(bundle, 'bundle.js');
14
+ if ((0, is_serve_url_1.isServeUrl)(bundle)) {
15
+ throw new Error('Can only use getCompositionFromBundle from a local file');
16
+ }
17
+ const content = fs_1.default.readFileSync(bundleFile, 'utf-8');
18
+ // @ts-éxpect-error
19
+ process.env.REMOTION_SERVER_RENDERING = 'true';
20
+ const context = {
21
+ window: {
22
+ remotion_envVariables: options.envVariables,
23
+ },
24
+ clearTimeout: () => {
25
+ console.trace('clearTimeout() called inside a server-side bundle. This is not supported.');
26
+ },
27
+ setTimeout: () => {
28
+ console.trace('setTimeout() called inside a server-side bundle. This is not supported.');
29
+ },
30
+ process: {
31
+ env: {
32
+ REMOTION_SERVER_RENDERING: true,
33
+ },
34
+ },
35
+ require,
36
+ Buffer,
37
+ console,
38
+ };
39
+ const vmContext = vm_1.default.createContext(context);
40
+ // TODO: Set props and env
41
+ const code = content;
42
+ vm_1.default.runInContext(code, vmContext, {
43
+ filename: bundleFile,
44
+ breakOnSigint: true,
45
+ });
46
+ const theRoot = remotion_1.Internals.getRoot();
47
+ if (!theRoot) {
48
+ throw new Error('Did not call getRoot() in the bundle. Delaying the calling of getRoot() is not supported in server-side-rendering.');
49
+ }
50
+ const Comp = theRoot;
51
+ console.log({ Comp1: Comp });
52
+ const comps = (0, remotion_1.getCompositionsFromMarkup)(Comp);
53
+ return comps;
54
+ };
55
+ exports.getCompositionsFromBundle = getCompositionsFromBundle;
@@ -1,3 +1,3 @@
1
1
  import type { ComponentType } from 'react';
2
- import type { TCompMetadata } from 'remotion/src';
3
- export declare const getCompositionsOnServer: (Comp: ComponentType) => TCompMetadata[];
2
+ import type { TCompMetadata } from 'remotion';
3
+ export declare const getCompositionsFromMarkup: (Comp: ComponentType) => TCompMetadata[];
@@ -1,11 +1,12 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.getCompositionsOnServer = void 0;
3
+ exports.getCompositionsFromMarkup = void 0;
4
4
  const jsx_runtime_1 = require("react/jsx-runtime");
5
5
  const server_1 = require("react-dom/server");
6
- const getCompositionsOnServer = (Comp) => {
6
+ const getCompositionsFromMarkup = (Comp) => {
7
7
  process.env.REMOTION_SERVER_RENDERING = 'true';
8
8
  const str = (0, server_1.renderToString)((0, jsx_runtime_1.jsx)(Comp, {}));
9
+ console.log({ str }, (0, jsx_runtime_1.jsx)(Comp, {}));
9
10
  const matches = str.matchAll(/<div>(.*?)<\/div>/g);
10
11
  const metadata = [];
11
12
  for (const match of matches) {
@@ -14,4 +15,4 @@ const getCompositionsOnServer = (Comp) => {
14
15
  }
15
16
  return metadata;
16
17
  };
17
- exports.getCompositionsOnServer = getCompositionsOnServer;
18
+ exports.getCompositionsFromMarkup = getCompositionsFromMarkup;
@@ -1,11 +1,15 @@
1
1
  "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
2
5
  Object.defineProperty(exports, "__esModule", { value: true });
3
6
  exports.getExtensionOfFilename = void 0;
7
+ const path_1 = __importDefault(require("path"));
4
8
  const getExtensionOfFilename = (filename) => {
5
9
  if (filename === null) {
6
10
  return null;
7
11
  }
8
- const filenameArr = filename.split('.');
12
+ const filenameArr = path_1.default.normalize(filename).split('.');
9
13
  const hasExtension = filenameArr.length >= 2;
10
14
  const filenameArrLength = filenameArr.length;
11
15
  const extension = hasExtension ? filenameArr[filenameArrLength - 1] : null;
@@ -8,7 +8,7 @@ exports.getFrameOfVideoSlow = void 0;
8
8
  // if the video is corrupted
9
9
  const execa_1 = __importDefault(require("execa"));
10
10
  const determine_resize_params_1 = require("./determine-resize-params");
11
- const determine_vcodec_ffmepg_flags_1 = require("./determine-vcodec-ffmepg-flags");
11
+ const determine_vcodec_ffmpeg_flags_1 = require("./determine-vcodec-ffmpeg-flags");
12
12
  const ffmpeg_flags_1 = require("./ffmpeg-flags");
13
13
  const truthy_1 = require("./truthy");
14
14
  const getFrameOfVideoSlow = async ({ src, duration, ffmpegExecutable, imageFormat, specialVCodecForTransparency, needsResize, offset, fps, remotionRoot, }) => {
@@ -17,7 +17,7 @@ const getFrameOfVideoSlow = async ({ src, duration, ffmpegExecutable, imageForma
17
17
  const command = [
18
18
  '-itsoffset',
19
19
  actualOffset,
20
- ...(0, determine_vcodec_ffmepg_flags_1.determineVcodecFfmepgFlags)(specialVCodecForTransparency),
20
+ ...(0, determine_vcodec_ffmpeg_flags_1.determineVcodecFfmpegFlags)(specialVCodecForTransparency),
21
21
  '-i',
22
22
  src,
23
23
  '-frames:v',
package/dist/index.d.ts CHANGED
@@ -1,4 +1,3 @@
1
- /// <reference types="node" />
2
1
  import execa from 'execa';
3
2
  import { SymbolicateableError } from './error-handling/symbolicateable-error';
4
3
  import { mimeContentType, mimeLookup } from './mime-types';
@@ -115,8 +114,8 @@ export declare const RenderInternals: {
115
114
  validPixelFormats: readonly ["yuv420p", "yuva420p", "yuv422p", "yuv444p", "yuv420p10le", "yuv422p10le", "yuv444p10le", "yuva444p10le"];
116
115
  DEFAULT_BROWSER: import("./browser").Browser;
117
116
  validateFrameRange: (frameRange: import("./frame-range").FrameRange | null) => void;
118
- DEFAULT_OPENGL_RENDERER: "swangle" | "angle" | "egl" | "swiftshader" | null;
119
- validateOpenGlRenderer: (option: "swangle" | "angle" | "egl" | "swiftshader" | null) => "swangle" | "angle" | "egl" | "swiftshader" | null;
117
+ DEFAULT_OPENGL_RENDERER: "angle" | "swangle" | "egl" | "swiftshader" | null;
118
+ validateOpenGlRenderer: (option: "angle" | "swangle" | "egl" | "swiftshader" | null) => "angle" | "swangle" | "egl" | "swiftshader" | null;
120
119
  validImageFormats: readonly ["png", "jpeg", "none"];
121
120
  validCodecs: readonly ["h264", "h265", "vp8", "vp9", "mp3", "aac", "wav", "prores", "h264-mkv", "gif"];
122
121
  DEFAULT_PIXEL_FORMAT: "yuv420p" | "yuva420p" | "yuv422p" | "yuv444p" | "yuv420p10le" | "yuv422p10le" | "yuv444p10le" | "yuva444p10le";
@@ -126,7 +125,7 @@ export declare const RenderInternals: {
126
125
  DEFAULT_CODEC: "h264" | "h265" | "vp8" | "vp9" | "mp3" | "aac" | "wav" | "prores" | "h264-mkv" | "gif";
127
126
  isAudioCodec: (codec: "h264" | "h265" | "vp8" | "vp9" | "mp3" | "aac" | "wav" | "prores" | "h264-mkv" | "gif" | undefined) => boolean;
128
127
  logLevels: readonly ["verbose", "info", "warn", "error"];
129
- isEqualOrBelowLogLevel: (currentLevel: "verbose" | "error" | "info" | "warn", level: "verbose" | "error" | "info" | "warn") => boolean;
128
+ isEqualOrBelowLogLevel: (currentLevel: "error" | "verbose" | "info" | "warn", level: "error" | "verbose" | "info" | "warn") => boolean;
130
129
  isValidLogLevel: (level: string) => boolean;
131
130
  perf: typeof perf;
132
131
  makeDownloadMap: () => import("./assets/download-map").DownloadMap;
@@ -4,4 +4,11 @@ export declare const makeCancelSignal: () => {
4
4
  cancelSignal: CancelSignal;
5
5
  cancel: () => void;
6
6
  };
7
+ export declare const cancelErrorMessages: {
8
+ renderMedia: string;
9
+ renderFrames: string;
10
+ renderStill: string;
11
+ stitchFramesToVideo: string;
12
+ };
13
+ export declare const isUserCancelledRender: (err: unknown) => boolean;
7
14
  export {};
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.makeCancelSignal = void 0;
3
+ exports.isUserCancelledRender = exports.cancelErrorMessages = exports.makeCancelSignal = void 0;
4
4
  const makeCancelSignal = () => {
5
5
  const callbacks = [];
6
6
  let cancelled = false;
@@ -23,3 +23,22 @@ const makeCancelSignal = () => {
23
23
  };
24
24
  };
25
25
  exports.makeCancelSignal = makeCancelSignal;
26
+ exports.cancelErrorMessages = {
27
+ renderMedia: 'renderMedia() got cancelled',
28
+ renderFrames: 'renderFrames() got cancelled',
29
+ renderStill: 'renderStill() got cancelled',
30
+ stitchFramesToVideo: 'stitchFramesToVideo() got cancelled',
31
+ };
32
+ const isUserCancelledRender = (err) => {
33
+ if (typeof err === 'object' &&
34
+ err !== null &&
35
+ 'message' in err &&
36
+ typeof err.message === 'string') {
37
+ return (err.message.includes(exports.cancelErrorMessages.renderMedia) ||
38
+ err.message.includes(exports.cancelErrorMessages.renderFrames) ||
39
+ err.message.includes(exports.cancelErrorMessages.renderStill) ||
40
+ err.message.includes(exports.cancelErrorMessages.stitchFramesToVideo));
41
+ }
42
+ return false;
43
+ };
44
+ exports.isUserCancelledRender = isUserCancelledRender;
@@ -9,4 +9,4 @@ export declare const screenshot: (options: {
9
9
  width: number;
10
10
  height: number;
11
11
  clipRegion: ClipRegion | null;
12
- }) => Promise<Buffer | string | void>;
12
+ }) => Promise<Buffer | string>;
@@ -21,6 +21,7 @@ const get_frame_padded_index_1 = require("./get-frame-padded-index");
21
21
  const get_frame_to_render_1 = require("./get-frame-to-render");
22
22
  const image_format_1 = require("./image-format");
23
23
  const legacy_webpack_config_1 = require("./legacy-webpack-config");
24
+ const make_cancel_signal_1 = require("./make-cancel-signal");
24
25
  const open_browser_1 = require("./open-browser");
25
26
  const perf_1 = require("./perf");
26
27
  const pool_1 = require("./pool");
@@ -241,6 +242,9 @@ const innerRenderFrames = ({ onFrameUpdate, outputDir, onStart, inputProps, qual
241
242
  !((_b = err === null || err === void 0 ? void 0 : err.message) === null || _b === void 0 ? void 0 : _b.includes('Session closed'))) {
242
243
  throw err;
243
244
  }
245
+ if ((0, make_cancel_signal_1.isUserCancelledRender)(err)) {
246
+ throw err;
247
+ }
244
248
  if (retriesLeft === 0) {
245
249
  console.warn(err, `The browser crashed ${attempt} times while rendering frame ${frame}. Not retrying anymore. Learn more about this error under https://www.remotion.dev/docs/target-closed`);
246
250
  throw err;
@@ -320,7 +324,7 @@ const renderFrames = (options) => {
320
324
  new Promise((_, rej) => {
321
325
  var _a;
322
326
  (_a = options.cancelSignal) === null || _a === void 0 ? void 0 : _a.call(options, () => {
323
- rej(new Error('renderFrames() got cancelled'));
327
+ rej(new Error(make_cancel_signal_1.cancelErrorMessages.renderFrames));
324
328
  });
325
329
  }),
326
330
  Promise.all([
@@ -362,7 +362,7 @@ const renderMedia = ({ proResProfile, crf, composition, ffmpegExecutable, ffprob
362
362
  happyPath,
363
363
  new Promise((_resolve, reject) => {
364
364
  cancelSignal === null || cancelSignal === void 0 ? void 0 : cancelSignal(() => {
365
- reject(new Error('renderMedia() got cancelled'));
365
+ reject(new Error(make_cancel_signal_1.cancelErrorMessages.renderMedia));
366
366
  });
367
367
  }),
368
368
  ]);
@@ -38,6 +38,7 @@ const handle_javascript_exception_1 = require("./error-handling/handle-javascrip
38
38
  const find_closest_package_json_1 = require("./find-closest-package-json");
39
39
  const image_format_1 = require("./image-format");
40
40
  const legacy_webpack_config_1 = require("./legacy-webpack-config");
41
+ const make_cancel_signal_1 = require("./make-cancel-signal");
41
42
  const open_browser_1 = require("./open-browser");
42
43
  const prepare_server_1 = require("./prepare-server");
43
44
  const puppeteer_evaluate_1 = require("./puppeteer-evaluate");
@@ -215,7 +216,7 @@ const renderStill = (options) => {
215
216
  new Promise((_resolve, reject) => {
216
217
  var _a;
217
218
  (_a = options.cancelSignal) === null || _a === void 0 ? void 0 : _a.call(options, () => {
218
- reject(new Error('renderStill() got cancelled'));
219
+ reject(new Error(make_cancel_signal_1.cancelErrorMessages.renderStill));
219
220
  });
220
221
  }),
221
222
  ]);
@@ -0,0 +1,73 @@
1
+ import type { SmallTCompMetadata, TAsset } from 'remotion/src';
2
+ import type { RenderMediaOnDownload } from './assets/download-and-map-assets-to-file';
3
+ import type { DownloadMap } from './assets/download-map';
4
+ import type { BrowserExecutable } from './browser-executable';
5
+ import type { BrowserLog } from './browser-log';
6
+ import type { Page } from './browser/BrowserPage';
7
+ import type { CountType } from './get-frame-padded-index';
8
+ import type { ServeUrl } from './legacy-webpack-config';
9
+ import type { ChromiumOptions } from './open-browser';
10
+ import type { Pool } from './pool';
11
+ import type { BrowserReplacer } from './replace-browser';
12
+ export declare const renderWebFrameAndRetryTargetClose: ({ frame, index, retriesLeft, attempt, actualConcurrency, browserReplacer, poolPromise, composition, downloadMap, imageFormat, onFrameBuffer, onFrameUpdate, outputDir, stopState, assets, countType, scale, quality, framesToRender, lastFrame, framesRendered, browserExecutable, chromiumOptions, dumpBrowserLogs, pagesArray, onBrowserLog, inputProps, envVariables, muted, proxyPort, realFrameRange, serveUrl, timeoutInMilliseconds, onDownload, onError, }: {
13
+ frame: number;
14
+ index: number;
15
+ retriesLeft: number;
16
+ attempt: number;
17
+ actualConcurrency: number;
18
+ browserReplacer: BrowserReplacer | null;
19
+ poolPromise: Promise<Pool<Page>>;
20
+ composition: SmallTCompMetadata;
21
+ downloadMap: DownloadMap;
22
+ imageFormat: 'png' | 'jpeg' | 'none';
23
+ onFrameBuffer: ((buffer: Buffer, frame: number) => void) | undefined;
24
+ onFrameUpdate: (framesRendered: number, frameIndex: number, timeToRenderInMilliseconds: number) => void;
25
+ outputDir: string | null;
26
+ stopState: {
27
+ isStopped: boolean;
28
+ };
29
+ assets: TAsset[][];
30
+ countType: CountType;
31
+ scale: number;
32
+ quality: number | undefined;
33
+ framesToRender: number[];
34
+ lastFrame: number;
35
+ framesRendered: {
36
+ frames: number;
37
+ };
38
+ browserExecutable?: BrowserExecutable | undefined;
39
+ chromiumOptions?: ChromiumOptions | undefined;
40
+ dumpBrowserLogs?: boolean | undefined;
41
+ pagesArray: Page[];
42
+ onBrowserLog?: ((log: BrowserLog) => void) | undefined;
43
+ inputProps: unknown;
44
+ envVariables?: Record<string, string> | undefined;
45
+ muted: boolean;
46
+ proxyPort: number;
47
+ realFrameRange: [number, number];
48
+ serveUrl: ServeUrl;
49
+ timeoutInMilliseconds: number;
50
+ onDownload: RenderMediaOnDownload;
51
+ onError: (err: Error) => void;
52
+ }) => Promise<void>;
53
+ export declare const makePage: ({ browserReplacer, pagesArray, composition, scale, onBrowserLog, inputProps, envVariables, serveUrl, realFrameRange, timeoutInMilliseconds, proxyPort, imageFormat, muted, }: {
54
+ browserReplacer: BrowserReplacer;
55
+ pagesArray: Page[];
56
+ composition: SmallTCompMetadata;
57
+ scale?: number | undefined;
58
+ onBrowserLog?: ((log: BrowserLog) => void) | undefined;
59
+ inputProps: unknown;
60
+ envVariables?: Record<string, string> | undefined;
61
+ serveUrl: ServeUrl;
62
+ realFrameRange: [number, number];
63
+ timeoutInMilliseconds: number | undefined;
64
+ proxyPort: number;
65
+ imageFormat: 'png' | 'jpeg' | 'none';
66
+ muted: boolean;
67
+ }) => Promise<Page>;
68
+ export declare const makeBrowser: ({ dumpBrowserLogs, browserExecutable, chromiumOptions, scale, }: {
69
+ dumpBrowserLogs?: boolean | undefined;
70
+ browserExecutable?: BrowserExecutable | undefined;
71
+ chromiumOptions?: ChromiumOptions | undefined;
72
+ scale?: number | undefined;
73
+ }) => Promise<import("./browser/Browser").Browser>;
@@ -0,0 +1,298 @@
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.makeBrowser = exports.makePage = exports.renderWebFrameAndRetryTargetClose = void 0;
7
+ const path_1 = __importDefault(require("path"));
8
+ const download_and_map_assets_to_file_1 = require("./assets/download-and-map-assets-to-file");
9
+ const browser_1 = require("./browser");
10
+ const compress_assets_1 = require("./compress-assets");
11
+ const handle_javascript_exception_1 = require("./error-handling/handle-javascript-exception");
12
+ const get_frame_padded_index_1 = require("./get-frame-padded-index");
13
+ const make_cancel_signal_1 = require("./make-cancel-signal");
14
+ const open_browser_1 = require("./open-browser");
15
+ const perf_1 = require("./perf");
16
+ const puppeteer_evaluate_1 = require("./puppeteer-evaluate");
17
+ const seek_to_frame_1 = require("./seek-to-frame");
18
+ const set_props_and_env_1 = require("./set-props-and-env");
19
+ const take_frame_and_compose_1 = require("./take-frame-and-compose");
20
+ const truthy_1 = require("./truthy");
21
+ const renderFrameWithOptionToReject = async ({ frame, index, reject, width, height, poolPromise, stopState, outputDir, onFrameBuffer, imageFormat, downloadMap, onFrameUpdate, scale, assets, countType, quality, framesToRender, lastFrame, framesRendered, onDownload, onError, }) => {
22
+ const pool = await poolPromise;
23
+ const freePage = await pool.acquire();
24
+ if (stopState.isStopped) {
25
+ return reject(new Error('Render was stopped'));
26
+ }
27
+ const startTime = performance.now();
28
+ const errorCallbackOnFrame = (err) => {
29
+ reject(err);
30
+ };
31
+ const cleanupPageError = (0, handle_javascript_exception_1.handleJavascriptException)({
32
+ page: freePage,
33
+ onError: errorCallbackOnFrame,
34
+ frame,
35
+ });
36
+ freePage.on('error', errorCallbackOnFrame);
37
+ await (0, seek_to_frame_1.seekToFrame)({ frame, page: freePage });
38
+ if (!outputDir && !onFrameBuffer && imageFormat !== 'none') {
39
+ throw new Error('Called renderFrames() without specifying either `outputDir` or `onFrameBuffer`');
40
+ }
41
+ if (outputDir && onFrameBuffer && imageFormat !== 'none') {
42
+ throw new Error('Pass either `outputDir` or `onFrameBuffer` to renderFrames(), not both.');
43
+ }
44
+ const id = (0, perf_1.startPerfMeasure)('save');
45
+ const frameDir = outputDir !== null && outputDir !== void 0 ? outputDir : downloadMap.compositingDir;
46
+ const { buffer, collectedAssets } = await (0, take_frame_and_compose_1.takeFrameAndCompose)({
47
+ frame,
48
+ freePage,
49
+ height,
50
+ imageFormat,
51
+ output: path_1.default.join(frameDir, (0, get_frame_padded_index_1.getFrameOutputFileName)({
52
+ frame,
53
+ imageFormat,
54
+ index,
55
+ countType,
56
+ lastFrame,
57
+ totalFrames: framesToRender.length,
58
+ })),
59
+ quality,
60
+ width,
61
+ scale,
62
+ downloadMap,
63
+ wantsBuffer: Boolean(onFrameBuffer),
64
+ });
65
+ if (onFrameBuffer) {
66
+ if (!buffer) {
67
+ throw new Error('unexpected null buffer');
68
+ }
69
+ onFrameBuffer(buffer, frame);
70
+ }
71
+ (0, perf_1.stopPerfMeasure)(id);
72
+ const compressedAssets = collectedAssets.map((asset) => (0, compress_assets_1.compressAsset)(assets.filter(truthy_1.truthy).flat(1), asset));
73
+ assets[index] = compressedAssets;
74
+ compressedAssets.forEach((asset) => {
75
+ (0, download_and_map_assets_to_file_1.downloadAndMapAssetsToFileUrl)({
76
+ asset,
77
+ onDownload,
78
+ downloadMap,
79
+ }).catch((err) => {
80
+ onError(new Error(`Error while downloading asset: ${err.stack}`));
81
+ });
82
+ });
83
+ framesRendered.frames++;
84
+ onFrameUpdate(framesRendered.frames, frame, performance.now() - startTime);
85
+ cleanupPageError();
86
+ freePage.off('error', errorCallbackOnFrame);
87
+ pool.release(freePage);
88
+ };
89
+ const renderWebFrame = ({ frame, index, downloadMap, imageFormat, onFrameBuffer, onFrameUpdate, outputDir, poolPromise, stopState, composition, assets, countType, scale, quality, lastFrame, framesToRender, framesRendered, onDownload, onError, }) => {
90
+ return new Promise((resolve, reject) => {
91
+ renderFrameWithOptionToReject({
92
+ frame,
93
+ index,
94
+ reject,
95
+ width: composition.width,
96
+ height: composition.height,
97
+ downloadMap,
98
+ imageFormat,
99
+ onFrameBuffer,
100
+ onFrameUpdate,
101
+ outputDir,
102
+ poolPromise,
103
+ stopState,
104
+ assets,
105
+ countType,
106
+ scale,
107
+ quality,
108
+ framesToRender,
109
+ lastFrame,
110
+ framesRendered,
111
+ onDownload,
112
+ onError,
113
+ })
114
+ .then(() => {
115
+ resolve();
116
+ })
117
+ .catch((err) => {
118
+ reject(err);
119
+ });
120
+ });
121
+ };
122
+ const renderWebFrameAndRetryTargetClose = async ({ frame, index, retriesLeft, attempt, actualConcurrency, browserReplacer, poolPromise, composition, downloadMap, imageFormat, onFrameBuffer, onFrameUpdate, outputDir, stopState, assets, countType, scale, quality, framesToRender, lastFrame, framesRendered, browserExecutable, chromiumOptions, dumpBrowserLogs, pagesArray, onBrowserLog, inputProps, envVariables, muted, proxyPort, realFrameRange, serveUrl, timeoutInMilliseconds, onDownload, onError, }) => {
123
+ var _a, _b;
124
+ try {
125
+ await renderWebFrame({
126
+ frame,
127
+ index,
128
+ poolPromise,
129
+ composition,
130
+ downloadMap,
131
+ imageFormat,
132
+ onFrameBuffer,
133
+ onFrameUpdate,
134
+ outputDir,
135
+ stopState,
136
+ assets,
137
+ countType,
138
+ scale,
139
+ quality,
140
+ framesToRender,
141
+ lastFrame,
142
+ framesRendered,
143
+ onDownload,
144
+ onError,
145
+ });
146
+ }
147
+ catch (err) {
148
+ if (!((_a = err === null || err === void 0 ? void 0 : err.message) === null || _a === void 0 ? void 0 : _a.includes('Target closed')) &&
149
+ !((_b = err === null || err === void 0 ? void 0 : err.message) === null || _b === void 0 ? void 0 : _b.includes('Session closed'))) {
150
+ throw err;
151
+ }
152
+ if ((0, make_cancel_signal_1.isUserCancelledRender)(err)) {
153
+ throw err;
154
+ }
155
+ if (retriesLeft === 0) {
156
+ console.warn(err, `The browser crashed ${attempt} times while rendering frame ${frame}. Not retrying anymore. Learn more about this error under https://www.remotion.dev/docs/target-closed`);
157
+ throw err;
158
+ }
159
+ console.warn(`The browser crashed while rendering frame ${frame}, retrying ${retriesLeft} more times. Learn more about this error under https://www.remotion.dev/docs/target-closed`);
160
+ if (!browserReplacer) {
161
+ throw new Error('Did not have browser replacer for web frame');
162
+ }
163
+ await browserReplacer.replaceBrowser(() => (0, exports.makeBrowser)({
164
+ browserExecutable,
165
+ chromiumOptions,
166
+ dumpBrowserLogs,
167
+ scale,
168
+ }), async () => {
169
+ const pages = new Array(actualConcurrency).fill(true).map(() => (0, exports.makePage)({
170
+ browserReplacer,
171
+ composition,
172
+ pagesArray,
173
+ onBrowserLog,
174
+ scale,
175
+ inputProps,
176
+ envVariables,
177
+ imageFormat,
178
+ muted,
179
+ proxyPort,
180
+ realFrameRange,
181
+ serveUrl,
182
+ timeoutInMilliseconds,
183
+ }));
184
+ const puppeteerPages = await Promise.all(pages);
185
+ const pool = await poolPromise;
186
+ for (const newPage of puppeteerPages) {
187
+ pool.release(newPage);
188
+ }
189
+ });
190
+ await (0, exports.renderWebFrameAndRetryTargetClose)({
191
+ frame,
192
+ index,
193
+ retriesLeft: retriesLeft - 1,
194
+ attempt: attempt + 1,
195
+ actualConcurrency,
196
+ browserReplacer,
197
+ composition,
198
+ downloadMap,
199
+ imageFormat,
200
+ onFrameBuffer,
201
+ onFrameUpdate,
202
+ outputDir,
203
+ poolPromise,
204
+ stopState,
205
+ assets,
206
+ countType,
207
+ scale,
208
+ quality,
209
+ framesToRender,
210
+ lastFrame,
211
+ framesRendered,
212
+ inputProps,
213
+ pagesArray,
214
+ browserExecutable,
215
+ chromiumOptions,
216
+ dumpBrowserLogs,
217
+ envVariables,
218
+ muted,
219
+ onBrowserLog,
220
+ proxyPort,
221
+ realFrameRange,
222
+ serveUrl,
223
+ timeoutInMilliseconds,
224
+ onDownload,
225
+ onError,
226
+ });
227
+ }
228
+ };
229
+ exports.renderWebFrameAndRetryTargetClose = renderWebFrameAndRetryTargetClose;
230
+ const makePage = async ({ browserReplacer, pagesArray, composition, scale, onBrowserLog, inputProps, envVariables, serveUrl, realFrameRange, timeoutInMilliseconds, proxyPort, imageFormat, muted, }) => {
231
+ if (!browserReplacer) {
232
+ throw new Error('canonot make page without browser replacer');
233
+ }
234
+ const page = await browserReplacer.getBrowser().newPage();
235
+ pagesArray.push(page);
236
+ await page.setViewport({
237
+ width: composition.width,
238
+ height: composition.height,
239
+ deviceScaleFactor: scale !== null && scale !== void 0 ? scale : 1,
240
+ });
241
+ const logCallback = (log) => {
242
+ onBrowserLog === null || onBrowserLog === void 0 ? void 0 : onBrowserLog({
243
+ stackTrace: log.stackTrace(),
244
+ text: log.text,
245
+ type: log.type,
246
+ });
247
+ };
248
+ if (onBrowserLog) {
249
+ page.on('console', logCallback);
250
+ }
251
+ const initialFrame = realFrameRange[0];
252
+ await (0, set_props_and_env_1.setPropsAndEnv)({
253
+ inputProps,
254
+ envVariables,
255
+ page,
256
+ serveUrl,
257
+ initialFrame,
258
+ timeoutInMilliseconds,
259
+ proxyPort,
260
+ retriesRemaining: 2,
261
+ audioEnabled: !muted,
262
+ videoEnabled: imageFormat !== 'none',
263
+ });
264
+ await (0, puppeteer_evaluate_1.puppeteerEvaluateWithCatch)({
265
+ // eslint-disable-next-line max-params
266
+ pageFunction: (id, defaultProps, durationInFrames, fps, height, width) => {
267
+ window.setBundleMode({
268
+ type: 'composition',
269
+ compositionName: id,
270
+ compositionDefaultProps: defaultProps,
271
+ compositionDurationInFrames: durationInFrames,
272
+ compositionFps: fps,
273
+ compositionHeight: height,
274
+ compositionWidth: width,
275
+ });
276
+ },
277
+ args: [
278
+ composition.id,
279
+ composition.defaultProps,
280
+ composition.durationInFrames,
281
+ composition.fps,
282
+ composition.height,
283
+ composition.width,
284
+ ],
285
+ frame: null,
286
+ page,
287
+ });
288
+ page.off('console', logCallback);
289
+ return page;
290
+ };
291
+ exports.makePage = makePage;
292
+ const makeBrowser = ({ dumpBrowserLogs, browserExecutable, chromiumOptions, scale, }) => (0, open_browser_1.openBrowser)(browser_1.DEFAULT_BROWSER, {
293
+ shouldDumpIo: dumpBrowserLogs,
294
+ browserExecutable,
295
+ chromiumOptions,
296
+ forceDeviceScaleFactor: scale !== null && scale !== void 0 ? scale : 1,
297
+ });
298
+ exports.makeBrowser = makeBrowser;
@@ -28,7 +28,7 @@ const screenshotDOMElement = async ({ page, imageFormat, quality, opts, height,
28
28
  if (imageFormat === 'none') {
29
29
  throw new TypeError('Tried to make a screenshot with format "none"');
30
30
  }
31
- return (0, puppeteer_screenshot_1.screenshot)({
31
+ const buf = await (0, puppeteer_screenshot_1.screenshot)({
32
32
  page,
33
33
  omitBackground: imageFormat === 'png',
34
34
  path: path !== null && path !== void 0 ? path : undefined,
@@ -38,5 +38,9 @@ const screenshotDOMElement = async ({ page, imageFormat, quality, opts, height,
38
38
  height,
39
39
  clipRegion,
40
40
  });
41
+ if (typeof buf === 'string') {
42
+ throw new TypeError('Expected a buffer');
43
+ }
44
+ return buf;
41
45
  };
42
46
  exports.screenshotDOMElement = screenshotDOMElement;
@@ -45,6 +45,7 @@ const get_audio_codec_name_1 = require("./get-audio-codec-name");
45
45
  const get_codec_name_1 = require("./get-codec-name");
46
46
  const get_extension_from_codec_1 = require("./get-extension-from-codec");
47
47
  const get_prores_profile_name_1 = require("./get-prores-profile-name");
48
+ const make_cancel_signal_1 = require("./make-cancel-signal");
48
49
  const merge_audio_track_1 = require("./merge-audio-track");
49
50
  const parse_ffmpeg_progress_1 = require("./parse-ffmpeg-progress");
50
51
  const pixel_format_1 = require("./pixel-format");
@@ -98,11 +99,13 @@ const getAssetsData = async ({ assets, onDownload, fps, expectedFrames, verbose,
98
99
  downloadMap,
99
100
  remotionRoot,
100
101
  });
101
- (0, delete_directory_1.deleteDirectory)(downloadMap.audioMixing);
102
102
  onProgress(1);
103
- preprocessed.forEach((p) => {
104
- (0, delete_directory_1.deleteDirectory)(p);
105
- });
103
+ await Promise.all([
104
+ (0, delete_directory_1.deleteDirectory)(downloadMap.audioMixing),
105
+ ...preprocessed.map((p) => {
106
+ return (0, delete_directory_1.deleteDirectory)(p);
107
+ }),
108
+ ]);
106
109
  return outName;
107
110
  };
108
111
  const spawnFfmpeg = async (options, remotionRoot) => {
@@ -344,7 +347,7 @@ const stitchFramesToVideo = async (options) => {
344
347
  new Promise((_resolve, reject) => {
345
348
  var _a;
346
349
  (_a = options.cancelSignal) === null || _a === void 0 ? void 0 : _a.call(options, () => {
347
- reject(new Error('stitchFramesToVideo() got cancelled'));
350
+ reject(new Error(make_cancel_signal_1.cancelErrorMessages.stitchFramesToVideo));
348
351
  });
349
352
  }),
350
353
  ]);
@@ -6,14 +6,14 @@ Object.defineProperty(exports, "__esModule", { value: true });
6
6
  exports.tryToExtractFrameOfVideoFast = void 0;
7
7
  const execa_1 = __importDefault(require("execa"));
8
8
  const determine_resize_params_1 = require("./determine-resize-params");
9
- const determine_vcodec_ffmepg_flags_1 = require("./determine-vcodec-ffmepg-flags");
9
+ const determine_vcodec_ffmpeg_flags_1 = require("./determine-vcodec-ffmpeg-flags");
10
10
  const ffmpeg_flags_1 = require("./ffmpeg-flags");
11
11
  const truthy_1 = require("./truthy");
12
12
  const tryToExtractFrameOfVideoFast = async ({ ffmpegExecutable, remotionRoot, specialVCodecForTransparency, imageFormat, needsResize, src, actualOffset, }) => {
13
13
  const { stdout, stderr } = (0, execa_1.default)(await (0, ffmpeg_flags_1.getExecutableBinary)(ffmpegExecutable, remotionRoot, 'ffmpeg'), [
14
14
  '-ss',
15
15
  actualOffset,
16
- ...(0, determine_vcodec_ffmepg_flags_1.determineVcodecFfmepgFlags)(specialVCodecForTransparency),
16
+ ...(0, determine_vcodec_ffmpeg_flags_1.determineVcodecFfmpegFlags)(specialVCodecForTransparency),
17
17
  '-i',
18
18
  src,
19
19
  '-frames:v',
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@remotion/renderer",
3
- "version": "3.3.26",
3
+ "version": "3.3.28",
4
4
  "description": "Renderer for Remotion",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -24,7 +24,7 @@
24
24
  "dependencies": {
25
25
  "execa": "5.1.1",
26
26
  "extract-zip": "2.0.1",
27
- "remotion": "3.3.26",
27
+ "remotion": "3.3.28",
28
28
  "source-map": "^0.8.0-beta.0",
29
29
  "ws": "8.7.0"
30
30
  },
@@ -49,13 +49,13 @@
49
49
  "vitest": "0.24.3"
50
50
  },
51
51
  "optionalDependencies": {
52
- "@remotion/compositor-darwin-arm64": "3.3.26",
53
- "@remotion/compositor-darwin-x64": "3.3.26",
54
- "@remotion/compositor-linux-arm64-gnu": "3.3.26",
55
- "@remotion/compositor-linux-arm64-musl": "3.3.26",
56
- "@remotion/compositor-linux-x64-gnu": "3.3.26",
57
- "@remotion/compositor-linux-x64-musl": "3.3.26",
58
- "@remotion/compositor-win32-x64-msvc": "3.3.26"
52
+ "@remotion/compositor-darwin-arm64": "3.3.28",
53
+ "@remotion/compositor-darwin-x64": "3.3.28",
54
+ "@remotion/compositor-linux-arm64-gnu": "3.3.28",
55
+ "@remotion/compositor-linux-arm64-musl": "3.3.28",
56
+ "@remotion/compositor-linux-x64-gnu": "3.3.28",
57
+ "@remotion/compositor-linux-x64-musl": "3.3.28",
58
+ "@remotion/compositor-win32-x64-msvc": "3.3.28"
59
59
  },
60
60
  "keywords": [
61
61
  "remotion",
@@ -67,5 +67,5 @@
67
67
  "publishConfig": {
68
68
  "access": "public"
69
69
  },
70
- "gitHead": "8efe8771f7c2b1d22bd50e8c81cc37ae054dfae9"
70
+ "gitHead": "0caa0bec583b5e4c2b12b7375c365e02c2378eeb"
71
71
  }