@remotion/serverless 4.0.517 → 4.0.518
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/finish-render.d.ts +24 -0
- package/dist/finish-render.js +64 -0
- package/dist/handlers/launch.d.ts +2 -0
- package/dist/handlers/launch.js +106 -58
- package/dist/handlers/renderer.d.ts +2 -1
- package/dist/handlers/renderer.js +9 -4
- package/dist/inner-routine.js +2 -0
- package/dist/merge-chunks.js +14 -49
- package/dist/render-with-single-function.d.ts +20 -0
- package/dist/render-with-single-function.js +123 -0
- package/package.json +6 -6
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import type { CloudProvider, CustomCredentials, DownloadBehavior, PostRenderData, Privacy, ProviderSpecifics, RenderMetadata, SerializedInputProps } from '@remotion/serverless-client';
|
|
2
|
+
import type { OverallProgressHelper } from './overall-render-progress';
|
|
3
|
+
import type { InsideFunctionSpecifics } from './provider-implementation';
|
|
4
|
+
export declare const finishRender: <Provider extends CloudProvider<string, Record<string, unknown>, Record<string, unknown>, string, object>>({ expectedBucketOwner, renderBucketName, customCredentials, downloadBehavior, key, privacy, inputProps, serializedResolvedProps, renderMetadata, logLevel, overallProgress, startTime, providerSpecifics, insideFunctionSpecifics, forcePathStyle, storageClass, requestHandler, outputFile, timeToCombine, }: {
|
|
5
|
+
expectedBucketOwner: string;
|
|
6
|
+
renderBucketName: string;
|
|
7
|
+
customCredentials: CustomCredentials<Provider> | null;
|
|
8
|
+
downloadBehavior: DownloadBehavior;
|
|
9
|
+
key: string;
|
|
10
|
+
privacy: Privacy;
|
|
11
|
+
inputProps: SerializedInputProps;
|
|
12
|
+
serializedResolvedProps: SerializedInputProps;
|
|
13
|
+
renderMetadata: RenderMetadata<Provider>;
|
|
14
|
+
logLevel: "error" | "info" | "trace" | "verbose" | "warn";
|
|
15
|
+
overallProgress: OverallProgressHelper<Provider>;
|
|
16
|
+
startTime: number;
|
|
17
|
+
providerSpecifics: ProviderSpecifics<Provider>;
|
|
18
|
+
insideFunctionSpecifics: InsideFunctionSpecifics<Provider>;
|
|
19
|
+
forcePathStyle: boolean;
|
|
20
|
+
storageClass: Provider["storageClass"] | null;
|
|
21
|
+
requestHandler: Provider["requestHandler"] | null;
|
|
22
|
+
outputFile: string;
|
|
23
|
+
timeToCombine: number | null;
|
|
24
|
+
}) => Promise<PostRenderData<Provider>>;
|
|
@@ -0,0 +1,64 @@
|
|
|
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
|
+
exports.finishRender = void 0;
|
|
7
|
+
const node_fs_1 = __importDefault(require("node:fs"));
|
|
8
|
+
const serverless_client_1 = require("@remotion/serverless-client");
|
|
9
|
+
const cleanup_props_1 = require("./cleanup-props");
|
|
10
|
+
const create_post_render_data_1 = require("./create-post-render-data");
|
|
11
|
+
const finishRender = async ({ expectedBucketOwner, renderBucketName, customCredentials, downloadBehavior, key, privacy, inputProps, serializedResolvedProps, renderMetadata, logLevel, overallProgress, startTime, providerSpecifics, insideFunctionSpecifics, forcePathStyle, storageClass, requestHandler, outputFile, timeToCombine, }) => {
|
|
12
|
+
const outputSize = node_fs_1.default.statSync(outputFile).size;
|
|
13
|
+
const writeToBucket = insideFunctionSpecifics.timer(`Writing to bucket (${outputSize} bytes)`, logLevel);
|
|
14
|
+
await providerSpecifics.writeFile({
|
|
15
|
+
bucketName: renderBucketName,
|
|
16
|
+
key,
|
|
17
|
+
body: node_fs_1.default.createReadStream(outputFile),
|
|
18
|
+
region: insideFunctionSpecifics.getCurrentRegionInFunction(),
|
|
19
|
+
privacy,
|
|
20
|
+
expectedBucketOwner,
|
|
21
|
+
downloadBehavior,
|
|
22
|
+
customCredentials,
|
|
23
|
+
forcePathStyle,
|
|
24
|
+
storageClass,
|
|
25
|
+
requestHandler,
|
|
26
|
+
});
|
|
27
|
+
writeToBucket.end();
|
|
28
|
+
const errorExplanations = (0, serverless_client_1.inspectErrors)({
|
|
29
|
+
errors: overallProgress.get().errors,
|
|
30
|
+
});
|
|
31
|
+
const cleanupProm = (0, cleanup_props_1.cleanupProps)({
|
|
32
|
+
inputProps,
|
|
33
|
+
serializedResolvedProps,
|
|
34
|
+
providerSpecifics,
|
|
35
|
+
forcePathStyle,
|
|
36
|
+
insideFunctionSpecifics,
|
|
37
|
+
});
|
|
38
|
+
const { url: outputUrl } = providerSpecifics.getOutputUrl({
|
|
39
|
+
bucketName: renderBucketName,
|
|
40
|
+
currentRegion: insideFunctionSpecifics.getCurrentRegionInFunction(),
|
|
41
|
+
customCredentials,
|
|
42
|
+
renderMetadata,
|
|
43
|
+
});
|
|
44
|
+
const postRenderData = (0, create_post_render_data_1.createPostRenderData)({
|
|
45
|
+
region: insideFunctionSpecifics.getCurrentRegionInFunction(),
|
|
46
|
+
memorySizeInMb: insideFunctionSpecifics.getCurrentMemorySizeInMb(),
|
|
47
|
+
renderMetadata,
|
|
48
|
+
errorExplanations,
|
|
49
|
+
timeToDelete: (await cleanupProm).reduce((a, b) => Math.max(a, b), 0),
|
|
50
|
+
outputFile: {
|
|
51
|
+
sizeInBytes: outputSize,
|
|
52
|
+
url: outputUrl,
|
|
53
|
+
},
|
|
54
|
+
outputSize,
|
|
55
|
+
timeToCombine,
|
|
56
|
+
overallProgress: overallProgress.get(),
|
|
57
|
+
timeToFinish: Date.now() - startTime,
|
|
58
|
+
providerSpecifics,
|
|
59
|
+
});
|
|
60
|
+
await overallProgress.setPostRenderData(postRenderData);
|
|
61
|
+
node_fs_1.default.unlinkSync(outputFile);
|
|
62
|
+
return postRenderData;
|
|
63
|
+
};
|
|
64
|
+
exports.finishRender = finishRender;
|
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
import type { CloudProvider, ProviderSpecifics, ServerlessPayload } from '@remotion/serverless-client';
|
|
2
2
|
import type { InsideFunctionSpecifics } from '../provider-implementation';
|
|
3
|
+
import type { RequestContext } from './renderer';
|
|
3
4
|
type Options = {
|
|
4
5
|
expectedBucketOwner: string;
|
|
5
6
|
getRemainingTimeInMillis: () => number;
|
|
7
|
+
requestContext: RequestContext | null;
|
|
6
8
|
};
|
|
7
9
|
export declare const launchHandler: <Provider extends CloudProvider<string, Record<string, unknown>, Record<string, unknown>, string, object>>({ params, options, providerSpecifics, insideFunctionSpecifics, }: {
|
|
8
10
|
params: ServerlessPayload<Provider>;
|
package/dist/handlers/launch.js
CHANGED
|
@@ -9,11 +9,13 @@ const serverless_client_2 = require("@remotion/serverless-client");
|
|
|
9
9
|
const artifact_registry_1 = require("../artifact-registry");
|
|
10
10
|
const cleanup_props_1 = require("../cleanup-props");
|
|
11
11
|
const find_output_file_in_bucket_1 = require("../find-output-file-in-bucket");
|
|
12
|
+
const finish_render_1 = require("../finish-render");
|
|
12
13
|
const get_tmp_dir_1 = require("../get-tmp-dir");
|
|
13
14
|
const merge_chunks_1 = require("../merge-chunks");
|
|
14
15
|
const overall_render_progress_1 = require("../overall-render-progress");
|
|
15
16
|
const plan_frame_ranges_1 = require("../plan-frame-ranges");
|
|
16
17
|
const remove_outname_credentials_1 = require("../remove-outname-credentials");
|
|
18
|
+
const render_with_single_function_1 = require("../render-with-single-function");
|
|
17
19
|
const stream_renderer_1 = require("../stream-renderer");
|
|
18
20
|
const validate_composition_1 = require("../validate-composition");
|
|
19
21
|
const send_telemetry_event_1 = require("./send-telemetry-event");
|
|
@@ -224,16 +226,18 @@ const innerLaunchHandler = async ({ params, options, overallProgress, registerCl
|
|
|
224
226
|
});
|
|
225
227
|
renderer_1.RenderInternals.Log.info(logOptions, 'Render plan: ', chunks.map((c, i) => `Chunk ${i} (Frames ${c[0]} - ${c[1]})`).join(', '));
|
|
226
228
|
const rendererFunctionName = (_j = params.rendererFunctionName) !== null && _j !== void 0 ? _j : insideFunctionSpecifics.getCurrentFunctionName();
|
|
229
|
+
const shouldRenderDirectly = params.concurrency === 1 &&
|
|
230
|
+
params.rendererFunctionName === null &&
|
|
231
|
+
options.requestContext !== null;
|
|
227
232
|
const renderMetadata = {
|
|
228
233
|
startedDate,
|
|
229
234
|
totalChunks: chunks.length,
|
|
230
235
|
estimatedTotalLambdaInvokations: [
|
|
231
|
-
|
|
232
|
-
chunks.length,
|
|
236
|
+
shouldRenderDirectly ? 0 : chunks.length,
|
|
233
237
|
// This function
|
|
234
238
|
1,
|
|
235
239
|
].reduce((a, b) => a + b, 0),
|
|
236
|
-
estimatedRenderLambdaInvokations: chunks.length,
|
|
240
|
+
estimatedRenderLambdaInvokations: shouldRenderDirectly ? 0 : chunks.length,
|
|
237
241
|
compositionId: comp.id,
|
|
238
242
|
siteId: params.serveUrl,
|
|
239
243
|
codec: params.codec,
|
|
@@ -291,14 +295,6 @@ const innerLaunchHandler = async ({ params, options, overallProgress, registerCl
|
|
|
291
295
|
findOutputFile.end();
|
|
292
296
|
}
|
|
293
297
|
overallProgress.setRenderMetadata(renderMetadata);
|
|
294
|
-
const outdir = (0, path_1.join)(renderer_1.RenderInternals.tmpDir(serverless_client_2.CONCAT_FOLDER_TOKEN), 'bucket');
|
|
295
|
-
if ((0, fs_1.existsSync)(outdir)) {
|
|
296
|
-
(0, fs_1.rmSync)(outdir, {
|
|
297
|
-
recursive: true,
|
|
298
|
-
});
|
|
299
|
-
}
|
|
300
|
-
(0, fs_1.mkdirSync)(outdir);
|
|
301
|
-
const files = [];
|
|
302
298
|
const artifactRegistry = (0, artifact_registry_1.makeArtifactRegistry)();
|
|
303
299
|
const onArtifact = ({ artifact, chunk, attempt }) => {
|
|
304
300
|
var _a;
|
|
@@ -357,59 +353,111 @@ const innerLaunchHandler = async ({ params, options, overallProgress, registerCl
|
|
|
357
353
|
});
|
|
358
354
|
return artifactRegistration;
|
|
359
355
|
};
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
356
|
+
let postRenderData;
|
|
357
|
+
if (shouldRenderDirectly) {
|
|
358
|
+
const directRender = await (0, render_with_single_function_1.renderWithSingleFunction)({
|
|
359
|
+
params,
|
|
360
|
+
composition: comp,
|
|
361
|
+
serializedInputPropsWithCustomSchema,
|
|
362
|
+
frameRange: realFrameRange,
|
|
363
|
+
browserInstance: instance,
|
|
364
|
+
chromiumOptions: chromiumParams,
|
|
365
365
|
overallProgress,
|
|
366
|
-
payload,
|
|
367
|
-
logLevel: params.logLevel,
|
|
368
366
|
onArtifact,
|
|
369
367
|
providerSpecifics,
|
|
370
368
|
insideFunctionSpecifics,
|
|
371
|
-
|
|
369
|
+
});
|
|
370
|
+
try {
|
|
371
|
+
postRenderData = await (0, finish_render_1.finishRender)({
|
|
372
|
+
expectedBucketOwner: options.expectedBucketOwner,
|
|
373
|
+
renderBucketName,
|
|
374
|
+
customCredentials,
|
|
375
|
+
downloadBehavior: params.downloadBehavior,
|
|
376
|
+
key,
|
|
377
|
+
privacy: params.privacy,
|
|
378
|
+
inputProps: params.inputProps,
|
|
379
|
+
serializedResolvedProps,
|
|
380
|
+
renderMetadata,
|
|
381
|
+
logLevel: params.logLevel,
|
|
382
|
+
overallProgress,
|
|
383
|
+
startTime,
|
|
384
|
+
providerSpecifics,
|
|
385
|
+
insideFunctionSpecifics,
|
|
386
|
+
forcePathStyle: params.forcePathStyle,
|
|
387
|
+
storageClass: params.storageClass,
|
|
388
|
+
requestHandler: null,
|
|
389
|
+
outputFile: directRender.outputFile,
|
|
390
|
+
timeToCombine: null,
|
|
391
|
+
});
|
|
392
|
+
}
|
|
393
|
+
finally {
|
|
394
|
+
await directRender.cleanup();
|
|
395
|
+
}
|
|
396
|
+
}
|
|
397
|
+
else {
|
|
398
|
+
const outdir = (0, path_1.join)(renderer_1.RenderInternals.tmpDir(serverless_client_2.CONCAT_FOLDER_TOKEN), 'bucket');
|
|
399
|
+
if ((0, fs_1.existsSync)(outdir)) {
|
|
400
|
+
(0, fs_1.rmSync)(outdir, {
|
|
401
|
+
recursive: true,
|
|
402
|
+
});
|
|
403
|
+
}
|
|
404
|
+
(0, fs_1.mkdirSync)(outdir);
|
|
405
|
+
const files = [];
|
|
406
|
+
await Promise.all(lambdaPayloads.map(async (payload) => {
|
|
407
|
+
await (0, stream_renderer_1.renderRendererFunctionWithRetry)({
|
|
408
|
+
files,
|
|
409
|
+
functionName: rendererFunctionName,
|
|
410
|
+
outdir,
|
|
411
|
+
overallProgress,
|
|
412
|
+
payload,
|
|
413
|
+
logLevel: params.logLevel,
|
|
414
|
+
onArtifact,
|
|
415
|
+
providerSpecifics,
|
|
416
|
+
insideFunctionSpecifics,
|
|
417
|
+
requestHandler: null,
|
|
418
|
+
expectedBucketOwner: options.expectedBucketOwner,
|
|
419
|
+
});
|
|
420
|
+
}));
|
|
421
|
+
postRenderData = await (0, merge_chunks_1.mergeChunksAndFinishRender)({
|
|
422
|
+
bucketName: params.bucketName,
|
|
423
|
+
renderId: params.renderId,
|
|
372
424
|
expectedBucketOwner: options.expectedBucketOwner,
|
|
425
|
+
numberOfFrames: comp.durationInFrames,
|
|
426
|
+
audioCodec: params.audioCodec,
|
|
427
|
+
chunkCount: chunks.length,
|
|
428
|
+
codec: params.codec,
|
|
429
|
+
customCredentials,
|
|
430
|
+
downloadBehavior: params.downloadBehavior,
|
|
431
|
+
fps,
|
|
432
|
+
key,
|
|
433
|
+
numberOfGifLoops: params.numberOfGifLoops,
|
|
434
|
+
privacy: params.privacy,
|
|
435
|
+
renderBucketName,
|
|
436
|
+
inputProps: params.inputProps,
|
|
437
|
+
serializedResolvedProps,
|
|
438
|
+
renderMetadata,
|
|
439
|
+
audioBitrate: params.audioBitrate,
|
|
440
|
+
logLevel: params.logLevel,
|
|
441
|
+
framesPerLambda,
|
|
442
|
+
binariesDirectory: null,
|
|
443
|
+
preferLossless: params.preferLossless,
|
|
444
|
+
compositionStart: realFrameRange[0],
|
|
445
|
+
outdir,
|
|
446
|
+
files: files.sort(),
|
|
447
|
+
overallProgress,
|
|
448
|
+
startTime,
|
|
449
|
+
providerSpecifics,
|
|
450
|
+
forcePathStyle: params.forcePathStyle,
|
|
451
|
+
insideFunctionSpecifics,
|
|
452
|
+
everyNthFrame: params.everyNthFrame,
|
|
453
|
+
frameRange: params.frameRange,
|
|
454
|
+
storageClass: params.storageClass,
|
|
455
|
+
requestHandler: null,
|
|
456
|
+
sampleRate: params.sampleRate,
|
|
373
457
|
});
|
|
374
|
-
}
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
renderId: params.renderId,
|
|
378
|
-
expectedBucketOwner: options.expectedBucketOwner,
|
|
379
|
-
numberOfFrames: comp.durationInFrames,
|
|
380
|
-
audioCodec: params.audioCodec,
|
|
381
|
-
chunkCount: chunks.length,
|
|
382
|
-
codec: params.codec,
|
|
383
|
-
customCredentials,
|
|
384
|
-
downloadBehavior: params.downloadBehavior,
|
|
385
|
-
fps,
|
|
386
|
-
key,
|
|
387
|
-
numberOfGifLoops: params.numberOfGifLoops,
|
|
388
|
-
privacy: params.privacy,
|
|
389
|
-
renderBucketName,
|
|
390
|
-
inputProps: params.inputProps,
|
|
391
|
-
serializedResolvedProps,
|
|
392
|
-
renderMetadata,
|
|
393
|
-
audioBitrate: params.audioBitrate,
|
|
394
|
-
logLevel: params.logLevel,
|
|
395
|
-
framesPerLambda,
|
|
396
|
-
binariesDirectory: null,
|
|
397
|
-
preferLossless: params.preferLossless,
|
|
398
|
-
compositionStart: realFrameRange[0],
|
|
399
|
-
outdir,
|
|
400
|
-
files: files.sort(),
|
|
401
|
-
overallProgress,
|
|
402
|
-
startTime,
|
|
403
|
-
providerSpecifics,
|
|
404
|
-
forcePathStyle: params.forcePathStyle,
|
|
405
|
-
insideFunctionSpecifics,
|
|
406
|
-
everyNthFrame: params.everyNthFrame,
|
|
407
|
-
frameRange: params.frameRange,
|
|
408
|
-
storageClass: params.storageClass,
|
|
409
|
-
requestHandler: null,
|
|
410
|
-
sampleRate: params.sampleRate,
|
|
411
|
-
});
|
|
412
|
-
if (providerSpecifics.getRendererFunctionTransport(insideFunctionSpecifics.getCurrentRegionInFunction()) === 's3') {
|
|
458
|
+
}
|
|
459
|
+
if (!shouldRenderDirectly &&
|
|
460
|
+
providerSpecifics.getRendererFunctionTransport(insideFunctionSpecifics.getCurrentRegionInFunction()) === 's3') {
|
|
413
461
|
try {
|
|
414
462
|
const transportObjects = await providerSpecifics.listObjects({
|
|
415
463
|
bucketName: params.bucketName,
|
|
@@ -9,7 +9,7 @@ export type RequestContext = {
|
|
|
9
9
|
getRemainingTimeInMillis: () => number;
|
|
10
10
|
awsRequestId: string;
|
|
11
11
|
};
|
|
12
|
-
export declare const rendererHandler: <Provider extends CloudProvider<string, Record<string, unknown>, Record<string, unknown>, string, object>>({ onStream, options, params, providerSpecifics, requestContext, insideFunctionSpecifics, onMediaFiles, }: {
|
|
12
|
+
export declare const rendererHandler: <Provider extends CloudProvider<string, Record<string, unknown>, Record<string, unknown>, string, object>>({ onStream, options, params, providerSpecifics, requestContext, insideFunctionSpecifics, onMediaFiles, executionMode, }: {
|
|
13
13
|
params: ServerlessPayload<Provider>;
|
|
14
14
|
options: Options;
|
|
15
15
|
onStream: OnStream<Provider>;
|
|
@@ -22,5 +22,6 @@ export declare const rendererHandler: <Provider extends CloudProvider<string, Re
|
|
|
22
22
|
isAudioOnly: boolean;
|
|
23
23
|
completedAt: number;
|
|
24
24
|
}) => Promise<void>) | null;
|
|
25
|
+
executionMode: "direct" | "invoked";
|
|
25
26
|
}) => Promise<void>;
|
|
26
27
|
export {};
|
|
@@ -285,9 +285,9 @@ const renderHandler = async ({ params, options, logs, onStream, providerSpecific
|
|
|
285
285
|
streamTimer.end();
|
|
286
286
|
renderer_1.RenderInternals.Log.verbose({ indent: false, logLevel: params.logLevel }, 'Cleaning up and writing timings');
|
|
287
287
|
await Promise.all([
|
|
288
|
-
node_fs_1.default.promises.rm(videoOutputLocation, { recursive: true }),
|
|
288
|
+
node_fs_1.default.promises.rm(videoOutputLocation, { recursive: true, force: true }),
|
|
289
289
|
audioOutputLocation
|
|
290
|
-
? node_fs_1.default.promises.rm(audioOutputLocation, { recursive: true })
|
|
290
|
+
? node_fs_1.default.promises.rm(audioOutputLocation, { recursive: true, force: true })
|
|
291
291
|
: null,
|
|
292
292
|
node_fs_1.default.promises.rm(outputPath, { recursive: true }),
|
|
293
293
|
].filter(serverless_client_1.truthy));
|
|
@@ -295,7 +295,7 @@ const renderHandler = async ({ params, options, logs, onStream, providerSpecific
|
|
|
295
295
|
return {};
|
|
296
296
|
};
|
|
297
297
|
const ENABLE_SLOW_LEAK_DETECTION = false;
|
|
298
|
-
const rendererHandler = async ({ onStream, options, params, providerSpecifics, requestContext, insideFunctionSpecifics, onMediaFiles, }) => {
|
|
298
|
+
const rendererHandler = async ({ onStream, options, params, providerSpecifics, requestContext, insideFunctionSpecifics, onMediaFiles, executionMode, }) => {
|
|
299
299
|
if (params.type !== serverless_client_1.ServerlessRoutines.renderer) {
|
|
300
300
|
throw new Error('Params must be renderer');
|
|
301
301
|
}
|
|
@@ -374,7 +374,12 @@ const rendererHandler = async ({ onStream, options, params, providerSpecifics, r
|
|
|
374
374
|
}
|
|
375
375
|
finally {
|
|
376
376
|
stopCancellationPolling();
|
|
377
|
-
if (
|
|
377
|
+
if (executionMode === 'direct') {
|
|
378
|
+
if (!shouldKeepBrowserOpen && instance) {
|
|
379
|
+
await instance.instance.close({ silent: true });
|
|
380
|
+
}
|
|
381
|
+
}
|
|
382
|
+
else if (shouldKeepBrowserOpen && instance) {
|
|
378
383
|
insideFunctionSpecifics.forgetBrowserEventLoop({
|
|
379
384
|
logLevel: params.logLevel,
|
|
380
385
|
launchedBrowser: instance,
|
package/dist/inner-routine.js
CHANGED
|
@@ -159,6 +159,7 @@ const innerHandler = async ({ params, responseWriter, context, providerSpecifics
|
|
|
159
159
|
options: {
|
|
160
160
|
expectedBucketOwner: currentUserId,
|
|
161
161
|
getRemainingTimeInMillis: context.getRemainingTimeInMillis,
|
|
162
|
+
requestContext: context,
|
|
162
163
|
},
|
|
163
164
|
providerSpecifics,
|
|
164
165
|
insideFunctionSpecifics,
|
|
@@ -236,6 +237,7 @@ const innerHandler = async ({ params, responseWriter, context, providerSpecifics
|
|
|
236
237
|
});
|
|
237
238
|
},
|
|
238
239
|
onMediaFiles: (_a = s3Output === null || s3Output === void 0 ? void 0 : s3Output.uploadMediaAndComplete) !== null && _a !== void 0 ? _a : null,
|
|
240
|
+
executionMode: 'invoked',
|
|
239
241
|
requestContext: context,
|
|
240
242
|
providerSpecifics,
|
|
241
243
|
insideFunctionSpecifics,
|
package/dist/merge-chunks.js
CHANGED
|
@@ -1,14 +1,8 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
-
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
-
};
|
|
5
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
3
|
exports.mergeChunksAndFinishRender = void 0;
|
|
7
|
-
const fs_1 = __importDefault(require("fs"));
|
|
8
|
-
const serverless_client_1 = require("@remotion/serverless-client");
|
|
9
|
-
const cleanup_props_1 = require("./cleanup-props");
|
|
10
4
|
const concat_videos_1 = require("./concat-videos");
|
|
11
|
-
const
|
|
5
|
+
const finish_render_1 = require("./finish-render");
|
|
12
6
|
const mergeChunksAndFinishRender = async (options) => {
|
|
13
7
|
const onProgress = ({ frames: framesEncoded }) => {
|
|
14
8
|
options.overallProgress.setCombinedFrames(framesEncoded);
|
|
@@ -43,56 +37,27 @@ const mergeChunksAndFinishRender = async (options) => {
|
|
|
43
37
|
});
|
|
44
38
|
const encodingStop = Date.now();
|
|
45
39
|
options.overallProgress.setTimeToCombine(encodingStop - encodingStart);
|
|
46
|
-
const
|
|
47
|
-
const writeToBucket = options.insideFunctionSpecifics.timer(`Writing to bucket (${outputSize} bytes)`, options.logLevel);
|
|
48
|
-
await options.providerSpecifics.writeFile({
|
|
49
|
-
bucketName: options.renderBucketName,
|
|
50
|
-
key: options.key,
|
|
51
|
-
body: fs_1.default.createReadStream(outfile),
|
|
52
|
-
region: options.insideFunctionSpecifics.getCurrentRegionInFunction(),
|
|
53
|
-
privacy: options.privacy,
|
|
40
|
+
const postRenderData = await (0, finish_render_1.finishRender)({
|
|
54
41
|
expectedBucketOwner: options.expectedBucketOwner,
|
|
55
|
-
|
|
42
|
+
renderBucketName: options.renderBucketName,
|
|
56
43
|
customCredentials: options.customCredentials,
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
});
|
|
61
|
-
writeToBucket.end();
|
|
62
|
-
const errorExplanations = (0, serverless_client_1.inspectErrors)({
|
|
63
|
-
errors: options.overallProgress.get().errors,
|
|
64
|
-
});
|
|
65
|
-
const cleanupProm = (0, cleanup_props_1.cleanupProps)({
|
|
44
|
+
downloadBehavior: options.downloadBehavior,
|
|
45
|
+
key: options.key,
|
|
46
|
+
privacy: options.privacy,
|
|
66
47
|
inputProps: options.inputProps,
|
|
67
48
|
serializedResolvedProps: options.serializedResolvedProps,
|
|
49
|
+
renderMetadata: options.renderMetadata,
|
|
50
|
+
logLevel: options.logLevel,
|
|
51
|
+
overallProgress: options.overallProgress,
|
|
52
|
+
startTime: options.startTime,
|
|
68
53
|
providerSpecifics: options.providerSpecifics,
|
|
69
|
-
forcePathStyle: options.forcePathStyle,
|
|
70
54
|
insideFunctionSpecifics: options.insideFunctionSpecifics,
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
customCredentials: options.customCredentials,
|
|
76
|
-
renderMetadata: options.renderMetadata,
|
|
77
|
-
});
|
|
78
|
-
const postRenderData = (0, create_post_render_data_1.createPostRenderData)({
|
|
79
|
-
region: options.insideFunctionSpecifics.getCurrentRegionInFunction(),
|
|
80
|
-
memorySizeInMb: options.insideFunctionSpecifics.getCurrentMemorySizeInMb(),
|
|
81
|
-
renderMetadata: options.renderMetadata,
|
|
82
|
-
errorExplanations,
|
|
83
|
-
timeToDelete: (await cleanupProm).reduce((a, b) => Math.max(a, b), 0),
|
|
84
|
-
outputFile: {
|
|
85
|
-
sizeInBytes: outputSize,
|
|
86
|
-
url: outputUrl,
|
|
87
|
-
},
|
|
88
|
-
outputSize,
|
|
55
|
+
forcePathStyle: options.forcePathStyle,
|
|
56
|
+
storageClass: options.storageClass,
|
|
57
|
+
requestHandler: options.requestHandler,
|
|
58
|
+
outputFile: outfile,
|
|
89
59
|
timeToCombine: encodingStop - encodingStart,
|
|
90
|
-
overallProgress: options.overallProgress.get(),
|
|
91
|
-
timeToFinish: Date.now() - options.startTime,
|
|
92
|
-
providerSpecifics: options.providerSpecifics,
|
|
93
60
|
});
|
|
94
|
-
await options.overallProgress.setPostRenderData(postRenderData);
|
|
95
|
-
fs_1.default.unlinkSync(outfile);
|
|
96
61
|
await cleanupChunksProm;
|
|
97
62
|
return postRenderData;
|
|
98
63
|
};
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import type { ChromiumOptions, ResolvedFrameRange } from '@remotion/renderer';
|
|
2
|
+
import type { CloudProvider, ProviderSpecifics, ServerlessPayload, VideoConfig } from '@remotion/serverless-client';
|
|
3
|
+
import type { OnArtifactFromRenderer } from './artifact-registry';
|
|
4
|
+
import type { OverallProgressHelper } from './overall-render-progress';
|
|
5
|
+
import type { InsideFunctionSpecifics } from './provider-implementation';
|
|
6
|
+
export declare const renderWithSingleFunction: <Provider extends CloudProvider<string, Record<string, unknown>, Record<string, unknown>, string, object>>({ params, composition, serializedInputPropsWithCustomSchema, frameRange, browserInstance, chromiumOptions, overallProgress, onArtifact, providerSpecifics, insideFunctionSpecifics, }: {
|
|
7
|
+
params: ServerlessPayload<Provider>;
|
|
8
|
+
composition: VideoConfig;
|
|
9
|
+
serializedInputPropsWithCustomSchema: string;
|
|
10
|
+
frameRange: ResolvedFrameRange;
|
|
11
|
+
browserInstance: import("@remotion/renderer").HeadlessBrowser;
|
|
12
|
+
chromiumOptions: ChromiumOptions;
|
|
13
|
+
overallProgress: OverallProgressHelper<Provider>;
|
|
14
|
+
onArtifact: OnArtifactFromRenderer;
|
|
15
|
+
providerSpecifics: ProviderSpecifics<Provider>;
|
|
16
|
+
insideFunctionSpecifics: InsideFunctionSpecifics<Provider>;
|
|
17
|
+
}) => Promise<{
|
|
18
|
+
outputFile: string;
|
|
19
|
+
cleanup: () => Promise<void>;
|
|
20
|
+
}>;
|
|
@@ -0,0 +1,123 @@
|
|
|
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
|
+
exports.renderWithSingleFunction = void 0;
|
|
7
|
+
const node_fs_1 = __importDefault(require("node:fs"));
|
|
8
|
+
const node_path_1 = require("node:path");
|
|
9
|
+
const renderer_1 = require("@remotion/renderer");
|
|
10
|
+
const serverless_client_1 = require("@remotion/serverless-client");
|
|
11
|
+
const cancellation_polling_1 = require("./cancellation-polling");
|
|
12
|
+
const on_downloads_helpers_1 = require("./on-downloads-helpers");
|
|
13
|
+
const renderWithSingleFunction = async ({ params, composition, serializedInputPropsWithCustomSchema, frameRange, browserInstance, chromiumOptions, overallProgress, onArtifact, providerSpecifics, insideFunctionSpecifics, }) => {
|
|
14
|
+
var _a, _b, _c, _d, _e, _f;
|
|
15
|
+
if (params.type !== serverless_client_1.ServerlessRoutines.launch) {
|
|
16
|
+
throw new Error('Expected launch type');
|
|
17
|
+
}
|
|
18
|
+
const outputDirectory = renderer_1.RenderInternals.tmpDir('remotion-direct-render-');
|
|
19
|
+
const outputFile = (0, node_path_1.join)(outputDirectory, `output.${renderer_1.RenderInternals.getFileExtensionFromCodec(params.codec, params.audioCodec)}`);
|
|
20
|
+
const cleanup = () => node_fs_1.default.promises.rm(outputDirectory, { recursive: true, force: true });
|
|
21
|
+
const frameCount = renderer_1.RenderInternals.getFramesToRender(frameRange, params.everyNthFrame).length;
|
|
22
|
+
const startedAt = Date.now();
|
|
23
|
+
const { cancel, cancelSignal } = (0, renderer_1.makeCancelSignal)();
|
|
24
|
+
const stopCancellationPolling = params.enableCancellation
|
|
25
|
+
? (0, cancellation_polling_1.startCancellationPolling)({
|
|
26
|
+
bucketName: params.bucketName,
|
|
27
|
+
renderId: params.renderId,
|
|
28
|
+
region: insideFunctionSpecifics.getCurrentRegionInFunction(),
|
|
29
|
+
providerSpecifics,
|
|
30
|
+
forcePathStyle: params.forcePathStyle,
|
|
31
|
+
intervalInMilliseconds: 1000,
|
|
32
|
+
logLevel: params.logLevel,
|
|
33
|
+
onCancelled: cancel,
|
|
34
|
+
})
|
|
35
|
+
: () => undefined;
|
|
36
|
+
try {
|
|
37
|
+
await (0, renderer_1.renderMedia)({
|
|
38
|
+
composition,
|
|
39
|
+
serveUrl: params.serveUrl,
|
|
40
|
+
codec: params.codec,
|
|
41
|
+
outputLocation: outputFile,
|
|
42
|
+
inputProps: JSON.parse(serializedInputPropsWithCustomSchema),
|
|
43
|
+
imageFormat: params.imageFormat,
|
|
44
|
+
frameRange,
|
|
45
|
+
concurrency: params.concurrencyPerFunction,
|
|
46
|
+
puppeteerInstance: browserInstance,
|
|
47
|
+
jpegQuality: (_a = params.jpegQuality) !== null && _a !== void 0 ? _a : renderer_1.RenderInternals.DEFAULT_JPEG_QUALITY,
|
|
48
|
+
envVariables: (_b = params.envVariables) !== null && _b !== void 0 ? _b : {},
|
|
49
|
+
logLevel: params.logLevel,
|
|
50
|
+
crf: params.crf,
|
|
51
|
+
pixelFormat: (_c = params.pixelFormat) !== null && _c !== void 0 ? _c : undefined,
|
|
52
|
+
proResProfile: (_d = params.proResProfile) !== null && _d !== void 0 ? _d : undefined,
|
|
53
|
+
x264Preset: params.x264Preset,
|
|
54
|
+
gopSize: (_e = params.gopSize) !== null && _e !== void 0 ? _e : null,
|
|
55
|
+
onDownload: (0, on_downloads_helpers_1.onDownloadsHelper)(params.logLevel),
|
|
56
|
+
overwrite: true,
|
|
57
|
+
chromiumOptions,
|
|
58
|
+
scale: params.scale,
|
|
59
|
+
timeoutInMilliseconds: params.timeoutInMilliseconds,
|
|
60
|
+
everyNthFrame: params.everyNthFrame,
|
|
61
|
+
numberOfGifLoops: params.numberOfGifLoops,
|
|
62
|
+
muted: params.muted,
|
|
63
|
+
enforceAudioTrack: true,
|
|
64
|
+
audioBitrate: params.audioBitrate,
|
|
65
|
+
videoBitrate: params.videoBitrate,
|
|
66
|
+
encodingBufferSize: params.encodingBufferSize,
|
|
67
|
+
encodingMaxRate: params.encodingMaxRate,
|
|
68
|
+
audioCodec: params.audioCodec,
|
|
69
|
+
preferLossless: params.preferLossless,
|
|
70
|
+
browserExecutable: providerSpecifics.getChromiumPath(),
|
|
71
|
+
cancelSignal: params.enableCancellation ? cancelSignal : undefined,
|
|
72
|
+
disallowParallelEncoding: false,
|
|
73
|
+
offthreadVideoCacheSizeInBytes: params.offthreadVideoCacheSizeInBytes,
|
|
74
|
+
colorSpace: (_f = params.colorSpace) !== null && _f !== void 0 ? _f : undefined,
|
|
75
|
+
repro: false,
|
|
76
|
+
binariesDirectory: null,
|
|
77
|
+
onBrowserDownload: () => {
|
|
78
|
+
throw new Error('Should not download a browser in Lambda');
|
|
79
|
+
},
|
|
80
|
+
onArtifact: (artifact) => {
|
|
81
|
+
const registration = onArtifact({
|
|
82
|
+
artifact,
|
|
83
|
+
chunk: 0,
|
|
84
|
+
attempt: 1,
|
|
85
|
+
});
|
|
86
|
+
if (registration.type === 'conflict') {
|
|
87
|
+
throw new Error(`The artifact filename ${artifact.filename} was emitted more than once. https://remotion.dev/docs/artifacts`);
|
|
88
|
+
}
|
|
89
|
+
},
|
|
90
|
+
metadata: params.metadata,
|
|
91
|
+
hardwareAcceleration: 'disable',
|
|
92
|
+
chromeMode: 'headless-shell',
|
|
93
|
+
offthreadVideoThreads: params.offthreadVideoThreads,
|
|
94
|
+
mediaCacheSizeInBytes: params.mediaCacheSizeInBytes,
|
|
95
|
+
licenseKey: null,
|
|
96
|
+
isProduction: false,
|
|
97
|
+
sampleRate: params.sampleRate,
|
|
98
|
+
onProgress: ({ renderedFrames, encodedFrames }) => {
|
|
99
|
+
overallProgress.setFrames({
|
|
100
|
+
index: 0,
|
|
101
|
+
rendered: renderedFrames,
|
|
102
|
+
encoded: encodedFrames,
|
|
103
|
+
});
|
|
104
|
+
},
|
|
105
|
+
});
|
|
106
|
+
overallProgress.setFrames({
|
|
107
|
+
index: 0,
|
|
108
|
+
rendered: frameCount,
|
|
109
|
+
encoded: frameCount,
|
|
110
|
+
});
|
|
111
|
+
overallProgress.addChunkCompleted(0, startedAt, Date.now());
|
|
112
|
+
overallProgress.setCombinedFrames(frameCount);
|
|
113
|
+
return { outputFile, cleanup };
|
|
114
|
+
}
|
|
115
|
+
catch (err) {
|
|
116
|
+
await cleanup();
|
|
117
|
+
throw err;
|
|
118
|
+
}
|
|
119
|
+
finally {
|
|
120
|
+
stopCancellationPolling();
|
|
121
|
+
}
|
|
122
|
+
};
|
|
123
|
+
exports.renderWithSingleFunction = renderWithSingleFunction;
|
package/package.json
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
"url": "https://github.com/remotion-dev/remotion/tree/main/packages/serverless"
|
|
4
4
|
},
|
|
5
5
|
"name": "@remotion/serverless",
|
|
6
|
-
"version": "4.0.
|
|
6
|
+
"version": "4.0.518",
|
|
7
7
|
"description": "A runtime for distributed rendering",
|
|
8
8
|
"main": "dist",
|
|
9
9
|
"scripts": {
|
|
@@ -23,13 +23,13 @@
|
|
|
23
23
|
"access": "public"
|
|
24
24
|
},
|
|
25
25
|
"dependencies": {
|
|
26
|
-
"@remotion/renderer": "4.0.
|
|
27
|
-
"@remotion/bundler": "4.0.
|
|
28
|
-
"@remotion/licensing": "4.0.
|
|
29
|
-
"@remotion/serverless-client": "4.0.
|
|
26
|
+
"@remotion/renderer": "4.0.518",
|
|
27
|
+
"@remotion/bundler": "4.0.518",
|
|
28
|
+
"@remotion/licensing": "4.0.518",
|
|
29
|
+
"@remotion/serverless-client": "4.0.518"
|
|
30
30
|
},
|
|
31
31
|
"devDependencies": {
|
|
32
|
-
"@remotion/eslint-config-internal": "4.0.
|
|
32
|
+
"@remotion/eslint-config-internal": "4.0.518",
|
|
33
33
|
"eslint": "9.19.0",
|
|
34
34
|
"@typescript/native-preview": "7.0.0-dev.20260217.1"
|
|
35
35
|
},
|