@remotion/web-renderer 4.0.432 → 4.0.434

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.
@@ -0,0 +1,4 @@
1
+ export declare const setFilter: ({ ctx, filter, }: {
2
+ ctx: OffscreenCanvasRenderingContext2D;
3
+ filter: string;
4
+ }) => () => void;
@@ -115,6 +115,7 @@ var checkWebGLSupport = () => {
115
115
  // src/mediabunny-mappings.ts
116
116
  import {
117
117
  AdtsOutputFormat,
118
+ FlacOutputFormat,
118
119
  MkvOutputFormat,
119
120
  MovOutputFormat,
120
121
  Mp3OutputFormat,
@@ -129,7 +130,7 @@ import {
129
130
  WebMOutputFormat
130
131
  } from "mediabunny";
131
132
  var isAudioOnlyContainer = (container) => {
132
- return container === "wav" || container === "mp3" || container === "aac" || container === "ogg";
133
+ return container === "wav" || container === "mp3" || container === "aac" || container === "ogg" || container === "flac";
133
134
  };
134
135
  var codecToMediabunnyCodec = (codec) => {
135
136
  switch (codec) {
@@ -163,6 +164,8 @@ var containerToMediabunnyContainer = (container) => {
163
164
  return new AdtsOutputFormat;
164
165
  case "ogg":
165
166
  return new OggOutputFormat;
167
+ case "flac":
168
+ return new FlacOutputFormat;
166
169
  case "mov":
167
170
  return new MovOutputFormat({ fastStart: "reserve" });
168
171
  default:
@@ -182,6 +185,7 @@ var getDefaultVideoCodecForContainer = (container) => {
182
185
  case "mp3":
183
186
  case "aac":
184
187
  case "ogg":
188
+ case "flac":
185
189
  return null;
186
190
  default:
187
191
  throw new Error(`Unsupported container: ${container}`);
@@ -232,6 +236,8 @@ var getMimeType = (container) => {
232
236
  return "audio/aac";
233
237
  case "ogg":
234
238
  return "audio/ogg";
239
+ case "flac":
240
+ return "audio/flac";
235
241
  case "mov":
236
242
  return "video/quicktime";
237
243
  default:
@@ -254,6 +260,8 @@ var getDefaultAudioCodecForContainer = (container) => {
254
260
  return "aac";
255
261
  case "ogg":
256
262
  return "opus";
263
+ case "flac":
264
+ return "flac";
257
265
  case "mov":
258
266
  return "aac";
259
267
  default:
@@ -280,7 +288,8 @@ var WEB_RENDERER_AUDIO_CODECS = [
280
288
  "opus",
281
289
  "mp3",
282
290
  "vorbis",
283
- "pcm-s16"
291
+ "pcm-s16",
292
+ "flac"
284
293
  ];
285
294
  var audioCodecToMediabunnyAudioCodec = (audioCodec) => {
286
295
  switch (audioCodec) {
@@ -294,6 +303,8 @@ var audioCodecToMediabunnyAudioCodec = (audioCodec) => {
294
303
  return "vorbis";
295
304
  case "pcm-s16":
296
305
  return "pcm-s16";
306
+ case "flac":
307
+ return "flac";
297
308
  default:
298
309
  throw new Error(`Unsupported audio codec: ${audioCodec}`);
299
310
  }
@@ -305,25 +316,59 @@ var getSupportedAudioCodecsForContainer = (container) => {
305
316
  };
306
317
 
307
318
  // src/resolve-audio-codec.ts
308
- import { canEncodeAudio as canEncodeAudio2 } from "mediabunny";
319
+ import { canEncodeAudio as canEncodeAudio4 } from "mediabunny";
309
320
 
310
- // src/register-mp3-encoder.ts
321
+ // src/register-aac-encoder.ts
311
322
  import { canEncodeAudio } from "mediabunny";
312
323
  var registrationPromise = null;
313
324
  var doRegister = async () => {
314
- const nativeSupport = await canEncodeAudio("mp3");
325
+ const nativeSupport = await canEncodeAudio("aac");
315
326
  if (!nativeSupport) {
316
- const { registerMp3Encoder } = await import("@mediabunny/mp3-encoder");
317
- registerMp3Encoder();
327
+ const { registerAacEncoder } = await import("@mediabunny/aac-encoder");
328
+ registerAacEncoder();
318
329
  }
319
330
  };
320
- var ensureMp3EncoderRegistered = () => {
331
+ var ensureAacEncoderRegistered = () => {
321
332
  if (!registrationPromise) {
322
333
  registrationPromise = doRegister();
323
334
  }
324
335
  return registrationPromise;
325
336
  };
326
337
 
338
+ // src/register-flac-encoder.ts
339
+ import { canEncodeAudio as canEncodeAudio2 } from "mediabunny";
340
+ var registrationPromise2 = null;
341
+ var doRegister2 = async () => {
342
+ const nativeSupport = await canEncodeAudio2("flac");
343
+ if (!nativeSupport) {
344
+ const { registerFlacEncoder } = await import("@mediabunny/flac-encoder");
345
+ registerFlacEncoder();
346
+ }
347
+ };
348
+ var ensureFlacEncoderRegistered = () => {
349
+ if (!registrationPromise2) {
350
+ registrationPromise2 = doRegister2();
351
+ }
352
+ return registrationPromise2;
353
+ };
354
+
355
+ // src/register-mp3-encoder.ts
356
+ import { canEncodeAudio as canEncodeAudio3 } from "mediabunny";
357
+ var registrationPromise3 = null;
358
+ var doRegister3 = async () => {
359
+ const nativeSupport = await canEncodeAudio3("mp3");
360
+ if (!nativeSupport) {
361
+ const { registerMp3Encoder } = await import("@mediabunny/mp3-encoder");
362
+ registerMp3Encoder();
363
+ }
364
+ };
365
+ var ensureMp3EncoderRegistered = () => {
366
+ if (!registrationPromise3) {
367
+ registrationPromise3 = doRegister3();
368
+ }
369
+ return registrationPromise3;
370
+ };
371
+
327
372
  // src/resolve-audio-codec.ts
328
373
  var resolveAudioCodec = async (options) => {
329
374
  const issues = [];
@@ -342,7 +387,13 @@ var resolveAudioCodec = async (options) => {
342
387
  if (audioCodec === "mp3") {
343
388
  await ensureMp3EncoderRegistered();
344
389
  }
345
- const canEncode = await canEncodeAudio2(mediabunnyAudioCodec, { bitrate });
390
+ if (audioCodec === "aac") {
391
+ await ensureAacEncoderRegistered();
392
+ }
393
+ if (audioCodec === "flac") {
394
+ await ensureFlacEncoderRegistered();
395
+ }
396
+ const canEncode = await canEncodeAudio4(mediabunnyAudioCodec, { bitrate });
346
397
  if (canEncode) {
347
398
  return { codec: audioCodec, issues };
348
399
  }
@@ -359,8 +410,14 @@ var resolveAudioCodec = async (options) => {
359
410
  if (fallbackCodec === "mp3") {
360
411
  await ensureMp3EncoderRegistered();
361
412
  }
413
+ if (fallbackCodec === "aac") {
414
+ await ensureAacEncoderRegistered();
415
+ }
416
+ if (fallbackCodec === "flac") {
417
+ await ensureFlacEncoderRegistered();
418
+ }
362
419
  const fallbackMediabunnyCodec = audioCodecToMediabunnyAudioCodec(fallbackCodec);
363
- const canEncodeFallback = await canEncodeAudio2(fallbackMediabunnyCodec, {
420
+ const canEncodeFallback = await canEncodeAudio4(fallbackMediabunnyCodec, {
364
421
  bitrate
365
422
  });
366
423
  if (canEncodeFallback) {
@@ -513,6 +570,12 @@ var getEncodableAudioCodecs = async (container, options) => {
513
570
  if (supported.includes("mp3")) {
514
571
  await ensureMp3EncoderRegistered();
515
572
  }
573
+ if (supported.includes("aac")) {
574
+ await ensureAacEncoderRegistered();
575
+ }
576
+ if (supported.includes("flac")) {
577
+ await ensureFlacEncoderRegistered();
578
+ }
516
579
  const resolvedBitrate = options?.audioBitrate ? typeof options.audioBitrate === "number" ? options.audioBitrate : getQualityForWebRendererQuality(options.audioBitrate) : undefined;
517
580
  const encodable = await mediabunnyGetEncodableAudioCodecs(supported, {
518
581
  bitrate: resolvedBitrate
@@ -792,13 +855,73 @@ var UpdateTime = ({
792
855
  frameState: {
793
856
  [compId]: frame
794
857
  },
795
- nonceContextSeed: 0,
796
858
  children
797
859
  });
798
860
  };
799
861
 
800
862
  // src/create-scaffold.tsx
801
863
  import { jsx as jsx2 } from "react/jsx-runtime";
864
+ var GENERIC_REACT_RENDER_ERROR_MESSAGES = new Set([
865
+ "Error thrown during rendering"
866
+ ]);
867
+ var isMessageLikeObject = (err) => {
868
+ return typeof err === "object" && err !== null && "message" in err && typeof err.message === "string";
869
+ };
870
+ var unknownErrorToMessage = (err) => {
871
+ if (typeof err === "string") {
872
+ return err;
873
+ }
874
+ if (isMessageLikeObject(err)) {
875
+ return err.message;
876
+ }
877
+ try {
878
+ const serialized = JSON.stringify(err);
879
+ if (serialized) {
880
+ return serialized;
881
+ }
882
+ } catch {}
883
+ return String(err);
884
+ };
885
+ var setErrorCause = (error, cause) => {
886
+ try {
887
+ Object.defineProperty(error, "cause", {
888
+ value: cause,
889
+ enumerable: false,
890
+ configurable: true,
891
+ writable: true
892
+ });
893
+ } catch {}
894
+ };
895
+ var appendComponentStack = (error, componentStack) => {
896
+ if (!componentStack?.trim()) {
897
+ return error;
898
+ }
899
+ const normalizedComponentStack = componentStack.trim();
900
+ const stack = error.stack ?? `${error.name}: ${error.message}`;
901
+ if (stack.includes(normalizedComponentStack)) {
902
+ return error;
903
+ }
904
+ const errorTitle = `${error.name}: ${error.message}`;
905
+ const stackWithoutTitle = stack.startsWith(errorTitle) ? stack.slice(errorTitle.length).trimStart() : stack;
906
+ const stackBody = stackWithoutTitle.length > 0 ? `
907
+ ${stackWithoutTitle}` : "";
908
+ error.stack = `${errorTitle}
909
+ For the likely root cause, see "React component stack:" after the JavaScript stack trace below.${stackBody}
910
+ React component stack:
911
+ ${normalizedComponentStack}`;
912
+ return error;
913
+ };
914
+ var normalizeUncaughtReactError = (err, componentStack) => {
915
+ if (err instanceof Error) {
916
+ const { cause } = err;
917
+ const shouldUnwrapCause = cause instanceof Error && GENERIC_REACT_RENDER_ERROR_MESSAGES.has(err.message);
918
+ const errorToThrow = shouldUnwrapCause ? cause : err;
919
+ return appendComponentStack(errorToThrow, componentStack);
920
+ }
921
+ const normalized = new Error(unknownErrorToMessage(err));
922
+ setErrorCause(normalized, err);
923
+ return appendComponentStack(normalized, componentStack);
924
+ };
802
925
  function checkForError(errorHolder) {
803
926
  if (errorHolder.error) {
804
927
  throw errorHolder.error;
@@ -848,8 +971,8 @@ function createScaffold({
848
971
  document.body.appendChild(wrapper);
849
972
  const errorHolder = { error: null };
850
973
  const root = ReactDOM.createRoot(div, {
851
- onUncaughtError: (err) => {
852
- errorHolder.error = err instanceof Error ? err : new Error(String(err));
974
+ onUncaughtError: (err, errorInfo) => {
975
+ errorHolder.error = normalizeUncaughtReactError(err, errorInfo?.componentStack);
853
976
  }
854
977
  });
855
978
  const delayRenderScope = {
@@ -880,7 +1003,7 @@ function createScaffold({
880
1003
  {
881
1004
  id,
882
1005
  component: Component,
883
- nonce: 0,
1006
+ nonce: [[0, 0]],
884
1007
  defaultProps: {},
885
1008
  folderName: null,
886
1009
  parentFolderName: null,
@@ -2769,6 +2892,20 @@ var drawOutline = ({
2769
2892
  ctx.setLineDash(originalLineDash);
2770
2893
  };
2771
2894
 
2895
+ // src/drawing/filter.ts
2896
+ var setFilter = ({
2897
+ ctx,
2898
+ filter
2899
+ }) => {
2900
+ const previousFilter = ctx.filter;
2901
+ if (filter && filter !== "none") {
2902
+ ctx.filter = filter;
2903
+ }
2904
+ return () => {
2905
+ ctx.filter = previousFilter;
2906
+ };
2907
+ };
2908
+
2772
2909
  // src/drawing/opacity.ts
2773
2910
  var setOpacity = ({
2774
2911
  ctx,
@@ -2847,6 +2984,10 @@ var drawElement = async ({
2847
2984
  ctx: context,
2848
2985
  opacity
2849
2986
  });
2987
+ const finishFilter = setFilter({
2988
+ ctx: context,
2989
+ filter: computedStyle.filter
2990
+ });
2850
2991
  drawBorderRadius({
2851
2992
  ctx: context,
2852
2993
  computedStyle,
@@ -2901,6 +3042,7 @@ var drawElement = async ({
2901
3042
  finishTransform();
2902
3043
  return {
2903
3044
  cleanupAfterChildren: () => {
3045
+ finishFilter();
2904
3046
  finishOpacity();
2905
3047
  finishOverflowHidden();
2906
3048
  }
@@ -3503,7 +3645,8 @@ var drawText = ({
3503
3645
  webkitTextStrokeWidth,
3504
3646
  webkitTextStrokeColor,
3505
3647
  textShadow: textShadowValue,
3506
- paintOrder
3648
+ paintOrder,
3649
+ filter
3507
3650
  } = computedStyle;
3508
3651
  const isVertical = writingMode !== "horizontal-tb";
3509
3652
  if (isVertical) {
@@ -3514,6 +3657,10 @@ var drawText = ({
3514
3657
  return;
3515
3658
  }
3516
3659
  contextToDraw.save();
3660
+ const finishFilter = setFilter({
3661
+ ctx: contextToDraw,
3662
+ filter
3663
+ });
3517
3664
  const fontSizePx = parseFloat(fontSize);
3518
3665
  contextToDraw.font = `${fontStyle} ${fontWeight} ${fontSizePx}px ${fontFamily}`;
3519
3666
  contextToDraw.fillStyle = onlyBackgroundClipText ? "black" : webkitTextFillColor;
@@ -3568,6 +3715,7 @@ var drawText = ({
3568
3715
  }
3569
3716
  }
3570
3717
  span.textContent = originalText;
3718
+ finishFilter();
3571
3719
  contextToDraw.restore();
3572
3720
  };
3573
3721
  return drawFn;
@@ -1,8 +1,8 @@
1
1
  import type { Quality } from 'mediabunny';
2
2
  import { type OutputFormat } from 'mediabunny';
3
3
  export type WebRendererVideoCodec = 'h264' | 'h265' | 'vp8' | 'vp9' | 'av1';
4
- export type WebRendererContainer = 'mp4' | 'webm' | 'mkv' | 'mov' | 'wav' | 'mp3' | 'aac' | 'ogg';
5
- export type WebRendererAudioCodec = 'aac' | 'opus' | 'mp3' | 'vorbis' | 'pcm-s16';
4
+ export type WebRendererContainer = 'mp4' | 'webm' | 'mkv' | 'mov' | 'wav' | 'mp3' | 'aac' | 'ogg' | 'flac';
5
+ export type WebRendererAudioCodec = 'aac' | 'opus' | 'mp3' | 'vorbis' | 'pcm-s16' | 'flac';
6
6
  export type WebRendererQuality = 'very-low' | 'low' | 'medium' | 'high' | 'very-high';
7
7
  export declare const isAudioOnlyContainer: (container: WebRendererContainer) => boolean;
8
8
  export declare const codecToMediabunnyCodec: (codec: WebRendererVideoCodec) => "av1" | "avc" | "hevc" | "vp8" | "vp9";
@@ -0,0 +1 @@
1
+ export declare const ensureAacEncoderRegistered: () => Promise<void>;
@@ -0,0 +1 @@
1
+ export declare const ensureFlacEncoderRegistered: () => Promise<void>;
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.432",
6
+ "version": "4.0.434",
7
7
  "main": "dist/index.js",
8
8
  "type": "module",
9
9
  "scripts": {
@@ -19,19 +19,21 @@
19
19
  "author": "Remotion <jonny@remotion.dev>",
20
20
  "license": "UNLICENSED",
21
21
  "dependencies": {
22
- "@mediabunny/mp3-encoder": "1.35.1",
23
- "@remotion/licensing": "4.0.432",
24
- "remotion": "4.0.432",
25
- "mediabunny": "1.35.1"
22
+ "@mediabunny/mp3-encoder": "1.37.0",
23
+ "@mediabunny/aac-encoder": "1.37.0",
24
+ "@mediabunny/flac-encoder": "1.37.0",
25
+ "@remotion/licensing": "4.0.434",
26
+ "remotion": "4.0.434",
27
+ "mediabunny": "1.37.0"
26
28
  },
27
29
  "devDependencies": {
28
30
  "@react-three/fiber": "9.2.0",
29
- "@remotion/eslint-config-internal": "4.0.432",
30
- "@remotion/player": "4.0.432",
31
- "@remotion/media": "4.0.432",
32
- "@remotion/three": "4.0.432",
31
+ "@remotion/eslint-config-internal": "4.0.434",
32
+ "@remotion/player": "4.0.434",
33
+ "@remotion/media": "4.0.434",
34
+ "@remotion/three": "4.0.434",
33
35
  "@types/three": "0.170.0",
34
- "@typescript/native-preview": "7.0.0-dev.20260301.1",
36
+ "@typescript/native-preview": "7.0.0-dev.20260217.1",
35
37
  "@vitejs/plugin-react": "4.3.4",
36
38
  "@vitest/browser-playwright": "4.0.9",
37
39
  "playwright": "1.55.1",