@remotion/cloudrun 4.0.21 → 4.0.23
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/.turbo/turbo-build.log +3 -3
- package/dist/api/render-media-on-cloudrun.d.ts +6 -3
- package/dist/api/render-media-on-cloudrun.js +26 -9
- package/dist/api/render-still-on-cloudrun.d.ts +5 -4
- package/dist/api/render-still-on-cloudrun.js +52 -3
- package/dist/cli/commands/render/index.js +7 -52
- package/dist/cli/commands/render/renderMedia.d.ts +2 -0
- package/dist/cli/commands/render/renderMedia.js +156 -0
- package/dist/cli/commands/render/renderStill.d.ts +2 -0
- package/dist/cli/commands/render/renderStill.js +123 -0
- package/dist/cli/commands/still.js +24 -16
- package/dist/cli/helpers/cloudrun-crash-logs.d.ts +2 -0
- package/dist/cli/helpers/cloudrun-crash-logs.js +57 -0
- package/dist/cli/index.js +18 -2
- package/dist/functions/helpers/get-composition-from-body.js +1 -0
- package/dist/functions/helpers/payloads.d.ts +35 -23
- package/dist/functions/helpers/payloads.js +10 -5
- package/dist/functions/helpers/write-cloudrun-error.d.ts +12 -0
- package/dist/functions/helpers/write-cloudrun-error.js +18 -0
- package/dist/functions/index.js +6 -8
- package/dist/functions/render-media-single-thread.js +107 -88
- package/dist/functions/render-still-single-thread.js +82 -65
- package/dist/shared/read-dir.js +4 -2
- package/package.json +7 -7
|
@@ -6,98 +6,117 @@ const renderer_1 = require("@remotion/renderer");
|
|
|
6
6
|
const remotion_1 = require("remotion");
|
|
7
7
|
const random_hash_1 = require("../shared/random-hash");
|
|
8
8
|
const get_composition_from_body_1 = require("./helpers/get-composition-from-body");
|
|
9
|
+
const write_cloudrun_error_1 = require("./helpers/write-cloudrun-error");
|
|
9
10
|
const renderMediaSingleThread = async (body, res) => {
|
|
10
|
-
var _a, _b, _c, _d, _e, _f, _g;
|
|
11
|
+
var _a, _b, _c, _d, _e, _f, _g, _h;
|
|
11
12
|
if (body.type !== 'media') {
|
|
12
13
|
throw new Error('expected type media');
|
|
13
14
|
}
|
|
14
|
-
const composition = await (0, get_composition_from_body_1.getCompositionFromBody)(body);
|
|
15
|
-
const defaultOutName = `out.${renderer_1.RenderInternals.getFileExtensionFromCodec(body.codec, body.audioCodec)}`;
|
|
16
|
-
const tempFilePath = `/tmp/${defaultOutName}`;
|
|
17
15
|
const renderId = (0, random_hash_1.randomHash)({ randomInTests: true });
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
16
|
+
try {
|
|
17
|
+
const composition = await (0, get_composition_from_body_1.getCompositionFromBody)(body);
|
|
18
|
+
const defaultOutName = `out.${renderer_1.RenderInternals.getFileExtensionFromCodec(body.codec, body.audioCodec)}`;
|
|
19
|
+
const tempFilePath = `/tmp/${defaultOutName}`;
|
|
20
|
+
let previousProgress = 2;
|
|
21
|
+
const onProgress = ({ progress }) => {
|
|
22
|
+
if (previousProgress !== progress) {
|
|
23
|
+
res.write(JSON.stringify({ onProgress: progress }) + '\n');
|
|
24
|
+
previousProgress = progress;
|
|
25
|
+
}
|
|
26
|
+
};
|
|
27
|
+
res.writeHead(200, { 'Content-Type': 'text/html' });
|
|
28
|
+
const actualChromiumOptions = {
|
|
29
|
+
...body.chromiumOptions,
|
|
30
|
+
// Override the `null` value, which might come from CLI with swANGLE
|
|
31
|
+
gl: (_b = (_a = body.chromiumOptions) === null || _a === void 0 ? void 0 : _a.gl) !== null && _b !== void 0 ? _b : 'swangle',
|
|
32
|
+
};
|
|
33
|
+
await renderer_1.RenderInternals.internalRenderMedia({
|
|
34
|
+
composition: {
|
|
35
|
+
...composition,
|
|
36
|
+
height: (_c = body.forceHeight) !== null && _c !== void 0 ? _c : composition.height,
|
|
37
|
+
width: (_d = body.forceWidth) !== null && _d !== void 0 ? _d : composition.width,
|
|
38
|
+
},
|
|
39
|
+
serveUrl: body.serveUrl,
|
|
40
|
+
codec: body.codec,
|
|
41
|
+
outputLocation: tempFilePath,
|
|
42
|
+
serializedInputPropsWithCustomSchema: body.serializedInputPropsWithCustomSchema,
|
|
43
|
+
serializedResolvedPropsWithCustomSchema: remotion_1.Internals.serializeJSONWithDate({
|
|
44
|
+
data: composition.props,
|
|
45
|
+
indent: undefined,
|
|
46
|
+
staticBase: null,
|
|
47
|
+
}).serializedString,
|
|
48
|
+
jpegQuality: body.jpegQuality,
|
|
49
|
+
audioCodec: body.audioCodec,
|
|
50
|
+
audioBitrate: body.audioBitrate,
|
|
51
|
+
videoBitrate: body.videoBitrate,
|
|
52
|
+
crf: body.crf,
|
|
53
|
+
pixelFormat: body.pixelFormat,
|
|
54
|
+
imageFormat: body.imageFormat,
|
|
55
|
+
scale: body.scale,
|
|
56
|
+
proResProfile: (_e = body.proResProfile) !== null && _e !== void 0 ? _e : undefined,
|
|
57
|
+
x264Preset: (_f = body.x264Preset) !== null && _f !== void 0 ? _f : undefined,
|
|
58
|
+
everyNthFrame: body.everyNthFrame,
|
|
59
|
+
numberOfGifLoops: body.numberOfGifLoops,
|
|
60
|
+
onProgress,
|
|
61
|
+
frameRange: body.frameRange,
|
|
62
|
+
envVariables: body.envVariables,
|
|
63
|
+
chromiumOptions: actualChromiumOptions,
|
|
64
|
+
muted: body.muted,
|
|
65
|
+
logLevel: body.logLevel,
|
|
66
|
+
browserExecutable: null,
|
|
67
|
+
timeoutInMilliseconds: body.delayRenderTimeoutInMilliseconds,
|
|
68
|
+
cancelSignal: undefined,
|
|
69
|
+
concurrency: (_g = body.concurrency) !== null && _g !== void 0 ? _g : '100%',
|
|
70
|
+
disallowParallelEncoding: false,
|
|
71
|
+
enforceAudioTrack: body.enforceAudioTrack,
|
|
72
|
+
ffmpegOverride: undefined,
|
|
73
|
+
indent: false,
|
|
74
|
+
onBrowserLog: null,
|
|
75
|
+
onCtrlCExit: () => undefined,
|
|
76
|
+
onDownload: () => undefined,
|
|
77
|
+
onStart: () => undefined,
|
|
78
|
+
overwrite: true,
|
|
79
|
+
port: null,
|
|
80
|
+
preferLossless: body.preferLossless,
|
|
81
|
+
puppeteerInstance: undefined,
|
|
82
|
+
server: undefined,
|
|
83
|
+
offthreadVideoCacheSizeInBytes: body.offthreadVideoCacheSizeInBytes,
|
|
84
|
+
});
|
|
85
|
+
const storage = new storage_1.Storage();
|
|
86
|
+
const publicUpload = body.privacy === 'public' || !body.privacy;
|
|
87
|
+
const uploadedResponse = await storage
|
|
88
|
+
.bucket(body.outputBucket)
|
|
89
|
+
.upload(tempFilePath, {
|
|
90
|
+
destination: `renders/${renderId}/${(_h = body.outName) !== null && _h !== void 0 ? _h : defaultOutName}`,
|
|
91
|
+
predefinedAcl: publicUpload ? 'publicRead' : 'projectPrivate',
|
|
92
|
+
});
|
|
93
|
+
const uploadedFile = uploadedResponse[0];
|
|
94
|
+
const renderMetadata = await uploadedFile.getMetadata();
|
|
95
|
+
const responseData = {
|
|
96
|
+
type: 'success',
|
|
97
|
+
publicUrl: publicUpload ? uploadedFile.publicUrl() : null,
|
|
98
|
+
cloudStorageUri: uploadedFile.cloudStorageURI.href,
|
|
99
|
+
size: renderMetadata[0].size,
|
|
100
|
+
bucketName: body.outputBucket,
|
|
101
|
+
renderId,
|
|
102
|
+
privacy: publicUpload ? 'public-read' : 'project-private',
|
|
103
|
+
};
|
|
104
|
+
renderer_1.RenderInternals.Log.info('Render Completed:', responseData);
|
|
105
|
+
res.end(JSON.stringify({ response: responseData }));
|
|
106
|
+
}
|
|
107
|
+
catch (err) {
|
|
108
|
+
await (0, write_cloudrun_error_1.writeCloudrunError)({
|
|
109
|
+
bucketName: body.outputBucket,
|
|
110
|
+
renderId,
|
|
111
|
+
errorInfo: {
|
|
112
|
+
name: err.name,
|
|
113
|
+
message: err.message,
|
|
114
|
+
stack: err.stack,
|
|
115
|
+
type: 'renderer',
|
|
116
|
+
},
|
|
117
|
+
publicUpload: body.privacy === 'public' || !body.privacy,
|
|
118
|
+
});
|
|
119
|
+
throw err;
|
|
120
|
+
}
|
|
102
121
|
};
|
|
103
122
|
exports.renderMediaSingleThread = renderMediaSingleThread;
|
|
@@ -7,76 +7,93 @@ const remotion_1 = require("remotion");
|
|
|
7
7
|
const log_1 = require("../cli/log");
|
|
8
8
|
const random_hash_1 = require("../shared/random-hash");
|
|
9
9
|
const get_composition_from_body_1 = require("./helpers/get-composition-from-body");
|
|
10
|
+
const write_cloudrun_error_1 = require("./helpers/write-cloudrun-error");
|
|
10
11
|
const renderStillSingleThread = async (body, res) => {
|
|
11
12
|
var _a, _b, _c, _d, _e, _f;
|
|
12
13
|
if (body.type !== 'still') {
|
|
13
14
|
throw new Error('expected type still');
|
|
14
15
|
}
|
|
15
|
-
log_1.Log.verbose('Rendering still frame', body);
|
|
16
|
-
const composition = await (0, get_composition_from_body_1.getCompositionFromBody)(body);
|
|
17
|
-
log_1.Log.verbose('Composition loaded', composition);
|
|
18
|
-
const tempFilePath = '/tmp/still.png';
|
|
19
16
|
const renderId = (0, random_hash_1.randomHash)({ randomInTests: true });
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
17
|
+
try {
|
|
18
|
+
log_1.Log.verbose('Rendering still frame', body);
|
|
19
|
+
const composition = await (0, get_composition_from_body_1.getCompositionFromBody)(body);
|
|
20
|
+
log_1.Log.verbose('Composition loaded', composition);
|
|
21
|
+
const tempFilePath = '/tmp/still.png';
|
|
22
|
+
const actualChromiumOptions = {
|
|
23
|
+
...body.chromiumOptions,
|
|
24
|
+
// Override the `null` value, which might come from CLI with swANGLE
|
|
25
|
+
gl: (_b = (_a = body.chromiumOptions) === null || _a === void 0 ? void 0 : _a.gl) !== null && _b !== void 0 ? _b : 'swangle',
|
|
26
|
+
};
|
|
27
|
+
await renderer_1.RenderInternals.internalRenderStill({
|
|
28
|
+
composition: {
|
|
29
|
+
...composition,
|
|
30
|
+
height: (_c = body.forceHeight) !== null && _c !== void 0 ? _c : composition.height,
|
|
31
|
+
width: (_d = body.forceWidth) !== null && _d !== void 0 ? _d : composition.width,
|
|
32
|
+
},
|
|
33
|
+
serveUrl: body.serveUrl,
|
|
34
|
+
output: tempFilePath,
|
|
35
|
+
serializedInputPropsWithCustomSchema: body.serializedInputPropsWithCustomSchema,
|
|
36
|
+
serializedResolvedPropsWithCustomSchema: remotion_1.Internals.serializeJSONWithDate({
|
|
37
|
+
data: composition.props,
|
|
38
|
+
indent: undefined,
|
|
39
|
+
staticBase: null,
|
|
40
|
+
}).serializedString,
|
|
41
|
+
jpegQuality: (_e = body.jpegQuality) !== null && _e !== void 0 ? _e : renderer_1.RenderInternals.DEFAULT_JPEG_QUALITY,
|
|
42
|
+
imageFormat: body.imageFormat,
|
|
43
|
+
scale: body.scale,
|
|
44
|
+
envVariables: body.envVariables,
|
|
45
|
+
chromiumOptions: actualChromiumOptions,
|
|
46
|
+
frame: body.frame,
|
|
47
|
+
logLevel: body.logLevel,
|
|
48
|
+
browserExecutable: null,
|
|
49
|
+
cancelSignal: null,
|
|
50
|
+
indent: false,
|
|
51
|
+
timeoutInMilliseconds: body.delayRenderTimeoutInMilliseconds,
|
|
52
|
+
onBrowserLog: null,
|
|
53
|
+
onDownload: null,
|
|
54
|
+
overwrite: true,
|
|
55
|
+
port: null,
|
|
56
|
+
puppeteerInstance: null,
|
|
57
|
+
server: undefined,
|
|
58
|
+
offthreadVideoCacheSizeInBytes: body.offthreadVideoCacheSizeInBytes,
|
|
59
|
+
});
|
|
60
|
+
log_1.Log.info('Still rendered');
|
|
61
|
+
const storage = new storage_1.Storage();
|
|
62
|
+
const publicUpload = body.privacy === 'public' || !body.privacy;
|
|
63
|
+
const uploadedResponse = await storage
|
|
64
|
+
.bucket(body.outputBucket)
|
|
65
|
+
.upload(tempFilePath, {
|
|
66
|
+
destination: `renders/${renderId}/${(_f = body.outName) !== null && _f !== void 0 ? _f : 'out.png'}`,
|
|
67
|
+
predefinedAcl: publicUpload ? 'publicRead' : 'projectPrivate',
|
|
68
|
+
});
|
|
69
|
+
log_1.Log.info('Still uploaded');
|
|
70
|
+
const uploadedFile = uploadedResponse[0];
|
|
71
|
+
const renderMetadata = await uploadedFile.getMetadata();
|
|
72
|
+
const responseData = {
|
|
73
|
+
publicUrl: uploadedFile.publicUrl(),
|
|
74
|
+
cloudStorageUri: uploadedFile.cloudStorageURI.href,
|
|
75
|
+
size: renderMetadata[0].size,
|
|
76
|
+
bucketName: body.outputBucket,
|
|
77
|
+
renderId,
|
|
78
|
+
type: 'success',
|
|
79
|
+
privacy: publicUpload ? 'public-read' : 'project-private',
|
|
80
|
+
};
|
|
81
|
+
renderer_1.RenderInternals.Log.info('Render Completed:', responseData);
|
|
82
|
+
res.end(JSON.stringify({ response: responseData }));
|
|
83
|
+
}
|
|
84
|
+
catch (err) {
|
|
85
|
+
await (0, write_cloudrun_error_1.writeCloudrunError)({
|
|
86
|
+
bucketName: body.outputBucket,
|
|
87
|
+
renderId,
|
|
88
|
+
errorInfo: {
|
|
89
|
+
name: err.name,
|
|
90
|
+
message: err.message,
|
|
91
|
+
stack: err.stack,
|
|
92
|
+
type: 'renderer',
|
|
93
|
+
},
|
|
94
|
+
publicUpload: body.privacy === 'public' || !body.privacy,
|
|
95
|
+
});
|
|
96
|
+
throw err;
|
|
97
|
+
}
|
|
81
98
|
};
|
|
82
99
|
exports.renderStillSingleThread = renderStillSingleThread;
|
package/dist/shared/read-dir.js
CHANGED
|
@@ -45,10 +45,12 @@ async function readDirectory({ dir, etags, originalDir, }) {
|
|
|
45
45
|
// eslint-disable-next-line no-lonely-if
|
|
46
46
|
if (fs.lstatSync(filePath).isSymbolicLink()) {
|
|
47
47
|
const realPath = fs.realpathSync(filePath);
|
|
48
|
-
etags[path.relative(originalDir, filePath)] =
|
|
48
|
+
etags[path.relative(originalDir, filePath)] =
|
|
49
|
+
await (0, get_etag_1.getEtagOfFile)(realPath);
|
|
49
50
|
}
|
|
50
51
|
else {
|
|
51
|
-
etags[path.relative(originalDir, filePath)] =
|
|
52
|
+
etags[path.relative(originalDir, filePath)] =
|
|
53
|
+
await (0, get_etag_1.getEtagOfFile)(filePath);
|
|
52
54
|
}
|
|
53
55
|
}
|
|
54
56
|
// Return the list of files with their etags and file names
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@remotion/cloudrun",
|
|
3
|
-
"version": "4.0.
|
|
3
|
+
"version": "4.0.23",
|
|
4
4
|
"description": "GCP Cloud Run alternative to lambda rendering",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"dependencies": {
|
|
@@ -12,21 +12,21 @@
|
|
|
12
12
|
"@google-cloud/logging": "^10.5.0",
|
|
13
13
|
"google-auth-library": "^8.7.0",
|
|
14
14
|
"zod": "^3.21.4",
|
|
15
|
-
"@remotion/bundler": "4.0.
|
|
16
|
-
"@remotion/
|
|
17
|
-
"@remotion/
|
|
18
|
-
"remotion": "4.0.
|
|
15
|
+
"@remotion/bundler": "4.0.23",
|
|
16
|
+
"@remotion/renderer": "4.0.23",
|
|
17
|
+
"@remotion/cli": "4.0.23",
|
|
18
|
+
"remotion": "4.0.23"
|
|
19
19
|
},
|
|
20
20
|
"devDependencies": {
|
|
21
21
|
"@jonny/eslint-config": "3.0.266",
|
|
22
22
|
"@types/node": "^18.11.2",
|
|
23
23
|
"@types/minimist": "1.2.2",
|
|
24
24
|
"eslint": "8.42.0",
|
|
25
|
-
"prettier": "
|
|
25
|
+
"prettier": "3.0.2",
|
|
26
26
|
"prettier-plugin-organize-imports": "^3.2.2",
|
|
27
27
|
"ts-node": "^10.8.0",
|
|
28
28
|
"vitest": "0.24.3",
|
|
29
|
-
"@remotion/compositor-linux-x64-gnu": "4.0.
|
|
29
|
+
"@remotion/compositor-linux-x64-gnu": "4.0.23"
|
|
30
30
|
},
|
|
31
31
|
"exports": {
|
|
32
32
|
"./package.json": "./package.json",
|