@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.
Files changed (99) hide show
  1. package/dist/admin/make-layer-public.js +5 -5
  2. package/dist/api/bucket-exists.js +1 -1
  3. package/dist/api/clean-items.js +1 -1
  4. package/dist/api/create-bucket.js +1 -1
  5. package/dist/api/delete-render.d.ts +19 -0
  6. package/dist/api/delete-render.js +66 -0
  7. package/dist/api/delete-site.js +0 -5
  8. package/dist/api/deploy-function.js +4 -2
  9. package/dist/api/deploy-site.d.ts +2 -0
  10. package/dist/api/deploy-site.js +2 -0
  11. package/dist/api/download-media.d.ts +13 -0
  12. package/dist/api/download-media.js +15 -3
  13. package/dist/api/enable-s3-website.js +1 -1
  14. package/dist/api/get-aws-client.d.ts +4 -2
  15. package/dist/api/get-aws-client.js +7 -2
  16. package/dist/api/get-buckets.js +2 -2
  17. package/dist/api/get-function-info.d.ts +1 -2
  18. package/dist/api/get-functions.js +2 -1
  19. package/dist/api/get-render-progress.d.ts +4 -1
  20. package/dist/api/get-render-progress.js +5 -1
  21. package/dist/api/mock-functions.d.ts +4 -5
  22. package/dist/api/presign-url.js +6 -1
  23. package/dist/api/render-media-on-lambda.d.ts +18 -10
  24. package/dist/api/render-media-on-lambda.js +65 -40
  25. package/dist/api/render-still-on-lambda.d.ts +1 -0
  26. package/dist/api/render-still-on-lambda.js +48 -30
  27. package/dist/api/upload-dir.js +1 -1
  28. package/dist/api/validate-webhook-signature.d.ts +13 -0
  29. package/dist/api/validate-webhook-signature.js +32 -0
  30. package/dist/cli/args.d.ts +2 -0
  31. package/dist/cli/commands/functions/deploy.js +2 -1
  32. package/dist/cli/commands/render/render.js +24 -15
  33. package/dist/cli/commands/still.js +20 -16
  34. package/dist/cli/get-aws-region.js +2 -1
  35. package/dist/cli/helpers/determine-image-format.d.ts +10 -0
  36. package/dist/cli/helpers/determine-image-format.js +47 -0
  37. package/dist/cli/helpers/find-function-name.js +3 -2
  38. package/dist/cli/helpers/webhook-types.d.ts +6 -0
  39. package/dist/cli/helpers/webhook-types.js +2 -0
  40. package/dist/cli/index.js +1 -1
  41. package/dist/client.d.ts +4 -2
  42. package/dist/client.js +3 -1
  43. package/dist/functions/chunk-optimization/can-use-optimization.js +2 -2
  44. package/dist/functions/chunk-optimization/s3-optimization-file.js +1 -0
  45. package/dist/functions/chunk-optimization/types.d.ts +1 -2
  46. package/dist/functions/helpers/check-if-render-exists.d.ts +3 -0
  47. package/dist/functions/helpers/check-if-render-exists.js +14 -0
  48. package/dist/functions/helpers/expected-out-name.d.ts +4 -2
  49. package/dist/functions/helpers/expected-out-name.js +26 -5
  50. package/dist/functions/helpers/find-output-file-in-bucket.d.ts +3 -1
  51. package/dist/functions/helpers/find-output-file-in-bucket.js +17 -13
  52. package/dist/functions/helpers/get-custom-out-name.d.ts +6 -0
  53. package/dist/functions/helpers/get-custom-out-name.js +31 -0
  54. package/dist/functions/helpers/get-files-to-delete.js +1 -1
  55. package/dist/functions/helpers/get-lambdas-invoked-stats.js +1 -1
  56. package/dist/functions/helpers/get-output-url-from-metadata.d.ts +2 -1
  57. package/dist/functions/helpers/get-output-url-from-metadata.js +2 -2
  58. package/dist/functions/helpers/get-progress.d.ts +4 -2
  59. package/dist/functions/helpers/get-progress.js +13 -6
  60. package/dist/functions/helpers/get-retry-stats.js +1 -1
  61. package/dist/functions/helpers/io.d.ts +17 -1
  62. package/dist/functions/helpers/io.js +21 -6
  63. package/dist/functions/helpers/read-with-progress.d.ts +3 -1
  64. package/dist/functions/helpers/read-with-progress.js +2 -2
  65. package/dist/functions/helpers/write-lambda-error.d.ts +1 -1
  66. package/dist/functions/helpers/write-lambda-error.js +1 -0
  67. package/dist/functions/helpers/write-post-render-data.js +1 -0
  68. package/dist/functions/index.js +4 -4
  69. package/dist/functions/info.d.ts +2 -2
  70. package/dist/functions/info.js +2 -1
  71. package/dist/functions/launch.js +206 -13
  72. package/dist/functions/progress.d.ts +1 -1
  73. package/dist/functions/progress.js +10 -1
  74. package/dist/functions/renderer.js +104 -74
  75. package/dist/functions/start.d.ts +5 -1
  76. package/dist/functions/start.js +23 -1
  77. package/dist/functions/still.js +17 -4
  78. package/dist/index.d.ts +6 -2
  79. package/dist/index.js +5 -1
  80. package/dist/shared/aws-clients.d.ts +13 -2
  81. package/dist/shared/aws-clients.js +56 -26
  82. package/dist/shared/bundle-site.d.ts +2 -1
  83. package/dist/shared/constants.d.ts +31 -6
  84. package/dist/shared/constants.js +14 -7
  85. package/dist/shared/get-cloudwatch-stream-url.d.ts +8 -0
  86. package/dist/shared/get-cloudwatch-stream-url.js +7 -0
  87. package/dist/shared/get-function-version.d.ts +1 -2
  88. package/dist/shared/hosted-layers.js +60 -60
  89. package/dist/shared/invoke-webhook.d.ts +59 -0
  90. package/dist/shared/invoke-webhook.js +103 -0
  91. package/dist/shared/is-in-lambda.js +5 -1
  92. package/dist/shared/lambda-version-string.d.ts +1 -0
  93. package/dist/shared/lambda-version-string.js +7 -0
  94. package/dist/shared/validate-frames-per-lambda.d.ts +4 -1
  95. package/dist/shared/validate-frames-per-lambda.js +4 -3
  96. package/dist/shared/validate-outname.d.ts +3 -2
  97. package/dist/shared/validate-outname.js +5 -1
  98. package/package.json +9 -9
  99. package/remotionlambda.zip +0 -0
@@ -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)(framesPerLambda);
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: constants_1.CURRENT_VERSION,
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 (0, aws_clients_1.getLambdaClient)((0, get_current_region_1.getCurrentRegionInFunction)()).send(new client_lambda_1.InvokeCommand({
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: constants_1.CURRENT_VERSION,
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: (0, get_output_url_from_metadata_1.getOutputUrlFromMetadata)(renderMetadata, params.bucketName),
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
- timeoutInMiliseconds: number;
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
- timeoutInMiliseconds: options.timeoutInMiliseconds,
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, _b;
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
- await (0, renderer_1.renderMedia)({
45
- composition: {
46
- id: params.composition,
47
- durationInFrames: params.durationInFrames,
48
- fps: params.fps,
49
- height: params.height,
50
- width: params.width,
51
- },
52
- imageFormat: params.imageFormat,
53
- inputProps: params.inputProps,
54
- frameRange: params.frameRange,
55
- onProgress: ({ renderedFrames, encodedFrames, stitchStage }) => {
56
- if (renderedFrames % 10 === 0 &&
57
- renderer_1.RenderInternals.isEqualOrBelowLogLevel(params.logLevel, 'verbose')) {
58
- console.log(`Rendered ${renderedFrames} frames, encoded ${encodedFrames} frames, stage = ${stitchStage}`);
59
- }
60
- const allFrames = renderer_1.RenderInternals.getFramesToRender(params.frameRange, params.everyNthFrame);
61
- if (renderedFrames === allFrames.length) {
62
- console.log('Rendered all frames!');
63
- }
64
- chunkTimingData.timings[renderedFrames] = Date.now() - start;
65
- },
66
- parallelism: params.concurrencyPerLambda,
67
- onStart: () => {
68
- (0, io_1.lambdaWriteFile)({
69
- privacy: 'private',
70
- bucketName: params.bucketName,
71
- body: JSON.stringify({
72
- filesCleaned: clean_tmpdir_1.deletedFilesSize,
73
- filesInTmp: fs_1.default.readdirSync('/tmp'),
74
- isWarm: options.isWarm,
75
- deletedFiles: clean_tmpdir_1.deletedFiles,
76
- tmpSize: (0, get_folder_size_1.getFolderSizeRecursively)('/tmp'),
77
- tmpDirFiles: (0, get_files_in_folder_1.getFolderFiles)('/tmp'),
78
- }),
79
- key: (0, constants_1.lambdaInitializedKey)({
80
- renderId: params.renderId,
81
- chunk: params.chunk,
82
- attempt: params.attempt,
83
- }),
84
- region: (0, get_current_region_1.getCurrentRegionInFunction)(),
85
- expectedBucketOwner: options.expectedBucketOwner,
86
- downloadBehavior: null,
87
- });
88
- },
89
- puppeteerInstance: browserInstance,
90
- serveUrl: params.serveUrl,
91
- quality: params.quality,
92
- envVariables: params.envVariables,
93
- dumpBrowserLogs: renderer_1.RenderInternals.isEqualOrBelowLogLevel(params.logLevel, 'verbose'),
94
- verbose: renderer_1.RenderInternals.isEqualOrBelowLogLevel(params.logLevel, 'verbose'),
95
- onBrowserLog: (log) => {
96
- logs.push(log);
97
- },
98
- outputLocation,
99
- codec: chunkCodec,
100
- crf: (_b = params.crf) !== null && _b !== void 0 ? _b : undefined,
101
- ffmpegExecutable: process.env.NODE_ENV === 'test' ? null : '/opt/bin/ffmpeg',
102
- pixelFormat: params.pixelFormat,
103
- proResProfile: params.proResProfile,
104
- onDownload: (src) => {
105
- console.log('Downloading', src);
106
- return () => undefined;
107
- },
108
- overwrite: false,
109
- chromiumOptions: params.chromiumOptions,
110
- scale: params.scale,
111
- timeoutInMilliseconds: params.timeoutInMilliseconds,
112
- port: null,
113
- everyNthFrame: params.everyNthFrame,
114
- numberOfGifLoops: null,
115
- downloadMap,
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
- export declare const startHandler: (params: LambdaPayload) => Promise<{
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 {};