@remotion/renderer 4.0.278 → 4.0.279

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.
@@ -45,7 +45,6 @@ const calculateAssetPositions = (frames) => {
45
45
  trimLeft: asset.mediaFrame,
46
46
  volume: [],
47
47
  playbackRate: asset.playbackRate,
48
- allowAmplificationDuringRender: asset.allowAmplificationDuringRender,
49
48
  toneFrequency: asset.toneFrequency,
50
49
  audioStartFrame: asset.audioStartFrame,
51
50
  });
@@ -4,10 +4,9 @@ type FfmpegVolumeExpression = {
4
4
  eval: FfmpegEval;
5
5
  value: string;
6
6
  };
7
- export declare const ffmpegVolumeExpression: ({ volume, fps, trimLeft, allowAmplificationDuringRender, }: {
7
+ export declare const ffmpegVolumeExpression: ({ volume, fps, trimLeft, }: {
8
8
  volume: AssetVolume;
9
9
  trimLeft: number;
10
10
  fps: number;
11
- allowAmplificationDuringRender: boolean;
12
11
  }) => FfmpegVolumeExpression;
13
12
  export {};
@@ -43,14 +43,13 @@ const ffmpegBuildVolumeExpression = ({ arr, delay, fps, }) => {
43
43
  const [volume, frames] = first;
44
44
  return ffmpegIfOrElse(ffmpegIsOneOfFrames({ frames, trimLeft: delay, fps }), String(volume), ffmpegBuildVolumeExpression({ arr: rest, delay, fps }));
45
45
  };
46
- const ffmpegVolumeExpression = ({ volume, fps, trimLeft, allowAmplificationDuringRender, }) => {
47
- const maxVolume = allowAmplificationDuringRender ? Infinity : 1;
46
+ const ffmpegVolumeExpression = ({ volume, fps, trimLeft, }) => {
48
47
  // If it's a static volume, we return it and tell
49
48
  // FFMPEG it only has to evaluate it once
50
49
  if (typeof volume === 'number') {
51
50
  return {
52
51
  eval: 'once',
53
- value: String(Math.min(maxVolume, volume)),
52
+ value: String(volume),
54
53
  };
55
54
  }
56
55
  if ([...new Set(volume)].length === 1) {
@@ -58,7 +57,6 @@ const ffmpegVolumeExpression = ({ volume, fps, trimLeft, allowAmplificationDurin
58
57
  volume: volume[0],
59
58
  fps,
60
59
  trimLeft,
61
- allowAmplificationDuringRender,
62
60
  });
63
61
  }
64
62
  // A 1 sec video with frames 0-29 would mean that
@@ -73,7 +71,7 @@ const ffmpegVolumeExpression = ({ volume, fps, trimLeft, allowAmplificationDurin
73
71
  const volumeMap = {};
74
72
  paddedVolume.forEach((baseVolume, frame) => {
75
73
  // Adjust volume based on how many other tracks have not yet finished
76
- const actualVolume = (0, round_volume_to_avoid_stack_overflow_1.roundVolumeToAvoidStackOverflow)(Math.min(maxVolume, baseVolume));
74
+ const actualVolume = (0, round_volume_to_avoid_stack_overflow_1.roundVolumeToAvoidStackOverflow)(baseVolume);
77
75
  if (!volumeMap[actualVolume]) {
78
76
  volumeMap[actualVolume] = [];
79
77
  }
@@ -6,7 +6,6 @@ export type UnsafeAsset = Omit<AudioOrVideoAsset, 'frame' | 'id' | 'volume' | 'm
6
6
  volume: number[];
7
7
  id: string;
8
8
  playbackRate: number;
9
- allowAmplificationDuringRender: boolean;
10
9
  toneFrequency: number | null;
11
10
  };
12
11
  export type AssetVolume = number | number[];
@@ -0,0 +1,4 @@
1
+ import type { Codec } from './codec';
2
+ import type { AudioCodec } from './options/audio-codec';
3
+ export declare const canConcatAudioSeamlessly: (audioCodec: AudioCodec | null, chunkDurationInFrames: number) => boolean;
4
+ export declare const canConcatVideoSeamlessly: (codec: Codec) => codec is "h264";
@@ -0,0 +1,17 @@
1
+ "use strict";
2
+ // Cannot do WAV yet, because currently assumes AAC in+outpoint
3
+ Object.defineProperty(exports, "__esModule", { value: true });
4
+ exports.canConcatVideoSeamlessly = exports.canConcatAudioSeamlessly = void 0;
5
+ const canConcatAudioSeamlessly = (audioCodec, chunkDurationInFrames) => {
6
+ // Rendering a chunk that is too small generates too much overhead
7
+ // and is currently buggy
8
+ if (chunkDurationInFrames <= 4) {
9
+ return false;
10
+ }
11
+ return audioCodec === 'aac';
12
+ };
13
+ exports.canConcatAudioSeamlessly = canConcatAudioSeamlessly;
14
+ const canConcatVideoSeamlessly = (codec) => {
15
+ return codec === 'h264';
16
+ };
17
+ exports.canConcatVideoSeamlessly = canConcatVideoSeamlessly;
package/dist/client.d.ts CHANGED
@@ -412,7 +412,7 @@ export declare const BrowserSafeApis: {
412
412
  webhookCustomDataOption: {
413
413
  name: string;
414
414
  cliFlag: "webhook-custom-data";
415
- description: (type: "ssr" | "cli") => import("react/jsx-runtime").JSX.Element;
415
+ description: (type: "cli" | "ssr") => import("react/jsx-runtime").JSX.Element;
416
416
  ssrName: "customData";
417
417
  docLink: string;
418
418
  type: Record<string, unknown> | null;
@@ -825,7 +825,7 @@ export declare const BrowserSafeApis: {
825
825
  metadataOption: {
826
826
  name: string;
827
827
  cliFlag: "metadata";
828
- description: (mode: "ssr" | "cli") => import("react/jsx-runtime").JSX.Element;
828
+ description: (mode: "cli" | "ssr") => import("react/jsx-runtime").JSX.Element;
829
829
  docLink: string;
830
830
  type: import("./options/metadata").Metadata;
831
831
  getValue: ({ commandLine }: {
@@ -0,0 +1,39 @@
1
+ import type { Codec } from './codec';
2
+ import type { FrameRange } from './frame-range';
3
+ import type { LogLevel } from './log-level';
4
+ import type { CancelSignal } from './make-cancel-signal';
5
+ import type { AudioCodec } from './options/audio-codec';
6
+ type MandatoryCombineChunksOptions = {
7
+ outputLocation: string;
8
+ audioFiles: string[];
9
+ codec: Codec;
10
+ videoFiles: string[];
11
+ fps: number;
12
+ framesPerChunk: number;
13
+ preferLossless: boolean;
14
+ compositionDurationInFrames: number;
15
+ };
16
+ type CombineChunksProgress = {
17
+ totalProgress: number;
18
+ frames: number;
19
+ };
20
+ export type CombineChunksOnProgress = (options: CombineChunksProgress) => void;
21
+ type OptionalCombineChunksOptions = {
22
+ onProgress: CombineChunksOnProgress;
23
+ audioBitrate: string | null;
24
+ numberOfGifLoops: number | null;
25
+ logLevel: LogLevel;
26
+ binariesDirectory: string | null;
27
+ audioCodec: AudioCodec | null;
28
+ cancelSignal: CancelSignal | undefined;
29
+ metadata: Record<string, string> | null;
30
+ frameRange: FrameRange | null;
31
+ everyNthFrame: number;
32
+ };
33
+ type AllCombineChunksOptions = MandatoryCombineChunksOptions & OptionalCombineChunksOptions;
34
+ export type CombineChunksOptions = MandatoryCombineChunksOptions & Partial<OptionalCombineChunksOptions>;
35
+ export declare const internalCombineChunks: ({ outputLocation: output, onProgress, codec, fps, numberOfGifLoops, audioBitrate, indent, logLevel, binariesDirectory, cancelSignal, metadata, audioFiles, videoFiles, framesPerChunk, audioCodec, preferLossless, everyNthFrame, frameRange, compositionDurationInFrames, }: AllCombineChunksOptions & {
36
+ indent: boolean;
37
+ }) => Promise<void>;
38
+ export declare const combineChunks: (options: CombineChunksOptions) => Promise<void>;
39
+ export {};
@@ -1,17 +1,21 @@
1
1
  "use strict";
2
2
  // Combine multiple video chunks, useful for decentralized rendering
3
3
  Object.defineProperty(exports, "__esModule", { value: true });
4
- exports.combineChunks = void 0;
4
+ exports.combineChunks = exports.internalCombineChunks = void 0;
5
5
  const node_fs_1 = require("node:fs");
6
6
  const node_path_1 = require("node:path");
7
+ const can_concat_seamlessly_1 = require("./can-concat-seamlessly");
7
8
  const combine_audio_1 = require("./combine-audio");
8
9
  const combine_video_streams_1 = require("./combine-video-streams");
9
10
  const combine_video_streams_seamlessly_1 = require("./combine-video-streams-seamlessly");
11
+ const get_duration_from_frame_range_1 = require("./get-duration-from-frame-range");
10
12
  const get_extension_from_codec_1 = require("./get-extension-from-codec");
13
+ const get_frame_to_render_1 = require("./get-frame-to-render");
11
14
  const is_audio_codec_1 = require("./is-audio-codec");
12
15
  const logger_1 = require("./logger");
13
16
  const mux_video_and_audio_1 = require("./mux-video-and-audio");
14
17
  const audio_codec_1 = require("./options/audio-codec");
18
+ const tmp_dir_1 = require("./tmp-dir");
15
19
  const truthy_1 = require("./truthy");
16
20
  const codecSupportsFastStart = {
17
21
  'h264-mkv': false,
@@ -26,17 +30,28 @@ const codecSupportsFastStart = {
26
30
  vp9: false,
27
31
  wav: false,
28
32
  };
29
- const combineChunks = async ({ files, filelistDir, output, onProgress, numberOfFrames, codec, fps, numberOfGifLoops, resolvedAudioCodec, audioBitrate, indent, logLevel, chunkDurationInSeconds, binariesDirectory, cancelSignal, seamlessAudio, seamlessVideo, muted, metadata, }) => {
30
- const shouldCreateAudio = resolvedAudioCodec !== null && !muted;
33
+ const REMOTION_FILELIST_TOKEN = 'remotion-filelist';
34
+ const internalCombineChunks = async ({ outputLocation: output, onProgress, codec, fps, numberOfGifLoops, audioBitrate, indent, logLevel, binariesDirectory, cancelSignal, metadata, audioFiles, videoFiles, framesPerChunk, audioCodec, preferLossless, everyNthFrame, frameRange, compositionDurationInFrames, }) => {
35
+ const filelistDir = (0, tmp_dir_1.tmpDir)(REMOTION_FILELIST_TOKEN);
31
36
  const shouldCreateVideo = !(0, is_audio_codec_1.isAudioCodec)(codec);
37
+ const resolvedAudioCodec = (0, audio_codec_1.resolveAudioCodec)({
38
+ setting: audioCodec,
39
+ codec,
40
+ preferLossless,
41
+ separateAudioTo: null,
42
+ });
43
+ const shouldCreateAudio = resolvedAudioCodec !== null && audioFiles.length > 0;
44
+ const seamlessVideo = (0, can_concat_seamlessly_1.canConcatVideoSeamlessly)(codec);
45
+ const seamlessAudio = (0, can_concat_seamlessly_1.canConcatAudioSeamlessly)(resolvedAudioCodec, framesPerChunk);
46
+ const realFrameRange = (0, get_frame_to_render_1.getRealFrameRange)(compositionDurationInFrames, frameRange);
47
+ const numberOfFrames = (0, get_duration_from_frame_range_1.getFramesToRender)(realFrameRange, everyNthFrame).length;
32
48
  const videoOutput = shouldCreateVideo
33
49
  ? (0, node_path_1.join)(filelistDir, `video.${(0, get_extension_from_codec_1.getFileExtensionFromCodec)(codec, resolvedAudioCodec)}`)
34
50
  : null;
35
51
  const audioOutput = shouldCreateAudio
36
52
  ? (0, node_path_1.join)(filelistDir, `audio.${(0, audio_codec_1.getExtensionFromAudioCodec)(resolvedAudioCodec)}`)
37
53
  : null;
38
- const audioFiles = files.filter((f) => f.endsWith('audio'));
39
- const videoFiles = files.filter((f) => f.endsWith('video'));
54
+ const chunkDurationInSeconds = framesPerChunk / fps;
40
55
  let concatenatedAudio = 0;
41
56
  let concatenatedVideo = 0;
42
57
  let muxing = 0;
@@ -45,7 +60,10 @@ const combineChunks = async ({ files, filelistDir, output, onProgress, numberOfF
45
60
  (shouldCreateVideo ? numberOfFrames : 0) +
46
61
  numberOfFrames;
47
62
  const actualProgress = concatenatedAudio + concatenatedVideo + muxing;
48
- onProgress((actualProgress / totalFrames) * numberOfFrames);
63
+ onProgress({
64
+ frames: (actualProgress / totalFrames) * numberOfFrames,
65
+ totalProgress: actualProgress / totalFrames,
66
+ });
49
67
  };
50
68
  logger_1.Log.verbose({ indent, logLevel }, `Combining chunks, audio = ${shouldCreateAudio === false
51
69
  ? 'no'
@@ -117,7 +135,7 @@ const combineChunks = async ({ files, filelistDir, output, onProgress, numberOfF
117
135
  addFaststart: codecSupportsFastStart[codec],
118
136
  metadata,
119
137
  });
120
- onProgress(numberOfFrames);
138
+ onProgress({ totalProgress: 1, frames: numberOfFrames });
121
139
  (0, node_fs_1.rmSync)(filelistDir, { recursive: true });
122
140
  }
123
141
  catch (err) {
@@ -125,4 +143,29 @@ const combineChunks = async ({ files, filelistDir, output, onProgress, numberOfF
125
143
  throw err;
126
144
  }
127
145
  };
146
+ exports.internalCombineChunks = internalCombineChunks;
147
+ const combineChunks = (options) => {
148
+ var _a, _b, _c, _d, _e, _f, _g, _h, _j;
149
+ return (0, exports.internalCombineChunks)({
150
+ audioBitrate: (_a = options.audioBitrate) !== null && _a !== void 0 ? _a : null,
151
+ numberOfGifLoops: (_b = options.numberOfGifLoops) !== null && _b !== void 0 ? _b : null,
152
+ indent: false,
153
+ logLevel: (_c = options.logLevel) !== null && _c !== void 0 ? _c : 'info',
154
+ binariesDirectory: (_d = options.binariesDirectory) !== null && _d !== void 0 ? _d : null,
155
+ cancelSignal: options.cancelSignal,
156
+ metadata: (_e = options.metadata) !== null && _e !== void 0 ? _e : null,
157
+ audioCodec: (_f = options.audioCodec) !== null && _f !== void 0 ? _f : null,
158
+ preferLossless: options.preferLossless,
159
+ audioFiles: options.audioFiles,
160
+ codec: options.codec,
161
+ fps: options.fps,
162
+ framesPerChunk: options.framesPerChunk,
163
+ outputLocation: options.outputLocation,
164
+ onProgress: (_g = options.onProgress) !== null && _g !== void 0 ? _g : (() => { }),
165
+ videoFiles: options.videoFiles,
166
+ everyNthFrame: (_h = options.everyNthFrame) !== null && _h !== void 0 ? _h : 1,
167
+ frameRange: (_j = options.frameRange) !== null && _j !== void 0 ? _j : null,
168
+ compositionDurationInFrames: options.compositionDurationInFrames,
169
+ });
170
+ };
128
171
  exports.combineChunks = combineChunks;
@@ -321,6 +321,14 @@ var printUsefulErrorMessage = (err, logLevel, indent) => {
321
321
  Log.info({ indent, logLevel }, "\uD83D\uDCA1 On Lambda, one reason this could happen is that Chrome is rejecting an asset to be loaded when it is running low on disk space.");
322
322
  Log.info({ indent, logLevel }, "Try increasing the disk size of your Lambda function.");
323
323
  }
324
+ if (err.message.includes("Invalid value specified for cpu")) {
325
+ Log.info({ indent, logLevel });
326
+ Log.info({ indent, logLevel }, "\uD83D\uDCA1 This error indicates that your GCP account does have a limit. Try setting `--maxInstances=5` / `maxInstances: 5` when deploying this service.");
327
+ Log.info({
328
+ indent,
329
+ logLevel
330
+ });
331
+ }
324
332
  };
325
333
 
326
334
  // src/wrap-with-error-handling.ts