@remotion/serverless-client 4.0.470 → 4.0.472

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.
@@ -1,4 +1,121 @@
1
1
  // ../core/dist/esm/no-react.mjs
2
+ var normalizeNumber = (value) => {
3
+ return Math.round(value * 1e6) / 1e6;
4
+ };
5
+ var angleUnits = new Set(["deg", "rad", "grad", "turn"]);
6
+ var lengthUnits = new Set([
7
+ "%",
8
+ "cap",
9
+ "ch",
10
+ "cm",
11
+ "cqb",
12
+ "cqh",
13
+ "cqi",
14
+ "cqmax",
15
+ "cqmin",
16
+ "cqw",
17
+ "dvh",
18
+ "dvw",
19
+ "em",
20
+ "ex",
21
+ "ic",
22
+ "in",
23
+ "lh",
24
+ "lvh",
25
+ "lvw",
26
+ "mm",
27
+ "pc",
28
+ "pt",
29
+ "px",
30
+ "q",
31
+ "rem",
32
+ "rlh",
33
+ "svh",
34
+ "svw",
35
+ "vb",
36
+ "vh",
37
+ "vi",
38
+ "vmax",
39
+ "vmin",
40
+ "vw"
41
+ ]);
42
+ var cssNumberRegex = /^([+-]?(?:\d+\.?\d*|\.\d+))([a-zA-Z%]+)?$/;
43
+ var stringifyNumber = (value) => {
44
+ return String(normalizeNumber(value));
45
+ };
46
+ var parseStringInterpolationComponent = (component, value) => {
47
+ const match = cssNumberRegex.exec(component);
48
+ if (match === null) {
49
+ throw new TypeError(`Cannot interpolate "${value}" because "${component}" is not a supported scale, translate, or rotate value`);
50
+ }
51
+ const unit = match[2] ?? null;
52
+ const numberValue = Number(match[1]);
53
+ if (!Number.isFinite(numberValue)) {
54
+ throw new TypeError(`Cannot interpolate "${value}" because "${component}" is not finite`);
55
+ }
56
+ if (unit === null) {
57
+ return { kind: "scale", value: numberValue, unit: null };
58
+ }
59
+ if (angleUnits.has(unit)) {
60
+ return { kind: "rotate", value: numberValue, unit };
61
+ }
62
+ if (lengthUnits.has(unit)) {
63
+ return { kind: "translate", value: numberValue, unit };
64
+ }
65
+ throw new TypeError(`Cannot interpolate "${value}" because "${unit}" is not a supported translate or rotate unit`);
66
+ };
67
+ var parseStringInterpolationValue = (output) => {
68
+ if (typeof output === "number") {
69
+ if (!Number.isFinite(output)) {
70
+ throw new Error(`outputRange must contain only finite numbers, but got [${output}]`);
71
+ }
72
+ return {
73
+ kind: "scale",
74
+ values: [output, output, 1],
75
+ units: [null, null, null],
76
+ dimensions: 1
77
+ };
78
+ }
79
+ const parts = output.trim().split(/\s+/);
80
+ if (parts.length < 1 || parts.length > 3 || parts[0] === "") {
81
+ throw new TypeError(`String outputRange values must contain 1 to 3 components, but got "${output}"`);
82
+ }
83
+ const parsed = parts.map((part) => parseStringInterpolationComponent(part, output));
84
+ const [{ kind }] = parsed;
85
+ for (const part of parsed) {
86
+ if (part.kind !== kind) {
87
+ throw new TypeError(`Cannot interpolate "${output}" because it mixes ${kind} and ${part.kind} values`);
88
+ }
89
+ }
90
+ if (kind === "scale") {
91
+ const x = parsed[0].value;
92
+ const y = parsed[1]?.value ?? x;
93
+ const z = parsed[2]?.value ?? 1;
94
+ return {
95
+ kind,
96
+ values: [x, y, z],
97
+ units: [null, null, null],
98
+ dimensions: parsed.length
99
+ };
100
+ }
101
+ return {
102
+ kind,
103
+ values: [parsed[0].value, parsed[1]?.value ?? 0, parsed[2]?.value ?? 0],
104
+ units: [parsed[0].unit, parsed[1]?.unit ?? null, parsed[2]?.unit ?? null],
105
+ dimensions: parsed.length
106
+ };
107
+ };
108
+ var serializeStringInterpolationValue = ({
109
+ kind,
110
+ values,
111
+ units,
112
+ dimensions
113
+ }) => {
114
+ if (kind === "scale") {
115
+ return values.slice(0, dimensions).map((value) => stringifyNumber(value)).join(" ");
116
+ }
117
+ return values.slice(0, dimensions).map((value, index) => `${stringifyNumber(value)}${units[index]}`).join(" ");
118
+ };
2
119
  function interpolateFunction(input, inputRange, outputRange, options) {
3
120
  const { extrapolateLeft, extrapolateRight, easing } = options;
4
121
  let result = input;
@@ -43,6 +160,96 @@ function findRange(input, inputRange) {
43
160
  }
44
161
  return i - 1;
45
162
  }
163
+ var defaultEasing = (num) => num;
164
+ var interpolateNumber = ({
165
+ input,
166
+ inputRange,
167
+ outputRange,
168
+ options
169
+ }) => {
170
+ if (inputRange.length === 1) {
171
+ return outputRange[0];
172
+ }
173
+ const easingOption = options?.easing;
174
+ const resolveEasingForSegment = (segmentIndex) => {
175
+ if (easingOption === undefined) {
176
+ return defaultEasing;
177
+ }
178
+ if (typeof easingOption === "function") {
179
+ return easingOption;
180
+ }
181
+ return easingOption[segmentIndex];
182
+ };
183
+ let extrapolateLeft = "extend";
184
+ if (options?.extrapolateLeft !== undefined) {
185
+ extrapolateLeft = options.extrapolateLeft;
186
+ }
187
+ let extrapolateRight = "extend";
188
+ if (options?.extrapolateRight !== undefined) {
189
+ extrapolateRight = options.extrapolateRight;
190
+ }
191
+ const posterizedInput = options?.posterize === undefined ? input : Math.floor(input / options.posterize) * options.posterize;
192
+ const range = findRange(posterizedInput, inputRange);
193
+ return interpolateFunction(posterizedInput, [inputRange[range], inputRange[range + 1]], [outputRange[range], outputRange[range + 1]], {
194
+ easing: resolveEasingForSegment(range),
195
+ extrapolateLeft,
196
+ extrapolateRight
197
+ });
198
+ };
199
+ var interpolateString = ({
200
+ input,
201
+ inputRange,
202
+ outputRange,
203
+ options
204
+ }) => {
205
+ const parsedOutputRange = outputRange.map(parseStringInterpolationValue);
206
+ const kind = parsedOutputRange[0]?.kind;
207
+ if (kind === undefined) {
208
+ throw new Error("outputRange must have at least 1 element");
209
+ }
210
+ for (const parsed of parsedOutputRange) {
211
+ if (parsed.kind !== kind) {
212
+ throw new TypeError(`Cannot interpolate ${kind} values with ${parsed.kind} values`);
213
+ }
214
+ }
215
+ const dimensions = Math.max(...parsedOutputRange.map((parsed) => parsed.dimensions));
216
+ const units = [
217
+ null,
218
+ null,
219
+ null
220
+ ];
221
+ if (kind !== "scale") {
222
+ for (let axis = 0;axis < dimensions; axis++) {
223
+ for (const parsed of parsedOutputRange) {
224
+ const unit = parsed.units[axis];
225
+ if (unit === null) {
226
+ continue;
227
+ }
228
+ if (units[axis] === null) {
229
+ units[axis] = unit;
230
+ continue;
231
+ }
232
+ if (units[axis] !== unit) {
233
+ throw new TypeError(`Cannot interpolate ${kind} values with different units on axis ${axis + 1}: ${units[axis]} and ${unit}`);
234
+ }
235
+ }
236
+ if (units[axis] === null) {
237
+ throw new TypeError(`Cannot interpolate ${kind} values because axis ${axis + 1} has no unit`);
238
+ }
239
+ }
240
+ }
241
+ return serializeStringInterpolationValue({
242
+ kind,
243
+ values: [0, 0, 0].map((_, axis) => interpolateNumber({
244
+ input,
245
+ inputRange,
246
+ outputRange: parsedOutputRange.map((parsed) => parsed.values[axis]),
247
+ options
248
+ })),
249
+ units,
250
+ dimensions
251
+ });
252
+ };
46
253
  function checkValidInputRange(arr) {
47
254
  for (let i = 1;i < arr.length; ++i) {
48
255
  if (!(arr[i] > arr[i - 1])) {
@@ -102,42 +309,27 @@ function interpolate(input, inputRange, outputRange, options) {
102
309
  throw new Error("inputRange (" + inputRange.length + ") and outputRange (" + outputRange.length + ") must have the same length");
103
310
  }
104
311
  checkInfiniteRange("inputRange", inputRange);
105
- checkInfiniteRange("outputRange", outputRange);
106
312
  checkValidInputRange(inputRange);
107
313
  assertValidInterpolateEasingOption(options?.easing, inputRange.length);
108
314
  assertValidInterpolatePosterizeOption(options?.posterize);
109
- const easingOption = options?.easing;
110
- const defaultEasing = (num) => num;
111
- const resolveEasingForSegment = (segmentIndex) => {
112
- if (easingOption === undefined) {
113
- return defaultEasing;
114
- }
115
- if (typeof easingOption === "function") {
116
- return easingOption;
117
- }
118
- return easingOption[segmentIndex];
119
- };
120
- let extrapolateLeft = "extend";
121
- if (options?.extrapolateLeft !== undefined) {
122
- extrapolateLeft = options.extrapolateLeft;
123
- }
124
- let extrapolateRight = "extend";
125
- if (options?.extrapolateRight !== undefined) {
126
- extrapolateRight = options.extrapolateRight;
127
- }
128
315
  if (typeof input !== "number") {
129
316
  throw new TypeError("Cannot interpolate an input which is not a number");
130
317
  }
131
- if (inputRange.length === 1) {
132
- return outputRange[0];
318
+ if (!Array.isArray(outputRange)) {
319
+ throw new Error("outputRange must contain only numbers");
133
320
  }
134
- const posterizedInput = options?.posterize === undefined ? input : Math.floor(input / options.posterize) * options.posterize;
135
- const range = findRange(posterizedInput, inputRange);
136
- return interpolateFunction(posterizedInput, [inputRange[range], inputRange[range + 1]], [outputRange[range], outputRange[range + 1]], {
137
- easing: resolveEasingForSegment(range),
138
- extrapolateLeft,
139
- extrapolateRight
140
- });
321
+ const hasStringOutput = outputRange.some((output) => typeof output === "string");
322
+ if (hasStringOutput) {
323
+ if (!outputRange.every((output) => typeof output === "string" || typeof output === "number")) {
324
+ throw new TypeError("outputRange must contain only numbers, or supported scale, translate, and rotate strings");
325
+ }
326
+ return interpolateString({ input, inputRange, outputRange, options });
327
+ }
328
+ if (!outputRange.every((output) => typeof output === "number")) {
329
+ throw new TypeError("outputRange must contain only numbers, or supported scale, translate, and rotate strings");
330
+ }
331
+ checkInfiniteRange("outputRange", outputRange);
332
+ return interpolateNumber({ input, inputRange, outputRange, options });
141
333
  }
142
334
  function mulberry32(a) {
143
335
  let t = a + 1831565813;
@@ -720,6 +912,45 @@ var proResProfileOptions = [
720
912
  "light",
721
913
  "proxy"
722
914
  ];
915
+ var defaultScaleValue = [1, 1, 1];
916
+ var parseScaleString = (value) => {
917
+ const parts = value.trim().split(/\s+/);
918
+ if (parts.length < 1 || parts.length > 3 || parts[0] === "") {
919
+ return null;
920
+ }
921
+ const parsed = parts.map((part) => Number(part));
922
+ if (!parsed.every((part) => Number.isFinite(part))) {
923
+ return null;
924
+ }
925
+ const x = parsed[0];
926
+ const y = parsed[1] ?? x;
927
+ const z = parsed[2] ?? 1;
928
+ return [x, y, z];
929
+ };
930
+ var parseValidScaleValue = (value) => {
931
+ if (typeof value === "number") {
932
+ return Number.isFinite(value) ? [value, value, 1] : null;
933
+ }
934
+ if (typeof value === "string") {
935
+ return parseScaleString(value);
936
+ }
937
+ return null;
938
+ };
939
+ var parseScaleValue = (value) => {
940
+ return parseValidScaleValue(value) ?? defaultScaleValue;
941
+ };
942
+ var serializeScaleValue = ([x, y, z]) => {
943
+ const normalizedX = normalizeNumber(x);
944
+ const normalizedY = normalizeNumber(y);
945
+ const normalizedZ = normalizeNumber(z);
946
+ if (normalizedX === normalizedY && normalizedZ === 1) {
947
+ return normalizedX;
948
+ }
949
+ if (normalizedZ === 1) {
950
+ return `${normalizedX} ${normalizedY}`;
951
+ }
952
+ return `${normalizedX} ${normalizedY} ${normalizedZ}`;
953
+ };
723
954
  var sequenceVisualStyleSchema = {
724
955
  "style.translate": {
725
956
  type: "translate",
@@ -728,7 +959,7 @@ var sequenceVisualStyleSchema = {
728
959
  description: "Offset"
729
960
  },
730
961
  "style.scale": {
731
- type: "number",
962
+ type: "scale",
732
963
  min: 0.05,
733
964
  max: 100,
734
965
  step: 0.01,
@@ -736,7 +967,7 @@ var sequenceVisualStyleSchema = {
736
967
  description: "Scale"
737
968
  },
738
969
  "style.rotate": {
739
- type: "rotation",
970
+ type: "rotation-css",
740
971
  step: 1,
741
972
  default: "0deg",
742
973
  description: "Rotation"
@@ -747,7 +978,8 @@ var sequenceVisualStyleSchema = {
747
978
  max: 1,
748
979
  step: 0.01,
749
980
  default: 1,
750
- description: "Opacity"
981
+ description: "Opacity",
982
+ hiddenFromList: false
751
983
  }
752
984
  };
753
985
  var sequencePremountSchema = {
@@ -756,10 +988,15 @@ var sequencePremountSchema = {
756
988
  default: 0,
757
989
  description: "Premount For",
758
990
  min: 0,
759
- step: 1
991
+ step: 1,
992
+ hiddenFromList: false
760
993
  },
761
994
  postmountFor: {
762
- type: "hidden"
995
+ type: "number",
996
+ default: 0,
997
+ min: 0,
998
+ step: 1,
999
+ hiddenFromList: true
763
1000
  },
764
1001
  styleWhilePremounted: {
765
1002
  type: "hidden"
@@ -777,8 +1014,23 @@ var hiddenField = {
777
1014
  default: false,
778
1015
  description: "Hidden"
779
1016
  };
1017
+ var durationInFramesField = {
1018
+ type: "number",
1019
+ default: undefined,
1020
+ min: 1,
1021
+ step: 1,
1022
+ hiddenFromList: true
1023
+ };
1024
+ var fromField = {
1025
+ type: "number",
1026
+ default: 0,
1027
+ step: 1,
1028
+ hiddenFromList: true
1029
+ };
780
1030
  var sequenceSchema = {
781
1031
  hidden: hiddenField,
1032
+ from: fromField,
1033
+ durationInFrames: durationInFramesField,
782
1034
  layout: {
783
1035
  type: "enum",
784
1036
  default: "absolute-fill",
@@ -960,7 +1212,9 @@ var NoReactInternals = {
960
1212
  validateCodec,
961
1213
  proResProfileOptions,
962
1214
  findPropsToDelete,
963
- sequenceSchema
1215
+ sequenceSchema,
1216
+ parseScaleValue,
1217
+ serializeScaleValue
964
1218
  };
965
1219
 
966
1220
  // src/constants.ts
@@ -1149,7 +1403,7 @@ var validateFramesPerFunction = ({
1149
1403
  import * as tty from "tty";
1150
1404
 
1151
1405
  // ../core/dist/esm/version.mjs
1152
- var VERSION = "4.0.470";
1406
+ var VERSION = "4.0.472";
1153
1407
 
1154
1408
  // ../renderer/dist/esm/error-handling.mjs
1155
1409
  var isColorSupported = () => {
@@ -2609,6 +2863,51 @@ var getExpectedOutName = ({
2609
2863
  }
2610
2864
  throw new TypeError("no type passed");
2611
2865
  };
2866
+ // src/find-output-file-in-bucket.ts
2867
+ var findOutputFileInBucket = async ({
2868
+ region,
2869
+ renderMetadata,
2870
+ bucketName,
2871
+ customCredentials,
2872
+ currentRegion,
2873
+ providerSpecifics,
2874
+ forcePathStyle,
2875
+ requestHandler
2876
+ }) => {
2877
+ const { renderBucketName, key } = getExpectedOutName({
2878
+ renderMetadata,
2879
+ bucketName,
2880
+ customCredentials,
2881
+ bucketNamePrefix: providerSpecifics.getBucketPrefix()
2882
+ });
2883
+ try {
2884
+ const metadata = await providerSpecifics.headFile({
2885
+ bucketName: renderBucketName,
2886
+ key,
2887
+ region,
2888
+ customCredentials,
2889
+ forcePathStyle,
2890
+ requestHandler
2891
+ });
2892
+ return {
2893
+ url: providerSpecifics.getOutputUrl({
2894
+ renderMetadata,
2895
+ bucketName,
2896
+ customCredentials,
2897
+ currentRegion
2898
+ }).url,
2899
+ sizeInBytes: metadata.ContentLength ?? null
2900
+ };
2901
+ } catch (err) {
2902
+ if (err.name === "NotFound") {
2903
+ return null;
2904
+ }
2905
+ if (err.message === "UnknownError" || err.$metadata?.httpStatusCode === 403) {
2906
+ throw new Error(`Unable to access item "${key}" from bucket "${renderBucketName}" ${customCredentials?.endpoint ? `(S3 Endpoint = ${customCredentials?.endpoint})` : ""} - got a 403 error when heading the file. Check your credentials and permissions. The Lambda role must have permission for both "s3:GetObject" and "s3:ListBucket" actions.`, { cause: err });
2907
+ }
2908
+ throw err;
2909
+ }
2910
+ };
2612
2911
  // src/format-costs-info.ts
2613
2912
  var display = (accrued) => {
2614
2913
  if (accrued < 0.001) {
@@ -3054,6 +3353,76 @@ var getProgress = async ({
3054
3353
  });
3055
3354
  const isBeyondTimeoutAndMissingChunks = Date.now() > renderMetadata.startedDate + timeoutInMilliseconds + 20000 && missingChunks && missingChunks.length > 0;
3056
3355
  const isBeyondTimeoutAndHasStitchTimeout = Date.now() > renderMetadata.startedDate + timeoutInMilliseconds * 2 + 20000;
3356
+ const shouldCheckForCompletedOutput = allChunks && (isBeyondTimeoutAndHasStitchTimeout || overallProgress.combinedFrames >= frameCount && overallProgress.timeToCombine !== null);
3357
+ if (shouldCheckForCompletedOutput) {
3358
+ const outputFile = await findOutputFileInBucket({
3359
+ bucketName,
3360
+ customCredentials,
3361
+ renderMetadata,
3362
+ region,
3363
+ currentRegion: region,
3364
+ providerSpecifics,
3365
+ forcePathStyle,
3366
+ requestHandler
3367
+ });
3368
+ if (outputFile) {
3369
+ const outData = getExpectedOutName({
3370
+ renderMetadata,
3371
+ bucketName,
3372
+ customCredentials,
3373
+ bucketNamePrefix: providerSpecifics.getBucketPrefix()
3374
+ });
3375
+ const now = Date.now();
3376
+ const timeToFinishChunks = calculateChunkTimes({
3377
+ type: "absolute-time",
3378
+ timings: overallProgress.timings
3379
+ });
3380
+ return {
3381
+ framesRendered: frameCount,
3382
+ bucket: bucketName,
3383
+ renderSize: outputFile.sizeInBytes ?? 0,
3384
+ chunks: renderMetadata.totalChunks,
3385
+ cleanup: {
3386
+ doneIn: null,
3387
+ filesDeleted: 0,
3388
+ minFilesToDelete: 0
3389
+ },
3390
+ costs: priceFromBucket ? formatCostsInfo(priceFromBucket.accruedSoFar) : formatCostsInfo(0),
3391
+ currentTime: now,
3392
+ done: true,
3393
+ encodingStatus: {
3394
+ framesEncoded: frameCount,
3395
+ combinedFrames: frameCount,
3396
+ timeToCombine: overallProgress.timeToCombine
3397
+ },
3398
+ errors: errorExplanations,
3399
+ fatalErrorEncountered: false,
3400
+ lambdasInvoked: renderMetadata.totalChunks,
3401
+ outputFile: outputFile.url,
3402
+ renderId,
3403
+ timeToFinish: now - renderMetadata.startedDate,
3404
+ timeToFinishChunks,
3405
+ timeToRenderFrames: overallProgress.timeToRenderFrames,
3406
+ overallProgress: 1,
3407
+ retriesInfo: overallProgress.retries ?? [],
3408
+ outKey: outData.key,
3409
+ outBucket: outData.renderBucketName,
3410
+ mostExpensiveFrameRanges: null,
3411
+ timeToEncode: overallProgress.timeToEncode,
3412
+ outputSizeInBytes: outputFile.sizeInBytes ?? 0,
3413
+ type: "success",
3414
+ estimatedBillingDurationInMilliseconds: priceFromBucket?.estimatedBillingDurationInMilliseconds ?? null,
3415
+ timeToCombine: overallProgress.timeToCombine,
3416
+ combinedFrames: frameCount,
3417
+ renderMetadata,
3418
+ timeoutTimestamp: overallProgress.timeoutTimestamp,
3419
+ compositionValidated: overallProgress.compositionValidated,
3420
+ functionLaunched: overallProgress.functionLaunched,
3421
+ serveUrlOpened: overallProgress.serveUrlOpened,
3422
+ artifacts: overallProgress.receivedArtifact
3423
+ };
3424
+ }
3425
+ }
3057
3426
  const allErrors = [
3058
3427
  isBeyondTimeoutAndMissingChunks || isBeyondTimeoutAndHasStitchTimeout ? makeTimeoutError({
3059
3428
  timeoutInMilliseconds,
@@ -3237,6 +3606,7 @@ export {
3237
3606
  getCredentialsFromOutName,
3238
3607
  formatMap,
3239
3608
  formatCostsInfo,
3609
+ findOutputFileInBucket,
3240
3610
  expiryDays,
3241
3611
  estimatePriceFromMetadata,
3242
3612
  errorIsOutOfSpaceError,
@@ -0,0 +1,18 @@
1
+ import type { CustomCredentials } from './constants';
2
+ import type { ProviderSpecifics } from './provider-implementation';
3
+ import type { RenderMetadata } from './render-metadata';
4
+ import type { CloudProvider } from './types';
5
+ export type OutputFileMetadata = {
6
+ url: string;
7
+ sizeInBytes: number | null;
8
+ };
9
+ export declare const findOutputFileInBucket: <Provider extends CloudProvider<string, Record<string, unknown>, Record<string, unknown>, string, object>>({ region, renderMetadata, bucketName, customCredentials, currentRegion, providerSpecifics, forcePathStyle, requestHandler, }: {
10
+ region: Provider["region"];
11
+ renderMetadata: RenderMetadata<Provider>;
12
+ bucketName: string;
13
+ customCredentials: CustomCredentials<Provider> | null;
14
+ currentRegion: Provider["region"];
15
+ providerSpecifics: ProviderSpecifics<Provider>;
16
+ forcePathStyle: boolean;
17
+ requestHandler: Provider["requestHandler"] | null;
18
+ }) => Promise<OutputFileMetadata | null>;
@@ -0,0 +1,46 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.findOutputFileInBucket = void 0;
4
+ const expected_out_name_1 = require("./expected-out-name");
5
+ const findOutputFileInBucket = async ({ region, renderMetadata, bucketName, customCredentials, currentRegion, providerSpecifics, forcePathStyle, requestHandler, }) => {
6
+ var _a;
7
+ var _b;
8
+ const { renderBucketName, key } = (0, expected_out_name_1.getExpectedOutName)({
9
+ renderMetadata,
10
+ bucketName,
11
+ customCredentials,
12
+ bucketNamePrefix: providerSpecifics.getBucketPrefix(),
13
+ });
14
+ try {
15
+ const metadata = await providerSpecifics.headFile({
16
+ bucketName: renderBucketName,
17
+ key,
18
+ region,
19
+ customCredentials,
20
+ forcePathStyle,
21
+ requestHandler,
22
+ });
23
+ return {
24
+ url: providerSpecifics.getOutputUrl({
25
+ renderMetadata,
26
+ bucketName,
27
+ customCredentials,
28
+ currentRegion,
29
+ }).url,
30
+ sizeInBytes: (_b = metadata.ContentLength) !== null && _b !== void 0 ? _b : null,
31
+ };
32
+ }
33
+ catch (err) {
34
+ if (err.name === 'NotFound') {
35
+ return null;
36
+ }
37
+ if (err.message === 'UnknownError' ||
38
+ ((_a = err.$metadata) === null || _a === void 0 ? void 0 : _a.httpStatusCode) === 403) {
39
+ throw new Error(`Unable to access item "${key}" from bucket "${renderBucketName}" ${(customCredentials === null || customCredentials === void 0 ? void 0 : customCredentials.endpoint)
40
+ ? `(S3 Endpoint = ${customCredentials === null || customCredentials === void 0 ? void 0 : customCredentials.endpoint})`
41
+ : ''} - got a 403 error when heading the file. Check your credentials and permissions. The Lambda role must have permission for both "s3:GetObject" and "s3:ListBucket" actions.`, { cause: err });
42
+ }
43
+ throw err;
44
+ }
45
+ };
46
+ exports.findOutputFileInBucket = findOutputFileInBucket;
package/dist/index.d.ts CHANGED
@@ -20,6 +20,7 @@ export { DOCS_URL } from './docs-url';
20
20
  export { errorIsOutOfSpaceError, isBrowserCrashedError, isErrInsufficientResourcesErr, } from './error-category';
21
21
  export { estimatePriceFromMetadata } from './estimate-price-from-bucket';
22
22
  export { getCredentialsFromOutName, getExpectedOutName, } from './expected-out-name';
23
+ export { findOutputFileInBucket, type OutputFileMetadata, } from './find-output-file-in-bucket';
23
24
  export { formatCostsInfo } from './format-costs-info';
24
25
  export { FileNameAndSize, GetFolderFiles } from './get-files-in-folder';
25
26
  export { GetOrCreateBucketInput, GetOrCreateBucketOutput, internalGetOrCreateBucket, } from './get-or-create-bucket';
package/dist/index.js CHANGED
@@ -14,8 +14,8 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
14
  for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
15
  };
16
16
  Object.defineProperty(exports, "__esModule", { value: true });
17
- exports.validatePrivacy = exports.validateOutname = exports.validateBucketName = exports.truthy = exports.messageTypeIdToMessageType = exports.makeStreamPayload = exports.formatMap = exports.streamToString = exports.getProgress = exports.OVERHEAD_TIME_PER_LAMBDA = exports.getMostExpensiveChunks = exports.makeBucketName = exports.inspectErrors = exports.resolvedPropsKey = exports.inputPropsKey = exports.getRemotionVersionFromIndexHtml = exports.getOverallProgressFromStorage = exports.internalGetOrCreateBucket = exports.formatCostsInfo = exports.getExpectedOutName = exports.getCredentialsFromOutName = exports.estimatePriceFromMetadata = exports.isErrInsufficientResourcesErr = exports.isBrowserCrashedError = exports.errorIsOutOfSpaceError = exports.DOCS_URL = exports.MAX_FUNCTIONS_PER_RENDER = exports.serializeOrThrow = exports.getNeedsToUpload = exports.decompressInputProps = exports.compressInputProps = exports.calculateChunkTimes = exports.VERSION = exports.makeStreamPayloadMessage = exports.makeStreamer = exports.wrapWithErrorHandling = exports.validateFramesPerFunction = exports.validateDownloadBehavior = exports.serializeArtifact = exports.deserializeArtifact = exports.ServerlessRoutines = exports.serverlessCodecs = exports.rendersPrefix = exports.overallProgressKey = exports.outStillName = exports.outName = exports.MINIMUM_FRAMES_PER_FUNCTION = exports.expiryDays = exports.customOutName = exports.artifactName = void 0;
18
- exports.validateCodec = exports.validateDurationInFrames = exports.validateDimension = exports.validateFps = exports.serializeJSONWithSpecialTypes = exports.ENABLE_V5_BREAKING_CHANGES = exports.random = exports.interpolate = exports.validateWebhook = void 0;
17
+ exports.validateOutname = exports.validateBucketName = exports.truthy = exports.messageTypeIdToMessageType = exports.makeStreamPayload = exports.formatMap = exports.streamToString = exports.getProgress = exports.OVERHEAD_TIME_PER_LAMBDA = exports.getMostExpensiveChunks = exports.makeBucketName = exports.inspectErrors = exports.resolvedPropsKey = exports.inputPropsKey = exports.getRemotionVersionFromIndexHtml = exports.getOverallProgressFromStorage = exports.internalGetOrCreateBucket = exports.formatCostsInfo = exports.findOutputFileInBucket = exports.getExpectedOutName = exports.getCredentialsFromOutName = exports.estimatePriceFromMetadata = exports.isErrInsufficientResourcesErr = exports.isBrowserCrashedError = exports.errorIsOutOfSpaceError = exports.DOCS_URL = exports.MAX_FUNCTIONS_PER_RENDER = exports.serializeOrThrow = exports.getNeedsToUpload = exports.decompressInputProps = exports.compressInputProps = exports.calculateChunkTimes = exports.VERSION = exports.makeStreamPayloadMessage = exports.makeStreamer = exports.wrapWithErrorHandling = exports.validateFramesPerFunction = exports.validateDownloadBehavior = exports.serializeArtifact = exports.deserializeArtifact = exports.ServerlessRoutines = exports.serverlessCodecs = exports.rendersPrefix = exports.overallProgressKey = exports.outStillName = exports.outName = exports.MINIMUM_FRAMES_PER_FUNCTION = exports.expiryDays = exports.customOutName = exports.artifactName = void 0;
18
+ exports.validateCodec = exports.validateDurationInFrames = exports.validateDimension = exports.validateFps = exports.serializeJSONWithSpecialTypes = exports.ENABLE_V5_BREAKING_CHANGES = exports.random = exports.interpolate = exports.validateWebhook = exports.validatePrivacy = void 0;
19
19
  const no_react_1 = require("remotion/no-react");
20
20
  Object.defineProperty(exports, "interpolate", { enumerable: true, get: function () { return no_react_1.interpolate; } });
21
21
  Object.defineProperty(exports, "random", { enumerable: true, get: function () { return no_react_1.random; } });
@@ -65,6 +65,8 @@ Object.defineProperty(exports, "estimatePriceFromMetadata", { enumerable: true,
65
65
  const expected_out_name_1 = require("./expected-out-name");
66
66
  Object.defineProperty(exports, "getCredentialsFromOutName", { enumerable: true, get: function () { return expected_out_name_1.getCredentialsFromOutName; } });
67
67
  Object.defineProperty(exports, "getExpectedOutName", { enumerable: true, get: function () { return expected_out_name_1.getExpectedOutName; } });
68
+ const find_output_file_in_bucket_1 = require("./find-output-file-in-bucket");
69
+ Object.defineProperty(exports, "findOutputFileInBucket", { enumerable: true, get: function () { return find_output_file_in_bucket_1.findOutputFileInBucket; } });
68
70
  const format_costs_info_1 = require("./format-costs-info");
69
71
  Object.defineProperty(exports, "formatCostsInfo", { enumerable: true, get: function () { return format_costs_info_1.formatCostsInfo; } });
70
72
  const get_or_create_bucket_1 = require("./get-or-create-bucket");
package/dist/progress.js CHANGED
@@ -5,6 +5,7 @@ const pure_1 = require("@remotion/renderer/pure");
5
5
  const calculate_chunk_times_1 = require("./calculate-chunk-times");
6
6
  const estimate_price_from_bucket_1 = require("./estimate-price-from-bucket");
7
7
  const expected_out_name_1 = require("./expected-out-name");
8
+ const find_output_file_in_bucket_1 = require("./find-output-file-in-bucket");
8
9
  const format_costs_info_1 = require("./format-costs-info");
9
10
  const get_overall_progress_1 = require("./get-overall-progress");
10
11
  const get_overall_progress_from_storage_1 = require("./get-overall-progress-from-storage");
@@ -14,7 +15,7 @@ const render_has_audio_video_1 = require("./render-has-audio-video");
14
15
  const truthy_1 = require("./truthy");
15
16
  const getProgress = async ({ bucketName, renderId, expectedBucketOwner, region, memorySizeInMb, timeoutInMilliseconds, customCredentials, providerSpecifics, forcePathStyle, functionName, requestHandler, }) => {
16
17
  var _a;
17
- var _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s, _t, _u, _v, _w, _x;
18
+ var _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s, _t, _u, _v, _w, _x, _y, _z, _0, _1;
18
19
  const overallProgress = await (0, get_overall_progress_from_storage_1.getOverallProgressFromStorage)({
19
20
  renderId,
20
21
  bucketName,
@@ -183,6 +184,81 @@ const getProgress = async ({ bucketName, renderId, expectedBucketOwner, region,
183
184
  missingChunks.length > 0;
184
185
  // 2. If we have no missing chunks, but the encoding is not done, even after the additional `merge` function has been spawned, we consider it timed out
185
186
  const isBeyondTimeoutAndHasStitchTimeout = Date.now() > renderMetadata.startedDate + timeoutInMilliseconds * 2 + 20000;
187
+ const shouldCheckForCompletedOutput = allChunks &&
188
+ (isBeyondTimeoutAndHasStitchTimeout ||
189
+ (overallProgress.combinedFrames >= frameCount &&
190
+ overallProgress.timeToCombine !== null));
191
+ if (shouldCheckForCompletedOutput) {
192
+ const outputFile = await (0, find_output_file_in_bucket_1.findOutputFileInBucket)({
193
+ bucketName,
194
+ customCredentials,
195
+ renderMetadata,
196
+ region,
197
+ currentRegion: region,
198
+ providerSpecifics,
199
+ forcePathStyle,
200
+ requestHandler,
201
+ });
202
+ if (outputFile) {
203
+ const outData = (0, expected_out_name_1.getExpectedOutName)({
204
+ renderMetadata,
205
+ bucketName,
206
+ customCredentials,
207
+ bucketNamePrefix: providerSpecifics.getBucketPrefix(),
208
+ });
209
+ const now = Date.now();
210
+ const timeToFinishChunks = (0, calculate_chunk_times_1.calculateChunkTimes)({
211
+ type: 'absolute-time',
212
+ timings: overallProgress.timings,
213
+ });
214
+ return {
215
+ framesRendered: frameCount,
216
+ bucket: bucketName,
217
+ renderSize: (_q = outputFile.sizeInBytes) !== null && _q !== void 0 ? _q : 0,
218
+ chunks: renderMetadata.totalChunks,
219
+ cleanup: {
220
+ doneIn: null,
221
+ filesDeleted: 0,
222
+ minFilesToDelete: 0,
223
+ },
224
+ costs: priceFromBucket
225
+ ? (0, format_costs_info_1.formatCostsInfo)(priceFromBucket.accruedSoFar)
226
+ : (0, format_costs_info_1.formatCostsInfo)(0),
227
+ currentTime: now,
228
+ done: true,
229
+ encodingStatus: {
230
+ framesEncoded: frameCount,
231
+ combinedFrames: frameCount,
232
+ timeToCombine: overallProgress.timeToCombine,
233
+ },
234
+ errors: errorExplanations,
235
+ fatalErrorEncountered: false,
236
+ lambdasInvoked: renderMetadata.totalChunks,
237
+ outputFile: outputFile.url,
238
+ renderId,
239
+ timeToFinish: now - renderMetadata.startedDate,
240
+ timeToFinishChunks,
241
+ timeToRenderFrames: overallProgress.timeToRenderFrames,
242
+ overallProgress: 1,
243
+ retriesInfo: (_r = overallProgress.retries) !== null && _r !== void 0 ? _r : [],
244
+ outKey: outData.key,
245
+ outBucket: outData.renderBucketName,
246
+ mostExpensiveFrameRanges: null,
247
+ timeToEncode: overallProgress.timeToEncode,
248
+ outputSizeInBytes: (_s = outputFile.sizeInBytes) !== null && _s !== void 0 ? _s : 0,
249
+ type: 'success',
250
+ estimatedBillingDurationInMilliseconds: (_t = priceFromBucket === null || priceFromBucket === void 0 ? void 0 : priceFromBucket.estimatedBillingDurationInMilliseconds) !== null && _t !== void 0 ? _t : null,
251
+ timeToCombine: overallProgress.timeToCombine,
252
+ combinedFrames: frameCount,
253
+ renderMetadata,
254
+ timeoutTimestamp: overallProgress.timeoutTimestamp,
255
+ compositionValidated: overallProgress.compositionValidated,
256
+ functionLaunched: overallProgress.functionLaunched,
257
+ serveUrlOpened: overallProgress.serveUrlOpened,
258
+ artifacts: overallProgress.receivedArtifact,
259
+ };
260
+ }
261
+ }
186
262
  const allErrors = [
187
263
  isBeyondTimeoutAndMissingChunks || isBeyondTimeoutAndHasStitchTimeout
188
264
  ? (0, make_timeout_error_1.makeTimeoutError)({
@@ -198,7 +274,7 @@ const getProgress = async ({ bucketName, renderId, expectedBucketOwner, region,
198
274
  ...errorExplanations,
199
275
  ].filter(truthy_1.truthy);
200
276
  return {
201
- framesRendered: (_q = overallProgress.framesRendered) !== null && _q !== void 0 ? _q : 0,
277
+ framesRendered: (_u = overallProgress.framesRendered) !== null && _u !== void 0 ? _u : 0,
202
278
  chunks: chunkCount,
203
279
  done: false,
204
280
  encodingStatus: {
@@ -219,7 +295,7 @@ const getProgress = async ({ bucketName, renderId, expectedBucketOwner, region,
219
295
  fatalErrorEncountered: allErrors.some((f) => f.isFatal && !f.willRetry),
220
296
  currentTime: Date.now(),
221
297
  renderSize: 0,
222
- lambdasInvoked: (_r = overallProgress.lambdasInvoked) !== null && _r !== void 0 ? _r : 0,
298
+ lambdasInvoked: (_v = overallProgress.lambdasInvoked) !== null && _v !== void 0 ? _v : 0,
223
299
  cleanup,
224
300
  timeToFinishChunks: allChunks && overallProgress
225
301
  ? (0, calculate_chunk_times_1.calculateChunkTimes)({
@@ -229,17 +305,17 @@ const getProgress = async ({ bucketName, renderId, expectedBucketOwner, region,
229
305
  : null,
230
306
  overallProgress: (0, get_overall_progress_1.getOverallProgress)({
231
307
  encoding: frameCount
232
- ? ((_s = overallProgress.framesEncoded) !== null && _s !== void 0 ? _s : 0) / frameCount
308
+ ? ((_w = overallProgress.framesEncoded) !== null && _w !== void 0 ? _w : 0) / frameCount
233
309
  : 0,
234
- invoking: ((_t = overallProgress.lambdasInvoked) !== null && _t !== void 0 ? _t : 0) /
310
+ invoking: ((_x = overallProgress.lambdasInvoked) !== null && _x !== void 0 ? _x : 0) /
235
311
  renderMetadata.estimatedRenderLambdaInvokations,
236
- frames: ((_u = overallProgress.framesRendered) !== null && _u !== void 0 ? _u : 0) / (frameCount !== null && frameCount !== void 0 ? frameCount : 1),
312
+ frames: ((_y = overallProgress.framesRendered) !== null && _y !== void 0 ? _y : 0) / (frameCount !== null && frameCount !== void 0 ? frameCount : 1),
237
313
  gotComposition: overallProgress.compositionValidated,
238
314
  visitedServeUrl: overallProgress.serveUrlOpened,
239
315
  invokedLambda: overallProgress.lambdasInvoked,
240
316
  combining: overallProgress.combinedFrames / (frameCount !== null && frameCount !== void 0 ? frameCount : 1),
241
317
  }),
242
- retriesInfo: (_v = overallProgress.retries) !== null && _v !== void 0 ? _v : [],
318
+ retriesInfo: (_z = overallProgress.retries) !== null && _z !== void 0 ? _z : [],
243
319
  outKey: null,
244
320
  outBucket: null,
245
321
  mostExpensiveFrameRanges: null,
@@ -248,8 +324,8 @@ const getProgress = async ({ bucketName, renderId, expectedBucketOwner, region,
248
324
  estimatedBillingDurationInMilliseconds: priceFromBucket
249
325
  ? priceFromBucket.estimatedBillingDurationInMilliseconds
250
326
  : null,
251
- combinedFrames: (_w = overallProgress.combinedFrames) !== null && _w !== void 0 ? _w : 0,
252
- timeToCombine: (_x = overallProgress.timeToCombine) !== null && _x !== void 0 ? _x : null,
327
+ combinedFrames: (_0 = overallProgress.combinedFrames) !== null && _0 !== void 0 ? _0 : 0,
328
+ timeToCombine: (_1 = overallProgress.timeToCombine) !== null && _1 !== void 0 ? _1 : null,
253
329
  timeoutTimestamp: overallProgress.timeoutTimestamp,
254
330
  type: 'success',
255
331
  compositionValidated: overallProgress.compositionValidated,
package/package.json CHANGED
@@ -3,7 +3,7 @@
3
3
  "url": "https://github.com/remotion-dev/remotion/tree/main/packages/serverless-client"
4
4
  },
5
5
  "name": "@remotion/serverless-client",
6
- "version": "4.0.470",
6
+ "version": "4.0.472",
7
7
  "main": "dist",
8
8
  "scripts": {
9
9
  "lint": "eslint src",
@@ -23,10 +23,10 @@
23
23
  },
24
24
  "dependencies": {},
25
25
  "devDependencies": {
26
- "remotion": "4.0.470",
27
- "@remotion/streaming": "4.0.470",
28
- "@remotion/renderer": "4.0.470",
29
- "@remotion/eslint-config-internal": "4.0.470",
26
+ "remotion": "4.0.472",
27
+ "@remotion/streaming": "4.0.472",
28
+ "@remotion/renderer": "4.0.472",
29
+ "@remotion/eslint-config-internal": "4.0.472",
30
30
  "eslint": "9.19.0",
31
31
  "@typescript/native-preview": "7.0.0-dev.20260217.1"
32
32
  },