@remotion/lambda 4.0.0-umungobongo.5 → 4.0.0-webhook.26
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/admin/make-layer-public.js +5 -5
- package/dist/api/bucket-exists.js +1 -1
- package/dist/api/clean-items.js +1 -1
- package/dist/api/create-bucket.js +1 -1
- package/dist/api/delete-render.d.ts +19 -0
- package/dist/api/delete-render.js +66 -0
- package/dist/api/delete-site.js +0 -5
- package/dist/api/deploy-function.js +4 -2
- package/dist/api/deploy-site.d.ts +2 -0
- package/dist/api/deploy-site.js +2 -0
- package/dist/api/download-media.d.ts +13 -0
- package/dist/api/download-media.js +15 -3
- package/dist/api/enable-s3-website.js +1 -1
- package/dist/api/get-aws-client.d.ts +4 -2
- package/dist/api/get-aws-client.js +7 -2
- package/dist/api/get-buckets.js +2 -2
- package/dist/api/get-function-info.d.ts +1 -2
- package/dist/api/get-functions.js +2 -1
- package/dist/api/get-render-progress.d.ts +4 -1
- package/dist/api/get-render-progress.js +5 -1
- package/dist/api/mock-functions.d.ts +4 -5
- package/dist/api/presign-url.js +6 -1
- package/dist/api/render-media-on-lambda.d.ts +18 -10
- package/dist/api/render-media-on-lambda.js +65 -40
- package/dist/api/render-still-on-lambda.d.ts +1 -0
- package/dist/api/render-still-on-lambda.js +48 -30
- package/dist/api/upload-dir.js +1 -1
- package/dist/api/validate-webhook-signature.d.ts +13 -0
- package/dist/api/validate-webhook-signature.js +32 -0
- package/dist/cli/args.d.ts +2 -0
- package/dist/cli/commands/functions/deploy.js +2 -1
- package/dist/cli/commands/render/render.js +24 -15
- package/dist/cli/commands/still.js +20 -16
- package/dist/cli/get-aws-region.js +2 -1
- package/dist/cli/helpers/determine-image-format.d.ts +10 -0
- package/dist/cli/helpers/determine-image-format.js +47 -0
- package/dist/cli/helpers/find-function-name.js +3 -2
- package/dist/cli/helpers/webhook-types.d.ts +6 -0
- package/dist/cli/helpers/webhook-types.js +2 -0
- package/dist/cli/index.js +1 -1
- package/dist/client.d.ts +4 -2
- package/dist/client.js +3 -1
- package/dist/functions/chunk-optimization/can-use-optimization.js +2 -2
- package/dist/functions/chunk-optimization/s3-optimization-file.js +1 -0
- package/dist/functions/chunk-optimization/types.d.ts +1 -2
- package/dist/functions/helpers/check-if-render-exists.d.ts +3 -0
- package/dist/functions/helpers/check-if-render-exists.js +14 -0
- package/dist/functions/helpers/expected-out-name.d.ts +4 -2
- package/dist/functions/helpers/expected-out-name.js +26 -5
- package/dist/functions/helpers/find-output-file-in-bucket.d.ts +3 -1
- package/dist/functions/helpers/find-output-file-in-bucket.js +17 -13
- package/dist/functions/helpers/get-custom-out-name.d.ts +6 -0
- package/dist/functions/helpers/get-custom-out-name.js +31 -0
- package/dist/functions/helpers/get-files-to-delete.js +1 -1
- package/dist/functions/helpers/get-lambdas-invoked-stats.js +1 -1
- package/dist/functions/helpers/get-output-url-from-metadata.d.ts +2 -1
- package/dist/functions/helpers/get-output-url-from-metadata.js +2 -2
- package/dist/functions/helpers/get-progress.d.ts +4 -2
- package/dist/functions/helpers/get-progress.js +13 -6
- package/dist/functions/helpers/get-retry-stats.js +1 -1
- package/dist/functions/helpers/io.d.ts +17 -1
- package/dist/functions/helpers/io.js +21 -6
- package/dist/functions/helpers/read-with-progress.d.ts +3 -1
- package/dist/functions/helpers/read-with-progress.js +2 -2
- package/dist/functions/helpers/write-lambda-error.d.ts +1 -1
- package/dist/functions/helpers/write-lambda-error.js +1 -0
- package/dist/functions/helpers/write-post-render-data.js +1 -0
- package/dist/functions/index.js +4 -4
- package/dist/functions/info.d.ts +2 -2
- package/dist/functions/info.js +2 -1
- package/dist/functions/launch.js +206 -13
- package/dist/functions/progress.d.ts +1 -1
- package/dist/functions/progress.js +10 -1
- package/dist/functions/renderer.js +104 -74
- package/dist/functions/start.d.ts +5 -1
- package/dist/functions/start.js +23 -1
- package/dist/functions/still.js +17 -4
- package/dist/index.d.ts +6 -2
- package/dist/index.js +5 -1
- package/dist/shared/aws-clients.d.ts +13 -2
- package/dist/shared/aws-clients.js +56 -26
- package/dist/shared/bundle-site.d.ts +2 -1
- package/dist/shared/constants.d.ts +31 -6
- package/dist/shared/constants.js +14 -7
- package/dist/shared/get-cloudwatch-stream-url.d.ts +8 -0
- package/dist/shared/get-cloudwatch-stream-url.js +7 -0
- package/dist/shared/get-function-version.d.ts +1 -2
- package/dist/shared/hosted-layers.js +60 -60
- package/dist/shared/invoke-webhook.d.ts +59 -0
- package/dist/shared/invoke-webhook.js +103 -0
- package/dist/shared/is-in-lambda.js +5 -1
- package/dist/shared/lambda-version-string.d.ts +1 -0
- package/dist/shared/lambda-version-string.js +7 -0
- package/dist/shared/validate-frames-per-lambda.d.ts +4 -1
- package/dist/shared/validate-frames-per-lambda.js +4 -3
- package/dist/shared/validate-outname.d.ts +3 -2
- package/dist/shared/validate-outname.js +5 -1
- package/package.json +9 -9
- package/remotionlambda.zip +0 -0
package/dist/functions/launch.js
CHANGED
|
@@ -8,9 +8,11 @@ const client_lambda_1 = require("@aws-sdk/client-lambda");
|
|
|
8
8
|
const renderer_1 = require("@remotion/renderer");
|
|
9
9
|
const fs_1 = __importDefault(require("fs"));
|
|
10
10
|
const remotion_1 = require("remotion");
|
|
11
|
+
const version_1 = require("remotion/version");
|
|
11
12
|
const aws_clients_1 = require("../shared/aws-clients");
|
|
12
13
|
const constants_1 = require("../shared/constants");
|
|
13
14
|
const docs_url_1 = require("../shared/docs-url");
|
|
15
|
+
const invoke_webhook_1 = require("../shared/invoke-webhook");
|
|
14
16
|
const make_s3_url_1 = require("../shared/make-s3-url");
|
|
15
17
|
const validate_frames_per_lambda_1 = require("../shared/validate-frames-per-lambda");
|
|
16
18
|
const validate_outname_1 = require("../shared/validate-outname");
|
|
@@ -28,6 +30,7 @@ const concat_videos_1 = require("./helpers/concat-videos");
|
|
|
28
30
|
const create_post_render_data_1 = require("./helpers/create-post-render-data");
|
|
29
31
|
const delete_chunks_1 = require("./helpers/delete-chunks");
|
|
30
32
|
const expected_out_name_1 = require("./helpers/expected-out-name");
|
|
33
|
+
const find_output_file_in_bucket_1 = require("./helpers/find-output-file-in-bucket");
|
|
31
34
|
const get_browser_instance_1 = require("./helpers/get-browser-instance");
|
|
32
35
|
const get_current_region_1 = require("./helpers/get-current-region");
|
|
33
36
|
const get_files_to_delete_1 = require("./helpers/get-files-to-delete");
|
|
@@ -39,12 +42,76 @@ const timer_1 = require("./helpers/timer");
|
|
|
39
42
|
const validate_composition_1 = require("./helpers/validate-composition");
|
|
40
43
|
const write_lambda_error_1 = require("./helpers/write-lambda-error");
|
|
41
44
|
const write_post_render_data_1 = require("./helpers/write-post-render-data");
|
|
45
|
+
const callFunctionWithRetry = async (payload, retries = 0) => {
|
|
46
|
+
try {
|
|
47
|
+
await (0, aws_clients_1.getLambdaClient)((0, get_current_region_1.getCurrentRegionInFunction)()).send(new client_lambda_1.InvokeCommand({
|
|
48
|
+
FunctionName: process.env.AWS_LAMBDA_FUNCTION_NAME,
|
|
49
|
+
// @ts-expect-error
|
|
50
|
+
Payload: JSON.stringify(payload),
|
|
51
|
+
InvocationType: 'Event',
|
|
52
|
+
}), {});
|
|
53
|
+
}
|
|
54
|
+
catch (err) {
|
|
55
|
+
if (err.name === 'ResourceConflictException') {
|
|
56
|
+
if (retries > 10) {
|
|
57
|
+
throw err;
|
|
58
|
+
}
|
|
59
|
+
await new Promise((resolve) => {
|
|
60
|
+
setTimeout(resolve, 1000);
|
|
61
|
+
});
|
|
62
|
+
return callFunctionWithRetry(payload, retries + 1);
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
};
|
|
42
66
|
const innerLaunchHandler = async (params, options) => {
|
|
43
|
-
var _a, _b;
|
|
67
|
+
var _a, _b, _c, _d;
|
|
44
68
|
if (params.type !== constants_1.LambdaRoutines.launch) {
|
|
45
69
|
throw new Error('Expected launch type');
|
|
46
70
|
}
|
|
47
71
|
const startedDate = Date.now();
|
|
72
|
+
let webhookInvoked = false;
|
|
73
|
+
const webhookDueToTimeout = setTimeout(async () => {
|
|
74
|
+
if (params.webhook && !webhookInvoked) {
|
|
75
|
+
try {
|
|
76
|
+
await (0, invoke_webhook_1.invokeWebhook)({
|
|
77
|
+
url: params.webhook.url,
|
|
78
|
+
secret: params.webhook.secret,
|
|
79
|
+
payload: {
|
|
80
|
+
type: 'timeout',
|
|
81
|
+
renderId: params.renderId,
|
|
82
|
+
expectedBucketOwner: options.expectedBucketOwner,
|
|
83
|
+
bucketName: params.bucketName,
|
|
84
|
+
},
|
|
85
|
+
});
|
|
86
|
+
webhookInvoked = true;
|
|
87
|
+
}
|
|
88
|
+
catch (err) {
|
|
89
|
+
if (process.env.NODE_ENV === 'test') {
|
|
90
|
+
throw err;
|
|
91
|
+
}
|
|
92
|
+
await (0, write_lambda_error_1.writeLambdaError)({
|
|
93
|
+
bucketName: params.bucketName,
|
|
94
|
+
errorInfo: {
|
|
95
|
+
type: 'webhook',
|
|
96
|
+
message: err.message,
|
|
97
|
+
name: err.name,
|
|
98
|
+
stack: err.stack,
|
|
99
|
+
tmpDir: null,
|
|
100
|
+
frame: 0,
|
|
101
|
+
chunk: 0,
|
|
102
|
+
isFatal: false,
|
|
103
|
+
attempt: 1,
|
|
104
|
+
willRetry: false,
|
|
105
|
+
totalAttempts: 1,
|
|
106
|
+
},
|
|
107
|
+
renderId: params.renderId,
|
|
108
|
+
expectedBucketOwner: options.expectedBucketOwner,
|
|
109
|
+
});
|
|
110
|
+
console.log('Failed to invoke webhook:');
|
|
111
|
+
console.log(err);
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
}, Math.max(params.timeoutInMilliseconds - 1000, 1000));
|
|
48
115
|
const [browserInstance, optimization] = await Promise.all([
|
|
49
116
|
(0, get_browser_instance_1.getBrowserInstance)(renderer_1.RenderInternals.isEqualOrBelowLogLevel(params.logLevel, 'verbose'), params.chromiumOptions),
|
|
50
117
|
(0, s3_optimization_file_1.getOptimization)({
|
|
@@ -77,12 +144,15 @@ const innerLaunchHandler = async (params, options) => {
|
|
|
77
144
|
const realFrameRange = renderer_1.RenderInternals.getRealFrameRange(comp.durationInFrames, params.frameRange);
|
|
78
145
|
const frameCount = renderer_1.RenderInternals.getFramesToRender(realFrameRange, params.everyNthFrame);
|
|
79
146
|
const framesPerLambda = (_a = params.framesPerLambda) !== null && _a !== void 0 ? _a : (0, best_frames_per_lambda_param_1.bestFramesPerLambdaParam)(frameCount.length);
|
|
80
|
-
(0, validate_frames_per_lambda_1.validateFramesPerLambda)(
|
|
147
|
+
(0, validate_frames_per_lambda_1.validateFramesPerLambda)({
|
|
148
|
+
framesPerLambda,
|
|
149
|
+
durationInFrames: frameCount.length,
|
|
150
|
+
});
|
|
81
151
|
const chunkCount = Math.ceil(frameCount.length / framesPerLambda);
|
|
82
152
|
if (chunkCount > constants_1.MAX_FUNCTIONS_PER_RENDER) {
|
|
83
153
|
throw new Error(`Too many functions: This render would cause ${chunkCount} 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 for how this parameter is calculated.`);
|
|
84
154
|
}
|
|
85
|
-
(0, validate_outname_1.validateOutname)(params.outName);
|
|
155
|
+
(0, validate_outname_1.validateOutname)(params.outName, params.codec);
|
|
86
156
|
(0, validate_privacy_1.validatePrivacy)(params.privacy);
|
|
87
157
|
renderer_1.RenderInternals.validatePuppeteerTimeout(params.timeoutInMilliseconds);
|
|
88
158
|
const { chunks, didUseOptimization } = (0, plan_frame_ranges_1.planFrameRanges)({
|
|
@@ -127,6 +197,7 @@ const innerLaunchHandler = async (params, options) => {
|
|
|
127
197
|
scale: params.scale,
|
|
128
198
|
everyNthFrame: params.everyNthFrame,
|
|
129
199
|
concurrencyPerLambda: params.concurrencyPerLambda,
|
|
200
|
+
muted: params.muted,
|
|
130
201
|
};
|
|
131
202
|
return payload;
|
|
132
203
|
});
|
|
@@ -149,13 +220,37 @@ const innerLaunchHandler = async (params, options) => {
|
|
|
149
220
|
type: 'video',
|
|
150
221
|
imageFormat: params.imageFormat,
|
|
151
222
|
inputProps: params.inputProps,
|
|
152
|
-
lambdaVersion:
|
|
223
|
+
lambdaVersion: version_1.VERSION,
|
|
153
224
|
framesPerLambda,
|
|
154
225
|
memorySizeInMb: Number(process.env.AWS_LAMBDA_FUNCTION_MEMORY_SIZE),
|
|
155
226
|
region: (0, get_current_region_1.getCurrentRegionInFunction)(),
|
|
156
227
|
renderId: params.renderId,
|
|
157
228
|
outName: (_b = params.outName) !== null && _b !== void 0 ? _b : undefined,
|
|
229
|
+
privacy: params.privacy,
|
|
158
230
|
};
|
|
231
|
+
const { key, renderBucketName, customCredentials } = (0, expected_out_name_1.getExpectedOutName)(renderMetadata, params.bucketName, typeof params.outName === 'string' || typeof params.outName === 'undefined'
|
|
232
|
+
? null
|
|
233
|
+
: (_d = (_c = params.outName) === null || _c === void 0 ? void 0 : _c.s3OutputProvider) !== null && _d !== void 0 ? _d : null);
|
|
234
|
+
const output = await (0, find_output_file_in_bucket_1.findOutputFileInBucket)({
|
|
235
|
+
bucketName: params.bucketName,
|
|
236
|
+
customCredentials,
|
|
237
|
+
region: (0, get_current_region_1.getCurrentRegionInFunction)(),
|
|
238
|
+
renderMetadata,
|
|
239
|
+
});
|
|
240
|
+
if (output) {
|
|
241
|
+
if (params.overwrite) {
|
|
242
|
+
console.info('Deleting', { bucketName: renderBucketName, key }, 'because it already existed and will be overwritten');
|
|
243
|
+
await (0, io_1.lambdaDeleteFile)({
|
|
244
|
+
bucketName: renderBucketName,
|
|
245
|
+
customCredentials,
|
|
246
|
+
key,
|
|
247
|
+
region: (0, get_current_region_1.getCurrentRegionInFunction)(),
|
|
248
|
+
});
|
|
249
|
+
}
|
|
250
|
+
else {
|
|
251
|
+
throw new TypeError(`Output file "${key}" in bucket "${renderBucketName}" in region "${(0, get_current_region_1.getCurrentRegionInFunction)()}" already exists. Delete it before re-rendering, or use the overwrite option to delete it before render."`);
|
|
252
|
+
}
|
|
253
|
+
}
|
|
159
254
|
await (0, io_1.lambdaWriteFile)({
|
|
160
255
|
bucketName: params.bucketName,
|
|
161
256
|
key: (0, constants_1.renderMetadataKey)(params.renderId),
|
|
@@ -164,15 +259,11 @@ const innerLaunchHandler = async (params, options) => {
|
|
|
164
259
|
privacy: 'private',
|
|
165
260
|
expectedBucketOwner: options.expectedBucketOwner,
|
|
166
261
|
downloadBehavior: null,
|
|
262
|
+
customCredentials: null,
|
|
167
263
|
});
|
|
168
264
|
await Promise.all(lambdaPayloads.map(async (payload, index) => {
|
|
169
265
|
const callingLambdaTimer = (0, timer_1.timer)('Calling chunk ' + index);
|
|
170
|
-
await (
|
|
171
|
-
FunctionName: process.env.AWS_LAMBDA_FUNCTION_NAME,
|
|
172
|
-
// @ts-expect-error
|
|
173
|
-
Payload: JSON.stringify(payload),
|
|
174
|
-
InvocationType: 'Event',
|
|
175
|
-
}), {});
|
|
266
|
+
await callFunctionWithRetry(payload);
|
|
176
267
|
callingLambdaTimer.end();
|
|
177
268
|
}));
|
|
178
269
|
reqSend.end();
|
|
@@ -202,6 +293,7 @@ const innerLaunchHandler = async (params, options) => {
|
|
|
202
293
|
privacy: 'private',
|
|
203
294
|
expectedBucketOwner: options.expectedBucketOwner,
|
|
204
295
|
downloadBehavior: null,
|
|
296
|
+
customCredentials: null,
|
|
205
297
|
}).catch((err) => {
|
|
206
298
|
(0, write_lambda_error_1.writeLambdaError)({
|
|
207
299
|
bucketName: params.bucketName,
|
|
@@ -239,7 +331,6 @@ const innerLaunchHandler = async (params, options) => {
|
|
|
239
331
|
if (!encodingStop) {
|
|
240
332
|
encodingStop = Date.now();
|
|
241
333
|
}
|
|
242
|
-
const { key, renderBucketName } = (0, expected_out_name_1.getExpectedOutName)(renderMetadata, params.bucketName);
|
|
243
334
|
const outputSize = fs_1.default.statSync(outfile);
|
|
244
335
|
await (0, io_1.lambdaWriteFile)({
|
|
245
336
|
bucketName: renderBucketName,
|
|
@@ -249,6 +340,7 @@ const innerLaunchHandler = async (params, options) => {
|
|
|
249
340
|
privacy: params.privacy,
|
|
250
341
|
expectedBucketOwner: options.expectedBucketOwner,
|
|
251
342
|
downloadBehavior: params.downloadBehavior,
|
|
343
|
+
customCredentials,
|
|
252
344
|
});
|
|
253
345
|
let chunkProm = Promise.resolve();
|
|
254
346
|
// TODO: Enable in a later release
|
|
@@ -271,7 +363,7 @@ const innerLaunchHandler = async (params, options) => {
|
|
|
271
363
|
newTiming: (0, get_profile_duration_1.getProfileDuration)(optimizedProfile),
|
|
272
364
|
createdFromRenderId: params.renderId,
|
|
273
365
|
framesPerLambda,
|
|
274
|
-
lambdaVersion:
|
|
366
|
+
lambdaVersion: version_1.VERSION,
|
|
275
367
|
frameRange: realFrameRange,
|
|
276
368
|
everyNthFrame: params.everyNthFrame,
|
|
277
369
|
},
|
|
@@ -311,6 +403,7 @@ const innerLaunchHandler = async (params, options) => {
|
|
|
311
403
|
privacy: 'private',
|
|
312
404
|
expectedBucketOwner: options.expectedBucketOwner,
|
|
313
405
|
downloadBehavior: null,
|
|
406
|
+
customCredentials: null,
|
|
314
407
|
});
|
|
315
408
|
const errorExplanationsProm = (0, inspect_errors_1.inspectErrors)({
|
|
316
409
|
contents,
|
|
@@ -329,6 +422,7 @@ const innerLaunchHandler = async (params, options) => {
|
|
|
329
422
|
contents,
|
|
330
423
|
jobs,
|
|
331
424
|
});
|
|
425
|
+
const outputUrl = (0, get_output_url_from_metadata_1.getOutputUrlFromMetadata)(renderMetadata, params.bucketName, customCredentials);
|
|
332
426
|
const postRenderData = (0, create_post_render_data_1.createPostRenderData)({
|
|
333
427
|
expectedBucketOwner: options.expectedBucketOwner,
|
|
334
428
|
region: (0, get_current_region_1.getCurrentRegionInFunction)(),
|
|
@@ -342,7 +436,7 @@ const innerLaunchHandler = async (params, options) => {
|
|
|
342
436
|
outputFile: {
|
|
343
437
|
lastModified: Date.now(),
|
|
344
438
|
size: outputSize.size,
|
|
345
|
-
url:
|
|
439
|
+
url: outputUrl,
|
|
346
440
|
},
|
|
347
441
|
});
|
|
348
442
|
await finalEncodingProgressProm;
|
|
@@ -353,9 +447,61 @@ const innerLaunchHandler = async (params, options) => {
|
|
|
353
447
|
region: (0, get_current_region_1.getCurrentRegionInFunction)(),
|
|
354
448
|
renderId: params.renderId,
|
|
355
449
|
});
|
|
450
|
+
await (0, io_1.lambdaDeleteFile)({
|
|
451
|
+
bucketName: params.bucketName,
|
|
452
|
+
key: (0, constants_1.initalizedMetadataKey)(params.renderId),
|
|
453
|
+
region: (0, get_current_region_1.getCurrentRegionInFunction)(),
|
|
454
|
+
customCredentials: null,
|
|
455
|
+
});
|
|
356
456
|
await Promise.all([cleanupChunksProm, fs_1.default.promises.rm(outfile)]);
|
|
457
|
+
clearTimeout(webhookDueToTimeout);
|
|
458
|
+
if (params.webhook && !webhookInvoked) {
|
|
459
|
+
try {
|
|
460
|
+
await (0, invoke_webhook_1.invokeWebhook)({
|
|
461
|
+
url: params.webhook.url,
|
|
462
|
+
secret: params.webhook.secret,
|
|
463
|
+
payload: {
|
|
464
|
+
type: 'success',
|
|
465
|
+
renderId: params.renderId,
|
|
466
|
+
expectedBucketOwner: options.expectedBucketOwner,
|
|
467
|
+
bucketName: params.bucketName,
|
|
468
|
+
outputUrl,
|
|
469
|
+
lambdaErrors: postRenderData.errors,
|
|
470
|
+
outputFile: postRenderData.outputFile,
|
|
471
|
+
timeToFinish: postRenderData.timeToFinish,
|
|
472
|
+
},
|
|
473
|
+
});
|
|
474
|
+
webhookInvoked = true;
|
|
475
|
+
}
|
|
476
|
+
catch (err) {
|
|
477
|
+
if (process.env.NODE_ENV === 'test') {
|
|
478
|
+
throw err;
|
|
479
|
+
}
|
|
480
|
+
await (0, write_lambda_error_1.writeLambdaError)({
|
|
481
|
+
bucketName: params.bucketName,
|
|
482
|
+
errorInfo: {
|
|
483
|
+
type: 'webhook',
|
|
484
|
+
message: err.message,
|
|
485
|
+
name: err.name,
|
|
486
|
+
stack: err.stack,
|
|
487
|
+
tmpDir: null,
|
|
488
|
+
frame: 0,
|
|
489
|
+
chunk: 0,
|
|
490
|
+
isFatal: false,
|
|
491
|
+
attempt: 1,
|
|
492
|
+
willRetry: false,
|
|
493
|
+
totalAttempts: 1,
|
|
494
|
+
},
|
|
495
|
+
renderId: params.renderId,
|
|
496
|
+
expectedBucketOwner: options.expectedBucketOwner,
|
|
497
|
+
});
|
|
498
|
+
console.log('Failed to invoke webhook:');
|
|
499
|
+
console.log(err);
|
|
500
|
+
}
|
|
501
|
+
}
|
|
357
502
|
};
|
|
358
503
|
const launchHandler = async (params, options) => {
|
|
504
|
+
var _a, _b;
|
|
359
505
|
if (params.type !== constants_1.LambdaRoutines.launch) {
|
|
360
506
|
throw new Error('Expected launch type');
|
|
361
507
|
}
|
|
@@ -363,6 +509,9 @@ const launchHandler = async (params, options) => {
|
|
|
363
509
|
await innerLaunchHandler(params, options);
|
|
364
510
|
}
|
|
365
511
|
catch (err) {
|
|
512
|
+
if (process.env.NODE_ENV === 'test') {
|
|
513
|
+
throw err;
|
|
514
|
+
}
|
|
366
515
|
console.log('Error occurred', err);
|
|
367
516
|
await (0, write_lambda_error_1.writeLambdaError)({
|
|
368
517
|
bucketName: params.bucketName,
|
|
@@ -382,6 +531,50 @@ const launchHandler = async (params, options) => {
|
|
|
382
531
|
expectedBucketOwner: options.expectedBucketOwner,
|
|
383
532
|
renderId: params.renderId,
|
|
384
533
|
});
|
|
534
|
+
if ((_a = params.webhook) === null || _a === void 0 ? void 0 : _a.url) {
|
|
535
|
+
try {
|
|
536
|
+
await (0, invoke_webhook_1.invokeWebhook)({
|
|
537
|
+
url: params.webhook.url,
|
|
538
|
+
secret: (_b = params.webhook.secret) !== null && _b !== void 0 ? _b : null,
|
|
539
|
+
payload: {
|
|
540
|
+
type: 'error',
|
|
541
|
+
renderId: params.renderId,
|
|
542
|
+
expectedBucketOwner: options.expectedBucketOwner,
|
|
543
|
+
bucketName: params.bucketName,
|
|
544
|
+
errors: [err].map((e) => ({
|
|
545
|
+
message: e.message,
|
|
546
|
+
name: e.name,
|
|
547
|
+
stack: e.stack,
|
|
548
|
+
})),
|
|
549
|
+
},
|
|
550
|
+
});
|
|
551
|
+
}
|
|
552
|
+
catch (error) {
|
|
553
|
+
if (process.env.NODE_ENV === 'test') {
|
|
554
|
+
throw error;
|
|
555
|
+
}
|
|
556
|
+
await (0, write_lambda_error_1.writeLambdaError)({
|
|
557
|
+
bucketName: params.bucketName,
|
|
558
|
+
errorInfo: {
|
|
559
|
+
type: 'webhook',
|
|
560
|
+
message: err.message,
|
|
561
|
+
name: err.name,
|
|
562
|
+
stack: err.stack,
|
|
563
|
+
tmpDir: null,
|
|
564
|
+
frame: 0,
|
|
565
|
+
chunk: 0,
|
|
566
|
+
isFatal: false,
|
|
567
|
+
attempt: 1,
|
|
568
|
+
willRetry: false,
|
|
569
|
+
totalAttempts: 1,
|
|
570
|
+
},
|
|
571
|
+
renderId: params.renderId,
|
|
572
|
+
expectedBucketOwner: options.expectedBucketOwner,
|
|
573
|
+
});
|
|
574
|
+
console.log('Failed to invoke webhook:');
|
|
575
|
+
console.log(error);
|
|
576
|
+
}
|
|
577
|
+
}
|
|
385
578
|
}
|
|
386
579
|
};
|
|
387
580
|
exports.launchHandler = launchHandler;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type { LambdaPayload, RenderProgress } from '../shared/constants';
|
|
2
2
|
declare type Options = {
|
|
3
3
|
expectedBucketOwner: string;
|
|
4
|
-
|
|
4
|
+
timeoutInMilliseconds: number;
|
|
5
5
|
};
|
|
6
6
|
export declare const progressHandler: (lambdaParams: LambdaPayload, options: Options) => Promise<RenderProgress>;
|
|
7
7
|
export {};
|
|
@@ -1,20 +1,29 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.progressHandler = void 0;
|
|
4
|
+
const version_1 = require("remotion/version");
|
|
4
5
|
const constants_1 = require("../shared/constants");
|
|
5
6
|
const get_current_region_1 = require("./helpers/get-current-region");
|
|
6
7
|
const get_progress_1 = require("./helpers/get-progress");
|
|
7
8
|
const progressHandler = (lambdaParams, options) => {
|
|
9
|
+
var _a;
|
|
8
10
|
if (lambdaParams.type !== constants_1.LambdaRoutines.status) {
|
|
9
11
|
throw new TypeError('Expected status type');
|
|
10
12
|
}
|
|
13
|
+
if (lambdaParams.version !== version_1.VERSION) {
|
|
14
|
+
if (!lambdaParams.version) {
|
|
15
|
+
throw new Error(`Version mismatch: When calling getRenderProgress(), the deployed Lambda function had version ${version_1.VERSION} but the @remotion/lambda package is an older version. Align the versions.`);
|
|
16
|
+
}
|
|
17
|
+
throw new Error(`Version mismatch: When calling getRenderProgress(), get deployed Lambda function had version ${version_1.VERSION} and the @remotion/lambda package has version ${lambdaParams.version}. Align the versions.`);
|
|
18
|
+
}
|
|
11
19
|
return (0, get_progress_1.getProgress)({
|
|
12
20
|
bucketName: lambdaParams.bucketName,
|
|
13
21
|
renderId: lambdaParams.renderId,
|
|
14
22
|
expectedBucketOwner: options.expectedBucketOwner,
|
|
15
23
|
region: (0, get_current_region_1.getCurrentRegionInFunction)(),
|
|
16
24
|
memorySizeInMb: Number(process.env.AWS_LAMBDA_FUNCTION_MEMORY_SIZE),
|
|
17
|
-
|
|
25
|
+
timeoutInMilliseconds: options.timeoutInMilliseconds,
|
|
26
|
+
customCredentials: (_a = lambdaParams.s3OutputProvider) !== null && _a !== void 0 ? _a : null,
|
|
18
27
|
});
|
|
19
28
|
};
|
|
20
29
|
exports.progressHandler = progressHandler;
|
|
@@ -18,7 +18,7 @@ const get_folder_size_1 = require("./helpers/get-folder-size");
|
|
|
18
18
|
const io_1 = require("./helpers/io");
|
|
19
19
|
const write_lambda_error_1 = require("./helpers/write-lambda-error");
|
|
20
20
|
const renderHandler = async (params, options, logs) => {
|
|
21
|
-
var _a
|
|
21
|
+
var _a;
|
|
22
22
|
if (params.type !== constants_1.LambdaRoutines.renderer) {
|
|
23
23
|
throw new Error('Params must be renderer');
|
|
24
24
|
}
|
|
@@ -41,81 +41,106 @@ const renderHandler = async (params, options, logs) => {
|
|
|
41
41
|
const outputLocation = path_1.default.join(outdir, `localchunk-${String(params.chunk).padStart(8, '0')}.${renderer_1.RenderInternals.getFileExtensionFromCodec(params.codec, 'chunk')}`);
|
|
42
42
|
const chunkCodec = params.codec === 'gif' ? 'h264-mkv' : params.codec;
|
|
43
43
|
const downloadMap = renderer_1.RenderInternals.makeDownloadMap();
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
44
|
+
const downloads = {};
|
|
45
|
+
await new Promise((resolve, reject) => {
|
|
46
|
+
var _a;
|
|
47
|
+
(0, renderer_1.renderMedia)({
|
|
48
|
+
composition: {
|
|
49
|
+
id: params.composition,
|
|
50
|
+
durationInFrames: params.durationInFrames,
|
|
51
|
+
fps: params.fps,
|
|
52
|
+
height: params.height,
|
|
53
|
+
width: params.width,
|
|
54
|
+
},
|
|
55
|
+
imageFormat: params.imageFormat,
|
|
56
|
+
inputProps: params.inputProps,
|
|
57
|
+
frameRange: params.frameRange,
|
|
58
|
+
onProgress: ({ renderedFrames, encodedFrames, stitchStage }) => {
|
|
59
|
+
if (renderedFrames % 10 === 0 &&
|
|
60
|
+
renderer_1.RenderInternals.isEqualOrBelowLogLevel(params.logLevel, 'verbose')) {
|
|
61
|
+
console.log(`Rendered ${renderedFrames} frames, encoded ${encodedFrames} frames, stage = ${stitchStage}`);
|
|
62
|
+
}
|
|
63
|
+
const allFrames = renderer_1.RenderInternals.getFramesToRender(params.frameRange, params.everyNthFrame);
|
|
64
|
+
if (renderedFrames === allFrames.length) {
|
|
65
|
+
console.log('Rendered all frames!');
|
|
66
|
+
}
|
|
67
|
+
chunkTimingData.timings[renderedFrames] = Date.now() - start;
|
|
68
|
+
},
|
|
69
|
+
concurrency: params.concurrencyPerLambda,
|
|
70
|
+
onStart: () => {
|
|
71
|
+
(0, io_1.lambdaWriteFile)({
|
|
72
|
+
privacy: 'private',
|
|
73
|
+
bucketName: params.bucketName,
|
|
74
|
+
body: JSON.stringify({
|
|
75
|
+
filesCleaned: clean_tmpdir_1.deletedFilesSize,
|
|
76
|
+
filesInTmp: fs_1.default.readdirSync('/tmp'),
|
|
77
|
+
isWarm: options.isWarm,
|
|
78
|
+
deletedFiles: clean_tmpdir_1.deletedFiles,
|
|
79
|
+
tmpSize: (0, get_folder_size_1.getFolderSizeRecursively)('/tmp'),
|
|
80
|
+
tmpDirFiles: (0, get_files_in_folder_1.getFolderFiles)('/tmp'),
|
|
81
|
+
}),
|
|
82
|
+
key: (0, constants_1.lambdaChunkInitializedKey)({
|
|
83
|
+
renderId: params.renderId,
|
|
84
|
+
chunk: params.chunk,
|
|
85
|
+
attempt: params.attempt,
|
|
86
|
+
}),
|
|
87
|
+
region: (0, get_current_region_1.getCurrentRegionInFunction)(),
|
|
88
|
+
expectedBucketOwner: options.expectedBucketOwner,
|
|
89
|
+
downloadBehavior: null,
|
|
90
|
+
customCredentials: null,
|
|
91
|
+
}).catch((err) => reject(err));
|
|
92
|
+
},
|
|
93
|
+
puppeteerInstance: browserInstance,
|
|
94
|
+
serveUrl: params.serveUrl,
|
|
95
|
+
quality: params.quality,
|
|
96
|
+
envVariables: params.envVariables,
|
|
97
|
+
dumpBrowserLogs: renderer_1.RenderInternals.isEqualOrBelowLogLevel(params.logLevel, 'verbose'),
|
|
98
|
+
verbose: renderer_1.RenderInternals.isEqualOrBelowLogLevel(params.logLevel, 'verbose'),
|
|
99
|
+
onBrowserLog: (log) => {
|
|
100
|
+
logs.push(log);
|
|
101
|
+
},
|
|
102
|
+
outputLocation,
|
|
103
|
+
codec: chunkCodec,
|
|
104
|
+
crf: (_a = params.crf) !== null && _a !== void 0 ? _a : undefined,
|
|
105
|
+
ffmpegExecutable: process.env.NODE_ENV === 'test' ? null : '/opt/bin/ffmpeg',
|
|
106
|
+
pixelFormat: params.pixelFormat,
|
|
107
|
+
proResProfile: params.proResProfile,
|
|
108
|
+
onDownload: (src) => {
|
|
109
|
+
console.log('Downloading', src);
|
|
110
|
+
downloads[src] = 0;
|
|
111
|
+
return ({ percent, downloaded }) => {
|
|
112
|
+
if (percent === null) {
|
|
113
|
+
console.log(`Download progress (${src}): ${downloaded} bytes. Don't know final size of download, no Content-Length header.`);
|
|
114
|
+
return;
|
|
115
|
+
}
|
|
116
|
+
if (
|
|
117
|
+
// Only report every 10% change
|
|
118
|
+
downloads[src] > percent - 0.1 &&
|
|
119
|
+
percent !== 1) {
|
|
120
|
+
return;
|
|
121
|
+
}
|
|
122
|
+
downloads[src] = percent;
|
|
123
|
+
console.log(`Download progress (${src}): ${downloaded} bytes, ${(percent * 100).toFixed(1)}%`);
|
|
124
|
+
if (percent === 1) {
|
|
125
|
+
console.log(`Download complete: ${src}`);
|
|
126
|
+
}
|
|
127
|
+
};
|
|
128
|
+
},
|
|
129
|
+
overwrite: false,
|
|
130
|
+
chromiumOptions: params.chromiumOptions,
|
|
131
|
+
scale: params.scale,
|
|
132
|
+
timeoutInMilliseconds: params.timeoutInMilliseconds,
|
|
133
|
+
port: null,
|
|
134
|
+
everyNthFrame: params.everyNthFrame,
|
|
135
|
+
numberOfGifLoops: null,
|
|
136
|
+
downloadMap,
|
|
137
|
+
muted: params.muted,
|
|
138
|
+
enforceAudioTrack: true,
|
|
139
|
+
})
|
|
140
|
+
.then(() => resolve())
|
|
141
|
+
.catch((err) => reject(err));
|
|
116
142
|
});
|
|
117
143
|
const endRendered = Date.now();
|
|
118
|
-
console.log('Adding silent audio, chunk', params.chunk);
|
|
119
144
|
const condensedTimingData = {
|
|
120
145
|
...chunkTimingData,
|
|
121
146
|
timings: Object.values(chunkTimingData.timings),
|
|
@@ -131,6 +156,7 @@ const renderHandler = async (params, options, logs) => {
|
|
|
131
156
|
privacy: params.privacy,
|
|
132
157
|
expectedBucketOwner: options.expectedBucketOwner,
|
|
133
158
|
downloadBehavior: null,
|
|
159
|
+
customCredentials: null,
|
|
134
160
|
});
|
|
135
161
|
await Promise.all([
|
|
136
162
|
fs_1.default.promises.rm(outputLocation, { recursive: true }),
|
|
@@ -148,6 +174,7 @@ const renderHandler = async (params, options, logs) => {
|
|
|
148
174
|
privacy: 'private',
|
|
149
175
|
expectedBucketOwner: options.expectedBucketOwner,
|
|
150
176
|
downloadBehavior: null,
|
|
177
|
+
customCredentials: null,
|
|
151
178
|
}),
|
|
152
179
|
]);
|
|
153
180
|
};
|
|
@@ -160,6 +187,9 @@ const rendererHandler = async (params, options) => {
|
|
|
160
187
|
await renderHandler(params, options, logs);
|
|
161
188
|
}
|
|
162
189
|
catch (err) {
|
|
190
|
+
if (process.env.NODE_ENV === 'test') {
|
|
191
|
+
throw err;
|
|
192
|
+
}
|
|
163
193
|
// If this error is encountered, we can just retry as it
|
|
164
194
|
// is a very rare error to occur
|
|
165
195
|
const isBrowserError = err.message.includes('FATAL:zygote_communication_linux.cc') ||
|
|
@@ -1,5 +1,9 @@
|
|
|
1
1
|
import type { LambdaPayload } from '../shared/constants';
|
|
2
|
-
|
|
2
|
+
declare type Options = {
|
|
3
|
+
expectedBucketOwner: string;
|
|
4
|
+
};
|
|
5
|
+
export declare const startHandler: (params: LambdaPayload, options: Options) => Promise<{
|
|
3
6
|
bucketName: string;
|
|
4
7
|
renderId: string;
|
|
5
8
|
}>;
|
|
9
|
+
export {};
|