@remotion/renderer 4.1.0-alpha5 → 4.1.0-alpha8

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.
@@ -40,6 +40,14 @@ const TaskQueue_1 = require("./TaskQueue");
40
40
  const TimeoutSettings_1 = require("./TimeoutSettings");
41
41
  const util_1 = require("./util");
42
42
  const format_logs_1 = require("../format-logs");
43
+ const shouldHideWarning = (log) => {
44
+ // Mixed Content warnings caused by localhost should not be displayed
45
+ if (log.text.includes('Mixed Content:') &&
46
+ log.text.includes('http://localhost:')) {
47
+ return true;
48
+ }
49
+ return false;
50
+ };
43
51
  class Page extends EventEmitter_1.EventEmitter {
44
52
  static async _create({ client, target, defaultViewport, browser, sourcemapContext, logLevel, indent, }) {
45
53
  const page = new Page({
@@ -106,6 +114,9 @@ class Page extends EventEmitter_1.EventEmitter {
106
114
  this.on('console', (log) => {
107
115
  var _a;
108
116
  const { url, columnNumber, lineNumber } = log.location();
117
+ if (shouldHideWarning(log)) {
118
+ return;
119
+ }
109
120
  if ((url === null || url === void 0 ? void 0 : url.endsWith(remotion_1.Internals.bundleName)) &&
110
121
  lineNumber &&
111
122
  this.sourcemapContext) {
@@ -18,6 +18,12 @@ const shouldLogBrowserMessage = (message) => {
18
18
  if (message.includes('Failed to send GpuControl.CreateCommandBuffer')) {
19
19
  return false;
20
20
  }
21
+ if (message.includes('CreatePlatformSocket() failed: Address family not supported by protocol')) {
22
+ return false;
23
+ }
24
+ if (message.includes('Fontconfig error: No writable cache directories')) {
25
+ return false;
26
+ }
21
27
  return true;
22
28
  };
23
29
  exports.shouldLogBrowserMessage = shouldLogBrowserMessage;
@@ -75,6 +75,11 @@ const callCompositor = (payload) => {
75
75
  }
76
76
  }
77
77
  });
78
+ if (child.stdin.closed) {
79
+ reject(new Error('Compositor stdin closed unexpectedly,' +
80
+ Buffer.concat(stderrChunks).toString('utf-8')));
81
+ return;
82
+ }
78
83
  child.stdin.write(payload);
79
84
  child.stdin.end();
80
85
  });
@@ -19,9 +19,9 @@ const getIdealMaximumFrameCacheItems = () => {
19
19
  // Assuming 1 frame is approximately 6MB
20
20
  // Assuming only half the available memory should be used
21
21
  const max = Math.floor(freeMemory / (1024 * 1024 * 6));
22
- // Never store more than 1000 frames
23
- // But 100 is needed even if it's going to swap
24
- return Math.max(100, Math.min(max, 1000));
22
+ // Never store more than 2000 frames
23
+ // But 500 is needed even if it's going to swap
24
+ return Math.max(500, Math.min(max, 2000));
25
25
  };
26
26
  exports.getIdealMaximumFrameCacheItems = getIdealMaximumFrameCacheItems;
27
27
  const startLongRunningCompositor = (maximumFrameCacheItems, logLevel, indent) => {
@@ -206,7 +206,6 @@ const startCompositor = (type, payload, logLevel, indent) => {
206
206
  params,
207
207
  },
208
208
  };
209
- // TODO: Should have a way to error out a single task
210
209
  child.stdin.write(JSON.stringify(composed) + '\n');
211
210
  waiters.set(nonce, {
212
211
  resolve: _resolve,
@@ -48,6 +48,9 @@ const formatObjectPreview = (preview) => {
48
48
  return chalk_1.chalk.reset(`${property.name}: ${formatProperty(property)}`);
49
49
  });
50
50
  if (preview.subtype === 'array') {
51
+ if (preview.overflow) {
52
+ return chalk_1.chalk.reset(`[ ${preview.properties.map((p) => formatProperty(p)).join(', ')}, …]`);
53
+ }
51
54
  return chalk_1.chalk.reset(`[ ${preview.properties.map((p) => formatProperty(p)).join(', ')} ]`);
52
55
  }
53
56
  if (preview.subtype === 'arraybuffer') {
@@ -104,6 +107,9 @@ const formatObjectPreview = (preview) => {
104
107
  if (properties.length === 0) {
105
108
  return chalk_1.chalk.reset('{}');
106
109
  }
110
+ if (preview.overflow) {
111
+ return chalk_1.chalk.reset(`{ ${properties.join(', ')}, …}`);
112
+ }
107
113
  return chalk_1.chalk.reset(`{ ${properties.join(', ')} }`);
108
114
  }
109
115
  return '';
@@ -1,4 +1,4 @@
1
- import type { VideoConfig } from 'remotion';
1
+ import { type VideoConfig } from 'remotion';
2
2
  import type { BrowserExecutable } from './browser-executable';
3
3
  import type { BrowserLog } from './browser-log';
4
4
  import type { HeadlessBrowser } from './browser/Browser';
@@ -6,7 +6,7 @@ import type { ChromiumOptions } from './open-browser';
6
6
  import type { RemotionServer } from './prepare-server';
7
7
  import { type LogLevel } from './log-level';
8
8
  type InternalGetCompositionsOptions = {
9
- inputProps: Record<string, unknown>;
9
+ serializedInputPropsWithCustomSchema: string;
10
10
  envVariables: Record<string, string>;
11
11
  puppeteerInstance: HeadlessBrowser | undefined;
12
12
  onBrowserLog: null | ((log: BrowserLog) => void);
@@ -30,7 +30,7 @@ export type GetCompositionsOptions = {
30
30
  port?: number | null;
31
31
  logLevel?: LogLevel;
32
32
  };
33
- export declare const internalGetCompositions: ({ browserExecutable, chromiumOptions, envVariables, indent, inputProps, onBrowserLog, port, puppeteerInstance, serveUrlOrWebpackUrl, server, timeoutInMilliseconds, logLevel, }: InternalGetCompositionsOptions) => Promise<VideoConfig[]>;
33
+ export declare const internalGetCompositions: ({ browserExecutable, chromiumOptions, envVariables, indent, serializedInputPropsWithCustomSchema, onBrowserLog, port, puppeteerInstance, serveUrlOrWebpackUrl, server, timeoutInMilliseconds, logLevel, }: InternalGetCompositionsOptions) => Promise<VideoConfig[]>;
34
34
  /**
35
35
  * @description Gets the compositions defined in a Remotion project based on a Webpack bundle.
36
36
  * @see [Documentation](https://www.remotion.dev/docs/renderer/get-compositions)
@@ -1,6 +1,7 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.getCompositions = exports.internalGetCompositions = void 0;
4
+ const remotion_1 = require("remotion");
4
5
  const TimeoutSettings_1 = require("./browser/TimeoutSettings");
5
6
  const handle_javascript_exception_1 = require("./error-handling/handle-javascript-exception");
6
7
  const find_closest_package_json_1 = require("./find-closest-package-json");
@@ -11,7 +12,7 @@ const seek_to_frame_1 = require("./seek-to-frame");
11
12
  const set_props_and_env_1 = require("./set-props-and-env");
12
13
  const validate_puppeteer_timeout_1 = require("./validate-puppeteer-timeout");
13
14
  const logger_1 = require("./logger");
14
- const innerGetCompositions = async ({ envVariables, inputProps, onBrowserLog, page, proxyPort, serveUrl, timeoutInMilliseconds, }) => {
15
+ const innerGetCompositions = async ({ envVariables, serializedInputPropsWithCustomSchema, onBrowserLog, page, proxyPort, serveUrl, timeoutInMilliseconds, indent, logLevel, }) => {
15
16
  if (onBrowserLog) {
16
17
  page.on('console', (log) => {
17
18
  onBrowserLog({
@@ -23,7 +24,7 @@ const innerGetCompositions = async ({ envVariables, inputProps, onBrowserLog, pa
23
24
  }
24
25
  (0, validate_puppeteer_timeout_1.validatePuppeteerTimeout)(timeoutInMilliseconds);
25
26
  await (0, set_props_and_env_1.setPropsAndEnv)({
26
- inputProps,
27
+ serializedInputPropsWithCustomSchema,
27
28
  envVariables,
28
29
  page,
29
30
  serveUrl,
@@ -33,6 +34,8 @@ const innerGetCompositions = async ({ envVariables, inputProps, onBrowserLog, pa
33
34
  retriesRemaining: 2,
34
35
  audioEnabled: false,
35
36
  videoEnabled: false,
37
+ indent,
38
+ logLevel,
36
39
  });
37
40
  await (0, puppeteer_evaluate_1.puppeteerEvaluateWithCatch)({
38
41
  page,
@@ -55,7 +58,7 @@ const innerGetCompositions = async ({ envVariables, inputProps, onBrowserLog, pa
55
58
  });
56
59
  return result;
57
60
  };
58
- const internalGetCompositions = async ({ browserExecutable, chromiumOptions, envVariables, indent, inputProps, onBrowserLog, port, puppeteerInstance, serveUrlOrWebpackUrl, server, timeoutInMilliseconds, logLevel, }) => {
61
+ const internalGetCompositions = async ({ browserExecutable, chromiumOptions, envVariables, indent, serializedInputPropsWithCustomSchema, onBrowserLog, port, puppeteerInstance, serveUrlOrWebpackUrl, server, timeoutInMilliseconds, logLevel, }) => {
59
62
  const { page, cleanup: cleanupPage } = await (0, get_browser_instance_1.getPageAndCleanupFn)({
60
63
  passedInInstance: puppeteerInstance,
61
64
  browserExecutable,
@@ -89,12 +92,14 @@ const internalGetCompositions = async ({ browserExecutable, chromiumOptions, env
89
92
  cleanup.push(() => cleanupServer(true));
90
93
  return innerGetCompositions({
91
94
  envVariables,
92
- inputProps,
95
+ serializedInputPropsWithCustomSchema,
93
96
  onBrowserLog,
94
97
  page,
95
98
  proxyPort: offthreadPort,
96
99
  serveUrl,
97
100
  timeoutInMilliseconds,
101
+ indent,
102
+ logLevel,
98
103
  });
99
104
  })
100
105
  .then((comp) => {
@@ -121,7 +126,11 @@ const getCompositions = (serveUrlOrWebpackUrl, config) => {
121
126
  browserExecutable: browserExecutable !== null && browserExecutable !== void 0 ? browserExecutable : null,
122
127
  chromiumOptions: chromiumOptions !== null && chromiumOptions !== void 0 ? chromiumOptions : {},
123
128
  envVariables: envVariables !== null && envVariables !== void 0 ? envVariables : {},
124
- inputProps: inputProps !== null && inputProps !== void 0 ? inputProps : {},
129
+ serializedInputPropsWithCustomSchema: remotion_1.Internals.serializeJSONWithDate({
130
+ data: inputProps !== null && inputProps !== void 0 ? inputProps : {},
131
+ indent: undefined,
132
+ staticBase: null,
133
+ }).serializedString,
125
134
  indent: false,
126
135
  onBrowserLog: onBrowserLog !== null && onBrowserLog !== void 0 ? onBrowserLog : null,
127
136
  port: port !== null && port !== void 0 ? port : null,
package/dist/index.d.ts CHANGED
@@ -1,3 +1,4 @@
1
+ /// <reference types="node" />
1
2
  import execa from 'execa';
2
3
  import { HeadlessBrowser } from './browser/Browser';
3
4
  import { SymbolicateableError } from './error-handling/symbolicateable-error';
@@ -113,8 +114,8 @@ export declare const RenderInternals: {
113
114
  validPixelFormats: readonly ["yuv420p", "yuva420p", "yuv422p", "yuv444p", "yuv420p10le", "yuv422p10le", "yuv444p10le", "yuva444p10le"];
114
115
  DEFAULT_BROWSER: import("./browser").Browser;
115
116
  validateFrameRange: (frameRange: import("./frame-range").FrameRange | null) => void;
116
- DEFAULT_OPENGL_RENDERER: "swangle" | "angle" | "egl" | "swiftshader" | null;
117
- 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;
118
119
  validCodecs: readonly ["h264", "h265", "vp8", "vp9", "mp3", "aac", "wav", "prores", "h264-mkv", "gif"];
119
120
  DEFAULT_PIXEL_FORMAT: "yuv420p" | "yuva420p" | "yuv422p" | "yuv444p" | "yuv420p10le" | "yuv422p10le" | "yuv444p10le" | "yuva444p10le";
120
121
  validateJpegQuality: (q: number | undefined) => void;
@@ -299,8 +300,8 @@ export declare const RenderInternals: {
299
300
  };
300
301
  validStillImageFormats: readonly ["png", "jpeg", "pdf", "webp"];
301
302
  validVideoImageFormats: readonly ["png", "jpeg", "none"];
302
- DEFAULT_STILL_IMAGE_FORMAT: "png" | "jpeg" | "pdf" | "webp";
303
- DEFAULT_VIDEO_IMAGE_FORMAT: "png" | "jpeg" | "none";
303
+ DEFAULT_STILL_IMAGE_FORMAT: "jpeg" | "png" | "webp" | "pdf";
304
+ DEFAULT_VIDEO_IMAGE_FORMAT: "jpeg" | "png" | "none";
304
305
  DEFAULT_JPEG_QUALITY: number;
305
306
  chalk: {
306
307
  enabled: () => boolean;
@@ -403,8 +404,9 @@ export declare const RenderInternals: {
403
404
  composition: import("remotion").VideoConfig;
404
405
  output: string | null;
405
406
  frame: number;
406
- inputProps: Record<string, unknown>;
407
- imageFormat: "png" | "jpeg" | "pdf" | "webp";
407
+ serializedInputPropsWithCustomSchema: string;
408
+ serializedResolvedPropsWithCustomSchema: string;
409
+ imageFormat: "jpeg" | "png" | "webp" | "pdf";
408
410
  jpegQuality: number;
409
411
  puppeteerInstance: HeadlessBrowser | null;
410
412
  envVariables: Record<string, string>;
@@ -434,7 +436,7 @@ export declare const RenderInternals: {
434
436
  logLevel: "verbose" | "info" | "warn" | "error";
435
437
  }) => Promise<HeadlessBrowser>;
436
438
  internalSelectComposition: (options: {
437
- inputProps: Record<string, unknown>;
439
+ serializedInputPropsWithCustomSchema: string;
438
440
  envVariables: Record<string, string>;
439
441
  puppeteerInstance: HeadlessBrowser | undefined;
440
442
  onBrowserLog: ((log: import("./browser-log").BrowserLog) => void) | null;
@@ -451,8 +453,8 @@ export declare const RenderInternals: {
451
453
  metadata: import("remotion").VideoConfig;
452
454
  propsSize: number;
453
455
  }>;
454
- internalGetCompositions: ({ browserExecutable, chromiumOptions, envVariables, indent, inputProps, onBrowserLog, port, puppeteerInstance, serveUrlOrWebpackUrl, server, timeoutInMilliseconds, logLevel, }: {
455
- inputProps: Record<string, unknown>;
456
+ internalGetCompositions: ({ browserExecutable, chromiumOptions, envVariables, indent, serializedInputPropsWithCustomSchema, onBrowserLog, port, puppeteerInstance, serveUrlOrWebpackUrl, server, timeoutInMilliseconds, logLevel, }: {
457
+ serializedInputPropsWithCustomSchema: string;
456
458
  envVariables: Record<string, string>;
457
459
  puppeteerInstance: HeadlessBrowser | undefined;
458
460
  onBrowserLog: ((log: import("./browser-log").BrowserLog) => void) | null;
@@ -465,8 +467,8 @@ export declare const RenderInternals: {
465
467
  logLevel: "verbose" | "info" | "warn" | "error";
466
468
  serveUrlOrWebpackUrl: string;
467
469
  }) => Promise<import("remotion").VideoConfig[]>;
468
- internalRenderFrames: ({ browserExecutable, cancelSignal, chromiumOptions, composition, concurrency, envVariables, everyNthFrame, frameRange, imageFormat, indent, inputProps, jpegQuality, muted, onBrowserLog, onDownload, onFrameBuffer, onFrameUpdate, onStart, outputDir, port, puppeteerInstance, scale, server, timeoutInMilliseconds, logLevel, webpackBundleOrServeUrl, }: import("./render-frames").InternalRenderFramesOptions) => Promise<import("./types").RenderFramesOutput>;
469
- internalRenderMedia: ({ proResProfile, crf, composition, inputProps, pixelFormat, codec, envVariables, frameRange, puppeteerInstance, outputLocation, onProgress, overwrite, onDownload, 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, logLevel, }: import("./render-media").InternalRenderMediaOptions) => Promise<{
470
+ internalRenderFrames: ({ browserExecutable, cancelSignal, chromiumOptions, composition, concurrency, envVariables, everyNthFrame, frameRange, imageFormat, indent, jpegQuality, muted, onBrowserLog, onDownload, onFrameBuffer, onFrameUpdate, onStart, outputDir, port, puppeteerInstance, scale, server, timeoutInMilliseconds, logLevel, webpackBundleOrServeUrl, serializedInputPropsWithCustomSchema, serializedResolvedPropsWithCustomSchema, }: import("./render-frames").InternalRenderFramesOptions) => Promise<import("./types").RenderFramesOutput>;
471
+ internalRenderMedia: ({ proResProfile, crf, composition, serializedInputPropsWithCustomSchema, pixelFormat, codec, envVariables, frameRange, puppeteerInstance, outputLocation, onProgress, overwrite, onDownload, 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, logLevel, serializedResolvedPropsWithCustomSchema, }: import("./render-media").InternalRenderMediaOptions) => Promise<{
470
472
  buffer: Buffer | null;
471
473
  slowestFrames: import("./render-media").SlowFrame[];
472
474
  }>;
package/dist/logger.d.ts CHANGED
@@ -18,6 +18,6 @@ export declare const Log: {
18
18
  warnAdvanced: (options: LogOptions, message?: any, ...optionalParams: any[]) => void;
19
19
  error: (message?: any, ...optionalParams: any[]) => void;
20
20
  };
21
- export declare const getLogLevel: () => "error" | "verbose" | "info" | "warn";
21
+ export declare const getLogLevel: () => "verbose" | "info" | "warn" | "error";
22
22
  export declare const setLogLevel: (newLogLevel: LogLevel) => void;
23
23
  export {};
package/dist/logger.js CHANGED
@@ -23,15 +23,16 @@ exports.Log = {
23
23
  return console.log(...[
24
24
  options.indent ? exports.INDENT_TOKEN : null,
25
25
  options.tag ? (0, exports.verboseTag)(options.tag) : null,
26
- ...args.map((a) => chalk_1.chalk.gray(a)),
27
- ].filter(truthy_1.truthy));
26
+ ]
27
+ .filter(truthy_1.truthy)
28
+ .concat(args.map((a) => chalk_1.chalk.gray(a))));
28
29
  }
29
30
  },
30
31
  info: (...args) => {
31
32
  exports.Log.infoAdvanced({ indent: false, logLevel: (0, exports.getLogLevel)() }, ...args);
32
33
  },
33
34
  infoAdvanced: (options, ...args) => {
34
- return console.log(...[options.indent ? exports.INDENT_TOKEN : null, ...args].filter(truthy_1.truthy));
35
+ return console.log(...[options.indent ? exports.INDENT_TOKEN : null].filter(truthy_1.truthy).concat(args));
35
36
  },
36
37
  warn: (...args) => {
37
38
  if ((0, log_level_1.isEqualOrBelowLogLevel)((0, exports.getLogLevel)(), 'warn')) {
@@ -40,10 +41,9 @@ exports.Log = {
40
41
  },
41
42
  warnAdvanced: (options, ...args) => {
42
43
  if ((0, log_level_1.isEqualOrBelowLogLevel)(options.logLevel, 'warn')) {
43
- return console.warn(...[
44
- options.indent ? chalk_1.chalk.yellow(exports.INDENT_TOKEN) : null,
45
- ...args.map((a) => chalk_1.chalk.yellow(a)),
46
- ].filter(truthy_1.truthy));
44
+ return console.warn(...[options.indent ? chalk_1.chalk.yellow(exports.INDENT_TOKEN) : null]
45
+ .filter(truthy_1.truthy)
46
+ .concat(args.map((a) => chalk_1.chalk.yellow(a))));
47
47
  }
48
48
  },
49
49
  error: (...args) => {
@@ -5,6 +5,7 @@ const node_url_1 = require("node:url");
5
5
  const download_and_map_assets_to_file_1 = require("./assets/download-and-map-assets-to-file");
6
6
  const compositor_1 = require("./compositor/compositor");
7
7
  const log_level_1 = require("./log-level");
8
+ const logger_1 = require("./logger");
8
9
  const extractUrlAndSourceFromUrl = (url) => {
9
10
  const parsed = new URL(url, 'http://localhost');
10
11
  const query = parsed.search;
@@ -68,8 +69,10 @@ const startOffthreadVideoServer = ({ downloadMap, concurrency, logLevel, indent,
68
69
  res.end();
69
70
  return;
70
71
  }
72
+ let extractStart = Date.now();
71
73
  (0, download_and_map_assets_to_file_1.downloadAsset)({ src, emitter: events, downloadMap })
72
74
  .then((to) => {
75
+ extractStart = Date.now();
73
76
  return compositor.executeCommand('ExtractFrame', {
74
77
  input: to,
75
78
  time,
@@ -77,6 +80,11 @@ const startOffthreadVideoServer = ({ downloadMap, concurrency, logLevel, indent,
77
80
  });
78
81
  })
79
82
  .then((readable) => {
83
+ const extractEnd = Date.now();
84
+ const timeToExtract = extractEnd - extractStart;
85
+ if (timeToExtract > 1000) {
86
+ logger_1.Log.verbose(`Took ${timeToExtract}ms to extract frame from ${src} at ${time}`);
87
+ }
80
88
  if (!readable) {
81
89
  throw new Error('no readable from ffmpeg');
82
90
  }
@@ -5,7 +5,7 @@ const jsx_runtime_1 = require("react/jsx-runtime");
5
5
  exports.crfOption = {
6
6
  name: 'CRF',
7
7
  cliFlag: '--crf',
8
- description: ((0, jsx_runtime_1.jsx)(jsx_runtime_1.Fragment, { children: "No matter which codec you end up using, there's always a tradeoff between file size and video quality. You can control it by setting the so called CRF (Constant Rate Factor). The lower the number, the better the quality, the higher the number, the smaller the file is \u2013 of course at the cost of quality." })),
8
+ description: ((0, jsx_runtime_1.jsx)(jsx_runtime_1.Fragment, { children: "No matter which codec you end up using, there's always a tradeoff between file size and video quality. You can control it by setting the CRF (Constant Rate Factor). The lower the number, the better the quality, the higher the number, the smaller the file is \u2013 of course at the cost of quality." })),
9
9
  ssrName: 'crf',
10
10
  docLink: 'https://www.remotion.dev/docs/encoding/#controlling-quality-using-the-crf-setting',
11
11
  };
@@ -5,7 +5,7 @@ const jsx_runtime_1 = require("react/jsx-runtime");
5
5
  exports.videoCodecOption = {
6
6
  name: 'Codec',
7
7
  cliFlag: '--codec',
8
- description: ((0, jsx_runtime_1.jsx)(jsx_runtime_1.Fragment, { children: "H264 works well in most cases, sometimes it's worth going for a different codec. WebM achieves higher compression but is slower to render. WebM and ProRes support transparency." })),
8
+ description: ((0, jsx_runtime_1.jsx)(jsx_runtime_1.Fragment, { children: "H264 works well in most cases, but sometimes it's worth going for a different codec. WebM achieves higher compression but is slower to render. WebM and ProRes support transparency." })),
9
9
  ssrName: 'codec',
10
10
  docLink: 'https://www.remotion.dev/docs/encoding/#choosing-a-codec',
11
11
  };
@@ -15,7 +15,6 @@ export type InternalRenderFramesOptions = {
15
15
  onStart: null | ((data: OnStartData) => void);
16
16
  onFrameUpdate: null | ((framesRendered: number, frameIndex: number, timeToRenderInMilliseconds: number) => void);
17
17
  outputDir: string | null;
18
- inputProps: Record<string, unknown>;
19
18
  envVariables: Record<string, string>;
20
19
  imageFormat: VideoImageFormat;
21
20
  jpegQuality: number;
@@ -31,13 +30,15 @@ export type InternalRenderFramesOptions = {
31
30
  scale: number;
32
31
  port: number | null;
33
32
  cancelSignal: CancelSignal | undefined;
34
- composition: VideoConfig;
33
+ composition: Omit<VideoConfig, 'props' | 'defaultProps'>;
35
34
  indent: boolean;
36
35
  server: RemotionServer | undefined;
37
36
  muted: boolean;
38
37
  concurrency: number | string | null;
39
38
  webpackBundleOrServeUrl: string;
40
39
  logLevel: LogLevel;
40
+ serializedInputPropsWithCustomSchema: string;
41
+ serializedResolvedPropsWithCustomSchema: string;
41
42
  };
42
43
  export type RenderFramesOptions = {
43
44
  onStart: (data: OnStartData) => void;
@@ -77,7 +78,7 @@ export type RenderFramesOptions = {
77
78
  concurrency?: number | string | null;
78
79
  serveUrl: string;
79
80
  };
80
- export declare const internalRenderFrames: ({ browserExecutable, cancelSignal, chromiumOptions, composition, concurrency, envVariables, everyNthFrame, frameRange, imageFormat, indent, inputProps, jpegQuality, muted, onBrowserLog, onDownload, onFrameBuffer, onFrameUpdate, onStart, outputDir, port, puppeteerInstance, scale, server, timeoutInMilliseconds, logLevel, webpackBundleOrServeUrl, }: InternalRenderFramesOptions) => Promise<RenderFramesOutput>;
81
+ export declare const internalRenderFrames: ({ browserExecutable, cancelSignal, chromiumOptions, composition, concurrency, envVariables, everyNthFrame, frameRange, imageFormat, indent, jpegQuality, muted, onBrowserLog, onDownload, onFrameBuffer, onFrameUpdate, onStart, outputDir, port, puppeteerInstance, scale, server, timeoutInMilliseconds, logLevel, webpackBundleOrServeUrl, serializedInputPropsWithCustomSchema, serializedResolvedPropsWithCustomSchema, }: InternalRenderFramesOptions) => Promise<RenderFramesOutput>;
81
82
  /**
82
83
  * @description Renders a series of images using Puppeteer and computes information for mixing audio.
83
84
  * @see [Documentation](https://www.remotion.dev/docs/renderer/render-frames)
@@ -35,7 +35,7 @@ const truthy_1 = require("./truthy");
35
35
  const validate_scale_1 = require("./validate-scale");
36
36
  const logger_1 = require("./logger");
37
37
  const MAX_RETRIES_PER_FRAME = 1;
38
- const innerRenderFrames = async ({ onFrameUpdate, outputDir, onStart, inputProps, jpegQuality, imageFormat, frameRange, onError, envVariables, onBrowserLog, onFrameBuffer, onDownload, pagesArray, serveUrl, composition, timeoutInMilliseconds, scale, actualConcurrency, everyNthFrame, proxyPort, cancelSignal, downloadMap, muted, makeBrowser, browserReplacer, compositor, sourcemapContext, logLevel, indent, }) => {
38
+ const innerRenderFrames = async ({ onFrameUpdate, outputDir, onStart, serializedInputPropsWithCustomSchema, serializedResolvedPropsWithCustomSchema, jpegQuality, imageFormat, frameRange, onError, envVariables, onBrowserLog, onFrameBuffer, onDownload, pagesArray, serveUrl, composition, timeoutInMilliseconds, scale, actualConcurrency, everyNthFrame, proxyPort, cancelSignal, downloadMap, muted, makeBrowser, browserReplacer, compositor, sourcemapContext, logLevel, indent, }) => {
39
39
  if (outputDir) {
40
40
  if (!node_fs_1.default.existsSync(outputDir)) {
41
41
  node_fs_1.default.mkdirSync(outputDir, {
@@ -69,7 +69,7 @@ const innerRenderFrames = async ({ onFrameUpdate, outputDir, onStart, inputProps
69
69
  }
70
70
  const initialFrame = realFrameRange[0];
71
71
  await (0, set_props_and_env_1.setPropsAndEnv)({
72
- inputProps,
72
+ serializedInputPropsWithCustomSchema,
73
73
  envVariables,
74
74
  page,
75
75
  serveUrl,
@@ -79,6 +79,8 @@ const innerRenderFrames = async ({ onFrameUpdate, outputDir, onStart, inputProps
79
79
  retriesRemaining: 2,
80
80
  audioEnabled: !muted,
81
81
  videoEnabled: imageFormat !== 'none',
82
+ indent,
83
+ logLevel,
82
84
  });
83
85
  await (0, puppeteer_evaluate_1.puppeteerEvaluateWithCatch)({
84
86
  // eslint-disable-next-line max-params
@@ -86,7 +88,7 @@ const innerRenderFrames = async ({ onFrameUpdate, outputDir, onStart, inputProps
86
88
  window.remotion_setBundleMode({
87
89
  type: 'composition',
88
90
  compositionName: id,
89
- props,
91
+ serializedResolvedPropsWithSchema: props,
90
92
  compositionDurationInFrames: durationInFrames,
91
93
  compositionFps: fps,
92
94
  compositionHeight: height,
@@ -95,7 +97,7 @@ const innerRenderFrames = async ({ onFrameUpdate, outputDir, onStart, inputProps
95
97
  },
96
98
  args: [
97
99
  composition.id,
98
- composition.props,
100
+ serializedResolvedPropsWithCustomSchema,
99
101
  composition.durationInFrames,
100
102
  composition.fps,
101
103
  composition.height,
@@ -133,7 +135,7 @@ const innerRenderFrames = async ({ onFrameUpdate, outputDir, onStart, inputProps
133
135
  cancelSignal === null || cancelSignal === void 0 ? void 0 : cancelSignal(() => {
134
136
  stopped = true;
135
137
  });
136
- const renderFrameWithOptionToReject = async ({ frame, index, reject, width, height, }) => {
138
+ const renderFrameWithOptionToReject = async ({ frame, index, reject, width, height, compId, }) => {
137
139
  const pool = await poolPromise;
138
140
  const freePage = await pool.acquire();
139
141
  if (stopped) {
@@ -149,7 +151,12 @@ const innerRenderFrames = async ({ onFrameUpdate, outputDir, onStart, inputProps
149
151
  frame,
150
152
  });
151
153
  freePage.on('error', errorCallbackOnFrame);
152
- await (0, seek_to_frame_1.seekToFrame)({ frame, page: freePage });
154
+ const startSeeking = Date.now();
155
+ await (0, seek_to_frame_1.seekToFrame)({ frame, page: freePage, composition: compId });
156
+ const timeToSeek = Date.now() - startSeeking;
157
+ if (timeToSeek > 1000) {
158
+ logger_1.Log.verbose(`Seeking to frame ${frame} took ${timeToSeek}ms`);
159
+ }
153
160
  if (!outputDir && !onFrameBuffer && imageFormat !== 'none') {
154
161
  throw new Error('Called renderFrames() without specifying either `outputDir` or `onFrameBuffer`');
155
162
  }
@@ -210,6 +217,7 @@ const innerRenderFrames = async ({ onFrameUpdate, outputDir, onStart, inputProps
210
217
  reject,
211
218
  width: composition.width,
212
219
  height: composition.height,
220
+ compId: composition.id,
213
221
  })
214
222
  .then(() => {
215
223
  resolve();
@@ -286,12 +294,11 @@ const innerRenderFrames = async ({ onFrameUpdate, outputDir, onStart, inputProps
286
294
  await Promise.all(downloadPromises);
287
295
  return result;
288
296
  };
289
- const internalRenderFrames = ({ browserExecutable, cancelSignal, chromiumOptions, composition, concurrency, envVariables, everyNthFrame, frameRange, imageFormat, indent, inputProps, jpegQuality, muted, onBrowserLog, onDownload, onFrameBuffer, onFrameUpdate, onStart, outputDir, port, puppeteerInstance, scale, server, timeoutInMilliseconds, logLevel, webpackBundleOrServeUrl, }) => {
297
+ const internalRenderFrames = ({ browserExecutable, cancelSignal, chromiumOptions, composition, concurrency, envVariables, everyNthFrame, frameRange, imageFormat, indent, jpegQuality, muted, onBrowserLog, onDownload, onFrameBuffer, onFrameUpdate, onStart, outputDir, port, puppeteerInstance, scale, server, timeoutInMilliseconds, logLevel, webpackBundleOrServeUrl, serializedInputPropsWithCustomSchema, serializedResolvedPropsWithCustomSchema, }) => {
290
298
  remotion_1.Internals.validateDimension(composition.height, 'height', 'in the `config` object passed to `renderFrames()`');
291
299
  remotion_1.Internals.validateDimension(composition.width, 'width', 'in the `config` object passed to `renderFrames()`');
292
300
  remotion_1.Internals.validateFps(composition.fps, 'in the `config` object of `renderFrames()`', false);
293
- remotion_1.Internals.validateDurationInFrames({
294
- durationInFrames: composition.durationInFrames,
301
+ remotion_1.Internals.validateDurationInFrames(composition.durationInFrames, {
295
302
  component: 'in the `config` object passed to `renderFrames()`',
296
303
  allowFloats: false,
297
304
  });
@@ -355,7 +362,6 @@ const internalRenderFrames = ({ browserExecutable, cancelSignal, chromiumOptions
355
362
  everyNthFrame,
356
363
  frameRange,
357
364
  imageFormat,
358
- inputProps,
359
365
  jpegQuality,
360
366
  muted,
361
367
  onBrowserLog,
@@ -367,6 +373,8 @@ const internalRenderFrames = ({ browserExecutable, cancelSignal, chromiumOptions
367
373
  timeoutInMilliseconds,
368
374
  logLevel,
369
375
  indent,
376
+ serializedInputPropsWithCustomSchema,
377
+ serializedResolvedPropsWithCustomSchema,
370
378
  });
371
379
  }),
372
380
  ])
@@ -433,7 +441,16 @@ const renderFrames = (options) => {
433
441
  indent: false,
434
442
  jpegQuality: jpegQuality !== null && jpegQuality !== void 0 ? jpegQuality : jpeg_quality_1.DEFAULT_JPEG_QUALITY,
435
443
  onDownload: onDownload !== null && onDownload !== void 0 ? onDownload : null,
436
- inputProps,
444
+ serializedInputPropsWithCustomSchema: remotion_1.Internals.serializeJSONWithDate({
445
+ indent: undefined,
446
+ staticBase: null,
447
+ data: inputProps !== null && inputProps !== void 0 ? inputProps : {},
448
+ }).serializedString,
449
+ serializedResolvedPropsWithCustomSchema: remotion_1.Internals.serializeJSONWithDate({
450
+ indent: undefined,
451
+ staticBase: null,
452
+ data: composition.props,
453
+ }).serializedString,
437
454
  puppeteerInstance,
438
455
  muted: muted !== null && muted !== void 0 ? muted : false,
439
456
  onBrowserLog: onBrowserLog !== null && onBrowserLog !== void 0 ? onBrowserLog : null,
@@ -32,8 +32,9 @@ export type RenderMediaOnProgress = (progress: {
32
32
  export type InternalRenderMediaOptions = {
33
33
  outputLocation: string | null;
34
34
  codec: Codec;
35
- composition: VideoConfig;
36
- inputProps: Record<string, unknown>;
35
+ composition: Omit<VideoConfig, 'props' | 'defaultProps'>;
36
+ serializedInputPropsWithCustomSchema: string;
37
+ serializedResolvedPropsWithCustomSchema: string;
37
38
  crf: number | null;
38
39
  imageFormat: VideoImageFormat;
39
40
  pixelFormat: PixelFormat;
@@ -124,7 +125,7 @@ type RenderMediaResult = {
124
125
  buffer: Buffer | null;
125
126
  slowestFrames: SlowFrame[];
126
127
  };
127
- export declare const internalRenderMedia: ({ proResProfile, crf, composition, inputProps, pixelFormat, codec, envVariables, frameRange, puppeteerInstance, outputLocation, onProgress, overwrite, onDownload, 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, logLevel, }: InternalRenderMediaOptions) => Promise<RenderMediaResult>;
128
+ export declare const internalRenderMedia: ({ proResProfile, crf, composition, serializedInputPropsWithCustomSchema, pixelFormat, codec, envVariables, frameRange, puppeteerInstance, outputLocation, onProgress, overwrite, onDownload, 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, logLevel, serializedResolvedPropsWithCustomSchema, }: InternalRenderMediaOptions) => Promise<RenderMediaResult>;
128
129
  /**
129
130
  *
130
131
  * @description Render a video from a composition
@@ -43,7 +43,7 @@ const validate_output_filename_1 = require("./validate-output-filename");
43
43
  const validate_scale_1 = require("./validate-scale");
44
44
  const validate_videobitrate_1 = require("./validate-videobitrate");
45
45
  const SLOWEST_FRAME_COUNT = 10;
46
- const internalRenderMedia = ({ proResProfile, crf, composition, inputProps, pixelFormat, codec, envVariables, frameRange, puppeteerInstance, outputLocation, onProgress, overwrite, onDownload, 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, logLevel, }) => {
46
+ const internalRenderMedia = ({ proResProfile, crf, composition, serializedInputPropsWithCustomSchema, pixelFormat, codec, envVariables, frameRange, puppeteerInstance, outputLocation, onProgress, overwrite, onDownload, 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, logLevel, serializedResolvedPropsWithCustomSchema, }) => {
47
47
  (0, jpeg_quality_1.validateJpegQuality)(jpegQuality);
48
48
  (0, crf_1.validateQualitySettings)({ crf, codec, videoBitrate });
49
49
  (0, validate_videobitrate_1.validateBitrate)(audioBitrate, 'audioBitrate');
@@ -94,11 +94,13 @@ const internalRenderMedia = ({ proResProfile, crf, composition, inputProps, pixe
94
94
  logLevel,
95
95
  tag: 'renderMedia()',
96
96
  }, 'Codec supports parallel rendering:', (0, can_use_parallel_encoding_1.canUseParallelEncoding)(codec));
97
- logger_1.Log.verboseAdvanced({
98
- indent,
99
- logLevel,
100
- tag: 'renderMedia()',
101
- }, 'User disallowed parallel encoding:', Boolean(disallowParallelEncoding));
97
+ if (disallowParallelEncoding) {
98
+ logger_1.Log.verboseAdvanced({
99
+ indent,
100
+ logLevel,
101
+ tag: 'renderMedia()',
102
+ }, 'User disallowed parallel encoding.');
103
+ }
102
104
  if (parallelEncoding) {
103
105
  logger_1.Log.verboseAdvanced({
104
106
  indent,
@@ -248,7 +250,7 @@ const internalRenderMedia = ({ proResProfile, crf, composition, inputProps, pixe
248
250
  callUpdate();
249
251
  onStart === null || onStart === void 0 ? void 0 : onStart(data);
250
252
  },
251
- inputProps,
253
+ serializedInputPropsWithCustomSchema,
252
254
  envVariables,
253
255
  imageFormat,
254
256
  jpegQuality,
@@ -288,6 +290,7 @@ const internalRenderMedia = ({ proResProfile, crf, composition, inputProps, pixe
288
290
  logLevel,
289
291
  indent,
290
292
  server,
293
+ serializedResolvedPropsWithCustomSchema,
291
294
  });
292
295
  return renderFramesProc;
293
296
  })
@@ -424,7 +427,11 @@ const renderMedia = ({ proResProfile, crf, composition, inputProps, pixelFormat,
424
427
  ffmpegOverride: ffmpegOverride !== null && ffmpegOverride !== void 0 ? ffmpegOverride : undefined,
425
428
  frameRange: frameRange !== null && frameRange !== void 0 ? frameRange : null,
426
429
  imageFormat: imageFormat !== null && imageFormat !== void 0 ? imageFormat : image_format_1.DEFAULT_VIDEO_IMAGE_FORMAT,
427
- inputProps: inputProps !== null && inputProps !== void 0 ? inputProps : {},
430
+ serializedInputPropsWithCustomSchema: remotion_1.Internals.serializeJSONWithDate({
431
+ indent: undefined,
432
+ staticBase: null,
433
+ data: inputProps !== null && inputProps !== void 0 ? inputProps : {},
434
+ }).serializedString,
428
435
  jpegQuality: (_a = jpegQuality !== null && jpegQuality !== void 0 ? jpegQuality : quality) !== null && _a !== void 0 ? _a : jpeg_quality_1.DEFAULT_JPEG_QUALITY,
429
436
  muted: muted !== null && muted !== void 0 ? muted : false,
430
437
  numberOfGifLoops: numberOfGifLoops !== null && numberOfGifLoops !== void 0 ? numberOfGifLoops : null,
@@ -445,6 +452,11 @@ const renderMedia = ({ proResProfile, crf, composition, inputProps, pixelFormat,
445
452
  indent: false,
446
453
  onCtrlCExit: () => undefined,
447
454
  server: undefined,
455
+ serializedResolvedPropsWithCustomSchema: remotion_1.Internals.serializeJSONWithDate({
456
+ indent: undefined,
457
+ staticBase: null,
458
+ data: composition.props,
459
+ }).serializedString,
448
460
  });
449
461
  };
450
462
  exports.renderMedia = renderMedia;
@@ -13,7 +13,8 @@ type InternalRenderStillOptions = {
13
13
  composition: VideoConfig;
14
14
  output: string | null;
15
15
  frame: number;
16
- inputProps: Record<string, unknown>;
16
+ serializedInputPropsWithCustomSchema: string;
17
+ serializedResolvedPropsWithCustomSchema: string;
17
18
  imageFormat: StillImageFormat;
18
19
  jpegQuality: number;
19
20
  puppeteerInstance: HeadlessBrowser | null;
@@ -49,12 +49,11 @@ const take_frame_and_compose_1 = require("./take-frame-and-compose");
49
49
  const validate_puppeteer_timeout_1 = require("./validate-puppeteer-timeout");
50
50
  const validate_scale_1 = require("./validate-scale");
51
51
  const logger_1 = require("./logger");
52
- const innerRenderStill = async ({ composition, imageFormat = image_format_1.DEFAULT_STILL_IMAGE_FORMAT, serveUrl, puppeteerInstance, onError, inputProps, envVariables, output, frame = 0, overwrite, browserExecutable, timeoutInMilliseconds, chromiumOptions, scale, proxyPort, cancelSignal, jpegQuality, onBrowserLog, compositor, sourceMapContext, downloadMap, logLevel, indent, }) => {
52
+ const innerRenderStill = async ({ composition, imageFormat = image_format_1.DEFAULT_STILL_IMAGE_FORMAT, serveUrl, puppeteerInstance, onError, serializedInputPropsWithCustomSchema, envVariables, output, frame = 0, overwrite, browserExecutable, timeoutInMilliseconds, chromiumOptions, scale, proxyPort, cancelSignal, jpegQuality, onBrowserLog, compositor, sourceMapContext, downloadMap, logLevel, indent, serializedResolvedPropsWithCustomSchema, }) => {
53
53
  remotion_1.Internals.validateDimension(composition.height, 'height', 'in the `config` object passed to `renderStill()`');
54
54
  remotion_1.Internals.validateDimension(composition.width, 'width', 'in the `config` object passed to `renderStill()`');
55
55
  remotion_1.Internals.validateFps(composition.fps, 'in the `config` object of `renderStill()`', false);
56
- remotion_1.Internals.validateDurationInFrames({
57
- durationInFrames: composition.durationInFrames,
56
+ remotion_1.Internals.validateDurationInFrames(composition.durationInFrames, {
58
57
  component: 'in the `config` object passed to `renderStill()`',
59
58
  allowFloats: false,
60
59
  });
@@ -135,7 +134,7 @@ const innerRenderStill = async ({ composition, imageFormat = image_format_1.DEFA
135
134
  page.on('console', logCallback);
136
135
  }
137
136
  await (0, set_props_and_env_1.setPropsAndEnv)({
138
- inputProps,
137
+ serializedInputPropsWithCustomSchema,
139
138
  envVariables,
140
139
  page,
141
140
  serveUrl,
@@ -145,6 +144,8 @@ const innerRenderStill = async ({ composition, imageFormat = image_format_1.DEFA
145
144
  retriesRemaining: 2,
146
145
  audioEnabled: false,
147
146
  videoEnabled: true,
147
+ indent,
148
+ logLevel,
148
149
  });
149
150
  await (0, puppeteer_evaluate_1.puppeteerEvaluateWithCatch)({
150
151
  // eslint-disable-next-line max-params
@@ -152,7 +153,7 @@ const innerRenderStill = async ({ composition, imageFormat = image_format_1.DEFA
152
153
  window.remotion_setBundleMode({
153
154
  type: 'composition',
154
155
  compositionName: id,
155
- props,
156
+ serializedResolvedPropsWithSchema: props,
156
157
  compositionDurationInFrames: durationInFrames,
157
158
  compositionFps: fps,
158
159
  compositionHeight: height,
@@ -161,7 +162,7 @@ const innerRenderStill = async ({ composition, imageFormat = image_format_1.DEFA
161
162
  },
162
163
  args: [
163
164
  composition.id,
164
- composition.props,
165
+ serializedResolvedPropsWithCustomSchema,
165
166
  composition.durationInFrames,
166
167
  composition.fps,
167
168
  composition.height,
@@ -170,7 +171,7 @@ const innerRenderStill = async ({ composition, imageFormat = image_format_1.DEFA
170
171
  frame: null,
171
172
  page,
172
173
  });
173
- await (0, seek_to_frame_1.seekToFrame)({ frame: stillFrame, page });
174
+ await (0, seek_to_frame_1.seekToFrame)({ frame: stillFrame, page, composition: composition.id });
174
175
  const { buffer } = await (0, take_frame_and_compose_1.takeFrameAndCompose)({
175
176
  frame: stillFrame,
176
177
  freePage: page,
@@ -240,7 +241,7 @@ exports.internalRenderStill = internalRenderStill;
240
241
  * @see [Documentation](https://www.remotion.dev/docs/renderer/render-still)
241
242
  */
242
243
  const renderStill = (options) => {
243
- var _a;
244
+ var _a, _b;
244
245
  const { composition, serveUrl, browserExecutable, cancelSignal, chromiumOptions, dumpBrowserLogs, envVariables, frame, imageFormat, inputProps, jpegQuality, onBrowserLog, onDownload, output, overwrite, port, puppeteerInstance, scale, timeoutInMilliseconds, verbose, quality, } = options;
245
246
  if (typeof jpegQuality !== 'undefined' && imageFormat !== 'jpeg') {
246
247
  throw new Error("You can only pass the `quality` option if `imageFormat` is 'jpeg'.");
@@ -257,7 +258,11 @@ const renderStill = (options) => {
257
258
  frame: frame !== null && frame !== void 0 ? frame : 0,
258
259
  imageFormat: imageFormat !== null && imageFormat !== void 0 ? imageFormat : image_format_1.DEFAULT_STILL_IMAGE_FORMAT,
259
260
  indent: false,
260
- inputProps: inputProps !== null && inputProps !== void 0 ? inputProps : {},
261
+ serializedInputPropsWithCustomSchema: remotion_1.Internals.serializeJSONWithDate({
262
+ staticBase: null,
263
+ indent: undefined,
264
+ data: inputProps !== null && inputProps !== void 0 ? inputProps : {},
265
+ }).serializedString,
261
266
  jpegQuality: (_a = jpegQuality !== null && jpegQuality !== void 0 ? jpegQuality : quality) !== null && _a !== void 0 ? _a : jpeg_quality_1.DEFAULT_JPEG_QUALITY,
262
267
  onBrowserLog: onBrowserLog !== null && onBrowserLog !== void 0 ? onBrowserLog : null,
263
268
  onDownload: onDownload !== null && onDownload !== void 0 ? onDownload : null,
@@ -270,6 +275,11 @@ const renderStill = (options) => {
270
275
  serveUrl,
271
276
  timeoutInMilliseconds: timeoutInMilliseconds !== null && timeoutInMilliseconds !== void 0 ? timeoutInMilliseconds : TimeoutSettings_1.DEFAULT_TIMEOUT,
272
277
  logLevel: verbose || dumpBrowserLogs ? 'verbose' : (0, logger_1.getLogLevel)(),
278
+ serializedResolvedPropsWithCustomSchema: remotion_1.Internals.serializeJSONWithDate({
279
+ indent: undefined,
280
+ staticBase: null,
281
+ data: (_b = composition.props) !== null && _b !== void 0 ? _b : {},
282
+ }).serializedString,
273
283
  });
274
284
  };
275
285
  exports.renderStill = renderStill;
@@ -1,6 +1,7 @@
1
1
  import type { Page } from './browser/BrowserPage';
2
2
  export declare const waitForReady: (page: Page) => Promise<unknown>;
3
- export declare const seekToFrame: ({ frame, page, }: {
3
+ export declare const seekToFrame: ({ frame, page, composition, }: {
4
4
  frame: number;
5
+ composition: string;
5
6
  page: Page;
6
7
  }) => Promise<void>;
@@ -48,13 +48,13 @@ const waitForReady = (page) => {
48
48
  ]);
49
49
  };
50
50
  exports.waitForReady = waitForReady;
51
- const seekToFrame = async ({ frame, page, }) => {
51
+ const seekToFrame = async ({ frame, page, composition, }) => {
52
52
  await (0, exports.waitForReady)(page);
53
53
  await (0, puppeteer_evaluate_1.puppeteerEvaluateWithCatch)({
54
- pageFunction: (f) => {
55
- window.remotion_setFrame(f);
54
+ pageFunction: (f, c) => {
55
+ window.remotion_setFrame(f, c);
56
56
  },
57
- args: [frame],
57
+ args: [frame, composition],
58
58
  frame,
59
59
  page,
60
60
  });
@@ -1,4 +1,4 @@
1
- import type { VideoConfig } from 'remotion';
1
+ import { type VideoConfig } from 'remotion';
2
2
  import type { BrowserExecutable } from './browser-executable';
3
3
  import type { BrowserLog } from './browser-log';
4
4
  import type { HeadlessBrowser } from './browser/Browser';
@@ -6,7 +6,7 @@ import type { ChromiumOptions } from './open-browser';
6
6
  import type { RemotionServer } from './prepare-server';
7
7
  import { type LogLevel } from './log-level';
8
8
  type InternalSelectCompositionsConfig = {
9
- inputProps: Record<string, unknown>;
9
+ serializedInputPropsWithCustomSchema: string;
10
10
  envVariables: Record<string, string>;
11
11
  puppeteerInstance: HeadlessBrowser | undefined;
12
12
  onBrowserLog: null | ((log: BrowserLog) => void);
@@ -42,5 +42,5 @@ export declare const internalSelectComposition: (options: InternalSelectComposit
42
42
  * @description Gets a composition defined in a Remotion project based on a Webpack bundle.
43
43
  * @see [Documentation](https://www.remotion.dev/docs/renderer/select-composition)
44
44
  */
45
- export declare const selectComposition: (options: SelectCompositionOptions) => Promise<VideoConfig>;
45
+ export declare const selectComposition: (options: SelectCompositionOptions) => Promise<Omit<VideoConfig, 'defaultProps'>>;
46
46
  export {};
@@ -1,6 +1,7 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.selectComposition = exports.internalSelectComposition = void 0;
4
+ const remotion_1 = require("remotion");
4
5
  const TimeoutSettings_1 = require("./browser/TimeoutSettings");
5
6
  const handle_javascript_exception_1 = require("./error-handling/handle-javascript-exception");
6
7
  const find_closest_package_json_1 = require("./find-closest-package-json");
@@ -11,7 +12,7 @@ const puppeteer_evaluate_1 = require("./puppeteer-evaluate");
11
12
  const seek_to_frame_1 = require("./seek-to-frame");
12
13
  const set_props_and_env_1 = require("./set-props-and-env");
13
14
  const validate_puppeteer_timeout_1 = require("./validate-puppeteer-timeout");
14
- const innerSelectComposition = async ({ page, onBrowserLog, inputProps, envVariables, serveUrl, timeoutInMilliseconds, port, id, indent, logLevel, }) => {
15
+ const innerSelectComposition = async ({ page, onBrowserLog, serializedInputPropsWithCustomSchema, envVariables, serveUrl, timeoutInMilliseconds, port, id, indent, logLevel, }) => {
15
16
  if (onBrowserLog) {
16
17
  page.on('console', (log) => {
17
18
  onBrowserLog({
@@ -23,7 +24,7 @@ const innerSelectComposition = async ({ page, onBrowserLog, inputProps, envVaria
23
24
  }
24
25
  (0, validate_puppeteer_timeout_1.validatePuppeteerTimeout)(timeoutInMilliseconds);
25
26
  await (0, set_props_and_env_1.setPropsAndEnv)({
26
- inputProps,
27
+ serializedInputPropsWithCustomSchema,
27
28
  envVariables,
28
29
  page,
29
30
  serveUrl,
@@ -33,6 +34,8 @@ const innerSelectComposition = async ({ page, onBrowserLog, inputProps, envVaria
33
34
  retriesRemaining: 2,
34
35
  audioEnabled: false,
35
36
  videoEnabled: false,
37
+ indent,
38
+ logLevel,
36
39
  });
37
40
  await (0, puppeteer_evaluate_1.puppeteerEvaluateWithCatch)({
38
41
  page,
@@ -64,11 +67,24 @@ const innerSelectComposition = async ({ page, onBrowserLog, inputProps, envVaria
64
67
  tag: 'selectComposition()',
65
68
  logLevel,
66
69
  }, `calculateMetadata() took ${Date.now() - time}ms`);
67
- return { metadata: result, propsSize: size };
70
+ const res = result;
71
+ const { width, durationInFrames, fps, height } = res;
72
+ return {
73
+ metadata: {
74
+ id,
75
+ width,
76
+ height,
77
+ fps,
78
+ durationInFrames,
79
+ props: remotion_1.Internals.deserializeJSONWithCustomFields(res.serializedResolvedPropsWithCustomSchema),
80
+ defaultProps: remotion_1.Internals.deserializeJSONWithCustomFields(res.serializedDefaultPropsWithCustomSchema),
81
+ },
82
+ propsSize: size,
83
+ };
68
84
  };
69
85
  const internalSelectComposition = async (options) => {
70
86
  const cleanup = [];
71
- const { puppeteerInstance, browserExecutable, chromiumOptions, serveUrl: serveUrlOrWebpackUrl, logLevel, indent, port, envVariables, id, inputProps, onBrowserLog, server, timeoutInMilliseconds, } = options;
87
+ const { puppeteerInstance, browserExecutable, chromiumOptions, serveUrl: serveUrlOrWebpackUrl, logLevel, indent, port, envVariables, id, serializedInputPropsWithCustomSchema, onBrowserLog, server, timeoutInMilliseconds, } = options;
72
88
  const { page, cleanup: cleanupPage } = await (0, get_browser_instance_1.getPageAndCleanupFn)({
73
89
  passedInInstance: puppeteerInstance,
74
90
  browserExecutable,
@@ -108,7 +124,7 @@ const internalSelectComposition = async (options) => {
108
124
  chromiumOptions,
109
125
  envVariables,
110
126
  id,
111
- inputProps,
127
+ serializedInputPropsWithCustomSchema,
112
128
  onBrowserLog,
113
129
  timeoutInMilliseconds,
114
130
  logLevel,
@@ -143,7 +159,11 @@ const selectComposition = async (options) => {
143
159
  browserExecutable: browserExecutable !== null && browserExecutable !== void 0 ? browserExecutable : null,
144
160
  chromiumOptions: chromiumOptions !== null && chromiumOptions !== void 0 ? chromiumOptions : {},
145
161
  envVariables: envVariables !== null && envVariables !== void 0 ? envVariables : {},
146
- inputProps: inputProps !== null && inputProps !== void 0 ? inputProps : {},
162
+ serializedInputPropsWithCustomSchema: remotion_1.Internals.serializeJSONWithDate({
163
+ indent: undefined,
164
+ staticBase: null,
165
+ data: inputProps !== null && inputProps !== void 0 ? inputProps : {},
166
+ }).serializedString,
147
167
  onBrowserLog: onBrowserLog !== null && onBrowserLog !== void 0 ? onBrowserLog : null,
148
168
  port: port !== null && port !== void 0 ? port : null,
149
169
  puppeteerInstance,
@@ -0,0 +1,6 @@
1
+ import type { SerializedJSONWithCustomFields } from 'remotion';
2
+ export declare const serializeJSONWithDate: ({ data, indent, staticBase, }: {
3
+ data: Record<string, unknown>;
4
+ indent: number | undefined;
5
+ staticBase: string | null;
6
+ }) => SerializedJSONWithCustomFields;
@@ -0,0 +1,36 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.serializeJSONWithDate = void 0;
4
+ // Keep in sync with /packages/core/src/input-props-serialization.ts
5
+ const DATE_TOKEN = 'remotion-date:';
6
+ const FILE_TOKEN = 'remotion-file:';
7
+ const serializeJSONWithDate = ({ data, indent, staticBase, }) => {
8
+ let customDateUsed = false;
9
+ let customFileUsed = false;
10
+ let mapUsed = false;
11
+ let setUsed = false;
12
+ const serializedString = JSON.stringify(data, function (key, value) {
13
+ const item = this[key];
14
+ if (item instanceof Date) {
15
+ customDateUsed = true;
16
+ return `${DATE_TOKEN}${item.toISOString()}`;
17
+ }
18
+ if (item instanceof Map) {
19
+ mapUsed = true;
20
+ return value;
21
+ }
22
+ if (item instanceof Set) {
23
+ setUsed = true;
24
+ return value;
25
+ }
26
+ if (typeof item === 'string' &&
27
+ staticBase !== null &&
28
+ item.startsWith(staticBase)) {
29
+ customFileUsed = true;
30
+ return `${FILE_TOKEN}${item.replace(staticBase + '/', '')}`;
31
+ }
32
+ return value;
33
+ }, indent);
34
+ return { serializedString, customDateUsed, customFileUsed, mapUsed, setUsed };
35
+ };
36
+ exports.serializeJSONWithDate = serializeJSONWithDate;
@@ -1,6 +1,7 @@
1
1
  import type { Page } from './browser/BrowserPage';
2
+ import type { LogLevel } from './log-level';
2
3
  type SetPropsAndEnv = {
3
- inputProps: Record<string, unknown>;
4
+ serializedInputPropsWithCustomSchema: string;
4
5
  envVariables: Record<string, string> | undefined;
5
6
  page: Page;
6
7
  serveUrl: string;
@@ -10,6 +11,8 @@ type SetPropsAndEnv = {
10
11
  retriesRemaining: number;
11
12
  audioEnabled: boolean;
12
13
  videoEnabled: boolean;
14
+ indent: boolean;
15
+ logLevel: LogLevel;
13
16
  };
14
17
  export declare const setPropsAndEnv: (params: SetPropsAndEnv) => Promise<unknown>;
15
18
  export {};
@@ -7,7 +7,8 @@ const normalize_serve_url_1 = require("./normalize-serve-url");
7
7
  const puppeteer_evaluate_1 = require("./puppeteer-evaluate");
8
8
  const redirect_status_codes_1 = require("./redirect-status-codes");
9
9
  const validate_puppeteer_timeout_1 = require("./validate-puppeteer-timeout");
10
- const innerSetPropsAndEnv = async ({ inputProps, envVariables, page, serveUrl, initialFrame, timeoutInMilliseconds, proxyPort, retriesRemaining, audioEnabled, videoEnabled, }) => {
10
+ const logger_1 = require("./logger");
11
+ const innerSetPropsAndEnv = async ({ serializedInputPropsWithCustomSchema, envVariables, page, serveUrl, initialFrame, timeoutInMilliseconds, proxyPort, retriesRemaining, audioEnabled, videoEnabled, indent, logLevel, }) => {
11
12
  (0, validate_puppeteer_timeout_1.validatePuppeteerTimeout)(timeoutInMilliseconds);
12
13
  const actualTimeout = timeoutInMilliseconds !== null && timeoutInMilliseconds !== void 0 ? timeoutInMilliseconds : TimeoutSettings_1.DEFAULT_TIMEOUT;
13
14
  page.setDefaultTimeout(actualTimeout);
@@ -16,14 +17,9 @@ const innerSetPropsAndEnv = async ({ inputProps, envVariables, page, serveUrl, i
16
17
  await page.evaluateOnNewDocument((timeout) => {
17
18
  window.remotion_puppeteerTimeout = timeout;
18
19
  }, actualTimeout);
19
- if (typeof inputProps === 'string') {
20
- throw new Error('Input props should be an object, not a string.');
21
- }
22
- if (inputProps) {
23
- await page.evaluateOnNewDocument((input) => {
24
- window.remotion_inputProps = input;
25
- }, JSON.stringify(inputProps));
26
- }
20
+ await page.evaluateOnNewDocument((input) => {
21
+ window.remotion_inputProps = input;
22
+ }, serializedInputPropsWithCustomSchema);
27
23
  if (envVariables) {
28
24
  await page.evaluateOnNewDocument((input) => {
29
25
  window.remotion_envVariables = input;
@@ -57,7 +53,7 @@ const innerSetPropsAndEnv = async ({ inputProps, envVariables, page, serveUrl, i
57
53
  return innerSetPropsAndEnv({
58
54
  envVariables,
59
55
  initialFrame,
60
- inputProps,
56
+ serializedInputPropsWithCustomSchema,
61
57
  page,
62
58
  proxyPort,
63
59
  retriesRemaining: retriesRemaining - 1,
@@ -65,12 +61,14 @@ const innerSetPropsAndEnv = async ({ inputProps, envVariables, page, serveUrl, i
65
61
  timeoutInMilliseconds,
66
62
  audioEnabled,
67
63
  videoEnabled,
64
+ indent,
65
+ logLevel,
68
66
  });
69
67
  }
70
68
  if (!redirect_status_codes_1.redirectStatusCodes.every((code) => code !== status)) {
71
69
  throw new Error(`Error while getting compositions: Tried to go to ${urlToVisit} but the status code was ${status} instead of 200. Does the site you specified exist?`);
72
70
  }
73
- const isRemotionFn = await (0, puppeteer_evaluate_1.puppeteerEvaluateWithCatch)({
71
+ const { value: isRemotionFn } = await (0, puppeteer_evaluate_1.puppeteerEvaluateWithCatch)({
74
72
  pageFunction: () => {
75
73
  return window.getStaticCompositions;
76
74
  },
@@ -78,8 +76,23 @@ const innerSetPropsAndEnv = async ({ inputProps, envVariables, page, serveUrl, i
78
76
  frame: null,
79
77
  page,
80
78
  });
81
- if (isRemotionFn === undefined) {
82
- throw new Error(`Error while getting compositions: Tried to go to ${urlToVisit} and verify that it is a Remotion project by checking if window.getStaticCompositions is defined. However, the function was undefined, which indicates that this is not a valid Remotion project. Please check the URL you passed.`);
79
+ if (typeof isRemotionFn === 'undefined') {
80
+ const { value: body } = await (0, puppeteer_evaluate_1.puppeteerEvaluateWithCatch)({
81
+ pageFunction: () => {
82
+ return document.body.innerHTML;
83
+ },
84
+ args: [],
85
+ frame: null,
86
+ page,
87
+ });
88
+ const errorMessage = [
89
+ `Error while getting compositions: Tried to go to ${urlToVisit} and verify that it is a Remotion project by checking if window.getStaticCompositions is defined.`,
90
+ 'However, the function was undefined, which indicates that this is not a valid Remotion project. Please check the URL you passed.',
91
+ 'The page loaded contained the following markup:',
92
+ body.substring(0, 500) + (body.length > 500 ? '...' : ''),
93
+ 'Does this look like a foreign page? If so, try to stop this server.',
94
+ ].join('\n');
95
+ throw new Error(errorMessage);
83
96
  }
84
97
  const { value: siteVersion } = await (0, puppeteer_evaluate_1.puppeteerEvaluateWithCatch)({
85
98
  pageFunction: () => {
@@ -97,16 +110,22 @@ const innerSetPropsAndEnv = async ({ inputProps, envVariables, page, serveUrl, i
97
110
  frame: null,
98
111
  page,
99
112
  });
100
- const requiredVersion = '6';
113
+ const requiredVersion = '8';
101
114
  if (siteVersion !== requiredVersion) {
102
115
  throw new Error(`Incompatible site: When visiting ${urlToVisit}, a bundle was found, but one that is not compatible with this version of Remotion. Found version: ${siteVersion} - Required version: ${requiredVersion}. To resolve this error, please bundle and deploy again.`);
103
116
  }
104
117
  if (remotionVersion !== version_1.VERSION && process.env.NODE_ENV !== 'test') {
105
118
  if (remotionVersion) {
106
- console.warn(`The site was bundled with version ${remotionVersion} of @remotion/bundler, while @remotion/renderer is on version ${version_1.VERSION}. You may not have the newest bugfixes and features. Re-bundle the site to fix this issue.`);
119
+ logger_1.Log.warnAdvanced({
120
+ indent,
121
+ logLevel,
122
+ }, `The site was bundled with version ${remotionVersion} of @remotion/bundler, while @remotion/renderer is on version ${version_1.VERSION}. You may not have the newest bugfixes and features. Re-bundle the site to fix this issue.`);
107
123
  }
108
124
  else {
109
- console.warn(`The site was bundled with an old version of Remotion, while @remotion/renderer is on version ${version_1.VERSION}. You may not have the newest bugfixes and features. Re-bundle the site to fix this issue.`);
125
+ logger_1.Log.warnAdvanced({
126
+ indent,
127
+ logLevel,
128
+ }, `The site was bundled with an old version of Remotion, while @remotion/renderer is on version ${version_1.VERSION}. You may not have the newest bugfixes and features. Re-bundle the site to fix this issue.`);
110
129
  }
111
130
  }
112
131
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@remotion/renderer",
3
- "version": "4.1.0-alpha5",
3
+ "version": "4.1.0-alpha8",
4
4
  "description": "Renderer for Remotion",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -18,7 +18,7 @@
18
18
  "extract-zip": "2.0.1",
19
19
  "source-map": "^0.8.0-beta.0",
20
20
  "ws": "8.7.0",
21
- "remotion": "4.1.0-alpha5"
21
+ "remotion": "4.1.0-alpha8"
22
22
  },
23
23
  "peerDependencies": {
24
24
  "react": ">=16.8.0",
@@ -42,13 +42,13 @@
42
42
  "zod": "^3.21.4"
43
43
  },
44
44
  "optionalDependencies": {
45
- "@remotion/compositor-darwin-arm64": "4.1.0-alpha5",
46
- "@remotion/compositor-darwin-x64": "4.1.0-alpha5",
47
- "@remotion/compositor-linux-x64-gnu": "4.1.0-alpha5",
48
- "@remotion/compositor-linux-arm64-gnu": "4.1.0-alpha5",
49
- "@remotion/compositor-linux-arm64-musl": "4.1.0-alpha5",
50
- "@remotion/compositor-linux-x64-musl": "4.1.0-alpha5",
51
- "@remotion/compositor-win32-x64-msvc": "4.1.0-alpha5"
45
+ "@remotion/compositor-linux-arm64-musl": "4.1.0-alpha8",
46
+ "@remotion/compositor-darwin-x64": "4.1.0-alpha8",
47
+ "@remotion/compositor-linux-x64-musl": "4.1.0-alpha8",
48
+ "@remotion/compositor-linux-x64-gnu": "4.1.0-alpha8",
49
+ "@remotion/compositor-win32-x64-msvc": "4.1.0-alpha8",
50
+ "@remotion/compositor-darwin-arm64": "4.1.0-alpha8",
51
+ "@remotion/compositor-linux-arm64-gnu": "4.1.0-alpha8"
52
52
  },
53
53
  "keywords": [
54
54
  "remotion",