@remotion/lambda 4.0.8 → 4.0.11
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/get-compositions-on-lambda.js +3 -1
- package/dist/api/make-lambda-payload.js +3 -1
- package/dist/api/render-still-on-lambda.js +1 -1
- package/dist/functions/launch.js +14 -2
- package/dist/functions/renderer.js +14 -9
- package/dist/shared/compress-props.d.ts +1 -1
- package/dist/shared/compress-props.js +6 -4
- package/dist/shared/invoke-webhook.d.ts +3 -2
- package/dist/shared/invoke-webhook.js +24 -1
- package/package.json +8 -8
- package/remotionlambda-arm64.zip +0 -0
|
@@ -26,7 +26,9 @@ const getCompositionsOnLambda = async ({ chromiumOptions, serveUrl, region, inpu
|
|
|
26
26
|
region,
|
|
27
27
|
userSpecifiedBucketName: bucketName !== null && bucketName !== void 0 ? bucketName : null,
|
|
28
28
|
propsType: 'input-props',
|
|
29
|
-
needsToUpload: (0, compress_props_1.getNeedsToUpload)('video-or-audio',
|
|
29
|
+
needsToUpload: (0, compress_props_1.getNeedsToUpload)('video-or-audio', [
|
|
30
|
+
stringifiedInputProps.length,
|
|
31
|
+
]),
|
|
30
32
|
});
|
|
31
33
|
try {
|
|
32
34
|
const res = await (0, call_lambda_1.callLambda)({
|
|
@@ -23,7 +23,9 @@ const makeLambdaRenderMediaPayload = async ({ rendererFunctionName, frameRange,
|
|
|
23
23
|
const serialized = await (0, compress_props_1.compressInputProps)({
|
|
24
24
|
stringifiedInputProps,
|
|
25
25
|
region,
|
|
26
|
-
needsToUpload: (0, compress_props_1.getNeedsToUpload)('video-or-audio',
|
|
26
|
+
needsToUpload: (0, compress_props_1.getNeedsToUpload)('video-or-audio', [
|
|
27
|
+
stringifiedInputProps.length,
|
|
28
|
+
]),
|
|
27
29
|
userSpecifiedBucketName: bucketName !== null && bucketName !== void 0 ? bucketName : null,
|
|
28
30
|
propsType: 'input-props',
|
|
29
31
|
});
|
|
@@ -31,7 +31,7 @@ const renderStillOnLambda = async ({ functionName, serveUrl, inputProps, imageFo
|
|
|
31
31
|
const serializedInputProps = await (0, compress_props_1.compressInputProps)({
|
|
32
32
|
stringifiedInputProps,
|
|
33
33
|
region,
|
|
34
|
-
needsToUpload: (0, compress_props_1.getNeedsToUpload)('still', stringifiedInputProps),
|
|
34
|
+
needsToUpload: (0, compress_props_1.getNeedsToUpload)('still', [stringifiedInputProps.length]),
|
|
35
35
|
userSpecifiedBucketName: forceBucketName !== null && forceBucketName !== void 0 ? forceBucketName : null,
|
|
36
36
|
propsType: 'input-props',
|
|
37
37
|
});
|
package/dist/functions/launch.js
CHANGED
|
@@ -191,7 +191,12 @@ const innerLaunchHandler = async (params, options) => {
|
|
|
191
191
|
const sortedChunks = chunks.slice().sort((a, b) => a[0] - b[0]);
|
|
192
192
|
const reqSend = (0, timer_1.timer)('sending off requests');
|
|
193
193
|
const serializedResolved = (0, compress_props_1.serializeOrThrow)(comp.props, 'resolved-props');
|
|
194
|
-
const needsToUpload = (0, compress_props_1.getNeedsToUpload)('video-or-audio',
|
|
194
|
+
const needsToUpload = (0, compress_props_1.getNeedsToUpload)('video-or-audio', [
|
|
195
|
+
serializedResolved.length,
|
|
196
|
+
params.inputProps.type === 'bucket-url'
|
|
197
|
+
? params.inputProps.hash.length
|
|
198
|
+
: params.inputProps.payload.length,
|
|
199
|
+
]);
|
|
195
200
|
const serializedResolvedProps = await (0, compress_props_1.compressInputProps)({
|
|
196
201
|
propsType: 'resolved-props',
|
|
197
202
|
region: (0, get_current_region_1.getCurrentRegionInFunction)(),
|
|
@@ -368,7 +373,14 @@ const innerLaunchHandler = async (params, options) => {
|
|
|
368
373
|
else {
|
|
369
374
|
console.log('No webhook specified');
|
|
370
375
|
}
|
|
371
|
-
|
|
376
|
+
const firstError = errors[0];
|
|
377
|
+
if (firstError.chunk !== null) {
|
|
378
|
+
throw new Error(`Stopping Lambda function because error occurred while rendering chunk ${firstError.chunk}:\n${errors[0].stack
|
|
379
|
+
.split('\n')
|
|
380
|
+
.map((s) => ` ${s}`)
|
|
381
|
+
.join('\n')}`);
|
|
382
|
+
}
|
|
383
|
+
throw new Error(`Stopping Lambda function because error occurred: ${errors[0].stack}`);
|
|
372
384
|
};
|
|
373
385
|
const fps = comp.fps / params.everyNthFrame;
|
|
374
386
|
const outdir = (0, node_path_1.join)(renderer_1.RenderInternals.tmpDir(constants_1.CONCAT_FOLDER_TOKEN), 'bucket');
|
|
@@ -79,9 +79,8 @@ const renderHandler = async (params, options, logs) => {
|
|
|
79
79
|
serializedInputPropsWithCustomSchema,
|
|
80
80
|
frameRange: params.frameRange,
|
|
81
81
|
onProgress: ({ renderedFrames, encodedFrames, stitchStage }) => {
|
|
82
|
-
if (renderedFrames % 5 === 0
|
|
83
|
-
renderer_1.RenderInternals.
|
|
84
|
-
console.log(`Rendered ${renderedFrames} frames, encoded ${encodedFrames} frames, stage = ${stitchStage}`);
|
|
82
|
+
if (renderedFrames % 5 === 0) {
|
|
83
|
+
renderer_1.RenderInternals.Log.info(`Rendered ${renderedFrames} frames, encoded ${encodedFrames} frames, stage = ${stitchStage}`);
|
|
85
84
|
(0, chunk_progress_1.writeLambdaInitializedFile)({
|
|
86
85
|
attempt: params.attempt,
|
|
87
86
|
bucketName: params.bucketName,
|
|
@@ -90,10 +89,13 @@ const renderHandler = async (params, options, logs) => {
|
|
|
90
89
|
framesRendered: renderedFrames,
|
|
91
90
|
renderId: params.renderId,
|
|
92
91
|
}).catch((err) => {
|
|
93
|
-
console.log(err);
|
|
92
|
+
console.log('Could not write progress', err);
|
|
94
93
|
return reject(err);
|
|
95
94
|
});
|
|
96
95
|
}
|
|
96
|
+
else {
|
|
97
|
+
renderer_1.RenderInternals.Log.verbose(`Rendered ${renderedFrames} frames, encoded ${encodedFrames} frames, stage = ${stitchStage}`);
|
|
98
|
+
}
|
|
97
99
|
const allFrames = renderer_1.RenderInternals.getFramesToRender(params.frameRange, params.everyNthFrame);
|
|
98
100
|
if (renderedFrames === allFrames.length) {
|
|
99
101
|
console.log('Rendered all frames!');
|
|
@@ -242,11 +244,14 @@ const rendererHandler = async (params, options) => {
|
|
|
242
244
|
}
|
|
243
245
|
// If this error is encountered, we can just retry as it
|
|
244
246
|
// is a very rare error to occur
|
|
245
|
-
const
|
|
246
|
-
err.message.includes('error while loading shared libraries: libnss3.so')
|
|
247
|
+
const isRetryableError = err.message.includes('FATAL:zygote_communication_linux.cc') ||
|
|
248
|
+
err.message.includes('error while loading shared libraries: libnss3.so') ||
|
|
249
|
+
err.message.includes('but the server sent no data') ||
|
|
250
|
+
err.message.includes('Timed out while setting up the headless browser');
|
|
247
251
|
const shouldNotRetry = err.name === 'CancelledError';
|
|
248
|
-
const
|
|
249
|
-
|
|
252
|
+
const isFatal = !isRetryableError;
|
|
253
|
+
const willRetry = isRetryableError && params.retriesLeft > 0 && !shouldNotRetry;
|
|
254
|
+
console.log(`Error occurred (will retry = ${String(willRetry)})`);
|
|
250
255
|
console.log(err);
|
|
251
256
|
await (0, write_lambda_error_1.writeLambdaError)({
|
|
252
257
|
bucketName: params.bucketName,
|
|
@@ -257,7 +262,7 @@ const rendererHandler = async (params, options) => {
|
|
|
257
262
|
chunk: params.chunk,
|
|
258
263
|
frame: null,
|
|
259
264
|
type: 'renderer',
|
|
260
|
-
isFatal
|
|
265
|
+
isFatal,
|
|
261
266
|
tmpDir: (0, write_lambda_error_1.getTmpDirStateIfENoSp)(err.stack),
|
|
262
267
|
attempt: params.attempt,
|
|
263
268
|
totalAttempts: params.retriesLeft + params.attempt,
|
|
@@ -2,7 +2,7 @@ import type { AwsRegion } from '../client';
|
|
|
2
2
|
import type { SerializedInputProps } from './constants';
|
|
3
3
|
type PropsType = 'input-props' | 'resolved-props';
|
|
4
4
|
export declare const serializeOrThrow: (inputProps: Record<string, unknown>, propsType: PropsType) => string;
|
|
5
|
-
export declare const getNeedsToUpload: (type: 'still' | 'video-or-audio',
|
|
5
|
+
export declare const getNeedsToUpload: (type: 'still' | 'video-or-audio', sizes: number[]) => boolean;
|
|
6
6
|
export declare const compressInputProps: ({ stringifiedInputProps, region, userSpecifiedBucketName, propsType, needsToUpload, }: {
|
|
7
7
|
stringifiedInputProps: string;
|
|
8
8
|
region: AwsRegion;
|
|
@@ -21,10 +21,12 @@ const serializeOrThrow = (inputProps, propsType) => {
|
|
|
21
21
|
}
|
|
22
22
|
};
|
|
23
23
|
exports.serializeOrThrow = serializeOrThrow;
|
|
24
|
-
const getNeedsToUpload = (type,
|
|
25
|
-
const
|
|
26
|
-
|
|
27
|
-
|
|
24
|
+
const getNeedsToUpload = (type, sizes) => {
|
|
25
|
+
const MARGIN = 5000;
|
|
26
|
+
const MAX_INLINE_PAYLOAD_SIZE = (type === 'still' ? 5000000 : 200000) - MARGIN;
|
|
27
|
+
const sizesAlreadyUsed = sizes.reduce((a, b) => a + b);
|
|
28
|
+
if (sizesAlreadyUsed > MAX_INLINE_PAYLOAD_SIZE) {
|
|
29
|
+
console.warn(`Warning: The props are over ${Math.round(MAX_INLINE_PAYLOAD_SIZE / 1000)}KB (${Math.ceil(sizesAlreadyUsed / 1024)}KB) in size. Uploading them to S3 to circumvent AWS Lambda payload size, which may lead to slowdown.`);
|
|
28
30
|
return true;
|
|
29
31
|
}
|
|
30
32
|
return false;
|
|
@@ -38,9 +38,10 @@ export declare const mockableHttpClients: {
|
|
|
38
38
|
http: typeof http.request;
|
|
39
39
|
https: typeof https.request;
|
|
40
40
|
};
|
|
41
|
-
|
|
41
|
+
type InvokeWebhookOptions = {
|
|
42
42
|
payload: WebhookPayload;
|
|
43
43
|
url: string;
|
|
44
44
|
secret: string | null;
|
|
45
|
-
}
|
|
45
|
+
};
|
|
46
|
+
export declare const invokeWebhook: (options: InvokeWebhookOptions, retries?: number, errors?: number) => Promise<void>;
|
|
46
47
|
export {};
|
|
@@ -27,6 +27,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
27
27
|
};
|
|
28
28
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
29
29
|
exports.invokeWebhook = exports.mockableHttpClients = exports.calculateSignature = void 0;
|
|
30
|
+
const renderer_1 = require("@remotion/renderer");
|
|
30
31
|
const https_1 = __importDefault(require("https"));
|
|
31
32
|
const Crypto = __importStar(require("node:crypto"));
|
|
32
33
|
const node_http_1 = __importDefault(require("node:http"));
|
|
@@ -59,7 +60,7 @@ exports.mockableHttpClients = {
|
|
|
59
60
|
http: node_http_1.default.request,
|
|
60
61
|
https: https_1.default.request,
|
|
61
62
|
};
|
|
62
|
-
function
|
|
63
|
+
function invokeWebhookRaw({ payload, secret, url, }) {
|
|
63
64
|
const jsonPayload = JSON.stringify(payload);
|
|
64
65
|
return new Promise((resolve, reject) => {
|
|
65
66
|
const req = getWebhookClient(url)(url, {
|
|
@@ -86,4 +87,26 @@ function invokeWebhook({ payload, secret, url, }) {
|
|
|
86
87
|
req.end();
|
|
87
88
|
});
|
|
88
89
|
}
|
|
90
|
+
function exponentialBackoff(errorCount) {
|
|
91
|
+
return 1000 * 2 ** (errorCount - 1);
|
|
92
|
+
}
|
|
93
|
+
const invokeWebhook = async (options, retries = 2, errors = 0) => {
|
|
94
|
+
try {
|
|
95
|
+
await invokeWebhookRaw(options);
|
|
96
|
+
}
|
|
97
|
+
catch (err) {
|
|
98
|
+
if (retries === 0) {
|
|
99
|
+
throw err;
|
|
100
|
+
}
|
|
101
|
+
renderer_1.RenderInternals.Log.error('Could not send webhook due to error:');
|
|
102
|
+
renderer_1.RenderInternals.Log.error(err.stack);
|
|
103
|
+
renderer_1.RenderInternals.Log.error(`Retrying in ${exponentialBackoff(errors)}ms.`);
|
|
104
|
+
await new Promise((resolve) => {
|
|
105
|
+
setTimeout(() => {
|
|
106
|
+
resolve();
|
|
107
|
+
}, exponentialBackoff(errors));
|
|
108
|
+
});
|
|
109
|
+
return (0, exports.invokeWebhook)(options, retries - 1, errors + 1);
|
|
110
|
+
}
|
|
111
|
+
};
|
|
89
112
|
exports.invokeWebhook = invokeWebhook;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@remotion/lambda",
|
|
3
|
-
"version": "4.0.
|
|
3
|
+
"version": "4.0.11",
|
|
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.21.4",
|
|
29
|
-
"@remotion/
|
|
30
|
-
"@remotion/renderer": "4.0.
|
|
31
|
-
"remotion": "4.0.
|
|
32
|
-
"
|
|
29
|
+
"@remotion/cli": "4.0.11",
|
|
30
|
+
"@remotion/renderer": "4.0.11",
|
|
31
|
+
"@remotion/bundler": "4.0.11",
|
|
32
|
+
"remotion": "4.0.11"
|
|
33
33
|
},
|
|
34
34
|
"devDependencies": {
|
|
35
35
|
"@jonny/eslint-config": "3.0.266",
|
|
@@ -44,11 +44,11 @@
|
|
|
44
44
|
"typescript": "4.9.5",
|
|
45
45
|
"vitest": "0.31.1",
|
|
46
46
|
"zip-lib": "^0.7.2",
|
|
47
|
-
"@remotion/bundler": "4.0.
|
|
48
|
-
"@remotion/compositor-linux-arm64-gnu": "4.0.
|
|
47
|
+
"@remotion/bundler": "4.0.11",
|
|
48
|
+
"@remotion/compositor-linux-arm64-gnu": "4.0.11"
|
|
49
49
|
},
|
|
50
50
|
"peerDependencies": {
|
|
51
|
-
"@remotion/bundler": "4.0.
|
|
51
|
+
"@remotion/bundler": "4.0.11"
|
|
52
52
|
},
|
|
53
53
|
"publishConfig": {
|
|
54
54
|
"access": "public"
|
package/remotionlambda-arm64.zip
CHANGED
|
Binary file
|