remotion 4.0.277 → 4.0.279

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.
@@ -64,7 +64,6 @@ export type AudioOrVideoAsset = {
64
64
  volume: number;
65
65
  mediaFrame: number;
66
66
  playbackRate: number;
67
- allowAmplificationDuringRender: boolean;
68
67
  toneFrequency: number | null;
69
68
  audioStartFrame: number;
70
69
  };
@@ -5,8 +5,10 @@ const jsx_runtime_1 = require("react/jsx-runtime");
5
5
  const react_1 = require("react");
6
6
  const SequenceContext_js_1 = require("../SequenceContext.js");
7
7
  const SequenceManager_js_1 = require("../SequenceManager.js");
8
+ const log_level_context_js_1 = require("../log-level-context.js");
8
9
  const prefetch_js_1 = require("../prefetch.js");
9
10
  const random_js_1 = require("../random.js");
11
+ const use_amplification_js_1 = require("../use-amplification.js");
10
12
  const use_media_in_timeline_js_1 = require("../use-media-in-timeline.js");
11
13
  const use_media_playback_js_1 = require("../use-media-playback.js");
12
14
  const use_sync_volume_with_media_tag_js_1 = require("../use-sync-volume-with-media-tag.js");
@@ -20,6 +22,7 @@ const AudioForDevelopmentForwardRefFunction = (props, ref) => {
20
22
  if (props.shouldPreMountAudioTags !== initialShouldPreMountAudioElements) {
21
23
  throw new Error('Cannot change the behavior for pre-mounting audio tags dynamically.');
22
24
  }
25
+ const logLevel = (0, log_level_context_js_1.useLogLevel)();
23
26
  const { volume, muted, playbackRate, shouldPreMountAudioTags, src, onDuration, acceptableTimeShiftInSeconds, _remotionInternalNeedsDurationCalculation, _remotionInternalNativeLoopPassed, _remotionInternalStack, allowAmplificationDuringRender, name, pauseWhenBuffering, showInTimeline, loopVolumeCurveBehavior, stack, ...nativeProps } = props;
24
27
  const [mediaVolume] = (0, volume_position_state_js_1.useMediaVolumeState)();
25
28
  const [mediaMuted] = (0, volume_position_state_js_1.useMediaMutedState)();
@@ -36,7 +39,6 @@ const AudioForDevelopmentForwardRefFunction = (props, ref) => {
36
39
  frame: volumePropFrame,
37
40
  volume,
38
41
  mediaVolume,
39
- allowAmplificationDuringRender: false,
40
42
  });
41
43
  const propsToPass = (0, react_1.useMemo)(() => {
42
44
  return {
@@ -86,16 +88,22 @@ const AudioForDevelopmentForwardRefFunction = (props, ref) => {
86
88
  onAutoPlayError: null,
87
89
  isPremounting: Boolean(sequenceContext === null || sequenceContext === void 0 ? void 0 : sequenceContext.premounting),
88
90
  });
91
+ (0, use_amplification_js_1.useAmplification)({
92
+ logLevel,
93
+ mediaRef: audioRef,
94
+ volume: userPreferredVolume,
95
+ });
89
96
  (0, use_media_playback_js_1.useMediaPlayback)({
90
97
  mediaRef: audioRef,
91
98
  src,
92
99
  mediaType: 'audio',
93
100
  playbackRate: playbackRate !== null && playbackRate !== void 0 ? playbackRate : 1,
94
101
  onlyWarnForMediaSeekingError: false,
95
- acceptableTimeshift: acceptableTimeShiftInSeconds !== null && acceptableTimeShiftInSeconds !== void 0 ? acceptableTimeShiftInSeconds : use_media_playback_js_1.DEFAULT_ACCEPTABLE_TIMESHIFT,
102
+ acceptableTimeshift: acceptableTimeShiftInSeconds !== null && acceptableTimeShiftInSeconds !== void 0 ? acceptableTimeShiftInSeconds : null,
96
103
  isPremounting: Boolean(sequenceContext === null || sequenceContext === void 0 ? void 0 : sequenceContext.premounting),
97
104
  pauseWhenBuffering,
98
105
  onAutoPlayError: null,
106
+ userPreferredVolume,
99
107
  });
100
108
  (0, react_1.useImperativeHandle)(ref, () => {
101
109
  return audioRef.current;
@@ -35,7 +35,6 @@ const AudioForRenderingRefForwardingFunction = (props, ref) => {
35
35
  volume: volumeProp,
36
36
  frame: volumePropFrame,
37
37
  mediaVolume: 1,
38
- allowAmplificationDuringRender: allowAmplificationDuringRender !== null && allowAmplificationDuringRender !== void 0 ? allowAmplificationDuringRender : false,
39
38
  });
40
39
  (0, react_1.useImperativeHandle)(ref, () => {
41
40
  return audioRef.current;
@@ -62,7 +61,6 @@ const AudioForRenderingRefForwardingFunction = (props, ref) => {
62
61
  volume,
63
62
  mediaFrame: frame,
64
63
  playbackRate: (_a = props.playbackRate) !== null && _a !== void 0 ? _a : 1,
65
- allowAmplificationDuringRender: allowAmplificationDuringRender !== null && allowAmplificationDuringRender !== void 0 ? allowAmplificationDuringRender : false,
66
64
  toneFrequency: toneFrequency !== null && toneFrequency !== void 0 ? toneFrequency : null,
67
65
  audioStartFrame: Math.max(0, -((_b = sequenceContext === null || sequenceContext === void 0 ? void 0 : sequenceContext.relativeFrom) !== null && _b !== void 0 ? _b : 0)),
68
66
  });
@@ -79,7 +77,6 @@ const AudioForRenderingRefForwardingFunction = (props, ref) => {
79
77
  frame,
80
78
  playbackRate,
81
79
  props.playbackRate,
82
- allowAmplificationDuringRender,
83
80
  toneFrequency,
84
81
  sequenceContext === null || sequenceContext === void 0 ? void 0 : sequenceContext.relativeFrom,
85
82
  ]);
@@ -9,6 +9,9 @@ export type RemotionAudioProps = Omit<React.DetailedHTMLProps<React.AudioHTMLAtt
9
9
  volume?: VolumeProp;
10
10
  playbackRate?: number;
11
11
  acceptableTimeShiftInSeconds?: number;
12
+ /**
13
+ * @deprecated Amplification is now always enabled. To prevent amplification, set `volume` to a value less than 1.
14
+ */
12
15
  allowAmplificationDuringRender?: boolean;
13
16
  _remotionInternalNeedsDurationCalculation?: boolean;
14
17
  _remotionInternalNativeLoopPassed?: boolean;
@@ -0,0 +1,14 @@
1
+ import { type RefObject } from 'react';
2
+ import type { LogLevel } from './log';
3
+ type AudioItems = {
4
+ gainNode: GainNode;
5
+ source: MediaElementAudioSourceNode;
6
+ audioContext: AudioContext;
7
+ };
8
+ export declare const getShouldAmplify: (volume: number) => boolean;
9
+ export declare const useAmplification: ({ mediaRef, volume, logLevel, }: {
10
+ mediaRef: RefObject<HTMLAudioElement | HTMLVideoElement | null>;
11
+ volume: number;
12
+ logLevel: LogLevel;
13
+ }) => RefObject<AudioItems | null>;
14
+ export {};
@@ -0,0 +1,66 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.useAmplification = exports.getShouldAmplify = void 0;
4
+ const react_1 = require("react");
5
+ const log_1 = require("./log");
6
+ let warned = false;
7
+ const warnOnce = (logLevel) => {
8
+ if (warned) {
9
+ return;
10
+ }
11
+ warned = true;
12
+ log_1.Log.warn(logLevel, 'AudioContext is not supported in this browser');
13
+ };
14
+ const getShouldAmplify = (volume) => {
15
+ return volume > 1;
16
+ };
17
+ exports.getShouldAmplify = getShouldAmplify;
18
+ const useAmplification = ({ mediaRef, volume, logLevel, }) => {
19
+ var _a;
20
+ const shouldAmplify = (0, exports.getShouldAmplify)(volume);
21
+ const audioStuffRef = (0, react_1.useRef)(null);
22
+ const currentVolumeRef = (0, react_1.useRef)(volume);
23
+ currentVolumeRef.current = volume;
24
+ (0, react_1.useLayoutEffect)(() => {
25
+ var _a;
26
+ if (!shouldAmplify) {
27
+ return;
28
+ }
29
+ if (!AudioContext) {
30
+ warnOnce(logLevel);
31
+ return;
32
+ }
33
+ if (!mediaRef.current) {
34
+ return;
35
+ }
36
+ if (audioStuffRef.current) {
37
+ return;
38
+ }
39
+ const audioContext = new AudioContext({
40
+ latencyHint: 'interactive',
41
+ });
42
+ const source = new MediaElementAudioSourceNode(audioContext, {
43
+ mediaElement: mediaRef.current,
44
+ });
45
+ const gainNode = new GainNode(audioContext, {
46
+ gain: Math.max(currentVolumeRef.current, 1),
47
+ });
48
+ audioStuffRef.current = {
49
+ gainNode,
50
+ source,
51
+ audioContext,
52
+ };
53
+ source.connect(gainNode);
54
+ gainNode.connect(audioContext.destination);
55
+ log_1.Log.trace(logLevel, `Starting to amplify ${(_a = mediaRef.current) === null || _a === void 0 ? void 0 : _a.src}. Gain = ${currentVolumeRef.current}`);
56
+ }, [logLevel, mediaRef, shouldAmplify]);
57
+ if (audioStuffRef.current) {
58
+ const valueToSet = Math.max(volume, 1);
59
+ if (audioStuffRef.current.gainNode.gain.value !== valueToSet) {
60
+ audioStuffRef.current.gainNode.gain.value = valueToSet;
61
+ log_1.Log.trace(logLevel, `Setting gain to ${valueToSet} for ${(_a = mediaRef.current) === null || _a === void 0 ? void 0 : _a.src}`);
62
+ }
63
+ }
64
+ return audioStuffRef;
65
+ };
66
+ exports.useAmplification = useAmplification;
@@ -51,7 +51,6 @@ const useMediaInTimeline = ({ volume, mediaVolume, mediaRef, src, mediaType, pla
51
51
  frame: i + startsAt,
52
52
  volume,
53
53
  mediaVolume,
54
- allowAmplificationDuringRender: false,
55
54
  });
56
55
  })
57
56
  .join(',');
@@ -1,13 +1,13 @@
1
1
  import type { RefObject } from 'react';
2
- export declare const DEFAULT_ACCEPTABLE_TIMESHIFT = 0.45;
3
- export declare const useMediaPlayback: ({ mediaRef, src, mediaType, playbackRate: localPlaybackRate, onlyWarnForMediaSeekingError, acceptableTimeshift, pauseWhenBuffering, isPremounting, onAutoPlayError, }: {
2
+ export declare const useMediaPlayback: ({ mediaRef, src, mediaType, playbackRate: localPlaybackRate, onlyWarnForMediaSeekingError, acceptableTimeshift, pauseWhenBuffering, isPremounting, onAutoPlayError, userPreferredVolume, }: {
4
3
  mediaRef: RefObject<HTMLVideoElement | HTMLAudioElement | null>;
5
4
  src: string | undefined;
6
5
  mediaType: "audio" | "video";
7
6
  playbackRate: number;
8
7
  onlyWarnForMediaSeekingError: boolean;
9
- acceptableTimeshift: number;
8
+ acceptableTimeshift: number | null;
10
9
  pauseWhenBuffering: boolean;
11
10
  isPremounting: boolean;
12
11
  onAutoPlayError: null | (() => void);
12
+ userPreferredVolume: number;
13
13
  }) => void;
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.useMediaPlayback = exports.DEFAULT_ACCEPTABLE_TIMESHIFT = void 0;
3
+ exports.useMediaPlayback = void 0;
4
4
  const react_1 = require("react");
5
5
  const use_audio_frame_js_1 = require("./audio/use-audio-frame.js");
6
6
  const buffer_until_first_frame_js_1 = require("./buffer-until-first-frame.js");
@@ -11,14 +11,14 @@ const play_and_handle_not_allowed_error_js_1 = require("./play-and-handle-not-al
11
11
  const playback_logging_js_1 = require("./playback-logging.js");
12
12
  const seek_js_1 = require("./seek.js");
13
13
  const timeline_position_state_js_1 = require("./timeline-position-state.js");
14
+ const use_amplification_js_1 = require("./use-amplification.js");
14
15
  const use_current_frame_js_1 = require("./use-current-frame.js");
15
16
  const use_media_buffering_js_1 = require("./use-media-buffering.js");
16
17
  const use_request_video_callback_time_js_1 = require("./use-request-video-callback-time.js");
17
18
  const use_video_config_js_1 = require("./use-video-config.js");
18
19
  const get_current_time_js_1 = require("./video/get-current-time.js");
19
20
  const warn_about_non_seekable_media_js_1 = require("./warn-about-non-seekable-media.js");
20
- exports.DEFAULT_ACCEPTABLE_TIMESHIFT = 0.45;
21
- const useMediaPlayback = ({ mediaRef, src, mediaType, playbackRate: localPlaybackRate, onlyWarnForMediaSeekingError, acceptableTimeshift, pauseWhenBuffering, isPremounting, onAutoPlayError, }) => {
21
+ const useMediaPlayback = ({ mediaRef, src, mediaType, playbackRate: localPlaybackRate, onlyWarnForMediaSeekingError, acceptableTimeshift, pauseWhenBuffering, isPremounting, onAutoPlayError, userPreferredVolume, }) => {
22
22
  const { playbackRate: globalPlaybackRate } = (0, react_1.useContext)(timeline_position_state_js_1.TimelineContext);
23
23
  const frame = (0, use_current_frame_js_1.useCurrentFrame)();
24
24
  const absoluteFrame = (0, timeline_position_state_js_1.useTimelinePosition)();
@@ -69,13 +69,20 @@ const useMediaPlayback = ({ mediaRef, src, mediaType, playbackRate: localPlaybac
69
69
  mountTime,
70
70
  });
71
71
  const playbackRate = localPlaybackRate * globalPlaybackRate;
72
- // For short audio, a lower acceptable time shift is used
73
72
  const acceptableTimeShiftButLessThanDuration = (() => {
74
73
  var _a;
74
+ // In Safari, it seems to lag behind mostly around ~0.4 seconds
75
+ const DEFAULT_ACCEPTABLE_TIMESHIFT_WITH_NORMAL_PLAYBACK = 0.45;
76
+ // If there is amplification, the acceptable timeshift is higher
77
+ const DEFAULT_ACCEPTABLE_TIMESHIFT_WITH_AMPLIFICATION = DEFAULT_ACCEPTABLE_TIMESHIFT_WITH_NORMAL_PLAYBACK + 0.2;
78
+ const defaultAcceptableTimeshift = (0, use_amplification_js_1.getShouldAmplify)(userPreferredVolume)
79
+ ? DEFAULT_ACCEPTABLE_TIMESHIFT_WITH_AMPLIFICATION
80
+ : DEFAULT_ACCEPTABLE_TIMESHIFT_WITH_NORMAL_PLAYBACK;
81
+ // For short audio, a lower acceptable time shift is used
75
82
  if ((_a = mediaRef.current) === null || _a === void 0 ? void 0 : _a.duration) {
76
- return Math.min(mediaRef.current.duration, acceptableTimeshift !== null && acceptableTimeshift !== void 0 ? acceptableTimeshift : exports.DEFAULT_ACCEPTABLE_TIMESHIFT);
83
+ return Math.min(mediaRef.current.duration, acceptableTimeshift !== null && acceptableTimeshift !== void 0 ? acceptableTimeshift : defaultAcceptableTimeshift);
77
84
  }
78
- return acceptableTimeshift;
85
+ return acceptableTimeshift !== null && acceptableTimeshift !== void 0 ? acceptableTimeshift : defaultAcceptableTimeshift;
79
86
  })();
80
87
  const isPlayerBuffering = (0, buffering_js_1.useIsPlayerBuffering)(buffering);
81
88
  (0, react_1.useEffect)(() => {
@@ -171,7 +178,7 @@ const useMediaPlayback = ({ mediaRef, src, mediaType, playbackRate: localPlaybac
171
178
  }
172
179
  return;
173
180
  }
174
- const seekThreshold = playing ? 0.15 : 0.00001;
181
+ const seekThreshold = playing ? 0.15 : 0.01;
175
182
  // Only perform a seek if the time is not already the same.
176
183
  // Chrome rounds to 6 digits, so 0.033333333 -> 0.033333,
177
184
  // therefore a threshold is allowed.
@@ -13,10 +13,9 @@ const useSyncVolumeWithMediaTag = ({ volumePropFrame, volume, mediaVolume, media
13
13
  frame: volumePropFrame,
14
14
  volume,
15
15
  mediaVolume,
16
- allowAmplificationDuringRender: false,
17
16
  });
18
17
  if (!(0, is_approximately_the_same_js_1.isApproximatelyTheSame)(userPreferredVolume, mediaRef.current.volume)) {
19
- mediaRef.current.volume = userPreferredVolume;
18
+ mediaRef.current.volume = Math.min(userPreferredVolume, 1);
20
19
  }
21
20
  }, [mediaRef, mediaVolume, volume, volumePropFrame]);
22
21
  (0, react_1.useEffect)(() => {
@@ -3,4 +3,4 @@
3
3
  * @see [Documentation](https://remotion.dev/docs/version)
4
4
  * @returns {string} The current version of the remotion package
5
5
  */
6
- export declare const VERSION = "4.0.277";
6
+ export declare const VERSION = "4.0.279";
@@ -7,4 +7,4 @@ exports.VERSION = void 0;
7
7
  * @see [Documentation](https://remotion.dev/docs/version)
8
8
  * @returns {string} The current version of the remotion package
9
9
  */
10
- exports.VERSION = '4.0.277';
10
+ exports.VERSION = '4.0.279';
@@ -48,7 +48,6 @@ crossOrigin, ...props }) => {
48
48
  volume: volumeProp,
49
49
  frame: volumePropsFrame,
50
50
  mediaVolume: 1,
51
- allowAmplificationDuringRender: allowAmplificationDuringRender !== null && allowAmplificationDuringRender !== void 0 ? allowAmplificationDuringRender : false,
52
51
  });
53
52
  (0, react_1.useEffect)(() => {
54
53
  var _a;
@@ -72,7 +71,6 @@ crossOrigin, ...props }) => {
72
71
  volume,
73
72
  mediaFrame: frame,
74
73
  playbackRate: playbackRate !== null && playbackRate !== void 0 ? playbackRate : 1,
75
- allowAmplificationDuringRender: allowAmplificationDuringRender !== null && allowAmplificationDuringRender !== void 0 ? allowAmplificationDuringRender : false,
76
74
  toneFrequency: toneFrequency !== null && toneFrequency !== void 0 ? toneFrequency : null,
77
75
  audioStartFrame: Math.max(0, -((_a = sequenceContext === null || sequenceContext === void 0 ? void 0 : sequenceContext.relativeFrom) !== null && _a !== void 0 ? _a : 0)),
78
76
  });
@@ -87,7 +85,6 @@ crossOrigin, ...props }) => {
87
85
  frame,
88
86
  absoluteFrame,
89
87
  playbackRate,
90
- allowAmplificationDuringRender,
91
88
  toneFrequency,
92
89
  sequenceContext === null || sequenceContext === void 0 ? void 0 : sequenceContext.relativeFrom,
93
90
  ]);
@@ -9,11 +9,13 @@ const use_audio_frame_js_1 = require("../audio/use-audio-frame.js");
9
9
  const log_level_context_js_1 = require("../log-level-context.js");
10
10
  const playback_logging_js_1 = require("../playback-logging.js");
11
11
  const prefetch_js_1 = require("../prefetch.js");
12
+ const use_amplification_js_1 = require("../use-amplification.js");
12
13
  const use_media_in_timeline_js_1 = require("../use-media-in-timeline.js");
13
14
  const use_media_playback_js_1 = require("../use-media-playback.js");
14
15
  const use_sync_volume_with_media_tag_js_1 = require("../use-sync-volume-with-media-tag.js");
15
16
  const use_video_config_js_1 = require("../use-video-config.js");
16
17
  const volume_position_state_js_1 = require("../volume-position-state.js");
18
+ const volume_prop_js_1 = require("../volume-prop.js");
17
19
  const emit_video_frame_js_1 = require("./emit-video-frame.js");
18
20
  const video_fragment_js_1 = require("./video-fragment.js");
19
21
  const VideoForDevelopmentRefForwardingFunction = (props, ref) => {
@@ -35,6 +37,11 @@ const VideoForDevelopmentRefForwardingFunction = (props, ref) => {
35
37
  }
36
38
  const [mediaVolume] = (0, volume_position_state_js_1.useMediaVolumeState)();
37
39
  const [mediaMuted] = (0, volume_position_state_js_1.useMediaMutedState)();
40
+ const userPreferredVolume = (0, volume_prop_js_1.evaluateVolume)({
41
+ frame: volumePropFrame,
42
+ volume,
43
+ mediaVolume,
44
+ });
38
45
  (0, use_media_in_timeline_js_1.useMediaInTimeline)({
39
46
  mediaRef: videoRef,
40
47
  volume,
@@ -56,16 +63,22 @@ const VideoForDevelopmentRefForwardingFunction = (props, ref) => {
56
63
  mediaVolume,
57
64
  mediaRef: videoRef,
58
65
  });
66
+ (0, use_amplification_js_1.useAmplification)({
67
+ logLevel,
68
+ mediaRef: videoRef,
69
+ volume: userPreferredVolume,
70
+ });
59
71
  (0, use_media_playback_js_1.useMediaPlayback)({
60
72
  mediaRef: videoRef,
61
73
  src,
62
74
  mediaType: 'video',
63
75
  playbackRate: (_c = props.playbackRate) !== null && _c !== void 0 ? _c : 1,
64
76
  onlyWarnForMediaSeekingError,
65
- acceptableTimeshift: acceptableTimeShiftInSeconds !== null && acceptableTimeShiftInSeconds !== void 0 ? acceptableTimeShiftInSeconds : use_media_playback_js_1.DEFAULT_ACCEPTABLE_TIMESHIFT,
77
+ acceptableTimeshift: acceptableTimeShiftInSeconds !== null && acceptableTimeShiftInSeconds !== void 0 ? acceptableTimeShiftInSeconds : null,
66
78
  isPremounting: Boolean(parentSequence === null || parentSequence === void 0 ? void 0 : parentSequence.premounting),
67
79
  pauseWhenBuffering,
68
80
  onAutoPlayError: onAutoPlayError !== null && onAutoPlayError !== void 0 ? onAutoPlayError : null,
81
+ userPreferredVolume,
69
82
  });
70
83
  const actualFrom = parentSequence ? parentSequence.relativeFrom : 0;
71
84
  const duration = parentSequence
@@ -166,6 +179,6 @@ const VideoForDevelopmentRefForwardingFunction = (props, ref) => {
166
179
  };
167
180
  }, [isSequenceHidden, style]);
168
181
  const crossOriginValue = crossOrigin !== null && crossOrigin !== void 0 ? crossOrigin : (onVideoFrame ? 'anonymous' : undefined);
169
- return ((0, jsx_runtime_1.jsx)("video", { ref: videoRef, muted: muted || mediaMuted, playsInline: true, src: actualSrc, loop: _remotionInternalNativeLoopPassed, style: actualStyle, disableRemotePlayback: true, crossOrigin: crossOriginValue, ...nativeProps }));
182
+ return ((0, jsx_runtime_1.jsx)("video", { ref: videoRef, muted: muted || mediaMuted || isSequenceHidden || userPreferredVolume <= 0, playsInline: true, src: actualSrc, loop: _remotionInternalNativeLoopPassed, style: actualStyle, disableRemotePlayback: true, crossOrigin: crossOriginValue, ...nativeProps }));
170
183
  };
171
184
  exports.VideoForPreview = (0, react_1.forwardRef)(VideoForDevelopmentRefForwardingFunction);
@@ -48,7 +48,6 @@ const VideoForRenderingForwardFunction = ({ onError, volume: volumeProp, allowAm
48
48
  volume: volumeProp,
49
49
  frame: volumePropsFrame,
50
50
  mediaVolume: 1,
51
- allowAmplificationDuringRender: allowAmplificationDuringRender !== null && allowAmplificationDuringRender !== void 0 ? allowAmplificationDuringRender : false,
52
51
  });
53
52
  (0, react_1.useEffect)(() => {
54
53
  var _a;
@@ -72,7 +71,6 @@ const VideoForRenderingForwardFunction = ({ onError, volume: volumeProp, allowAm
72
71
  volume,
73
72
  mediaFrame: frame,
74
73
  playbackRate: playbackRate !== null && playbackRate !== void 0 ? playbackRate : 1,
75
- allowAmplificationDuringRender: allowAmplificationDuringRender !== null && allowAmplificationDuringRender !== void 0 ? allowAmplificationDuringRender : false,
76
74
  toneFrequency: toneFrequency !== null && toneFrequency !== void 0 ? toneFrequency : null,
77
75
  audioStartFrame: Math.max(0, -((_a = sequenceContext === null || sequenceContext === void 0 ? void 0 : sequenceContext.relativeFrom) !== null && _a !== void 0 ? _a : 0)),
78
76
  });
@@ -87,7 +85,6 @@ const VideoForRenderingForwardFunction = ({ onError, volume: volumeProp, allowAm
87
85
  frame,
88
86
  absoluteFrame,
89
87
  playbackRate,
90
- allowAmplificationDuringRender,
91
88
  toneFrequency,
92
89
  sequenceContext === null || sequenceContext === void 0 ? void 0 : sequenceContext.relativeFrom,
93
90
  ]);
@@ -1,7 +1,6 @@
1
1
  export type VolumeProp = number | ((frame: number) => number);
2
- export declare const evaluateVolume: ({ frame, volume, mediaVolume, allowAmplificationDuringRender, }: {
2
+ export declare const evaluateVolume: ({ frame, volume, mediaVolume, }: {
3
3
  frame: number;
4
4
  volume: VolumeProp | undefined;
5
5
  mediaVolume: number;
6
- allowAmplificationDuringRender: boolean;
7
6
  }) => number;
@@ -1,10 +1,9 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.evaluateVolume = void 0;
4
- const evaluateVolume = ({ frame, volume, mediaVolume = 1, allowAmplificationDuringRender, }) => {
5
- const maxVolume = allowAmplificationDuringRender ? Infinity : 1;
4
+ const evaluateVolume = ({ frame, volume, mediaVolume = 1, }) => {
6
5
  if (typeof volume === 'number') {
7
- return Math.min(maxVolume, volume * mediaVolume);
6
+ return volume * mediaVolume;
8
7
  }
9
8
  if (typeof volume === 'undefined') {
10
9
  return Number(mediaVolume);
@@ -19,6 +18,6 @@ const evaluateVolume = ({ frame, volume, mediaVolume = 1, allowAmplificationDuri
19
18
  if (!Number.isFinite(evaluated)) {
20
19
  throw new TypeError(`You passed in a function to the volume prop but it returned a non-finite number for frame ${frame}.`);
21
20
  }
22
- return Math.max(0, Math.min(maxVolume, evaluated));
21
+ return Math.max(0, evaluated);
23
22
  };
24
23
  exports.evaluateVolume = evaluateVolume;
@@ -104,7 +104,7 @@ function truthy(value) {
104
104
  }
105
105
 
106
106
  // src/version.ts
107
- var VERSION = "4.0.277";
107
+ var VERSION = "4.0.279";
108
108
 
109
109
  // src/multiple-versions-warning.ts
110
110
  var checkMultipleRemotionVersions = () => {
@@ -2449,10 +2449,32 @@ import {
2449
2449
  useEffect as useEffect14,
2450
2450
  useImperativeHandle as useImperativeHandle5,
2451
2451
  useMemo as useMemo19,
2452
- useRef as useRef10,
2452
+ useRef as useRef11,
2453
2453
  useState as useState13
2454
2454
  } from "react";
2455
2455
 
2456
+ // src/log-level-context.tsx
2457
+ import { createContext as createContext14 } from "react";
2458
+ import * as React12 from "react";
2459
+ var LogLevelContext = createContext14({
2460
+ logLevel: "info",
2461
+ mountTime: 0
2462
+ });
2463
+ var useLogLevel = () => {
2464
+ const { logLevel } = React12.useContext(LogLevelContext);
2465
+ if (logLevel === null) {
2466
+ throw new Error("useLogLevel must be used within a LogLevelProvider");
2467
+ }
2468
+ return logLevel;
2469
+ };
2470
+ var useMountTime = () => {
2471
+ const { mountTime } = React12.useContext(LogLevelContext);
2472
+ if (mountTime === null) {
2473
+ throw new Error("useMountTime must be used within a LogLevelProvider");
2474
+ }
2475
+ return mountTime;
2476
+ };
2477
+
2456
2478
  // src/random.ts
2457
2479
  function mulberry32(a) {
2458
2480
  let t = a + 1831565813;
@@ -2487,13 +2509,77 @@ var random = (seed, dummy) => {
2487
2509
  throw new Error("random() argument must be a number or a string");
2488
2510
  };
2489
2511
 
2512
+ // src/use-amplification.ts
2513
+ import { useLayoutEffect as useLayoutEffect3, useRef as useRef4 } from "react";
2514
+ var warned = false;
2515
+ var warnOnce = (logLevel) => {
2516
+ if (warned) {
2517
+ return;
2518
+ }
2519
+ warned = true;
2520
+ Log.warn(logLevel, "AudioContext is not supported in this browser");
2521
+ };
2522
+ var getShouldAmplify = (volume) => {
2523
+ return volume > 1;
2524
+ };
2525
+ var useAmplification = ({
2526
+ mediaRef,
2527
+ volume,
2528
+ logLevel
2529
+ }) => {
2530
+ const shouldAmplify = getShouldAmplify(volume);
2531
+ const audioStuffRef = useRef4(null);
2532
+ const currentVolumeRef = useRef4(volume);
2533
+ currentVolumeRef.current = volume;
2534
+ useLayoutEffect3(() => {
2535
+ if (!shouldAmplify) {
2536
+ return;
2537
+ }
2538
+ if (!AudioContext) {
2539
+ warnOnce(logLevel);
2540
+ return;
2541
+ }
2542
+ if (!mediaRef.current) {
2543
+ return;
2544
+ }
2545
+ if (audioStuffRef.current) {
2546
+ return;
2547
+ }
2548
+ const audioContext = new AudioContext({
2549
+ latencyHint: "interactive"
2550
+ });
2551
+ const source = new MediaElementAudioSourceNode(audioContext, {
2552
+ mediaElement: mediaRef.current
2553
+ });
2554
+ const gainNode = new GainNode(audioContext, {
2555
+ gain: Math.max(currentVolumeRef.current, 1)
2556
+ });
2557
+ audioStuffRef.current = {
2558
+ gainNode,
2559
+ source,
2560
+ audioContext
2561
+ };
2562
+ source.connect(gainNode);
2563
+ gainNode.connect(audioContext.destination);
2564
+ Log.trace(logLevel, `Starting to amplify ${mediaRef.current?.src}. Gain = ${currentVolumeRef.current}`);
2565
+ }, [logLevel, mediaRef, shouldAmplify]);
2566
+ if (audioStuffRef.current) {
2567
+ const valueToSet = Math.max(volume, 1);
2568
+ if (audioStuffRef.current.gainNode.gain.value !== valueToSet) {
2569
+ audioStuffRef.current.gainNode.gain.value = valueToSet;
2570
+ Log.trace(logLevel, `Setting gain to ${valueToSet} for ${mediaRef.current?.src}`);
2571
+ }
2572
+ }
2573
+ return audioStuffRef;
2574
+ };
2575
+
2490
2576
  // src/use-media-in-timeline.ts
2491
2577
  import { useContext as useContext15, useEffect as useEffect7, useMemo as useMemo13, useState as useState9 } from "react";
2492
2578
 
2493
2579
  // src/audio/use-audio-frame.ts
2494
- import { useContext as useContext13 } from "react";
2580
+ import { useContext as useContext14 } from "react";
2495
2581
  var useMediaStartsAt = () => {
2496
- const parentSequence = useContext13(SequenceContext);
2582
+ const parentSequence = useContext14(SequenceContext);
2497
2583
  const startsAt = Math.min(0, parentSequence?.relativeFrom ?? 0);
2498
2584
  return startsAt;
2499
2585
  };
@@ -2516,28 +2602,6 @@ var getAssetDisplayName = (filename) => {
2516
2602
  return splitted[splitted.length - 1];
2517
2603
  };
2518
2604
 
2519
- // src/log-level-context.tsx
2520
- import { createContext as createContext14 } from "react";
2521
- import * as React12 from "react";
2522
- var LogLevelContext = createContext14({
2523
- logLevel: "info",
2524
- mountTime: 0
2525
- });
2526
- var useLogLevel = () => {
2527
- const { logLevel } = React12.useContext(LogLevelContext);
2528
- if (logLevel === null) {
2529
- throw new Error("useLogLevel must be used within a LogLevelProvider");
2530
- }
2531
- return logLevel;
2532
- };
2533
- var useMountTime = () => {
2534
- const { mountTime } = React12.useContext(LogLevelContext);
2535
- if (mountTime === null) {
2536
- throw new Error("useMountTime must be used within a LogLevelProvider");
2537
- }
2538
- return mountTime;
2539
- };
2540
-
2541
2605
  // src/play-and-handle-not-allowed-error.ts
2542
2606
  var playAndHandleNotAllowedError = ({
2543
2607
  mediaRef,
@@ -2603,12 +2667,10 @@ var playAndHandleNotAllowedError = ({
2603
2667
  var evaluateVolume = ({
2604
2668
  frame,
2605
2669
  volume,
2606
- mediaVolume = 1,
2607
- allowAmplificationDuringRender
2670
+ mediaVolume = 1
2608
2671
  }) => {
2609
- const maxVolume = allowAmplificationDuringRender ? Infinity : 1;
2610
2672
  if (typeof volume === "number") {
2611
- return Math.min(maxVolume, volume * mediaVolume);
2673
+ return volume * mediaVolume;
2612
2674
  }
2613
2675
  if (typeof volume === "undefined") {
2614
2676
  return Number(mediaVolume);
@@ -2623,12 +2685,12 @@ var evaluateVolume = ({
2623
2685
  if (!Number.isFinite(evaluated)) {
2624
2686
  throw new TypeError(`You passed in a function to the volume prop but it returned a non-finite number for frame ${frame}.`);
2625
2687
  }
2626
- return Math.max(0, Math.min(maxVolume, evaluated));
2688
+ return Math.max(0, evaluated);
2627
2689
  };
2628
2690
 
2629
2691
  // src/use-media-in-timeline.ts
2630
2692
  var didWarn = {};
2631
- var warnOnce = (message) => {
2693
+ var warnOnce2 = (message) => {
2632
2694
  if (didWarn[message]) {
2633
2695
  return;
2634
2696
  }
@@ -2671,14 +2733,13 @@ var useMediaInTimeline = ({
2671
2733
  return evaluateVolume({
2672
2734
  frame: i + startsAt,
2673
2735
  volume,
2674
- mediaVolume,
2675
- allowAmplificationDuringRender: false
2736
+ mediaVolume
2676
2737
  });
2677
2738
  }).join(",");
2678
2739
  }, [duration, startsAt, volume, mediaVolume]);
2679
2740
  useEffect7(() => {
2680
2741
  if (typeof volume === "number" && volume !== initialVolume) {
2681
- warnOnce(`Remotion: The ${mediaType} with src ${src} has changed it's volume. Prefer the callback syntax for setting volume to get better timeline display: https://www.remotion.dev/docs/using-audio/#controlling-volume`);
2742
+ warnOnce2(`Remotion: The ${mediaType} with src ${src} has changed it's volume. Prefer the callback syntax for setting volume to get better timeline display: https://www.remotion.dev/docs/using-audio/#controlling-volume`);
2682
2743
  }
2683
2744
  }, [initialVolume, mediaType, src, volume]);
2684
2745
  useEffect7(() => {
@@ -2776,10 +2837,10 @@ var useMediaInTimeline = ({
2776
2837
  };
2777
2838
 
2778
2839
  // src/use-media-playback.ts
2779
- import { useCallback as useCallback8, useContext as useContext18, useEffect as useEffect11, useRef as useRef8 } from "react";
2840
+ import { useCallback as useCallback8, useContext as useContext18, useEffect as useEffect11, useRef as useRef9 } from "react";
2780
2841
 
2781
2842
  // src/buffer-until-first-frame.ts
2782
- import { useCallback as useCallback7, useMemo as useMemo16, useRef as useRef5 } from "react";
2843
+ import { useCallback as useCallback7, useMemo as useMemo16, useRef as useRef6 } from "react";
2783
2844
 
2784
2845
  // src/use-buffer-state.ts
2785
2846
  import { useContext as useContext17, useMemo as useMemo15 } from "react";
@@ -2790,7 +2851,7 @@ import React13, {
2790
2851
  useContext as useContext16,
2791
2852
  useEffect as useEffect8,
2792
2853
  useMemo as useMemo14,
2793
- useRef as useRef4,
2854
+ useRef as useRef5,
2794
2855
  useState as useState10
2795
2856
  } from "react";
2796
2857
  import { jsx as jsx15 } from "react/jsx-runtime";
@@ -2798,7 +2859,7 @@ var useBufferManager = (logLevel, mountTime) => {
2798
2859
  const [blocks, setBlocks] = useState10([]);
2799
2860
  const [onBufferingCallbacks, setOnBufferingCallbacks] = useState10([]);
2800
2861
  const [onResumeCallbacks, setOnResumeCallbacks] = useState10([]);
2801
- const buffering = useRef4(false);
2862
+ const buffering = useRef5(false);
2802
2863
  const addBlock = useCallback6((block) => {
2803
2864
  setBlocks((b) => [...b, block]);
2804
2865
  return {
@@ -2917,7 +2978,7 @@ var useBufferUntilFirstFrame = ({
2917
2978
  logLevel,
2918
2979
  mountTime
2919
2980
  }) => {
2920
- const bufferingRef = useRef5(false);
2981
+ const bufferingRef = useRef6(false);
2921
2982
  const { delayPlayback } = useBufferState();
2922
2983
  const bufferUntilFirstFrame = useCallback7((requestedTime) => {
2923
2984
  if (mediaType !== "video") {
@@ -2993,7 +3054,7 @@ var useBufferUntilFirstFrame = ({
2993
3054
  };
2994
3055
 
2995
3056
  // src/video/video-fragment.ts
2996
- import { useRef as useRef6 } from "react";
3057
+ import { useRef as useRef7 } from "react";
2997
3058
  var toSeconds = (time, fps) => {
2998
3059
  return Math.round(time / fps * 100) / 100;
2999
3060
  };
@@ -3070,9 +3131,9 @@ var useAppendVideoFragment = ({
3070
3131
  duration: initialDuration,
3071
3132
  fps
3072
3133
  }) => {
3073
- const actualFromRef = useRef6(initialActualFrom);
3074
- const actualDuration = useRef6(initialDuration);
3075
- const actualSrc = useRef6(initialActualSrc);
3134
+ const actualFromRef = useRef7(initialActualFrom);
3135
+ const actualDuration = useRef7(initialDuration);
3136
+ const actualSrc = useRef7(initialActualSrc);
3076
3137
  if (!isSubsetOfDuration({
3077
3138
  prevStartFrom: actualFromRef.current,
3078
3139
  newStartFrom: initialActualFrom,
@@ -3238,14 +3299,14 @@ var useMediaBuffering = ({
3238
3299
  };
3239
3300
 
3240
3301
  // src/use-request-video-callback-time.ts
3241
- import { useEffect as useEffect10, useRef as useRef7 } from "react";
3302
+ import { useEffect as useEffect10, useRef as useRef8 } from "react";
3242
3303
  var useRequestVideoCallbackTime = ({
3243
3304
  mediaRef,
3244
3305
  mediaType,
3245
3306
  lastSeek,
3246
3307
  onVariableFpsVideoDetected
3247
3308
  }) => {
3248
- const currentTime = useRef7(null);
3309
+ const currentTime = useRef8(null);
3249
3310
  useEffect10(() => {
3250
3311
  const { current } = mediaRef;
3251
3312
  if (current) {
@@ -3458,7 +3519,6 @@ var warnAboutNonSeekableMedia = (ref, type) => {
3458
3519
  };
3459
3520
 
3460
3521
  // src/use-media-playback.ts
3461
- var DEFAULT_ACCEPTABLE_TIMESHIFT = 0.45;
3462
3522
  var useMediaPlayback = ({
3463
3523
  mediaRef,
3464
3524
  src,
@@ -3468,7 +3528,8 @@ var useMediaPlayback = ({
3468
3528
  acceptableTimeshift,
3469
3529
  pauseWhenBuffering,
3470
3530
  isPremounting,
3471
- onAutoPlayError
3531
+ onAutoPlayError,
3532
+ userPreferredVolume
3472
3533
  }) => {
3473
3534
  const { playbackRate: globalPlaybackRate } = useContext18(TimelineContext);
3474
3535
  const frame = useCurrentFrame();
@@ -3477,14 +3538,14 @@ var useMediaPlayback = ({
3477
3538
  const buffering = useContext18(BufferingContextReact);
3478
3539
  const { fps } = useVideoConfig();
3479
3540
  const mediaStartsAt = useMediaStartsAt();
3480
- const lastSeekDueToShift = useRef8(null);
3481
- const lastSeek = useRef8(null);
3541
+ const lastSeekDueToShift = useRef9(null);
3542
+ const lastSeek = useRef9(null);
3482
3543
  const logLevel = useLogLevel();
3483
3544
  const mountTime = useMountTime();
3484
3545
  if (!buffering) {
3485
3546
  throw new Error("useMediaPlayback must be used inside a <BufferingContext>");
3486
3547
  }
3487
- const isVariableFpsVideoMap = useRef8({});
3548
+ const isVariableFpsVideoMap = useRef9({});
3488
3549
  const onVariableFpsVideoDetected = useCallback8(() => {
3489
3550
  if (!src) {
3490
3551
  return;
@@ -3521,10 +3582,13 @@ var useMediaPlayback = ({
3521
3582
  });
3522
3583
  const playbackRate = localPlaybackRate * globalPlaybackRate;
3523
3584
  const acceptableTimeShiftButLessThanDuration = (() => {
3585
+ const DEFAULT_ACCEPTABLE_TIMESHIFT_WITH_NORMAL_PLAYBACK = 0.45;
3586
+ const DEFAULT_ACCEPTABLE_TIMESHIFT_WITH_AMPLIFICATION = DEFAULT_ACCEPTABLE_TIMESHIFT_WITH_NORMAL_PLAYBACK + 0.2;
3587
+ const defaultAcceptableTimeshift = getShouldAmplify(userPreferredVolume) ? DEFAULT_ACCEPTABLE_TIMESHIFT_WITH_AMPLIFICATION : DEFAULT_ACCEPTABLE_TIMESHIFT_WITH_NORMAL_PLAYBACK;
3524
3588
  if (mediaRef.current?.duration) {
3525
- return Math.min(mediaRef.current.duration, acceptableTimeshift ?? DEFAULT_ACCEPTABLE_TIMESHIFT);
3589
+ return Math.min(mediaRef.current.duration, acceptableTimeshift ?? defaultAcceptableTimeshift);
3526
3590
  }
3527
- return acceptableTimeshift;
3591
+ return acceptableTimeshift ?? defaultAcceptableTimeshift;
3528
3592
  })();
3529
3593
  const isPlayerBuffering = useIsPlayerBuffering(buffering);
3530
3594
  useEffect11(() => {
@@ -3611,7 +3675,7 @@ var useMediaPlayback = ({
3611
3675
  }
3612
3676
  return;
3613
3677
  }
3614
- const seekThreshold = playing ? 0.15 : 0.00001;
3678
+ const seekThreshold = playing ? 0.15 : 0.01;
3615
3679
  const makesSenseToSeek = Math.abs(mediaRef.current.currentTime - shouldBeTime) > seekThreshold;
3616
3680
  const isMediaTagBufferingOrStalled = isMediaTagBuffering || isBuffering();
3617
3681
  const isSomethingElseBuffering = buffering.buffering.current && !isMediaTagBufferingOrStalled;
@@ -3701,11 +3765,10 @@ var useSyncVolumeWithMediaTag = ({
3701
3765
  const userPreferredVolume = evaluateVolume({
3702
3766
  frame: volumePropFrame,
3703
3767
  volume,
3704
- mediaVolume,
3705
- allowAmplificationDuringRender: false
3768
+ mediaVolume
3706
3769
  });
3707
3770
  if (!isApproximatelyTheSame(userPreferredVolume, mediaRef.current.volume)) {
3708
- mediaRef.current.volume = userPreferredVolume;
3771
+ mediaRef.current.volume = Math.min(userPreferredVolume, 1);
3709
3772
  }
3710
3773
  }, [mediaRef, mediaVolume, volume, volumePropFrame]);
3711
3774
  useEffect12(() => {
@@ -3763,7 +3826,7 @@ import React14, {
3763
3826
  useContext as useContext20,
3764
3827
  useEffect as useEffect13,
3765
3828
  useMemo as useMemo18,
3766
- useRef as useRef9,
3829
+ useRef as useRef10,
3767
3830
  useState as useState12
3768
3831
  } from "react";
3769
3832
  import { jsx as jsx16, jsxs } from "react/jsx-runtime";
@@ -3795,7 +3858,7 @@ var didPropChange = (key, newProp, prevProp) => {
3795
3858
  };
3796
3859
  var SharedAudioContext = createContext16(null);
3797
3860
  var SharedAudioContextProvider = ({ children, numberOfAudioTags, component }) => {
3798
- const audios = useRef9([]);
3861
+ const audios = useRef10([]);
3799
3862
  const [initialNumberOfAudioTags] = useState12(numberOfAudioTags);
3800
3863
  if (numberOfAudioTags !== initialNumberOfAudioTags) {
3801
3864
  throw new Error("The number of shared audio tags has changed dynamically. Once you have set this property, you cannot change it afterwards.");
@@ -3805,7 +3868,7 @@ var SharedAudioContextProvider = ({ children, numberOfAudioTags, component }) =>
3805
3868
  return { id: Math.random(), ref: createRef2() };
3806
3869
  });
3807
3870
  }, [numberOfAudioTags]);
3808
- const takenAudios = useRef9(new Array(numberOfAudioTags).fill(false));
3871
+ const takenAudios = useRef10(new Array(numberOfAudioTags).fill(false));
3809
3872
  const rerenderAudios = useCallback10(() => {
3810
3873
  refs.forEach(({ ref, id }) => {
3811
3874
  const data = audios.current?.find((a) => a.id === id);
@@ -3977,6 +4040,7 @@ var AudioForDevelopmentForwardRefFunction = (props, ref) => {
3977
4040
  if (props.shouldPreMountAudioTags !== initialShouldPreMountAudioElements) {
3978
4041
  throw new Error("Cannot change the behavior for pre-mounting audio tags dynamically.");
3979
4042
  }
4043
+ const logLevel = useLogLevel();
3980
4044
  const {
3981
4045
  volume,
3982
4046
  muted,
@@ -4010,8 +4074,7 @@ var AudioForDevelopmentForwardRefFunction = (props, ref) => {
4010
4074
  const userPreferredVolume = evaluateVolume({
4011
4075
  frame: volumePropFrame,
4012
4076
  volume,
4013
- mediaVolume,
4014
- allowAmplificationDuringRender: false
4077
+ mediaVolume
4015
4078
  });
4016
4079
  const propsToPass = useMemo19(() => {
4017
4080
  return {
@@ -4059,21 +4122,27 @@ var AudioForDevelopmentForwardRefFunction = (props, ref) => {
4059
4122
  onAutoPlayError: null,
4060
4123
  isPremounting: Boolean(sequenceContext?.premounting)
4061
4124
  });
4125
+ useAmplification({
4126
+ logLevel,
4127
+ mediaRef: audioRef,
4128
+ volume: userPreferredVolume
4129
+ });
4062
4130
  useMediaPlayback({
4063
4131
  mediaRef: audioRef,
4064
4132
  src,
4065
4133
  mediaType: "audio",
4066
4134
  playbackRate: playbackRate ?? 1,
4067
4135
  onlyWarnForMediaSeekingError: false,
4068
- acceptableTimeshift: acceptableTimeShiftInSeconds ?? DEFAULT_ACCEPTABLE_TIMESHIFT,
4136
+ acceptableTimeshift: acceptableTimeShiftInSeconds ?? null,
4069
4137
  isPremounting: Boolean(sequenceContext?.premounting),
4070
4138
  pauseWhenBuffering,
4071
- onAutoPlayError: null
4139
+ onAutoPlayError: null,
4140
+ userPreferredVolume
4072
4141
  });
4073
4142
  useImperativeHandle5(ref, () => {
4074
4143
  return audioRef.current;
4075
4144
  }, [audioRef]);
4076
- const currentOnDurationCallback = useRef10(onDuration);
4145
+ const currentOnDurationCallback = useRef11(onDuration);
4077
4146
  currentOnDurationCallback.current = onDuration;
4078
4147
  useEffect14(() => {
4079
4148
  const { current } = audioRef;
@@ -4109,13 +4178,13 @@ import {
4109
4178
  useContext as useContext22,
4110
4179
  useEffect as useEffect15,
4111
4180
  useImperativeHandle as useImperativeHandle6,
4112
- useLayoutEffect as useLayoutEffect3,
4181
+ useLayoutEffect as useLayoutEffect4,
4113
4182
  useMemo as useMemo20,
4114
- useRef as useRef11
4183
+ useRef as useRef12
4115
4184
  } from "react";
4116
4185
  import { jsx as jsx18 } from "react/jsx-runtime";
4117
4186
  var AudioForRenderingRefForwardingFunction = (props, ref) => {
4118
- const audioRef = useRef11(null);
4187
+ const audioRef = useRef12(null);
4119
4188
  const {
4120
4189
  volume: volumeProp,
4121
4190
  playbackRate,
@@ -4147,8 +4216,7 @@ var AudioForRenderingRefForwardingFunction = (props, ref) => {
4147
4216
  const volume = evaluateVolume({
4148
4217
  volume: volumeProp,
4149
4218
  frame: volumePropFrame,
4150
- mediaVolume: 1,
4151
- allowAmplificationDuringRender: allowAmplificationDuringRender ?? false
4219
+ mediaVolume: 1
4152
4220
  });
4153
4221
  useImperativeHandle6(ref, () => {
4154
4222
  return audioRef.current;
@@ -4174,7 +4242,6 @@ var AudioForRenderingRefForwardingFunction = (props, ref) => {
4174
4242
  volume,
4175
4243
  mediaFrame: frame,
4176
4244
  playbackRate: props.playbackRate ?? 1,
4177
- allowAmplificationDuringRender: allowAmplificationDuringRender ?? false,
4178
4245
  toneFrequency: toneFrequency ?? null,
4179
4246
  audioStartFrame: Math.max(0, -(sequenceContext?.relativeFrom ?? 0))
4180
4247
  });
@@ -4191,13 +4258,12 @@ var AudioForRenderingRefForwardingFunction = (props, ref) => {
4191
4258
  frame,
4192
4259
  playbackRate,
4193
4260
  props.playbackRate,
4194
- allowAmplificationDuringRender,
4195
4261
  toneFrequency,
4196
4262
  sequenceContext?.relativeFrom
4197
4263
  ]);
4198
4264
  const { src } = props;
4199
4265
  const needsToRenderAudioTag = ref || _remotionInternalNeedsDurationCalculation;
4200
- useLayoutEffect3(() => {
4266
+ useLayoutEffect4(() => {
4201
4267
  if (window.process?.env?.NODE_ENV === "test") {
4202
4268
  return;
4203
4269
  }
@@ -4905,8 +4971,8 @@ import {
4905
4971
  useCallback as useCallback13,
4906
4972
  useContext as useContext26,
4907
4973
  useImperativeHandle as useImperativeHandle7,
4908
- useLayoutEffect as useLayoutEffect4,
4909
- useRef as useRef12
4974
+ useLayoutEffect as useLayoutEffect5,
4975
+ useRef as useRef13
4910
4976
  } from "react";
4911
4977
  import { jsx as jsx24 } from "react/jsx-runtime";
4912
4978
  function exponentialBackoff(errorCount) {
@@ -4922,8 +4988,8 @@ var ImgRefForwarding = ({
4922
4988
  onImageFrame,
4923
4989
  ...props2
4924
4990
  }, ref) => {
4925
- const imageRef = useRef12(null);
4926
- const errors = useRef12({});
4991
+ const imageRef = useRef13(null);
4992
+ const errors = useRef13({});
4927
4993
  const { delayPlayback } = useBufferState();
4928
4994
  const sequenceContext = useContext26(SequenceContext);
4929
4995
  if (!src) {
@@ -4969,7 +5035,7 @@ var ImgRefForwarding = ({
4969
5035
  }, [maxRetries, onError, retryIn]);
4970
5036
  if (typeof window !== "undefined") {
4971
5037
  const isPremounting = Boolean(sequenceContext?.premounting);
4972
- useLayoutEffect4(() => {
5038
+ useLayoutEffect5(() => {
4973
5039
  if (window.process?.env?.NODE_ENV === "test") {
4974
5040
  if (imageRef.current) {
4975
5041
  imageRef.current.src = actualSrc;
@@ -5048,7 +5114,7 @@ import React22, {
5048
5114
  useCallback as useCallback14,
5049
5115
  useImperativeHandle as useImperativeHandle8,
5050
5116
  useMemo as useMemo23,
5051
- useRef as useRef13,
5117
+ useRef as useRef14,
5052
5118
  useState as useState15
5053
5119
  } from "react";
5054
5120
  import { jsx as jsx25 } from "react/jsx-runtime";
@@ -5060,7 +5126,7 @@ var CompositionManagerProvider = ({
5060
5126
  currentCompositionMetadata
5061
5127
  }) => {
5062
5128
  const [compositions, setCompositions] = useState15([]);
5063
- const currentcompositionsRef = useRef13(compositions);
5129
+ const currentcompositionsRef = useRef14(compositions);
5064
5130
  const [folders, setFolders] = useState15([]);
5065
5131
  const [canvasContent, setCanvasContent] = useState15(null);
5066
5132
  const updateCompositions = useCallback14((updateComps) => {
@@ -5256,9 +5322,9 @@ var waitForRoot = (fn) => {
5256
5322
  // src/RemotionRoot.tsx
5257
5323
  import {
5258
5324
  useEffect as useEffect18,
5259
- useLayoutEffect as useLayoutEffect5,
5325
+ useLayoutEffect as useLayoutEffect6,
5260
5326
  useMemo as useMemo24,
5261
- useRef as useRef14,
5327
+ useRef as useRef15,
5262
5328
  useState as useState16
5263
5329
  } from "react";
5264
5330
  import { jsx as jsx26 } from "react/jsx-runtime";
@@ -5272,12 +5338,12 @@ var RemotionRoot = ({
5272
5338
  const [remotionRootId] = useState16(() => String(random(null)));
5273
5339
  const [frame, setFrame] = useState16(() => getInitialFrameState());
5274
5340
  const [playing, setPlaying] = useState16(false);
5275
- const imperativePlaying = useRef14(false);
5341
+ const imperativePlaying = useRef15(false);
5276
5342
  const [fastRefreshes, setFastRefreshes] = useState16(0);
5277
5343
  const [playbackRate, setPlaybackRate] = useState16(1);
5278
- const audioAndVideoTags = useRef14([]);
5344
+ const audioAndVideoTags = useRef15([]);
5279
5345
  if (typeof window !== "undefined") {
5280
- useLayoutEffect5(() => {
5346
+ useLayoutEffect6(() => {
5281
5347
  window.remotion_setFrame = (f, composition, attempt) => {
5282
5348
  window.remotion_attempt = attempt;
5283
5349
  const id = delayRender(`Setting the current frame to ${f}`);
@@ -6388,7 +6454,7 @@ var problematicCharacters = {
6388
6454
  "%3B": ";"
6389
6455
  };
6390
6456
  var didWarn2 = {};
6391
- var warnOnce2 = (message) => {
6457
+ var warnOnce3 = (message) => {
6392
6458
  if (didWarn2[message]) {
6393
6459
  return;
6394
6460
  }
@@ -6447,7 +6513,7 @@ var staticFile = (path) => {
6447
6513
  }
6448
6514
  const includesHex = includesHexOfUnsafeChar(path);
6449
6515
  if (includesHex.containsHex) {
6450
- warnOnce2(`WARNING: You seem to pass an already encoded path (path contains ${includesHex.hexCode}). Since Remotion 4.0, the encoding is done by staticFile() itself. You may want to remove a encodeURIComponent() wrapping.`);
6516
+ warnOnce3(`WARNING: You seem to pass an already encoded path (path contains ${includesHex.hexCode}). Since Remotion 4.0, the encoding is done by staticFile() itself. You may want to remove a encodeURIComponent() wrapping.`);
6451
6517
  }
6452
6518
  const preprocessed = encodeBySplitting(path);
6453
6519
  const preparsed = inner(preprocessed);
@@ -6474,7 +6540,7 @@ import {
6474
6540
  useCallback as useCallback15,
6475
6541
  useContext as useContext27,
6476
6542
  useEffect as useEffect19,
6477
- useLayoutEffect as useLayoutEffect6,
6543
+ useLayoutEffect as useLayoutEffect7,
6478
6544
  useMemo as useMemo27,
6479
6545
  useState as useState17
6480
6546
  } from "react";
@@ -6519,8 +6585,7 @@ var OffthreadVideoForRendering = ({
6519
6585
  const volume = evaluateVolume({
6520
6586
  volume: volumeProp,
6521
6587
  frame: volumePropsFrame,
6522
- mediaVolume: 1,
6523
- allowAmplificationDuringRender: allowAmplificationDuringRender ?? false
6588
+ mediaVolume: 1
6524
6589
  });
6525
6590
  useEffect19(() => {
6526
6591
  if (!src) {
@@ -6543,7 +6608,6 @@ var OffthreadVideoForRendering = ({
6543
6608
  volume,
6544
6609
  mediaFrame: frame,
6545
6610
  playbackRate: playbackRate ?? 1,
6546
- allowAmplificationDuringRender: allowAmplificationDuringRender ?? false,
6547
6611
  toneFrequency: toneFrequency ?? null,
6548
6612
  audioStartFrame: Math.max(0, -(sequenceContext?.relativeFrom ?? 0))
6549
6613
  });
@@ -6558,7 +6622,6 @@ var OffthreadVideoForRendering = ({
6558
6622
  frame,
6559
6623
  absoluteFrame,
6560
6624
  playbackRate,
6561
- allowAmplificationDuringRender,
6562
6625
  toneFrequency,
6563
6626
  sequenceContext?.relativeFrom
6564
6627
  ]);
@@ -6578,7 +6641,7 @@ var OffthreadVideoForRendering = ({
6578
6641
  });
6579
6642
  }, [toneMapped, currentTime, src, transparent]);
6580
6643
  const [imageSrc, setImageSrc] = useState17(null);
6581
- useLayoutEffect6(() => {
6644
+ useLayoutEffect7(() => {
6582
6645
  if (!window.remotion_videoEnabled) {
6583
6646
  return;
6584
6647
  }
@@ -6684,7 +6747,7 @@ import {
6684
6747
  useEffect as useEffect21,
6685
6748
  useImperativeHandle as useImperativeHandle9,
6686
6749
  useMemo as useMemo28,
6687
- useRef as useRef15,
6750
+ useRef as useRef16,
6688
6751
  useState as useState18
6689
6752
  } from "react";
6690
6753
 
@@ -6720,7 +6783,7 @@ var useEmitVideoFrame = ({
6720
6783
  // src/video/VideoForPreview.tsx
6721
6784
  import { jsx as jsx31 } from "react/jsx-runtime";
6722
6785
  var VideoForDevelopmentRefForwardingFunction = (props2, ref) => {
6723
- const videoRef = useRef15(null);
6786
+ const videoRef = useRef16(null);
6724
6787
  const {
6725
6788
  volume,
6726
6789
  muted,
@@ -6757,6 +6820,11 @@ var VideoForDevelopmentRefForwardingFunction = (props2, ref) => {
6757
6820
  }
6758
6821
  const [mediaVolume] = useMediaVolumeState();
6759
6822
  const [mediaMuted] = useMediaMutedState();
6823
+ const userPreferredVolume = evaluateVolume({
6824
+ frame: volumePropFrame,
6825
+ volume,
6826
+ mediaVolume
6827
+ });
6760
6828
  useMediaInTimeline({
6761
6829
  mediaRef: videoRef,
6762
6830
  volume,
@@ -6778,16 +6846,22 @@ var VideoForDevelopmentRefForwardingFunction = (props2, ref) => {
6778
6846
  mediaVolume,
6779
6847
  mediaRef: videoRef
6780
6848
  });
6849
+ useAmplification({
6850
+ logLevel,
6851
+ mediaRef: videoRef,
6852
+ volume: userPreferredVolume
6853
+ });
6781
6854
  useMediaPlayback({
6782
6855
  mediaRef: videoRef,
6783
6856
  src,
6784
6857
  mediaType: "video",
6785
6858
  playbackRate: props2.playbackRate ?? 1,
6786
6859
  onlyWarnForMediaSeekingError,
6787
- acceptableTimeshift: acceptableTimeShiftInSeconds ?? DEFAULT_ACCEPTABLE_TIMESHIFT,
6860
+ acceptableTimeshift: acceptableTimeShiftInSeconds ?? null,
6788
6861
  isPremounting: Boolean(parentSequence?.premounting),
6789
6862
  pauseWhenBuffering,
6790
- onAutoPlayError: onAutoPlayError ?? null
6863
+ onAutoPlayError: onAutoPlayError ?? null,
6864
+ userPreferredVolume
6791
6865
  });
6792
6866
  const actualFrom = parentSequence ? parentSequence.relativeFrom : 0;
6793
6867
  const duration = parentSequence ? Math.min(parentSequence.durationInFrames, durationInFrames) : durationInFrames;
@@ -6834,7 +6908,7 @@ var VideoForDevelopmentRefForwardingFunction = (props2, ref) => {
6834
6908
  current.removeEventListener("error", errorHandler);
6835
6909
  };
6836
6910
  }, [onError, src]);
6837
- const currentOnDurationCallback = useRef15(onDuration);
6911
+ const currentOnDurationCallback = useRef16(onDuration);
6838
6912
  currentOnDurationCallback.current = onDuration;
6839
6913
  useEmitVideoFrame({ ref: videoRef, onVideoFrame });
6840
6914
  useEffect21(() => {
@@ -6874,7 +6948,7 @@ var VideoForDevelopmentRefForwardingFunction = (props2, ref) => {
6874
6948
  const crossOriginValue = crossOrigin ?? (onVideoFrame ? "anonymous" : undefined);
6875
6949
  return /* @__PURE__ */ jsx31("video", {
6876
6950
  ref: videoRef,
6877
- muted: muted || mediaMuted,
6951
+ muted: muted || mediaMuted || isSequenceHidden || userPreferredVolume <= 0,
6878
6952
  playsInline: true,
6879
6953
  src: actualSrc,
6880
6954
  loop: _remotionInternalNativeLoopPassed,
@@ -6962,9 +7036,9 @@ import {
6962
7036
  useContext as useContext29,
6963
7037
  useEffect as useEffect22,
6964
7038
  useImperativeHandle as useImperativeHandle10,
6965
- useLayoutEffect as useLayoutEffect7,
7039
+ useLayoutEffect as useLayoutEffect8,
6966
7040
  useMemo as useMemo29,
6967
- useRef as useRef16
7041
+ useRef as useRef17
6968
7042
  } from "react";
6969
7043
 
6970
7044
  // src/video/seek-until-right.ts
@@ -7113,7 +7187,7 @@ var VideoForRenderingForwardFunction = ({
7113
7187
  const frame = useCurrentFrame();
7114
7188
  const volumePropsFrame = useFrameForVolumeProp(loopVolumeCurveBehavior ?? "repeat");
7115
7189
  const videoConfig = useUnsafeVideoConfig();
7116
- const videoRef = useRef16(null);
7190
+ const videoRef = useRef17(null);
7117
7191
  const sequenceContext = useContext29(SequenceContext);
7118
7192
  const mediaStartsAt = useMediaStartsAt();
7119
7193
  const environment = getRemotionEnvironment();
@@ -7132,8 +7206,7 @@ var VideoForRenderingForwardFunction = ({
7132
7206
  const volume = evaluateVolume({
7133
7207
  volume: volumeProp,
7134
7208
  frame: volumePropsFrame,
7135
- mediaVolume: 1,
7136
- allowAmplificationDuringRender: allowAmplificationDuringRender ?? false
7209
+ mediaVolume: 1
7137
7210
  });
7138
7211
  useEffect22(() => {
7139
7212
  if (!props2.src) {
@@ -7156,7 +7229,6 @@ var VideoForRenderingForwardFunction = ({
7156
7229
  volume,
7157
7230
  mediaFrame: frame,
7158
7231
  playbackRate: playbackRate ?? 1,
7159
- allowAmplificationDuringRender: allowAmplificationDuringRender ?? false,
7160
7232
  toneFrequency: toneFrequency ?? null,
7161
7233
  audioStartFrame: Math.max(0, -(sequenceContext?.relativeFrom ?? 0))
7162
7234
  });
@@ -7171,7 +7243,6 @@ var VideoForRenderingForwardFunction = ({
7171
7243
  frame,
7172
7244
  absoluteFrame,
7173
7245
  playbackRate,
7174
- allowAmplificationDuringRender,
7175
7246
  toneFrequency,
7176
7247
  sequenceContext?.relativeFrom
7177
7248
  ]);
@@ -7260,7 +7331,7 @@ var VideoForRenderingForwardFunction = ({
7260
7331
  ]);
7261
7332
  const { src } = props2;
7262
7333
  if (environment.isRendering) {
7263
- useLayoutEffect7(() => {
7334
+ useLayoutEffect8(() => {
7264
7335
  if (window.process?.env?.NODE_ENV === "test") {
7265
7336
  return;
7266
7337
  }
@@ -1,5 +1,5 @@
1
1
  // src/version.ts
2
- var VERSION = "4.0.277";
2
+ var VERSION = "4.0.279";
3
3
  export {
4
4
  VERSION
5
5
  };
package/package.json CHANGED
@@ -3,7 +3,7 @@
3
3
  "url": "https://github.com/remotion-dev/remotion/tree/main/packages/core"
4
4
  },
5
5
  "name": "remotion",
6
- "version": "4.0.277",
6
+ "version": "4.0.279",
7
7
  "description": "Make videos programmatically",
8
8
  "main": "dist/cjs/index.js",
9
9
  "types": "dist/cjs/index.d.ts",
@@ -28,7 +28,7 @@
28
28
  "webpack": "5.96.1",
29
29
  "zod": "3.22.3",
30
30
  "eslint": "9.19.0",
31
- "@remotion/eslint-config-internal": "4.0.277"
31
+ "@remotion/eslint-config-internal": "4.0.279"
32
32
  },
33
33
  "keywords": [
34
34
  "remotion",
@@ -1 +0,0 @@
1
- export declare const RootLog: () => null;
@@ -1,8 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.RootLog = void 0;
4
- const RootLog = () => {
5
- console.log('gets logged ');
6
- return null;
7
- };
8
- exports.RootLog = RootLog;