@remotion/web-renderer 4.0.394 → 4.0.396

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (72) hide show
  1. package/dist/border-radius.d.ts +31 -0
  2. package/dist/border-radius.js +152 -0
  3. package/dist/calculate-transforms.d.ts +2 -0
  4. package/dist/calculate-transforms.js +17 -0
  5. package/dist/composable.d.ts +2 -8
  6. package/dist/compose-canvas.js +28 -4
  7. package/dist/compose.d.ts +6 -3
  8. package/dist/compose.js +41 -12
  9. package/dist/drawing/border-radius.d.ts +3 -5
  10. package/dist/drawing/border-radius.js +12 -11
  11. package/dist/drawing/calculate-transforms.d.ts +6 -2
  12. package/dist/drawing/calculate-transforms.js +19 -22
  13. package/dist/drawing/canvas-offset-from-rect.d.ts +8 -0
  14. package/dist/drawing/canvas-offset-from-rect.js +12 -0
  15. package/dist/drawing/clamp-rect-to-parent-bounds.d.ts +4 -0
  16. package/dist/drawing/clamp-rect-to-parent-bounds.js +7 -0
  17. package/dist/drawing/compose-canvas.d.ts +1 -0
  18. package/dist/drawing/compose-canvas.js +36 -0
  19. package/dist/drawing/compose-svg.d.ts +1 -0
  20. package/dist/drawing/compose-svg.js +34 -0
  21. package/dist/drawing/compose.d.ts +5 -0
  22. package/dist/drawing/compose.js +6 -0
  23. package/dist/drawing/draw-border.d.ts +2 -5
  24. package/dist/drawing/draw-border.js +307 -55
  25. package/dist/drawing/draw-element-to-canvas.d.ts +4 -1
  26. package/dist/drawing/draw-element-to-canvas.js +9 -26
  27. package/dist/drawing/draw-element.d.ts +5 -3
  28. package/dist/drawing/draw-element.js +29 -14
  29. package/dist/drawing/draw-outline.d.ts +9 -0
  30. package/dist/drawing/draw-outline.js +116 -0
  31. package/dist/drawing/get-bounding-box-including-shadow.d.ts +1 -0
  32. package/dist/drawing/get-bounding-box-including-shadow.js +6 -0
  33. package/dist/drawing/get-computed-style-cache.d.ts +0 -0
  34. package/dist/drawing/get-computed-style-cache.js +1 -0
  35. package/dist/drawing/get-pretransform-rect.d.ts +1 -0
  36. package/dist/drawing/get-pretransform-rect.js +31 -0
  37. package/dist/drawing/handle-3d-transform.d.ts +10 -0
  38. package/dist/drawing/handle-3d-transform.js +39 -0
  39. package/dist/drawing/has-transform.d.ts +4 -0
  40. package/dist/drawing/has-transform.js +14 -0
  41. package/dist/drawing/overflow.d.ts +7 -0
  42. package/dist/drawing/overflow.js +12 -0
  43. package/dist/drawing/process-node.d.ts +17 -0
  44. package/dist/drawing/process-node.js +41 -0
  45. package/dist/drawing/text/draw-text.js +6 -8
  46. package/dist/drawing/text/handle-text-node.d.ts +8 -5
  47. package/dist/drawing/text/handle-text-node.js +6 -5
  48. package/dist/drawing/transform-in-3d.d.ts +7 -7
  49. package/dist/drawing/transform-in-3d.js +27 -13
  50. package/dist/drawing/transform-rect-with-matrix.d.ts +4 -0
  51. package/dist/drawing/transform-rect-with-matrix.js +19 -0
  52. package/dist/drawing/turn-svg-into-drawable.js +7 -0
  53. package/dist/esm/index.mjs +897 -205
  54. package/dist/find-canvas-elements.d.ts +1 -0
  55. package/dist/find-canvas-elements.js +13 -0
  56. package/dist/find-capturable-elements.d.ts +1 -1
  57. package/dist/find-capturable-elements.js +20 -22
  58. package/dist/get-biggest-bounding-client-rect.js +18 -5
  59. package/dist/internal-state.d.ts +9 -0
  60. package/dist/internal-state.js +12 -0
  61. package/dist/opacity.d.ts +4 -0
  62. package/dist/opacity.js +7 -0
  63. package/dist/render-media-on-web.d.ts +3 -0
  64. package/dist/render-media-on-web.js +38 -15
  65. package/dist/render-still-on-web.d.ts +6 -1
  66. package/dist/render-still-on-web.js +29 -8
  67. package/dist/send-telemetry-event.js +1 -1
  68. package/dist/take-screenshot.d.ts +8 -2
  69. package/dist/take-screenshot.js +16 -4
  70. package/dist/transform.d.ts +4 -0
  71. package/dist/transform.js +6 -0
  72. package/package.json +7 -6
@@ -0,0 +1 @@
1
+ export declare const findCanvasElements: (element: HTMLDivElement) => HTMLCanvasElement[];
@@ -0,0 +1,13 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.findCanvasElements = void 0;
4
+ const findCanvasElements = (element) => {
5
+ const canvasElements = element.querySelectorAll('canvas');
6
+ const composables = [];
7
+ Array.from(canvasElements).forEach((canvasElement) => {
8
+ const canvas = canvasElement;
9
+ composables.push(canvas);
10
+ });
11
+ return composables;
12
+ };
13
+ exports.findCanvasElements = findCanvasElements;
@@ -1,2 +1,2 @@
1
1
  import type { Composable } from './composable';
2
- export declare const findCapturableElements: (element: HTMLDivElement) => Composable[];
2
+ export declare const findCapturableElements: (element: HTMLDivElement, context: OffscreenCanvasRenderingContext2D) => Promise<Composable[]>;
@@ -1,28 +1,26 @@
1
- export const findCapturableElements = (element) => {
2
- const canvasAndSvgElements = element.querySelectorAll('svg,canvas,img');
3
- const composables = [];
4
- Array.from(canvasAndSvgElements).forEach((capturableElement) => {
5
- if (capturableElement.tagName.toLocaleLowerCase() === 'canvas') {
6
- const canvas = capturableElement;
7
- composables.push({
8
- type: 'canvas',
9
- element: canvas,
10
- });
1
+ import { drawElementToCanvas } from './drawing/draw-element-to-canvas';
2
+ export const findCapturableElements = async (element, context) => {
3
+ const treeWalker = document.createTreeWalker(element, NodeFilter.SHOW_ELEMENT | NodeFilter.SHOW_TEXT, (node) => {
4
+ if (node instanceof Element) {
5
+ const computedStyle = getComputedStyle(node);
6
+ return computedStyle.display === 'none'
7
+ ? NodeFilter.FILTER_REJECT
8
+ : NodeFilter.FILTER_ACCEPT;
11
9
  }
12
- else if (capturableElement.tagName.toLocaleLowerCase() === 'svg') {
13
- const svg = capturableElement;
14
- composables.push({
15
- type: 'svg',
16
- element: svg,
17
- });
18
- }
19
- else if (capturableElement.tagName.toLocaleLowerCase() === 'img') {
20
- const img = capturableElement;
10
+ return NodeFilter.FILTER_ACCEPT;
11
+ });
12
+ const composables = [];
13
+ while (treeWalker.nextNode()) {
14
+ const node = treeWalker.currentNode;
15
+ if (node instanceof HTMLCanvasElement ||
16
+ node instanceof SVGSVGElement ||
17
+ node instanceof HTMLImageElement) {
18
+ await drawElementToCanvas(node, context);
21
19
  composables.push({
22
- type: 'img',
23
- element: img,
20
+ type: 'element',
21
+ element: node,
24
22
  });
25
23
  }
26
- });
24
+ }
27
25
  return composables;
28
26
  };
@@ -1,15 +1,28 @@
1
+ import { parseOutlineOffset, parseOutlineWidth } from './drawing/draw-outline';
2
+ import { skipToNextNonDescendant } from './walk-tree';
1
3
  export const getBiggestBoundingClientRect = (element) => {
2
4
  const treeWalker = document.createTreeWalker(element, NodeFilter.SHOW_ELEMENT);
3
5
  let mostLeft = Infinity;
4
6
  let mostTop = Infinity;
5
7
  let mostRight = -Infinity;
6
8
  let mostBottom = -Infinity;
7
- while (treeWalker.nextNode()) {
9
+ while (true) {
10
+ const computedStyle = getComputedStyle(treeWalker.currentNode);
11
+ const outlineWidth = parseOutlineWidth(computedStyle.outlineWidth);
12
+ const outlineOffset = parseOutlineOffset(computedStyle.outlineOffset);
8
13
  const rect = treeWalker.currentNode.getBoundingClientRect();
9
- mostLeft = Math.min(mostLeft, rect.left);
10
- mostTop = Math.min(mostTop, rect.top);
11
- mostRight = Math.max(mostRight, rect.right);
12
- mostBottom = Math.max(mostBottom, rect.bottom);
14
+ mostLeft = Math.min(mostLeft, rect.left - outlineOffset - outlineWidth);
15
+ mostTop = Math.min(mostTop, rect.top - outlineOffset - outlineWidth);
16
+ mostRight = Math.max(mostRight, rect.right + outlineOffset + outlineWidth);
17
+ mostBottom = Math.max(mostBottom, rect.bottom + outlineOffset + outlineWidth);
18
+ if (computedStyle.overflow === 'hidden') {
19
+ if (!skipToNextNonDescendant(treeWalker)) {
20
+ break;
21
+ }
22
+ }
23
+ if (!treeWalker.nextNode()) {
24
+ break;
25
+ }
13
26
  }
14
27
  return new DOMRect(mostLeft, mostTop, mostRight - mostLeft, mostBottom - mostTop);
15
28
  };
@@ -0,0 +1,9 @@
1
+ export declare const makeInternalState: () => {
2
+ getDrawn3dPixels: () => number;
3
+ getDrawn3dTextures: () => number;
4
+ add3DTransform: ({ canvasWidth, canvasHeight, }: {
5
+ canvasWidth: number;
6
+ canvasHeight: number;
7
+ }) => void;
8
+ };
9
+ export type InternalState = ReturnType<typeof makeInternalState>;
@@ -0,0 +1,12 @@
1
+ export const makeInternalState = () => {
2
+ let drawn3dPixels = 0;
3
+ let drawn3dTextures = 0;
4
+ return {
5
+ getDrawn3dPixels: () => drawn3dPixels,
6
+ getDrawn3dTextures: () => drawn3dTextures,
7
+ add3DTransform: ({ canvasWidth, canvasHeight, }) => {
8
+ drawn3dPixels += canvasWidth * canvasHeight;
9
+ drawn3dTextures++;
10
+ },
11
+ };
12
+ };
@@ -0,0 +1,4 @@
1
+ export declare const setOpacity: ({ ctx, opacity, }: {
2
+ ctx: OffscreenCanvasRenderingContext2D;
3
+ opacity: number;
4
+ }) => () => void;
@@ -0,0 +1,7 @@
1
+ export const setOpacity = ({ ctx, opacity, }) => {
2
+ const previousAlpha = ctx.globalAlpha;
3
+ ctx.globalAlpha = opacity;
4
+ return () => {
5
+ ctx.globalAlpha = previousAlpha;
6
+ };
7
+ };
@@ -2,6 +2,7 @@ import { type LogLevel } from 'remotion';
2
2
  import type { AnyZodObject, z } from 'zod';
3
3
  import { type OnArtifact } from './artifact';
4
4
  import { type FrameRange } from './frame-range';
5
+ import type { InternalState } from './internal-state';
5
6
  import type { WebRendererContainer, WebRendererQuality } from './mediabunny-mappings';
6
7
  import { type WebRendererCodec } from './mediabunny-mappings';
7
8
  import type { WebRendererOutputTarget } from './output-target';
@@ -25,6 +26,7 @@ export type RenderMediaOnWebProgress = {
25
26
  };
26
27
  export type RenderMediaOnWebResult = {
27
28
  getBlob: () => Promise<Blob>;
29
+ internalState: InternalState;
28
30
  };
29
31
  export type RenderMediaOnWebProgressCallback = (progress: RenderMediaOnWebProgress) => void;
30
32
  type OptionalRenderMediaOnWebOptions<Schema extends AnyZodObject> = {
@@ -44,6 +46,7 @@ type OptionalRenderMediaOnWebOptions<Schema extends AnyZodObject> = {
44
46
  onArtifact: OnArtifact | null;
45
47
  onFrame: OnFrameCallback | null;
46
48
  outputTarget: WebRendererOutputTarget | null;
49
+ licenseKey: string | undefined;
47
50
  };
48
51
  export type RenderMediaOnWebOptions<Schema extends AnyZodObject, Props extends Record<string, unknown>> = MandatoryRenderMediaOnWebOptions<Schema, Props> & Partial<OptionalRenderMediaOnWebOptions<Schema>> & InputPropsIfHasProps<Schema, Props>;
49
52
  export declare const renderMediaOnWeb: <Schema extends AnyZodObject, Props extends Record<string, unknown>>(options: RenderMediaOnWebOptions<Schema, Props>) => Promise<RenderMediaOnWebResult>;
@@ -7,8 +7,10 @@ import { canUseWebFsWriter } from './can-use-webfs-target';
7
7
  import { createScaffold } from './create-scaffold';
8
8
  import { getRealFrameRange } from './frame-range';
9
9
  import { getDefaultAudioEncodingConfig } from './get-audio-encoding-config';
10
+ import { makeInternalState } from './internal-state';
10
11
  import { codecToMediabunnyCodec, containerToMediabunnyContainer, getDefaultVideoCodecForContainer, getMimeType, getQualityForWebRendererQuality, } from './mediabunny-mappings';
11
12
  import { onlyOneRenderAtATimeQueue } from './render-operations-queue';
13
+ import { sendUsageEvent } from './send-telemetry-event';
12
14
  import { createFrame } from './take-screenshot';
13
15
  import { createThrottledProgressCallback } from './throttle-progress';
14
16
  import { validateVideoFrame } from './validate-video-frame';
@@ -19,7 +21,7 @@ import { cleanupStaleOpfsFiles, createWebFsTarget } from './web-fs-target';
19
21
  // TODO: Metadata
20
22
  // TODO: Validating inputs
21
23
  // TODO: Apply defaultCodec
22
- const internalRenderMediaOnWeb = async ({ composition, inputProps, delayRenderTimeoutInMilliseconds, logLevel, mediaCacheSizeInBytes, schema, codec, container, signal, onProgress, hardwareAcceleration, keyframeIntervalInSeconds, videoBitrate, frameRange, transparent, onArtifact, onFrame, outputTarget: userDesiredOutputTarget, }) => {
24
+ const internalRenderMediaOnWeb = async ({ composition, inputProps, delayRenderTimeoutInMilliseconds, logLevel, mediaCacheSizeInBytes, schema, codec, container, signal, onProgress, hardwareAcceleration, keyframeIntervalInSeconds, videoBitrate, frameRange, transparent, onArtifact, onFrame, outputTarget: userDesiredOutputTarget, licenseKey, }) => {
23
25
  var _a, _b, _c, _d, _e, _f, _g;
24
26
  const outputTarget = userDesiredOutputTarget === null
25
27
  ? (await canUseWebFsWriter())
@@ -68,6 +70,7 @@ const internalRenderMediaOnWeb = async ({ composition, inputProps, delayRenderTi
68
70
  defaultCodec: resolved.defaultCodec,
69
71
  defaultOutName: resolved.defaultOutName,
70
72
  });
73
+ const internalState = makeInternalState();
71
74
  const artifactsHandler = handleArtifacts();
72
75
  cleanupFns.push(() => {
73
76
  cleanupScaffold();
@@ -151,6 +154,8 @@ const internalRenderMediaOnWeb = async ({ composition, inputProps, delayRenderTi
151
154
  div,
152
155
  width: resolved.width,
153
156
  height: resolved.height,
157
+ logLevel,
158
+ internalState,
154
159
  });
155
160
  if (signal === null || signal === void 0 ? void 0 : signal.aborted) {
156
161
  throw new Error('renderMediaOnWeb() was cancelled');
@@ -211,11 +216,17 @@ const internalRenderMediaOnWeb = async ({ composition, inputProps, delayRenderTi
211
216
  getBlob: () => {
212
217
  return webFsTarget.getBlob();
213
218
  },
219
+ internalState,
214
220
  };
215
221
  }
216
222
  if (!(target instanceof BufferTarget)) {
217
223
  throw new Error('Expected target to be a BufferTarget');
218
224
  }
225
+ sendUsageEvent({
226
+ licenseKey: licenseKey !== null && licenseKey !== void 0 ? licenseKey : null,
227
+ succeeded: true,
228
+ apiName: 'renderMediaOnWeb',
229
+ });
219
230
  return {
220
231
  getBlob: () => {
221
232
  if (!target.buffer) {
@@ -223,8 +234,19 @@ const internalRenderMediaOnWeb = async ({ composition, inputProps, delayRenderTi
223
234
  }
224
235
  return Promise.resolve(new Blob([target.buffer], { type: mimeType }));
225
236
  },
237
+ internalState,
226
238
  };
227
239
  }
240
+ catch (err) {
241
+ sendUsageEvent({
242
+ succeeded: false,
243
+ licenseKey: licenseKey !== null && licenseKey !== void 0 ? licenseKey : null,
244
+ apiName: 'renderMediaOnWeb',
245
+ }).catch((err2) => {
246
+ Internals.Log.error({ logLevel: 'error', tag: 'web-renderer' }, 'Failed to send usage event', err2);
247
+ });
248
+ throw err;
249
+ }
228
250
  finally {
229
251
  cleanupFns.forEach((fn) => fn());
230
252
  }
@@ -236,25 +258,26 @@ export const renderMediaOnWeb = (options) => {
236
258
  onlyOneRenderAtATimeQueue.ref = onlyOneRenderAtATimeQueue.ref
237
259
  .catch(() => Promise.resolve())
238
260
  .then(() => {
239
- var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p;
261
+ var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r;
240
262
  return internalRenderMediaOnWeb({
241
263
  ...options,
242
264
  delayRenderTimeoutInMilliseconds: (_a = options.delayRenderTimeoutInMilliseconds) !== null && _a !== void 0 ? _a : 30000,
243
- logLevel: (_b = options.logLevel) !== null && _b !== void 0 ? _b : 'info',
244
- schema: (_c = options.schema) !== null && _c !== void 0 ? _c : undefined,
245
- mediaCacheSizeInBytes: (_d = options.mediaCacheSizeInBytes) !== null && _d !== void 0 ? _d : null,
265
+ logLevel: (_c = (_b = options.logLevel) !== null && _b !== void 0 ? _b : window.remotion_logLevel) !== null && _c !== void 0 ? _c : 'info',
266
+ schema: (_d = options.schema) !== null && _d !== void 0 ? _d : undefined,
267
+ mediaCacheSizeInBytes: (_e = options.mediaCacheSizeInBytes) !== null && _e !== void 0 ? _e : null,
246
268
  codec,
247
269
  container,
248
- signal: (_e = options.signal) !== null && _e !== void 0 ? _e : null,
249
- onProgress: (_f = options.onProgress) !== null && _f !== void 0 ? _f : null,
250
- hardwareAcceleration: (_g = options.hardwareAcceleration) !== null && _g !== void 0 ? _g : 'no-preference',
251
- keyframeIntervalInSeconds: (_h = options.keyframeIntervalInSeconds) !== null && _h !== void 0 ? _h : 5,
252
- videoBitrate: (_j = options.videoBitrate) !== null && _j !== void 0 ? _j : 'medium',
253
- frameRange: (_k = options.frameRange) !== null && _k !== void 0 ? _k : null,
254
- transparent: (_l = options.transparent) !== null && _l !== void 0 ? _l : false,
255
- onArtifact: (_m = options.onArtifact) !== null && _m !== void 0 ? _m : null,
256
- onFrame: (_o = options.onFrame) !== null && _o !== void 0 ? _o : null,
257
- outputTarget: (_p = options.outputTarget) !== null && _p !== void 0 ? _p : null,
270
+ signal: (_f = options.signal) !== null && _f !== void 0 ? _f : null,
271
+ onProgress: (_g = options.onProgress) !== null && _g !== void 0 ? _g : null,
272
+ hardwareAcceleration: (_h = options.hardwareAcceleration) !== null && _h !== void 0 ? _h : 'no-preference',
273
+ keyframeIntervalInSeconds: (_j = options.keyframeIntervalInSeconds) !== null && _j !== void 0 ? _j : 5,
274
+ videoBitrate: (_k = options.videoBitrate) !== null && _k !== void 0 ? _k : 'medium',
275
+ frameRange: (_l = options.frameRange) !== null && _l !== void 0 ? _l : null,
276
+ transparent: (_m = options.transparent) !== null && _m !== void 0 ? _m : false,
277
+ onArtifact: (_o = options.onArtifact) !== null && _o !== void 0 ? _o : null,
278
+ onFrame: (_p = options.onFrame) !== null && _p !== void 0 ? _p : null,
279
+ outputTarget: (_q = options.outputTarget) !== null && _q !== void 0 ? _q : null,
280
+ licenseKey: (_r = options.licenseKey) !== null && _r !== void 0 ? _r : undefined,
258
281
  });
259
282
  });
260
283
  return onlyOneRenderAtATimeQueue.ref;
@@ -1,6 +1,7 @@
1
1
  import { type LogLevel } from 'remotion';
2
2
  import type { AnyZodObject } from 'zod';
3
3
  import type { OnArtifact } from './artifact';
4
+ import type { InternalState } from './internal-state';
4
5
  import type { CompositionCalculateMetadataOrExplicit } from './props-if-has-props';
5
6
  import type { InputPropsIfHasProps } from './render-media-on-web';
6
7
  export type RenderStillOnWebImageFormat = 'png' | 'jpeg' | 'webp';
@@ -17,7 +18,11 @@ type OptionalRenderStillOnWebOptions<Schema extends AnyZodObject> = {
17
18
  mediaCacheSizeInBytes: number | null;
18
19
  signal: AbortSignal | null;
19
20
  onArtifact: OnArtifact | null;
21
+ licenseKey: string | undefined;
20
22
  };
21
23
  export type RenderStillOnWebOptions<Schema extends AnyZodObject, Props extends Record<string, unknown>> = MandatoryRenderStillOnWebOptions<Schema, Props> & Partial<OptionalRenderStillOnWebOptions<Schema>> & InputPropsIfHasProps<Schema, Props>;
22
- export declare const renderStillOnWeb: <Schema extends AnyZodObject, Props extends Record<string, unknown>>(options: RenderStillOnWebOptions<Schema, Props>) => Promise<Blob>;
24
+ export declare const renderStillOnWeb: <Schema extends AnyZodObject, Props extends Record<string, unknown>>(options: RenderStillOnWebOptions<Schema, Props>) => Promise<{
25
+ blob: Blob;
26
+ internalState: InternalState;
27
+ }>;
23
28
  export {};
@@ -1,10 +1,12 @@
1
1
  import { Internals, } from 'remotion';
2
2
  import { handleArtifacts } from './artifact';
3
3
  import { createScaffold } from './create-scaffold';
4
+ import { makeInternalState } from './internal-state';
4
5
  import { onlyOneRenderAtATimeQueue } from './render-operations-queue';
6
+ import { sendUsageEvent } from './send-telemetry-event';
5
7
  import { takeScreenshot } from './take-screenshot';
6
8
  import { waitForReady } from './wait-for-ready';
7
- async function internalRenderStillOnWeb({ frame, delayRenderTimeoutInMilliseconds, logLevel, inputProps, schema, imageFormat, mediaCacheSizeInBytes, composition, signal, onArtifact, }) {
9
+ async function internalRenderStillOnWeb({ frame, delayRenderTimeoutInMilliseconds, logLevel, inputProps, schema, imageFormat, mediaCacheSizeInBytes, composition, signal, onArtifact, licenseKey, }) {
8
10
  var _a, _b, _c, _d, _e, _f;
9
11
  const resolved = await Internals.resolveVideoConfig({
10
12
  calculateMetadata: (_a = composition.calculateMetadata) !== null && _a !== void 0 ? _a : null,
@@ -20,6 +22,7 @@ async function internalRenderStillOnWeb({ frame, delayRenderTimeoutInMillisecond
20
22
  if (signal === null || signal === void 0 ? void 0 : signal.aborted) {
21
23
  return Promise.reject(new Error('renderStillOnWeb() was cancelled'));
22
24
  }
25
+ const internalState = makeInternalState();
23
26
  const { delayRenderScope, div, cleanupScaffold, collectAssets } = await createScaffold({
24
27
  width: resolved.width,
25
28
  height: resolved.height,
@@ -57,12 +60,29 @@ async function internalRenderStillOnWeb({ frame, delayRenderTimeoutInMillisecond
57
60
  width: resolved.width,
58
61
  height: resolved.height,
59
62
  imageFormat,
63
+ logLevel,
64
+ internalState,
60
65
  });
61
66
  const assets = collectAssets.current.collectAssets();
62
67
  if (onArtifact) {
63
68
  await artifactsHandler.handle({ imageData, frame, assets, onArtifact });
64
69
  }
65
- return imageData;
70
+ sendUsageEvent({
71
+ licenseKey: licenseKey !== null && licenseKey !== void 0 ? licenseKey : null,
72
+ succeeded: true,
73
+ apiName: 'renderStillOnWeb',
74
+ });
75
+ return { blob: imageData, internalState };
76
+ }
77
+ catch (err) {
78
+ sendUsageEvent({
79
+ succeeded: false,
80
+ licenseKey: licenseKey !== null && licenseKey !== void 0 ? licenseKey : null,
81
+ apiName: 'renderStillOnWeb',
82
+ }).catch((err2) => {
83
+ Internals.Log.error({ logLevel: 'error', tag: 'web-renderer' }, 'Failed to send usage event', err2);
84
+ });
85
+ throw err;
66
86
  }
67
87
  finally {
68
88
  cleanupScaffold();
@@ -72,15 +92,16 @@ export const renderStillOnWeb = (options) => {
72
92
  onlyOneRenderAtATimeQueue.ref = onlyOneRenderAtATimeQueue.ref
73
93
  .catch(() => Promise.resolve())
74
94
  .then(() => {
75
- var _a, _b, _c, _d, _e, _f;
95
+ var _a, _b, _c, _d, _e, _f, _g, _h;
76
96
  return internalRenderStillOnWeb({
77
97
  ...options,
78
98
  delayRenderTimeoutInMilliseconds: (_a = options.delayRenderTimeoutInMilliseconds) !== null && _a !== void 0 ? _a : 30000,
79
- logLevel: (_b = options.logLevel) !== null && _b !== void 0 ? _b : 'info',
80
- schema: (_c = options.schema) !== null && _c !== void 0 ? _c : undefined,
81
- mediaCacheSizeInBytes: (_d = options.mediaCacheSizeInBytes) !== null && _d !== void 0 ? _d : null,
82
- signal: (_e = options.signal) !== null && _e !== void 0 ? _e : null,
83
- onArtifact: (_f = options.onArtifact) !== null && _f !== void 0 ? _f : null,
99
+ logLevel: (_c = (_b = options.logLevel) !== null && _b !== void 0 ? _b : window.remotion_logLevel) !== null && _c !== void 0 ? _c : 'info',
100
+ schema: (_d = options.schema) !== null && _d !== void 0 ? _d : undefined,
101
+ mediaCacheSizeInBytes: (_e = options.mediaCacheSizeInBytes) !== null && _e !== void 0 ? _e : null,
102
+ signal: (_f = options.signal) !== null && _f !== void 0 ? _f : null,
103
+ onArtifact: (_g = options.onArtifact) !== null && _g !== void 0 ? _g : null,
104
+ licenseKey: (_h = options.licenseKey) !== null && _h !== void 0 ? _h : undefined,
84
105
  });
85
106
  });
86
107
  return onlyOneRenderAtATimeQueue.ref;
@@ -14,7 +14,7 @@ export const sendUsageEvent = async ({ licenseKey, succeeded, apiName, }) => {
14
14
  Internals.Log.warn({ logLevel: 'warn', tag: 'web-renderer' }, `Pass "licenseKey" to ${apiName}(). If you qualify for the free license (https://remotion.dev/license), pass "free-license" instead.`);
15
15
  }
16
16
  await registerUsageEvent({
17
- apiKey: licenseKey,
17
+ apiKey: licenseKey === 'free-license' ? null : licenseKey,
18
18
  event: 'webcodec-conversion',
19
19
  host,
20
20
  succeeded,
@@ -1,12 +1,18 @@
1
+ import type { LogLevel } from 'remotion';
2
+ import type { InternalState } from './internal-state';
1
3
  import type { RenderStillOnWebImageFormat } from './render-still-on-web';
2
- export declare const createFrame: ({ div, width, height, }: {
4
+ export declare const createFrame: ({ div, width, height, logLevel, internalState, }: {
3
5
  div: HTMLDivElement;
4
6
  width: number;
5
7
  height: number;
8
+ logLevel: LogLevel;
9
+ internalState: InternalState;
6
10
  }) => Promise<OffscreenCanvas>;
7
- export declare const takeScreenshot: ({ div, width, height, imageFormat, }: {
11
+ export declare const takeScreenshot: ({ div, width, height, imageFormat, logLevel, internalState, }: {
8
12
  div: HTMLDivElement;
9
13
  width: number;
10
14
  height: number;
11
15
  imageFormat: RenderStillOnWebImageFormat;
16
+ logLevel: LogLevel;
17
+ internalState: InternalState;
12
18
  }) => Promise<Blob>;
@@ -1,15 +1,27 @@
1
1
  import { compose } from './compose';
2
- export const createFrame = async ({ div, width, height, }) => {
2
+ export const createFrame = async ({ div, width, height, logLevel, internalState, }) => {
3
3
  const canvas = new OffscreenCanvas(width, height);
4
4
  const context = canvas.getContext('2d');
5
5
  if (!context) {
6
6
  throw new Error('Could not get context');
7
7
  }
8
- await compose({ element: div, context, offsetLeft: 0, offsetTop: 0 });
8
+ await compose({
9
+ element: div,
10
+ context,
11
+ logLevel,
12
+ parentRect: new DOMRect(0, 0, width, height),
13
+ internalState,
14
+ });
9
15
  return canvas;
10
16
  };
11
- export const takeScreenshot = async ({ div, width, height, imageFormat, }) => {
12
- const frame = await createFrame({ div, width, height });
17
+ export const takeScreenshot = async ({ div, width, height, imageFormat, logLevel, internalState, }) => {
18
+ const frame = await createFrame({
19
+ div,
20
+ width,
21
+ height,
22
+ logLevel,
23
+ internalState,
24
+ });
13
25
  const imageData = await frame.convertToBlob({
14
26
  type: `image/${imageFormat}`,
15
27
  });
@@ -0,0 +1,4 @@
1
+ export declare const setTransform: ({ ctx, transform, }: {
2
+ ctx: OffscreenCanvasRenderingContext2D;
3
+ transform: DOMMatrix;
4
+ }) => () => void;
@@ -0,0 +1,6 @@
1
+ export const setTransform = ({ ctx, transform, }) => {
2
+ ctx.setTransform(transform);
3
+ return () => {
4
+ ctx.setTransform(new DOMMatrix());
5
+ };
6
+ };
package/package.json CHANGED
@@ -3,7 +3,7 @@
3
3
  "url": "https://github.com/remotion-dev/remotion/tree/main/packages/web-renderer"
4
4
  },
5
5
  "name": "@remotion/web-renderer",
6
- "version": "4.0.394",
6
+ "version": "4.0.396",
7
7
  "main": "dist/index.js",
8
8
  "sideEffects": false,
9
9
  "scripts": {
@@ -16,13 +16,14 @@
16
16
  "author": "Remotion <jonny@remotion.dev>",
17
17
  "license": "UNLICENSED",
18
18
  "dependencies": {
19
- "remotion": "4.0.394",
20
- "mediabunny": "1.27.0"
19
+ "@remotion/licensing": "4.0.396",
20
+ "remotion": "4.0.396",
21
+ "mediabunny": "1.27.2"
21
22
  },
22
23
  "devDependencies": {
23
- "@remotion/eslint-config-internal": "4.0.394",
24
- "@remotion/player": "4.0.394",
25
- "@remotion/media": "4.0.394",
24
+ "@remotion/eslint-config-internal": "4.0.396",
25
+ "@remotion/player": "4.0.396",
26
+ "@remotion/media": "4.0.396",
26
27
  "@vitejs/plugin-react": "4.1.0",
27
28
  "@vitest/browser-playwright": "4.0.9",
28
29
  "playwright": "1.55.1",