remotion 4.0.520 → 4.0.521

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.
@@ -71,22 +71,10 @@ export declare const absoluteFillSchema: {
71
71
  readonly hiddenFromList: false;
72
72
  };
73
73
  readonly 'style.fontWeight': {
74
- readonly type: "enum";
75
- readonly default: "400";
74
+ readonly type: "font-weight";
75
+ readonly default: 400;
76
76
  readonly description: "Font weight";
77
- readonly variants: {
78
- readonly '100': {};
79
- readonly '200': {};
80
- readonly '300': {};
81
- readonly '400': {};
82
- readonly '500': {};
83
- readonly '600': {};
84
- readonly '700': {};
85
- readonly '800': {};
86
- readonly '900': {};
87
- readonly normal: {};
88
- readonly bold: {};
89
- };
77
+ readonly keyframable: false;
90
78
  };
91
79
  readonly 'style.fontStyle': {
92
80
  readonly type: "enum";
package/dist/cjs/Img.d.ts CHANGED
@@ -213,6 +213,7 @@ export declare const imgSchema: {
213
213
  readonly showInTimeline: import("./interactivity-schema.js").HiddenFieldSchema;
214
214
  readonly src: {
215
215
  readonly type: "asset";
216
+ readonly assetType: "image";
216
217
  readonly default: undefined;
217
218
  readonly description: "Source";
218
219
  readonly keyframable: false;
package/dist/cjs/Img.js CHANGED
@@ -224,6 +224,7 @@ const CanvasImageWithPrivateProps = index_js_1.CanvasImage;
224
224
  exports.imgSchema = {
225
225
  src: {
226
226
  type: 'asset',
227
+ assetType: 'image',
227
228
  default: undefined,
228
229
  description: 'Source',
229
230
  keyframable: false,
@@ -123,22 +123,10 @@ export declare const Interactive: {
123
123
  readonly hiddenFromList: false;
124
124
  };
125
125
  readonly 'style.fontWeight': {
126
- readonly type: "enum";
127
- readonly default: "400";
126
+ readonly type: "font-weight";
127
+ readonly default: 400;
128
128
  readonly description: "Font weight";
129
- readonly variants: {
130
- readonly '100': {};
131
- readonly '200': {};
132
- readonly '300': {};
133
- readonly '400': {};
134
- readonly '500': {};
135
- readonly '600': {};
136
- readonly '700': {};
137
- readonly '800': {};
138
- readonly '900': {};
139
- readonly normal: {};
140
- readonly bold: {};
141
- };
129
+ readonly keyframable: false;
142
130
  };
143
131
  readonly 'style.fontStyle': {
144
132
  readonly type: "enum";
@@ -201,6 +201,7 @@ export declare const animatedImageSchema: {
201
201
  readonly showInTimeline: import("../interactivity-schema.js").HiddenFieldSchema;
202
202
  readonly src: {
203
203
  readonly type: "asset";
204
+ readonly assetType: "image";
204
205
  readonly default: undefined;
205
206
  readonly description: "Source";
206
207
  readonly keyframable: false;
@@ -23,6 +23,7 @@ const resolve_image_source_1 = require("./resolve-image-source");
23
23
  exports.animatedImageSchema = {
24
24
  src: {
25
25
  type: 'asset',
26
+ assetType: 'image',
26
27
  default: undefined,
27
28
  description: 'Source',
28
29
  keyframable: false,
@@ -58,6 +58,7 @@ type SharedAudioContextValue = {
58
58
  audioSyncAnchorEmitter: AudioSyncAnchorEmitter;
59
59
  scheduleAudioNode: (options: ScheduleAudioNodeOptions) => ScheduleAudioNodeResult;
60
60
  resume: () => Promise<void>;
61
+ resumeAsAutoPlay: () => Promise<void>;
61
62
  suspend: () => Promise<void>;
62
63
  getIsResumingAudioContext: () => Promise<AudioContextResumeResult> | null;
63
64
  unscheduleAudioNode: (node: AudioBufferSourceNode) => void;
@@ -111,6 +111,7 @@ const SharedAudioContextProvider = ({ children, audioLatencyHint, audioEnabled,
111
111
  }
112
112
  const isResuming = (0, react_1.useRef)(null);
113
113
  const nextResumeAttemptId = (0, react_1.useRef)(0);
114
+ const nextResumeIsAutoPlayAttempt = (0, react_1.useRef)(false);
114
115
  const audioSyncAnchor = (0, react_1.useMemo)(() => ({ value: 0 }), []);
115
116
  const audioSyncAnchorListeners = (0, react_1.useRef)([]);
116
117
  const audioSyncAnchorEmitter = (0, react_1.useMemo)(() => {
@@ -201,6 +202,8 @@ const SharedAudioContextProvider = ({ children, audioLatencyHint, audioEnabled,
201
202
  };
202
203
  }, [ctxAndGain, _experimentalKeepAudioContextAlive, logLevel]);
203
204
  const resume = (0, react_1.useCallback)(() => {
205
+ const isAutoPlayAttempt = nextResumeIsAutoPlayAttempt.current;
206
+ nextResumeIsAutoPlayAttempt.current = false;
204
207
  if (!ctxAndGain) {
205
208
  return Promise.resolve();
206
209
  }
@@ -226,7 +229,7 @@ const SharedAudioContextProvider = ({ children, audioLatencyHint, audioEnabled,
226
229
  const abortController = new AbortController();
227
230
  const resumeAttemptId = nextResumeAttemptId.current++;
228
231
  const waitPromise = new Promise((resolve) => {
229
- (0, wait_until_actually_resumed_js_1.waitUntilActuallyResumed)(ctxAndGain.audioContext, logLevel, abortController.signal).then(resolve);
232
+ (0, wait_until_actually_resumed_js_1.waitUntilActuallyResumed)(ctxAndGain.audioContext, logLevel, abortController.signal, isAutoPlayAttempt).then(resolve);
230
233
  resumePromise.catch((err) => {
231
234
  log_js_1.Log.warn({ logLevel, tag: 'audio' }, 'AudioContext resume rejected, muting playback and continuing without audio', err);
232
235
  abortController.abort();
@@ -248,6 +251,10 @@ const SharedAudioContextProvider = ({ children, audioLatencyHint, audioEnabled,
248
251
  // since callers (e.g. use-playback.ts) do not await this.
249
252
  });
250
253
  }, [ctxAndGain, _experimentalKeepAudioContextAlive, logLevel]);
254
+ const resumeAsAutoPlay = (0, react_1.useCallback)(() => {
255
+ nextResumeIsAutoPlayAttempt.current = true;
256
+ return resume();
257
+ }, [resume]);
251
258
  const getIsResumingAudioContext = (0, react_1.useCallback)(() => {
252
259
  var _a;
253
260
  var _b;
@@ -326,6 +333,7 @@ const SharedAudioContextProvider = ({ children, audioLatencyHint, audioEnabled,
326
333
  audioSyncAnchorEmitter,
327
334
  scheduleAudioNode,
328
335
  resume,
336
+ resumeAsAutoPlay,
329
337
  suspend,
330
338
  getIsResumingAudioContext,
331
339
  unscheduleAudioNode,
@@ -337,6 +345,7 @@ const SharedAudioContextProvider = ({ children, audioLatencyHint, audioEnabled,
337
345
  audioSyncAnchorEmitter,
338
346
  scheduleAudioNode,
339
347
  resume,
348
+ resumeAsAutoPlay,
340
349
  suspend,
341
350
  getIsResumingAudioContext,
342
351
  unscheduleAudioNode,
@@ -1,2 +1,2 @@
1
1
  export type AudioContextResumeResult = 'resumed' | 'cancelled' | 'failed';
2
- export declare const waitUntilActuallyResumed: (audioContext: AudioContext, logLevel: "error" | "info" | "trace" | "verbose" | "warn", signal: AbortSignal) => Promise<AudioContextResumeResult>;
2
+ export declare const waitUntilActuallyResumed: (audioContext: AudioContext, logLevel: "error" | "info" | "trace" | "verbose" | "warn", signal: AbortSignal, isAutoPlayAttempt: boolean) => Promise<AudioContextResumeResult>;
@@ -3,7 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.waitUntilActuallyResumed = void 0;
4
4
  const log_js_1 = require("../log.js");
5
5
  const RESUME_WAIT_TIMEOUT = 1000;
6
- const waitUntilActuallyResumed = (audioContext, logLevel, signal) => {
6
+ const waitUntilActuallyResumed = (audioContext, logLevel, signal, isAutoPlayAttempt) => {
7
7
  return new Promise((resolve) => {
8
8
  const startCurrentTime = audioContext.currentTime;
9
9
  const start = audioContext.getOutputTimestamp();
@@ -55,19 +55,21 @@ const waitUntilActuallyResumed = (audioContext, logLevel, signal) => {
55
55
  return;
56
56
  }
57
57
  signal.addEventListener('abort', onAbort, { once: true });
58
- timeout = setTimeout(() => {
59
- // The success check is scheduled with requestAnimationFrame, which can
60
- // be starved while the main thread is busy. Re-check once before
61
- // declaring failure so a resume that actually completed is not
62
- // reported as failed - the Player would otherwise mute itself even
63
- // though playback was started by a user gesture and audio is running.
64
- if (hasAudiblyStarted(startOutputPerformanceTime)) {
65
- finish('resumed');
66
- return;
67
- }
68
- log_js_1.Log.warn({ logLevel, tag: 'audio' }, 'WARNING: You enabled autoPlay on an unmuted <Player /> and the browser did not allow the video to be started. Remotion muted the <Player /> so it can play. To properly handle this, either set the `muted` prop or remove the `autoPlay` prop');
69
- finish('failed');
70
- }, RESUME_WAIT_TIMEOUT);
58
+ if (isAutoPlayAttempt) {
59
+ timeout = setTimeout(() => {
60
+ // The success check is scheduled with requestAnimationFrame, which can
61
+ // be starved while the main thread is busy. Re-check once before
62
+ // declaring failure so a resume that actually completed is not
63
+ // reported as failed - the Player would otherwise mute itself even
64
+ // though playback was started by a user gesture and audio is running.
65
+ if (hasAudiblyStarted(startOutputPerformanceTime)) {
66
+ finish('resumed');
67
+ return;
68
+ }
69
+ log_js_1.Log.warn({ logLevel, tag: 'audio' }, 'WARNING: You enabled autoPlay on an unmuted <Player /> and the browser did not allow the video to be started. Remotion muted the <Player /> so it can play. To properly handle this, either set the `muted` prop or remove the `autoPlay` prop');
70
+ finish('failed');
71
+ }, RESUME_WAIT_TIMEOUT);
72
+ }
71
73
  animationFrame = requestAnimationFrame(check);
72
74
  });
73
75
  };
@@ -201,6 +201,7 @@ export declare const canvasImageSchema: {
201
201
  readonly showInTimeline: import("../interactivity-schema.js").HiddenFieldSchema;
202
202
  readonly src: {
203
203
  readonly type: "asset";
204
+ readonly assetType: "image";
204
205
  readonly default: undefined;
205
206
  readonly description: "Source";
206
207
  readonly keyframable: false;
@@ -22,6 +22,7 @@ const with_interactivity_schema_js_1 = require("../with-interactivity-schema.js"
22
22
  exports.canvasImageSchema = {
23
23
  src: {
24
24
  type: 'asset',
25
+ assetType: 'image',
25
26
  default: undefined,
26
27
  description: 'Source',
27
28
  keyframable: false,
@@ -97,8 +97,15 @@ export type FontFamilyFieldSchema = {
97
97
  description?: string;
98
98
  keyframable?: false;
99
99
  };
100
+ export type FontWeightFieldSchema = {
101
+ type: 'font-weight';
102
+ default: number | string | undefined;
103
+ description?: string;
104
+ keyframable?: false;
105
+ };
100
106
  export type AssetFieldSchema = {
101
107
  type: 'asset';
108
+ assetType?: 'audio' | 'video' | 'image';
102
109
  default: string | undefined;
103
110
  description?: string;
104
111
  keyframable?: false;
@@ -138,7 +145,7 @@ export type CaptionsFieldSchema = {
138
145
  description?: string;
139
146
  keyframable: false;
140
147
  };
141
- export type VisibleFieldSchema = NumberFieldSchema | BooleanFieldSchema | RotationCssFieldSchema | RotationDegreesFieldSchema | TranslateFieldSchema | TransformOriginFieldSchema | ScaleFieldSchema | UvCoordinateFieldSchema | ColorFieldSchema | TextContentFieldSchema | FontFamilyFieldSchema | AssetFieldSchema | ArrayFieldSchema | CaptionsFieldSchema | EnumFieldSchema;
148
+ export type VisibleFieldSchema = NumberFieldSchema | BooleanFieldSchema | RotationCssFieldSchema | RotationDegreesFieldSchema | TranslateFieldSchema | TransformOriginFieldSchema | ScaleFieldSchema | UvCoordinateFieldSchema | ColorFieldSchema | TextContentFieldSchema | FontFamilyFieldSchema | FontWeightFieldSchema | AssetFieldSchema | ArrayFieldSchema | CaptionsFieldSchema | EnumFieldSchema;
142
149
  export type InteractivitySchemaField = VisibleFieldSchema | HiddenFieldSchema;
143
150
  export type InteractivitySchema = {
144
151
  [key: string]: InteractivitySchemaField;
@@ -255,22 +262,10 @@ export declare const textSchema: {
255
262
  readonly hiddenFromList: false;
256
263
  };
257
264
  readonly 'style.fontWeight': {
258
- readonly type: "enum";
259
- readonly default: "400";
265
+ readonly type: "font-weight";
266
+ readonly default: 400;
260
267
  readonly description: "Font weight";
261
- readonly variants: {
262
- readonly '100': {};
263
- readonly '200': {};
264
- readonly '300': {};
265
- readonly '400': {};
266
- readonly '500': {};
267
- readonly '600': {};
268
- readonly '700': {};
269
- readonly '800': {};
270
- readonly '900': {};
271
- readonly normal: {};
272
- readonly bold: {};
273
- };
268
+ readonly keyframable: false;
274
269
  };
275
270
  readonly 'style.fontStyle': {
276
271
  readonly type: "enum";
@@ -76,22 +76,10 @@ exports.textSchema = {
76
76
  hiddenFromList: false,
77
77
  },
78
78
  'style.fontWeight': {
79
- type: 'enum',
80
- default: '400',
79
+ type: 'font-weight',
80
+ default: 400,
81
81
  description: 'Font weight',
82
- variants: {
83
- '100': {},
84
- '200': {},
85
- '300': {},
86
- '400': {},
87
- '500': {},
88
- '600': {},
89
- '700': {},
90
- '800': {},
91
- '900': {},
92
- normal: {},
93
- bold: {},
94
- },
82
+ keyframable: false,
95
83
  },
96
84
  'style.fontStyle': {
97
85
  type: 'enum',
@@ -645,22 +645,10 @@ export declare const Internals: {
645
645
  readonly hiddenFromList: false;
646
646
  };
647
647
  readonly 'style.fontWeight': {
648
- readonly type: "enum";
649
- readonly default: "400";
648
+ readonly type: "font-weight";
649
+ readonly default: 400;
650
650
  readonly description: "Font weight";
651
- readonly variants: {
652
- readonly '100': {};
653
- readonly '200': {};
654
- readonly '300': {};
655
- readonly '400': {};
656
- readonly '500': {};
657
- readonly '600': {};
658
- readonly '700': {};
659
- readonly '800': {};
660
- readonly '900': {};
661
- readonly normal: {};
662
- readonly bold: {};
663
- };
651
+ readonly keyframable: false;
664
652
  };
665
653
  readonly 'style.fontStyle': {
666
654
  readonly type: "enum";
@@ -837,6 +825,7 @@ export declare const Internals: {
837
825
  audioSyncAnchorEmitter: import("./audio/shared-audio-tags.js").AudioSyncAnchorEmitter;
838
826
  scheduleAudioNode: (options: ScheduleAudioNodeOptions) => ScheduleAudioNodeResult;
839
827
  resume: () => Promise<void>;
828
+ resumeAsAutoPlay: () => Promise<void>;
840
829
  suspend: () => Promise<void>;
841
830
  getIsResumingAudioContext: () => Promise<import("./audio/wait-until-actually-resumed.js").AudioContextResumeResult> | null;
842
831
  unscheduleAudioNode: (node: AudioBufferSourceNode) => void;
@@ -101,6 +101,11 @@ const useMediaPlayback = ({ mediaRef, src, mediaType, playbackRate: localPlaybac
101
101
  // and it is also in a useLayoutEffect.
102
102
  (0, react_1.useLayoutEffect)(() => {
103
103
  const playbackRateToSet = Math.max(0, playbackRate);
104
+ // Loading a resource resets playbackRate to defaultPlaybackRate.
105
+ if (mediaRef.current &&
106
+ mediaRef.current.defaultPlaybackRate !== playbackRateToSet) {
107
+ mediaRef.current.defaultPlaybackRate = playbackRateToSet;
108
+ }
104
109
  if (mediaRef.current &&
105
110
  mediaRef.current.playbackRate !== playbackRateToSet) {
106
111
  mediaRef.current.playbackRate = playbackRateToSet;
@@ -3,4 +3,4 @@
3
3
  * @see [Documentation](https://remotion.dev/docs/version)
4
4
  * @returns {string} The current version of the remotion package
5
5
  */
6
- export declare const VERSION = "4.0.520";
6
+ export declare const VERSION = "4.0.521";
@@ -7,4 +7,4 @@ exports.VERSION = void 0;
7
7
  * @see [Documentation](https://remotion.dev/docs/version)
8
8
  * @returns {string} The current version of the remotion package
9
9
  */
10
- exports.VERSION = '4.0.520';
10
+ exports.VERSION = '4.0.521';
@@ -1537,7 +1537,7 @@ var Composition = (props) => {
1537
1537
  };
1538
1538
 
1539
1539
  // src/version.ts
1540
- var VERSION = "4.0.520";
1540
+ var VERSION = "4.0.521";
1541
1541
 
1542
1542
  // src/multiple-versions-warning.ts
1543
1543
  var checkMultipleRemotionVersions = () => {
@@ -2053,22 +2053,10 @@ var textSchema = {
2053
2053
  hiddenFromList: false
2054
2054
  },
2055
2055
  "style.fontWeight": {
2056
- type: "enum",
2057
- default: "400",
2056
+ type: "font-weight",
2057
+ default: 400,
2058
2058
  description: "Font weight",
2059
- variants: {
2060
- "100": {},
2061
- "200": {},
2062
- "300": {},
2063
- "400": {},
2064
- "500": {},
2065
- "600": {},
2066
- "700": {},
2067
- "800": {},
2068
- "900": {},
2069
- normal: {},
2070
- bold: {}
2071
- }
2059
+ keyframable: false
2072
2060
  },
2073
2061
  "style.fontStyle": {
2074
2062
  type: "enum",
@@ -6465,6 +6453,7 @@ import { jsx as jsx15 } from "react/jsx-runtime";
6465
6453
  var animatedImageSchema = {
6466
6454
  src: {
6467
6455
  type: "asset",
6456
+ assetType: "image",
6468
6457
  default: undefined,
6469
6458
  description: "Source",
6470
6459
  keyframable: false
@@ -7693,7 +7682,7 @@ var useSingletonAudioContext = ({
7693
7682
 
7694
7683
  // src/audio/wait-until-actually-resumed.ts
7695
7684
  var RESUME_WAIT_TIMEOUT = 1000;
7696
- var waitUntilActuallyResumed = (audioContext, logLevel, signal) => {
7685
+ var waitUntilActuallyResumed = (audioContext, logLevel, signal, isAutoPlayAttempt) => {
7697
7686
  return new Promise((resolve) => {
7698
7687
  const startCurrentTime = audioContext.currentTime;
7699
7688
  const start = audioContext.getOutputTimestamp();
@@ -7741,14 +7730,16 @@ var waitUntilActuallyResumed = (audioContext, logLevel, signal) => {
7741
7730
  return;
7742
7731
  }
7743
7732
  signal.addEventListener("abort", onAbort, { once: true });
7744
- timeout = setTimeout(() => {
7745
- if (hasAudiblyStarted(startOutputPerformanceTime)) {
7746
- finish("resumed");
7747
- return;
7748
- }
7749
- Log.warn({ logLevel, tag: "audio" }, "WARNING: You enabled autoPlay on an unmuted <Player /> and the browser did not allow the video to be started. Remotion muted the <Player /> so it can play. To properly handle this, either set the `muted` prop or remove the `autoPlay` prop");
7750
- finish("failed");
7751
- }, RESUME_WAIT_TIMEOUT);
7733
+ if (isAutoPlayAttempt) {
7734
+ timeout = setTimeout(() => {
7735
+ if (hasAudiblyStarted(startOutputPerformanceTime)) {
7736
+ finish("resumed");
7737
+ return;
7738
+ }
7739
+ Log.warn({ logLevel, tag: "audio" }, "WARNING: You enabled autoPlay on an unmuted <Player /> and the browser did not allow the video to be started. Remotion muted the <Player /> so it can play. To properly handle this, either set the `muted` prop or remove the `autoPlay` prop");
7740
+ finish("failed");
7741
+ }, RESUME_WAIT_TIMEOUT);
7742
+ }
7752
7743
  animationFrame = requestAnimationFrame(check);
7753
7744
  });
7754
7745
  };
@@ -7820,6 +7811,7 @@ var SharedAudioContextProvider = ({
7820
7811
  }
7821
7812
  const isResuming = useRef13(null);
7822
7813
  const nextResumeAttemptId = useRef13(0);
7814
+ const nextResumeIsAutoPlayAttempt = useRef13(false);
7823
7815
  const audioSyncAnchor = useMemo21(() => ({ value: 0 }), []);
7824
7816
  const audioSyncAnchorListeners = useRef13([]);
7825
7817
  const audioSyncAnchorEmitter = useMemo21(() => {
@@ -7895,6 +7887,8 @@ var SharedAudioContextProvider = ({
7895
7887
  };
7896
7888
  }, [ctxAndGain, _experimentalKeepAudioContextAlive, logLevel]);
7897
7889
  const resume = useCallback10(() => {
7890
+ const isAutoPlayAttempt = nextResumeIsAutoPlayAttempt.current;
7891
+ nextResumeIsAutoPlayAttempt.current = false;
7898
7892
  if (!ctxAndGain) {
7899
7893
  return Promise.resolve();
7900
7894
  }
@@ -7916,7 +7910,7 @@ var SharedAudioContextProvider = ({
7916
7910
  const abortController = new AbortController;
7917
7911
  const resumeAttemptId = nextResumeAttemptId.current++;
7918
7912
  const waitPromise = new Promise((resolve) => {
7919
- waitUntilActuallyResumed(ctxAndGain.audioContext, logLevel, abortController.signal).then(resolve);
7913
+ waitUntilActuallyResumed(ctxAndGain.audioContext, logLevel, abortController.signal, isAutoPlayAttempt).then(resolve);
7920
7914
  resumePromise.catch((err) => {
7921
7915
  Log.warn({ logLevel, tag: "audio" }, "AudioContext resume rejected, muting playback and continuing without audio", err);
7922
7916
  abortController.abort();
@@ -7934,6 +7928,10 @@ var SharedAudioContextProvider = ({
7934
7928
  };
7935
7929
  return resumePromise.catch(() => {});
7936
7930
  }, [ctxAndGain, _experimentalKeepAudioContextAlive, logLevel]);
7931
+ const resumeAsAutoPlay = useCallback10(() => {
7932
+ nextResumeIsAutoPlayAttempt.current = true;
7933
+ return resume();
7934
+ }, [resume]);
7937
7935
  const getIsResumingAudioContext = useCallback10(() => {
7938
7936
  return isResuming.current?.promise ?? null;
7939
7937
  }, []);
@@ -7990,6 +7988,7 @@ var SharedAudioContextProvider = ({
7990
7988
  audioSyncAnchorEmitter,
7991
7989
  scheduleAudioNode,
7992
7990
  resume,
7991
+ resumeAsAutoPlay,
7993
7992
  suspend,
7994
7993
  getIsResumingAudioContext,
7995
7994
  unscheduleAudioNode,
@@ -8001,6 +8000,7 @@ var SharedAudioContextProvider = ({
8001
8000
  audioSyncAnchorEmitter,
8002
8001
  scheduleAudioNode,
8003
8002
  resume,
8003
+ resumeAsAutoPlay,
8004
8004
  suspend,
8005
8005
  getIsResumingAudioContext,
8006
8006
  unscheduleAudioNode,
@@ -9387,6 +9387,9 @@ var useMediaPlayback = ({
9387
9387
  const env = useRemotionEnvironment();
9388
9388
  useLayoutEffect10(() => {
9389
9389
  const playbackRateToSet = Math.max(0, playbackRate);
9390
+ if (mediaRef.current && mediaRef.current.defaultPlaybackRate !== playbackRateToSet) {
9391
+ mediaRef.current.defaultPlaybackRate = playbackRateToSet;
9392
+ }
9390
9393
  if (mediaRef.current && mediaRef.current.playbackRate !== playbackRateToSet) {
9391
9394
  mediaRef.current.playbackRate = playbackRateToSet;
9392
9395
  }
@@ -10804,6 +10807,7 @@ import { jsx as jsx27 } from "react/jsx-runtime";
10804
10807
  var canvasImageSchema = {
10805
10808
  src: {
10806
10809
  type: "asset",
10810
+ assetType: "image",
10807
10811
  default: undefined,
10808
10812
  description: "Source",
10809
10813
  keyframable: false
@@ -11572,6 +11576,7 @@ var CanvasImageWithPrivateProps = CanvasImage;
11572
11576
  var imgSchema = {
11573
11577
  src: {
11574
11578
  type: "asset",
11579
+ assetType: "image",
11575
11580
  default: undefined,
11576
11581
  description: "Source",
11577
11582
  keyframable: false
@@ -1,5 +1,5 @@
1
1
  // src/version.ts
2
- var VERSION = "4.0.520";
2
+ var VERSION = "4.0.521";
3
3
  export {
4
4
  VERSION
5
5
  };
package/package.json CHANGED
@@ -3,7 +3,7 @@
3
3
  "url": "https://github.com/remotion-dev/remotion/tree/main/packages/core"
4
4
  },
5
5
  "name": "remotion",
6
- "version": "4.0.520",
6
+ "version": "4.0.521",
7
7
  "description": "Make videos programmatically",
8
8
  "main": "dist/cjs/index.js",
9
9
  "types": "dist/cjs/index.d.ts",
@@ -34,8 +34,8 @@
34
34
  "react": "19.2.3",
35
35
  "react-dom": "19.2.3",
36
36
  "webpack": "5.105.0",
37
- "zod": "4.4.3",
38
- "@remotion/eslint-config-internal": "4.0.520",
37
+ "zod": "4.5.4",
38
+ "@remotion/eslint-config-internal": "4.0.521",
39
39
  "eslint": "9.19.0",
40
40
  "@typescript/native-preview": "7.0.0-dev.20260217.1"
41
41
  },