@remotion/lambda 4.0.121 → 4.0.123
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/api/make-lambda-payload.d.ts +1 -1
- package/dist/api/make-lambda-payload.js +2 -1
- package/dist/api/render-media-on-lambda.js +2 -1
- package/dist/cli/commands/render/progress.d.ts +1 -1
- package/dist/cli/commands/render/progress.js +4 -4
- package/dist/cli/commands/render/render.js +7 -3
- package/dist/functions/chunk-optimization/plan-frame-ranges.d.ts +4 -1
- package/dist/functions/helpers/can-concat-seamlessly.d.ts +3 -2
- package/dist/functions/helpers/can-concat-seamlessly.js +9 -4
- package/dist/functions/helpers/concat-videos.d.ts +5 -2
- package/dist/functions/helpers/concat-videos.js +22 -7
- package/dist/functions/helpers/create-post-render-data.js +7 -1
- package/dist/functions/helpers/expected-out-name.js +6 -1
- package/dist/functions/helpers/get-chromium-executable-path.js +0 -1
- package/dist/functions/helpers/get-cleanup-progress.d.ts +3 -1
- package/dist/functions/helpers/get-cleanup-progress.js +3 -1
- package/dist/functions/helpers/get-files-to-delete.d.ts +3 -1
- package/dist/functions/helpers/get-files-to-delete.js +22 -6
- package/dist/functions/helpers/get-progress.js +14 -3
- package/dist/functions/helpers/make-timeout-message.js +5 -3
- package/dist/functions/helpers/merge-chunks.d.ts +3 -0
- package/dist/functions/helpers/merge-chunks.js +15 -1
- package/dist/functions/helpers/timer.d.ts +2 -1
- package/dist/functions/helpers/timer.js +4 -2
- package/dist/functions/launch.js +19 -4
- package/dist/functions/merge.js +5 -0
- package/dist/functions/renderer.js +66 -26
- package/dist/functions/start.js +1 -0
- package/dist/functions/still.js +6 -3
- package/dist/internals.d.ts +1 -1
- package/dist/shared/constants.d.ts +10 -3
- package/dist/shared/constants.js +1 -1
- package/dist/shared/invoke-webhook.d.ts +0 -2
- package/dist/shared/parse-chunk-key.d.ts +1 -0
- package/dist/shared/parse-chunk-key.js +2 -1
- package/dist/shared/validate-outname.d.ts +6 -1
- package/dist/shared/validate-outname.js +3 -2
- package/package.json +8 -8
- package/remotionlambda-arm64.zip +0 -0
|
@@ -48,6 +48,6 @@ export type InnerRenderMediaOnLambdaInput = {
|
|
|
48
48
|
colorSpace: ColorSpace;
|
|
49
49
|
deleteAfter: DeleteAfter | null;
|
|
50
50
|
} & ToOptions<typeof BrowserSafeApis.optionsMap.renderMediaOnLambda>;
|
|
51
|
-
export declare const makeLambdaRenderMediaPayload: ({ rendererFunctionName, frameRange, framesPerLambda, forceBucketName: bucketName, codec, composition, serveUrl, imageFormat, inputProps, region, crf, envVariables, pixelFormat, proResProfile, x264Preset, maxRetries, privacy, logLevel, outName, timeoutInMilliseconds, chromiumOptions, scale, everyNthFrame, numberOfGifLoops, audioBitrate, concurrencyPerLambda, audioCodec, forceHeight, forceWidth, webhook, videoBitrate, encodingMaxRate, encodingBufferSize, downloadBehavior, muted, overwrite, jpegQuality, offthreadVideoCacheSizeInBytes, deleteAfter, colorSpace, }: InnerRenderMediaOnLambdaInput) => Promise<LambdaStartPayload>;
|
|
51
|
+
export declare const makeLambdaRenderMediaPayload: ({ rendererFunctionName, frameRange, framesPerLambda, forceBucketName: bucketName, codec, composition, serveUrl, imageFormat, inputProps, region, crf, envVariables, pixelFormat, proResProfile, x264Preset, maxRetries, privacy, logLevel, outName, timeoutInMilliseconds, chromiumOptions, scale, everyNthFrame, numberOfGifLoops, audioBitrate, concurrencyPerLambda, audioCodec, forceHeight, forceWidth, webhook, videoBitrate, encodingMaxRate, encodingBufferSize, downloadBehavior, muted, overwrite, jpegQuality, offthreadVideoCacheSizeInBytes, deleteAfter, colorSpace, preferLossless, }: InnerRenderMediaOnLambdaInput) => Promise<LambdaStartPayload>;
|
|
52
52
|
export declare const getRenderProgressPayload: ({ bucketName, renderId, s3OutputProvider, logLevel, }: GetRenderProgressInput) => LambdaStatusPayload;
|
|
53
53
|
export declare const makeLambdaRenderStillPayload: ({ serveUrl, inputProps, imageFormat, envVariables, quality, jpegQuality, region, maxRetries, composition, privacy, frame, logLevel, outName, timeoutInMilliseconds, chromiumOptions, scale, downloadBehavior, forceHeight, forceWidth, forceBucketName, dumpBrowserLogs, offthreadVideoCacheSizeInBytes, deleteAfter, }: RenderStillOnLambdaInput) => Promise<LambdaPayloads[LambdaRoutines.still]>;
|
|
@@ -9,7 +9,7 @@ const validate_frames_per_lambda_1 = require("../shared/validate-frames-per-lamb
|
|
|
9
9
|
const validate_lambda_codec_1 = require("../shared/validate-lambda-codec");
|
|
10
10
|
const validate_serveurl_1 = require("../shared/validate-serveurl");
|
|
11
11
|
const validate_webhook_1 = require("../shared/validate-webhook");
|
|
12
|
-
const makeLambdaRenderMediaPayload = async ({ rendererFunctionName, frameRange, framesPerLambda, forceBucketName: bucketName, codec, composition, serveUrl, imageFormat, inputProps, region, crf, envVariables, pixelFormat, proResProfile, x264Preset, maxRetries, privacy, logLevel, outName, timeoutInMilliseconds, chromiumOptions, scale, everyNthFrame, numberOfGifLoops, audioBitrate, concurrencyPerLambda, audioCodec, forceHeight, forceWidth, webhook, videoBitrate, encodingMaxRate, encodingBufferSize, downloadBehavior, muted, overwrite, jpegQuality, offthreadVideoCacheSizeInBytes, deleteAfter, colorSpace, }) => {
|
|
12
|
+
const makeLambdaRenderMediaPayload = async ({ rendererFunctionName, frameRange, framesPerLambda, forceBucketName: bucketName, codec, composition, serveUrl, imageFormat, inputProps, region, crf, envVariables, pixelFormat, proResProfile, x264Preset, maxRetries, privacy, logLevel, outName, timeoutInMilliseconds, chromiumOptions, scale, everyNthFrame, numberOfGifLoops, audioBitrate, concurrencyPerLambda, audioCodec, forceHeight, forceWidth, webhook, videoBitrate, encodingMaxRate, encodingBufferSize, downloadBehavior, muted, overwrite, jpegQuality, offthreadVideoCacheSizeInBytes, deleteAfter, colorSpace, preferLossless, }) => {
|
|
13
13
|
const actualCodec = (0, validate_lambda_codec_1.validateLambdaCodec)(codec);
|
|
14
14
|
(0, validate_serveurl_1.validateServeUrl)(serveUrl);
|
|
15
15
|
(0, validate_frames_per_lambda_1.validateFramesPerLambda)({
|
|
@@ -70,6 +70,7 @@ const makeLambdaRenderMediaPayload = async ({ rendererFunctionName, frameRange,
|
|
|
70
70
|
offthreadVideoCacheSizeInBytes: offthreadVideoCacheSizeInBytes !== null && offthreadVideoCacheSizeInBytes !== void 0 ? offthreadVideoCacheSizeInBytes : null,
|
|
71
71
|
deleteAfter: deleteAfter !== null && deleteAfter !== void 0 ? deleteAfter : null,
|
|
72
72
|
colorSpace: colorSpace !== null && colorSpace !== void 0 ? colorSpace : 'default',
|
|
73
|
+
preferLossless: preferLossless !== null && preferLossless !== void 0 ? preferLossless : false,
|
|
73
74
|
};
|
|
74
75
|
};
|
|
75
76
|
exports.makeLambdaRenderMediaPayload = makeLambdaRenderMediaPayload;
|
|
@@ -68,7 +68,7 @@ exports.internalRenderMediaOnLambdaRaw = internalRenderMediaOnLambdaRaw;
|
|
|
68
68
|
* @returns {Promise<RenderMediaOnLambdaOutput>} See documentation for detailed structure
|
|
69
69
|
*/
|
|
70
70
|
const renderMediaOnLambda = (options) => {
|
|
71
|
-
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s, _t, _u, _v, _w, _x, _y, _z, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10;
|
|
71
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s, _t, _u, _v, _w, _x, _y, _z, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11;
|
|
72
72
|
const wrapped = pure_1.NoReactAPIs.wrapWithErrorHandling(exports.internalRenderMediaOnLambdaRaw);
|
|
73
73
|
if (options.quality) {
|
|
74
74
|
throw new Error('quality has been renamed to jpegQuality. Please rename the option.');
|
|
@@ -115,6 +115,7 @@ const renderMediaOnLambda = (options) => {
|
|
|
115
115
|
webhook: (_8 = options.webhook) !== null && _8 !== void 0 ? _8 : null,
|
|
116
116
|
x264Preset: (_9 = options.x264Preset) !== null && _9 !== void 0 ? _9 : null,
|
|
117
117
|
deleteAfter: (_10 = options.deleteAfter) !== null && _10 !== void 0 ? _10 : null,
|
|
118
|
+
preferLossless: (_11 = options.preferLossless) !== null && _11 !== void 0 ? _11 : false,
|
|
118
119
|
});
|
|
119
120
|
};
|
|
120
121
|
exports.renderMediaOnLambda = renderMediaOnLambda;
|
|
@@ -19,11 +19,11 @@ const makeInvokeProgress = (invokeProgress, totalSteps, retriesInfo) => {
|
|
|
19
19
|
].join(' ');
|
|
20
20
|
};
|
|
21
21
|
const makeRenderProgress = ({ chunkProgress, totalSteps, }) => {
|
|
22
|
-
const {
|
|
22
|
+
const { chunksEncoded, totalChunks, doneIn } = chunkProgress;
|
|
23
23
|
const renderProgress = chunkProgress.totalFrames === null
|
|
24
24
|
? 0
|
|
25
25
|
: chunkProgress.framesRendered / chunkProgress.totalFrames;
|
|
26
|
-
const encodingProgress = totalChunks === null ? 0 :
|
|
26
|
+
const encodingProgress = totalChunks === null ? 0 : chunksEncoded / totalChunks;
|
|
27
27
|
const frames = chunkProgress.totalFrames === null
|
|
28
28
|
? null
|
|
29
29
|
: `(${chunkProgress.framesRendered}/${chunkProgress.totalFrames})`;
|
|
@@ -106,11 +106,11 @@ const makeMultiProgressFromStatus = (status) => {
|
|
|
106
106
|
var _a, _b, _c, _d, _e, _f;
|
|
107
107
|
return {
|
|
108
108
|
chunkProgress: {
|
|
109
|
-
|
|
109
|
+
chunksEncoded: status.chunks,
|
|
110
110
|
totalChunks: (_b = (_a = status.renderMetadata) === null || _a === void 0 ? void 0 : _a.totalChunks) !== null && _b !== void 0 ? _b : null,
|
|
111
111
|
doneIn: status.timeToFinishChunks,
|
|
112
112
|
framesRendered: status.framesRendered,
|
|
113
|
-
totalFrames: status.renderMetadata
|
|
113
|
+
totalFrames: status.renderMetadata && status.renderMetadata.type === 'video'
|
|
114
114
|
? renderer_1.RenderInternals.getFramesToRender(status.renderMetadata.frameRange, status.renderMetadata.everyNthFrame).length
|
|
115
115
|
: null,
|
|
116
116
|
},
|
|
@@ -24,11 +24,11 @@ const log_1 = require("../../log");
|
|
|
24
24
|
const progress_1 = require("./progress");
|
|
25
25
|
exports.RENDER_COMMAND = 'render';
|
|
26
26
|
function getTotalFrames(status) {
|
|
27
|
-
return status.renderMetadata
|
|
27
|
+
return status.renderMetadata && status.renderMetadata.type === 'video'
|
|
28
28
|
? renderer_1.RenderInternals.getFramesToRender(status.renderMetadata.frameRange, status.renderMetadata.everyNthFrame).length
|
|
29
29
|
: null;
|
|
30
30
|
}
|
|
31
|
-
const { x264Option, audioBitrateOption, offthreadVideoCacheSizeInBytesOption, scaleOption, crfOption, jpegQualityOption, videoBitrateOption, mutedOption, colorSpaceOption, deleteAfterOption, enableMultiprocessOnLinuxOption, glOption, headlessOption, numberOfGifLoopsOption, encodingMaxRateOption, encodingBufferSizeOption, delayRenderTimeoutInMillisecondsOption, overwriteOption, binariesDirectoryOption, } = client_1.BrowserSafeApis.options;
|
|
31
|
+
const { x264Option, audioBitrateOption, offthreadVideoCacheSizeInBytesOption, scaleOption, crfOption, jpegQualityOption, videoBitrateOption, mutedOption, colorSpaceOption, deleteAfterOption, enableMultiprocessOnLinuxOption, glOption, headlessOption, numberOfGifLoopsOption, encodingMaxRateOption, encodingBufferSizeOption, delayRenderTimeoutInMillisecondsOption, overwriteOption, binariesDirectoryOption, preferLosslessOption, } = client_1.BrowserSafeApis.options;
|
|
32
32
|
const renderCommand = async (args, remotionRoot, logLevel) => {
|
|
33
33
|
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k;
|
|
34
34
|
const serveUrl = args[0];
|
|
@@ -101,6 +101,9 @@ const renderCommand = async (args, remotionRoot, logLevel) => {
|
|
|
101
101
|
const binariesDirectory = binariesDirectoryOption.getValue({
|
|
102
102
|
commandLine: cli_1.CliInternals.parsedCli,
|
|
103
103
|
}).value;
|
|
104
|
+
const preferLossless = preferLosslessOption.getValue({
|
|
105
|
+
commandLine: cli_1.CliInternals.parsedCli,
|
|
106
|
+
}).value;
|
|
104
107
|
const chromiumOptions = {
|
|
105
108
|
disableWebSecurity,
|
|
106
109
|
enableMultiProcessOnLinux,
|
|
@@ -216,12 +219,13 @@ const renderCommand = async (args, remotionRoot, logLevel) => {
|
|
|
216
219
|
: null,
|
|
217
220
|
rendererFunctionName: (_j = args_1.parsedLambdaCli['renderer-function-name']) !== null && _j !== void 0 ? _j : null,
|
|
218
221
|
forceBucketName: (_k = args_1.parsedLambdaCli['force-bucket-name']) !== null && _k !== void 0 ? _k : null,
|
|
219
|
-
audioCodec: cli_1.CliInternals.parsedCli[
|
|
222
|
+
audioCodec: cli_1.CliInternals.parsedCli[client_1.BrowserSafeApis.options.audioCodecOption.cliFlag],
|
|
220
223
|
deleteAfter: deleteAfter !== null && deleteAfter !== void 0 ? deleteAfter : null,
|
|
221
224
|
colorSpace,
|
|
222
225
|
downloadBehavior: { type: 'play-in-browser' },
|
|
223
226
|
offthreadVideoCacheSizeInBytes: offthreadVideoCacheSizeInBytes !== null && offthreadVideoCacheSizeInBytes !== void 0 ? offthreadVideoCacheSizeInBytes : null,
|
|
224
227
|
x264Preset: x264Preset !== null && x264Preset !== void 0 ? x264Preset : null,
|
|
228
|
+
preferLossless,
|
|
225
229
|
});
|
|
226
230
|
const totalSteps = downloadName ? 6 : 5;
|
|
227
231
|
const progressBar = cli_1.CliInternals.createOverwriteableCliOutput({
|
|
@@ -1,2 +1,3 @@
|
|
|
1
|
-
import type { AudioCodec
|
|
2
|
-
export declare const
|
|
1
|
+
import type { AudioCodec } from '@remotion/renderer';
|
|
2
|
+
export declare const canConcatAudioSeamlessly: (audioCodec: AudioCodec | null) => boolean;
|
|
3
|
+
export declare const canConcatVideoSeamlessly: (codec: string) => boolean;
|
|
@@ -1,7 +1,12 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.
|
|
4
|
-
|
|
5
|
-
|
|
3
|
+
exports.canConcatVideoSeamlessly = exports.canConcatAudioSeamlessly = void 0;
|
|
4
|
+
// Cannot do WAV yet, because currently assumes AAC in+outpoint
|
|
5
|
+
const canConcatAudioSeamlessly = (audioCodec) => {
|
|
6
|
+
return audioCodec === 'aac';
|
|
6
7
|
};
|
|
7
|
-
exports.
|
|
8
|
+
exports.canConcatAudioSeamlessly = canConcatAudioSeamlessly;
|
|
9
|
+
const canConcatVideoSeamlessly = (codec) => {
|
|
10
|
+
return codec === 'h264';
|
|
11
|
+
};
|
|
12
|
+
exports.canConcatVideoSeamlessly = canConcatVideoSeamlessly;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { AudioCodec, LogLevel } from '@remotion/renderer';
|
|
1
|
+
import type { AudioCodec, CancelSignal, LogLevel } from '@remotion/renderer';
|
|
2
2
|
import type { AwsRegion } from '../../pricing/aws-regions';
|
|
3
3
|
import type { LambdaCodec } from '../../shared/validate-lambda-codec';
|
|
4
4
|
import type { EnhancedErrorInfo } from './write-lambda-error';
|
|
@@ -12,7 +12,7 @@ export declare const getAllFilesS3: ({ bucket, expectedFiles, outdir, renderId,
|
|
|
12
12
|
onErrors: (errors: EnhancedErrorInfo[]) => void;
|
|
13
13
|
logLevel: LogLevel;
|
|
14
14
|
}) => Promise<string[]>;
|
|
15
|
-
export declare const concatVideosS3: ({ onProgress, numberOfFrames, codec, fps, numberOfGifLoops, files, outdir, audioCodec, audioBitrate, logLevel, binariesDirectory, }: {
|
|
15
|
+
export declare const concatVideosS3: ({ onProgress, numberOfFrames, codec, fps, numberOfGifLoops, files, outdir, audioCodec, audioBitrate, logLevel, framesPerLambda, binariesDirectory, cancelSignal, preferLossless, }: {
|
|
16
16
|
onProgress: (frames: number) => void;
|
|
17
17
|
numberOfFrames: number;
|
|
18
18
|
codec: LambdaCodec;
|
|
@@ -23,7 +23,10 @@ export declare const concatVideosS3: ({ onProgress, numberOfFrames, codec, fps,
|
|
|
23
23
|
audioCodec: AudioCodec | null;
|
|
24
24
|
audioBitrate: string | null;
|
|
25
25
|
logLevel: LogLevel;
|
|
26
|
+
framesPerLambda: number;
|
|
26
27
|
binariesDirectory: string | null;
|
|
28
|
+
cancelSignal: CancelSignal | undefined;
|
|
29
|
+
preferLossless: boolean;
|
|
27
30
|
}) => Promise<{
|
|
28
31
|
outfile: string;
|
|
29
32
|
cleanupChunksProm: Promise<void>;
|
|
@@ -28,6 +28,7 @@ const renderer_1 = require("@remotion/renderer");
|
|
|
28
28
|
const node_fs_1 = __importStar(require("node:fs"));
|
|
29
29
|
const node_path_1 = __importStar(require("node:path"));
|
|
30
30
|
const constants_1 = require("../../shared/constants");
|
|
31
|
+
const can_concat_seamlessly_1 = require("./can-concat-seamlessly");
|
|
31
32
|
const inspect_errors_1 = require("./inspect-errors");
|
|
32
33
|
const io_1 = require("./io");
|
|
33
34
|
const timer_1 = require("./timer");
|
|
@@ -56,7 +57,7 @@ const getAllFilesS3 = ({ bucket, expectedFiles, outdir, renderId, region, expect
|
|
|
56
57
|
const downloaded = {};
|
|
57
58
|
const getFiles = async () => {
|
|
58
59
|
const prefix = (0, constants_1.rendersPrefix)(renderId);
|
|
59
|
-
const lsTimer = (0, timer_1.timer)('Listing files');
|
|
60
|
+
const lsTimer = (0, timer_1.timer)('Listing files', logLevel);
|
|
60
61
|
const contents = await (0, io_1.lambdaLs)({
|
|
61
62
|
bucketName: bucket,
|
|
62
63
|
prefix,
|
|
@@ -105,7 +106,7 @@ const getAllFilesS3 = ({ bucket, expectedFiles, outdir, renderId, region, expect
|
|
|
105
106
|
}
|
|
106
107
|
alreadyDownloading[key] = true;
|
|
107
108
|
try {
|
|
108
|
-
const downloadTimer = (0, timer_1.timer)('Downloading ' + key);
|
|
109
|
+
const downloadTimer = (0, timer_1.timer)('Downloading ' + key, logLevel);
|
|
109
110
|
await downloadS3File({
|
|
110
111
|
bucket,
|
|
111
112
|
key,
|
|
@@ -133,28 +134,42 @@ const getAllFilesS3 = ({ bucket, expectedFiles, outdir, renderId, region, expect
|
|
|
133
134
|
});
|
|
134
135
|
};
|
|
135
136
|
exports.getAllFilesS3 = getAllFilesS3;
|
|
136
|
-
const concatVideosS3 = async ({ onProgress, numberOfFrames, codec, fps, numberOfGifLoops, files, outdir, audioCodec, audioBitrate, logLevel, binariesDirectory, }) => {
|
|
137
|
-
const outfile = (0, node_path_1.join)(renderer_1.RenderInternals.tmpDir(constants_1.REMOTION_CONCATED_TOKEN),
|
|
138
|
-
const combine = (0, timer_1.timer)('Combine videos');
|
|
137
|
+
const concatVideosS3 = async ({ onProgress, numberOfFrames, codec, fps, numberOfGifLoops, files, outdir, audioCodec, audioBitrate, logLevel, framesPerLambda, binariesDirectory, cancelSignal, preferLossless, }) => {
|
|
138
|
+
const outfile = (0, node_path_1.join)(renderer_1.RenderInternals.tmpDir(constants_1.REMOTION_CONCATED_TOKEN), `concat.${renderer_1.RenderInternals.getFileExtensionFromCodec(codec, audioCodec)}`);
|
|
139
|
+
const combine = (0, timer_1.timer)('Combine videos', logLevel);
|
|
139
140
|
const filelistDir = renderer_1.RenderInternals.tmpDir(constants_1.REMOTION_FILELIST_TOKEN);
|
|
141
|
+
const chunkDurationInSeconds = framesPerLambda / fps;
|
|
142
|
+
const resolvedAudioCodec = renderer_1.RenderInternals.resolveAudioCodec({
|
|
143
|
+
setting: audioCodec,
|
|
144
|
+
codec,
|
|
145
|
+
preferLossless,
|
|
146
|
+
separateAudioTo: null,
|
|
147
|
+
});
|
|
148
|
+
const seamlessAudio = (0, can_concat_seamlessly_1.canConcatAudioSeamlessly)(resolvedAudioCodec);
|
|
149
|
+
const seamlessVideo = (0, can_concat_seamlessly_1.canConcatVideoSeamlessly)(codec);
|
|
140
150
|
await renderer_1.RenderInternals.combineVideos({
|
|
141
151
|
files,
|
|
142
152
|
filelistDir,
|
|
143
153
|
output: outfile,
|
|
144
|
-
onProgress
|
|
154
|
+
onProgress,
|
|
145
155
|
numberOfFrames,
|
|
146
156
|
codec,
|
|
147
157
|
fps,
|
|
148
158
|
numberOfGifLoops,
|
|
149
|
-
|
|
159
|
+
resolvedAudioCodec,
|
|
150
160
|
audioBitrate,
|
|
151
161
|
indent: false,
|
|
152
162
|
logLevel,
|
|
163
|
+
chunkDurationInSeconds,
|
|
153
164
|
binariesDirectory,
|
|
165
|
+
cancelSignal,
|
|
166
|
+
seamlessAudio,
|
|
167
|
+
seamlessVideo,
|
|
154
168
|
});
|
|
155
169
|
combine.end();
|
|
156
170
|
const cleanupChunksProm = node_fs_1.default.promises.rm(outdir, {
|
|
157
171
|
recursive: true,
|
|
172
|
+
force: true,
|
|
158
173
|
});
|
|
159
174
|
return { outfile, cleanupChunksProm };
|
|
160
175
|
};
|
|
@@ -9,6 +9,7 @@ const calculate_chunk_times_1 = require("./calculate-chunk-times");
|
|
|
9
9
|
const get_files_to_delete_1 = require("./get-files-to-delete");
|
|
10
10
|
const get_retry_stats_1 = require("./get-retry-stats");
|
|
11
11
|
const get_time_to_finish_1 = require("./get-time-to-finish");
|
|
12
|
+
const render_has_audio_video_1 = require("./render-has-audio-video");
|
|
12
13
|
const createPostRenderData = ({ renderId, region, memorySizeInMb, renderMetadata, contents, timeToEncode, errorExplanations, timeToDelete, outputFile, }) => {
|
|
13
14
|
const initializedKeys = contents.filter((c) => { var _a; return (_a = c.Key) === null || _a === void 0 ? void 0 : _a.startsWith((0, constants_1.lambdaTimingsPrefix)(renderId)); });
|
|
14
15
|
const parsedTimings = initializedKeys.map(({ Key }) => (0, parse_lambda_timings_key_1.parseLambdaTimingsKey)(Key));
|
|
@@ -42,6 +43,7 @@ const createPostRenderData = ({ renderId, region, memorySizeInMb, renderMetadata
|
|
|
42
43
|
contents,
|
|
43
44
|
renderId,
|
|
44
45
|
});
|
|
46
|
+
const { hasAudio, hasVideo } = (0, render_has_audio_video_1.lambdaRenderHasAudioVideo)(renderMetadata);
|
|
45
47
|
return {
|
|
46
48
|
cost: {
|
|
47
49
|
currency: 'USD',
|
|
@@ -63,6 +65,8 @@ const createPostRenderData = ({ renderId, region, memorySizeInMb, renderMetadata
|
|
|
63
65
|
filesCleanedUp: (0, get_files_to_delete_1.getFilesToDelete)({
|
|
64
66
|
chunkCount: renderMetadata.totalChunks,
|
|
65
67
|
renderId,
|
|
68
|
+
hasAudio,
|
|
69
|
+
hasVideo,
|
|
66
70
|
}).length,
|
|
67
71
|
timeToEncode,
|
|
68
72
|
timeToCleanUp: timeToDelete,
|
|
@@ -72,7 +76,9 @@ const createPostRenderData = ({ renderId, region, memorySizeInMb, renderMetadata
|
|
|
72
76
|
type: 'absolute-time',
|
|
73
77
|
}),
|
|
74
78
|
retriesInfo,
|
|
75
|
-
mostExpensiveFrameRanges:
|
|
79
|
+
mostExpensiveFrameRanges: renderMetadata.type === 'still'
|
|
80
|
+
? []
|
|
81
|
+
: (0, get_most_expensive_chunks_1.getMostExpensiveChunks)(parsedTimings, renderMetadata.framesPerLambda, renderMetadata.frameRange[0], renderMetadata.frameRange[1]),
|
|
76
82
|
deleteAfter: renderMetadata.deleteAfter,
|
|
77
83
|
estimatedBillingDurationInMilliseconds,
|
|
78
84
|
};
|
|
@@ -25,7 +25,12 @@ const getExpectedOutName = (renderMetadata, bucketName, customCredentials) => {
|
|
|
25
25
|
renderMetadata,
|
|
26
26
|
});
|
|
27
27
|
if (outNameValue) {
|
|
28
|
-
(0, validate_outname_1.validateOutname)(
|
|
28
|
+
(0, validate_outname_1.validateOutname)({
|
|
29
|
+
outName: outNameValue,
|
|
30
|
+
codec: renderMetadata.codec,
|
|
31
|
+
audioCodecSetting: renderMetadata.audioCodec,
|
|
32
|
+
separateAudioTo: null,
|
|
33
|
+
});
|
|
29
34
|
return (0, defaults_1.customOutName)(renderMetadata.renderId, bucketName, outNameValue);
|
|
30
35
|
}
|
|
31
36
|
if (renderMetadata.type === 'still') {
|
|
@@ -6,7 +6,6 @@ if (/^AWS_Lambda_nodejs(?:18)[.]x$/.test((_a = process.env.AWS_EXECUTION_ENV) !=
|
|
|
6
6
|
true) {
|
|
7
7
|
process.env.FONTCONFIG_PATH = '/opt';
|
|
8
8
|
process.env.FONTCONFIG_FILE = '/opt/fonts.conf';
|
|
9
|
-
process.env.READ_ONLY_FS = '1';
|
|
10
9
|
process.env.DISABLE_FROM_SURFACE = '1';
|
|
11
10
|
process.env.NO_COLOR = '1';
|
|
12
11
|
}
|
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
import type { _Object } from '@aws-sdk/client-s3';
|
|
2
2
|
import type { CleanupInfo } from '../../shared/constants';
|
|
3
|
-
export declare const getCleanupProgress: ({ contents, output, chunkCount, renderId, }: {
|
|
3
|
+
export declare const getCleanupProgress: ({ contents, output, chunkCount, renderId, hasAudio, hasVideo, }: {
|
|
4
4
|
contents: _Object[];
|
|
5
5
|
output: string | null;
|
|
6
6
|
chunkCount: number;
|
|
7
7
|
renderId: string;
|
|
8
|
+
hasAudio: boolean;
|
|
9
|
+
hasVideo: boolean;
|
|
8
10
|
}) => null | CleanupInfo;
|
|
@@ -2,13 +2,15 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.getCleanupProgress = void 0;
|
|
4
4
|
const get_files_to_delete_1 = require("./get-files-to-delete");
|
|
5
|
-
const getCleanupProgress = ({ contents, output, chunkCount, renderId, }) => {
|
|
5
|
+
const getCleanupProgress = ({ contents, output, chunkCount, renderId, hasAudio, hasVideo, }) => {
|
|
6
6
|
if (output === null) {
|
|
7
7
|
return null;
|
|
8
8
|
}
|
|
9
9
|
const filesToDelete = (0, get_files_to_delete_1.getFilesToDelete)({
|
|
10
10
|
chunkCount,
|
|
11
11
|
renderId,
|
|
12
|
+
hasAudio,
|
|
13
|
+
hasVideo,
|
|
12
14
|
});
|
|
13
15
|
const filesStillThere = contents.filter((c) => {
|
|
14
16
|
return filesToDelete.find((f) => {
|
|
@@ -2,7 +2,9 @@ export type CleanupJob = {
|
|
|
2
2
|
name: string;
|
|
3
3
|
type: 'exact' | 'prefix';
|
|
4
4
|
};
|
|
5
|
-
export declare const getFilesToDelete: ({ chunkCount, renderId, }: {
|
|
5
|
+
export declare const getFilesToDelete: ({ chunkCount, renderId, hasVideo, hasAudio, }: {
|
|
6
6
|
chunkCount: number;
|
|
7
7
|
renderId: string;
|
|
8
|
+
hasVideo: boolean;
|
|
9
|
+
hasAudio: boolean;
|
|
8
10
|
}) => CleanupJob[];
|
|
@@ -2,11 +2,21 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.getFilesToDelete = void 0;
|
|
4
4
|
const constants_1 = require("../../shared/constants");
|
|
5
|
-
const getFilesToDelete = ({ chunkCount, renderId, }) => {
|
|
6
|
-
const
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
5
|
+
const getFilesToDelete = ({ chunkCount, renderId, hasVideo, hasAudio, }) => {
|
|
6
|
+
const videoChunks = hasVideo
|
|
7
|
+
? new Array(chunkCount).fill(true).map((_x, i) => (0, constants_1.chunkKeyForIndex)({
|
|
8
|
+
index: i,
|
|
9
|
+
renderId,
|
|
10
|
+
type: 'video',
|
|
11
|
+
}))
|
|
12
|
+
: [];
|
|
13
|
+
const audioChunks = hasAudio
|
|
14
|
+
? new Array(chunkCount).fill(true).map((_x, i) => (0, constants_1.chunkKeyForIndex)({
|
|
15
|
+
index: i,
|
|
16
|
+
renderId,
|
|
17
|
+
type: 'audio',
|
|
18
|
+
}))
|
|
19
|
+
: [];
|
|
10
20
|
const lambdaTimings = new Array(chunkCount)
|
|
11
21
|
.fill(true)
|
|
12
22
|
.map((_x, i) => (0, constants_1.lambdaTimingsPrefixForChunk)(renderId, i));
|
|
@@ -15,7 +25,13 @@ const getFilesToDelete = ({ chunkCount, renderId, }) => {
|
|
|
15
25
|
name: (0, constants_1.lambdaChunkInitializedPrefix)(renderId),
|
|
16
26
|
type: 'prefix',
|
|
17
27
|
},
|
|
18
|
-
...
|
|
28
|
+
...videoChunks.map((i) => {
|
|
29
|
+
return {
|
|
30
|
+
name: i,
|
|
31
|
+
type: 'exact',
|
|
32
|
+
};
|
|
33
|
+
}),
|
|
34
|
+
...audioChunks.map((i) => {
|
|
19
35
|
return {
|
|
20
36
|
name: i,
|
|
21
37
|
type: 'exact',
|
|
@@ -5,6 +5,7 @@ const renderer_1 = require("@remotion/renderer");
|
|
|
5
5
|
const no_react_1 = require("remotion/no-react");
|
|
6
6
|
const constants_1 = require("../../shared/constants");
|
|
7
7
|
const parse_chunk_key_1 = require("../../shared/parse-chunk-key");
|
|
8
|
+
const truthy_1 = require("../../shared/truthy");
|
|
8
9
|
const calculate_chunk_times_1 = require("./calculate-chunk-times");
|
|
9
10
|
const calculate_price_from_bucket_1 = require("./calculate-price-from-bucket");
|
|
10
11
|
const check_if_render_exists_1 = require("./check-if-render-exists");
|
|
@@ -25,6 +26,7 @@ const get_time_to_finish_1 = require("./get-time-to-finish");
|
|
|
25
26
|
const inspect_errors_1 = require("./inspect-errors");
|
|
26
27
|
const io_1 = require("./io");
|
|
27
28
|
const make_timeout_error_1 = require("./make-timeout-error");
|
|
29
|
+
const render_has_audio_video_1 = require("./render-has-audio-video");
|
|
28
30
|
const getProgress = async ({ bucketName, renderId, expectedBucketOwner, region, memorySizeInMb, timeoutInMilliseconds, customCredentials, }) => {
|
|
29
31
|
var _a, _b, _c, _d, _e, _f, _g, _h, _j;
|
|
30
32
|
const postRenderData = await (0, get_post_render_data_1.getPostRenderData)({
|
|
@@ -35,7 +37,9 @@ const getProgress = async ({ bucketName, renderId, expectedBucketOwner, region,
|
|
|
35
37
|
});
|
|
36
38
|
if (postRenderData) {
|
|
37
39
|
const outData = (0, expected_out_name_1.getExpectedOutName)(postRenderData.renderMetadata, bucketName, customCredentials);
|
|
38
|
-
const totalFrameCount =
|
|
40
|
+
const totalFrameCount = postRenderData.renderMetadata.type === 'still'
|
|
41
|
+
? 1
|
|
42
|
+
: renderer_1.RenderInternals.getFramesToRender(postRenderData.renderMetadata.frameRange, postRenderData.renderMetadata.everyNthFrame).length;
|
|
39
43
|
return {
|
|
40
44
|
framesRendered: totalFrameCount,
|
|
41
45
|
bucket: bucketName,
|
|
@@ -122,16 +126,22 @@ const getProgress = async ({ bucketName, renderId, expectedBucketOwner, region,
|
|
|
122
126
|
// overestimate the price, but will only have a miniscule effect (~0.2%)
|
|
123
127
|
diskSizeInMb: constants_1.MAX_EPHEMERAL_STORAGE_IN_MB,
|
|
124
128
|
});
|
|
129
|
+
const { hasAudio, hasVideo } = renderMetadata
|
|
130
|
+
? (0, render_has_audio_video_1.lambdaRenderHasAudioVideo)(renderMetadata)
|
|
131
|
+
: { hasAudio: false, hasVideo: false };
|
|
125
132
|
const cleanup = (0, get_cleanup_progress_1.getCleanupProgress)({
|
|
126
133
|
chunkCount: (_c = renderMetadata === null || renderMetadata === void 0 ? void 0 : renderMetadata.totalChunks) !== null && _c !== void 0 ? _c : 0,
|
|
127
134
|
contents,
|
|
128
135
|
output: (_d = outputFile === null || outputFile === void 0 ? void 0 : outputFile.url) !== null && _d !== void 0 ? _d : null,
|
|
129
136
|
renderId,
|
|
137
|
+
hasAudio,
|
|
138
|
+
hasVideo,
|
|
130
139
|
});
|
|
131
140
|
const timeToFinish = (0, get_time_to_finish_1.getTimeToFinish)({
|
|
132
141
|
lastModified: (_e = outputFile === null || outputFile === void 0 ? void 0 : outputFile.lastModified) !== null && _e !== void 0 ? _e : null,
|
|
133
142
|
renderMetadata,
|
|
134
143
|
});
|
|
144
|
+
const chunkMultiplier = [hasAudio, hasVideo].filter(truthy_1.truthy).length;
|
|
135
145
|
const chunks = contents.filter((c) => { var _a; return (_a = c.Key) === null || _a === void 0 ? void 0 : _a.startsWith((0, constants_1.chunkKey)(renderId)); });
|
|
136
146
|
const framesRendered = renderMetadata
|
|
137
147
|
? (0, get_rendered_frames_progress_1.getRenderedFramesProgress)({
|
|
@@ -142,7 +152,8 @@ const getProgress = async ({ bucketName, renderId, expectedBucketOwner, region,
|
|
|
142
152
|
renderId,
|
|
143
153
|
})
|
|
144
154
|
: 0;
|
|
145
|
-
const allChunks = chunks.length
|
|
155
|
+
const allChunks = chunks.length / chunkMultiplier ===
|
|
156
|
+
((_f = renderMetadata === null || renderMetadata === void 0 ? void 0 : renderMetadata.totalChunks) !== null && _f !== void 0 ? _f : Infinity);
|
|
146
157
|
const renderSize = contents
|
|
147
158
|
.map((c) => { var _a; return (_a = c.Size) !== null && _a !== void 0 ? _a : 0; })
|
|
148
159
|
.reduce((a, b) => a + b, 0);
|
|
@@ -168,7 +179,7 @@ const getProgress = async ({ bucketName, renderId, expectedBucketOwner, region,
|
|
|
168
179
|
});
|
|
169
180
|
const chunkCount = outputFile
|
|
170
181
|
? (_g = renderMetadata === null || renderMetadata === void 0 ? void 0 : renderMetadata.totalChunks) !== null && _g !== void 0 ? _g : 0
|
|
171
|
-
: chunks.length;
|
|
182
|
+
: chunks.length / chunkMultiplier;
|
|
172
183
|
const availableChunks = chunks.map((c) => (0, parse_chunk_key_1.parseLambdaChunkKey)(c.Key));
|
|
173
184
|
const missingChunks = renderMetadata
|
|
174
185
|
? new Array(renderMetadata.totalChunks)
|
|
@@ -16,9 +16,11 @@ const makeChunkMissingMessage = ({ missingChunks, renderMetadata, }) => {
|
|
|
16
16
|
.map((ch) => {
|
|
17
17
|
const isLastChunk = ch === renderMetadata.totalChunks - 1;
|
|
18
18
|
const start = ch * renderMetadata.framesPerLambda;
|
|
19
|
-
const end =
|
|
20
|
-
?
|
|
21
|
-
:
|
|
19
|
+
const end = renderMetadata.type === 'still'
|
|
20
|
+
? 0
|
|
21
|
+
: isLastChunk
|
|
22
|
+
? renderMetadata.frameRange[1]
|
|
23
|
+
: (ch + 1) * renderMetadata.framesPerLambda - 1;
|
|
22
24
|
const msg = `Chunk ${ch} (Frames ${start} - ${end})`;
|
|
23
25
|
return [
|
|
24
26
|
msg,
|
|
@@ -6,6 +6,7 @@ import type { LambdaCodec } from '../../shared/validate-lambda-codec';
|
|
|
6
6
|
export type OnAllChunksAvailable = (options: {
|
|
7
7
|
inputProps: SerializedInputProps;
|
|
8
8
|
serializedResolvedProps: SerializedInputProps;
|
|
9
|
+
framesPerLambda: number;
|
|
9
10
|
}) => void;
|
|
10
11
|
export declare const mergeChunksAndFinishRender: (options: {
|
|
11
12
|
bucketName: string;
|
|
@@ -28,5 +29,7 @@ export declare const mergeChunksAndFinishRender: (options: {
|
|
|
28
29
|
onAllChunks: OnAllChunksAvailable;
|
|
29
30
|
audioBitrate: string | null;
|
|
30
31
|
logLevel: LogLevel;
|
|
32
|
+
framesPerLambda: number;
|
|
31
33
|
binariesDirectory: string | null;
|
|
34
|
+
preferLossless: boolean;
|
|
32
35
|
}) => Promise<PostRenderData>;
|
|
@@ -10,6 +10,7 @@ const node_fs_1 = require("node:fs");
|
|
|
10
10
|
const node_path_1 = require("node:path");
|
|
11
11
|
const cleanup_serialized_input_props_1 = require("../../shared/cleanup-serialized-input-props");
|
|
12
12
|
const constants_1 = require("../../shared/constants");
|
|
13
|
+
const truthy_1 = require("../../shared/truthy");
|
|
13
14
|
const concat_videos_1 = require("./concat-videos");
|
|
14
15
|
const create_post_render_data_1 = require("./create-post-render-data");
|
|
15
16
|
const delete_chunks_1 = require("./delete-chunks");
|
|
@@ -18,6 +19,8 @@ const get_files_to_delete_1 = require("./get-files-to-delete");
|
|
|
18
19
|
const get_output_url_from_metadata_1 = require("./get-output-url-from-metadata");
|
|
19
20
|
const inspect_errors_1 = require("./inspect-errors");
|
|
20
21
|
const io_1 = require("./io");
|
|
22
|
+
const render_has_audio_video_1 = require("./render-has-audio-video");
|
|
23
|
+
const timer_1 = require("./timer");
|
|
21
24
|
const write_lambda_error_1 = require("./write-lambda-error");
|
|
22
25
|
const write_post_render_data_1 = require("./write-post-render-data");
|
|
23
26
|
const mergeChunksAndFinishRender = async (options) => {
|
|
@@ -76,9 +79,12 @@ const mergeChunksAndFinishRender = async (options) => {
|
|
|
76
79
|
});
|
|
77
80
|
}
|
|
78
81
|
(0, node_fs_1.mkdirSync)(outdir);
|
|
82
|
+
const { hasAudio, hasVideo } = (0, render_has_audio_video_1.lambdaRenderHasAudioVideo)(options.renderMetadata);
|
|
83
|
+
const chunkMultiplier = [hasAudio, hasVideo].filter(truthy_1.truthy).length;
|
|
84
|
+
const expectedFiles = chunkMultiplier * options.chunkCount;
|
|
79
85
|
const files = await (0, concat_videos_1.getAllFilesS3)({
|
|
80
86
|
bucket: options.bucketName,
|
|
81
|
-
expectedFiles
|
|
87
|
+
expectedFiles,
|
|
82
88
|
outdir,
|
|
83
89
|
renderId: options.renderId,
|
|
84
90
|
region: (0, get_current_region_1.getCurrentRegionInFunction)(),
|
|
@@ -89,6 +95,7 @@ const mergeChunksAndFinishRender = async (options) => {
|
|
|
89
95
|
options.onAllChunks({
|
|
90
96
|
inputProps: options.inputProps,
|
|
91
97
|
serializedResolvedProps: options.serializedResolvedProps,
|
|
98
|
+
framesPerLambda: options.framesPerLambda,
|
|
92
99
|
});
|
|
93
100
|
const encodingStart = Date.now();
|
|
94
101
|
const { outfile, cleanupChunksProm } = await (0, concat_videos_1.concatVideosS3)({
|
|
@@ -102,10 +109,14 @@ const mergeChunksAndFinishRender = async (options) => {
|
|
|
102
109
|
audioCodec: options.audioCodec,
|
|
103
110
|
audioBitrate: options.audioBitrate,
|
|
104
111
|
logLevel: options.logLevel,
|
|
112
|
+
framesPerLambda: options.framesPerLambda,
|
|
105
113
|
binariesDirectory: options.binariesDirectory,
|
|
114
|
+
cancelSignal: undefined,
|
|
115
|
+
preferLossless: options.preferLossless,
|
|
106
116
|
});
|
|
107
117
|
const encodingStop = Date.now();
|
|
108
118
|
const outputSize = fs_1.default.statSync(outfile);
|
|
119
|
+
const writeToS3 = (0, timer_1.timer)(`Writing to S3 (${outputSize.size} bytes)`, options.logLevel);
|
|
109
120
|
await (0, io_1.lambdaWriteFile)({
|
|
110
121
|
bucketName: options.renderBucketName,
|
|
111
122
|
key: options.key,
|
|
@@ -116,6 +127,7 @@ const mergeChunksAndFinishRender = async (options) => {
|
|
|
116
127
|
downloadBehavior: options.downloadBehavior,
|
|
117
128
|
customCredentials: options.customCredentials,
|
|
118
129
|
});
|
|
130
|
+
writeToS3.end();
|
|
119
131
|
const contents = await (0, io_1.lambdaLs)({
|
|
120
132
|
bucketName: options.bucketName,
|
|
121
133
|
prefix: (0, constants_1.rendersPrefix)(options.renderId),
|
|
@@ -142,6 +154,8 @@ const mergeChunksAndFinishRender = async (options) => {
|
|
|
142
154
|
const jobs = (0, get_files_to_delete_1.getFilesToDelete)({
|
|
143
155
|
chunkCount: options.chunkCount,
|
|
144
156
|
renderId: options.renderId,
|
|
157
|
+
hasAudio,
|
|
158
|
+
hasVideo,
|
|
145
159
|
});
|
|
146
160
|
const deletProm = options.logLevel === 'verbose'
|
|
147
161
|
? Promise.resolve(0)
|
|
@@ -1,16 +1,18 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.timer = void 0;
|
|
4
|
+
const renderer_1 = require("@remotion/renderer");
|
|
4
5
|
const formatTime = (time) => {
|
|
5
6
|
return time + 'ms';
|
|
6
7
|
};
|
|
7
|
-
const timer = (label) => {
|
|
8
|
+
const timer = (label, logLevel) => {
|
|
8
9
|
const start = Date.now();
|
|
10
|
+
renderer_1.RenderInternals.Log.verbose({ indent: false, logLevel }, `${label} - start\n`);
|
|
9
11
|
return {
|
|
10
12
|
end: () => {
|
|
11
13
|
const end = Date.now();
|
|
12
14
|
const time = end - start;
|
|
13
|
-
|
|
15
|
+
renderer_1.RenderInternals.Log.verbose({ indent: false, logLevel }, `${label} - ${formatTime(time)}\n`);
|
|
14
16
|
},
|
|
15
17
|
};
|
|
16
18
|
};
|
package/dist/functions/launch.js
CHANGED
|
@@ -110,7 +110,12 @@ const innerLaunchHandler = async ({ functionName, params, options, onAllChunksAv
|
|
|
110
110
|
framesPerLambda,
|
|
111
111
|
durationInFrames: frameCount.length,
|
|
112
112
|
});
|
|
113
|
-
(0, validate_outname_1.validateOutname)(
|
|
113
|
+
(0, validate_outname_1.validateOutname)({
|
|
114
|
+
outName: params.outName,
|
|
115
|
+
codec: params.codec,
|
|
116
|
+
audioCodecSetting: params.audioCodec,
|
|
117
|
+
separateAudioTo: null,
|
|
118
|
+
});
|
|
114
119
|
(0, validate_privacy_1.validatePrivacy)(params.privacy, true);
|
|
115
120
|
renderer_1.RenderInternals.validatePuppeteerTimeout(params.timeoutInMilliseconds);
|
|
116
121
|
const { chunks } = (0, plan_frame_ranges_1.planFrameRanges)({
|
|
@@ -122,7 +127,7 @@ const innerLaunchHandler = async ({ functionName, params, options, onAllChunksAv
|
|
|
122
127
|
throw new Error(`Too many functions: This render would cause ${chunks.length} functions to spawn. We limit this amount to ${constants_1.MAX_FUNCTIONS_PER_RENDER} functions as more would result in diminishing returns. Values set: frameCount = ${frameCount}, framesPerLambda=${framesPerLambda}. See ${docs_url_1.DOCS_URL}/docs/lambda/concurrency#too-many-functions for help.`);
|
|
123
128
|
}
|
|
124
129
|
const sortedChunks = chunks.slice().sort((a, b) => a[0] - b[0]);
|
|
125
|
-
const reqSend = (0, timer_1.timer)('sending off requests');
|
|
130
|
+
const reqSend = (0, timer_1.timer)('sending off requests', params.logLevel);
|
|
126
131
|
const serializedResolved = (0, compress_props_1.serializeOrThrow)(comp.props, 'resolved-props');
|
|
127
132
|
const needsToUpload = (0, compress_props_1.getNeedsToUpload)('video-or-audio', [
|
|
128
133
|
serializedResolved.length,
|
|
@@ -181,6 +186,7 @@ const innerLaunchHandler = async ({ functionName, params, options, onAllChunksAv
|
|
|
181
186
|
offthreadVideoCacheSizeInBytes: params.offthreadVideoCacheSizeInBytes,
|
|
182
187
|
deleteAfter: params.deleteAfter,
|
|
183
188
|
colorSpace: params.colorSpace,
|
|
189
|
+
preferLossless: params.preferLossless,
|
|
184
190
|
};
|
|
185
191
|
return payload;
|
|
186
192
|
});
|
|
@@ -216,6 +222,7 @@ const innerLaunchHandler = async ({ functionName, params, options, onAllChunksAv
|
|
|
216
222
|
numberOfGifLoops: params.numberOfGifLoops,
|
|
217
223
|
downloadBehavior: params.downloadBehavior,
|
|
218
224
|
audioBitrate: params.audioBitrate,
|
|
225
|
+
muted: params.muted,
|
|
219
226
|
};
|
|
220
227
|
const { key, renderBucketName, customCredentials } = (0, expected_out_name_1.getExpectedOutName)(renderMetadata, params.bucketName, typeof params.outName === 'string' || typeof params.outName === 'undefined'
|
|
221
228
|
? null
|
|
@@ -276,7 +283,9 @@ const innerLaunchHandler = async ({ functionName, params, options, onAllChunksAv
|
|
|
276
283
|
onAllChunks: onAllChunksAvailable,
|
|
277
284
|
audioBitrate: params.audioBitrate,
|
|
278
285
|
logLevel: params.logLevel,
|
|
286
|
+
framesPerLambda,
|
|
279
287
|
binariesDirectory: null,
|
|
288
|
+
preferLossless: params.preferLossless,
|
|
280
289
|
});
|
|
281
290
|
return postRenderData;
|
|
282
291
|
};
|
|
@@ -307,6 +316,8 @@ const launchHandler = async (params, options) => {
|
|
|
307
316
|
serializedResolvedProps: allChunksAvailable.serializedResolvedProps,
|
|
308
317
|
inputProps: allChunksAvailable.inputProps,
|
|
309
318
|
logLevel: params.logLevel,
|
|
319
|
+
framesPerLambda: allChunksAvailable.framesPerLambda,
|
|
320
|
+
preferLossless: params.preferLossless,
|
|
310
321
|
},
|
|
311
322
|
retries: 2,
|
|
312
323
|
});
|
|
@@ -400,8 +411,12 @@ const launchHandler = async (params, options) => {
|
|
|
400
411
|
functionName,
|
|
401
412
|
params,
|
|
402
413
|
options,
|
|
403
|
-
onAllChunksAvailable: ({ inputProps, serializedResolvedProps }) => {
|
|
404
|
-
allChunksAvailable = {
|
|
414
|
+
onAllChunksAvailable: ({ inputProps, serializedResolvedProps, framesPerLambda, }) => {
|
|
415
|
+
allChunksAvailable = {
|
|
416
|
+
inputProps,
|
|
417
|
+
serializedResolvedProps,
|
|
418
|
+
framesPerLambda,
|
|
419
|
+
};
|
|
405
420
|
},
|
|
406
421
|
});
|
|
407
422
|
clearTimeout(webhookDueToTimeout);
|
package/dist/functions/merge.js
CHANGED
|
@@ -23,6 +23,9 @@ const mergeHandler = async (params, options) => {
|
|
|
23
23
|
if (!renderMetadata.codec) {
|
|
24
24
|
throw new Error('expected codec');
|
|
25
25
|
}
|
|
26
|
+
if (renderMetadata.type === 'still') {
|
|
27
|
+
throw new Error('Cannot merge stills');
|
|
28
|
+
}
|
|
26
29
|
const { key, renderBucketName, customCredentials } = (0, expected_out_name_1.getExpectedOutName)(renderMetadata, params.bucketName, typeof params.outName === 'string' || typeof params.outName === 'undefined'
|
|
27
30
|
? null
|
|
28
31
|
: (_b = (_a = params.outName) === null || _a === void 0 ? void 0 : _a.s3OutputProvider) !== null && _b !== void 0 ? _b : null);
|
|
@@ -51,7 +54,9 @@ const mergeHandler = async (params, options) => {
|
|
|
51
54
|
},
|
|
52
55
|
audioBitrate: renderMetadata.audioBitrate,
|
|
53
56
|
logLevel: params.logLevel,
|
|
57
|
+
framesPerLambda: params.framesPerLambda,
|
|
54
58
|
binariesDirectory: null,
|
|
59
|
+
preferLossless: params.preferLossless,
|
|
55
60
|
});
|
|
56
61
|
return { type: 'success', postRenderData };
|
|
57
62
|
};
|
|
@@ -13,7 +13,9 @@ const chunk_progress_1 = require("../shared/chunk-progress");
|
|
|
13
13
|
const compress_props_1 = require("../shared/compress-props");
|
|
14
14
|
const constants_1 = require("../shared/constants");
|
|
15
15
|
const is_flaky_error_1 = require("../shared/is-flaky-error");
|
|
16
|
+
const truthy_1 = require("../shared/truthy");
|
|
16
17
|
const why_is_node_running_1 = require("../shared/why-is-node-running");
|
|
18
|
+
const can_concat_seamlessly_1 = require("./helpers/can-concat-seamlessly");
|
|
17
19
|
const get_browser_instance_1 = require("./helpers/get-browser-instance");
|
|
18
20
|
const get_chromium_executable_path_1 = require("./helpers/get-chromium-executable-path");
|
|
19
21
|
const get_current_region_1 = require("./helpers/get-current-region");
|
|
@@ -59,13 +61,30 @@ const renderHandler = async (params, options, logs) => {
|
|
|
59
61
|
startDate: start,
|
|
60
62
|
};
|
|
61
63
|
const outdir = renderer_1.RenderInternals.tmpDir(constants_1.RENDERER_PATH_TOKEN);
|
|
62
|
-
const
|
|
63
|
-
|
|
64
|
-
: params.codec;
|
|
65
|
-
const outputLocation = node_path_1.default.join(outdir, `localchunk-${String(params.chunk).padStart(8, '0')}.${renderer_1.RenderInternals.getFileExtensionFromCodec(chunkCodec, renderer_1.RenderInternals.getDefaultAudioCodec({
|
|
64
|
+
const chunk = `localchunk-${String(params.chunk).padStart(8, '0')}`;
|
|
65
|
+
const defaultAudioCodec = renderer_1.RenderInternals.getDefaultAudioCodec({
|
|
66
66
|
codec: params.codec,
|
|
67
|
-
preferLossless:
|
|
68
|
-
})
|
|
67
|
+
preferLossless: params.preferLossless,
|
|
68
|
+
});
|
|
69
|
+
const seamlessAudio = (0, can_concat_seamlessly_1.canConcatAudioSeamlessly)(defaultAudioCodec);
|
|
70
|
+
const seamlessVideo = (0, can_concat_seamlessly_1.canConcatVideoSeamlessly)(params.codec);
|
|
71
|
+
renderer_1.RenderInternals.Log.verbose({ indent: false, logLevel: params.logLevel }, `Preparing for rendering a chunk. Audio = ${seamlessAudio ? 'seamless' : 'normal'}, Video = ${seamlessVideo ? 'seamless' : 'normal'}`, params.logLevel);
|
|
72
|
+
const chunkCodec = params.codec === 'gif'
|
|
73
|
+
? 'h264-mkv'
|
|
74
|
+
: seamlessVideo
|
|
75
|
+
? 'h264-ts'
|
|
76
|
+
: params.codec;
|
|
77
|
+
const audioCodec = seamlessAudio
|
|
78
|
+
? defaultAudioCodec
|
|
79
|
+
: 'pcm-16';
|
|
80
|
+
const videoExtension = renderer_1.RenderInternals.getFileExtensionFromCodec(chunkCodec, audioCodec);
|
|
81
|
+
const audioExtension = audioCodec
|
|
82
|
+
? renderer_1.RenderInternals.getExtensionFromAudioCodec(audioCodec)
|
|
83
|
+
: null;
|
|
84
|
+
const videoOutputLocation = node_path_1.default.join(outdir, `${chunk}.${videoExtension}`);
|
|
85
|
+
const audioOutputLocation = audioExtension
|
|
86
|
+
? node_path_1.default.join(outdir, `${chunk}.${audioExtension}`)
|
|
87
|
+
: null;
|
|
69
88
|
const resolvedProps = await resolvedPropsPromise;
|
|
70
89
|
const serializedInputPropsWithCustomSchema = await inputPropsPromise;
|
|
71
90
|
await new Promise((resolve, reject) => {
|
|
@@ -126,7 +145,7 @@ const renderHandler = async (params, options, logs) => {
|
|
|
126
145
|
onBrowserLog: (log) => {
|
|
127
146
|
logs.push(log);
|
|
128
147
|
},
|
|
129
|
-
outputLocation,
|
|
148
|
+
outputLocation: videoOutputLocation,
|
|
130
149
|
codec: chunkCodec,
|
|
131
150
|
crf: (_c = params.crf) !== null && _c !== void 0 ? _c : null,
|
|
132
151
|
pixelFormat: (_d = params.pixelFormat) !== null && _d !== void 0 ? _d : renderer_1.RenderInternals.DEFAULT_PIXEL_FORMAT,
|
|
@@ -146,11 +165,8 @@ const renderHandler = async (params, options, logs) => {
|
|
|
146
165
|
videoBitrate: params.videoBitrate,
|
|
147
166
|
encodingBufferSize: params.encodingBufferSize,
|
|
148
167
|
encodingMaxRate: params.encodingMaxRate,
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
// Special flag only in Lambda renderer which improves the audio quality
|
|
152
|
-
audioCodec: null,
|
|
153
|
-
preferLossless: true,
|
|
168
|
+
audioCodec,
|
|
169
|
+
preferLossless: params.preferLossless,
|
|
154
170
|
browserExecutable: (0, get_chromium_executable_path_1.executablePath)(),
|
|
155
171
|
cancelSignal: undefined,
|
|
156
172
|
disallowParallelEncoding: false,
|
|
@@ -163,6 +179,8 @@ const renderHandler = async (params, options, logs) => {
|
|
|
163
179
|
colorSpace: params.colorSpace,
|
|
164
180
|
finishRenderProgress: () => undefined,
|
|
165
181
|
binariesDirectory: null,
|
|
182
|
+
separateAudioTo: audioOutputLocation,
|
|
183
|
+
forSeamlessAacConcatenation: seamlessAudio,
|
|
166
184
|
})
|
|
167
185
|
.then(({ slowestFrames }) => {
|
|
168
186
|
console.log(`Slowest frames:`);
|
|
@@ -180,23 +198,45 @@ const renderHandler = async (params, options, logs) => {
|
|
|
180
198
|
};
|
|
181
199
|
renderer_1.RenderInternals.Log.verbose({ indent: false, logLevel: params.logLevel }, 'Writing chunk to S3');
|
|
182
200
|
const writeStart = Date.now();
|
|
183
|
-
await
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
201
|
+
await Promise.all([
|
|
202
|
+
(0, io_1.lambdaWriteFile)({
|
|
203
|
+
bucketName: params.bucketName,
|
|
204
|
+
key: (0, constants_1.chunkKeyForIndex)({
|
|
205
|
+
renderId: params.renderId,
|
|
206
|
+
index: params.chunk,
|
|
207
|
+
type: 'video',
|
|
208
|
+
}),
|
|
209
|
+
body: node_fs_1.default.createReadStream(videoOutputLocation),
|
|
210
|
+
region: (0, get_current_region_1.getCurrentRegionInFunction)(),
|
|
211
|
+
privacy: params.privacy,
|
|
212
|
+
expectedBucketOwner: options.expectedBucketOwner,
|
|
213
|
+
downloadBehavior: null,
|
|
214
|
+
customCredentials: null,
|
|
188
215
|
}),
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
216
|
+
audioOutputLocation
|
|
217
|
+
? (0, io_1.lambdaWriteFile)({
|
|
218
|
+
bucketName: params.bucketName,
|
|
219
|
+
key: (0, constants_1.chunkKeyForIndex)({
|
|
220
|
+
renderId: params.renderId,
|
|
221
|
+
index: params.chunk,
|
|
222
|
+
type: 'audio',
|
|
223
|
+
}),
|
|
224
|
+
body: node_fs_1.default.createReadStream(audioOutputLocation),
|
|
225
|
+
region: (0, get_current_region_1.getCurrentRegionInFunction)(),
|
|
226
|
+
privacy: params.privacy,
|
|
227
|
+
expectedBucketOwner: options.expectedBucketOwner,
|
|
228
|
+
downloadBehavior: null,
|
|
229
|
+
customCredentials: null,
|
|
230
|
+
})
|
|
231
|
+
: null,
|
|
232
|
+
]);
|
|
196
233
|
renderer_1.RenderInternals.Log.verbose({ indent: false, logLevel: params.logLevel }, `Wrote chunk to S3 (${Date.now() - writeStart}ms)`);
|
|
197
234
|
renderer_1.RenderInternals.Log.verbose({ indent: false, logLevel: params.logLevel }, 'Cleaning up and writing timings');
|
|
198
235
|
await Promise.all([
|
|
199
|
-
node_fs_1.default.promises.rm(
|
|
236
|
+
node_fs_1.default.promises.rm(videoOutputLocation, { recursive: true }),
|
|
237
|
+
audioOutputLocation
|
|
238
|
+
? node_fs_1.default.promises.rm(audioOutputLocation, { recursive: true })
|
|
239
|
+
: null,
|
|
200
240
|
node_fs_1.default.promises.rm(outputPath, { recursive: true }),
|
|
201
241
|
(0, io_1.lambdaWriteFile)({
|
|
202
242
|
bucketName: params.bucketName,
|
|
@@ -213,7 +253,7 @@ const renderHandler = async (params, options, logs) => {
|
|
|
213
253
|
downloadBehavior: null,
|
|
214
254
|
customCredentials: null,
|
|
215
255
|
}),
|
|
216
|
-
]);
|
|
256
|
+
].filter(truthy_1.truthy));
|
|
217
257
|
renderer_1.RenderInternals.Log.verbose({ indent: false, logLevel: params.logLevel }, 'Done!');
|
|
218
258
|
return {};
|
|
219
259
|
};
|
package/dist/functions/start.js
CHANGED
|
@@ -86,6 +86,7 @@ const startHandler = async (params, options) => {
|
|
|
86
86
|
offthreadVideoCacheSizeInBytes: params.offthreadVideoCacheSizeInBytes,
|
|
87
87
|
deleteAfter: params.deleteAfter,
|
|
88
88
|
colorSpace: params.colorSpace,
|
|
89
|
+
preferLossless: params.preferLossless,
|
|
89
90
|
};
|
|
90
91
|
// Don't replace with callLambda(), we want to return before the render is snone
|
|
91
92
|
await (0, aws_clients_1.getLambdaClient)((0, get_current_region_1.getCurrentRegionInFunction)()).send(new client_lambda_1.InvokeCommand({
|
package/dist/functions/still.js
CHANGED
|
@@ -43,7 +43,12 @@ const innerStillHandler = async ({ params: lambdaParams, expectedBucketOwner, re
|
|
|
43
43
|
}
|
|
44
44
|
(0, validate_download_behavior_1.validateDownloadBehavior)(lambdaParams.downloadBehavior);
|
|
45
45
|
(0, validate_privacy_1.validatePrivacy)(lambdaParams.privacy, true);
|
|
46
|
-
(0, validate_outname_1.validateOutname)(
|
|
46
|
+
(0, validate_outname_1.validateOutname)({
|
|
47
|
+
outName: lambdaParams.outName,
|
|
48
|
+
codec: null,
|
|
49
|
+
audioCodecSetting: null,
|
|
50
|
+
separateAudioTo: null,
|
|
51
|
+
});
|
|
47
52
|
const start = Date.now();
|
|
48
53
|
const browserInstancePromise = (0, get_browser_instance_1.getBrowserInstance)(lambdaParams.logLevel, false, lambdaParams.chromiumOptions);
|
|
49
54
|
const bucketNamePromise = (_a = lambdaParams.bucketName) !== null && _a !== void 0 ? _a : (0, get_or_create_bucket_1.internalGetOrCreateBucket)({
|
|
@@ -112,8 +117,6 @@ const innerStillHandler = async ({ params: lambdaParams, expectedBucketOwner, re
|
|
|
112
117
|
renderId,
|
|
113
118
|
outName: (_c = lambdaParams.outName) !== null && _c !== void 0 ? _c : undefined,
|
|
114
119
|
privacy: lambdaParams.privacy,
|
|
115
|
-
everyNthFrame: 1,
|
|
116
|
-
frameRange: [lambdaParams.frame, lambdaParams.frame],
|
|
117
120
|
audioCodec: null,
|
|
118
121
|
deleteAfter: lambdaParams.deleteAfter,
|
|
119
122
|
numberOfGifLoops: null,
|
package/dist/internals.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
export declare const LambdaInternals: {
|
|
2
2
|
executeCommand: (args: string[], remotionRoot: string, logLevel: "verbose" | "info" | "warn" | "error") => Promise<void>;
|
|
3
|
-
makeLambdaRenderMediaPayload: ({ rendererFunctionName, frameRange, framesPerLambda, forceBucketName: bucketName, codec, composition, serveUrl, imageFormat, inputProps, region, crf, envVariables, pixelFormat, proResProfile, x264Preset, maxRetries, privacy, logLevel, outName, timeoutInMilliseconds, chromiumOptions, scale, everyNthFrame, numberOfGifLoops, audioBitrate, concurrencyPerLambda, audioCodec, forceHeight, forceWidth, webhook, videoBitrate, encodingMaxRate, encodingBufferSize, downloadBehavior, muted, overwrite, jpegQuality, offthreadVideoCacheSizeInBytes, deleteAfter, colorSpace, }: import("./api/make-lambda-payload").InnerRenderMediaOnLambdaInput) => Promise<import("./defaults").LambdaStartPayload>;
|
|
3
|
+
makeLambdaRenderMediaPayload: ({ rendererFunctionName, frameRange, framesPerLambda, forceBucketName: bucketName, codec, composition, serveUrl, imageFormat, inputProps, region, crf, envVariables, pixelFormat, proResProfile, x264Preset, maxRetries, privacy, logLevel, outName, timeoutInMilliseconds, chromiumOptions, scale, everyNthFrame, numberOfGifLoops, audioBitrate, concurrencyPerLambda, audioCodec, forceHeight, forceWidth, webhook, videoBitrate, encodingMaxRate, encodingBufferSize, downloadBehavior, muted, overwrite, jpegQuality, offthreadVideoCacheSizeInBytes, deleteAfter, colorSpace, preferLossless, }: import("./api/make-lambda-payload").InnerRenderMediaOnLambdaInput) => Promise<import("./defaults").LambdaStartPayload>;
|
|
4
4
|
getRenderProgressPayload: ({ bucketName, renderId, s3OutputProvider, logLevel, }: import(".").GetRenderProgressInput) => import("./defaults").LambdaStatusPayload;
|
|
5
5
|
makeLambdaRenderStillPayload: ({ serveUrl, inputProps, imageFormat, envVariables, quality, jpegQuality, region, maxRetries, composition, privacy, frame, logLevel, outName, timeoutInMilliseconds, chromiumOptions, scale, downloadBehavior, forceHeight, forceWidth, forceBucketName, dumpBrowserLogs, offthreadVideoCacheSizeInBytes, deleteAfter, }: import(".").RenderStillOnLambdaInput) => Promise<{
|
|
6
6
|
type: import("./defaults").LambdaRoutines.still;
|
|
@@ -52,9 +52,10 @@ export declare const lambdaTimingsKey: ({ renderId, chunk, start, rendered, }: {
|
|
|
52
52
|
rendered: number;
|
|
53
53
|
}) => string;
|
|
54
54
|
export declare const chunkKey: (renderId: string) => string;
|
|
55
|
-
export declare const chunkKeyForIndex: ({ renderId, index, }: {
|
|
55
|
+
export declare const chunkKeyForIndex: ({ renderId, index, type, }: {
|
|
56
56
|
renderId: string;
|
|
57
57
|
index: number;
|
|
58
|
+
type: 'video' | 'audio';
|
|
58
59
|
}) => string;
|
|
59
60
|
export declare const getErrorKeyPrefix: (renderId: string) => string;
|
|
60
61
|
export declare const getErrorFileName: ({ renderId, chunk, attempt, }: {
|
|
@@ -157,6 +158,7 @@ export type LambdaStartPayload = {
|
|
|
157
158
|
offthreadVideoCacheSizeInBytes: number | null;
|
|
158
159
|
deleteAfter: DeleteAfter | null;
|
|
159
160
|
colorSpace: ColorSpace;
|
|
161
|
+
preferLossless: boolean;
|
|
160
162
|
};
|
|
161
163
|
export type LambdaStatusPayload = {
|
|
162
164
|
type: LambdaRoutines.status;
|
|
@@ -214,6 +216,7 @@ export type LambdaPayloads = {
|
|
|
214
216
|
offthreadVideoCacheSizeInBytes: number | null;
|
|
215
217
|
deleteAfter: DeleteAfter | null;
|
|
216
218
|
colorSpace: ColorSpace;
|
|
219
|
+
preferLossless: boolean;
|
|
217
220
|
};
|
|
218
221
|
status: LambdaStatusPayload;
|
|
219
222
|
renderer: {
|
|
@@ -255,6 +258,7 @@ export type LambdaPayloads = {
|
|
|
255
258
|
launchFunctionConfig: {
|
|
256
259
|
version: string;
|
|
257
260
|
};
|
|
261
|
+
preferLossless: boolean;
|
|
258
262
|
offthreadVideoCacheSizeInBytes: number | null;
|
|
259
263
|
deleteAfter: DeleteAfter | null;
|
|
260
264
|
colorSpace: ColorSpace;
|
|
@@ -304,6 +308,8 @@ export type LambdaPayloads = {
|
|
|
304
308
|
inputProps: SerializedInputProps;
|
|
305
309
|
serializedResolvedProps: SerializedInputProps;
|
|
306
310
|
logLevel: LogLevel;
|
|
311
|
+
framesPerLambda: number;
|
|
312
|
+
preferLossless: boolean;
|
|
307
313
|
};
|
|
308
314
|
};
|
|
309
315
|
export type LambdaPayload = LambdaPayloads[LambdaRoutines];
|
|
@@ -316,6 +322,9 @@ type Discriminated = {
|
|
|
316
322
|
} | {
|
|
317
323
|
type: 'video';
|
|
318
324
|
imageFormat: VideoImageFormat;
|
|
325
|
+
muted: boolean;
|
|
326
|
+
frameRange: [number, number];
|
|
327
|
+
everyNthFrame: number;
|
|
319
328
|
};
|
|
320
329
|
export type RenderMetadata = Discriminated & {
|
|
321
330
|
siteId: string;
|
|
@@ -335,8 +344,6 @@ export type RenderMetadata = Discriminated & {
|
|
|
335
344
|
renderId: string;
|
|
336
345
|
outName: OutNameInputWithoutCredentials | undefined;
|
|
337
346
|
privacy: Privacy;
|
|
338
|
-
frameRange: [number, number];
|
|
339
|
-
everyNthFrame: number;
|
|
340
347
|
deleteAfter: DeleteAfter | null;
|
|
341
348
|
numberOfGifLoops: number | null;
|
|
342
349
|
audioBitrate: string | null;
|
package/dist/shared/constants.js
CHANGED
|
@@ -47,7 +47,7 @@ const lambdaTimingsKey = ({ renderId, chunk, start, rendered, }) => `${(0, expor
|
|
|
47
47
|
exports.lambdaTimingsKey = lambdaTimingsKey;
|
|
48
48
|
const chunkKey = (renderId) => `${(0, exports.rendersPrefix)(renderId)}/chunks/chunk`;
|
|
49
49
|
exports.chunkKey = chunkKey;
|
|
50
|
-
const chunkKeyForIndex = ({ renderId, index, }) => `${(0, exports.chunkKey)(renderId)}:${String(index).padStart(8, '0')}`;
|
|
50
|
+
const chunkKeyForIndex = ({ renderId, index, type, }) => `${(0, exports.chunkKey)(renderId)}:${String(index).padStart(8, '0')}:${type}`;
|
|
51
51
|
exports.chunkKeyForIndex = chunkKeyForIndex;
|
|
52
52
|
const getErrorKeyPrefix = (renderId) => `${(0, exports.rendersPrefix)(renderId)}/errors/`;
|
|
53
53
|
exports.getErrorKeyPrefix = getErrorKeyPrefix;
|
|
@@ -2,13 +2,14 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.parseLambdaChunkKey = void 0;
|
|
4
4
|
const parseLambdaChunkKey = (key) => {
|
|
5
|
-
const match = key.match(/^renders\/(.*)\/chunks\/chunk:([0-9]+)$/);
|
|
5
|
+
const match = key.match(/^renders\/(.*)\/chunks\/chunk:([0-9]+):(video|audio)$/);
|
|
6
6
|
if (!match) {
|
|
7
7
|
throw new Error(`Cannot parse filename ${key} into timing information. Malformed data.`);
|
|
8
8
|
}
|
|
9
9
|
return {
|
|
10
10
|
renderId: match[1],
|
|
11
11
|
chunk: Number(match[2]),
|
|
12
|
+
type: match[3],
|
|
12
13
|
};
|
|
13
14
|
};
|
|
14
15
|
exports.parseLambdaChunkKey = parseLambdaChunkKey;
|
|
@@ -1,3 +1,8 @@
|
|
|
1
1
|
import type { AudioCodec, Codec } from '@remotion/renderer';
|
|
2
2
|
import type { OutNameInputWithoutCredentials } from './constants';
|
|
3
|
-
export declare const validateOutname: (outName
|
|
3
|
+
export declare const validateOutname: ({ outName, codec, audioCodecSetting, separateAudioTo, }: {
|
|
4
|
+
outName: OutNameInputWithoutCredentials | undefined | null;
|
|
5
|
+
codec: Codec | null;
|
|
6
|
+
audioCodecSetting: AudioCodec | null;
|
|
7
|
+
separateAudioTo: string | null;
|
|
8
|
+
}) => void;
|
|
@@ -14,7 +14,7 @@ const validateS3Key = (s3Key) => {
|
|
|
14
14
|
'. Check for invalid characters.');
|
|
15
15
|
}
|
|
16
16
|
};
|
|
17
|
-
const validateOutname = (outName, codec,
|
|
17
|
+
const validateOutname = ({ outName, codec, audioCodecSetting, separateAudioTo, }) => {
|
|
18
18
|
if (typeof outName === 'undefined' || outName === null) {
|
|
19
19
|
return;
|
|
20
20
|
}
|
|
@@ -26,9 +26,10 @@ const validateOutname = (outName, codec, audioCodec) => {
|
|
|
26
26
|
if (codec) {
|
|
27
27
|
pure_1.NoReactAPIs.validateOutputFilename({
|
|
28
28
|
codec,
|
|
29
|
-
|
|
29
|
+
audioCodecSetting,
|
|
30
30
|
extension: pure_1.NoReactAPIs.getExtensionOfFilename(outName),
|
|
31
31
|
preferLossless: false,
|
|
32
|
+
separateAudioTo,
|
|
32
33
|
});
|
|
33
34
|
}
|
|
34
35
|
validateS3Key(outName);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@remotion/lambda",
|
|
3
|
-
"version": "4.0.
|
|
3
|
+
"version": "4.0.123",
|
|
4
4
|
"description": "Distributed renderer for Remotion based on AWS Lambda",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"sideEffects": false,
|
|
@@ -26,10 +26,10 @@
|
|
|
26
26
|
"aws-policies": "^1.0.1",
|
|
27
27
|
"mime-types": "2.1.34",
|
|
28
28
|
"zod": "3.22.3",
|
|
29
|
-
"@remotion/
|
|
30
|
-
"@remotion/
|
|
31
|
-
"
|
|
32
|
-
"remotion": "4.0.
|
|
29
|
+
"@remotion/cli": "4.0.123",
|
|
30
|
+
"@remotion/renderer": "4.0.123",
|
|
31
|
+
"remotion": "4.0.123",
|
|
32
|
+
"@remotion/bundler": "4.0.123"
|
|
33
33
|
},
|
|
34
34
|
"devDependencies": {
|
|
35
35
|
"@jonny/eslint-config": "3.0.276",
|
|
@@ -43,11 +43,11 @@
|
|
|
43
43
|
"ts-node": "^10.8.0",
|
|
44
44
|
"vitest": "0.31.1",
|
|
45
45
|
"zip-lib": "^0.7.2",
|
|
46
|
-
"@remotion/bundler": "4.0.
|
|
47
|
-
"@remotion/compositor-linux-arm64-gnu": "4.0.
|
|
46
|
+
"@remotion/bundler": "4.0.123",
|
|
47
|
+
"@remotion/compositor-linux-arm64-gnu": "4.0.123"
|
|
48
48
|
},
|
|
49
49
|
"peerDependencies": {
|
|
50
|
-
"@remotion/bundler": "4.0.
|
|
50
|
+
"@remotion/bundler": "4.0.123"
|
|
51
51
|
},
|
|
52
52
|
"publishConfig": {
|
|
53
53
|
"access": "public"
|
package/remotionlambda-arm64.zip
CHANGED
|
Binary file
|