@remotion/cloudrun 4.0.246 → 4.0.248

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,6 +1,6 @@
1
1
 
2
2
  
3
- > @remotion/cloudrun@4.0.245 make /Users/jonathanburger/remotion/packages/cloudrun
3
+ > @remotion/cloudrun@4.0.247 make /Users/jonathanburger/remotion/packages/cloudrun
4
4
  > tsc -d && bun build.ts
5
5
 
6
- [6.63ms] Made reproducible build with gtar
6
+ [9.50ms] Made reproducible build with gtar
@@ -1,6 +1,7 @@
1
1
  import type { AudioCodec, ChromiumOptions, FrameRange, LogLevel, PixelFormat, ProResProfile, ToOptions, VideoImageFormat } from '@remotion/renderer';
2
2
  import type { BrowserSafeApis } from '@remotion/renderer/client';
3
- import type { CloudRunCrashResponse, DownloadBehavior, RenderMediaOnCloudrunOutput } from '../functions/helpers/payloads';
3
+ import type { z } from 'zod';
4
+ import type { CloudRunCrashResponse, CloudRunPayload, DownloadBehavior, RenderMediaOnCloudrunOutput } from '../functions/helpers/payloads';
4
5
  import type { GcpRegion } from '../pricing/gcp-regions';
5
6
  import type { CloudrunCodec } from '../shared/validate-gcp-codec';
6
7
  type InternalRenderMediaOnCloudrun = {
@@ -32,6 +33,8 @@ type InternalRenderMediaOnCloudrun = {
32
33
  logLevel: LogLevel;
33
34
  downloadBehavior: DownloadBehavior;
34
35
  metadata?: Record<string, string> | null;
36
+ renderIdOverride: z.infer<typeof CloudRunPayload>['renderIdOverride'];
37
+ renderStatusWebhook: z.infer<typeof CloudRunPayload>['renderStatusWebhook'];
35
38
  } & Partial<ToOptions<typeof BrowserSafeApis.optionsMap.renderMediaOnCloudRun>>;
36
39
  export type RenderMediaOnCloudrunInput = {
37
40
  cloudRunUrl?: string;
@@ -44,6 +47,7 @@ export type RenderMediaOnCloudrunInput = {
44
47
  forceBucketName?: string;
45
48
  outName?: string;
46
49
  updateRenderProgress?: (progress: number, error?: boolean) => void;
50
+ renderId: string | undefined;
47
51
  codec: CloudrunCodec;
48
52
  audioCodec?: AudioCodec;
49
53
  encodingMaxRate?: string | null;
@@ -61,8 +65,10 @@ export type RenderMediaOnCloudrunInput = {
61
65
  preferLossless?: boolean;
62
66
  downloadBehavior?: DownloadBehavior;
63
67
  metadata?: Record<string, string> | null;
68
+ renderIdOverride?: z.infer<typeof CloudRunPayload>['renderIdOverride'];
69
+ renderStatusWebhook?: z.infer<typeof CloudRunPayload>['renderStatusWebhook'];
64
70
  } & Partial<ToOptions<typeof BrowserSafeApis.optionsMap.renderMediaOnCloudRun>>;
65
- declare const internalRenderMediaOnCloudrunRaw: ({ cloudRunUrl, serviceName, region, serveUrl, composition, inputProps, codec, forceBucketName, privacy, outName, updateRenderProgress, jpegQuality, audioCodec, audioBitrate, videoBitrate, encodingMaxRate, encodingBufferSize, proResProfile, x264Preset, crf, pixelFormat, imageFormat, scale, everyNthFrame, numberOfGifLoops, frameRange, envVariables, chromiumOptions, muted, forceWidth, forceHeight, logLevel, delayRenderTimeoutInMilliseconds, concurrency, enforceAudioTrack, preferLossless, offthreadVideoCacheSizeInBytes, colorSpace, downloadBehavior, metadata, }: InternalRenderMediaOnCloudrun) => Promise<RenderMediaOnCloudrunOutput | CloudRunCrashResponse>;
71
+ declare const internalRenderMediaOnCloudrunRaw: ({ cloudRunUrl, serviceName, region, serveUrl, composition, inputProps, codec, forceBucketName, privacy, outName, updateRenderProgress, renderIdOverride, renderStatusWebhook, jpegQuality, audioCodec, audioBitrate, videoBitrate, encodingMaxRate, encodingBufferSize, proResProfile, x264Preset, crf, pixelFormat, imageFormat, scale, everyNthFrame, numberOfGifLoops, frameRange, envVariables, chromiumOptions, muted, forceWidth, forceHeight, logLevel, delayRenderTimeoutInMilliseconds, concurrency, enforceAudioTrack, preferLossless, offthreadVideoCacheSizeInBytes, colorSpace, downloadBehavior, metadata, }: InternalRenderMediaOnCloudrun) => Promise<RenderMediaOnCloudrunOutput | CloudRunCrashResponse>;
66
72
  export declare const internalRenderMediaOnCloudrun: typeof internalRenderMediaOnCloudrunRaw;
67
- export declare const renderMediaOnCloudrun: ({ cloudRunUrl, serviceName, region, serveUrl, composition, inputProps, codec, forceBucketName, privacy, outName, updateRenderProgress, jpegQuality, audioCodec, audioBitrate, videoBitrate, encodingMaxRate, encodingBufferSize, proResProfile, x264Preset, crf, pixelFormat, imageFormat, scale, everyNthFrame, numberOfGifLoops, frameRange, envVariables, chromiumOptions, muted, forceWidth, forceHeight, logLevel, delayRenderTimeoutInMilliseconds, concurrency, enforceAudioTrack, preferLossless, offthreadVideoCacheSizeInBytes, colorSpace, downloadBehavior, metadata, }: RenderMediaOnCloudrunInput) => Promise<RenderMediaOnCloudrunOutput | CloudRunCrashResponse>;
73
+ export declare const renderMediaOnCloudrun: ({ cloudRunUrl, serviceName, region, serveUrl, composition, inputProps, codec, forceBucketName, privacy, outName, updateRenderProgress, jpegQuality, audioCodec, audioBitrate, videoBitrate, encodingMaxRate, encodingBufferSize, proResProfile, x264Preset, crf, pixelFormat, imageFormat, scale, everyNthFrame, numberOfGifLoops, frameRange, envVariables, chromiumOptions, muted, forceWidth, forceHeight, logLevel, delayRenderTimeoutInMilliseconds, concurrency, enforceAudioTrack, preferLossless, offthreadVideoCacheSizeInBytes, colorSpace, downloadBehavior, metadata, renderIdOverride, renderStatusWebhook, }: RenderMediaOnCloudrunInput) => Promise<RenderMediaOnCloudrunOutput | CloudRunCrashResponse>;
68
74
  export {};
@@ -10,7 +10,7 @@ const validate_serveurl_1 = require("../shared/validate-serveurl");
10
10
  const get_or_create_bucket_1 = require("./get-or-create-bucket");
11
11
  const get_auth_client_for_url_1 = require("./helpers/get-auth-client-for-url");
12
12
  const get_cloudrun_endpoint_1 = require("./helpers/get-cloudrun-endpoint");
13
- const internalRenderMediaOnCloudrunRaw = async ({ cloudRunUrl, serviceName, region, serveUrl, composition, inputProps, codec, forceBucketName, privacy, outName, updateRenderProgress, jpegQuality, audioCodec, audioBitrate, videoBitrate, encodingMaxRate, encodingBufferSize, proResProfile, x264Preset, crf, pixelFormat, imageFormat, scale, everyNthFrame, numberOfGifLoops, frameRange, envVariables, chromiumOptions, muted, forceWidth, forceHeight, logLevel, delayRenderTimeoutInMilliseconds, concurrency, enforceAudioTrack, preferLossless, offthreadVideoCacheSizeInBytes, colorSpace, downloadBehavior, metadata, }) => {
13
+ const internalRenderMediaOnCloudrunRaw = async ({ cloudRunUrl, serviceName, region, serveUrl, composition, inputProps, codec, forceBucketName, privacy, outName, updateRenderProgress, renderIdOverride, renderStatusWebhook, jpegQuality, audioCodec, audioBitrate, videoBitrate, encodingMaxRate, encodingBufferSize, proResProfile, x264Preset, crf, pixelFormat, imageFormat, scale, everyNthFrame, numberOfGifLoops, frameRange, envVariables, chromiumOptions, muted, forceWidth, forceHeight, logLevel, delayRenderTimeoutInMilliseconds, concurrency, enforceAudioTrack, preferLossless, offthreadVideoCacheSizeInBytes, colorSpace, downloadBehavior, metadata, }) => {
14
14
  const actualCodec = (0, validate_gcp_codec_1.validateCloudrunCodec)(codec);
15
15
  (0, validate_serveurl_1.validateServeUrl)(serveUrl);
16
16
  if (privacy)
@@ -64,6 +64,8 @@ const internalRenderMediaOnCloudrunRaw = async ({ cloudRunUrl, serviceName, regi
64
64
  clientVersion: version_1.VERSION,
65
65
  downloadBehavior,
66
66
  metadata: metadata !== null && metadata !== void 0 ? metadata : null,
67
+ renderIdOverride,
68
+ renderStatusWebhook,
67
69
  };
68
70
  const client = await (0, get_auth_client_for_url_1.getAuthClientForUrl)(cloudRunEndpoint);
69
71
  const postResponse = await client.request({
@@ -133,7 +135,7 @@ exports.internalRenderMediaOnCloudrun = (0, error_handling_1.wrapWithErrorHandli
133
135
  * @description Initiates a media rendering process on the Remotion Cloud Run service, facilitating configurations like service region, project composition, and output settings.
134
136
  * @see [Documentation](https://remotion.dev/docs/cloudrun/rendermediaoncloudrun)
135
137
  */
136
- const renderMediaOnCloudrun = ({ cloudRunUrl, serviceName, region, serveUrl, composition, inputProps, codec, forceBucketName, privacy, outName, updateRenderProgress, jpegQuality, audioCodec, audioBitrate, videoBitrate, encodingMaxRate, encodingBufferSize, proResProfile, x264Preset, crf, pixelFormat, imageFormat, scale, everyNthFrame, numberOfGifLoops, frameRange, envVariables, chromiumOptions, muted, forceWidth, forceHeight, logLevel, delayRenderTimeoutInMilliseconds, concurrency, enforceAudioTrack, preferLossless, offthreadVideoCacheSizeInBytes, colorSpace, downloadBehavior, metadata, }) => {
138
+ const renderMediaOnCloudrun = ({ cloudRunUrl, serviceName, region, serveUrl, composition, inputProps, codec, forceBucketName, privacy, outName, updateRenderProgress, jpegQuality, audioCodec, audioBitrate, videoBitrate, encodingMaxRate, encodingBufferSize, proResProfile, x264Preset, crf, pixelFormat, imageFormat, scale, everyNthFrame, numberOfGifLoops, frameRange, envVariables, chromiumOptions, muted, forceWidth, forceHeight, logLevel, delayRenderTimeoutInMilliseconds, concurrency, enforceAudioTrack, preferLossless, offthreadVideoCacheSizeInBytes, colorSpace, downloadBehavior, metadata, renderIdOverride, renderStatusWebhook, }) => {
137
139
  return (0, exports.internalRenderMediaOnCloudrun)({
138
140
  cloudRunUrl: cloudRunUrl !== null && cloudRunUrl !== void 0 ? cloudRunUrl : undefined,
139
141
  serviceName: serviceName !== null && serviceName !== void 0 ? serviceName : undefined,
@@ -178,6 +180,8 @@ const renderMediaOnCloudrun = ({ cloudRunUrl, serviceName, region, serveUrl, com
178
180
  type: 'play-in-browser',
179
181
  },
180
182
  metadata: metadata !== null && metadata !== void 0 ? metadata : null,
183
+ renderIdOverride: renderIdOverride !== null && renderIdOverride !== void 0 ? renderIdOverride : undefined,
184
+ renderStatusWebhook: renderStatusWebhook !== null && renderStatusWebhook !== void 0 ? renderStatusWebhook : undefined,
181
185
  });
182
186
  };
183
187
  exports.renderMediaOnCloudrun = renderMediaOnCloudrun;
@@ -1,6 +1,7 @@
1
1
  import type { ChromiumOptions, StillImageFormat, ToOptions } from '@remotion/renderer';
2
2
  import { BrowserSafeApis } from '@remotion/renderer/client';
3
- import type { DownloadBehavior } from '../functions/helpers/payloads';
3
+ import type { z } from 'zod';
4
+ import type { CloudRunPayload, DownloadBehavior } from '../functions/helpers/payloads';
4
5
  import type { GcpRegion } from '../pricing/gcp-regions';
5
6
  type MandatoryParameters = {
6
7
  region: GcpRegion;
@@ -22,6 +23,8 @@ type OptionalParameters = {
22
23
  forceHeight: number | null;
23
24
  indent: boolean;
24
25
  downloadBehavior: DownloadBehavior;
26
+ renderIdOverride: z.infer<typeof CloudRunPayload>['renderIdOverride'];
27
+ renderStatusWebhook: z.infer<typeof CloudRunPayload>['renderStatusWebhook'];
25
28
  } & ToOptions<typeof BrowserSafeApis.optionsMap.renderStillOnCloudRun>;
26
29
  export type RenderStillOnCloudrunInput = Partial<OptionalParameters> & MandatoryParameters;
27
30
  export declare const renderStillOnCloudrun: (options: RenderStillOnCloudrunInput) => Promise<{
@@ -35,7 +35,7 @@ const get_cloudrun_endpoint_1 = require("./helpers/get-cloudrun-endpoint");
35
35
  * @param params.metadata Metadata to be attached to the output file.
36
36
  * @returns {Promise<RenderStillOnCloudrunOutput>} See documentation for detailed structure
37
37
  */
38
- const internalRenderStillOnCloudRun = async ({ cloudRunUrl, serviceName, region, serveUrl, composition, inputProps, forceBucketName, privacy, outName, imageFormat, envVariables, frame, jpegQuality, chromiumOptions, scale, forceWidth, forceHeight, logLevel, delayRenderTimeoutInMilliseconds, offthreadVideoCacheSizeInBytes, downloadBehavior, }) => {
38
+ const internalRenderStillOnCloudRun = async ({ cloudRunUrl, serviceName, region, serveUrl, composition, inputProps, forceBucketName, privacy, outName, imageFormat, envVariables, frame, jpegQuality, chromiumOptions, scale, forceWidth, forceHeight, logLevel, delayRenderTimeoutInMilliseconds, offthreadVideoCacheSizeInBytes, downloadBehavior, renderIdOverride, renderStatusWebhook, }) => {
39
39
  (0, validate_serveurl_1.validateServeUrl)(serveUrl);
40
40
  if (privacy)
41
41
  (0, validate_privacy_1.validatePrivacy)(privacy);
@@ -70,6 +70,8 @@ const internalRenderStillOnCloudRun = async ({ cloudRunUrl, serviceName, region,
70
70
  offthreadVideoCacheSizeInBytes,
71
71
  clientVersion: version_1.VERSION,
72
72
  downloadBehavior,
73
+ renderIdOverride,
74
+ renderStatusWebhook,
73
75
  };
74
76
  const client = await (0, get_auth_client_for_url_1.getAuthClientForUrl)(cloudRunEndpoint);
75
77
  const postResponse = await client.request({
@@ -129,7 +131,7 @@ const internalRenderStillOnCloudRun = async ({ cloudRunUrl, serviceName, region,
129
131
  };
130
132
  const errorHandled = (0, error_handling_1.wrapWithErrorHandling)(internalRenderStillOnCloudRun);
131
133
  const renderStillOnCloudrun = (options) => {
132
- var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s, _t;
134
+ var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s, _t, _u, _v;
133
135
  return errorHandled({
134
136
  chromiumOptions: (_a = options.chromiumOptions) !== null && _a !== void 0 ? _a : {},
135
137
  cloudRunUrl: (_b = options.cloudRunUrl) !== null && _b !== void 0 ? _b : null,
@@ -153,6 +155,8 @@ const renderStillOnCloudrun = (options) => {
153
155
  serveUrl: options.serveUrl,
154
156
  serviceName: (_s = options.serviceName) !== null && _s !== void 0 ? _s : null,
155
157
  downloadBehavior: (_t = options.downloadBehavior) !== null && _t !== void 0 ? _t : { type: 'play-in-browser' },
158
+ renderIdOverride: (_u = options.renderIdOverride) !== null && _u !== void 0 ? _u : undefined,
159
+ renderStatusWebhook: (_v = options.renderStatusWebhook) !== null && _v !== void 0 ? _v : undefined,
156
160
  });
157
161
  };
158
162
  exports.renderStillOnCloudrun = renderStillOnCloudrun;
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,50 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const bun_test_1 = require("bun:test");
4
+ const payloads_1 = require("../../functions/helpers/payloads");
5
+ (0, bun_test_1.test)('CloudRunPayload should work with and without optional webhook fields', () => {
6
+ const basePayload = {
7
+ type: 'still',
8
+ serveUrl: 'https://example.com',
9
+ composition: 'my-comp',
10
+ imageFormat: 'png',
11
+ scale: 1,
12
+ privacy: 'public',
13
+ envVariables: {},
14
+ outputBucket: 'my-bucket',
15
+ frame: 0,
16
+ delayRenderTimeoutInMilliseconds: 30000,
17
+ logLevel: 'info',
18
+ clientVersion: '1.0.0',
19
+ downloadBehavior: { type: 'play-in-browser' },
20
+ outName: null,
21
+ offthreadVideoCacheSizeInBytes: null,
22
+ serializedInputPropsWithCustomSchema: JSON.stringify({}),
23
+ };
24
+ const withWebhook = {
25
+ ...basePayload,
26
+ renderIdOverride: 'custom-render-id',
27
+ renderStatusWebhook: {
28
+ url: 'https://webhook.example.com',
29
+ headers: { 'x-custom-header': 'value' },
30
+ data: { key: 'value' },
31
+ },
32
+ };
33
+ const withoutWebhook = basePayload;
34
+ const parsedWithWebhook = payloads_1.CloudRunPayload.safeParse(withWebhook);
35
+ const parsedWithoutWebhook = payloads_1.CloudRunPayload.safeParse(withoutWebhook);
36
+ (0, bun_test_1.expect)(parsedWithWebhook.success).toBe(true);
37
+ (0, bun_test_1.expect)(parsedWithoutWebhook.success).toBe(true);
38
+ if (parsedWithWebhook.success) {
39
+ (0, bun_test_1.expect)(parsedWithWebhook.data.renderIdOverride).toBe('custom-render-id');
40
+ (0, bun_test_1.expect)(parsedWithWebhook.data.renderStatusWebhook).toEqual({
41
+ url: 'https://webhook.example.com',
42
+ headers: { 'x-custom-header': 'value' },
43
+ data: { key: 'value' },
44
+ });
45
+ }
46
+ if (parsedWithoutWebhook.success) {
47
+ (0, bun_test_1.expect)(parsedWithoutWebhook.data.renderIdOverride).toBeUndefined();
48
+ (0, bun_test_1.expect)(parsedWithoutWebhook.data.renderStatusWebhook).toBeUndefined();
49
+ }
50
+ });
@@ -13,6 +13,8 @@ type servicesCommandLineOptions = {
13
13
  ['out-name']: string | undefined;
14
14
  ['output-bucket']: string;
15
15
  ['output-folder-path']: string;
16
+ webhook: string;
17
+ ['render-id-override']: string;
16
18
  };
17
19
  export declare const parsedCloudrunCli: servicesCommandLineOptions & import("minimist").ParsedArgs;
18
20
  export declare const forceFlagProvided: boolean;
@@ -16,7 +16,7 @@ const renderArgsCheck_1 = require("./helpers/renderArgsCheck");
16
16
  exports.RENDER_COMMAND = 'render';
17
17
  const { audioBitrateOption, x264Option, offthreadVideoCacheSizeInBytesOption, scaleOption, crfOption, jpegQualityOption, videoBitrateOption, enforceAudioOption, mutedOption, colorSpaceOption, numberOfGifLoopsOption, enableMultiprocessOnLinuxOption, glOption, headlessOption, encodingMaxRateOption, encodingBufferSizeOption, delayRenderTimeoutInMillisecondsOption, binariesDirectoryOption, metadataOption, } = client_1.BrowserSafeApis.options;
18
18
  const renderCommand = async (args, remotionRoot, logLevel) => {
19
- var _a, _b;
19
+ var _a, _b, _c;
20
20
  const { serveUrl, cloudRunUrl, outName, forceBucketName, downloadName, privacy, region, } = await (0, renderArgsCheck_1.renderArgsCheck)(exports.RENDER_COMMAND, args, logLevel);
21
21
  const { value: codec, source: codecReason } = client_1.BrowserSafeApis.options.videoCodecOption.getValue({
22
22
  commandLine: cli_1.CliInternals.parsedCli,
@@ -104,6 +104,7 @@ const renderCommand = async (args, remotionRoot, logLevel) => {
104
104
  logLevel,
105
105
  quiet: cli_1.CliInternals.quietFlagProvided(),
106
106
  }),
107
+ chromeMode: 'headless-shell',
107
108
  });
108
109
  composition = compositionId;
109
110
  }
@@ -236,6 +237,15 @@ ${downloadName ? ` Downloaded File = ${downloadName}` : ''}
236
237
  indent: false,
237
238
  downloadBehavior: { type: 'play-in-browser' },
238
239
  metadata,
240
+ renderIdOverride: (_c = args_1.parsedCloudrunCli['render-id-override']) !== null && _c !== void 0 ? _c : null,
241
+ renderStatusWebhook: args_1.parsedCloudrunCli.webhook
242
+ ? {
243
+ url: args_1.parsedCloudrunCli.webhook,
244
+ headers: {},
245
+ data: null,
246
+ webhookProgressInterval: null,
247
+ }
248
+ : null,
239
249
  });
240
250
  if (res.type === 'crash') {
241
251
  (0, cloudrun_crash_logs_1.displayCrashLogs)(res, logLevel);
@@ -92,6 +92,7 @@ const stillCommand = async (args, remotionRoot, logLevel) => {
92
92
  logLevel,
93
93
  quiet: cli_1.CliInternals.quietFlagProvided(),
94
94
  }),
95
+ chromeMode: 'headless-shell',
95
96
  });
96
97
  composition = compositionId;
97
98
  }
@@ -27,6 +27,7 @@ const getCompositionFromBody = async (body) => {
27
27
  throw new Error('Should not download a browser in Cloud Run');
28
28
  },
29
29
  onServeUrlVisited: () => undefined,
30
+ chromeMode: 'headless-shell',
30
31
  });
31
32
  if (propsSize > 10000000) {
32
33
  renderer_1.RenderInternals.Log.warn({ indent: false, logLevel: body.logLevel }, `The props of your composition are large (${propsSize} bytes). This may cause slowdown.`);
@@ -88,6 +88,23 @@ export declare const CloudRunPayload: z.ZodDiscriminatedUnion<"type", [z.ZodObje
88
88
  fileName: string | null;
89
89
  }>]>;
90
90
  metadata: z.ZodNullable<z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>>;
91
+ renderIdOverride: z.ZodNullable<z.ZodOptional<z.ZodString>>;
92
+ renderStatusWebhook: z.ZodNullable<z.ZodOptional<z.ZodObject<{
93
+ url: z.ZodString;
94
+ headers: z.ZodRecord<z.ZodString, z.ZodString>;
95
+ data: z.ZodAny;
96
+ webhookProgressInterval: z.ZodNullable<z.ZodOptional<z.ZodNumber>>;
97
+ }, "strip", z.ZodTypeAny, {
98
+ url: string;
99
+ headers: Record<string, string>;
100
+ data?: any;
101
+ webhookProgressInterval?: number | null | undefined;
102
+ }, {
103
+ url: string;
104
+ headers: Record<string, string>;
105
+ data?: any;
106
+ webhookProgressInterval?: number | null | undefined;
107
+ }>>>;
91
108
  }, "strip", z.ZodTypeAny, {
92
109
  type: "media";
93
110
  serveUrl: string;
@@ -138,6 +155,13 @@ export declare const CloudRunPayload: z.ZodDiscriminatedUnion<"type", [z.ZodObje
138
155
  outName?: string | undefined;
139
156
  privacy?: "public" | "private" | undefined;
140
157
  metadata?: Record<string, string> | null | undefined;
158
+ renderIdOverride?: string | null | undefined;
159
+ renderStatusWebhook?: {
160
+ url: string;
161
+ headers: Record<string, string>;
162
+ data?: any;
163
+ webhookProgressInterval?: number | null | undefined;
164
+ } | null | undefined;
141
165
  }, {
142
166
  type: "media";
143
167
  serveUrl: string;
@@ -188,6 +212,13 @@ export declare const CloudRunPayload: z.ZodDiscriminatedUnion<"type", [z.ZodObje
188
212
  outName?: string | undefined;
189
213
  privacy?: "public" | "private" | undefined;
190
214
  metadata?: Record<string, string> | null | undefined;
215
+ renderIdOverride?: string | null | undefined;
216
+ renderStatusWebhook?: {
217
+ url: string;
218
+ headers: Record<string, string>;
219
+ data?: any;
220
+ webhookProgressInterval?: number | null | undefined;
221
+ } | null | undefined;
191
222
  }>, z.ZodObject<{
192
223
  type: z.ZodLiteral<"still">;
193
224
  serveUrl: z.ZodString;
@@ -243,6 +274,23 @@ export declare const CloudRunPayload: z.ZodDiscriminatedUnion<"type", [z.ZodObje
243
274
  fileName: string | null;
244
275
  }>]>;
245
276
  metadata: z.ZodNullable<z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>>;
277
+ renderIdOverride: z.ZodNullable<z.ZodOptional<z.ZodString>>;
278
+ renderStatusWebhook: z.ZodNullable<z.ZodOptional<z.ZodObject<{
279
+ url: z.ZodString;
280
+ headers: z.ZodRecord<z.ZodString, z.ZodString>;
281
+ data: z.ZodAny;
282
+ webhookProgressInterval: z.ZodNullable<z.ZodOptional<z.ZodNumber>>;
283
+ }, "strip", z.ZodTypeAny, {
284
+ url: string;
285
+ headers: Record<string, string>;
286
+ data?: any;
287
+ webhookProgressInterval?: number | null | undefined;
288
+ }, {
289
+ url: string;
290
+ headers: Record<string, string>;
291
+ data?: any;
292
+ webhookProgressInterval?: number | null | undefined;
293
+ }>>>;
246
294
  }, "strip", z.ZodTypeAny, {
247
295
  type: "still";
248
296
  serveUrl: string;
@@ -276,6 +324,13 @@ export declare const CloudRunPayload: z.ZodDiscriminatedUnion<"type", [z.ZodObje
276
324
  userAgent?: string | null | undefined;
277
325
  } | undefined;
278
326
  metadata?: Record<string, string> | null | undefined;
327
+ renderIdOverride?: string | null | undefined;
328
+ renderStatusWebhook?: {
329
+ url: string;
330
+ headers: Record<string, string>;
331
+ data?: any;
332
+ webhookProgressInterval?: number | null | undefined;
333
+ } | null | undefined;
279
334
  }, {
280
335
  type: "still";
281
336
  serveUrl: string;
@@ -309,6 +364,13 @@ export declare const CloudRunPayload: z.ZodDiscriminatedUnion<"type", [z.ZodObje
309
364
  userAgent?: string | null | undefined;
310
365
  } | undefined;
311
366
  metadata?: Record<string, string> | null | undefined;
367
+ renderIdOverride?: string | null | undefined;
368
+ renderStatusWebhook?: {
369
+ url: string;
370
+ headers: Record<string, string>;
371
+ data?: any;
372
+ webhookProgressInterval?: number | null | undefined;
373
+ } | null | undefined;
312
374
  }>]>;
313
375
  declare const renderFailResponsePayload: z.ZodObject<{
314
376
  type: z.ZodLiteral<"error">;
@@ -67,6 +67,16 @@ exports.CloudRunPayload = zod_1.z.discriminatedUnion('type', [
67
67
  clientVersion: zod_1.z.string(),
68
68
  downloadBehavior,
69
69
  metadata: zod_1.z.record(zod_1.z.string()).optional().nullable(),
70
+ renderIdOverride: zod_1.z.string().optional().nullable(),
71
+ renderStatusWebhook: zod_1.z
72
+ .object({
73
+ url: zod_1.z.string(),
74
+ headers: zod_1.z.record(zod_1.z.string()),
75
+ data: zod_1.z.any(),
76
+ webhookProgressInterval: zod_1.z.number().min(0).max(1).optional().nullable(),
77
+ })
78
+ .optional()
79
+ .nullable(),
70
80
  }),
71
81
  zod_1.z.object({
72
82
  type: zod_1.z.literal('still'),
@@ -90,6 +100,16 @@ exports.CloudRunPayload = zod_1.z.discriminatedUnion('type', [
90
100
  clientVersion: zod_1.z.string(),
91
101
  downloadBehavior,
92
102
  metadata: zod_1.z.record(zod_1.z.string()).optional().nullable(),
103
+ renderIdOverride: zod_1.z.string().optional().nullable(),
104
+ renderStatusWebhook: zod_1.z
105
+ .object({
106
+ url: zod_1.z.string(),
107
+ headers: zod_1.z.record(zod_1.z.string()),
108
+ data: zod_1.z.any(),
109
+ webhookProgressInterval: zod_1.z.number().min(0).max(1).optional().nullable(),
110
+ })
111
+ .optional()
112
+ .nullable(),
93
113
  }),
94
114
  ]);
95
115
  // eslint-disable-next-line @typescript-eslint/no-unused-vars
@@ -10,7 +10,7 @@ const get_composition_from_body_1 = require("./helpers/get-composition-from-body
10
10
  const get_download_behavior_setting_1 = require("./helpers/get-download-behavior-setting");
11
11
  const write_cloudrun_error_1 = require("./helpers/write-cloudrun-error");
12
12
  const renderMediaSingleThread = async (body, res) => {
13
- var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o;
13
+ var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p;
14
14
  if (body.type !== 'media') {
15
15
  throw new Error('expected type media');
16
16
  }
@@ -20,14 +20,16 @@ const renderMediaSingleThread = async (body, res) => {
20
20
  }
21
21
  throw new Error(`Version mismatch: When calling renderMediaOnCloudRun(), you called a service, which has the version ${version_1.VERSION}, but the @remotion/cloudrun package you used to invoke the function has version ${version_1.VERSION}. Deploy a new service and use it to call renderMediaOnCloudrun().`);
22
22
  }
23
- const renderId = (0, random_hash_1.randomHash)({ randomInTests: true });
23
+ const renderId = (_a = body.renderIdOverride) !== null && _a !== void 0 ? _a : (0, random_hash_1.randomHash)({ randomInTests: true });
24
24
  try {
25
25
  const composition = await (0, get_composition_from_body_1.getCompositionFromBody)(body);
26
26
  const defaultOutName = `out.${renderer_1.RenderInternals.getFileExtensionFromCodec(body.codec, body.audioCodec)}`;
27
27
  const tempFilePath = `/tmp/${defaultOutName}`;
28
28
  let previousProgress = 0.02;
29
+ let lastWebhookProgress = 0;
29
30
  let writingProgress = Promise.resolve();
30
31
  const onProgress = ({ progress, renderedFrames, encodedFrames, }) => {
32
+ var _a;
31
33
  if (previousProgress !== progress) {
32
34
  renderer_1.RenderInternals.Log.info({ indent: false, logLevel: body.logLevel }, 'Render progress:', renderedFrames, 'frames rendered', encodedFrames, 'frames encoded', Math.round(progress * 100), '%');
33
35
  writingProgress = writingProgress.then(() => {
@@ -37,6 +39,31 @@ const renderMediaSingleThread = async (body, res) => {
37
39
  });
38
40
  });
39
41
  });
42
+ if (body.renderStatusWebhook) {
43
+ const interval = (_a = body.renderStatusWebhook.webhookProgressInterval) !== null && _a !== void 0 ? _a : 0.1; // Default 10% intervals
44
+ const shouldCallWebhook = progress === 1 || // Always call on completion
45
+ lastWebhookProgress === 0 || // Always call first time
46
+ progress - lastWebhookProgress >= interval; // Call if interval exceeded
47
+ if (shouldCallWebhook) {
48
+ fetch(body.renderStatusWebhook.url, {
49
+ method: 'POST',
50
+ headers: {
51
+ ...body.renderStatusWebhook.headers,
52
+ 'Content-Type': 'application/json',
53
+ },
54
+ body: JSON.stringify({
55
+ ...body.renderStatusWebhook.data,
56
+ progress,
57
+ renderId,
58
+ renderedFrames,
59
+ encodedFrames,
60
+ }),
61
+ }).catch((err) => {
62
+ renderer_1.RenderInternals.Log.warn({ indent: false, logLevel: body.logLevel }, 'Failed to call webhook:', err);
63
+ });
64
+ lastWebhookProgress = progress;
65
+ }
66
+ }
40
67
  previousProgress = progress;
41
68
  }
42
69
  };
@@ -44,7 +71,7 @@ const renderMediaSingleThread = async (body, res) => {
44
71
  const actualChromiumOptions = {
45
72
  ...body.chromiumOptions,
46
73
  // Override the `null` value, which might come from CLI with swANGLE
47
- gl: (_b = (_a = body.chromiumOptions) === null || _a === void 0 ? void 0 : _a.gl) !== null && _b !== void 0 ? _b : 'swangle',
74
+ gl: (_c = (_b = body.chromiumOptions) === null || _b === void 0 ? void 0 : _b.gl) !== null && _c !== void 0 ? _c : 'swangle',
48
75
  enableMultiProcessOnLinux: true,
49
76
  };
50
77
  const onArtifact = () => {
@@ -53,8 +80,8 @@ const renderMediaSingleThread = async (body, res) => {
53
80
  await renderer_1.RenderInternals.internalRenderMedia({
54
81
  composition: {
55
82
  ...composition,
56
- height: (_c = body.forceHeight) !== null && _c !== void 0 ? _c : composition.height,
57
- width: (_d = body.forceWidth) !== null && _d !== void 0 ? _d : composition.width,
83
+ height: (_d = body.forceHeight) !== null && _d !== void 0 ? _d : composition.height,
84
+ width: (_e = body.forceWidth) !== null && _e !== void 0 ? _e : composition.width,
58
85
  },
59
86
  serveUrl: body.serveUrl,
60
87
  codec: body.codec,
@@ -65,17 +92,17 @@ const renderMediaSingleThread = async (body, res) => {
65
92
  indent: undefined,
66
93
  staticBase: null,
67
94
  }).serializedString,
68
- jpegQuality: (_e = body.jpegQuality) !== null && _e !== void 0 ? _e : renderer_1.RenderInternals.DEFAULT_JPEG_QUALITY,
95
+ jpegQuality: (_f = body.jpegQuality) !== null && _f !== void 0 ? _f : renderer_1.RenderInternals.DEFAULT_JPEG_QUALITY,
69
96
  audioCodec: body.audioCodec,
70
- audioBitrate: (_f = body.audioBitrate) !== null && _f !== void 0 ? _f : null,
97
+ audioBitrate: (_g = body.audioBitrate) !== null && _g !== void 0 ? _g : null,
71
98
  videoBitrate: body.videoBitrate,
72
99
  encodingMaxRate: body.encodingMaxRate,
73
100
  encodingBufferSize: body.encodingBufferSize,
74
101
  crf: body.crf,
75
- pixelFormat: (_g = body.pixelFormat) !== null && _g !== void 0 ? _g : renderer_1.RenderInternals.DEFAULT_PIXEL_FORMAT,
76
- imageFormat: (_h = body.imageFormat) !== null && _h !== void 0 ? _h : renderer_1.RenderInternals.DEFAULT_VIDEO_IMAGE_FORMAT,
102
+ pixelFormat: (_h = body.pixelFormat) !== null && _h !== void 0 ? _h : renderer_1.RenderInternals.DEFAULT_PIXEL_FORMAT,
103
+ imageFormat: (_j = body.imageFormat) !== null && _j !== void 0 ? _j : renderer_1.RenderInternals.DEFAULT_VIDEO_IMAGE_FORMAT,
77
104
  scale: body.scale,
78
- proResProfile: (_j = body.proResProfile) !== null && _j !== void 0 ? _j : undefined,
105
+ proResProfile: (_k = body.proResProfile) !== null && _k !== void 0 ? _k : undefined,
79
106
  x264Preset: body.x264Preset,
80
107
  everyNthFrame: body.everyNthFrame,
81
108
  numberOfGifLoops: body.numberOfGifLoops,
@@ -86,9 +113,9 @@ const renderMediaSingleThread = async (body, res) => {
86
113
  muted: body.muted,
87
114
  logLevel: body.logLevel,
88
115
  browserExecutable: null,
89
- timeoutInMilliseconds: (_k = body.delayRenderTimeoutInMilliseconds) !== null && _k !== void 0 ? _k : renderer_1.RenderInternals.DEFAULT_TIMEOUT,
116
+ timeoutInMilliseconds: (_l = body.delayRenderTimeoutInMilliseconds) !== null && _l !== void 0 ? _l : renderer_1.RenderInternals.DEFAULT_TIMEOUT,
90
117
  cancelSignal: undefined,
91
- concurrency: (_l = body.concurrency) !== null && _l !== void 0 ? _l : null,
118
+ concurrency: (_m = body.concurrency) !== null && _m !== void 0 ? _m : null,
92
119
  disallowParallelEncoding: false,
93
120
  enforceAudioTrack: body.enforceAudioTrack,
94
121
  ffmpegOverride: undefined,
@@ -113,15 +140,16 @@ const renderMediaSingleThread = async (body, res) => {
113
140
  throw new Error('Should not download a browser in Cloud Run');
114
141
  },
115
142
  onArtifact,
116
- metadata: (_m = body.metadata) !== null && _m !== void 0 ? _m : null,
143
+ metadata: (_o = body.metadata) !== null && _o !== void 0 ? _o : null,
117
144
  hardwareAcceleration: 'disable',
145
+ chromeMode: 'headless-shell',
118
146
  });
119
147
  const storage = new storage_1.Storage();
120
148
  const publicUpload = body.privacy === 'public' || !body.privacy;
121
149
  const uploadedResponse = await storage
122
150
  .bucket(body.outputBucket)
123
151
  .upload(tempFilePath, {
124
- destination: `renders/${renderId}/${(_o = body.outName) !== null && _o !== void 0 ? _o : defaultOutName}`,
152
+ destination: `renders/${renderId}/${(_p = body.outName) !== null && _p !== void 0 ? _p : defaultOutName}`,
125
153
  predefinedAcl: publicUpload ? 'publicRead' : 'projectPrivate',
126
154
  metadata: (0, get_download_behavior_setting_1.getDownloadBehaviorSetting)(body.downloadBehavior),
127
155
  });
@@ -11,7 +11,7 @@ const get_composition_from_body_1 = require("./helpers/get-composition-from-body
11
11
  const get_download_behavior_setting_1 = require("./helpers/get-download-behavior-setting");
12
12
  const write_cloudrun_error_1 = require("./helpers/write-cloudrun-error");
13
13
  const renderStillSingleThread = async (body, res) => {
14
- var _a, _b, _c, _d, _e, _f;
14
+ var _a, _b, _c, _d, _e, _f, _g;
15
15
  if (body.type !== 'still') {
16
16
  throw new Error('expected type still');
17
17
  }
@@ -21,7 +21,7 @@ const renderStillSingleThread = async (body, res) => {
21
21
  }
22
22
  throw new Error(`Version mismatch: When calling renderMediaOnCloudRun(), you called a service, which has the version ${version_1.VERSION}, but the @remotion/cloudrun package you used to invoke the function has version ${version_1.VERSION}. Deploy a new service and use it to call renderMediaOnCloudrun().`);
23
23
  }
24
- const renderId = (0, random_hash_1.randomHash)({ randomInTests: true });
24
+ const renderId = (_a = body.renderIdOverride) !== null && _a !== void 0 ? _a : (0, random_hash_1.randomHash)({ randomInTests: true });
25
25
  try {
26
26
  log_1.Log.verbose({ indent: false, logLevel: body.logLevel }, 'Rendering still frame', body);
27
27
  const composition = await (0, get_composition_from_body_1.getCompositionFromBody)(body);
@@ -30,14 +30,14 @@ const renderStillSingleThread = async (body, res) => {
30
30
  const actualChromiumOptions = {
31
31
  ...body.chromiumOptions,
32
32
  // Override the `null` value, which might come from CLI with swANGLE
33
- gl: (_b = (_a = body.chromiumOptions) === null || _a === void 0 ? void 0 : _a.gl) !== null && _b !== void 0 ? _b : 'swangle',
33
+ gl: (_c = (_b = body.chromiumOptions) === null || _b === void 0 ? void 0 : _b.gl) !== null && _c !== void 0 ? _c : 'swangle',
34
34
  enableMultiProcessOnLinux: true,
35
35
  };
36
36
  await renderer_1.RenderInternals.internalRenderStill({
37
37
  composition: {
38
38
  ...composition,
39
- height: (_c = body.forceHeight) !== null && _c !== void 0 ? _c : composition.height,
40
- width: (_d = body.forceWidth) !== null && _d !== void 0 ? _d : composition.width,
39
+ height: (_d = body.forceHeight) !== null && _d !== void 0 ? _d : composition.height,
40
+ width: (_e = body.forceWidth) !== null && _e !== void 0 ? _e : composition.width,
41
41
  },
42
42
  serveUrl: body.serveUrl,
43
43
  output: tempFilePath,
@@ -47,7 +47,7 @@ const renderStillSingleThread = async (body, res) => {
47
47
  indent: undefined,
48
48
  staticBase: null,
49
49
  }).serializedString,
50
- jpegQuality: (_e = body.jpegQuality) !== null && _e !== void 0 ? _e : renderer_1.RenderInternals.DEFAULT_JPEG_QUALITY,
50
+ jpegQuality: (_f = body.jpegQuality) !== null && _f !== void 0 ? _f : renderer_1.RenderInternals.DEFAULT_JPEG_QUALITY,
51
51
  imageFormat: body.imageFormat,
52
52
  scale: body.scale,
53
53
  envVariables: body.envVariables,
@@ -72,6 +72,7 @@ const renderStillSingleThread = async (body, res) => {
72
72
  onArtifact: () => {
73
73
  throw new Error('Emitting artifacts is not supported in Cloud Run');
74
74
  },
75
+ chromeMode: 'headless-shell',
75
76
  });
76
77
  log_1.Log.info({ indent: false, logLevel: body.logLevel }, 'Still rendered');
77
78
  const storage = new storage_1.Storage();
@@ -79,7 +80,7 @@ const renderStillSingleThread = async (body, res) => {
79
80
  const uploadedResponse = await storage
80
81
  .bucket(body.outputBucket)
81
82
  .upload(tempFilePath, {
82
- destination: `renders/${renderId}/${(_f = body.outName) !== null && _f !== void 0 ? _f : 'out.png'}`,
83
+ destination: `renders/${renderId}/${(_g = body.outName) !== null && _g !== void 0 ? _g : 'out.png'}`,
83
84
  predefinedAcl: publicUpload ? 'publicRead' : 'projectPrivate',
84
85
  metadata: (0, get_download_behavior_setting_1.getDownloadBehaviorSetting)(body.downloadBehavior),
85
86
  });
package/dist/index.d.ts CHANGED
@@ -16,7 +16,7 @@ import type { GcpRegion } from './pricing/gcp-regions';
16
16
  /**
17
17
  * @deprecated Import this from `@remotion/cloudrun/client` instead
18
18
  */
19
- declare const renderMediaOnCloudrun: ({ cloudRunUrl, serviceName, region, serveUrl, composition, inputProps, codec, forceBucketName, privacy, outName, updateRenderProgress, jpegQuality, audioCodec, audioBitrate, videoBitrate, encodingMaxRate, encodingBufferSize, proResProfile, x264Preset, crf, pixelFormat, imageFormat, scale, everyNthFrame, numberOfGifLoops, frameRange, envVariables, chromiumOptions, muted, forceWidth, forceHeight, logLevel, delayRenderTimeoutInMilliseconds, concurrency, enforceAudioTrack, preferLossless, offthreadVideoCacheSizeInBytes, colorSpace, downloadBehavior, metadata, }: RenderMediaOnCloudrunInput) => Promise<RenderMediaOnCloudrunOutput | import("./functions/helpers/payloads").CloudRunCrashResponse>;
19
+ declare const renderMediaOnCloudrun: ({ cloudRunUrl, serviceName, region, serveUrl, composition, inputProps, codec, forceBucketName, privacy, outName, updateRenderProgress, jpegQuality, audioCodec, audioBitrate, videoBitrate, encodingMaxRate, encodingBufferSize, proResProfile, x264Preset, crf, pixelFormat, imageFormat, scale, everyNthFrame, numberOfGifLoops, frameRange, envVariables, chromiumOptions, muted, forceWidth, forceHeight, logLevel, delayRenderTimeoutInMilliseconds, concurrency, enforceAudioTrack, preferLossless, offthreadVideoCacheSizeInBytes, colorSpace, downloadBehavior, metadata, renderIdOverride, renderStatusWebhook, }: RenderMediaOnCloudrunInput) => Promise<RenderMediaOnCloudrunOutput | import("./functions/helpers/payloads").CloudRunCrashResponse>;
20
20
  /**
21
21
  * @deprecated Import this from `@remotion/cloudrun/client` instead
22
22
  */
package/package.json CHANGED
@@ -3,7 +3,7 @@
3
3
  "url": "https://github.com/remotion-dev/remotion/tree/main/packages/cloudrun"
4
4
  },
5
5
  "name": "@remotion/cloudrun",
6
- "version": "4.0.246",
6
+ "version": "4.0.248",
7
7
  "description": "Render Remotion videos on Google Cloud Run",
8
8
  "main": "dist/index.js",
9
9
  "sideEffects": false,
@@ -16,16 +16,16 @@
16
16
  "@google-cloud/logging": "^11.1.0",
17
17
  "google-auth-library": "^8.7.0",
18
18
  "zod": "3.22.3",
19
- "@remotion/bundler": "4.0.246",
20
- "@remotion/cli": "4.0.246",
21
- "@remotion/renderer": "4.0.246",
22
- "remotion": "4.0.246"
19
+ "@remotion/bundler": "4.0.248",
20
+ "@remotion/cli": "4.0.248",
21
+ "remotion": "4.0.248",
22
+ "@remotion/renderer": "4.0.248"
23
23
  },
24
24
  "devDependencies": {
25
25
  "@types/minimist": "1.2.2",
26
26
  "eslint": "9.14.0",
27
- "@remotion/compositor-linux-x64-gnu": "4.0.246",
28
- "@remotion/eslint-config-internal": "4.0.246"
27
+ "@remotion/eslint-config-internal": "4.0.248",
28
+ "@remotion/compositor-linux-x64-gnu": "4.0.248"
29
29
  },
30
30
  "exports": {
31
31
  "./package.json": "./package.json",