@remotion/lambda 3.3.6 → 3.3.8

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 (64) hide show
  1. package/dist/admin/generate-etag-list.d.ts +1 -0
  2. package/dist/admin/generate-etag-list.js +14 -0
  3. package/dist/admin/make-layer-public.js +23 -1
  4. package/dist/api/deploy-site.d.ts +5 -0
  5. package/dist/api/deploy-site.js +39 -16
  6. package/dist/api/get-aws-client.d.ts +2 -0
  7. package/dist/api/get-aws-client.js +2 -0
  8. package/dist/api/iam-validation/simulate-rule.js +0 -22
  9. package/dist/api/iam-validation/simulate.js +17 -5
  10. package/dist/api/iam-validation/user-permissions.js +0 -6
  11. package/dist/api/upload-dir.d.ts +4 -3
  12. package/dist/api/upload-dir.js +33 -19
  13. package/dist/cli/commands/render/progress.d.ts +6 -3
  14. package/dist/cli/commands/render/progress.js +49 -39
  15. package/dist/cli/commands/render/render.js +16 -1
  16. package/dist/cli/commands/sites/create.js +12 -2
  17. package/dist/cli/helpers/progress-bar.d.ts +8 -1
  18. package/dist/cli/helpers/progress-bar.js +17 -1
  19. package/dist/cli/index.js +6 -1
  20. package/dist/functions/helpers/concat-videos.d.ts +10 -6
  21. package/dist/functions/helpers/concat-videos.js +5 -21
  22. package/dist/functions/helpers/create-post-render-data.js +0 -12
  23. package/dist/functions/helpers/get-chromium-executable-path.js +2 -1
  24. package/dist/functions/helpers/get-chunk-progress.d.ts +0 -0
  25. package/dist/functions/helpers/get-chunk-progress.js +1 -0
  26. package/dist/functions/helpers/get-current-region.d.ts +1 -1
  27. package/dist/functions/helpers/get-encoding-metadata.d.ts +4 -8
  28. package/dist/functions/helpers/get-encoding-metadata.js +4 -18
  29. package/dist/functions/helpers/get-final-encoding-status.d.ts +2 -4
  30. package/dist/functions/helpers/get-final-encoding-status.js +1 -4
  31. package/dist/functions/helpers/get-lambdas-invoked-stats.d.ts +1 -5
  32. package/dist/functions/helpers/get-lambdas-invoked-stats.js +1 -9
  33. package/dist/functions/helpers/get-overall-progress.d.ts +2 -1
  34. package/dist/functions/helpers/get-overall-progress.js +7 -5
  35. package/dist/functions/helpers/get-progress.js +37 -25
  36. package/dist/functions/helpers/get-rendered-frames-progress.d.ts +8 -0
  37. package/dist/functions/helpers/get-rendered-frames-progress.js +37 -0
  38. package/dist/functions/launch.js +48 -37
  39. package/dist/functions/renderer.js +15 -22
  40. package/dist/functions/still.js +2 -0
  41. package/dist/pricing/aws-regions.d.ts +1 -1
  42. package/dist/pricing/aws-regions.js +11 -0
  43. package/dist/pricing/price-per-1-s.js +413 -39
  44. package/dist/shared/aws-clients.d.ts +3 -0
  45. package/dist/shared/aws-clients.js +9 -1
  46. package/dist/shared/chunk-progress.d.ts +9 -0
  47. package/dist/shared/chunk-progress.js +2034 -0
  48. package/dist/shared/constants.d.ts +4 -5
  49. package/dist/shared/get-account-id.js +4 -6
  50. package/dist/shared/get-chunk-progress.d.ts +0 -0
  51. package/dist/shared/get-chunk-progress.js +1 -0
  52. package/dist/shared/get-etag.d.ts +1 -0
  53. package/dist/shared/get-etag.js +24 -0
  54. package/dist/shared/get-s3-operations.d.ts +10 -0
  55. package/dist/shared/get-s3-operations.js +36 -0
  56. package/dist/shared/hosted-layers.js +368 -60
  57. package/dist/shared/parse-chunk-key.d.ts +4 -0
  58. package/dist/shared/parse-chunk-key.js +14 -0
  59. package/dist/shared/read-dir.d.ts +9 -0
  60. package/dist/shared/read-dir.js +57 -0
  61. package/package.json +7 -6
  62. package/remotionlambda.zip +0 -0
  63. package/dist/shared/get-cloudwatch-stream-url.d.ts +0 -8
  64. package/dist/shared/get-cloudwatch-stream-url.js +0 -7
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,14 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ const crypto_1 = __importDefault(require("crypto"));
7
+ const fs_1 = require("fs");
8
+ const md5 = (data) => crypto_1.default.createHash('md5').update(data).digest('hex');
9
+ const chunks = [];
10
+ for (let i = 0; i < 2000; i++) {
11
+ const etag = `"${md5(String(i))}"`;
12
+ chunks.push(etag);
13
+ }
14
+ (0, fs_1.writeFileSync)('etags.json', JSON.stringify(chunks));
@@ -20,6 +20,17 @@ const layerInfo = {
20
20
  'us-east-1': [],
21
21
  'us-east-2': [],
22
22
  'us-west-2': [],
23
+ 'af-south-1': [],
24
+ 'ap-east-1': [],
25
+ 'ap-northeast-2': [],
26
+ 'ap-northeast-3': [],
27
+ 'ca-central-1': [],
28
+ 'eu-north-1': [],
29
+ 'eu-south-1': [],
30
+ 'eu-west-3': [],
31
+ 'me-south-1': [],
32
+ 'sa-east-1': [],
33
+ 'us-west-1': [],
23
34
  },
24
35
  x86_64: {
25
36
  'ap-northeast-1': [],
@@ -32,6 +43,17 @@ const layerInfo = {
32
43
  'us-east-1': [],
33
44
  'us-east-2': [],
34
45
  'us-west-2': [],
46
+ 'af-south-1': [],
47
+ 'ap-east-1': [],
48
+ 'ap-northeast-2': [],
49
+ 'ap-northeast-3': [],
50
+ 'ca-central-1': [],
51
+ 'eu-north-1': [],
52
+ 'eu-south-1': [],
53
+ 'eu-west-3': [],
54
+ 'me-south-1': [],
55
+ 'sa-east-1': [],
56
+ 'us-west-1': [],
35
57
  },
36
58
  };
37
59
  const makeLayerPublic = async () => {
@@ -43,7 +65,7 @@ const makeLayerPublic = async () => {
43
65
  const { Version, LayerArn } = await (0, aws_clients_1.getLambdaClient)(region).send(new client_lambda_1.PublishLayerVersionCommand({
44
66
  Content: {
45
67
  S3Bucket: 'remotionlambda-binaries-' + region,
46
- S3Key: `remotion-layer-${layer}-v8-${architecture}.zip`,
68
+ S3Key: `remotion-layer-${layer}-v9-${architecture}.zip`,
47
69
  },
48
70
  LayerName: layerName,
49
71
  LicenseInfo: layer === 'chromium'
@@ -18,6 +18,11 @@ export declare type DeploySiteInput = {
18
18
  export declare type DeploySiteOutput = Promise<{
19
19
  serveUrl: string;
20
20
  siteName: string;
21
+ stats: {
22
+ uploadedFiles: number;
23
+ deletedFiles: number;
24
+ untouchedFiles: number;
25
+ };
21
26
  }>;
22
27
  /**
23
28
  * @description Deploys a Remotion project to an S3 bucket to prepare it for rendering on AWS Lambda.
@@ -1,10 +1,11 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.deploySite = void 0;
4
- const delete_site_1 = require("../api/delete-site");
4
+ const io_1 = require("../functions/helpers/io");
5
5
  const bundle_site_1 = require("../shared/bundle-site");
6
6
  const constants_1 = require("../shared/constants");
7
7
  const get_account_id_1 = require("../shared/get-account-id");
8
+ const get_s3_operations_1 = require("../shared/get-s3-operations");
8
9
  const make_s3_url_1 = require("../shared/make-s3-url");
9
10
  const random_hash_1 = require("../shared/random-hash");
10
11
  const validate_aws_region_1 = require("../shared/validate-aws-region");
@@ -28,37 +29,54 @@ const deploySite = async ({ bucketName, entryPoint, siteName, options, region, }
28
29
  (0, validate_bucketname_1.validateBucketName)(bucketName, { mustStartWithRemotion: true });
29
30
  const siteId = siteName !== null && siteName !== void 0 ? siteName : (0, random_hash_1.randomHash)();
30
31
  (0, validate_site_name_1.validateSiteName)(siteId);
32
+ const accountId = await (0, get_account_id_1.getAccountId)({ region });
31
33
  const bucketExists = await (0, bucket_exists_1.bucketExistsInRegion)({
32
34
  bucketName,
33
35
  region,
34
- expectedBucketOwner: await (0, get_account_id_1.getAccountId)({ region }),
36
+ expectedBucketOwner: accountId,
35
37
  });
36
38
  if (!bucketExists) {
37
39
  throw new Error(`No bucket with the name ${bucketName} exists`);
38
40
  }
39
41
  const subFolder = (0, constants_1.getSitesKey)(siteId);
40
- await (0, delete_site_1.deleteSite)({
41
- bucketName,
42
- onAfterItemDeleted: () => undefined,
43
- region,
44
- siteName: siteId,
45
- });
46
- const bundled = await (0, bundle_site_1.bundleSite)(entryPoint, (_a = options === null || options === void 0 ? void 0 : options.onBundleProgress) !== null && _a !== void 0 ? _a : (() => undefined), {
47
- publicPath: `/${subFolder}/`,
48
- webpackOverride: (_b = options === null || options === void 0 ? void 0 : options.webpackOverride) !== null && _b !== void 0 ? _b : ((f) => f),
49
- enableCaching: (_c = options === null || options === void 0 ? void 0 : options.enableCaching) !== null && _c !== void 0 ? _c : true,
50
- publicDir: options === null || options === void 0 ? void 0 : options.publicDir,
51
- rootDir: options === null || options === void 0 ? void 0 : options.rootDir,
42
+ const [files, bundled] = await Promise.all([
43
+ (0, io_1.lambdaLs)({
44
+ bucketName,
45
+ expectedBucketOwner: accountId,
46
+ region,
47
+ prefix: subFolder,
48
+ }),
49
+ (0, bundle_site_1.bundleSite)(entryPoint, (_a = options === null || options === void 0 ? void 0 : options.onBundleProgress) !== null && _a !== void 0 ? _a : (() => undefined), {
50
+ publicPath: `/${subFolder}/`,
51
+ webpackOverride: (_b = options === null || options === void 0 ? void 0 : options.webpackOverride) !== null && _b !== void 0 ? _b : ((f) => f),
52
+ enableCaching: (_c = options === null || options === void 0 ? void 0 : options.enableCaching) !== null && _c !== void 0 ? _c : true,
53
+ publicDir: options === null || options === void 0 ? void 0 : options.publicDir,
54
+ rootDir: options === null || options === void 0 ? void 0 : options.rootDir,
55
+ }),
56
+ ]);
57
+ const { toDelete, toUpload, existingCount } = await (0, get_s3_operations_1.getS3DiffOperations)({
58
+ objects: files,
59
+ bundle: bundled,
60
+ prefix: subFolder,
52
61
  });
53
62
  await Promise.all([
54
63
  (0, upload_dir_1.uploadDir)({
55
64
  bucket: bucketName,
56
65
  region,
57
- dir: bundled,
66
+ localDir: bundled,
58
67
  onProgress: (_d = options === null || options === void 0 ? void 0 : options.onUploadProgress) !== null && _d !== void 0 ? _d : (() => undefined),
59
- folder: subFolder,
68
+ keyPrefix: subFolder,
60
69
  privacy: 'public',
70
+ toUpload,
61
71
  }),
72
+ Promise.all(toDelete.map((d) => {
73
+ return (0, io_1.lambdaDeleteFile)({
74
+ bucketName,
75
+ customCredentials: null,
76
+ key: d.Key,
77
+ region,
78
+ });
79
+ })),
62
80
  (0, enable_s3_website_1.enableS3Website)({
63
81
  region,
64
82
  bucketName,
@@ -67,6 +85,11 @@ const deploySite = async ({ bucketName, entryPoint, siteName, options, region, }
67
85
  return {
68
86
  serveUrl: (0, make_s3_url_1.makeS3ServeUrl)({ bucketName, subFolder, region }),
69
87
  siteName: siteId,
88
+ stats: {
89
+ uploadedFiles: toUpload.length,
90
+ deletedFiles: toDelete.length,
91
+ untouchedFiles: existingCount,
92
+ },
70
93
  };
71
94
  };
72
95
  exports.deploySite = deploySite;
@@ -3,6 +3,7 @@ import * as IamSdk from '@aws-sdk/client-iam';
3
3
  import * as LambdaSDK from '@aws-sdk/client-lambda';
4
4
  import * as S3SDK from '@aws-sdk/client-s3';
5
5
  import * as ServiceQuotasSDK from '@aws-sdk/client-service-quotas';
6
+ import * as StsSdk from '@aws-sdk/client-sts';
6
7
  import type { AwsRegion } from '../client';
7
8
  import type { CustomCredentials, ServiceMapping } from '../shared/aws-clients';
8
9
  export declare type GetAwsClientInput<T extends keyof ServiceMapping> = {
@@ -16,6 +17,7 @@ declare type SdkMapping = {
16
17
  iam: typeof IamSdk;
17
18
  lambda: typeof LambdaSDK;
18
19
  servicequotas: typeof ServiceQuotasSDK;
20
+ sts: typeof StsSdk;
19
21
  };
20
22
  export declare type GetAwsClientOutput<T extends keyof ServiceMapping> = {
21
23
  client: ServiceMapping[T];
@@ -29,6 +29,7 @@ const IamSdk = __importStar(require("@aws-sdk/client-iam"));
29
29
  const LambdaSDK = __importStar(require("@aws-sdk/client-lambda"));
30
30
  const S3SDK = __importStar(require("@aws-sdk/client-s3"));
31
31
  const ServiceQuotasSDK = __importStar(require("@aws-sdk/client-service-quotas"));
32
+ const StsSdk = __importStar(require("@aws-sdk/client-sts"));
32
33
  const aws_clients_1 = require("../shared/aws-clients");
33
34
  /**
34
35
  * @description Gets the full AWS SDK and an instantiated client for an AWS service
@@ -51,6 +52,7 @@ const getAwsClient = ({ region, service, customCredentials, }) => {
51
52
  iam: IamSdk,
52
53
  s3: S3SDK,
53
54
  servicequotas: ServiceQuotasSDK,
55
+ sts: StsSdk,
54
56
  }[service],
55
57
  };
56
58
  };
@@ -2,32 +2,10 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.simulateRule = void 0;
4
4
  const client_iam_1 = require("@aws-sdk/client-iam");
5
- const aws_policies_1 = require("aws-policies");
6
5
  const aws_clients_1 = require("../../shared/aws-clients");
7
6
  const simulateRule = async (options) => {
8
7
  var _a;
9
8
  try {
10
- if (options.actionNames.includes(aws_policies_1.iam.GetUser)) {
11
- try {
12
- await (0, aws_clients_1.getIamClient)(options.region).send(new client_iam_1.GetUserCommand({}));
13
- const result = [
14
- {
15
- decision: 'allowed',
16
- name: aws_policies_1.iam.GetUser,
17
- },
18
- ];
19
- return result;
20
- }
21
- catch (err) {
22
- const result = [
23
- {
24
- decision: 'explicitDeny',
25
- name: aws_policies_1.iam.GetUser,
26
- },
27
- ];
28
- return result;
29
- }
30
- }
31
9
  const res = await (0, aws_clients_1.getIamClient)(options.region).send(new client_iam_1.SimulatePrincipalPolicyCommand({
32
10
  ActionNames: options.actionNames,
33
11
  PolicySourceArn: options.arn,
@@ -1,7 +1,7 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.simulatePermissions = exports.logPermissionOutput = void 0;
4
- const client_iam_1 = require("@aws-sdk/client-iam");
4
+ const client_sts_1 = require("@aws-sdk/client-sts");
5
5
  const aws_clients_1 = require("../../shared/aws-clients");
6
6
  const simulate_rule_1 = require("./simulate-rule");
7
7
  const user_permissions_1 = require("./user-permissions");
@@ -26,15 +26,27 @@ exports.logPermissionOutput = logPermissionOutput;
26
26
  */
27
27
  const simulatePermissions = async (options) => {
28
28
  var _a;
29
- const user = await (0, aws_clients_1.getIamClient)(options.region).send(new client_iam_1.GetUserCommand({}));
30
- if (!user || !user.User) {
31
- throw new Error('No valid AWS user detected');
29
+ const callerIdentity = await (0, aws_clients_1.getStsClient)(options.region).send(new client_sts_1.GetCallerIdentityCommand({}));
30
+ if (!callerIdentity || !callerIdentity.Arn) {
31
+ throw new Error('No valid AWS Caller Identity detected');
32
+ }
33
+ const callerIdentityArnComponents = callerIdentity.Arn.match(/arn:aws:([^:]+)::(\d+):([^/]+)(.*)/);
34
+ if (!callerIdentityArnComponents) {
35
+ throw new Error('Unknown AWS Caller Identity ARN detected');
36
+ }
37
+ const callerIdentityArnType = callerIdentityArnComponents[1];
38
+ let callerArn;
39
+ if (callerIdentityArnType === 'iam' && callerIdentityArnComponents[3] === 'user') {
40
+ callerArn = callerIdentity.Arn;
41
+ }
42
+ else {
43
+ throw new Error('Unsupported AWS Caller Identity ARN detected');
32
44
  }
33
45
  const results = [];
34
46
  for (const per of user_permissions_1.requiredPermissions) {
35
47
  const result = await (0, simulate_rule_1.simulateRule)({
36
48
  actionNames: per.actions,
37
- arn: user.User.Arn,
49
+ arn: callerArn,
38
50
  region: options.region,
39
51
  resource: per.resource,
40
52
  retries: 2,
@@ -15,12 +15,6 @@ exports.requiredPermissions = [
15
15
  ],
16
16
  resource: ['*'],
17
17
  },
18
- {
19
- id: 'Identity',
20
- actions: [aws_policies_1.iam.GetUser],
21
- // eslint-disable-next-line no-template-curly-in-string
22
- resource: ['arn:aws:iam::*:user/${aws:username}'],
23
- },
24
18
  {
25
19
  id: 'PermissionValidation',
26
20
  actions: [aws_policies_1.iam.SimulatePrincipalPolicy],
@@ -11,11 +11,12 @@ export declare type MockFile = {
11
11
  content: string;
12
12
  };
13
13
  export declare const getDirFiles: (entry: string) => MockFile[];
14
- export declare const uploadDir: ({ bucket, region, dir, onProgress, folder, privacy, }: {
14
+ export declare const uploadDir: ({ bucket, region, localDir, onProgress, keyPrefix, privacy, toUpload, }: {
15
15
  bucket: string;
16
16
  region: AwsRegion;
17
- dir: string;
18
- folder: string;
17
+ localDir: string;
18
+ keyPrefix: string;
19
19
  onProgress: (progress: UploadDirProgress) => void;
20
20
  privacy: Privacy;
21
+ toUpload: string[];
21
22
  }) => Promise<void>;
@@ -15,31 +15,45 @@ const getDirFiles = (entry) => {
15
15
  throw new TypeError('should only be executed in test ' + JSON.stringify(entry));
16
16
  };
17
17
  exports.getDirFiles = getDirFiles;
18
- const uploadDir = async ({ bucket, region, dir, onProgress, folder, privacy, }) => {
19
- async function getFiles(directory) {
20
- const dirents = await fs_1.promises.readdir(directory, { withFileTypes: true });
21
- const _files = await Promise.all(dirents.map(async (dirent) => {
22
- const res = path_1.default.resolve(directory, dirent.name);
23
- const { size } = await fs_1.promises.stat(res);
24
- return dirent.isDirectory()
25
- ? getFiles(res)
26
- : [
27
- {
28
- name: res,
29
- size,
30
- },
31
- ];
32
- }));
33
- return _files.flat(1);
34
- }
35
- const files = await getFiles(dir);
18
+ async function getFiles(directory, originalDirectory, toUpload) {
19
+ const dirents = await fs_1.promises.readdir(directory, { withFileTypes: true });
20
+ const _files = await Promise.all(dirents
21
+ .map((dirent) => {
22
+ const res = path_1.default.resolve(directory, dirent.name);
23
+ return [dirent, res];
24
+ })
25
+ .filter(([dirent, res]) => {
26
+ const relative = path_1.default.relative(originalDirectory, res);
27
+ if (dirent.isDirectory()) {
28
+ return true;
29
+ }
30
+ if (!toUpload.includes(relative)) {
31
+ return false;
32
+ }
33
+ return true;
34
+ })
35
+ .map(async ([dirent, res]) => {
36
+ const { size } = await fs_1.promises.stat(res);
37
+ return dirent.isDirectory()
38
+ ? getFiles(res, originalDirectory, toUpload)
39
+ : [
40
+ {
41
+ name: res,
42
+ size,
43
+ },
44
+ ];
45
+ }));
46
+ return _files.flat(1);
47
+ }
48
+ const uploadDir = async ({ bucket, region, localDir, onProgress, keyPrefix, privacy, toUpload, }) => {
49
+ const files = await getFiles(localDir, localDir, toUpload);
36
50
  const progresses = {};
37
51
  for (const file of files) {
38
52
  progresses[file.name] = 0;
39
53
  }
40
54
  const client = (0, aws_clients_1.getS3Client)(region, null);
41
55
  const uploads = files.map(async (filePath) => {
42
- const Key = (0, make_s3_key_1.makeS3Key)(folder, dir, filePath.name);
56
+ const Key = (0, make_s3_key_1.makeS3Key)(keyPrefix, localDir, filePath.name);
43
57
  const Body = (0, fs_1.createReadStream)(filePath.name);
44
58
  const ContentType = mime_types_1.default.lookup(Key) || 'application/octet-stream';
45
59
  const ACL = privacy === 'no-acl'
@@ -3,12 +3,13 @@ import type { ChunkRetry } from '../../../functions/helpers/get-retry-stats';
3
3
  declare type LambdaInvokeProgress = {
4
4
  totalLambdas: number | null;
5
5
  lambdasInvoked: number;
6
- doneIn: number | null;
7
6
  };
8
7
  declare type ChunkProgress = {
8
+ doneIn: number | null;
9
+ framesRendered: number;
10
+ totalFrames: number | null;
9
11
  totalChunks: number | null;
10
12
  chunksInvoked: number;
11
- doneIn: number | null;
12
13
  };
13
14
  declare type MultiRenderProgress = {
14
15
  lambdaInvokeProgress: LambdaInvokeProgress;
@@ -22,11 +23,13 @@ declare type DownloadedInfo = {
22
23
  downloaded: number;
23
24
  doneIn: number | null;
24
25
  };
25
- export declare const makeProgressString: ({ progress, steps, downloadInfo, retriesInfo, verbose, }: {
26
+ export declare const makeProgressString: ({ progress, steps, downloadInfo, retriesInfo, verbose, timeToEncode, totalFrames, }: {
26
27
  progress: MultiRenderProgress;
27
28
  steps: number;
28
29
  downloadInfo: DownloadedInfo | null;
29
30
  retriesInfo: ChunkRetry[];
30
31
  verbose: boolean;
32
+ timeToEncode: number | null;
33
+ totalFrames: number | null;
31
34
  }) => string;
32
35
  export {};
@@ -2,45 +2,54 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.makeProgressString = exports.makeMultiProgressFromStatus = void 0;
4
4
  const cli_1 = require("@remotion/cli");
5
+ const renderer_1 = require("@remotion/renderer");
5
6
  const remotion_1 = require("remotion");
7
+ const truthy_1 = require("../../../shared/truthy");
6
8
  const makeInvokeProgress = (invokeProgress, totalSteps, retriesInfo) => {
7
- const { lambdasInvoked, totalLambdas, doneIn } = invokeProgress;
8
- const progress = doneIn
9
- ? 1
10
- : totalLambdas === null
11
- ? 0
12
- : lambdasInvoked / totalLambdas;
9
+ const { lambdasInvoked, totalLambdas } = invokeProgress;
10
+ const progress = totalLambdas === null ? 0 : lambdasInvoked / totalLambdas;
13
11
  return [
14
12
  '⚡️',
15
13
  `(1/${totalSteps})`,
16
14
  cli_1.CliInternals.makeProgressBar(progress),
17
- `${doneIn === null ? 'Invoking' : 'Invoked'} lambdas`,
18
- doneIn === null
19
- ? `${Math.round(progress * 100)}%`
20
- : cli_1.CliInternals.chalk.gray(`${doneIn}ms`),
15
+ `${progress === 0 ? 'Invoked' : 'Invoking'} lambdas`,
16
+ progress === 1
17
+ ? cli_1.CliInternals.chalk.gray('100%')
18
+ : `${Math.round(progress * 100)}%`,
21
19
  retriesInfo.length > 0 ? `(+${retriesInfo.length} retries)` : [],
22
20
  ].join(' ');
23
21
  };
24
- const makeChunkProgress = ({ chunkProgress, invokeProgress, totalSteps, }) => {
25
- const lambdaIsDone = invokeProgress.doneIn !== null;
22
+ const makeRenderProgress = ({ chunkProgress, totalSteps, }) => {
26
23
  const { chunksInvoked, totalChunks, doneIn } = chunkProgress;
27
- const progress = totalChunks === null ? 0 : chunksInvoked / totalChunks;
28
- const shouldShow = lambdaIsDone || progress > 0;
29
- if (!shouldShow) {
30
- return '';
31
- }
32
- return [
24
+ const renderProgress = chunkProgress.totalFrames === null
25
+ ? 0
26
+ : chunkProgress.framesRendered / chunkProgress.totalFrames;
27
+ const encodingProgress = totalChunks === null ? 0 : chunksInvoked / totalChunks;
28
+ const frames = chunkProgress.totalFrames === null
29
+ ? null
30
+ : `(${chunkProgress.framesRendered}/${chunkProgress.totalFrames})`;
31
+ const first = [
33
32
  '🧩',
34
33
  `(2/${totalSteps})`,
35
- cli_1.CliInternals.makeProgressBar(progress),
36
- `${doneIn === null ? 'Rendering' : 'Rendered'} chunks`,
34
+ cli_1.CliInternals.makeProgressBar(renderProgress),
35
+ doneIn === null ? 'Rendering frames' : 'Rendered frames',
36
+ doneIn === null ? frames : cli_1.CliInternals.chalk.gray(`${doneIn}ms`),
37
+ ]
38
+ .filter(truthy_1.truthy)
39
+ .join(' ');
40
+ const second = [
41
+ '🏗️ ',
42
+ `(3/${totalSteps})`,
43
+ cli_1.CliInternals.makeProgressBar(encodingProgress),
44
+ `${doneIn === null ? 'Encoding' : 'Encoded'} chunks`,
37
45
  doneIn === null
38
- ? `${Math.round(progress * 100)}%`
46
+ ? `${Math.round(encodingProgress * 100)}%`
39
47
  : cli_1.CliInternals.chalk.gray(`${doneIn}ms`),
40
48
  ].join(' ');
49
+ return [first, second];
41
50
  };
42
- const makeEncodingProgress = ({ encodingProgress, chunkProgress, totalSteps, }) => {
43
- const { framesEncoded, totalFrames, doneIn } = encodingProgress;
51
+ const makeEncodingProgress = ({ encodingProgress, chunkProgress, totalSteps, totalFrames, timeToEncode, }) => {
52
+ const { framesEncoded } = encodingProgress;
44
53
  const progress = totalFrames === null ? 0 : framesEncoded / totalFrames;
45
54
  const chunksDone = chunkProgress.doneIn !== null;
46
55
  const shouldShow = progress > 0 || chunksDone;
@@ -49,12 +58,12 @@ const makeEncodingProgress = ({ encodingProgress, chunkProgress, totalSteps, })
49
58
  }
50
59
  return [
51
60
  '📽 ',
52
- `(3/${totalSteps})`,
61
+ `(4/${totalSteps})`,
53
62
  cli_1.CliInternals.makeProgressBar(progress),
54
- `${doneIn === null ? 'Combining' : 'Combined'} videos`,
55
- doneIn === null
63
+ `${timeToEncode === null ? 'Combining' : 'Combined'} videos`,
64
+ timeToEncode === null
56
65
  ? `${Math.round(progress * 100)}%`
57
- : cli_1.CliInternals.chalk.gray(`${doneIn}ms`),
66
+ : cli_1.CliInternals.chalk.gray(`${timeToEncode}ms`),
58
67
  ].join(' ');
59
68
  };
60
69
  const makeCleanupProgress = (cleanupInfo, totalSteps, skipped) => {
@@ -64,7 +73,7 @@ const makeCleanupProgress = (cleanupInfo, totalSteps, skipped) => {
64
73
  if (skipped) {
65
74
  return [
66
75
  '🪣 ',
67
- `(4/${totalSteps})`,
76
+ `(5/${totalSteps})`,
68
77
  cli_1.CliInternals.chalk.blueBright(`Not cleaning up because --log=verbose was set`),
69
78
  ].join(' ');
70
79
  }
@@ -72,7 +81,7 @@ const makeCleanupProgress = (cleanupInfo, totalSteps, skipped) => {
72
81
  const progress = filesDeleted / minFilesToDelete;
73
82
  return [
74
83
  '🪣 ',
75
- `(4/${totalSteps})`,
84
+ `(5/${totalSteps})`,
76
85
  cli_1.CliInternals.makeProgressBar(progress),
77
86
  `${doneIn === null ? 'Cleaning up' : 'Cleaned up'} artifacts`,
78
87
  doneIn === null
@@ -83,7 +92,7 @@ const makeCleanupProgress = (cleanupInfo, totalSteps, skipped) => {
83
92
  const makeDownloadProgress = (downloadInfo, totalSteps) => {
84
93
  return [
85
94
  '💾',
86
- `(5/${totalSteps})`,
95
+ `(6/${totalSteps})`,
87
96
  downloadInfo.totalSize === null
88
97
  ? cli_1.CliInternals.getFileSizeDownloadBar(downloadInfo.downloaded)
89
98
  : cli_1.CliInternals.makeProgressBar(downloadInfo.downloaded / downloadInfo.totalSize),
@@ -101,40 +110,41 @@ const makeDownloadProgress = (downloadInfo, totalSteps) => {
101
110
  ].join(' ');
102
111
  };
103
112
  const makeMultiProgressFromStatus = (status) => {
104
- var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m;
113
+ var _a, _b, _c, _d, _e, _f;
105
114
  return {
106
115
  chunkProgress: {
107
116
  chunksInvoked: status.chunks,
108
117
  totalChunks: (_b = (_a = status.renderMetadata) === null || _a === void 0 ? void 0 : _a.totalChunks) !== null && _b !== void 0 ? _b : null,
109
118
  doneIn: status.timeToFinishChunks,
119
+ framesRendered: status.framesRendered,
120
+ totalFrames: status.renderMetadata
121
+ ? renderer_1.RenderInternals.getFramesToRender(status.renderMetadata.frameRange, status.renderMetadata.everyNthFrame).length
122
+ : null,
110
123
  },
111
124
  encodingProgress: {
112
125
  framesEncoded: (_d = (_c = status.encodingStatus) === null || _c === void 0 ? void 0 : _c.framesEncoded) !== null && _d !== void 0 ? _d : 0,
113
- totalFrames: (_f = (_e = status.renderMetadata) === null || _e === void 0 ? void 0 : _e.videoConfig.durationInFrames) !== null && _f !== void 0 ? _f : 1,
114
- doneIn: (_h = (_g = status.encodingStatus) === null || _g === void 0 ? void 0 : _g.doneIn) !== null && _h !== void 0 ? _h : null,
115
- timeToInvoke: (_k = (_j = status.encodingStatus) === null || _j === void 0 ? void 0 : _j.timeToInvoke) !== null && _k !== void 0 ? _k : null,
116
126
  },
117
127
  lambdaInvokeProgress: {
118
- doneIn: status.timeToInvokeLambdas,
119
128
  lambdasInvoked: status.lambdasInvoked,
120
- totalLambdas: (_m = (_l = status.renderMetadata) === null || _l === void 0 ? void 0 : _l.estimatedRenderLambdaInvokations) !== null && _m !== void 0 ? _m : null,
129
+ totalLambdas: (_f = (_e = status.renderMetadata) === null || _e === void 0 ? void 0 : _e.estimatedRenderLambdaInvokations) !== null && _f !== void 0 ? _f : null,
121
130
  },
122
131
  cleanupInfo: status.cleanup,
123
132
  };
124
133
  };
125
134
  exports.makeMultiProgressFromStatus = makeMultiProgressFromStatus;
126
- const makeProgressString = ({ progress, steps, downloadInfo, retriesInfo, verbose, }) => {
135
+ const makeProgressString = ({ progress, steps, downloadInfo, retriesInfo, verbose, timeToEncode, totalFrames, }) => {
127
136
  return [
128
137
  makeInvokeProgress(progress.lambdaInvokeProgress, steps, retriesInfo),
129
- makeChunkProgress({
138
+ ...makeRenderProgress({
130
139
  chunkProgress: progress.chunkProgress,
131
- invokeProgress: progress.lambdaInvokeProgress,
132
140
  totalSteps: steps,
133
141
  }),
134
142
  makeEncodingProgress({
135
143
  encodingProgress: progress.encodingProgress,
136
144
  chunkProgress: progress.chunkProgress,
137
145
  totalSteps: steps,
146
+ timeToEncode,
147
+ totalFrames,
138
148
  }),
139
149
  makeCleanupProgress(progress.cleanupInfo, steps, verbose),
140
150
  downloadInfo ? makeDownloadProgress(downloadInfo, steps) : null,
@@ -97,7 +97,7 @@ const renderCommand = async (args, remotionRoot) => {
97
97
  }
98
98
  : undefined,
99
99
  });
100
- const totalSteps = downloadName ? 5 : 4;
100
+ const totalSteps = downloadName ? 6 : 5;
101
101
  const progressBar = cli_1.CliInternals.createOverwriteableCliOutput(cli_1.CliInternals.quietFlagProvided());
102
102
  log_1.Log.info(cli_1.CliInternals.chalk.gray(`bucket = ${res.bucketName}, function = ${functionName}`));
103
103
  log_1.Log.info(cli_1.CliInternals.chalk.gray(`renderId = ${res.renderId}, codec = ${codec} (${reason})`));
@@ -117,6 +117,8 @@ const renderCommand = async (args, remotionRoot) => {
117
117
  downloadInfo: null,
118
118
  retriesInfo: status.retriesInfo,
119
119
  verbose,
120
+ totalFrames: getTotalFrames(status),
121
+ timeToEncode: status.timeToEncode,
120
122
  }));
121
123
  // eslint-disable-next-line no-constant-condition
122
124
  while (true) {
@@ -134,6 +136,8 @@ const renderCommand = async (args, remotionRoot) => {
134
136
  retriesInfo: newStatus.retriesInfo,
135
137
  downloadInfo: null,
136
138
  verbose,
139
+ timeToEncode: newStatus.timeToEncode,
140
+ totalFrames: getTotalFrames(newStatus),
137
141
  }));
138
142
  if (newStatus.done) {
139
143
  progressBar.update((0, progress_1.makeProgressString)({
@@ -142,6 +146,8 @@ const renderCommand = async (args, remotionRoot) => {
142
146
  downloadInfo: null,
143
147
  retriesInfo: newStatus.retriesInfo,
144
148
  verbose,
149
+ timeToEncode: newStatus.timeToEncode,
150
+ totalFrames: getTotalFrames(newStatus),
145
151
  }));
146
152
  if (downloadName) {
147
153
  const downloadStart = Date.now();
@@ -161,6 +167,8 @@ const renderCommand = async (args, remotionRoot) => {
161
167
  totalSize,
162
168
  },
163
169
  verbose,
170
+ timeToEncode: newStatus.timeToEncode,
171
+ totalFrames: getTotalFrames(newStatus),
164
172
  }));
165
173
  },
166
174
  });
@@ -174,6 +182,8 @@ const renderCommand = async (args, remotionRoot) => {
174
182
  totalSize: sizeInBytes,
175
183
  },
176
184
  verbose,
185
+ timeToEncode: newStatus.timeToEncode,
186
+ totalFrames: getTotalFrames(newStatus),
177
187
  }));
178
188
  log_1.Log.info();
179
189
  log_1.Log.info();
@@ -226,3 +236,8 @@ const renderCommand = async (args, remotionRoot) => {
226
236
  }
227
237
  };
228
238
  exports.renderCommand = renderCommand;
239
+ function getTotalFrames(status) {
240
+ return status.renderMetadata
241
+ ? renderer_1.RenderInternals.getFramesToRender(status.renderMetadata.frameRange, status.renderMetadata.everyNthFrame).length
242
+ : null;
243
+ }