@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.
- package/dist/assets/calculate-asset-positions.js +0 -1
- package/dist/assets/ffmpeg-volume-expression.d.ts +1 -2
- package/dist/assets/ffmpeg-volume-expression.js +3 -5
- package/dist/assets/types.d.ts +0 -1
- package/dist/can-concat-seamlessly.d.ts +4 -0
- package/dist/can-concat-seamlessly.js +17 -0
- package/dist/client.d.ts +2 -2
- package/dist/combine-chunks.d.ts +39 -0
- package/dist/{combine-videos.js → combine-chunks.js} +50 -7
- package/dist/esm/error-handling.mjs +8 -0
- package/dist/esm/index.mjs +2150 -2086
- package/dist/index.d.ts +30 -22
- package/dist/index.js +8 -3
- package/dist/options/index.d.ts +2 -2
- package/dist/options/metadata.d.ts +1 -1
- package/dist/options/webhook-custom-data.d.ts +1 -1
- package/dist/print-useful-error-message.js +8 -0
- package/dist/render-media.d.ts +2 -1
- package/dist/render-media.js +7 -8
- package/dist/stringify-ffmpeg-filter.js +0 -1
- package/dist/validate-even-dimensions-with-codec.d.ts +4 -1
- package/dist/validate-even-dimensions-with-codec.js +14 -4
- package/package.json +15 -15
- package/dist/combine-videos.d.ts +0 -27
|
@@ -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,
|
|
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,
|
|
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(
|
|
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)(
|
|
74
|
+
const actualVolume = (0, round_volume_to_avoid_stack_overflow_1.roundVolumeToAvoidStackOverflow)(baseVolume);
|
|
77
75
|
if (!volumeMap[actualVolume]) {
|
|
78
76
|
volumeMap[actualVolume] = [];
|
|
79
77
|
}
|
package/dist/assets/types.d.ts
CHANGED
|
@@ -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: "
|
|
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: "
|
|
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
|
|
30
|
-
|
|
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
|
|
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(
|
|
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
|