remotion 4.0.110 → 4.0.112

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -44,7 +44,7 @@ Remotion is a framework for **creating videos programmatically using React.**
44
44
  If you already have Node.JS installed, type
45
45
 
46
46
  ```console
47
- npm init video
47
+ npx create-video@latest
48
48
  ```
49
49
 
50
50
  to get started. Otherwise, read the [installation page](https://www.remotion.dev/docs/) in the documentation.
package/dist/cjs/Img.d.ts CHANGED
@@ -1,6 +1,7 @@
1
1
  import React from 'react';
2
2
  export type ImgProps = Omit<React.DetailedHTMLProps<React.ImgHTMLAttributes<HTMLImageElement>, HTMLImageElement>, 'src'> & {
3
3
  maxRetries?: number;
4
+ pauseWhenLoading?: boolean;
4
5
  src: string;
5
6
  };
6
7
  /**
package/dist/cjs/Img.js CHANGED
@@ -6,12 +6,14 @@ const react_1 = require("react");
6
6
  const cancel_render_js_1 = require("./cancel-render.js");
7
7
  const delay_render_js_1 = require("./delay-render.js");
8
8
  const prefetch_js_1 = require("./prefetch.js");
9
+ const use_buffer_state_js_1 = require("./use-buffer-state.js");
9
10
  function exponentialBackoff(errorCount) {
10
11
  return 1000 * 2 ** (errorCount - 1);
11
12
  }
12
- const ImgRefForwarding = ({ onError, maxRetries = 2, src, ...props }, ref) => {
13
+ const ImgRefForwarding = ({ onError, maxRetries = 2, src, pauseWhenLoading, ...props }, ref) => {
13
14
  const imageRef = (0, react_1.useRef)(null);
14
15
  const errors = (0, react_1.useRef)({});
16
+ const { delayPlayback } = (0, use_buffer_state_js_1.useBufferState)();
15
17
  if (!src) {
16
18
  throw new Error('No "src" prop was passed to <Img>.');
17
19
  }
@@ -67,6 +69,9 @@ const ImgRefForwarding = ({ onError, maxRetries = 2, src, ...props }, ref) => {
67
69
  return;
68
70
  }
69
71
  const newHandle = (0, delay_render_js_1.delayRender)('Loading <Img> with src=' + actualSrc);
72
+ const unblock = pauseWhenLoading
73
+ ? delayPlayback().unblock
74
+ : () => undefined;
70
75
  const { current } = imageRef;
71
76
  const onComplete = () => {
72
77
  var _a, _b, _c, _d;
@@ -75,6 +80,7 @@ const ImgRefForwarding = ({ onError, maxRetries = 2, src, ...props }, ref) => {
75
80
  // eslint-disable-next-line no-console
76
81
  console.info(`Retry successful - ${(_d = imageRef.current) === null || _d === void 0 ? void 0 : _d.src} is now loaded`);
77
82
  }
83
+ unblock();
78
84
  (0, delay_render_js_1.continueRender)(newHandle);
79
85
  };
80
86
  const didLoad = () => {
@@ -89,9 +95,10 @@ const ImgRefForwarding = ({ onError, maxRetries = 2, src, ...props }, ref) => {
89
95
  // If tag gets unmounted, clear pending handles because image is not going to load
90
96
  return () => {
91
97
  current === null || current === void 0 ? void 0 : current.removeEventListener('load', didLoad);
98
+ unblock();
92
99
  (0, delay_render_js_1.continueRender)(newHandle);
93
100
  };
94
- }, [actualSrc]);
101
+ }, [actualSrc, delayPlayback, pauseWhenLoading]);
95
102
  }
96
103
  return ((0, jsx_runtime_1.jsx)("img", { ...props, ref: imageRef, src: actualSrc, onError: didGetError }));
97
104
  };
@@ -3,6 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.RemotionRoot = void 0;
4
4
  const jsx_runtime_1 = require("react/jsx-runtime");
5
5
  const react_1 = require("react");
6
+ const buffering_js_1 = require("./buffering.js");
6
7
  const CompositionManager_js_1 = require("./CompositionManager.js");
7
8
  const delay_render_js_1 = require("./delay-render.js");
8
9
  const EditorProps_js_1 = require("./EditorProps.js");
@@ -69,6 +70,6 @@ const RemotionRoot = ({ children, numberOfAudioTags }) => {
69
70
  }
70
71
  }
71
72
  }, []);
72
- return ((0, jsx_runtime_1.jsx)(nonce_js_1.NonceContext.Provider, { value: nonceContext, children: (0, jsx_runtime_1.jsx)(timeline_position_state_js_1.TimelineContext.Provider, { value: timelineContextValue, children: (0, jsx_runtime_1.jsx)(timeline_position_state_js_1.SetTimelineContext.Provider, { value: setTimelineContextValue, children: (0, jsx_runtime_1.jsx)(EditorProps_js_1.EditorPropsProvider, { children: (0, jsx_runtime_1.jsx)(prefetch_state_js_1.PrefetchProvider, { children: (0, jsx_runtime_1.jsx)(NativeLayers_js_1.NativeLayersProvider, { children: (0, jsx_runtime_1.jsx)(CompositionManager_js_1.CompositionManagerProvider, { numberOfAudioTags: numberOfAudioTags, children: (0, jsx_runtime_1.jsx)(duration_state_js_1.DurationsContextProvider, { children: children }) }) }) }) }) }) }) }));
73
+ return ((0, jsx_runtime_1.jsx)(nonce_js_1.NonceContext.Provider, { value: nonceContext, children: (0, jsx_runtime_1.jsx)(timeline_position_state_js_1.TimelineContext.Provider, { value: timelineContextValue, children: (0, jsx_runtime_1.jsx)(timeline_position_state_js_1.SetTimelineContext.Provider, { value: setTimelineContextValue, children: (0, jsx_runtime_1.jsx)(EditorProps_js_1.EditorPropsProvider, { children: (0, jsx_runtime_1.jsx)(prefetch_state_js_1.PrefetchProvider, { children: (0, jsx_runtime_1.jsx)(NativeLayers_js_1.NativeLayersProvider, { children: (0, jsx_runtime_1.jsx)(CompositionManager_js_1.CompositionManagerProvider, { numberOfAudioTags: numberOfAudioTags, children: (0, jsx_runtime_1.jsx)(duration_state_js_1.DurationsContextProvider, { children: (0, jsx_runtime_1.jsx)(buffering_js_1.BufferingProvider, { children: children }) }) }) }) }) }) }) }) }));
73
74
  };
74
75
  exports.RemotionRoot = RemotionRoot;
@@ -13,6 +13,7 @@ export declare const Audio: React.ForwardRefExoticComponent<Omit<Omit<React.Deta
13
13
  _remotionInternalNeedsDurationCalculation?: boolean | undefined;
14
14
  _remotionInternalNativeLoopPassed?: boolean | undefined;
15
15
  toneFrequency?: number | undefined;
16
+ pauseWhenBuffering?: boolean | undefined;
16
17
  } & RemotionMainAudioProps & {
17
18
  /**
18
19
  * @deprecated For internal use only
@@ -16,13 +16,13 @@ const use_video_config_js_1 = require("../use-video-config.js");
16
16
  const validate_media_props_js_1 = require("../validate-media-props.js");
17
17
  const validate_start_from_props_js_1 = require("../validate-start-from-props.js");
18
18
  const duration_state_js_1 = require("../video/duration-state.js");
19
- const AudioForDevelopment_js_1 = require("./AudioForDevelopment.js");
19
+ const AudioForPreview_js_1 = require("./AudioForPreview.js");
20
20
  const AudioForRendering_js_1 = require("./AudioForRendering.js");
21
21
  const shared_audio_tags_js_1 = require("./shared-audio-tags.js");
22
22
  const AudioRefForwardingFunction = (props, ref) => {
23
23
  var _a, _b, _c;
24
24
  const audioContext = (0, react_1.useContext)(shared_audio_tags_js_1.SharedAudioContext);
25
- const { startFrom, endAt, name, stack, ...otherProps } = props;
25
+ const { startFrom, endAt, name, stack, pauseWhenBuffering, ...otherProps } = props;
26
26
  const { loop, ...propsOtherThanLoop } = props;
27
27
  const { fps } = (0, use_video_config_js_1.useVideoConfig)();
28
28
  const environment = (0, get_remotion_environment_js_1.getRemotionEnvironment)();
@@ -68,7 +68,9 @@ const AudioRefForwardingFunction = (props, ref) => {
68
68
  if (environment.isRendering) {
69
69
  return ((0, jsx_runtime_1.jsx)(AudioForRendering_js_1.AudioForRendering, { onDuration: onDuration, ...props, ref: ref, onError: onError, _remotionInternalNeedsDurationCalculation: Boolean(loop) }));
70
70
  }
71
- return ((0, jsx_runtime_1.jsx)(AudioForDevelopment_js_1.AudioForDevelopment, { _remotionInternalNativeLoopPassed: (_c = props._remotionInternalNativeLoopPassed) !== null && _c !== void 0 ? _c : false, _remotionInternalStack: stack !== null && stack !== void 0 ? stack : null, shouldPreMountAudioTags: audioContext !== null && audioContext.numberOfAudioTags > 0, ...props, ref: ref, onError: onError, onDuration: onDuration, _remotionInternalNeedsDurationCalculation: Boolean(loop) }));
71
+ return ((0, jsx_runtime_1.jsx)(AudioForPreview_js_1.AudioForPreview, { _remotionInternalNativeLoopPassed: (_c = props._remotionInternalNativeLoopPassed) !== null && _c !== void 0 ? _c : false, _remotionInternalStack: stack !== null && stack !== void 0 ? stack : null, shouldPreMountAudioTags: audioContext !== null && audioContext.numberOfAudioTags > 0, ...props, ref: ref, onError: onError, onDuration: onDuration,
72
+ // Proposal: Make this default to true in v5
73
+ pauseWhenBuffering: pauseWhenBuffering !== null && pauseWhenBuffering !== void 0 ? pauseWhenBuffering : false, _remotionInternalNeedsDurationCalculation: Boolean(loop) }));
72
74
  };
73
75
  /**
74
76
  * @description With this component, you can add audio to your video. All audio formats which are supported by Chromium are supported by the component.
@@ -9,6 +9,7 @@ export declare const AudioForRendering: ForwardRefExoticComponent<Omit<React.Det
9
9
  _remotionInternalNeedsDurationCalculation?: boolean | undefined;
10
10
  _remotionInternalNativeLoopPassed?: boolean | undefined;
11
11
  toneFrequency?: number | undefined;
12
+ pauseWhenBuffering?: boolean | undefined;
12
13
  } & {
13
14
  onDuration: (src: string, durationInSeconds: number) => void;
14
15
  } & RefAttributes<HTMLAudioElement>>;
@@ -13,4 +13,5 @@ export type RemotionAudioProps = Omit<React.DetailedHTMLProps<React.AudioHTMLAtt
13
13
  _remotionInternalNeedsDurationCalculation?: boolean;
14
14
  _remotionInternalNativeLoopPassed?: boolean;
15
15
  toneFrequency?: number;
16
+ pauseWhenBuffering?: boolean;
16
17
  };
@@ -93,7 +93,9 @@ export * from './spring/index.js';
93
93
  export { staticFile } from './static-file.js';
94
94
  export * from './Still.js';
95
95
  export type { PlayableMediaTag } from './timeline-position-state.js';
96
+ export { useBufferState } from './use-buffer-state';
96
97
  export { useCurrentFrame } from './use-current-frame.js';
98
+ export { CurrentScaleContextType, PreviewSize, PreviewSizeCtx, Translation, useCurrentScale, } from './use-current-scale';
97
99
  export * from './use-video-config.js';
98
100
  export * from './version.js';
99
101
  export * from './video-config.js';
package/dist/cjs/index.js CHANGED
@@ -14,7 +14,7 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
14
  for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
15
  };
16
16
  Object.defineProperty(exports, "__esModule", { value: true });
17
- exports.Config = exports.Experimental = exports.watchStaticFile = exports.useCurrentFrame = exports.staticFile = exports.Series = exports.Sequence = exports.registerRoot = exports.prefetch = exports.random = exports.interpolate = exports.Loop = exports.interpolateColors = exports.Img = exports.getStaticFiles = exports.getRemotionEnvironment = exports.delayRender = exports.continueRender = exports.getInputProps = exports.Composition = exports.cancelRender = void 0;
17
+ exports.Config = exports.Experimental = exports.watchStaticFile = exports.useCurrentScale = exports.useCurrentFrame = exports.useBufferState = exports.staticFile = exports.Series = exports.Sequence = exports.registerRoot = exports.prefetch = exports.random = exports.interpolate = exports.Loop = exports.interpolateColors = exports.Img = exports.getStaticFiles = exports.getRemotionEnvironment = exports.delayRender = exports.continueRender = exports.getInputProps = exports.Composition = exports.cancelRender = void 0;
18
18
  require("./asset-types.js");
19
19
  const Clipper_js_1 = require("./Clipper.js");
20
20
  const enable_sequence_stack_traces_js_1 = require("./enable-sequence-stack-traces.js");
@@ -64,8 +64,12 @@ __exportStar(require("./spring/index.js"), exports);
64
64
  var static_file_js_1 = require("./static-file.js");
65
65
  Object.defineProperty(exports, "staticFile", { enumerable: true, get: function () { return static_file_js_1.staticFile; } });
66
66
  __exportStar(require("./Still.js"), exports);
67
+ var use_buffer_state_1 = require("./use-buffer-state");
68
+ Object.defineProperty(exports, "useBufferState", { enumerable: true, get: function () { return use_buffer_state_1.useBufferState; } });
67
69
  var use_current_frame_js_1 = require("./use-current-frame.js");
68
70
  Object.defineProperty(exports, "useCurrentFrame", { enumerable: true, get: function () { return use_current_frame_js_1.useCurrentFrame; } });
71
+ var use_current_scale_1 = require("./use-current-scale");
72
+ Object.defineProperty(exports, "useCurrentScale", { enumerable: true, get: function () { return use_current_scale_1.useCurrentScale; } });
69
73
  __exportStar(require("./use-video-config.js"), exports);
70
74
  __exportStar(require("./version.js"), exports);
71
75
  __exportStar(require("./video-config.js"), exports);
@@ -128,9 +128,37 @@ export declare const Internals: {
128
128
  readonly WATCH_REMOTION_STATIC_FILES: "remotion_staticFilesChanged";
129
129
  readonly addSequenceStackTraces: (component: unknown) => void;
130
130
  readonly useMediaStartsAt: () => number;
131
+ readonly BufferingProvider: import("react").FC<{
132
+ children: import("react").ReactNode;
133
+ }>;
134
+ readonly BufferingContextReact: import("react").Context<{
135
+ addBlock: (block: {
136
+ id: string;
137
+ }) => {
138
+ unblock: () => void;
139
+ };
140
+ listenForBuffering: (callback: () => void) => {
141
+ remove: () => void;
142
+ };
143
+ listenForResume: (callback: () => void) => {
144
+ remove: () => void;
145
+ };
146
+ buffering: import("react").MutableRefObject<boolean>;
147
+ } | null>;
131
148
  readonly enableSequenceStackTraces: () => void;
132
149
  readonly colorNames: {
133
150
  [key: string]: number;
134
151
  };
152
+ readonly CurrentScaleContext: import("react").Context<import("./use-current-scale.js").CurrentScaleContextType | null>;
153
+ readonly PreviewSizeContext: import("react").Context<import("./use-current-scale.js").PreviewSizeCtx>;
154
+ readonly calculateScale: ({ canvasSize, compositionHeight, compositionWidth, previewSize, }: {
155
+ previewSize: number | "auto";
156
+ compositionWidth: number;
157
+ compositionHeight: number;
158
+ canvasSize: {
159
+ width: number;
160
+ height: number;
161
+ };
162
+ }) => number;
135
163
  };
136
164
  export type { TComposition, TimelinePosition as Timeline, TCompMetadata, TSequence, TRenderAsset as TAsset, TimelineContextValue, SetTimelineContextValue, CompProps, CompositionManagerContext, MediaVolumeContextValue, SetMediaVolumeContextValue, RemotionEnvironment, SerializedJSONWithCustomFields, WatchRemotionStaticFilesPayload, };
@@ -26,6 +26,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
26
26
  exports.Internals = void 0;
27
27
  const shared_audio_tags_js_1 = require("./audio/shared-audio-tags.js");
28
28
  const use_audio_frame_js_1 = require("./audio/use-audio-frame.js");
29
+ const buffering_js_1 = require("./buffering.js");
29
30
  const CanUseRemotionHooks_js_1 = require("./CanUseRemotionHooks.js");
30
31
  const Composition_js_1 = require("./Composition.js");
31
32
  const CompositionManager_js_1 = require("./CompositionManager.js");
@@ -54,6 +55,7 @@ const setup_env_variables_js_1 = require("./setup-env-variables.js");
54
55
  const TimelinePosition = __importStar(require("./timeline-position-state.js"));
55
56
  const timeline_position_state_js_1 = require("./timeline-position-state.js");
56
57
  const truthy_js_1 = require("./truthy.js");
58
+ const use_current_scale_js_1 = require("./use-current-scale.js");
57
59
  const use_lazy_component_js_1 = require("./use-lazy-component.js");
58
60
  const use_unsafe_video_config_js_1 = require("./use-unsafe-video-config.js");
59
61
  const use_video_js_1 = require("./use-video.js");
@@ -120,6 +122,11 @@ exports.Internals = {
120
122
  WATCH_REMOTION_STATIC_FILES: watch_static_file_js_1.WATCH_REMOTION_STATIC_FILES,
121
123
  addSequenceStackTraces: enable_sequence_stack_traces_js_1.addSequenceStackTraces,
122
124
  useMediaStartsAt: use_audio_frame_js_1.useMediaStartsAt,
125
+ BufferingProvider: buffering_js_1.BufferingProvider,
126
+ BufferingContextReact: buffering_js_1.BufferingContextReact,
123
127
  enableSequenceStackTraces: enable_sequence_stack_traces_js_1.enableSequenceStackTraces,
124
128
  colorNames: interpolate_colors_js_1.colorNames,
129
+ CurrentScaleContext: use_current_scale_js_1.CurrentScaleContext,
130
+ PreviewSizeContext: use_current_scale_js_1.PreviewSizeContext,
131
+ calculateScale: use_current_scale_js_1.calculateScale,
125
132
  };
@@ -3,21 +3,13 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.useBufferState = void 0;
4
4
  const react_1 = require("react");
5
5
  const buffering_1 = require("./buffering");
6
- const CanUseRemotionHooks_1 = require("./CanUseRemotionHooks");
7
6
  const useBufferState = () => {
8
- const canUseRemotionHooks = (0, react_1.useContext)(CanUseRemotionHooks_1.CanUseRemotionHooks);
9
- if (!canUseRemotionHooks) {
10
- if (typeof window !== 'undefined' && window.remotion_isPlayer) {
11
- throw new Error(`useCurrentFrame can only be called inside a component that was passed to <Player>. See: https://www.remotion.dev/docs/player/examples`);
12
- }
13
- throw new Error(`useCurrentFrame() can only be called inside a component that was registered as a composition. See https://www.remotion.dev/docs/the-fundamentals#defining-compositions`);
14
- }
15
7
  const buffer = (0, react_1.useContext)(buffering_1.BufferingContextReact);
16
- if (!buffer) {
17
- throw new Error('BufferingContextReact was unexpectedly not found. Most likely your Remotion versions are mismatching.');
18
- }
19
8
  return (0, react_1.useMemo)(() => ({
20
9
  delayPlayback: () => {
10
+ if (!buffer) {
11
+ throw new Error('Tried to enable the buffering state, but a Remotion context was not found. This API can only be called in a component that was passed to the Remotion Player or a <Composition>. Or you might have experienced a version mismatch - run `npx remotion versions` and ensure all packages have the same version. This error is thrown by the buffer state https://remotion.dev/docs/player/buffer-state');
12
+ }
21
13
  const { unblock } = buffer.addBlock({
22
14
  id: String(Math.random()),
23
15
  });
@@ -0,0 +1,43 @@
1
+ import React from 'react';
2
+ export type CurrentScaleContextType = {
3
+ type: 'scale';
4
+ scale: number;
5
+ } | {
6
+ type: 'canvas-size';
7
+ canvasSize: {
8
+ width: number;
9
+ height: number;
10
+ };
11
+ };
12
+ export declare const CurrentScaleContext: React.Context<CurrentScaleContextType | null>;
13
+ type Options = {
14
+ dontThrowIfOutsideOfRemotion: boolean;
15
+ };
16
+ export type Translation = {
17
+ x: number;
18
+ y: number;
19
+ };
20
+ export type PreviewSize = {
21
+ size: number | 'auto';
22
+ translation: Translation;
23
+ };
24
+ export type PreviewSizeCtx = {
25
+ size: PreviewSize;
26
+ setSize: (cb: (oldSize: PreviewSize) => PreviewSize) => void;
27
+ };
28
+ export declare const PreviewSizeContext: React.Context<PreviewSizeCtx>;
29
+ export declare const calculateScale: ({ canvasSize, compositionHeight, compositionWidth, previewSize, }: {
30
+ previewSize: PreviewSize['size'];
31
+ compositionWidth: number;
32
+ compositionHeight: number;
33
+ canvasSize: {
34
+ width: number;
35
+ height: number;
36
+ };
37
+ }) => number;
38
+ /**
39
+ * Gets the current scale of the container in which the component is being rendered.
40
+ * Only works in the Remotion Studio and in the Remotion Player.
41
+ */
42
+ export declare const useCurrentScale: (options?: Options) => number;
43
+ export {};
@@ -0,0 +1,70 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || function (mod) {
19
+ if (mod && mod.__esModule) return mod;
20
+ var result = {};
21
+ if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
22
+ __setModuleDefault(result, mod);
23
+ return result;
24
+ };
25
+ Object.defineProperty(exports, "__esModule", { value: true });
26
+ exports.useCurrentScale = exports.calculateScale = exports.PreviewSizeContext = exports.CurrentScaleContext = void 0;
27
+ const react_1 = __importStar(require("react"));
28
+ const use_unsafe_video_config_1 = require("./use-unsafe-video-config");
29
+ exports.CurrentScaleContext = react_1.default.createContext(null);
30
+ exports.PreviewSizeContext = (0, react_1.createContext)({
31
+ setSize: () => undefined,
32
+ size: { size: 'auto', translation: { x: 0, y: 0 } },
33
+ });
34
+ const calculateScale = ({ canvasSize, compositionHeight, compositionWidth, previewSize, }) => {
35
+ const heightRatio = canvasSize.height / compositionHeight;
36
+ const widthRatio = canvasSize.width / compositionWidth;
37
+ const ratio = Math.min(heightRatio, widthRatio);
38
+ return previewSize === 'auto' ? ratio : Number(previewSize);
39
+ };
40
+ exports.calculateScale = calculateScale;
41
+ /**
42
+ * Gets the current scale of the container in which the component is being rendered.
43
+ * Only works in the Remotion Studio and in the Remotion Player.
44
+ */
45
+ const useCurrentScale = (options) => {
46
+ const hasContext = react_1.default.useContext(exports.CurrentScaleContext);
47
+ const zoomContext = react_1.default.useContext(exports.PreviewSizeContext);
48
+ const config = (0, use_unsafe_video_config_1.useUnsafeVideoConfig)();
49
+ if (hasContext === null || config === null || zoomContext === null) {
50
+ if (options === null || options === void 0 ? void 0 : options.dontThrowIfOutsideOfRemotion) {
51
+ return 1;
52
+ }
53
+ throw new Error([
54
+ 'useCurrentScale() was called outside of a Remotion context.',
55
+ 'This hook can only be called in a component that is being rendered by Remotion.',
56
+ 'If you want to this hook to return 1 outside of Remotion, pass {dontThrowIfOutsideOfRemotion: true} as an option.',
57
+ 'If you think you called this hook in a Remotion component, make sure all versions of Remotion are aligned.',
58
+ ].join('\n'));
59
+ }
60
+ if (hasContext.type === 'scale') {
61
+ return hasContext.scale;
62
+ }
63
+ return (0, exports.calculateScale)({
64
+ canvasSize: hasContext.canvasSize,
65
+ compositionHeight: config.height,
66
+ compositionWidth: config.width,
67
+ previewSize: zoomContext.size.size,
68
+ });
69
+ };
70
+ exports.useCurrentScale = useCurrentScale;
@@ -3,6 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.useMediaPlayback = exports.DEFAULT_ACCEPTABLE_TIMESHIFT = void 0;
4
4
  const react_1 = require("react");
5
5
  const use_audio_frame_js_1 = require("./audio/use-audio-frame.js");
6
+ const buffering_js_1 = require("./buffering.js");
6
7
  const play_and_handle_not_allowed_error_js_1 = require("./play-and-handle-not-allowed-error.js");
7
8
  const timeline_position_state_js_1 = require("./timeline-position-state.js");
8
9
  const use_current_frame_js_1 = require("./use-current-frame.js");
@@ -27,6 +28,7 @@ const useMediaPlayback = ({ mediaRef, src, mediaType, playbackRate: localPlaybac
27
28
  const frame = (0, use_current_frame_js_1.useCurrentFrame)();
28
29
  const absoluteFrame = (0, timeline_position_state_js_1.useTimelinePosition)();
29
30
  const [playing] = (0, timeline_position_state_js_1.usePlayingState)();
31
+ const buffering = (0, react_1.useContext)(buffering_js_1.BufferingContextReact);
30
32
  const { fps } = (0, use_video_config_js_1.useVideoConfig)();
31
33
  const mediaStartsAt = (0, use_audio_frame_js_1.useMediaStartsAt)();
32
34
  const playbackRate = localPlaybackRate * globalPlaybackRate;
@@ -38,12 +40,13 @@ const useMediaPlayback = ({ mediaRef, src, mediaType, playbackRate: localPlaybac
38
40
  }
39
41
  return acceptableTimeshift;
40
42
  })();
43
+ const pausedOrBuffering = !playing || (buffering && buffering.buffering);
41
44
  (0, react_1.useEffect)(() => {
42
45
  var _a;
43
- if (!playing) {
46
+ if (pausedOrBuffering) {
44
47
  (_a = mediaRef.current) === null || _a === void 0 ? void 0 : _a.pause();
45
48
  }
46
- }, [mediaRef, mediaType, playing]);
49
+ }, [mediaRef, mediaType, pausedOrBuffering]);
47
50
  (0, react_1.useEffect)(() => {
48
51
  const tagName = mediaType === 'audio' ? '<Audio>' : '<Video>';
49
52
  if (!mediaRef.current) {
@@ -83,12 +86,14 @@ const useMediaPlayback = ({ mediaRef, src, mediaType, playbackRate: localPlaybac
83
86
  // Refer to the https://github.com/remotion-dev/video-buffering-example
84
87
  // which is fixed by only seeking conditionally.
85
88
  const makesSenseToSeek = Math.abs(mediaRef.current.currentTime - shouldBeTime) > 0.00001;
86
- if (!playing || absoluteFrame === 0) {
89
+ if (pausedOrBuffering || absoluteFrame === 0) {
87
90
  if (makesSenseToSeek) {
88
91
  seek(mediaRef, shouldBeTime);
89
92
  }
90
93
  }
91
- if (mediaRef.current.paused && !mediaRef.current.ended && playing) {
94
+ if (mediaRef.current.paused &&
95
+ !mediaRef.current.ended &&
96
+ !pausedOrBuffering) {
92
97
  if (makesSenseToSeek) {
93
98
  seek(mediaRef, shouldBeTime);
94
99
  }
@@ -101,13 +106,13 @@ const useMediaPlayback = ({ mediaRef, src, mediaType, playbackRate: localPlaybac
101
106
  frame,
102
107
  mediaRef,
103
108
  mediaType,
104
- playing,
105
109
  src,
106
110
  mediaStartsAt,
107
111
  localPlaybackRate,
108
112
  onlyWarnForMediaSeekingError,
109
113
  acceptableTimeshift,
110
114
  acceptableTimeShiftButLessThanDuration,
115
+ pausedOrBuffering,
111
116
  ]);
112
117
  };
113
118
  exports.useMediaPlayback = useMediaPlayback;
@@ -1 +1 @@
1
- export declare const VERSION = "4.0.110";
1
+ export declare const VERSION = "4.0.112";
@@ -2,4 +2,4 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.VERSION = void 0;
4
4
  // Automatically generated on publish
5
- exports.VERSION = '4.0.110';
5
+ exports.VERSION = '4.0.112';
@@ -8,7 +8,7 @@ const Sequence_js_1 = require("../Sequence.js");
8
8
  const validate_media_props_js_1 = require("../validate-media-props.js");
9
9
  const validate_start_from_props_js_1 = require("../validate-start-from-props.js");
10
10
  const OffthreadVideoForRendering_js_1 = require("./OffthreadVideoForRendering.js");
11
- const VideoForDevelopment_js_1 = require("./VideoForDevelopment.js");
11
+ const VideoForPreview_js_1 = require("./VideoForPreview.js");
12
12
  /**
13
13
  * @description This method imports and displays a video, similar to <Video />. During rendering, it extracts the exact frame from the video and displays it in an <img> tag
14
14
  * @see [Documentation](https://www.remotion.dev/docs/offthreadvideo)
@@ -16,7 +16,7 @@ const VideoForDevelopment_js_1 = require("./VideoForDevelopment.js");
16
16
  const OffthreadVideo = (props) => {
17
17
  // Should only destruct `startFrom` and `endAt` from props,
18
18
  // rest gets drilled down
19
- const { startFrom, endAt, name, stack, ...otherProps } = props;
19
+ const { startFrom, endAt, name, pauseWhenBuffering, stack, ...otherProps } = props;
20
20
  const environment = (0, get_remotion_environment_js_1.getRemotionEnvironment)();
21
21
  const onDuration = (0, react_1.useCallback)(() => undefined, []);
22
22
  if (typeof props.src !== 'string') {
@@ -36,6 +36,6 @@ const OffthreadVideo = (props) => {
36
36
  return (0, jsx_runtime_1.jsx)(OffthreadVideoForRendering_js_1.OffthreadVideoForRendering, { ...otherProps });
37
37
  }
38
38
  const { transparent, ...withoutTransparent } = otherProps;
39
- return ((0, jsx_runtime_1.jsx)(VideoForDevelopment_js_1.VideoForDevelopment, { _remotionInternalStack: stack !== null && stack !== void 0 ? stack : null, _remotionInternalNativeLoopPassed: false, onDuration: onDuration, onlyWarnForMediaSeekingError: true, ...withoutTransparent }));
39
+ return ((0, jsx_runtime_1.jsx)(VideoForPreview_js_1.VideoForPreview, { _remotionInternalStack: stack !== null && stack !== void 0 ? stack : null, _remotionInternalNativeLoopPassed: false, onDuration: onDuration, onlyWarnForMediaSeekingError: true, pauseWhenBuffering: pauseWhenBuffering !== null && pauseWhenBuffering !== void 0 ? pauseWhenBuffering : false, ...withoutTransparent }));
40
40
  };
41
41
  exports.OffthreadVideo = OffthreadVideo;
@@ -11,6 +11,7 @@ export declare const Video: React.ForwardRefExoticComponent<Omit<Omit<React.Deta
11
11
  acceptableTimeShiftInSeconds?: number | undefined;
12
12
  allowAmplificationDuringRender?: boolean | undefined;
13
13
  toneFrequency?: number | undefined;
14
+ pauseWhenBuffering?: boolean | undefined;
14
15
  } & RemotionMainVideoProps & {
15
16
  /**
16
17
  * @deprecated For internal use only
@@ -15,11 +15,11 @@ const use_video_config_js_1 = require("../use-video-config.js");
15
15
  const validate_media_props_js_1 = require("../validate-media-props.js");
16
16
  const validate_start_from_props_js_1 = require("../validate-start-from-props.js");
17
17
  const duration_state_js_1 = require("./duration-state.js");
18
- const VideoForDevelopment_js_1 = require("./VideoForDevelopment.js");
18
+ const VideoForPreview_js_1 = require("./VideoForPreview.js");
19
19
  const VideoForRendering_js_1 = require("./VideoForRendering.js");
20
20
  const VideoForwardingFunction = (props, ref) => {
21
21
  var _a, _b;
22
- const { startFrom, endAt, name, stack, _remotionInternalNativeLoopPassed, ...otherProps } = props;
22
+ const { startFrom, endAt, name, pauseWhenBuffering, stack, _remotionInternalNativeLoopPassed, ...otherProps } = props;
23
23
  const { loop, ...propsOtherThanLoop } = props;
24
24
  const { fps } = (0, use_video_config_js_1.useVideoConfig)();
25
25
  const environment = (0, get_remotion_environment_js_1.getRemotionEnvironment)();
@@ -54,7 +54,9 @@ const VideoForwardingFunction = (props, ref) => {
54
54
  if (environment.isRendering) {
55
55
  return ((0, jsx_runtime_1.jsx)(VideoForRendering_js_1.VideoForRendering, { onDuration: onDuration, ...otherProps, ref: ref }));
56
56
  }
57
- return ((0, jsx_runtime_1.jsx)(VideoForDevelopment_js_1.VideoForDevelopment, { onlyWarnForMediaSeekingError: false, ...otherProps, ref: ref, onDuration: onDuration, _remotionInternalStack: stack !== null && stack !== void 0 ? stack : null, _remotionInternalNativeLoopPassed: _remotionInternalNativeLoopPassed !== null && _remotionInternalNativeLoopPassed !== void 0 ? _remotionInternalNativeLoopPassed : false }));
57
+ return ((0, jsx_runtime_1.jsx)(VideoForPreview_js_1.VideoForPreview, { onlyWarnForMediaSeekingError: false, ...otherProps, ref: ref,
58
+ // Proposal: Make this default to true in v5
59
+ pauseWhenBuffering: pauseWhenBuffering !== null && pauseWhenBuffering !== void 0 ? pauseWhenBuffering : false, onDuration: onDuration, _remotionInternalStack: stack !== null && stack !== void 0 ? stack : null, _remotionInternalNativeLoopPassed: _remotionInternalNativeLoopPassed !== null && _remotionInternalNativeLoopPassed !== void 0 ? _remotionInternalNativeLoopPassed : false }));
58
60
  };
59
61
  /**
60
62
  * @description allows you to include a video file in your Remotion project. It wraps the native HTMLVideoElement.
@@ -7,6 +7,7 @@ export declare const VideoForRendering: ForwardRefExoticComponent<Omit<React.Det
7
7
  acceptableTimeShiftInSeconds?: number | undefined;
8
8
  allowAmplificationDuringRender?: boolean | undefined;
9
9
  toneFrequency?: number | undefined;
10
+ pauseWhenBuffering?: boolean | undefined;
10
11
  } & {
11
12
  onDuration: (src: string, durationInSeconds: number) => void;
12
13
  } & RefAttributes<HTMLVideoElement>>;
@@ -15,6 +15,7 @@ export type RemotionVideoProps = Omit<React.DetailedHTMLProps<React.VideoHTMLAtt
15
15
  acceptableTimeShiftInSeconds?: number;
16
16
  allowAmplificationDuringRender?: boolean;
17
17
  toneFrequency?: number;
18
+ pauseWhenBuffering?: boolean;
18
19
  };
19
20
  type DeprecatedOffthreadVideoProps = {
20
21
  /**
@@ -36,6 +37,7 @@ export type OffthreadVideoProps = {
36
37
  allowAmplificationDuringRender?: boolean;
37
38
  toneFrequency?: number;
38
39
  transparent?: boolean;
40
+ pauseWhenBuffering?: boolean;
39
41
  /**
40
42
  * @deprecated For internal use only
41
43
  */
@@ -23,6 +23,20 @@ export declare function useRemotionContexts(): {
23
23
  } | null;
24
24
  renderAssetManagerContext: import("./RenderAssetManager.js").RenderAssetManagerContext;
25
25
  sequenceManagerContext: import("./SequenceManager.js").SequenceManagerContext;
26
+ bufferManagerContext: {
27
+ addBlock: (block: {
28
+ id: string;
29
+ }) => {
30
+ unblock: () => void;
31
+ };
32
+ listenForBuffering: (callback: () => void) => {
33
+ remove: () => void;
34
+ };
35
+ listenForResume: (callback: () => void) => {
36
+ remove: () => void;
37
+ };
38
+ buffering: React.MutableRefObject<boolean>;
39
+ } | null;
26
40
  };
27
41
  export interface RemotionContextProviderProps {
28
42
  contexts: ReturnType<typeof useRemotionContexts>;
@@ -29,6 +29,7 @@ const jsx_runtime_1 = require("react/jsx-runtime");
29
29
  // such as in React Three Fiber. All the contexts need to be passed again
30
30
  // for them to be useable
31
31
  const react_1 = __importStar(require("react"));
32
+ const buffering_js_1 = require("./buffering.js");
32
33
  const CanUseRemotionHooks_js_1 = require("./CanUseRemotionHooks.js");
33
34
  const CompositionManagerContext_js_1 = require("./CompositionManagerContext.js");
34
35
  const NativeLayers_js_1 = require("./NativeLayers.js");
@@ -51,6 +52,7 @@ function useRemotionContexts() {
51
52
  const resolveCompositionContext = react_1.default.useContext(ResolveCompositionConfig_js_1.ResolveCompositionContext);
52
53
  const renderAssetManagerContext = react_1.default.useContext(RenderAssetManager_js_1.RenderAssetManager);
53
54
  const sequenceManagerContext = react_1.default.useContext(SequenceManager_js_1.SequenceManager);
55
+ const bufferManagerContext = react_1.default.useContext(buffering_js_1.BufferingContextReact);
54
56
  return (0, react_1.useMemo)(() => ({
55
57
  compositionManagerCtx,
56
58
  timelineContext,
@@ -63,6 +65,7 @@ function useRemotionContexts() {
63
65
  resolveCompositionContext,
64
66
  renderAssetManagerContext,
65
67
  sequenceManagerContext,
68
+ bufferManagerContext,
66
69
  }), [
67
70
  compositionManagerCtx,
68
71
  nonceContext,
@@ -75,11 +78,12 @@ function useRemotionContexts() {
75
78
  resolveCompositionContext,
76
79
  renderAssetManagerContext,
77
80
  sequenceManagerContext,
81
+ bufferManagerContext,
78
82
  ]);
79
83
  }
80
84
  exports.useRemotionContexts = useRemotionContexts;
81
85
  const RemotionContextProvider = (props) => {
82
86
  const { children, contexts } = props;
83
- return ((0, jsx_runtime_1.jsx)(CanUseRemotionHooks_js_1.CanUseRemotionHooks.Provider, { value: contexts.canUseRemotionHooksContext, children: (0, jsx_runtime_1.jsx)(nonce_js_1.NonceContext.Provider, { value: contexts.nonceContext, children: (0, jsx_runtime_1.jsx)(NativeLayers_js_1.NativeLayersContext.Provider, { value: contexts.nativeLayersContext, children: (0, jsx_runtime_1.jsx)(prefetch_state_js_1.PreloadContext.Provider, { value: contexts.preloadContext, children: (0, jsx_runtime_1.jsx)(CompositionManagerContext_js_1.CompositionManager.Provider, { value: contexts.compositionManagerCtx, children: (0, jsx_runtime_1.jsx)(SequenceManager_js_1.SequenceManager.Provider, { value: contexts.sequenceManagerContext, children: (0, jsx_runtime_1.jsx)(RenderAssetManager_js_1.RenderAssetManager.Provider, { value: contexts.renderAssetManagerContext, children: (0, jsx_runtime_1.jsx)(ResolveCompositionConfig_js_1.ResolveCompositionContext.Provider, { value: contexts.resolveCompositionContext, children: (0, jsx_runtime_1.jsx)(timeline_position_state_js_1.TimelineContext.Provider, { value: contexts.timelineContext, children: (0, jsx_runtime_1.jsx)(timeline_position_state_js_1.SetTimelineContext.Provider, { value: contexts.setTimelineContext, children: (0, jsx_runtime_1.jsx)(SequenceContext_js_1.SequenceContext.Provider, { value: contexts.sequenceContext, children: children }) }) }) }) }) }) }) }) }) }) }));
87
+ return ((0, jsx_runtime_1.jsx)(CanUseRemotionHooks_js_1.CanUseRemotionHooks.Provider, { value: contexts.canUseRemotionHooksContext, children: (0, jsx_runtime_1.jsx)(nonce_js_1.NonceContext.Provider, { value: contexts.nonceContext, children: (0, jsx_runtime_1.jsx)(NativeLayers_js_1.NativeLayersContext.Provider, { value: contexts.nativeLayersContext, children: (0, jsx_runtime_1.jsx)(prefetch_state_js_1.PreloadContext.Provider, { value: contexts.preloadContext, children: (0, jsx_runtime_1.jsx)(CompositionManagerContext_js_1.CompositionManager.Provider, { value: contexts.compositionManagerCtx, children: (0, jsx_runtime_1.jsx)(SequenceManager_js_1.SequenceManager.Provider, { value: contexts.sequenceManagerContext, children: (0, jsx_runtime_1.jsx)(RenderAssetManager_js_1.RenderAssetManager.Provider, { value: contexts.renderAssetManagerContext, children: (0, jsx_runtime_1.jsx)(ResolveCompositionConfig_js_1.ResolveCompositionContext.Provider, { value: contexts.resolveCompositionContext, children: (0, jsx_runtime_1.jsx)(timeline_position_state_js_1.TimelineContext.Provider, { value: contexts.timelineContext, children: (0, jsx_runtime_1.jsx)(timeline_position_state_js_1.SetTimelineContext.Provider, { value: contexts.setTimelineContext, children: (0, jsx_runtime_1.jsx)(SequenceContext_js_1.SequenceContext.Provider, { value: contexts.sequenceContext, children: (0, jsx_runtime_1.jsx)(buffering_js_1.BufferingContextReact.Provider, { value: contexts.bufferManagerContext, children: children }) }) }) }) }) }) }) }) }) }) }) }));
84
88
  };
85
89
  exports.RemotionContextProvider = RemotionContextProvider;
@@ -105,7 +105,7 @@ function truthy(value) {
105
105
  }
106
106
 
107
107
  // Automatically generated on publish
108
- const VERSION = '4.0.110';
108
+ const VERSION = '4.0.112';
109
109
 
110
110
  const checkMultipleRemotionVersions = () => {
111
111
  if (typeof globalThis === 'undefined') {
@@ -1492,6 +1492,105 @@ const random = (seed, dummy) => {
1492
1492
  throw new Error('random() argument must be a number or a string');
1493
1493
  };
1494
1494
 
1495
+ const useBufferManager = () => {
1496
+ const [blocks, setBlocks] = useState([]);
1497
+ const [onBufferingCallbacks, setOnBufferingCallbacks] = useState([]);
1498
+ const [onResumeCallbacks, setOnResumeCallbacks] = useState([]);
1499
+ const buffering = useRef(false);
1500
+ const addBlock = useCallback((block) => {
1501
+ setBlocks((b) => [...b, block]);
1502
+ return {
1503
+ unblock: () => {
1504
+ setBlocks((b) => b.filter((bx) => bx !== block));
1505
+ },
1506
+ };
1507
+ }, []);
1508
+ const listenForBuffering = useCallback((callback) => {
1509
+ setOnBufferingCallbacks((c) => [...c, callback]);
1510
+ return {
1511
+ remove: () => {
1512
+ setOnBufferingCallbacks((c) => c.filter((cb) => cb !== callback));
1513
+ },
1514
+ };
1515
+ }, []);
1516
+ const listenForResume = useCallback((callback) => {
1517
+ setOnResumeCallbacks((c) => [...c, callback]);
1518
+ return {
1519
+ remove: () => {
1520
+ setOnResumeCallbacks((c) => c.filter((cb) => cb !== callback));
1521
+ },
1522
+ };
1523
+ }, []);
1524
+ useEffect(() => {
1525
+ if (blocks.length > 0) {
1526
+ onBufferingCallbacks.forEach((c) => c());
1527
+ }
1528
+ else {
1529
+ onResumeCallbacks.forEach((c) => c());
1530
+ }
1531
+ }, [blocks, onBufferingCallbacks, onResumeCallbacks]);
1532
+ return useMemo(() => {
1533
+ return { addBlock, listenForBuffering, listenForResume, buffering };
1534
+ }, [addBlock, buffering, listenForBuffering, listenForResume]);
1535
+ };
1536
+ const BufferingContextReact = React.createContext(null);
1537
+ const BufferingProvider = ({ children }) => {
1538
+ const bufferManager = useBufferManager();
1539
+ return (jsx(BufferingContextReact.Provider, { value: bufferManager, children: children }));
1540
+ };
1541
+
1542
+ const useBufferState = () => {
1543
+ const buffer = useContext(BufferingContextReact);
1544
+ return useMemo(() => ({
1545
+ delayPlayback: () => {
1546
+ if (!buffer) {
1547
+ throw new Error('Tried to enable the buffering state, but a Remotion context was not found. This API can only be called in a component that was passed to the Remotion Player or a <Composition>. Or you might have experienced a version mismatch - run `npx remotion versions` and ensure all packages have the same version. This error is thrown by the buffer state https://remotion.dev/docs/player/buffer-state');
1548
+ }
1549
+ const { unblock } = buffer.addBlock({
1550
+ id: String(Math.random()),
1551
+ });
1552
+ return { unblock };
1553
+ },
1554
+ }), [buffer]);
1555
+ };
1556
+
1557
+ const useMediaBuffering = (element, shouldBuffer) => {
1558
+ const buffer = useBufferState();
1559
+ useEffect(() => {
1560
+ let cleanup = () => undefined;
1561
+ const { current } = element;
1562
+ if (!current) {
1563
+ return;
1564
+ }
1565
+ if (!shouldBuffer) {
1566
+ return;
1567
+ }
1568
+ const onWaiting = () => {
1569
+ const { unblock } = buffer.delayPlayback();
1570
+ const onCanPlay = () => {
1571
+ unblock();
1572
+ };
1573
+ current.addEventListener('canplay', onCanPlay, {
1574
+ once: true,
1575
+ });
1576
+ cleanup = () => {
1577
+ current.removeEventListener('canplay', onCanPlay);
1578
+ unblock();
1579
+ return undefined;
1580
+ };
1581
+ };
1582
+ if (current.readyState < current.HAVE_FUTURE_DATA) {
1583
+ onWaiting();
1584
+ }
1585
+ else {
1586
+ current.addEventListener('waiting', onWaiting);
1587
+ }
1588
+ return () => {
1589
+ cleanup();
1590
+ };
1591
+ }, [buffer, element, shouldBuffer]);
1592
+ };
1593
+
1495
1594
  const useMediaStartsAt = () => {
1496
1595
  var _a;
1497
1596
  const parentSequence = useContext(SequenceContext);
@@ -1940,6 +2039,7 @@ const useMediaPlayback = ({ mediaRef, src, mediaType, playbackRate: localPlaybac
1940
2039
  const frame = useCurrentFrame();
1941
2040
  const absoluteFrame = useTimelinePosition();
1942
2041
  const [playing] = usePlayingState();
2042
+ const buffering = useContext(BufferingContextReact);
1943
2043
  const { fps } = useVideoConfig();
1944
2044
  const mediaStartsAt = useMediaStartsAt();
1945
2045
  const playbackRate = localPlaybackRate * globalPlaybackRate;
@@ -1951,12 +2051,13 @@ const useMediaPlayback = ({ mediaRef, src, mediaType, playbackRate: localPlaybac
1951
2051
  }
1952
2052
  return acceptableTimeshift;
1953
2053
  })();
2054
+ const pausedOrBuffering = !playing || (buffering && buffering.buffering);
1954
2055
  useEffect(() => {
1955
2056
  var _a;
1956
- if (!playing) {
2057
+ if (pausedOrBuffering) {
1957
2058
  (_a = mediaRef.current) === null || _a === void 0 ? void 0 : _a.pause();
1958
2059
  }
1959
- }, [mediaRef, mediaType, playing]);
2060
+ }, [mediaRef, mediaType, pausedOrBuffering]);
1960
2061
  useEffect(() => {
1961
2062
  const tagName = mediaType === 'audio' ? '<Audio>' : '<Video>';
1962
2063
  if (!mediaRef.current) {
@@ -1996,12 +2097,14 @@ const useMediaPlayback = ({ mediaRef, src, mediaType, playbackRate: localPlaybac
1996
2097
  // Refer to the https://github.com/remotion-dev/video-buffering-example
1997
2098
  // which is fixed by only seeking conditionally.
1998
2099
  const makesSenseToSeek = Math.abs(mediaRef.current.currentTime - shouldBeTime) > 0.00001;
1999
- if (!playing || absoluteFrame === 0) {
2100
+ if (pausedOrBuffering || absoluteFrame === 0) {
2000
2101
  if (makesSenseToSeek) {
2001
2102
  seek(mediaRef, shouldBeTime);
2002
2103
  }
2003
2104
  }
2004
- if (mediaRef.current.paused && !mediaRef.current.ended && playing) {
2105
+ if (mediaRef.current.paused &&
2106
+ !mediaRef.current.ended &&
2107
+ !pausedOrBuffering) {
2005
2108
  if (makesSenseToSeek) {
2006
2109
  seek(mediaRef, shouldBeTime);
2007
2110
  }
@@ -2014,13 +2117,13 @@ const useMediaPlayback = ({ mediaRef, src, mediaType, playbackRate: localPlaybac
2014
2117
  frame,
2015
2118
  mediaRef,
2016
2119
  mediaType,
2017
- playing,
2018
2120
  src,
2019
2121
  mediaStartsAt,
2020
2122
  localPlaybackRate,
2021
2123
  onlyWarnForMediaSeekingError,
2022
2124
  acceptableTimeshift,
2023
2125
  acceptableTimeShiftButLessThanDuration,
2126
+ pausedOrBuffering,
2024
2127
  ]);
2025
2128
  };
2026
2129
 
@@ -2322,7 +2425,7 @@ const AudioForDevelopmentForwardRefFunction = (props, ref) => {
2322
2425
  const [mediaVolume] = useMediaVolumeState();
2323
2426
  const [mediaMuted] = useMediaMutedState();
2324
2427
  const volumePropFrame = useFrameForVolumeProp();
2325
- const { volume, muted, playbackRate, shouldPreMountAudioTags, src, onDuration, acceptableTimeShiftInSeconds, _remotionInternalNeedsDurationCalculation, _remotionInternalNativeLoopPassed, _remotionInternalStack, allowAmplificationDuringRender, name, ...nativeProps } = props;
2428
+ const { volume, muted, playbackRate, shouldPreMountAudioTags, src, onDuration, acceptableTimeShiftInSeconds, _remotionInternalNeedsDurationCalculation, _remotionInternalNativeLoopPassed, _remotionInternalStack, allowAmplificationDuringRender, name, pauseWhenBuffering, ...nativeProps } = props;
2326
2429
  const { hidden } = useContext(SequenceVisibilityToggleContext);
2327
2430
  if (!src) {
2328
2431
  throw new TypeError("No 'src' was passed to <Audio>.");
@@ -2384,6 +2487,7 @@ const AudioForDevelopmentForwardRefFunction = (props, ref) => {
2384
2487
  onlyWarnForMediaSeekingError: false,
2385
2488
  acceptableTimeshift: acceptableTimeShiftInSeconds !== null && acceptableTimeShiftInSeconds !== void 0 ? acceptableTimeShiftInSeconds : DEFAULT_ACCEPTABLE_TIMESHIFT,
2386
2489
  });
2490
+ useMediaBuffering(audioRef, pauseWhenBuffering);
2387
2491
  useImperativeHandle(ref, () => {
2388
2492
  return audioRef.current;
2389
2493
  }, [audioRef]);
@@ -2413,7 +2517,7 @@ const AudioForDevelopmentForwardRefFunction = (props, ref) => {
2413
2517
  }
2414
2518
  return jsx("audio", { ref: audioRef, preload: "metadata", ...propsToPass });
2415
2519
  };
2416
- const AudioForDevelopment = forwardRef(AudioForDevelopmentForwardRefFunction);
2520
+ const AudioForPreview = forwardRef(AudioForDevelopmentForwardRefFunction);
2417
2521
 
2418
2522
  if (typeof window !== 'undefined') {
2419
2523
  window.remotion_renderReady = false;
@@ -2642,7 +2746,7 @@ const AudioForRendering = forwardRef(AudioForRenderingRefForwardingFunction);
2642
2746
  const AudioRefForwardingFunction = (props, ref) => {
2643
2747
  var _a, _b, _c;
2644
2748
  const audioContext = useContext(SharedAudioContext);
2645
- const { startFrom, endAt, name, stack, ...otherProps } = props;
2749
+ const { startFrom, endAt, name, stack, pauseWhenBuffering, ...otherProps } = props;
2646
2750
  const { loop, ...propsOtherThanLoop } = props;
2647
2751
  const { fps } = useVideoConfig();
2648
2752
  const environment = getRemotionEnvironment();
@@ -2688,7 +2792,9 @@ const AudioRefForwardingFunction = (props, ref) => {
2688
2792
  if (environment.isRendering) {
2689
2793
  return (jsx(AudioForRendering, { onDuration: onDuration, ...props, ref: ref, onError: onError, _remotionInternalNeedsDurationCalculation: Boolean(loop) }));
2690
2794
  }
2691
- return (jsx(AudioForDevelopment, { _remotionInternalNativeLoopPassed: (_c = props._remotionInternalNativeLoopPassed) !== null && _c !== void 0 ? _c : false, _remotionInternalStack: stack !== null && stack !== void 0 ? stack : null, shouldPreMountAudioTags: audioContext !== null && audioContext.numberOfAudioTags > 0, ...props, ref: ref, onError: onError, onDuration: onDuration, _remotionInternalNeedsDurationCalculation: Boolean(loop) }));
2795
+ return (jsx(AudioForPreview, { _remotionInternalNativeLoopPassed: (_c = props._remotionInternalNativeLoopPassed) !== null && _c !== void 0 ? _c : false, _remotionInternalStack: stack !== null && stack !== void 0 ? stack : null, shouldPreMountAudioTags: audioContext !== null && audioContext.numberOfAudioTags > 0, ...props, ref: ref, onError: onError, onDuration: onDuration,
2796
+ // Proposal: Make this default to true in v5
2797
+ pauseWhenBuffering: pauseWhenBuffering !== null && pauseWhenBuffering !== void 0 ? pauseWhenBuffering : false, _remotionInternalNeedsDurationCalculation: Boolean(loop) }));
2692
2798
  };
2693
2799
  /**
2694
2800
  * @description With this component, you can add audio to your video. All audio formats which are supported by Chromium are supported by the component.
@@ -3221,9 +3327,10 @@ const IFrame = forwardRef(IFrameRefForwarding);
3221
3327
  function exponentialBackoff(errorCount) {
3222
3328
  return 1000 * 2 ** (errorCount - 1);
3223
3329
  }
3224
- const ImgRefForwarding = ({ onError, maxRetries = 2, src, ...props }, ref) => {
3330
+ const ImgRefForwarding = ({ onError, maxRetries = 2, src, pauseWhenLoading, ...props }, ref) => {
3225
3331
  const imageRef = useRef(null);
3226
3332
  const errors = useRef({});
3333
+ const { delayPlayback } = useBufferState();
3227
3334
  if (!src) {
3228
3335
  throw new Error('No "src" prop was passed to <Img>.');
3229
3336
  }
@@ -3279,6 +3386,9 @@ const ImgRefForwarding = ({ onError, maxRetries = 2, src, ...props }, ref) => {
3279
3386
  return;
3280
3387
  }
3281
3388
  const newHandle = delayRender('Loading <Img> with src=' + actualSrc);
3389
+ const unblock = pauseWhenLoading
3390
+ ? delayPlayback().unblock
3391
+ : () => undefined;
3282
3392
  const { current } = imageRef;
3283
3393
  const onComplete = () => {
3284
3394
  var _a, _b, _c, _d;
@@ -3287,6 +3397,7 @@ const ImgRefForwarding = ({ onError, maxRetries = 2, src, ...props }, ref) => {
3287
3397
  // eslint-disable-next-line no-console
3288
3398
  console.info(`Retry successful - ${(_d = imageRef.current) === null || _d === void 0 ? void 0 : _d.src} is now loaded`);
3289
3399
  }
3400
+ unblock();
3290
3401
  continueRender(newHandle);
3291
3402
  };
3292
3403
  const didLoad = () => {
@@ -3301,9 +3412,10 @@ const ImgRefForwarding = ({ onError, maxRetries = 2, src, ...props }, ref) => {
3301
3412
  // If tag gets unmounted, clear pending handles because image is not going to load
3302
3413
  return () => {
3303
3414
  current === null || current === void 0 ? void 0 : current.removeEventListener('load', didLoad);
3415
+ unblock();
3304
3416
  continueRender(newHandle);
3305
3417
  };
3306
- }, [actualSrc]);
3418
+ }, [actualSrc, delayPlayback, pauseWhenLoading]);
3307
3419
  }
3308
3420
  return (jsx("img", { ...props, ref: imageRef, src: actualSrc, onError: didGetError }));
3309
3421
  };
@@ -3939,7 +4051,7 @@ const RemotionRoot = ({ children, numberOfAudioTags }) => {
3939
4051
  }
3940
4052
  }
3941
4053
  }, []);
3942
- return (jsx(NonceContext.Provider, { value: nonceContext, children: jsx(TimelineContext.Provider, { value: timelineContextValue, children: jsx(SetTimelineContext.Provider, { value: setTimelineContextValue, children: jsx(EditorPropsProvider, { children: jsx(PrefetchProvider, { children: jsx(NativeLayersProvider, { children: jsx(CompositionManagerProvider, { numberOfAudioTags: numberOfAudioTags, children: jsx(DurationsContextProvider, { children: children }) }) }) }) }) }) }) }));
4054
+ return (jsx(NonceContext.Provider, { value: nonceContext, children: jsx(TimelineContext.Provider, { value: timelineContextValue, children: jsx(SetTimelineContext.Provider, { value: setTimelineContextValue, children: jsx(EditorPropsProvider, { children: jsx(PrefetchProvider, { children: jsx(NativeLayersProvider, { children: jsx(CompositionManagerProvider, { numberOfAudioTags: numberOfAudioTags, children: jsx(DurationsContextProvider, { children: jsx(BufferingProvider, { children: children }) }) }) }) }) }) }) }) }));
3943
4055
  };
3944
4056
 
3945
4057
  const getEnvVariables = () => {
@@ -3974,6 +4086,47 @@ const setupEnvVariables = () => {
3974
4086
  });
3975
4087
  };
3976
4088
 
4089
+ const CurrentScaleContext = React.createContext(null);
4090
+ const PreviewSizeContext = createContext({
4091
+ setSize: () => undefined,
4092
+ size: { size: 'auto', translation: { x: 0, y: 0 } },
4093
+ });
4094
+ const calculateScale = ({ canvasSize, compositionHeight, compositionWidth, previewSize, }) => {
4095
+ const heightRatio = canvasSize.height / compositionHeight;
4096
+ const widthRatio = canvasSize.width / compositionWidth;
4097
+ const ratio = Math.min(heightRatio, widthRatio);
4098
+ return previewSize === 'auto' ? ratio : Number(previewSize);
4099
+ };
4100
+ /**
4101
+ * Gets the current scale of the container in which the component is being rendered.
4102
+ * Only works in the Remotion Studio and in the Remotion Player.
4103
+ */
4104
+ const useCurrentScale = (options) => {
4105
+ const hasContext = React.useContext(CurrentScaleContext);
4106
+ const zoomContext = React.useContext(PreviewSizeContext);
4107
+ const config = useUnsafeVideoConfig();
4108
+ if (hasContext === null || config === null || zoomContext === null) {
4109
+ if (options === null || options === void 0 ? void 0 : options.dontThrowIfOutsideOfRemotion) {
4110
+ return 1;
4111
+ }
4112
+ throw new Error([
4113
+ 'useCurrentScale() was called outside of a Remotion context.',
4114
+ 'This hook can only be called in a component that is being rendered by Remotion.',
4115
+ 'If you want to this hook to return 1 outside of Remotion, pass {dontThrowIfOutsideOfRemotion: true} as an option.',
4116
+ 'If you think you called this hook in a Remotion component, make sure all versions of Remotion are aligned.',
4117
+ ].join('\n'));
4118
+ }
4119
+ if (hasContext.type === 'scale') {
4120
+ return hasContext.scale;
4121
+ }
4122
+ return calculateScale({
4123
+ canvasSize: hasContext.canvasSize,
4124
+ compositionHeight: config.height,
4125
+ compositionWidth: config.width,
4126
+ previewSize: zoomContext.size.size,
4127
+ });
4128
+ };
4129
+
3977
4130
  const WATCH_REMOTION_STATIC_FILES = 'remotion_staticFilesChanged';
3978
4131
  /**
3979
4132
  * @description Watch for changes in a specific static file.
@@ -4028,6 +4181,7 @@ function useRemotionContexts() {
4028
4181
  const resolveCompositionContext = React.useContext(ResolveCompositionContext);
4029
4182
  const renderAssetManagerContext = React.useContext(RenderAssetManager);
4030
4183
  const sequenceManagerContext = React.useContext(SequenceManager);
4184
+ const bufferManagerContext = React.useContext(BufferingContextReact);
4031
4185
  return useMemo(() => ({
4032
4186
  compositionManagerCtx,
4033
4187
  timelineContext,
@@ -4040,6 +4194,7 @@ function useRemotionContexts() {
4040
4194
  resolveCompositionContext,
4041
4195
  renderAssetManagerContext,
4042
4196
  sequenceManagerContext,
4197
+ bufferManagerContext,
4043
4198
  }), [
4044
4199
  compositionManagerCtx,
4045
4200
  nonceContext,
@@ -4052,11 +4207,12 @@ function useRemotionContexts() {
4052
4207
  resolveCompositionContext,
4053
4208
  renderAssetManagerContext,
4054
4209
  sequenceManagerContext,
4210
+ bufferManagerContext,
4055
4211
  ]);
4056
4212
  }
4057
4213
  const RemotionContextProvider = (props) => {
4058
4214
  const { children, contexts } = props;
4059
- return (jsx(CanUseRemotionHooks.Provider, { value: contexts.canUseRemotionHooksContext, children: jsx(NonceContext.Provider, { value: contexts.nonceContext, children: jsx(NativeLayersContext.Provider, { value: contexts.nativeLayersContext, children: jsx(PreloadContext.Provider, { value: contexts.preloadContext, children: jsx(CompositionManager.Provider, { value: contexts.compositionManagerCtx, children: jsx(SequenceManager.Provider, { value: contexts.sequenceManagerContext, children: jsx(RenderAssetManager.Provider, { value: contexts.renderAssetManagerContext, children: jsx(ResolveCompositionContext.Provider, { value: contexts.resolveCompositionContext, children: jsx(TimelineContext.Provider, { value: contexts.timelineContext, children: jsx(SetTimelineContext.Provider, { value: contexts.setTimelineContext, children: jsx(SequenceContext.Provider, { value: contexts.sequenceContext, children: children }) }) }) }) }) }) }) }) }) }) }));
4215
+ return (jsx(CanUseRemotionHooks.Provider, { value: contexts.canUseRemotionHooksContext, children: jsx(NonceContext.Provider, { value: contexts.nonceContext, children: jsx(NativeLayersContext.Provider, { value: contexts.nativeLayersContext, children: jsx(PreloadContext.Provider, { value: contexts.preloadContext, children: jsx(CompositionManager.Provider, { value: contexts.compositionManagerCtx, children: jsx(SequenceManager.Provider, { value: contexts.sequenceManagerContext, children: jsx(RenderAssetManager.Provider, { value: contexts.renderAssetManagerContext, children: jsx(ResolveCompositionContext.Provider, { value: contexts.resolveCompositionContext, children: jsx(TimelineContext.Provider, { value: contexts.timelineContext, children: jsx(SetTimelineContext.Provider, { value: contexts.setTimelineContext, children: jsx(SequenceContext.Provider, { value: contexts.sequenceContext, children: jsx(BufferingContextReact.Provider, { value: contexts.bufferManagerContext, children: children }) }) }) }) }) }) }) }) }) }) }) }));
4060
4216
  };
4061
4217
 
4062
4218
  // Mark them as Internals so use don't assume this is public
@@ -4116,8 +4272,13 @@ const Internals = {
4116
4272
  WATCH_REMOTION_STATIC_FILES,
4117
4273
  addSequenceStackTraces,
4118
4274
  useMediaStartsAt,
4275
+ BufferingProvider,
4276
+ BufferingContextReact,
4119
4277
  enableSequenceStackTraces,
4120
4278
  colorNames,
4279
+ CurrentScaleContext,
4280
+ PreviewSizeContext,
4281
+ calculateScale,
4121
4282
  };
4122
4283
 
4123
4284
  const validateFrame = ({ allowFloats, durationInFrames, frame, }) => {
@@ -4601,7 +4762,7 @@ const VideoForDevelopmentRefForwardingFunction = (props, ref) => {
4601
4762
  const isSequenceHidden = (_a = hidden[timelineId]) !== null && _a !== void 0 ? _a : false;
4602
4763
  const { volume, muted, playbackRate, onlyWarnForMediaSeekingError, src, onDuration,
4603
4764
  // @ts-expect-error
4604
- acceptableTimeShift, acceptableTimeShiftInSeconds, toneFrequency, name, _remotionInternalNativeLoopPassed, _remotionInternalStack, style, ...nativeProps } = props;
4765
+ acceptableTimeShift, acceptableTimeShiftInSeconds, toneFrequency, name, _remotionInternalNativeLoopPassed, _remotionInternalStack, style, pauseWhenBuffering, ...nativeProps } = props;
4605
4766
  if (typeof acceptableTimeShift !== 'undefined') {
4606
4767
  throw new Error('acceptableTimeShift has been removed. Use acceptableTimeShiftInSeconds instead.');
4607
4768
  }
@@ -4634,6 +4795,7 @@ const VideoForDevelopmentRefForwardingFunction = (props, ref) => {
4634
4795
  onlyWarnForMediaSeekingError,
4635
4796
  acceptableTimeshift: acceptableTimeShiftInSeconds !== null && acceptableTimeShiftInSeconds !== void 0 ? acceptableTimeShiftInSeconds : DEFAULT_ACCEPTABLE_TIMESHIFT,
4636
4797
  });
4798
+ useMediaBuffering(videoRef, pauseWhenBuffering);
4637
4799
  const actualFrom = parentSequence
4638
4800
  ? parentSequence.relativeFrom + parentSequence.cumulatedFrom
4639
4801
  : 0;
@@ -4721,8 +4883,7 @@ const VideoForDevelopmentRefForwardingFunction = (props, ref) => {
4721
4883
  }, [isSequenceHidden, style]);
4722
4884
  return (jsx("video", { ref: videoRef, muted: muted || mediaMuted, playsInline: true, src: actualSrc, loop: _remotionInternalNativeLoopPassed, style: actualStyle, ...nativeProps }));
4723
4885
  };
4724
- // Copy types from forwardRef but not necessary to remove ref
4725
- const VideoForDevelopment = forwardRef(VideoForDevelopmentRefForwardingFunction);
4886
+ const VideoForPreview = forwardRef(VideoForDevelopmentRefForwardingFunction);
4726
4887
 
4727
4888
  /**
4728
4889
  * @description This method imports and displays a video, similar to <Video />. During rendering, it extracts the exact frame from the video and displays it in an <img> tag
@@ -4731,7 +4892,7 @@ const VideoForDevelopment = forwardRef(VideoForDevelopmentRefForwardingFunction)
4731
4892
  const OffthreadVideo = (props) => {
4732
4893
  // Should only destruct `startFrom` and `endAt` from props,
4733
4894
  // rest gets drilled down
4734
- const { startFrom, endAt, name, stack, ...otherProps } = props;
4895
+ const { startFrom, endAt, name, pauseWhenBuffering, stack, ...otherProps } = props;
4735
4896
  const environment = getRemotionEnvironment();
4736
4897
  const onDuration = useCallback(() => undefined, []);
4737
4898
  if (typeof props.src !== 'string') {
@@ -4751,7 +4912,7 @@ const OffthreadVideo = (props) => {
4751
4912
  return jsx(OffthreadVideoForRendering, { ...otherProps });
4752
4913
  }
4753
4914
  const { transparent, ...withoutTransparent } = otherProps;
4754
- return (jsx(VideoForDevelopment, { _remotionInternalStack: stack !== null && stack !== void 0 ? stack : null, _remotionInternalNativeLoopPassed: false, onDuration: onDuration, onlyWarnForMediaSeekingError: true, ...withoutTransparent }));
4915
+ return (jsx(VideoForPreview, { _remotionInternalStack: stack !== null && stack !== void 0 ? stack : null, _remotionInternalNativeLoopPassed: false, onDuration: onDuration, onlyWarnForMediaSeekingError: true, pauseWhenBuffering: pauseWhenBuffering !== null && pauseWhenBuffering !== void 0 ? pauseWhenBuffering : false, ...withoutTransparent }));
4755
4916
  };
4756
4917
 
4757
4918
  const roundTo6Commas = (num) => {
@@ -5022,7 +5183,7 @@ const VideoForRendering = forwardRef(VideoForRenderingForwardFunction);
5022
5183
 
5023
5184
  const VideoForwardingFunction = (props, ref) => {
5024
5185
  var _a, _b;
5025
- const { startFrom, endAt, name, stack, _remotionInternalNativeLoopPassed, ...otherProps } = props;
5186
+ const { startFrom, endAt, name, pauseWhenBuffering, stack, _remotionInternalNativeLoopPassed, ...otherProps } = props;
5026
5187
  const { loop, ...propsOtherThanLoop } = props;
5027
5188
  const { fps } = useVideoConfig();
5028
5189
  const environment = getRemotionEnvironment();
@@ -5057,7 +5218,9 @@ const VideoForwardingFunction = (props, ref) => {
5057
5218
  if (environment.isRendering) {
5058
5219
  return (jsx(VideoForRendering, { onDuration: onDuration, ...otherProps, ref: ref }));
5059
5220
  }
5060
- return (jsx(VideoForDevelopment, { onlyWarnForMediaSeekingError: false, ...otherProps, ref: ref, onDuration: onDuration, _remotionInternalStack: stack !== null && stack !== void 0 ? stack : null, _remotionInternalNativeLoopPassed: _remotionInternalNativeLoopPassed !== null && _remotionInternalNativeLoopPassed !== void 0 ? _remotionInternalNativeLoopPassed : false }));
5221
+ return (jsx(VideoForPreview, { onlyWarnForMediaSeekingError: false, ...otherProps, ref: ref,
5222
+ // Proposal: Make this default to true in v5
5223
+ pauseWhenBuffering: pauseWhenBuffering !== null && pauseWhenBuffering !== void 0 ? pauseWhenBuffering : false, onDuration: onDuration, _remotionInternalStack: stack !== null && stack !== void 0 ? stack : null, _remotionInternalNativeLoopPassed: _remotionInternalNativeLoopPassed !== null && _remotionInternalNativeLoopPassed !== void 0 ? _remotionInternalNativeLoopPassed : false }));
5061
5224
  };
5062
5225
  /**
5063
5226
  * @description allows you to include a video file in your Remotion project. It wraps the native HTMLVideoElement.
@@ -5108,4 +5271,4 @@ const Config = new Proxy(proxyObj, {
5108
5271
  });
5109
5272
  addSequenceStackTraces(Sequence);
5110
5273
 
5111
- export { AbsoluteFill, Audio, Composition, Config, Easing, Experimental, Folder, FolderContext, Freeze, IFrame, Img, Internals, Loop, OffthreadVideo, Sequence, Series, Still, VERSION, Video, cancelRender, continueRender, delayRender, getInputProps, getRemotionEnvironment, getStaticFiles, interpolate, interpolateColors, measureSpring, prefetch, random, registerRoot, spring, staticFile, useCurrentFrame, useVideoConfig, watchStaticFile };
5274
+ export { AbsoluteFill, Audio, Composition, Config, Easing, Experimental, Folder, FolderContext, Freeze, IFrame, Img, Internals, Loop, OffthreadVideo, Sequence, Series, Still, VERSION, Video, cancelRender, continueRender, delayRender, getInputProps, getRemotionEnvironment, getStaticFiles, interpolate, interpolateColors, measureSpring, prefetch, random, registerRoot, spring, staticFile, useBufferState, useCurrentFrame, useCurrentScale, useVideoConfig, watchStaticFile };
@@ -1,4 +1,4 @@
1
1
  // Automatically generated on publish
2
- const VERSION = '4.0.110';
2
+ const VERSION = '4.0.112';
3
3
 
4
4
  export { VERSION };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "remotion",
3
- "version": "4.0.110",
3
+ "version": "4.0.112",
4
4
  "description": "Render videos in React",
5
5
  "main": "dist/cjs/index.js",
6
6
  "types": "dist/cjs/index.d.ts",