@remotion/lambda 4.0.45 → 4.0.47

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/LICENSE.md CHANGED
@@ -38,4 +38,4 @@ Support is provided on a best-we-can-do basis via GitHub Issues and Discord.
38
38
 
39
39
  You are required to obtain a company license to use Remotion if you are not within the group of entities eligible for a free license. This license will enable you to use Remotion for the allowed use cases specified in the free license, and give you access to prioritized support (read the [Support Policy](/docs/support)).
40
40
 
41
- Visit [companies.remotion.dev](https://companies.remotion.dev) for pricing and to buy a license.
41
+ Visit [remotion.pro](https://www.remotion.pro) for pricing and to buy a license.
@@ -22,6 +22,11 @@ const quit_1 = require("../../helpers/quit");
22
22
  const log_1 = require("../../log");
23
23
  const progress_1 = require("./progress");
24
24
  exports.RENDER_COMMAND = 'render';
25
+ function getTotalFrames(status) {
26
+ return status.renderMetadata
27
+ ? renderer_1.RenderInternals.getFramesToRender(status.renderMetadata.frameRange, status.renderMetadata.everyNthFrame).length
28
+ : null;
29
+ }
25
30
  const renderCommand = async (args, remotionRoot) => {
26
31
  var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k;
27
32
  const serveUrl = args[0];
@@ -299,8 +304,3 @@ const renderCommand = async (args, remotionRoot) => {
299
304
  }
300
305
  };
301
306
  exports.renderCommand = renderCommand;
302
- function getTotalFrames(status) {
303
- return status.renderMetadata
304
- ? renderer_1.RenderInternals.getFramesToRender(status.renderMetadata.frameRange, status.renderMetadata.everyNthFrame).length
305
- : null;
306
- }
@@ -10,7 +10,7 @@ const convert_to_serve_url_1 = require("../shared/convert-to-serve-url");
10
10
  const get_browser_instance_1 = require("./helpers/get-browser-instance");
11
11
  const get_current_region_1 = require("./helpers/get-current-region");
12
12
  const compositionsHandler = async (lambdaParams, options) => {
13
- var _a, _b, _c;
13
+ var _a;
14
14
  if (lambdaParams.type !== defaults_1.LambdaRoutines.compositions) {
15
15
  throw new TypeError('Expected info compositions');
16
16
  }
@@ -21,16 +21,17 @@ const compositionsHandler = async (lambdaParams, options) => {
21
21
  throw new Error(`Version mismatch: When calling getCompositionsOnLambda(), you passed ${process.env.AWS_LAMBDA_FUNCTION_NAME} as the function, which has the version ${version_1.VERSION}, but the @remotion/lambda package you used to invoke the function has version ${lambdaParams.version}. Deploy a new function and use it to call getCompositionsOnLambda(). See: https://www.remotion.dev/docs/lambda/upgrading`);
22
22
  }
23
23
  const region = (0, get_current_region_1.getCurrentRegionInFunction)();
24
- const [bucketName, browserInstance] = await Promise.all([
25
- (_a = lambdaParams.bucketName) !== null && _a !== void 0 ? _a : (0, get_or_create_bucket_1.internalGetOrCreateBucket)({
24
+ const browserInstancePromise = (0, get_browser_instance_1.getBrowserInstance)(lambdaParams.logLevel, false, lambdaParams.chromiumOptions);
25
+ const bucketNamePromise = lambdaParams.bucketName
26
+ ? Promise.resolve(lambdaParams.bucketName)
27
+ : (0, get_or_create_bucket_1.internalGetOrCreateBucket)({
26
28
  region,
27
29
  enableFolderExpiry: null,
28
30
  customCredentials: null,
29
- }).then((b) => b.bucketName),
30
- (0, get_browser_instance_1.getBrowserInstance)(lambdaParams.logLevel, false, (_b = lambdaParams.chromiumOptions) !== null && _b !== void 0 ? _b : {}),
31
- ]);
31
+ }).then((b) => b.bucketName);
32
+ const bucketName = await bucketNamePromise;
32
33
  const serializedInputPropsWithCustomSchema = await (0, compress_props_1.decompressInputProps)({
33
- bucketName,
34
+ bucketName: await bucketNamePromise,
34
35
  expectedBucketOwner: options.expectedBucketOwner,
35
36
  region: (0, get_current_region_1.getCurrentRegionInFunction)(),
36
37
  serialized: lambdaParams.inputProps,
@@ -43,9 +44,9 @@ const compositionsHandler = async (lambdaParams, options) => {
43
44
  });
44
45
  const compositions = await renderer_1.RenderInternals.internalGetCompositions({
45
46
  serveUrlOrWebpackUrl: realServeUrl,
46
- puppeteerInstance: browserInstance,
47
+ puppeteerInstance: (await browserInstancePromise).instance,
47
48
  serializedInputPropsWithCustomSchema,
48
- envVariables: (_c = lambdaParams.envVariables) !== null && _c !== void 0 ? _c : {},
49
+ envVariables: (_a = lambdaParams.envVariables) !== null && _a !== void 0 ? _a : {},
49
50
  timeoutInMilliseconds: lambdaParams.timeoutInMilliseconds,
50
51
  chromiumOptions: lambdaParams.chromiumOptions,
51
52
  port: null,
@@ -56,6 +57,7 @@ const compositionsHandler = async (lambdaParams, options) => {
56
57
  onBrowserLog: null,
57
58
  offthreadVideoCacheSizeInBytes: lambdaParams.offthreadVideoCacheSizeInBytes,
58
59
  });
60
+ (await browserInstancePromise).instance.forgetEventLoop();
59
61
  return Promise.resolve({
60
62
  compositions,
61
63
  type: 'success',
@@ -11,7 +11,7 @@ export declare const getAllFilesS3: ({ bucket, expectedFiles, outdir, renderId,
11
11
  expectedBucketOwner: string;
12
12
  onErrors: (errors: EnhancedErrorInfo[]) => void;
13
13
  }) => Promise<string[]>;
14
- export declare const concatVideosS3: ({ onProgress, numberOfFrames, codec, fps, numberOfGifLoops, files, outdir, audioCodec, }: {
14
+ export declare const concatVideosS3: ({ onProgress, numberOfFrames, codec, fps, numberOfGifLoops, files, outdir, audioCodec, audioBitrate, }: {
15
15
  onProgress: (frames: number) => void;
16
16
  numberOfFrames: number;
17
17
  codec: LambdaCodec;
@@ -20,6 +20,7 @@ export declare const concatVideosS3: ({ onProgress, numberOfFrames, codec, fps,
20
20
  files: string[];
21
21
  outdir: string;
22
22
  audioCodec: AudioCodec | null;
23
+ audioBitrate: string | null;
23
24
  }) => Promise<{
24
25
  outfile: string;
25
26
  cleanupChunksProm: Promise<void>;
@@ -133,7 +133,7 @@ const getAllFilesS3 = ({ bucket, expectedFiles, outdir, renderId, region, expect
133
133
  });
134
134
  };
135
135
  exports.getAllFilesS3 = getAllFilesS3;
136
- const concatVideosS3 = async ({ onProgress, numberOfFrames, codec, fps, numberOfGifLoops, files, outdir, audioCodec, }) => {
136
+ const concatVideosS3 = async ({ onProgress, numberOfFrames, codec, fps, numberOfGifLoops, files, outdir, audioCodec, audioBitrate, }) => {
137
137
  const outfile = (0, node_path_1.join)(renderer_1.RenderInternals.tmpDir(constants_1.REMOTION_CONCATED_TOKEN), 'concat.' + renderer_1.RenderInternals.getFileExtensionFromCodec(codec, audioCodec));
138
138
  const combine = (0, timer_1.timer)('Combine videos');
139
139
  const filelistDir = renderer_1.RenderInternals.tmpDir(constants_1.REMOTION_FILELIST_TOKEN);
@@ -147,6 +147,7 @@ const concatVideosS3 = async ({ onProgress, numberOfFrames, codec, fps, numberOf
147
147
  fps,
148
148
  numberOfGifLoops,
149
149
  audioCodec,
150
+ audioBitrate,
150
151
  });
151
152
  combine.end();
152
153
  const cleanupChunksProm = node_fs_1.default.promises.rm(outdir, {
@@ -1,2 +1,8 @@
1
1
  import type { ChromiumOptions, LogLevel, openBrowser } from '@remotion/renderer';
2
- export declare const getBrowserInstance: (logLevel: LogLevel, indent: boolean, chromiumOptions: ChromiumOptions) => ReturnType<typeof openBrowser>;
2
+ import type { Await } from '../../shared/await';
3
+ type LaunchedBrowser = {
4
+ instance: Await<ReturnType<typeof openBrowser>>;
5
+ configurationString: string;
6
+ };
7
+ export declare const getBrowserInstance: (logLevel: LogLevel, indent: boolean, chromiumOptions: ChromiumOptions) => Promise<LaunchedBrowser>;
8
+ export {};
@@ -3,6 +3,18 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.getBrowserInstance = void 0;
4
4
  const renderer_1 = require("@remotion/renderer");
5
5
  const get_chromium_executable_path_1 = require("./get-chromium-executable-path");
6
+ const makeConfigurationString = (options, logLevel) => {
7
+ var _a, _b, _c;
8
+ return [
9
+ `web-security-${Boolean(options.disableWebSecurity)}`,
10
+ `multi-process-${Boolean(options.enableMultiProcessOnLinux)}`,
11
+ `ignore-certificate-errors-${Boolean(options.ignoreCertificateErrors)}`,
12
+ `log-level-${logLevel}`,
13
+ `gl-${(_a = options.gl) !== null && _a !== void 0 ? _a : null}`,
14
+ `userAgent-${(_b = options.userAgent) !== null && _b !== void 0 ? _b : null}`,
15
+ `headless-${(_c = options.headless) !== null && _c !== void 0 ? _c : false}`,
16
+ ].join('/');
17
+ };
6
18
  let _browserInstance;
7
19
  let launching = false;
8
20
  const waitForLaunched = () => {
@@ -21,38 +33,54 @@ const waitForLaunched = () => {
21
33
  };
22
34
  const getBrowserInstance = async (logLevel, indent, chromiumOptions) => {
23
35
  var _a;
36
+ const actualChromiumOptions = {
37
+ ...chromiumOptions,
38
+ // Override the `null` value, which might come from CLI with swANGLE
39
+ gl: (_a = chromiumOptions.gl) !== null && _a !== void 0 ? _a : 'swangle',
40
+ };
24
41
  if (launching) {
42
+ renderer_1.RenderInternals.Log.info('Already waiting for browser launch...');
25
43
  await waitForLaunched();
26
44
  if (!_browserInstance) {
27
45
  throw new Error('expected to launch');
28
46
  }
29
- return _browserInstance;
30
47
  }
31
- if (_browserInstance) {
48
+ const configurationString = makeConfigurationString(actualChromiumOptions, logLevel);
49
+ if (!_browserInstance) {
50
+ renderer_1.RenderInternals.Log.info('Cold Lambda function, launching new Lambda function');
51
+ launching = true;
52
+ const execPath = (0, get_chromium_executable_path_1.executablePath)();
53
+ const instance = await renderer_1.RenderInternals.internalOpenBrowser({
54
+ browser: 'chrome',
55
+ browserExecutable: execPath,
56
+ chromiumOptions: actualChromiumOptions,
57
+ forceDeviceScaleFactor: undefined,
58
+ indent: false,
59
+ viewport: null,
60
+ logLevel,
61
+ });
62
+ instance.on('disconnected', () => {
63
+ var _a;
64
+ console.log('Browser disconnected / crashed');
65
+ (_a = _browserInstance === null || _browserInstance === void 0 ? void 0 : _browserInstance.instance) === null || _a === void 0 ? void 0 : _a.close(true, logLevel, indent).catch(() => undefined);
66
+ _browserInstance = null;
67
+ });
68
+ _browserInstance = {
69
+ instance,
70
+ configurationString,
71
+ };
72
+ launching = false;
32
73
  return _browserInstance;
33
74
  }
34
- launching = true;
35
- const execPath = (0, get_chromium_executable_path_1.executablePath)();
36
- const actualChromiumOptions = {
37
- ...chromiumOptions,
38
- // Override the `null` value, which might come from CLI with swANGLE
39
- gl: (_a = chromiumOptions.gl) !== null && _a !== void 0 ? _a : 'swangle',
40
- };
41
- _browserInstance = await renderer_1.RenderInternals.internalOpenBrowser({
42
- browser: 'chrome',
43
- browserExecutable: execPath,
44
- chromiumOptions: actualChromiumOptions,
45
- forceDeviceScaleFactor: undefined,
46
- indent: false,
47
- viewport: null,
48
- logLevel,
49
- });
50
- _browserInstance.on('disconnected', () => {
51
- console.log('Browser disconnected / crashed');
52
- _browserInstance === null || _browserInstance === void 0 ? void 0 : _browserInstance.close(true, logLevel, indent).catch(() => undefined);
75
+ if (_browserInstance.configurationString !== configurationString) {
76
+ renderer_1.RenderInternals.Log.info('Warm Lambda function, but Browser configuration changed. Killing old browser instance.');
77
+ _browserInstance.instance.rememberEventLoop();
78
+ await _browserInstance.instance.close(true, logLevel, indent);
53
79
  _browserInstance = null;
54
- });
55
- launching = false;
80
+ return (0, exports.getBrowserInstance)(logLevel, indent, chromiumOptions);
81
+ }
82
+ renderer_1.RenderInternals.Log.info('Warm Lambda function, reusing browser instance');
83
+ _browserInstance.instance.rememberEventLoop();
56
84
  return _browserInstance;
57
85
  };
58
86
  exports.getBrowserInstance = getBrowserInstance;
@@ -27,4 +27,5 @@ export declare const mergeChunksAndFinishRender: (options: {
27
27
  serializedResolvedProps: SerializedInputProps;
28
28
  renderMetadata: RenderMetadata;
29
29
  onAllChunks: OnAllChunksAvailable;
30
+ audioBitrate: string | null;
30
31
  }) => Promise<PostRenderData>;
@@ -23,12 +23,11 @@ const write_post_render_data_1 = require("./write-post-render-data");
23
23
  const mergeChunksAndFinishRender = async (options) => {
24
24
  let lastProgressUploaded = 0;
25
25
  const onProgress = (framesEncoded) => {
26
- const relativeProgress = framesEncoded / options.frameCountLength;
27
- const deltaSinceLastProgressUploaded = relativeProgress - lastProgressUploaded;
28
- if (deltaSinceLastProgressUploaded < 0.1) {
26
+ const deltaSinceLastProgressUploaded = framesEncoded - lastProgressUploaded;
27
+ if (deltaSinceLastProgressUploaded < 200) {
29
28
  return;
30
29
  }
31
- lastProgressUploaded = relativeProgress;
30
+ lastProgressUploaded = framesEncoded;
32
31
  (0, io_1.lambdaWriteFile)({
33
32
  bucketName: options.bucketName,
34
33
  key: (0, constants_1.encodingProgressKey)(options.renderId),
@@ -100,6 +99,7 @@ const mergeChunksAndFinishRender = async (options) => {
100
99
  files,
101
100
  outdir,
102
101
  audioCodec: options.audioCodec,
102
+ audioBitrate: options.audioBitrate,
103
103
  });
104
104
  const encodingStop = Date.now();
105
105
  const outputSize = fs_1.default.statSync(outfile);
@@ -22,6 +22,13 @@ class ResponseStream extends stream_1.Stream.Writable {
22
22
  }
23
23
  }
24
24
  exports.ResponseStream = ResponseStream;
25
+ function patchArgs(argList) {
26
+ if (!(argList[1] instanceof ResponseStream)) {
27
+ const responseStream = new ResponseStream();
28
+ argList.splice(1, 0, responseStream);
29
+ }
30
+ return argList[1];
31
+ }
25
32
  exports.HANDLER_STREAMING = Symbol.for('aws.lambda.runtime.handler.streaming');
26
33
  exports.STREAM_RESPONSE = 'response';
27
34
  function isInAWS(handler) {
@@ -61,10 +68,3 @@ function streamifyResponse(handler) {
61
68
  });
62
69
  }
63
70
  exports.streamifyResponse = streamifyResponse;
64
- function patchArgs(argList) {
65
- if (!(argList[1] instanceof ResponseStream)) {
66
- const responseStream = new ResponseStream();
67
- argList.splice(1, 0, responseStream);
68
- }
69
- return argList[1];
70
- }
@@ -164,12 +164,5 @@ const routine = async (params, responseStream, context) => {
164
164
  responseStream.write(JSON.stringify(res));
165
165
  responseStream.end();
166
166
  }
167
- finally {
168
- responseStream.on('close', () => {
169
- if (!process.env.VITEST) {
170
- process.exit(0);
171
- }
172
- });
173
- }
174
167
  };
175
168
  exports.handler = (0, streamify_response_1.streamifyResponse)(routine);
@@ -1,6 +1,7 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.launchHandler = void 0;
4
+ /* eslint-disable @typescript-eslint/no-use-before-define */
4
5
  const client_lambda_1 = require("@aws-sdk/client-lambda");
5
6
  const renderer_1 = require("@remotion/renderer");
6
7
  const version_1 = require("remotion/version");
@@ -56,7 +57,7 @@ const innerLaunchHandler = async ({ functionName, params, options, onAllChunksAv
56
57
  throw new Error('Expected launch type');
57
58
  }
58
59
  const startedDate = Date.now();
59
- const browserInstance = await (0, get_browser_instance_1.getBrowserInstance)(params.logLevel, false, params.chromiumOptions);
60
+ const browserInstance = (0, get_browser_instance_1.getBrowserInstance)(params.logLevel, false, params.chromiumOptions);
60
61
  const inputPropsPromise = (0, compress_props_1.decompressInputProps)({
61
62
  bucketName: params.bucketName,
62
63
  expectedBucketOwner: options.expectedBucketOwner,
@@ -69,7 +70,7 @@ const innerLaunchHandler = async ({ functionName, params, options, onAllChunksAv
69
70
  const comp = await (0, validate_composition_1.validateComposition)({
70
71
  serveUrl: params.serveUrl,
71
72
  composition: params.composition,
72
- browserInstance,
73
+ browserInstance: (await browserInstance).instance,
73
74
  serializedInputPropsWithCustomSchema,
74
75
  envVariables: (_a = params.envVariables) !== null && _a !== void 0 ? _a : {},
75
76
  timeoutInMilliseconds: params.timeoutInMilliseconds,
@@ -206,6 +207,7 @@ const innerLaunchHandler = async ({ functionName, params, options, onAllChunksAv
206
207
  deleteAfter: params.deleteAfter,
207
208
  numberOfGifLoops: params.numberOfGifLoops,
208
209
  downloadBehavior: params.downloadBehavior,
210
+ audioBitrate: params.audioBitrate,
209
211
  };
210
212
  const { key, renderBucketName, customCredentials } = (0, expected_out_name_1.getExpectedOutName)(renderMetadata, params.bucketName, typeof params.outName === 'string' || typeof params.outName === 'undefined'
211
213
  ? null
@@ -244,6 +246,7 @@ const innerLaunchHandler = async ({ functionName, params, options, onAllChunksAv
244
246
  await callFunctionWithRetry({ payload, retries: 0, functionName });
245
247
  }));
246
248
  reqSend.end();
249
+ (await browserInstance).instance.forgetEventLoop();
247
250
  const fps = comp.fps / params.everyNthFrame;
248
251
  const postRenderData = await (0, merge_chunks_1.mergeChunksAndFinishRender)({
249
252
  bucketName: params.bucketName,
@@ -265,6 +268,7 @@ const innerLaunchHandler = async ({ functionName, params, options, onAllChunksAv
265
268
  verbose,
266
269
  renderMetadata,
267
270
  onAllChunks: onAllChunksAvailable,
271
+ audioBitrate: params.audioBitrate,
268
272
  });
269
273
  return postRenderData;
270
274
  };
@@ -468,6 +472,7 @@ const launchHandler = async (params, options) => {
468
472
  expectedBucketOwner: options.expectedBucketOwner,
469
473
  renderId: params.renderId,
470
474
  });
475
+ renderer_1.RenderInternals.Log.error('Wrote error to S3');
471
476
  clearTimeout(webhookDueToTimeout);
472
477
  if (params.webhook && !webhookInvoked) {
473
478
  try {
@@ -50,6 +50,7 @@ const mergeHandler = async (params, options) => {
50
50
  onAllChunks: () => {
51
51
  renderer_1.RenderInternals.Log.info('All chunks have been downloaded now.');
52
52
  },
53
+ audioBitrate: renderMetadata.audioBitrate,
53
54
  });
54
55
  return { type: 'success', postRenderData };
55
56
  };
@@ -20,7 +20,6 @@ const io_1 = require("./helpers/io");
20
20
  const on_downloads_logger_1 = require("./helpers/on-downloads-logger");
21
21
  const write_lambda_error_1 = require("./helpers/write-lambda-error");
22
22
  const renderHandler = async (params, options, logs) => {
23
- var _a;
24
23
  if (params.type !== constants_1.LambdaRoutines.renderer) {
25
24
  throw new Error('Params must be renderer');
26
25
  }
@@ -41,7 +40,7 @@ const renderHandler = async (params, options, logs) => {
41
40
  serialized: params.resolvedProps,
42
41
  propsType: 'resolved-props',
43
42
  });
44
- const browserInstance = await (0, get_browser_instance_1.getBrowserInstance)(params.logLevel, false, (_a = params.chromiumOptions) !== null && _a !== void 0 ? _a : {});
43
+ const browserInstance = await (0, get_browser_instance_1.getBrowserInstance)(params.logLevel, false, params.chromiumOptions);
45
44
  const outputPath = renderer_1.RenderInternals.tmpDir('remotion-render-');
46
45
  if (typeof params.chunk !== 'number') {
47
46
  throw new Error('must pass chunk');
@@ -115,7 +114,7 @@ const renderHandler = async (params, options, logs) => {
115
114
  renderId: params.renderId,
116
115
  }).catch((err) => reject(err));
117
116
  },
118
- puppeteerInstance: browserInstance,
117
+ puppeteerInstance: browserInstance.instance,
119
118
  serveUrl: params.serveUrl,
120
119
  jpegQuality: (_a = params.jpegQuality) !== null && _a !== void 0 ? _a : renderer_1.RenderInternals.DEFAULT_JPEG_QUALITY,
121
120
  envVariables: (_b = params.envVariables) !== null && _b !== void 0 ? _b : {},
@@ -209,6 +208,8 @@ const renderHandler = async (params, options, logs) => {
209
208
  customCredentials: null,
210
209
  }),
211
210
  ]);
211
+ browserInstance.instance.forgetEventLoop();
212
+ renderer_1.RenderInternals.Log.verbose('Done!');
212
213
  return {};
213
214
  };
214
215
  const rendererHandler = async (params, options) => {
@@ -31,7 +31,7 @@ const on_downloads_logger_1 = require("./helpers/on-downloads-logger");
31
31
  const validate_composition_1 = require("./helpers/validate-composition");
32
32
  const write_lambda_error_1 = require("./helpers/write-lambda-error");
33
33
  const innerStillHandler = async ({ params: lambdaParams, expectedBucketOwner, renderId, }) => {
34
- var _a, _b, _c, _d, _e, _f;
34
+ var _a, _b, _c, _d, _e;
35
35
  if (lambdaParams.type !== constants_1.LambdaRoutines.still) {
36
36
  throw new TypeError('Expected still type');
37
37
  }
@@ -45,17 +45,16 @@ const innerStillHandler = async ({ params: lambdaParams, expectedBucketOwner, re
45
45
  (0, validate_privacy_1.validatePrivacy)(lambdaParams.privacy, true);
46
46
  (0, validate_outname_1.validateOutname)(lambdaParams.outName, null, null);
47
47
  const start = Date.now();
48
- const [bucketName, browserInstance] = await Promise.all([
49
- (_a = lambdaParams.bucketName) !== null && _a !== void 0 ? _a : (0, get_or_create_bucket_1.internalGetOrCreateBucket)({
50
- region: (0, get_current_region_1.getCurrentRegionInFunction)(),
51
- enableFolderExpiry: null,
52
- customCredentials: null,
53
- }).then((b) => b.bucketName),
54
- (0, get_browser_instance_1.getBrowserInstance)(lambdaParams.logLevel, false, (_b = lambdaParams.chromiumOptions) !== null && _b !== void 0 ? _b : {}),
55
- ]);
48
+ const browserInstancePromise = (0, get_browser_instance_1.getBrowserInstance)(lambdaParams.logLevel, false, lambdaParams.chromiumOptions);
49
+ const bucketNamePromise = (_a = lambdaParams.bucketName) !== null && _a !== void 0 ? _a : (0, get_or_create_bucket_1.internalGetOrCreateBucket)({
50
+ region: (0, get_current_region_1.getCurrentRegionInFunction)(),
51
+ enableFolderExpiry: null,
52
+ customCredentials: null,
53
+ }).then((b) => b.bucketName);
56
54
  const outputDir = renderer_1.RenderInternals.tmpDir('remotion-render-');
57
55
  const outputPath = node_path_1.default.join(outputDir, 'output');
58
56
  const region = (0, get_current_region_1.getCurrentRegionInFunction)();
57
+ const bucketName = await bucketNamePromise;
59
58
  const serializedInputPropsWithCustomSchema = await (0, compress_props_1.decompressInputProps)({
60
59
  bucketName,
61
60
  expectedBucketOwner,
@@ -77,12 +76,13 @@ const innerStillHandler = async ({ params: lambdaParams, expectedBucketOwner, re
77
76
  webpackConfigOrServeUrl: serveUrl,
78
77
  offthreadVideoCacheSizeInBytes: lambdaParams.offthreadVideoCacheSizeInBytes,
79
78
  });
79
+ const browserInstance = await browserInstancePromise;
80
80
  const composition = await (0, validate_composition_1.validateComposition)({
81
81
  serveUrl,
82
- browserInstance,
82
+ browserInstance: browserInstance.instance,
83
83
  composition: lambdaParams.composition,
84
84
  serializedInputPropsWithCustomSchema,
85
- envVariables: (_c = lambdaParams.envVariables) !== null && _c !== void 0 ? _c : {},
85
+ envVariables: (_b = lambdaParams.envVariables) !== null && _b !== void 0 ? _b : {},
86
86
  chromiumOptions: lambdaParams.chromiumOptions,
87
87
  timeoutInMilliseconds: lambdaParams.timeoutInMilliseconds,
88
88
  port: null,
@@ -109,7 +109,7 @@ const innerStillHandler = async ({ params: lambdaParams, expectedBucketOwner, re
109
109
  memorySizeInMb: Number(process.env.AWS_LAMBDA_FUNCTION_MEMORY_SIZE),
110
110
  region: (0, get_current_region_1.getCurrentRegionInFunction)(),
111
111
  renderId,
112
- outName: (_d = lambdaParams.outName) !== null && _d !== void 0 ? _d : undefined,
112
+ outName: (_c = lambdaParams.outName) !== null && _c !== void 0 ? _c : undefined,
113
113
  privacy: lambdaParams.privacy,
114
114
  everyNthFrame: 1,
115
115
  frameRange: [lambdaParams.frame, lambdaParams.frame],
@@ -117,6 +117,7 @@ const innerStillHandler = async ({ params: lambdaParams, expectedBucketOwner, re
117
117
  deleteAfter: lambdaParams.deleteAfter,
118
118
  numberOfGifLoops: null,
119
119
  downloadBehavior: lambdaParams.downloadBehavior,
120
+ audioBitrate: null,
120
121
  };
121
122
  await (0, io_1.lambdaWriteFile)({
122
123
  bucketName,
@@ -132,7 +133,7 @@ const innerStillHandler = async ({ params: lambdaParams, expectedBucketOwner, re
132
133
  composition,
133
134
  output: outputPath,
134
135
  serveUrl,
135
- envVariables: (_e = lambdaParams.envVariables) !== null && _e !== void 0 ? _e : {},
136
+ envVariables: (_d = lambdaParams.envVariables) !== null && _d !== void 0 ? _d : {},
136
137
  frame: renderer_1.RenderInternals.convertToPositiveFrameIndex({
137
138
  frame: lambdaParams.frame,
138
139
  durationInFrames: composition.durationInFrames,
@@ -140,8 +141,8 @@ const innerStillHandler = async ({ params: lambdaParams, expectedBucketOwner, re
140
141
  imageFormat: lambdaParams.imageFormat,
141
142
  serializedInputPropsWithCustomSchema,
142
143
  overwrite: false,
143
- puppeteerInstance: browserInstance,
144
- jpegQuality: (_f = lambdaParams.jpegQuality) !== null && _f !== void 0 ? _f : renderer_1.RenderInternals.DEFAULT_JPEG_QUALITY,
144
+ puppeteerInstance: browserInstance.instance,
145
+ jpegQuality: (_e = lambdaParams.jpegQuality) !== null && _e !== void 0 ? _e : renderer_1.RenderInternals.DEFAULT_JPEG_QUALITY,
145
146
  chromiumOptions: lambdaParams.chromiumOptions,
146
147
  scale: lambdaParams.scale,
147
148
  timeoutInMilliseconds: lambdaParams.timeoutInMilliseconds,
@@ -190,6 +191,7 @@ const innerStillHandler = async ({ params: lambdaParams, expectedBucketOwner, re
190
191
  // overestimate the price, but will only have a miniscule effect (~0.2%)
191
192
  diskSizeInMb: constants_1.MAX_EPHEMERAL_STORAGE_IN_MB,
192
193
  });
194
+ browserInstance.instance.forgetEventLoop();
193
195
  return {
194
196
  type: 'success',
195
197
  output: (0, get_output_url_from_metadata_1.getOutputUrlFromMetadata)(renderMetadata, bucketName, customCredentials),
@@ -5,6 +5,37 @@ const client_lambda_1 = require("@aws-sdk/client-lambda");
5
5
  const streaming_payloads_1 = require("../functions/helpers/streaming-payloads");
6
6
  const aws_clients_1 = require("./aws-clients");
7
7
  const INVALID_JSON_MESSAGE = 'Cannot parse Lambda response as JSON';
8
+ const parseJsonWithErrorSurfacing = (input) => {
9
+ try {
10
+ return JSON.parse(input);
11
+ }
12
+ catch (_a) {
13
+ throw new Error(`${INVALID_JSON_MESSAGE}. Response: ${input}`);
14
+ }
15
+ };
16
+ const parseJson = (input) => {
17
+ var _a;
18
+ let json = parseJsonWithErrorSurfacing(input);
19
+ if ('statusCode' in json) {
20
+ json = parseJsonWithErrorSurfacing(json.body);
21
+ }
22
+ if ('errorMessage' in json) {
23
+ const err = new Error(json.errorMessage);
24
+ err.name = json.errorType;
25
+ err.stack = ((_a = json.trace) !== null && _a !== void 0 ? _a : []).join('\n');
26
+ throw err;
27
+ }
28
+ // This will not happen, it is for narrowing purposes
29
+ if ('statusCode' in json) {
30
+ throw new Error(`Lambda function failed with status code ${json.statusCode}`);
31
+ }
32
+ if (json.type === 'error') {
33
+ const err = new Error(json.message);
34
+ err.stack = json.stack;
35
+ throw err;
36
+ }
37
+ return json;
38
+ };
8
39
  const callLambda = async (options) => {
9
40
  // As of August 2023, Lambda streaming sometimes misses parts of the JSON response.
10
41
  // Handling this for now by applying a retry mechanism.
@@ -61,34 +92,3 @@ const callLambdaWithoutRetry = async ({ functionName, type, payload, region, rec
61
92
  const json = parseJson(responsePayload.trim());
62
93
  return json;
63
94
  };
64
- const parseJsonWithErrorSurfacing = (input) => {
65
- try {
66
- return JSON.parse(input);
67
- }
68
- catch (_a) {
69
- throw new Error(`${INVALID_JSON_MESSAGE}. Response: ${input}`);
70
- }
71
- };
72
- const parseJson = (input) => {
73
- var _a;
74
- let json = parseJsonWithErrorSurfacing(input);
75
- if ('statusCode' in json) {
76
- json = parseJsonWithErrorSurfacing(json.body);
77
- }
78
- if ('errorMessage' in json) {
79
- const err = new Error(json.errorMessage);
80
- err.name = json.errorType;
81
- err.stack = ((_a = json.trace) !== null && _a !== void 0 ? _a : []).join('\n');
82
- throw err;
83
- }
84
- // This will not happen, it is for narrowing purposes
85
- if ('statusCode' in json) {
86
- throw new Error(`Lambda function failed with status code ${json.statusCode}`);
87
- }
88
- if (json.type === 'error') {
89
- const err = new Error(json.message);
90
- err.stack = json.stack;
91
- throw err;
92
- }
93
- return json;
94
- };
@@ -8,6 +8,12 @@ const random_hash_1 = require("./random-hash");
8
8
  const serialize_props_1 = require("./serialize-props");
9
9
  const stream_to_string_1 = require("./stream-to-string");
10
10
  const validate_webhook_1 = require("./validate-webhook");
11
+ const makeKey = (type, hash) => {
12
+ if (type === 'input-props') {
13
+ return (0, constants_1.inputPropsKey)(hash);
14
+ }
15
+ return (0, constants_1.resolvedPropsKey)(hash);
16
+ };
11
17
  const serializeOrThrow = (inputProps, propsType) => {
12
18
  try {
13
19
  const payload = (0, serialize_props_1.serializeJSONWithDate)({
@@ -82,9 +88,3 @@ const decompressInputProps = async ({ serialized, region, bucketName, expectedBu
82
88
  }
83
89
  };
84
90
  exports.decompressInputProps = decompressInputProps;
85
- const makeKey = (type, hash) => {
86
- if (type === 'input-props') {
87
- return (0, constants_1.inputPropsKey)(hash);
88
- }
89
- return (0, constants_1.resolvedPropsKey)(hash);
90
- };
@@ -329,6 +329,7 @@ export type RenderMetadata = Discriminated & {
329
329
  everyNthFrame: number;
330
330
  deleteAfter: DeleteAfter | null;
331
331
  numberOfGifLoops: number | null;
332
+ audioBitrate: string | null;
332
333
  downloadBehavior: DownloadBehavior;
333
334
  };
334
335
  export type AfterRenderCost = {
@@ -2,6 +2,9 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.getS3RenderUrl = exports.getCloudwatchRendererUrl = exports.getCloudwatchMethodUrl = void 0;
4
4
  const encode_aws_url_params_1 = require("./encode-aws-url-params");
5
+ const cloudWatchUrlWithQuery = ({ region, functionNameToUse, query, }) => {
6
+ return `https://${region}.console.aws.amazon.com/cloudwatch/home?region=${region}#logsV2:log-groups/log-group/$252Faws$252Flambda$252F${functionNameToUse}/log-events$3FfilterPattern$3D${(0, encode_aws_url_params_1.encodeAwsUrlParams)(query)}`;
7
+ };
5
8
  const getCloudwatchMethodUrl = ({ region, functionName, renderId, rendererFunctionName, method, }) => {
6
9
  const functionNameToUse = rendererFunctionName !== null && rendererFunctionName !== void 0 ? rendererFunctionName : functionName;
7
10
  const query = `"method=${method},renderId=${renderId}"`;
@@ -14,9 +17,6 @@ const getCloudwatchRendererUrl = ({ region, functionName, renderId, rendererFunc
14
17
  return cloudWatchUrlWithQuery({ region, functionNameToUse, query });
15
18
  };
16
19
  exports.getCloudwatchRendererUrl = getCloudwatchRendererUrl;
17
- const cloudWatchUrlWithQuery = ({ region, functionNameToUse, query, }) => {
18
- return `https://${region}.console.aws.amazon.com/cloudwatch/home?region=${region}#logsV2:log-groups/log-group/$252Faws$252Flambda$252F${functionNameToUse}/log-events$3FfilterPattern$3D${(0, encode_aws_url_params_1.encodeAwsUrlParams)(query)}`;
19
- };
20
20
  const getS3RenderUrl = ({ renderId, region, bucketName, }) => {
21
21
  return `https://s3.console.aws.amazon.com/s3/buckets/${bucketName}?region=${region}&prefix=renders/${renderId}/`;
22
22
  };
@@ -47,6 +47,10 @@ function calculateSignature(payload, secret) {
47
47
  return signature;
48
48
  }
49
49
  exports.calculateSignature = calculateSignature;
50
+ exports.mockableHttpClients = {
51
+ http: node_http_1.default.request,
52
+ https: https_1.default.request,
53
+ };
50
54
  const getWebhookClient = (url) => {
51
55
  if (url.startsWith('https://')) {
52
56
  return exports.mockableHttpClients.https;
@@ -56,10 +60,6 @@ const getWebhookClient = (url) => {
56
60
  }
57
61
  throw new Error('Can only request URLs starting with http:// or https://');
58
62
  };
59
- exports.mockableHttpClients = {
60
- http: node_http_1.default.request,
61
- https: https_1.default.request,
62
- };
63
63
  function invokeWebhookRaw({ payload, secret, url, }) {
64
64
  const jsonPayload = JSON.stringify(payload);
65
65
  return new Promise((resolve, reject) => {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@remotion/lambda",
3
- "version": "4.0.45",
3
+ "version": "4.0.47",
4
4
  "description": "Distributed renderer for Remotion based on AWS Lambda",
5
5
  "main": "dist/index.js",
6
6
  "sideEffects": false,
@@ -25,14 +25,14 @@
25
25
  "@aws-sdk/s3-request-presigner": "3.382.0",
26
26
  "aws-policies": "^1.0.1",
27
27
  "mime-types": "2.1.34",
28
- "zod": "3.21.4",
29
- "@remotion/cli": "4.0.45",
30
- "@remotion/bundler": "4.0.45",
31
- "@remotion/renderer": "4.0.45",
32
- "remotion": "4.0.45"
28
+ "zod": "3.22.3",
29
+ "@remotion/bundler": "4.0.47",
30
+ "@remotion/renderer": "4.0.47",
31
+ "@remotion/cli": "4.0.47",
32
+ "remotion": "4.0.47"
33
33
  },
34
34
  "devDependencies": {
35
- "@jonny/eslint-config": "3.0.266",
35
+ "@jonny/eslint-config": "3.0.276",
36
36
  "@types/mime-types": "2.1.1",
37
37
  "@types/minimist": "1.2.2",
38
38
  "@types/node": "18.14.6",
@@ -43,11 +43,11 @@
43
43
  "ts-node": "^10.8.0",
44
44
  "vitest": "0.31.1",
45
45
  "zip-lib": "^0.7.2",
46
- "@remotion/bundler": "4.0.45",
47
- "@remotion/compositor-linux-arm64-gnu": "4.0.45"
46
+ "@remotion/bundler": "4.0.47",
47
+ "@remotion/compositor-linux-arm64-gnu": "4.0.47"
48
48
  },
49
49
  "peerDependencies": {
50
- "@remotion/bundler": "4.0.45"
50
+ "@remotion/bundler": "4.0.47"
51
51
  },
52
52
  "publishConfig": {
53
53
  "access": "public"
Binary file