remotion 4.0.18 → 4.0.20

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.
@@ -9,4 +9,5 @@ export declare const Audio: React.ForwardRefExoticComponent<Pick<Omit<React.Deta
9
9
  playbackRate?: number | undefined;
10
10
  acceptableTimeShiftInSeconds?: number | undefined;
11
11
  allowAmplificationDuringRender?: boolean | undefined;
12
- } & RemotionMainAudioProps, "id" | "key" | "defaultChecked" | "defaultValue" | "suppressContentEditableWarning" | "suppressHydrationWarning" | "accessKey" | "className" | "contentEditable" | "contextMenu" | "dir" | "draggable" | "hidden" | "lang" | "placeholder" | "slot" | "spellCheck" | "style" | "tabIndex" | "title" | "translate" | "radioGroup" | "role" | "about" | "datatype" | "inlist" | "prefix" | "property" | "resource" | "typeof" | "vocab" | "autoCapitalize" | "autoCorrect" | "autoSave" | "color" | "itemProp" | "itemScope" | "itemType" | "itemID" | "itemRef" | "results" | "security" | "unselectable" | "inputMode" | "is" | "aria-activedescendant" | "aria-atomic" | "aria-autocomplete" | "aria-busy" | "aria-checked" | "aria-colcount" | "aria-colindex" | "aria-colspan" | "aria-controls" | "aria-current" | "aria-describedby" | "aria-details" | "aria-disabled" | "aria-dropeffect" | "aria-errormessage" | "aria-expanded" | "aria-flowto" | "aria-grabbed" | "aria-haspopup" | "aria-hidden" | "aria-invalid" | "aria-keyshortcuts" | "aria-label" | "aria-labelledby" | "aria-level" | "aria-live" | "aria-modal" | "aria-multiline" | "aria-multiselectable" | "aria-orientation" | "aria-owns" | "aria-placeholder" | "aria-posinset" | "aria-pressed" | "aria-readonly" | "aria-relevant" | "aria-required" | "aria-roledescription" | "aria-rowcount" | "aria-rowindex" | "aria-rowspan" | "aria-selected" | "aria-setsize" | "aria-sort" | "aria-valuemax" | "aria-valuemin" | "aria-valuenow" | "aria-valuetext" | "children" | "dangerouslySetInnerHTML" | "onCopy" | "onCopyCapture" | "onCut" | "onCutCapture" | "onPaste" | "onPasteCapture" | "onCompositionEnd" | "onCompositionEndCapture" | "onCompositionStart" | "onCompositionStartCapture" | "onCompositionUpdate" | "onCompositionUpdateCapture" | "onFocus" | "onFocusCapture" | "onBlur" | "onBlurCapture" | "onChange" | "onChangeCapture" | "onBeforeInput" | "onBeforeInputCapture" | "onInput" | "onInputCapture" | "onReset" | "onResetCapture" | "onSubmit" | "onSubmitCapture" | "onInvalid" | "onInvalidCapture" | "onLoad" | "onLoadCapture" | "onError" | "onErrorCapture" | "onKeyDown" | "onKeyDownCapture" | "onKeyPress" | "onKeyPressCapture" | "onKeyUp" | "onKeyUpCapture" | "onAbort" | "onAbortCapture" | "onCanPlay" | "onCanPlayCapture" | "onCanPlayThrough" | "onCanPlayThroughCapture" | "onDurationChange" | "onDurationChangeCapture" | "onEmptied" | "onEmptiedCapture" | "onEncrypted" | "onEncryptedCapture" | "onEndedCapture" | "onLoadedData" | "onLoadedDataCapture" | "onLoadedMetadata" | "onLoadedMetadataCapture" | "onLoadStart" | "onLoadStartCapture" | "onPause" | "onPauseCapture" | "onPlay" | "onPlayCapture" | "onPlaying" | "onPlayingCapture" | "onProgress" | "onProgressCapture" | "onRateChange" | "onRateChangeCapture" | "onSeeked" | "onSeekedCapture" | "onSeeking" | "onSeekingCapture" | "onStalled" | "onStalledCapture" | "onSuspend" | "onSuspendCapture" | "onTimeUpdate" | "onTimeUpdateCapture" | "onVolumeChange" | "onVolumeChangeCapture" | "onWaiting" | "onWaitingCapture" | "onAuxClick" | "onAuxClickCapture" | "onClick" | "onClickCapture" | "onContextMenu" | "onContextMenuCapture" | "onDoubleClick" | "onDoubleClickCapture" | "onDrag" | "onDragCapture" | "onDragEnd" | "onDragEndCapture" | "onDragEnter" | "onDragEnterCapture" | "onDragExit" | "onDragExitCapture" | "onDragLeave" | "onDragLeaveCapture" | "onDragOver" | "onDragOverCapture" | "onDragStart" | "onDragStartCapture" | "onDrop" | "onDropCapture" | "onMouseDown" | "onMouseDownCapture" | "onMouseEnter" | "onMouseLeave" | "onMouseMove" | "onMouseMoveCapture" | "onMouseOut" | "onMouseOutCapture" | "onMouseOver" | "onMouseOverCapture" | "onMouseUp" | "onMouseUpCapture" | "onSelect" | "onSelectCapture" | "onTouchCancel" | "onTouchCancelCapture" | "onTouchEnd" | "onTouchEndCapture" | "onTouchMove" | "onTouchMoveCapture" | "onTouchStart" | "onTouchStartCapture" | "onPointerDown" | "onPointerDownCapture" | "onPointerMove" | "onPointerMoveCapture" | "onPointerUp" | "onPointerUpCapture" | "onPointerCancel" | "onPointerCancelCapture" | "onPointerEnter" | "onPointerEnterCapture" | "onPointerLeave" | "onPointerLeaveCapture" | "onPointerOver" | "onPointerOverCapture" | "onPointerOut" | "onPointerOutCapture" | "onGotPointerCapture" | "onGotPointerCaptureCapture" | "onLostPointerCapture" | "onLostPointerCaptureCapture" | "onScroll" | "onScrollCapture" | "onWheel" | "onWheelCapture" | "onAnimationStart" | "onAnimationStartCapture" | "onAnimationEnd" | "onAnimationEndCapture" | "onAnimationIteration" | "onAnimationIterationCapture" | "onTransitionEnd" | "onTransitionEndCapture" | "volume" | "allowAmplificationDuringRender" | "controlsList" | "crossOrigin" | "loop" | "mediaGroup" | "muted" | "playsInline" | "preload" | "src" | "playbackRate" | "acceptableTimeShiftInSeconds" | keyof RemotionMainAudioProps> & React.RefAttributes<HTMLAudioElement>>;
12
+ _remotionInternalNeedsDurationCalculation?: boolean | undefined;
13
+ } & RemotionMainAudioProps, "id" | "key" | "defaultChecked" | "defaultValue" | "suppressContentEditableWarning" | "suppressHydrationWarning" | "accessKey" | "className" | "contentEditable" | "contextMenu" | "dir" | "draggable" | "hidden" | "lang" | "placeholder" | "slot" | "spellCheck" | "style" | "tabIndex" | "title" | "translate" | "radioGroup" | "role" | "about" | "datatype" | "inlist" | "prefix" | "property" | "resource" | "typeof" | "vocab" | "autoCapitalize" | "autoCorrect" | "autoSave" | "color" | "itemProp" | "itemScope" | "itemType" | "itemID" | "itemRef" | "results" | "security" | "unselectable" | "inputMode" | "is" | "aria-activedescendant" | "aria-atomic" | "aria-autocomplete" | "aria-busy" | "aria-checked" | "aria-colcount" | "aria-colindex" | "aria-colspan" | "aria-controls" | "aria-current" | "aria-describedby" | "aria-details" | "aria-disabled" | "aria-dropeffect" | "aria-errormessage" | "aria-expanded" | "aria-flowto" | "aria-grabbed" | "aria-haspopup" | "aria-hidden" | "aria-invalid" | "aria-keyshortcuts" | "aria-label" | "aria-labelledby" | "aria-level" | "aria-live" | "aria-modal" | "aria-multiline" | "aria-multiselectable" | "aria-orientation" | "aria-owns" | "aria-placeholder" | "aria-posinset" | "aria-pressed" | "aria-readonly" | "aria-relevant" | "aria-required" | "aria-roledescription" | "aria-rowcount" | "aria-rowindex" | "aria-rowspan" | "aria-selected" | "aria-setsize" | "aria-sort" | "aria-valuemax" | "aria-valuemin" | "aria-valuenow" | "aria-valuetext" | "children" | "dangerouslySetInnerHTML" | "onCopy" | "onCopyCapture" | "onCut" | "onCutCapture" | "onPaste" | "onPasteCapture" | "onCompositionEnd" | "onCompositionEndCapture" | "onCompositionStart" | "onCompositionStartCapture" | "onCompositionUpdate" | "onCompositionUpdateCapture" | "onFocus" | "onFocusCapture" | "onBlur" | "onBlurCapture" | "onChange" | "onChangeCapture" | "onBeforeInput" | "onBeforeInputCapture" | "onInput" | "onInputCapture" | "onReset" | "onResetCapture" | "onSubmit" | "onSubmitCapture" | "onInvalid" | "onInvalidCapture" | "onLoad" | "onLoadCapture" | "onError" | "onErrorCapture" | "onKeyDown" | "onKeyDownCapture" | "onKeyPress" | "onKeyPressCapture" | "onKeyUp" | "onKeyUpCapture" | "onAbort" | "onAbortCapture" | "onCanPlay" | "onCanPlayCapture" | "onCanPlayThrough" | "onCanPlayThroughCapture" | "onDurationChange" | "onDurationChangeCapture" | "onEmptied" | "onEmptiedCapture" | "onEncrypted" | "onEncryptedCapture" | "onEndedCapture" | "onLoadedData" | "onLoadedDataCapture" | "onLoadedMetadata" | "onLoadedMetadataCapture" | "onLoadStart" | "onLoadStartCapture" | "onPause" | "onPauseCapture" | "onPlay" | "onPlayCapture" | "onPlaying" | "onPlayingCapture" | "onProgress" | "onProgressCapture" | "onRateChange" | "onRateChangeCapture" | "onSeeked" | "onSeekedCapture" | "onSeeking" | "onSeekingCapture" | "onStalled" | "onStalledCapture" | "onSuspend" | "onSuspendCapture" | "onTimeUpdate" | "onTimeUpdateCapture" | "onVolumeChange" | "onVolumeChangeCapture" | "onWaiting" | "onWaitingCapture" | "onAuxClick" | "onAuxClickCapture" | "onClick" | "onClickCapture" | "onContextMenu" | "onContextMenuCapture" | "onDoubleClick" | "onDoubleClickCapture" | "onDrag" | "onDragCapture" | "onDragEnd" | "onDragEndCapture" | "onDragEnter" | "onDragEnterCapture" | "onDragExit" | "onDragExitCapture" | "onDragLeave" | "onDragLeaveCapture" | "onDragOver" | "onDragOverCapture" | "onDragStart" | "onDragStartCapture" | "onDrop" | "onDropCapture" | "onMouseDown" | "onMouseDownCapture" | "onMouseEnter" | "onMouseLeave" | "onMouseMove" | "onMouseMoveCapture" | "onMouseOut" | "onMouseOutCapture" | "onMouseOver" | "onMouseOverCapture" | "onMouseUp" | "onMouseUpCapture" | "onSelect" | "onSelectCapture" | "onTouchCancel" | "onTouchCancelCapture" | "onTouchEnd" | "onTouchEndCapture" | "onTouchMove" | "onTouchMoveCapture" | "onTouchStart" | "onTouchStartCapture" | "onPointerDown" | "onPointerDownCapture" | "onPointerMove" | "onPointerMoveCapture" | "onPointerUp" | "onPointerUpCapture" | "onPointerCancel" | "onPointerCancelCapture" | "onPointerEnter" | "onPointerEnterCapture" | "onPointerLeave" | "onPointerLeaveCapture" | "onPointerOver" | "onPointerOverCapture" | "onPointerOut" | "onPointerOutCapture" | "onGotPointerCapture" | "onGotPointerCaptureCapture" | "onLostPointerCapture" | "onLostPointerCaptureCapture" | "onScroll" | "onScrollCapture" | "onWheel" | "onWheelCapture" | "onAnimationStart" | "onAnimationStartCapture" | "onAnimationEnd" | "onAnimationEndCapture" | "onAnimationIteration" | "onAnimationIterationCapture" | "onTransitionEnd" | "onTransitionEndCapture" | "volume" | "allowAmplificationDuringRender" | "controlsList" | "crossOrigin" | "loop" | "mediaGroup" | "muted" | "playsInline" | "preload" | "src" | "playbackRate" | "acceptableTimeShiftInSeconds" | "_remotionInternalNeedsDurationCalculation" | keyof RemotionMainAudioProps> & React.RefAttributes<HTMLAudioElement>>;
@@ -45,7 +45,7 @@ const AudioRefForwardingFunction = (props, ref) => {
45
45
  const duration = Math.floor(durations[(0, absolute_src_js_1.getAbsoluteSrc)(props.src)] * fps);
46
46
  const playbackRate = (_a = props.playbackRate) !== null && _a !== void 0 ? _a : 1;
47
47
  const actualDuration = duration / playbackRate;
48
- return ((0, jsx_runtime_1.jsx)(index_js_1.Loop, { layout: "none", durationInFrames: Math.floor(actualDuration), children: (0, jsx_runtime_1.jsx)(exports.Audio, { ...propsOtherThanLoop, ref: ref }) }));
48
+ return ((0, jsx_runtime_1.jsx)(index_js_1.Loop, { layout: "none", durationInFrames: Math.floor(actualDuration), children: (0, jsx_runtime_1.jsx)(exports.Audio, { _remotionInternalNeedsDurationCalculation: true, ...propsOtherThanLoop, ref: ref }) }));
49
49
  }
50
50
  if (typeof startFrom !== 'undefined' || typeof endAt !== 'undefined') {
51
51
  (0, validate_start_from_props_js_1.validateStartFromProps)(startFrom, endAt);
@@ -5,6 +5,7 @@ export declare const AudioForDevelopment: ForwardRefExoticComponent<Omit<React.D
5
5
  playbackRate?: number | undefined;
6
6
  acceptableTimeShiftInSeconds?: number | undefined;
7
7
  allowAmplificationDuringRender?: boolean | undefined;
8
+ _remotionInternalNeedsDurationCalculation?: boolean | undefined;
8
9
  } & {
9
10
  shouldPreMountAudioTags: boolean;
10
11
  onDuration: (src: string, durationInSeconds: number) => void;
@@ -5,6 +5,7 @@ export declare const AudioForRendering: ForwardRefExoticComponent<Omit<React.Det
5
5
  playbackRate?: number | undefined;
6
6
  acceptableTimeShiftInSeconds?: number | undefined;
7
7
  allowAmplificationDuringRender?: boolean | undefined;
8
+ _remotionInternalNeedsDurationCalculation?: boolean | undefined;
8
9
  } & {
9
10
  onDuration: (src: string, durationInSeconds: number) => void;
10
11
  } & RefAttributes<HTMLAudioElement>>;
@@ -5,7 +5,6 @@ const jsx_runtime_1 = require("react/jsx-runtime");
5
5
  const react_1 = require("react");
6
6
  const absolute_src_js_1 = require("../absolute-src.js");
7
7
  const delay_render_js_1 = require("../delay-render.js");
8
- const get_environment_js_1 = require("../get-environment.js");
9
8
  const random_js_1 = require("../random.js");
10
9
  const RenderAssetManager_js_1 = require("../RenderAssetManager.js");
11
10
  const SequenceContext_js_1 = require("../SequenceContext.js");
@@ -20,14 +19,13 @@ const AudioForRenderingRefForwardingFunction = (props, ref) => {
20
19
  const frame = (0, use_current_frame_js_1.useCurrentFrame)();
21
20
  const sequenceContext = (0, react_1.useContext)(SequenceContext_js_1.SequenceContext);
22
21
  const { registerRenderAsset, unregisterRenderAsset } = (0, react_1.useContext)(RenderAssetManager_js_1.RenderAssetManager);
23
- const environment = (0, get_environment_js_1.useRemotionEnvironment)();
24
22
  // Generate a string that's as unique as possible for this asset
25
23
  // but at the same time the same on all threads
26
24
  const id = (0, react_1.useMemo)(() => {
27
25
  var _a;
28
26
  return `audio-${(0, random_js_1.random)((_a = props.src) !== null && _a !== void 0 ? _a : '')}-${sequenceContext === null || sequenceContext === void 0 ? void 0 : sequenceContext.relativeFrom}-${sequenceContext === null || sequenceContext === void 0 ? void 0 : sequenceContext.cumulatedFrom}-${sequenceContext === null || sequenceContext === void 0 ? void 0 : sequenceContext.durationInFrames}`;
29
27
  }, [props.src, sequenceContext]);
30
- const { volume: volumeProp, playbackRate, allowAmplificationDuringRender, onDuration, ...nativeProps } = props;
28
+ const { volume: volumeProp, playbackRate, allowAmplificationDuringRender, onDuration, _remotionInternalNeedsDurationCalculation, ...nativeProps } = props;
31
29
  const volume = (0, volume_prop_js_1.evaluateVolume)({
32
30
  volume: volumeProp,
33
31
  frame: volumePropFrame,
@@ -77,34 +75,40 @@ const AudioForRenderingRefForwardingFunction = (props, ref) => {
77
75
  allowAmplificationDuringRender,
78
76
  ]);
79
77
  const { src } = props;
78
+ // The <audio> tag is only rendered if the duration needs to be calculated for the `loop`
79
+ // attribute to work, or if the user assigns a ref to it.
80
+ const needsToRenderAudioTag = ref || _remotionInternalNeedsDurationCalculation;
80
81
  // If audio source switches, make new handle
81
- if (environment === 'rendering') {
82
- // eslint-disable-next-line react-hooks/rules-of-hooks
83
- (0, react_1.useLayoutEffect)(() => {
84
- if (process.env.NODE_ENV === 'test') {
85
- return;
86
- }
87
- const newHandle = (0, delay_render_js_1.delayRender)('Loading <Audio> duration with src=' + src);
88
- const { current } = audioRef;
89
- const didLoad = () => {
90
- if (current === null || current === void 0 ? void 0 : current.duration) {
91
- onDuration(current.src, current.duration);
92
- }
93
- (0, delay_render_js_1.continueRender)(newHandle);
94
- };
82
+ (0, react_1.useLayoutEffect)(() => {
83
+ if (process.env.NODE_ENV === 'test') {
84
+ return;
85
+ }
86
+ if (!needsToRenderAudioTag) {
87
+ return;
88
+ }
89
+ const newHandle = (0, delay_render_js_1.delayRender)('Loading <Audio> duration with src=' + src);
90
+ const { current } = audioRef;
91
+ const didLoad = () => {
95
92
  if (current === null || current === void 0 ? void 0 : current.duration) {
96
93
  onDuration(current.src, current.duration);
97
- (0, delay_render_js_1.continueRender)(newHandle);
98
- }
99
- else {
100
- current === null || current === void 0 ? void 0 : current.addEventListener('loadedmetadata', didLoad, { once: true });
101
94
  }
102
- // If tag gets unmounted, clear pending handles because video metadata is not going to load
103
- return () => {
104
- current === null || current === void 0 ? void 0 : current.removeEventListener('loadedmetadata', didLoad);
105
- (0, delay_render_js_1.continueRender)(newHandle);
106
- };
107
- }, [src, onDuration]);
95
+ (0, delay_render_js_1.continueRender)(newHandle);
96
+ };
97
+ if (current === null || current === void 0 ? void 0 : current.duration) {
98
+ onDuration(current.src, current.duration);
99
+ (0, delay_render_js_1.continueRender)(newHandle);
100
+ }
101
+ else {
102
+ current === null || current === void 0 ? void 0 : current.addEventListener('loadedmetadata', didLoad, { once: true });
103
+ }
104
+ // If tag gets unmounted, clear pending handles because video metadata is not going to load
105
+ return () => {
106
+ current === null || current === void 0 ? void 0 : current.removeEventListener('loadedmetadata', didLoad);
107
+ (0, delay_render_js_1.continueRender)(newHandle);
108
+ };
109
+ }, [src, onDuration, needsToRenderAudioTag]);
110
+ if (!needsToRenderAudioTag) {
111
+ return null;
108
112
  }
109
113
  return (0, jsx_runtime_1.jsx)("audio", { ref: audioRef, ...nativeProps });
110
114
  };
@@ -9,4 +9,5 @@ export type RemotionAudioProps = Omit<React.DetailedHTMLProps<React.AudioHTMLAtt
9
9
  playbackRate?: number;
10
10
  acceptableTimeShiftInSeconds?: number;
11
11
  allowAmplificationDuringRender?: boolean;
12
+ _remotionInternalNeedsDurationCalculation?: boolean;
12
13
  };
@@ -4,6 +4,10 @@ import type { TRenderAsset } from './CompositionManager.js';
4
4
  import type { StaticFile } from './get-static-files.js';
5
5
  import type { ClipRegion } from './NativeLayers.js';
6
6
  import type { VideoConfig } from './video-config.js';
7
+ export type VideoConfigWithSerializedProps = Omit<VideoConfig, 'defaultProps' | 'props'> & {
8
+ serializedDefaultPropsWithCustomSchema: string;
9
+ serializedResolvedPropsWithCustomSchema: string;
10
+ };
7
11
  declare global {
8
12
  interface Window {
9
13
  remotion_renderReady: boolean;
@@ -15,11 +19,8 @@ declare global {
15
19
  };
16
20
  remotion_cancelledError: string | undefined;
17
21
  remotion_getCompositionNames: () => string[];
18
- getStaticCompositions: () => Promise<VideoConfig[]>;
19
- remotion_calculateComposition: (compId: string) => Promise<Omit<VideoConfig, 'defaultProps' | 'props'> & {
20
- serializedDefaultPropsWithCustomSchema: string;
21
- serializedResolvedPropsWithCustomSchema: string;
22
- }>;
22
+ getStaticCompositions: () => Promise<VideoConfigWithSerializedProps[]>;
23
+ remotion_calculateComposition: (compId: string) => Promise<VideoConfigWithSerializedProps>;
23
24
  remotion_setBundleMode: (bundleMode: BundleState) => void;
24
25
  remotion_staticBase: string;
25
26
  remotion_staticFiles: StaticFile[];
@@ -42,7 +43,7 @@ declare global {
42
43
  remotion_isPlayer: boolean;
43
44
  remotion_isBuilding: undefined | (() => void);
44
45
  remotion_finishedBuilding: undefined | (() => void);
45
- siteVersion: '9';
46
+ siteVersion: '10';
46
47
  remotion_version: string;
47
48
  remotion_imported: string | boolean;
48
49
  }
@@ -65,15 +65,15 @@ const useMediaPlayback = ({ mediaRef, src, mediaType, playbackRate: localPlaybac
65
65
  // Refer to the https://github.com/remotion-dev/video-buffering-example
66
66
  // which is fixed by only seeking conditionally.
67
67
  const makesSenseToSeek = Math.abs(mediaRef.current.currentTime - shouldBeTime) > 0.00001;
68
- if (!makesSenseToSeek) {
69
- return;
70
- }
71
68
  if (!playing || absoluteFrame === 0) {
72
- mediaRef.current.currentTime = shouldBeTime;
73
- return;
69
+ if (makesSenseToSeek) {
70
+ mediaRef.current.currentTime = shouldBeTime;
71
+ }
74
72
  }
75
73
  if (mediaRef.current.paused && !mediaRef.current.ended && playing) {
76
- mediaRef.current.currentTime = shouldBeTime;
74
+ if (makesSenseToSeek) {
75
+ mediaRef.current.currentTime = shouldBeTime;
76
+ }
77
77
  (0, play_and_handle_not_allowed_error_js_1.playAndHandleNotAllowedError)(mediaRef, mediaType);
78
78
  }
79
79
  }, [
@@ -1 +1 @@
1
- export declare const VERSION = "4.0.18";
1
+ export declare const VERSION = "4.0.20";
@@ -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.18';
5
+ exports.VERSION = '4.0.20';
@@ -59,7 +59,7 @@ function truthy(value) {
59
59
  }
60
60
 
61
61
  // Automatically generated on publish
62
- const VERSION = '4.0.18';
62
+ const VERSION = '4.0.20';
63
63
 
64
64
  const checkMultipleRemotionVersions = () => {
65
65
  if (typeof globalThis === 'undefined') {
@@ -1809,15 +1809,15 @@ const useMediaPlayback = ({ mediaRef, src, mediaType, playbackRate: localPlaybac
1809
1809
  // Refer to the https://github.com/remotion-dev/video-buffering-example
1810
1810
  // which is fixed by only seeking conditionally.
1811
1811
  const makesSenseToSeek = Math.abs(mediaRef.current.currentTime - shouldBeTime) > 0.00001;
1812
- if (!makesSenseToSeek) {
1813
- return;
1814
- }
1815
1812
  if (!playing || absoluteFrame === 0) {
1816
- mediaRef.current.currentTime = shouldBeTime;
1817
- return;
1813
+ if (makesSenseToSeek) {
1814
+ mediaRef.current.currentTime = shouldBeTime;
1815
+ }
1818
1816
  }
1819
1817
  if (mediaRef.current.paused && !mediaRef.current.ended && playing) {
1820
- mediaRef.current.currentTime = shouldBeTime;
1818
+ if (makesSenseToSeek) {
1819
+ mediaRef.current.currentTime = shouldBeTime;
1820
+ }
1821
1821
  playAndHandleNotAllowedError(mediaRef, mediaType);
1822
1822
  }
1823
1823
  }, [
@@ -2334,14 +2334,13 @@ const AudioForRenderingRefForwardingFunction = (props, ref) => {
2334
2334
  const frame = useCurrentFrame();
2335
2335
  const sequenceContext = useContext(SequenceContext);
2336
2336
  const { registerRenderAsset, unregisterRenderAsset } = useContext(RenderAssetManager);
2337
- const environment = useRemotionEnvironment();
2338
2337
  // Generate a string that's as unique as possible for this asset
2339
2338
  // but at the same time the same on all threads
2340
2339
  const id = useMemo(() => {
2341
2340
  var _a;
2342
2341
  return `audio-${random((_a = props.src) !== null && _a !== void 0 ? _a : '')}-${sequenceContext === null || sequenceContext === void 0 ? void 0 : sequenceContext.relativeFrom}-${sequenceContext === null || sequenceContext === void 0 ? void 0 : sequenceContext.cumulatedFrom}-${sequenceContext === null || sequenceContext === void 0 ? void 0 : sequenceContext.durationInFrames}`;
2343
2342
  }, [props.src, sequenceContext]);
2344
- const { volume: volumeProp, playbackRate, allowAmplificationDuringRender, onDuration, ...nativeProps } = props;
2343
+ const { volume: volumeProp, playbackRate, allowAmplificationDuringRender, onDuration, _remotionInternalNeedsDurationCalculation, ...nativeProps } = props;
2345
2344
  const volume = evaluateVolume({
2346
2345
  volume: volumeProp,
2347
2346
  frame: volumePropFrame,
@@ -2391,34 +2390,40 @@ const AudioForRenderingRefForwardingFunction = (props, ref) => {
2391
2390
  allowAmplificationDuringRender,
2392
2391
  ]);
2393
2392
  const { src } = props;
2393
+ // The <audio> tag is only rendered if the duration needs to be calculated for the `loop`
2394
+ // attribute to work, or if the user assigns a ref to it.
2395
+ const needsToRenderAudioTag = ref || _remotionInternalNeedsDurationCalculation;
2394
2396
  // If audio source switches, make new handle
2395
- if (environment === 'rendering') {
2396
- // eslint-disable-next-line react-hooks/rules-of-hooks
2397
- useLayoutEffect(() => {
2398
- if (process.env.NODE_ENV === 'test') {
2399
- return;
2400
- }
2401
- const newHandle = delayRender('Loading <Audio> duration with src=' + src);
2402
- const { current } = audioRef;
2403
- const didLoad = () => {
2404
- if (current === null || current === void 0 ? void 0 : current.duration) {
2405
- onDuration(current.src, current.duration);
2406
- }
2407
- continueRender(newHandle);
2408
- };
2397
+ useLayoutEffect(() => {
2398
+ if (process.env.NODE_ENV === 'test') {
2399
+ return;
2400
+ }
2401
+ if (!needsToRenderAudioTag) {
2402
+ return;
2403
+ }
2404
+ const newHandle = delayRender('Loading <Audio> duration with src=' + src);
2405
+ const { current } = audioRef;
2406
+ const didLoad = () => {
2409
2407
  if (current === null || current === void 0 ? void 0 : current.duration) {
2410
2408
  onDuration(current.src, current.duration);
2411
- continueRender(newHandle);
2412
2409
  }
2413
- else {
2414
- current === null || current === void 0 ? void 0 : current.addEventListener('loadedmetadata', didLoad, { once: true });
2415
- }
2416
- // If tag gets unmounted, clear pending handles because video metadata is not going to load
2417
- return () => {
2418
- current === null || current === void 0 ? void 0 : current.removeEventListener('loadedmetadata', didLoad);
2419
- continueRender(newHandle);
2420
- };
2421
- }, [src, onDuration]);
2410
+ continueRender(newHandle);
2411
+ };
2412
+ if (current === null || current === void 0 ? void 0 : current.duration) {
2413
+ onDuration(current.src, current.duration);
2414
+ continueRender(newHandle);
2415
+ }
2416
+ else {
2417
+ current === null || current === void 0 ? void 0 : current.addEventListener('loadedmetadata', didLoad, { once: true });
2418
+ }
2419
+ // If tag gets unmounted, clear pending handles because video metadata is not going to load
2420
+ return () => {
2421
+ current === null || current === void 0 ? void 0 : current.removeEventListener('loadedmetadata', didLoad);
2422
+ continueRender(newHandle);
2423
+ };
2424
+ }, [src, onDuration, needsToRenderAudioTag]);
2425
+ if (!needsToRenderAudioTag) {
2426
+ return null;
2422
2427
  }
2423
2428
  return jsx("audio", { ref: audioRef, ...nativeProps });
2424
2429
  };
@@ -2454,7 +2459,7 @@ const AudioRefForwardingFunction = (props, ref) => {
2454
2459
  const duration = Math.floor(durations[getAbsoluteSrc(props.src)] * fps);
2455
2460
  const playbackRate = (_a = props.playbackRate) !== null && _a !== void 0 ? _a : 1;
2456
2461
  const actualDuration = duration / playbackRate;
2457
- return (jsx(Loop, { layout: "none", durationInFrames: Math.floor(actualDuration), children: jsx(Audio, { ...propsOtherThanLoop, ref: ref }) }));
2462
+ return (jsx(Loop, { layout: "none", durationInFrames: Math.floor(actualDuration), children: jsx(Audio, { _remotionInternalNeedsDurationCalculation: true, ...propsOtherThanLoop, ref: ref }) }));
2458
2463
  }
2459
2464
  if (typeof startFrom !== 'undefined' || typeof endAt !== 'undefined') {
2460
2465
  validateStartFromProps(startFrom, endAt);
@@ -1,4 +1,4 @@
1
1
  // Automatically generated on publish
2
- const VERSION = '4.0.18';
2
+ const VERSION = '4.0.20';
3
3
 
4
4
  export { VERSION };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "remotion",
3
- "version": "4.0.18",
3
+ "version": "4.0.20",
4
4
  "description": "Render videos in React",
5
5
  "main": "dist/cjs/index.js",
6
6
  "types": "dist/cjs/index.d.ts",
@@ -1,11 +0,0 @@
1
- /// <reference types="react" />
2
- import type { TAsset } from './CompositionManager.js';
3
- export type AssetManagerContext = {
4
- registerAsset: (asset: TAsset) => void;
5
- unregisterAsset: (id: string) => void;
6
- assets: TAsset[];
7
- };
8
- export declare const AssetManager: import("react").Context<AssetManagerContext>;
9
- export declare const AssetManagerProvider: React.FC<{
10
- children: React.ReactNode;
11
- }>;
@@ -1,40 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.AssetManagerProvider = exports.AssetManager = void 0;
4
- const jsx_runtime_1 = require("react/jsx-runtime");
5
- const react_1 = require("react");
6
- exports.AssetManager = (0, react_1.createContext)({
7
- registerAsset: () => undefined,
8
- unregisterAsset: () => undefined,
9
- assets: [],
10
- });
11
- const AssetManagerProvider = ({ children }) => {
12
- const [assets, setAssets] = (0, react_1.useState)([]);
13
- const registerAsset = (0, react_1.useCallback)((asset) => {
14
- setAssets((assts) => {
15
- return [...assts, asset];
16
- });
17
- }, []);
18
- const unregisterAsset = (0, react_1.useCallback)((id) => {
19
- setAssets((assts) => {
20
- return assts.filter((a) => a.id !== id);
21
- });
22
- }, []);
23
- (0, react_1.useLayoutEffect)(() => {
24
- if (typeof window !== 'undefined') {
25
- window.remotion_collectAssets = () => {
26
- setAssets([]); // clear assets at next render
27
- return assets;
28
- };
29
- }
30
- }, [assets]);
31
- const contextValue = (0, react_1.useMemo)(() => {
32
- return {
33
- registerAsset,
34
- unregisterAsset,
35
- assets,
36
- };
37
- }, [assets, registerAsset, unregisterAsset]);
38
- return ((0, jsx_runtime_1.jsx)(exports.AssetManager.Provider, { value: contextValue, children: children }));
39
- };
40
- exports.AssetManagerProvider = AssetManagerProvider;
@@ -1,7 +0,0 @@
1
- type ContinueRenderFnBinded = () => void;
2
- /**
3
- * @description Same as delayRender(), but as a hook.
4
- * @see [Documentation](https://remotion.dev/docs/use-delay-render)
5
- */
6
- export declare const useDelayRender: (label?: string) => ContinueRenderFnBinded;
7
- export {};
@@ -1,16 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.useDelayRender = void 0;
4
- const react_1 = require("react");
5
- const delay_render_js_1 = require("./delay-render.js");
6
- /**
7
- * @description Same as delayRender(), but as a hook.
8
- * @see [Documentation](https://remotion.dev/docs/use-delay-render)
9
- */
10
- const useDelayRender = (label) => {
11
- const [handle] = (0, react_1.useState)(() => (0, delay_render_js_1.delayRender)(label));
12
- return (0, react_1.useCallback)(() => {
13
- (0, delay_render_js_1.continueRender)(handle);
14
- }, [handle]);
15
- };
16
- exports.useDelayRender = useDelayRender;