@remotion/renderer 4.0.20 → 4.0.22

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.
@@ -56,6 +56,7 @@ const fs = __importStar(require("node:fs"));
56
56
  const readline = __importStar(require("readline"));
57
57
  const delete_directory_1 = require("../delete-directory");
58
58
  const logger_1 = require("../logger");
59
+ const truthy_1 = require("../truthy");
59
60
  const assert_1 = require("./assert");
60
61
  const Connection_1 = require("./Connection");
61
62
  const Errors_1 = require("./Errors");
@@ -230,17 +231,19 @@ function waitForWSEndpoint(browserProcess, timeout) {
230
231
  function onClose(error) {
231
232
  cleanup();
232
233
  reject(new Error([
233
- 'Failed to launch the browser process!' +
234
- (error ? ' ' + error.message : ''),
234
+ 'Failed to launch the browser process!',
235
+ error ? error.message : null,
235
236
  stderr,
236
237
  '',
237
238
  'TROUBLESHOOTING: https://github.com/puppeteer/puppeteer/blob/main/docs/troubleshooting.md',
238
239
  '',
239
- ].join('\n')));
240
+ ]
241
+ .filter(truthy_1.truthy)
242
+ .join('\n')));
240
243
  }
241
244
  function onTimeout() {
242
245
  cleanup();
243
- reject(new Errors_1.TimeoutError(`Timed out after ${timeout} ms while trying to connect to the browser!`));
246
+ reject(new Errors_1.TimeoutError(`Timed out after ${timeout} ms while trying to connect to the browser! Chrome logged the following: ${stderr}`));
244
247
  }
245
248
  function onLine(line) {
246
249
  stderr += line + '\n';
package/dist/client.d.ts CHANGED
@@ -6,6 +6,7 @@ export declare const BrowserSafeApis: {
6
6
  getValidCrfRanges: (codec: "h264" | "h265" | "vp8" | "vp9" | "mp3" | "aac" | "wav" | "prores" | "h264-mkv" | "gif") => [number, number];
7
7
  isAudioCodec: (codec: "h264" | "h265" | "vp8" | "vp9" | "mp3" | "aac" | "wav" | "prores" | "h264-mkv" | "gif" | undefined) => boolean;
8
8
  proResProfileOptions: readonly ["4444-xq", "4444", "hq", "standard", "light", "proxy"];
9
+ x264PresetOptions: readonly ["ultrafast", "superfast", "veryfast", "faster", "fast", "medium", "slow", "slower", "veryslow", "placebo"];
9
10
  validPixelFormats: readonly ["yuv420p", "yuva420p", "yuv422p", "yuv444p", "yuv420p10le", "yuv422p10le", "yuv444p10le", "yuva444p10le"];
10
11
  DEFAULT_PIXEL_FORMAT: "yuv420p" | "yuva420p" | "yuv422p" | "yuv444p" | "yuv420p10le" | "yuv422p10le" | "yuv444p10le" | "yuva444p10le";
11
12
  supportedAudioCodecs: {
package/dist/client.js CHANGED
@@ -19,6 +19,7 @@ const video_codec_1 = require("./options/video-codec");
19
19
  const pixel_format_1 = require("./pixel-format");
20
20
  const prores_profile_1 = require("./prores-profile");
21
21
  const validate_output_filename_1 = require("./validate-output-filename");
22
+ const x264_preset_1 = require("./x264-preset");
22
23
  exports.BrowserSafeApis = {
23
24
  getFileExtensionFromCodec: get_extension_from_codec_1.getFileExtensionFromCodec,
24
25
  validCodecs: codec_1.validCodecs,
@@ -27,6 +28,7 @@ exports.BrowserSafeApis = {
27
28
  getValidCrfRanges: crf_1.getValidCrfRanges,
28
29
  isAudioCodec: is_audio_codec_1.isAudioCodec,
29
30
  proResProfileOptions: prores_profile_1.proResProfileOptions,
31
+ x264PresetOptions: x264_preset_1.x264PresetOptions,
30
32
  validPixelFormats: pixel_format_1.validPixelFormats,
31
33
  DEFAULT_PIXEL_FORMAT: pixel_format_1.DEFAULT_PIXEL_FORMAT,
32
34
  supportedAudioCodecs: audio_codec_1.supportedAudioCodecs,
@@ -75,6 +75,9 @@ export type CompositorCommand = {
75
75
  maximum_frame_cache_items: number;
76
76
  verbose: boolean;
77
77
  };
78
+ CopyImageToClipboard: {
79
+ src: string;
80
+ };
78
81
  GetOpenVideoStats: {};
79
82
  DeliberatePanic: {};
80
83
  CloseAllVideos: {};
@@ -0,0 +1,2 @@
1
+ import type { LogLevel } from './log-level';
2
+ export declare const copyImageToClipboard: (src: string, logLevel: LogLevel) => Promise<void>;
@@ -0,0 +1,13 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.copyImageToClipboard = void 0;
4
+ const compositor_1 = require("./compositor/compositor");
5
+ const copyImageToClipboard = async (src, logLevel) => {
6
+ const compositor = (0, compositor_1.startLongRunningCompositor)((0, compositor_1.getIdealMaximumFrameCacheItems)(), logLevel, false);
7
+ await compositor.executeCommand('CopyImageToClipboard', {
8
+ src,
9
+ });
10
+ compositor.finishCommands();
11
+ await compositor.waitForDone();
12
+ };
13
+ exports.copyImageToClipboard = copyImageToClipboard;
package/dist/index.d.ts CHANGED
@@ -37,6 +37,7 @@ export { SymbolicatedStackFrame } from './symbolicate-stacktrace';
37
37
  export { OnStartData, RenderFramesOutput } from './types';
38
38
  export { OpenGlRenderer } from './validate-opengl-renderer';
39
39
  export { validateOutputFilename } from './validate-output-filename';
40
+ export { X264Preset } from './x264-preset';
40
41
  export declare const RenderInternals: {
41
42
  ensureLocalBrowser: (preferredBrowserExecutable: import("./browser-executable").BrowserExecutable) => Promise<void>;
42
43
  getActualConcurrency: (userPreference: string | number | null) => number;
@@ -115,8 +116,8 @@ export declare const RenderInternals: {
115
116
  validPixelFormats: readonly ["yuv420p", "yuva420p", "yuv422p", "yuv444p", "yuv420p10le", "yuv422p10le", "yuv444p10le", "yuva444p10le"];
116
117
  DEFAULT_BROWSER: "chrome";
117
118
  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;
119
+ DEFAULT_OPENGL_RENDERER: "angle" | "swangle" | "egl" | "swiftshader" | null;
120
+ validateOpenGlRenderer: (option: "angle" | "swangle" | "egl" | "swiftshader" | null) => "angle" | "swangle" | "egl" | "swiftshader" | null;
120
121
  validCodecs: readonly ["h264", "h265", "vp8", "vp9", "mp3", "aac", "wav", "prores", "h264-mkv", "gif"];
121
122
  DEFAULT_PIXEL_FORMAT: "yuv420p" | "yuva420p" | "yuv422p" | "yuv444p" | "yuv420p10le" | "yuv422p10le" | "yuv444p10le" | "yuva444p10le";
122
123
  validateJpegQuality: (q: number | undefined) => void;
@@ -304,8 +305,8 @@ export declare const RenderInternals: {
304
305
  };
305
306
  validStillImageFormats: readonly ["png", "jpeg", "pdf", "webp"];
306
307
  validVideoImageFormats: readonly ["png", "jpeg", "none"];
307
- DEFAULT_STILL_IMAGE_FORMAT: "png" | "jpeg" | "pdf" | "webp";
308
- DEFAULT_VIDEO_IMAGE_FORMAT: "none" | "png" | "jpeg";
308
+ DEFAULT_STILL_IMAGE_FORMAT: "jpeg" | "png" | "webp" | "pdf";
309
+ DEFAULT_VIDEO_IMAGE_FORMAT: "jpeg" | "png" | "none";
309
310
  DEFAULT_JPEG_QUALITY: number;
310
311
  chalk: {
311
312
  enabled: () => boolean;
@@ -416,7 +417,7 @@ export declare const RenderInternals: {
416
417
  frame: number;
417
418
  serializedInputPropsWithCustomSchema: string;
418
419
  serializedResolvedPropsWithCustomSchema: string;
419
- imageFormat: "png" | "jpeg" | "pdf" | "webp";
420
+ imageFormat: "jpeg" | "png" | "webp" | "pdf";
420
421
  jpegQuality: number;
421
422
  puppeteerInstance: HeadlessBrowser | null;
422
423
  envVariables: Record<string, string>;
@@ -478,9 +479,10 @@ export declare const RenderInternals: {
478
479
  serveUrlOrWebpackUrl: string;
479
480
  }) => Promise<import("remotion").VideoConfig[]>;
480
481
  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>;
481
- 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<{
482
+ internalRenderMedia: ({ proResProfile, x264Preset, 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<{
482
483
  buffer: Buffer | null;
483
484
  slowestFrames: import("./render-media").SlowFrame[];
484
485
  }>;
485
486
  validOpenGlRenderers: readonly ["swangle", "angle", "egl", "swiftshader"];
487
+ copyImageToClipboard: (src: string, logLevel: "verbose" | "info" | "warn" | "error") => Promise<void>;
486
488
  };
package/dist/index.js CHANGED
@@ -42,6 +42,7 @@ const codec_1 = require("./codec");
42
42
  const combine_videos_1 = require("./combine-videos");
43
43
  const get_executable_path_1 = require("./compositor/get-executable-path");
44
44
  const convert_to_positive_frame_index_1 = require("./convert-to-positive-frame-index");
45
+ const copy_to_clipboard_1 = require("./copy-to-clipboard");
45
46
  const delete_directory_1 = require("./delete-directory");
46
47
  const ensure_output_directory_1 = require("./ensure-output-directory");
47
48
  const symbolicate_error_1 = require("./error-handling/symbolicate-error");
@@ -187,6 +188,7 @@ exports.RenderInternals = {
187
188
  internalRenderFrames: render_frames_1.internalRenderFrames,
188
189
  internalRenderMedia: render_media_1.internalRenderMedia,
189
190
  validOpenGlRenderers: validate_opengl_renderer_1.validOpenGlRenderers,
191
+ copyImageToClipboard: copy_to_clipboard_1.copyImageToClipboard,
190
192
  };
191
193
  // Warn of potential performance issues with Apple Silicon (M1 chip under Rosetta)
192
194
  (0, check_apple_silicon_1.checkNodeVersionAndWarnAboutRosetta)();
@@ -67,6 +67,9 @@ const startOffthreadVideoServer = ({ downloadMap, concurrency, logLevel, indent,
67
67
  else {
68
68
  response.setHeader('content-type', `image/bmp`);
69
69
  }
70
+ // Prevent caching of the response and excessive disk writes
71
+ // https://github.com/remotion-dev/remotion/issues/2760
72
+ response.setHeader('cache-control', 'no-cache, no-store, must-revalidate');
70
73
  // Handling this case on Lambda:
71
74
  // https://support.google.com/chrome/a/answer/7679408?hl=en
72
75
  // Chrome sends Private Network Access preflights for subresources
@@ -0,0 +1,7 @@
1
+ import type { Codec } from './codec';
2
+ export declare const presetsProfileOptions: readonly ["ultrafast", "superfast", "veryfast", "faster", "fast", "medium", "slow", "slower", "veryslow", "placebo"];
3
+ export type PresetsProfile = typeof presetsProfileOptions[number];
4
+ export declare const validateSelectedCodecAndPresetCombination: ({ codec, presetsProfile, }: {
5
+ codec: Codec;
6
+ presetsProfile: PresetsProfile | undefined;
7
+ }) => void;
@@ -0,0 +1,27 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.validateSelectedCodecAndPresetCombination = exports.presetsProfileOptions = void 0;
4
+ exports.presetsProfileOptions = [
5
+ 'ultrafast',
6
+ 'superfast',
7
+ 'veryfast',
8
+ 'faster',
9
+ 'fast',
10
+ 'medium',
11
+ 'slow',
12
+ 'slower',
13
+ 'veryslow',
14
+ 'placebo',
15
+ ];
16
+ const validateSelectedCodecAndPresetCombination = ({ codec, presetsProfile, }) => {
17
+ if (typeof presetsProfile !== 'undefined' && codec !== 'h264') {
18
+ throw new TypeError(`You have set a Preset profile but the codec is "${codec}". Set the codec to "h264" or remove the Preset profile.`);
19
+ }
20
+ if (presetsProfile !== undefined &&
21
+ !exports.presetsProfileOptions.includes(presetsProfile)) {
22
+ throw new TypeError(`The Preset profile "${presetsProfile}" is not valid. Valid options are ${exports.presetsProfileOptions
23
+ .map((p) => `"${p}"`)
24
+ .join(', ')}`);
25
+ }
26
+ };
27
+ exports.validateSelectedCodecAndPresetCombination = validateSelectedCodecAndPresetCombination;
@@ -16,6 +16,7 @@ import type { PixelFormat } from './pixel-format';
16
16
  import type { RemotionServer } from './prepare-server';
17
17
  import type { ProResProfile } from './prores-profile';
18
18
  import type { OnStartData } from './types';
19
+ import type { X264Preset } from './x264-preset';
19
20
  export type StitchingState = 'encoding' | 'muxing';
20
21
  export type SlowFrame = {
21
22
  frame: number;
@@ -48,6 +49,7 @@ export type InternalRenderMediaOptions = {
48
49
  onProgress: RenderMediaOnProgress;
49
50
  onDownload: RenderMediaOnDownload;
50
51
  proResProfile: ProResProfile | undefined;
52
+ x264Preset: X264Preset | undefined;
51
53
  onBrowserLog: ((log: BrowserLog) => void) | null;
52
54
  onStart: (data: OnStartData) => void;
53
55
  timeoutInMilliseconds: number;
@@ -93,6 +95,7 @@ export type RenderMediaOptions = {
93
95
  onProgress?: RenderMediaOnProgress;
94
96
  onDownload?: RenderMediaOnDownload;
95
97
  proResProfile?: ProResProfile;
98
+ x264Preset?: X264Preset;
96
99
  /**
97
100
  * @deprecated Use "logLevel": "verbose" instead
98
101
  */
@@ -125,11 +128,11 @@ type RenderMediaResult = {
125
128
  buffer: Buffer | null;
126
129
  slowestFrames: SlowFrame[];
127
130
  };
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>;
131
+ export declare const internalRenderMedia: ({ proResProfile, x264Preset, 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>;
129
132
  /**
130
133
  *
131
134
  * @description Render a video from a composition
132
135
  * @see [Documentation](https://www.remotion.dev/docs/renderer/render-media)
133
136
  */
134
- export declare const renderMedia: ({ 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, jpegQuality, concurrency, serveUrl, disallowParallelEncoding, everyNthFrame, imageFormat, numberOfGifLoops, dumpBrowserLogs, preferLossless, verbose, quality, logLevel, }: RenderMediaOptions) => Promise<RenderMediaResult>;
137
+ export declare const renderMedia: ({ proResProfile, x264Preset, 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, jpegQuality, concurrency, serveUrl, disallowParallelEncoding, everyNthFrame, imageFormat, numberOfGifLoops, dumpBrowserLogs, preferLossless, verbose, quality, logLevel, }: RenderMediaOptions) => Promise<RenderMediaResult>;
135
138
  export {};
@@ -42,8 +42,9 @@ const validate_number_of_gif_loops_1 = require("./validate-number-of-gif-loops")
42
42
  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
+ const x264_preset_1 = require("./x264-preset");
45
46
  const SLOWEST_FRAME_COUNT = 10;
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
+ const internalRenderMedia = ({ proResProfile, x264Preset, 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
48
  (0, jpeg_quality_1.validateJpegQuality)(jpegQuality);
48
49
  (0, crf_1.validateQualitySettings)({ crf, codec, videoBitrate });
49
50
  (0, validate_videobitrate_1.validateBitrate)(audioBitrate, 'audioBitrate');
@@ -52,6 +53,10 @@ const internalRenderMedia = ({ proResProfile, crf, composition, serializedInputP
52
53
  codec,
53
54
  proResProfile,
54
55
  });
56
+ (0, x264_preset_1.validateSelectedCodecAndPresetCombination)({
57
+ codec,
58
+ x264Preset,
59
+ });
55
60
  (0, pixel_format_1.validateSelectedPixelFormatAndCodecCombination)(pixelFormat, codec);
56
61
  if (outputLocation) {
57
62
  (0, validate_output_filename_1.validateOutputFilename)({
@@ -346,6 +351,7 @@ const internalRenderMedia = ({ proResProfile, crf, composition, serializedInputP
346
351
  audioBitrate,
347
352
  videoBitrate,
348
353
  audioCodec,
354
+ x264Preset: x264Preset !== null && x264Preset !== void 0 ? x264Preset : null,
349
355
  }),
350
356
  stitchStart,
351
357
  ]);
@@ -411,13 +417,14 @@ exports.internalRenderMedia = internalRenderMedia;
411
417
  * @description Render a video from a composition
412
418
  * @see [Documentation](https://www.remotion.dev/docs/renderer/render-media)
413
419
  */
414
- const renderMedia = ({ 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, jpegQuality, concurrency, serveUrl, disallowParallelEncoding, everyNthFrame, imageFormat, numberOfGifLoops, dumpBrowserLogs, preferLossless, verbose, quality, logLevel, }) => {
420
+ const renderMedia = ({ proResProfile, x264Preset, 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, jpegQuality, concurrency, serveUrl, disallowParallelEncoding, everyNthFrame, imageFormat, numberOfGifLoops, dumpBrowserLogs, preferLossless, verbose, quality, logLevel, }) => {
415
421
  var _a, _b;
416
422
  if (quality !== undefined) {
417
423
  console.warn(`The "quality" option has been renamed. Please use "jpegQuality" instead.`);
418
424
  }
419
425
  return (0, exports.internalRenderMedia)({
420
426
  proResProfile: proResProfile !== null && proResProfile !== void 0 ? proResProfile : undefined,
427
+ x264Preset,
421
428
  codec,
422
429
  composition,
423
430
  serveUrl,
@@ -8,6 +8,7 @@ import type { LogLevel } from './log-level';
8
8
  import type { CancelSignal } from './make-cancel-signal';
9
9
  import type { PixelFormat } from './pixel-format';
10
10
  import type { ProResProfile } from './prores-profile';
11
+ import type { X264Preset } from './x264-preset';
11
12
  type InternalStitchFramesToVideoOptions = {
12
13
  audioBitrate: string | null;
13
14
  videoBitrate: string | null;
@@ -32,6 +33,7 @@ type InternalStitchFramesToVideoOptions = {
32
33
  preferLossless: boolean;
33
34
  indent: boolean;
34
35
  muted: boolean;
36
+ x264Preset: X264Preset | null;
35
37
  enforceAudioTrack: boolean;
36
38
  ffmpegOverride: null | FfmpegOverrideFn;
37
39
  };
@@ -58,11 +60,12 @@ export type StitchFramesToVideoOptions = {
58
60
  muted?: boolean;
59
61
  enforceAudioTrack?: boolean;
60
62
  ffmpegOverride?: FfmpegOverrideFn;
63
+ x264Preset?: X264Preset | null;
61
64
  };
62
65
  export declare const internalStitchFramesToVideo: (options: InternalStitchFramesToVideoOptions) => Promise<Buffer | null>;
63
66
  /**
64
67
  * @description Takes a series of images and audio information generated by renderFrames() and encodes it to a video.
65
68
  * @see [Documentation](https://www.remotion.dev/docs/renderer/stitch-frames-to-video)
66
69
  */
67
- export declare const stitchFramesToVideo: ({ assetsInfo, force, fps, height, width, audioBitrate, audioCodec, cancelSignal, codec, crf, dir, enforceAudioTrack, ffmpegOverride, muted, numberOfGifLoops, onDownload, onProgress, outputLocation, pixelFormat, proResProfile, verbose, videoBitrate, }: StitchFramesToVideoOptions) => Promise<Buffer | null>;
70
+ export declare const stitchFramesToVideo: ({ assetsInfo, force, fps, height, width, audioBitrate, audioCodec, cancelSignal, codec, crf, dir, enforceAudioTrack, ffmpegOverride, muted, numberOfGifLoops, onDownload, onProgress, outputLocation, pixelFormat, proResProfile, verbose, videoBitrate, x264Preset, }: StitchFramesToVideoOptions) => Promise<Buffer | null>;
68
71
  export {};
@@ -100,7 +100,7 @@ const getAssetsData = async ({ assets, onDownload, fps, expectedFrames, logLevel
100
100
  });
101
101
  return outName;
102
102
  };
103
- const innerStitchFramesToVideo = async ({ assetsInfo, audioBitrate, audioCodec, cancelSignal, codec, crf, dir, enforceAudioTrack, ffmpegOverride, force, fps, height, indent, muted, onDownload, outputLocation, pixelFormat, preEncodedFileLocation, preferLossless, proResProfile, logLevel, videoBitrate, width, numberOfGifLoops, onProgress, }, remotionRoot) => {
103
+ const innerStitchFramesToVideo = async ({ assetsInfo, audioBitrate, audioCodec, cancelSignal, codec, crf, dir, enforceAudioTrack, ffmpegOverride, force, fps, height, indent, muted, onDownload, outputLocation, pixelFormat, preEncodedFileLocation, preferLossless, proResProfile, logLevel, videoBitrate, width, numberOfGifLoops, onProgress, x264Preset, }, remotionRoot) => {
104
104
  var _a;
105
105
  remotion_1.Internals.validateDimension(height, 'height', 'passed to `stitchFramesToVideo()`');
106
106
  remotion_1.Internals.validateDimension(width, 'width', 'passed to `stitchFramesToVideo()`');
@@ -256,6 +256,7 @@ const innerStitchFramesToVideo = async ({ assetsInfo, audioBitrate, audioCodec,
256
256
  codec,
257
257
  }),
258
258
  ]),
259
+ x264Preset ? ['-preset', x264Preset] : null,
259
260
  codec === 'h264' ? ['-movflags', 'faststart'] : null,
260
261
  resolvedAudioCodec
261
262
  ? ['-c:a', (0, audio_codec_1.mapAudioCodecToFfmpegAudioCodecName)(resolvedAudioCodec)]
@@ -359,7 +360,7 @@ exports.internalStitchFramesToVideo = internalStitchFramesToVideo;
359
360
  * @description Takes a series of images and audio information generated by renderFrames() and encodes it to a video.
360
361
  * @see [Documentation](https://www.remotion.dev/docs/renderer/stitch-frames-to-video)
361
362
  */
362
- const stitchFramesToVideo = ({ assetsInfo, force, fps, height, width, audioBitrate, audioCodec, cancelSignal, codec, crf, dir, enforceAudioTrack, ffmpegOverride, muted, numberOfGifLoops, onDownload, onProgress, outputLocation, pixelFormat, proResProfile, verbose, videoBitrate, }) => {
363
+ const stitchFramesToVideo = ({ assetsInfo, force, fps, height, width, audioBitrate, audioCodec, cancelSignal, codec, crf, dir, enforceAudioTrack, ffmpegOverride, muted, numberOfGifLoops, onDownload, onProgress, outputLocation, pixelFormat, proResProfile, verbose, videoBitrate, x264Preset, }) => {
363
364
  return (0, exports.internalStitchFramesToVideo)({
364
365
  assetsInfo,
365
366
  audioBitrate: audioBitrate !== null && audioBitrate !== void 0 ? audioBitrate : null,
@@ -386,6 +387,7 @@ const stitchFramesToVideo = ({ assetsInfo, force, fps, height, width, audioBitra
386
387
  width,
387
388
  preEncodedFileLocation: null,
388
389
  preferLossless: false,
390
+ x264Preset: x264Preset !== null && x264Preset !== void 0 ? x264Preset : null,
389
391
  });
390
392
  };
391
393
  exports.stitchFramesToVideo = stitchFramesToVideo;
@@ -0,0 +1,7 @@
1
+ import type { Codec } from './codec';
2
+ export declare const x264PresetOptions: readonly ["ultrafast", "superfast", "veryfast", "faster", "fast", "medium", "slow", "slower", "veryslow", "placebo"];
3
+ export type X264Preset = typeof x264PresetOptions[number];
4
+ export declare const validateSelectedCodecAndPresetCombination: ({ codec, x264Preset, }: {
5
+ codec: Codec;
6
+ x264Preset: X264Preset | undefined;
7
+ }) => void;
@@ -0,0 +1,29 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.validateSelectedCodecAndPresetCombination = exports.x264PresetOptions = void 0;
4
+ exports.x264PresetOptions = [
5
+ 'ultrafast',
6
+ 'superfast',
7
+ 'veryfast',
8
+ 'faster',
9
+ 'fast',
10
+ 'medium',
11
+ 'slow',
12
+ 'slower',
13
+ 'veryslow',
14
+ 'placebo',
15
+ ];
16
+ const validateSelectedCodecAndPresetCombination = ({ codec, x264Preset, }) => {
17
+ if (typeof x264Preset !== 'undefined' &&
18
+ codec !== 'h264' &&
19
+ codec !== 'h264-mkv') {
20
+ throw new TypeError(`You have set a x264 preset but the codec is "${codec}". Set the codec to "h264" or remove the Preset profile.`);
21
+ }
22
+ if (x264Preset !== undefined &&
23
+ !exports.x264PresetOptions.includes(x264Preset)) {
24
+ throw new TypeError(`The Preset profile "${x264Preset}" is not valid. Valid options are ${exports.x264PresetOptions
25
+ .map((p) => `"${p}"`)
26
+ .join(', ')}`);
27
+ }
28
+ };
29
+ exports.validateSelectedCodecAndPresetCombination = validateSelectedCodecAndPresetCombination;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@remotion/renderer",
3
- "version": "4.0.20",
3
+ "version": "4.0.22",
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.0.20"
21
+ "remotion": "4.0.22"
22
22
  },
23
23
  "peerDependencies": {
24
24
  "react": ">=16.8.0",
@@ -41,13 +41,13 @@
41
41
  "zod": "^3.21.4"
42
42
  },
43
43
  "optionalDependencies": {
44
- "@remotion/compositor-darwin-arm64": "4.0.20",
45
- "@remotion/compositor-linux-x64-gnu": "4.0.20",
46
- "@remotion/compositor-linux-x64-musl": "4.0.20",
47
- "@remotion/compositor-win32-x64-msvc": "4.0.20",
48
- "@remotion/compositor-linux-arm64-musl": "4.0.20",
49
- "@remotion/compositor-darwin-x64": "4.0.20",
50
- "@remotion/compositor-linux-arm64-gnu": "4.0.20"
44
+ "@remotion/compositor-darwin-x64": "4.0.22",
45
+ "@remotion/compositor-linux-arm64-gnu": "4.0.22",
46
+ "@remotion/compositor-darwin-arm64": "4.0.22",
47
+ "@remotion/compositor-linux-arm64-musl": "4.0.22",
48
+ "@remotion/compositor-linux-x64-gnu": "4.0.22",
49
+ "@remotion/compositor-linux-x64-musl": "4.0.22",
50
+ "@remotion/compositor-win32-x64-msvc": "4.0.22"
51
51
  },
52
52
  "keywords": [
53
53
  "remotion",