@remotion/lambda 4.0.17 → 4.0.18

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/cli/log.d.ts CHANGED
@@ -2,24 +2,24 @@ export declare const Log: {
2
2
  verbose: (message?: any, ...optionalParams: any[]) => void;
3
3
  verboseAdvanced: (options: {
4
4
  indent: boolean;
5
- logLevel: "info" | "error" | "verbose" | "warn";
5
+ logLevel: "verbose" | "info" | "warn" | "error";
6
6
  } & {
7
7
  tag?: string | undefined;
8
8
  }, message?: any, ...optionalParams: any[]) => void;
9
9
  info: (message?: any, ...optionalParams: any[]) => void;
10
10
  infoAdvanced: (options: {
11
11
  indent: boolean;
12
- logLevel: "info" | "error" | "verbose" | "warn";
12
+ logLevel: "verbose" | "info" | "warn" | "error";
13
13
  }, message?: any, ...optionalParams: any[]) => void;
14
14
  warn: (message?: any, ...optionalParams: any[]) => void;
15
15
  warnAdvanced: (options: {
16
16
  indent: boolean;
17
- logLevel: "info" | "error" | "verbose" | "warn";
17
+ logLevel: "verbose" | "info" | "warn" | "error";
18
18
  }, message?: any, ...optionalParams: any[]) => void;
19
19
  error: (message?: any, ...optionalParams: any[]) => void;
20
20
  errorAdvanced: (options: {
21
21
  indent: boolean;
22
- logLevel: "info" | "error" | "verbose" | "warn";
22
+ logLevel: "verbose" | "info" | "warn" | "error";
23
23
  } & {
24
24
  tag?: string | undefined;
25
25
  }, message?: any, ...optionalParams: any[]) => void;
@@ -9,7 +9,7 @@ export declare const getAllFilesS3: ({ bucket, expectedFiles, outdir, renderId,
9
9
  renderId: string;
10
10
  region: AwsRegion;
11
11
  expectedBucketOwner: string;
12
- onErrors: (errors: EnhancedErrorInfo[]) => Promise<void>;
12
+ onErrors: (errors: EnhancedErrorInfo[]) => void;
13
13
  }) => Promise<string[]>;
14
14
  export declare const concatVideosS3: ({ onProgress, numberOfFrames, codec, fps, numberOfGifLoops, files, outdir, audioCodec, }: {
15
15
  onProgress: (frames: number) => void;
@@ -96,7 +96,7 @@ const getAllFilesS3 = ({ bucket, expectedFiles, outdir, renderId, region, expect
96
96
  renderId,
97
97
  })).filter((e) => e.isFatal);
98
98
  if (errors.length > 0) {
99
- await onErrors(errors);
99
+ onErrors(errors);
100
100
  // Will die here
101
101
  }
102
102
  filesInBucket.forEach(async (key) => {
@@ -89,51 +89,7 @@ const innerLaunchHandler = async (params, options) => {
89
89
  }
90
90
  const functionName = (_a = params.rendererFunctionName) !== null && _a !== void 0 ? _a : process.env.AWS_LAMBDA_FUNCTION_NAME;
91
91
  const startedDate = Date.now();
92
- let webhookInvoked = false;
93
- console.log(`Function has ${Math.max(options.getRemainingTimeInMillis() - 1000, 1000)} before it times out`);
94
92
  const verbose = renderer_1.RenderInternals.isEqualOrBelowLogLevel(params.logLevel, 'verbose');
95
- const webhookDueToTimeout = setTimeout(async () => {
96
- if (params.webhook && !webhookInvoked) {
97
- try {
98
- await (0, invoke_webhook_1.invokeWebhook)({
99
- url: params.webhook.url,
100
- secret: params.webhook.secret,
101
- payload: {
102
- type: 'timeout',
103
- renderId: params.renderId,
104
- expectedBucketOwner: options.expectedBucketOwner,
105
- bucketName: params.bucketName,
106
- },
107
- });
108
- webhookInvoked = true;
109
- }
110
- catch (err) {
111
- if (process.env.NODE_ENV === 'test') {
112
- throw err;
113
- }
114
- await (0, write_lambda_error_1.writeLambdaError)({
115
- bucketName: params.bucketName,
116
- errorInfo: {
117
- type: 'webhook',
118
- message: err.message,
119
- name: err.name,
120
- stack: err.stack,
121
- tmpDir: null,
122
- frame: 0,
123
- chunk: 0,
124
- isFatal: false,
125
- attempt: 1,
126
- willRetry: false,
127
- totalAttempts: 1,
128
- },
129
- renderId: params.renderId,
130
- expectedBucketOwner: options.expectedBucketOwner,
131
- });
132
- console.log('Failed to invoke webhook:');
133
- console.log(err);
134
- }
135
- }
136
- }, Math.max(options.getRemainingTimeInMillis() - 1000, 1000));
137
93
  const browserInstance = await (0, get_browser_instance_1.getBrowserInstance)(params.logLevel, false, params.chromiumOptions);
138
94
  const inputPropsPromise = (0, compress_props_1.decompressInputProps)({
139
95
  bucketName: params.bucketName,
@@ -245,7 +201,7 @@ const innerLaunchHandler = async (params, options) => {
245
201
  };
246
202
  return payload;
247
203
  });
248
- console.log('Render plan: ', chunks.map((c, i) => `Chunk ${i} (Frames ${c[0]} - ${c[1]})`).join(', '));
204
+ renderer_1.RenderInternals.Log.info('Render plan: ', chunks.map((c, i) => `Chunk ${i} (Frames ${c[0]} - ${c[1]})`).join(', '));
249
205
  const renderMetadata = {
250
206
  startedDate,
251
207
  videoConfig: comp,
@@ -349,30 +305,8 @@ const innerLaunchHandler = async (params, options) => {
349
305
  });
350
306
  });
351
307
  };
352
- const onErrors = async (errors) => {
353
- var _a;
354
- console.log('Found Errors', errors);
355
- if (params.webhook) {
356
- console.log('Sending webhook with errors');
357
- await (0, invoke_webhook_1.invokeWebhook)({
358
- url: params.webhook.url,
359
- secret: (_a = params.webhook.secret) !== null && _a !== void 0 ? _a : null,
360
- payload: {
361
- type: 'error',
362
- renderId: params.renderId,
363
- expectedBucketOwner: options.expectedBucketOwner,
364
- bucketName: params.bucketName,
365
- errors: errors.slice(0, 5).map((e) => ({
366
- message: e.message,
367
- name: e.name,
368
- stack: e.stack,
369
- })),
370
- },
371
- });
372
- }
373
- else {
374
- console.log('No webhook specified');
375
- }
308
+ const onErrors = (errors) => {
309
+ renderer_1.RenderInternals.Log.error('Found Errors', errors);
376
310
  const firstError = errors[0];
377
311
  if (firstError.chunk !== null) {
378
312
  throw new Error(`Stopping Lambda function because error occurred while rendering chunk ${firstError.chunk}:\n${errors[0].stack
@@ -503,60 +437,104 @@ const innerLaunchHandler = async (params, options) => {
503
437
  customCredentials: null,
504
438
  });
505
439
  await Promise.all([cleanupChunksProm, node_fs_1.default.promises.rm(outfile)]);
506
- clearTimeout(webhookDueToTimeout);
507
- if (params.webhook && !webhookInvoked) {
508
- try {
509
- await (0, invoke_webhook_1.invokeWebhook)({
510
- url: params.webhook.url,
511
- secret: params.webhook.secret,
512
- payload: {
513
- type: 'success',
514
- renderId: params.renderId,
515
- expectedBucketOwner: options.expectedBucketOwner,
516
- bucketName: params.bucketName,
517
- outputUrl,
518
- lambdaErrors: postRenderData.errors,
519
- outputFile: postRenderData.outputFile,
520
- timeToFinish: postRenderData.timeToFinish,
521
- costs: postRenderData.cost,
522
- },
523
- });
524
- webhookInvoked = true;
525
- }
526
- catch (err) {
527
- if (process.env.NODE_ENV === 'test') {
528
- throw err;
529
- }
530
- await (0, write_lambda_error_1.writeLambdaError)({
531
- bucketName: params.bucketName,
532
- errorInfo: {
533
- type: 'webhook',
534
- message: err.message,
535
- name: err.name,
536
- stack: err.stack,
537
- tmpDir: null,
538
- frame: 0,
539
- chunk: 0,
540
- isFatal: false,
541
- attempt: 1,
542
- willRetry: false,
543
- totalAttempts: 1,
544
- },
545
- renderId: params.renderId,
546
- expectedBucketOwner: options.expectedBucketOwner,
547
- });
548
- console.log('Failed to invoke webhook:');
549
- console.log(err);
550
- }
551
- }
440
+ return postRenderData;
552
441
  };
553
442
  const launchHandler = async (params, options) => {
554
- var _a, _b;
555
443
  if (params.type !== constants_1.LambdaRoutines.launch) {
556
444
  throw new Error('Expected launch type');
557
445
  }
446
+ let webhookInvoked = false;
447
+ const webhookDueToTimeout = setTimeout(async () => {
448
+ if (params.webhook && !webhookInvoked) {
449
+ try {
450
+ await (0, invoke_webhook_1.invokeWebhook)({
451
+ url: params.webhook.url,
452
+ secret: params.webhook.secret,
453
+ payload: {
454
+ type: 'timeout',
455
+ renderId: params.renderId,
456
+ expectedBucketOwner: options.expectedBucketOwner,
457
+ bucketName: params.bucketName,
458
+ },
459
+ });
460
+ webhookInvoked = true;
461
+ }
462
+ catch (err) {
463
+ if (process.env.NODE_ENV === 'test') {
464
+ throw err;
465
+ }
466
+ await (0, write_lambda_error_1.writeLambdaError)({
467
+ bucketName: params.bucketName,
468
+ errorInfo: {
469
+ type: 'webhook',
470
+ message: err.message,
471
+ name: err.name,
472
+ stack: err.stack,
473
+ tmpDir: null,
474
+ frame: 0,
475
+ chunk: 0,
476
+ isFatal: false,
477
+ attempt: 1,
478
+ willRetry: false,
479
+ totalAttempts: 1,
480
+ },
481
+ renderId: params.renderId,
482
+ expectedBucketOwner: options.expectedBucketOwner,
483
+ });
484
+ renderer_1.RenderInternals.Log.error('Failed to invoke webhook:');
485
+ renderer_1.RenderInternals.Log.error(err);
486
+ }
487
+ }
488
+ }, Math.max(options.getRemainingTimeInMillis() - 1000, 1000));
489
+ renderer_1.RenderInternals.Log.info(`Function has ${Math.max(options.getRemainingTimeInMillis() - 1000, 1000)} before it times out`);
558
490
  try {
559
- await innerLaunchHandler(params, options);
491
+ const postRenderData = await innerLaunchHandler(params, options);
492
+ clearTimeout(webhookDueToTimeout);
493
+ if (params.webhook && !webhookInvoked) {
494
+ try {
495
+ await (0, invoke_webhook_1.invokeWebhook)({
496
+ url: params.webhook.url,
497
+ secret: params.webhook.secret,
498
+ payload: {
499
+ type: 'success',
500
+ renderId: params.renderId,
501
+ expectedBucketOwner: options.expectedBucketOwner,
502
+ bucketName: params.bucketName,
503
+ outputUrl: postRenderData.outputFile,
504
+ lambdaErrors: postRenderData.errors,
505
+ outputFile: postRenderData.outputFile,
506
+ timeToFinish: postRenderData.timeToFinish,
507
+ costs: postRenderData.cost,
508
+ },
509
+ });
510
+ webhookInvoked = true;
511
+ }
512
+ catch (err) {
513
+ if (process.env.NODE_ENV === 'test') {
514
+ throw err;
515
+ }
516
+ await (0, write_lambda_error_1.writeLambdaError)({
517
+ bucketName: params.bucketName,
518
+ errorInfo: {
519
+ type: 'webhook',
520
+ message: err.message,
521
+ name: err.name,
522
+ stack: err.stack,
523
+ tmpDir: null,
524
+ frame: 0,
525
+ chunk: 0,
526
+ isFatal: false,
527
+ attempt: 1,
528
+ willRetry: false,
529
+ totalAttempts: 1,
530
+ },
531
+ renderId: params.renderId,
532
+ expectedBucketOwner: options.expectedBucketOwner,
533
+ });
534
+ renderer_1.RenderInternals.Log.error('Failed to invoke webhook:');
535
+ renderer_1.RenderInternals.Log.error(err);
536
+ }
537
+ }
560
538
  return {
561
539
  type: 'success',
562
540
  };
@@ -565,7 +543,7 @@ const launchHandler = async (params, options) => {
565
543
  if (process.env.NODE_ENV === 'test') {
566
544
  throw err;
567
545
  }
568
- console.log('Error occurred', err);
546
+ renderer_1.RenderInternals.Log.error('Error occurred', err);
569
547
  await (0, write_lambda_error_1.writeLambdaError)({
570
548
  bucketName: params.bucketName,
571
549
  errorInfo: {
@@ -584,11 +562,12 @@ const launchHandler = async (params, options) => {
584
562
  expectedBucketOwner: options.expectedBucketOwner,
585
563
  renderId: params.renderId,
586
564
  });
587
- if ((_a = params.webhook) === null || _a === void 0 ? void 0 : _a.url) {
565
+ clearTimeout(webhookDueToTimeout);
566
+ if (params.webhook && !webhookInvoked) {
588
567
  try {
589
568
  await (0, invoke_webhook_1.invokeWebhook)({
590
569
  url: params.webhook.url,
591
- secret: (_b = params.webhook.secret) !== null && _b !== void 0 ? _b : null,
570
+ secret: params.webhook.secret,
592
571
  payload: {
593
572
  type: 'error',
594
573
  renderId: params.renderId,
@@ -601,6 +580,7 @@ const launchHandler = async (params, options) => {
601
580
  })),
602
581
  },
603
582
  });
583
+ webhookInvoked = true;
604
584
  }
605
585
  catch (error) {
606
586
  if (process.env.NODE_ENV === 'test') {
@@ -624,8 +604,8 @@ const launchHandler = async (params, options) => {
624
604
  renderId: params.renderId,
625
605
  expectedBucketOwner: options.expectedBucketOwner,
626
606
  });
627
- console.log('Failed to invoke webhook:');
628
- console.log(error);
607
+ renderer_1.RenderInternals.Log.error('Failed to invoke webhook:');
608
+ renderer_1.RenderInternals.Log.error(error);
629
609
  }
630
610
  }
631
611
  throw err;
@@ -0,0 +1,8 @@
1
+ import type { AwsRegion } from '../client';
2
+ import type { SerializedInputProps } from './constants';
3
+ export declare const deserializeInputProps: ({ serialized, region, bucketName, expectedBucketOwner, }: {
4
+ serialized: SerializedInputProps;
5
+ region: AwsRegion;
6
+ bucketName: string;
7
+ expectedBucketOwner: string;
8
+ }) => Promise<Record<string, unknown>>;
@@ -0,0 +1,26 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.deserializeInputProps = void 0;
4
+ const io_1 = require("../functions/helpers/io");
5
+ const constants_1 = require("./constants");
6
+ const stream_to_string_1 = require("./stream-to-string");
7
+ const deserializeInputProps = async ({ serialized, region, bucketName, expectedBucketOwner, }) => {
8
+ if (serialized.type === 'payload') {
9
+ return JSON.parse(serialized.payload);
10
+ }
11
+ try {
12
+ const response = await (0, io_1.lambdaReadFile)({
13
+ bucketName,
14
+ expectedBucketOwner,
15
+ key: (0, constants_1.inputPropsKey)(serialized.hash),
16
+ region,
17
+ });
18
+ const body = await (0, stream_to_string_1.streamToString)(response);
19
+ const payload = JSON.parse(body);
20
+ return payload;
21
+ }
22
+ catch (err) {
23
+ throw new Error(`Failed to parse input props that were serialized: ${err.stack}`);
24
+ }
25
+ };
26
+ exports.deserializeInputProps = deserializeInputProps;
@@ -0,0 +1,14 @@
1
+ import type { AwsRegion } from '../client';
2
+ import type { SerializedInputProps } from './constants';
3
+ export declare const serializeInputProps: ({ inputProps, region, type, userSpecifiedBucketName, }: {
4
+ inputProps: Record<string, unknown>;
5
+ region: AwsRegion;
6
+ type: 'still' | 'video-or-audio';
7
+ userSpecifiedBucketName: string | null;
8
+ }) => Promise<SerializedInputProps>;
9
+ export declare const deserializeInputProps: ({ serialized, region, bucketName, expectedBucketOwner, }: {
10
+ serialized: SerializedInputProps;
11
+ region: AwsRegion;
12
+ bucketName: string;
13
+ expectedBucketOwner: string;
14
+ }) => Promise<Record<string, unknown>>;
@@ -0,0 +1,63 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.deserializeInputProps = exports.serializeInputProps = void 0;
4
+ const get_or_create_bucket_1 = require("../api/get-or-create-bucket");
5
+ const io_1 = require("../functions/helpers/io");
6
+ const constants_1 = require("./constants");
7
+ const random_hash_1 = require("./random-hash");
8
+ const stream_to_string_1 = require("./stream-to-string");
9
+ const serializeInputProps = async ({ inputProps, region, type, userSpecifiedBucketName, }) => {
10
+ try {
11
+ const payload = JSON.stringify(inputProps);
12
+ const hash = (0, random_hash_1.randomHash)();
13
+ const MAX_INLINE_PAYLOAD_SIZE = type === 'still' ? 5000000 : 200000;
14
+ if (payload.length > MAX_INLINE_PAYLOAD_SIZE) {
15
+ console.warn(`Warning: inputProps are over ${Math.round(MAX_INLINE_PAYLOAD_SIZE / 1000)}KB (${Math.ceil(payload.length / 1024)}KB) in size. Uploading them to S3 to circumvent AWS Lambda payload size.`);
16
+ const bucketName = userSpecifiedBucketName !== null && userSpecifiedBucketName !== void 0 ? userSpecifiedBucketName : (await (0, get_or_create_bucket_1.getOrCreateBucket)({
17
+ region,
18
+ })).bucketName;
19
+ await (0, io_1.lambdaWriteFile)({
20
+ body: payload,
21
+ bucketName,
22
+ region,
23
+ customCredentials: null,
24
+ downloadBehavior: null,
25
+ expectedBucketOwner: null,
26
+ key: (0, constants_1.inputPropsKey)(hash),
27
+ privacy: 'public',
28
+ });
29
+ return {
30
+ type: 'bucket-url',
31
+ hash,
32
+ };
33
+ }
34
+ return {
35
+ type: 'payload',
36
+ payload,
37
+ };
38
+ }
39
+ catch (err) {
40
+ throw new Error('Error serializing inputProps. Check it has no circular references or reduce the size if the object is big.');
41
+ }
42
+ };
43
+ exports.serializeInputProps = serializeInputProps;
44
+ const deserializeInputProps = async ({ serialized, region, bucketName, expectedBucketOwner, }) => {
45
+ if (serialized.type === 'payload') {
46
+ return JSON.parse(serialized.payload);
47
+ }
48
+ try {
49
+ const response = await (0, io_1.lambdaReadFile)({
50
+ bucketName,
51
+ expectedBucketOwner,
52
+ key: (0, constants_1.inputPropsKey)(serialized.hash),
53
+ region,
54
+ });
55
+ const body = await (0, stream_to_string_1.streamToString)(response);
56
+ const payload = JSON.parse(body);
57
+ return payload;
58
+ }
59
+ catch (err) {
60
+ throw new Error(`Failed to parse input props that were serialized: ${err.stack}`);
61
+ }
62
+ };
63
+ exports.deserializeInputProps = deserializeInputProps;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@remotion/lambda",
3
- "version": "4.0.17",
3
+ "version": "4.0.18",
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/bundler": "4.0.17",
30
- "remotion": "4.0.17",
31
- "@remotion/renderer": "4.0.17",
32
- "@remotion/cli": "4.0.17"
29
+ "@remotion/bundler": "4.0.18",
30
+ "@remotion/cli": "4.0.18",
31
+ "remotion": "4.0.18",
32
+ "@remotion/renderer": "4.0.18"
33
33
  },
34
34
  "devDependencies": {
35
35
  "@jonny/eslint-config": "3.0.266",
@@ -41,14 +41,13 @@
41
41
  "prettier": "^2.4.1",
42
42
  "prettier-plugin-organize-imports": "^3.2.2",
43
43
  "ts-node": "^10.8.0",
44
- "typescript": "4.9.5",
45
44
  "vitest": "0.31.1",
46
45
  "zip-lib": "^0.7.2",
47
- "@remotion/bundler": "4.0.17",
48
- "@remotion/compositor-linux-arm64-gnu": "4.0.17"
46
+ "@remotion/bundler": "4.0.18",
47
+ "@remotion/compositor-linux-arm64-gnu": "4.0.18"
49
48
  },
50
49
  "peerDependencies": {
51
- "@remotion/bundler": "4.0.17"
50
+ "@remotion/bundler": "4.0.18"
52
51
  },
53
52
  "publishConfig": {
54
53
  "access": "public"
Binary file
@@ -1 +0,0 @@
1
- export declare const isFlakyError: (err: Error) => boolean;
@@ -1,13 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.isFlakyError = void 0;
4
- const isFlakyError = (err) => {
5
- const { message } = err;
6
- return (message.includes('FATAL:zygote_communication_linux.cc') ||
7
- message.includes('error while loading shared libraries: libnss3.so') ||
8
- message.includes('but the server sent no data') ||
9
- message.includes('Compositor panicked') ||
10
- (message.includes('Compositor exited') && !message.includes('SIGSEGV')) ||
11
- message.includes('Timed out while setting up the headless browser'));
12
- };
13
- exports.isFlakyError = isFlakyError;