@remotion/player 4.0.451 → 4.0.452
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/dist/cjs/Player.js +1 -1
- package/dist/cjs/SharedPlayerContext.js +1 -1
- package/dist/cjs/set-global-time-anchor.d.ts +10 -0
- package/dist/cjs/set-global-time-anchor.js +20 -0
- package/dist/cjs/use-playback.js +88 -16
- package/dist/cjs/use-player.js +6 -6
- package/dist/cjs/utils/validate-playbackrate.js +4 -4
- package/dist/esm/index.mjs +171 -80
- package/package.json +3 -3
package/dist/cjs/Player.js
CHANGED
|
@@ -23,7 +23,7 @@ const componentOrNullIfLazy = (props) => {
|
|
|
23
23
|
return null;
|
|
24
24
|
};
|
|
25
25
|
exports.componentOrNullIfLazy = componentOrNullIfLazy;
|
|
26
|
-
const PlayerFn = ({ durationInFrames, compositionHeight, compositionWidth, fps, inputProps, style, controls = false, loop = false, autoPlay = false, showVolumeControls = true, allowFullscreen = true, clickToPlay, doubleClickToFullscreen = false, spaceKeyToPlayOrPause = true, moveToBeginningWhenEnded = true, numberOfSharedAudioTags = 5, errorFallback = () => '⚠️', playbackRate = 1, renderLoading, className, showPosterWhenUnplayed, showPosterWhenEnded, showPosterWhenPaused, showPosterWhenBuffering, showPosterWhenBufferingAndPaused, initialFrame, renderPoster, inFrame, outFrame, initiallyShowControls, renderFullscreenButton, renderPlayPauseButton, renderVolumeSlider, renderCustomControls, alwaysShowControls = false, initiallyMuted = false, showPlaybackRateControl = false, posterFillMode = 'player-size', bufferStateDelayInMilliseconds, hideControlsWhenPointerDoesntMove = true, overflowVisible = false, renderMuteButton, browserMediaControlsBehavior: passedBrowserMediaControlsBehavior, overrideInternalClassName, logLevel = 'info', noSuspense, acknowledgeRemotionLicense, audioLatencyHint = '
|
|
26
|
+
const PlayerFn = ({ durationInFrames, compositionHeight, compositionWidth, fps, inputProps, style, controls = false, loop = false, autoPlay = false, showVolumeControls = true, allowFullscreen = true, clickToPlay, doubleClickToFullscreen = false, spaceKeyToPlayOrPause = true, moveToBeginningWhenEnded = true, numberOfSharedAudioTags = 5, errorFallback = () => '⚠️', playbackRate = 1, renderLoading, className, showPosterWhenUnplayed, showPosterWhenEnded, showPosterWhenPaused, showPosterWhenBuffering, showPosterWhenBufferingAndPaused, initialFrame, renderPoster, inFrame, outFrame, initiallyShowControls, renderFullscreenButton, renderPlayPauseButton, renderVolumeSlider, renderCustomControls, alwaysShowControls = false, initiallyMuted = false, showPlaybackRateControl = false, posterFillMode = 'player-size', bufferStateDelayInMilliseconds, hideControlsWhenPointerDoesntMove = true, overflowVisible = false, renderMuteButton, browserMediaControlsBehavior: passedBrowserMediaControlsBehavior, overrideInternalClassName, logLevel = 'info', noSuspense, acknowledgeRemotionLicense, audioLatencyHint = 'playback', volumePersistenceKey, ...componentProps }, ref) => {
|
|
27
27
|
if (typeof window !== 'undefined') {
|
|
28
28
|
window.remotion_isPlayer = true;
|
|
29
29
|
}
|
|
@@ -83,6 +83,6 @@ const SharedPlayerContexts = ({ children, timelineContext, fps, compositionHeigh
|
|
|
83
83
|
isReadOnlyStudio: false,
|
|
84
84
|
};
|
|
85
85
|
}, []);
|
|
86
|
-
return (jsx_runtime_1.jsx(remotion_1.Internals.RemotionEnvironmentContext.Provider, { value: env, children: jsx_runtime_1.jsx(remotion_1.Internals.LogLevelContext.Provider, { value: logLevelContext, children: jsx_runtime_1.jsx(remotion_1.Internals.CanUseRemotionHooksProvider, { children: jsx_runtime_1.jsx(remotion_1.Internals.AbsoluteTimeContext.Provider, { value: timelineContext, children: jsx_runtime_1.jsx(remotion_1.Internals.TimelineContext.Provider, { value: timelineContext, children: jsx_runtime_1.jsx(remotion_1.Internals.CompositionManager.Provider, { value: compositionManagerContext, children: jsx_runtime_1.jsx(remotion_1.Internals.PrefetchProvider, { children: jsx_runtime_1.jsx(remotion_1.Internals.DurationsContextProvider, { children: jsx_runtime_1.jsx(remotion_1.Internals.MediaVolumeContext.Provider, { value: mediaVolumeContextValue, children: jsx_runtime_1.jsx(remotion_1.Internals.SetMediaVolumeContext.Provider, { value: setMediaVolumeContextValue, children: jsx_runtime_1.jsx(remotion_1.Internals.
|
|
86
|
+
return (jsx_runtime_1.jsx(remotion_1.Internals.RemotionEnvironmentContext.Provider, { value: env, children: jsx_runtime_1.jsx(remotion_1.Internals.LogLevelContext.Provider, { value: logLevelContext, children: jsx_runtime_1.jsx(remotion_1.Internals.CanUseRemotionHooksProvider, { children: jsx_runtime_1.jsx(remotion_1.Internals.AbsoluteTimeContext.Provider, { value: timelineContext, children: jsx_runtime_1.jsx(remotion_1.Internals.TimelineContext.Provider, { value: timelineContext, children: jsx_runtime_1.jsx(remotion_1.Internals.CompositionManager.Provider, { value: compositionManagerContext, children: jsx_runtime_1.jsx(remotion_1.Internals.PrefetchProvider, { children: jsx_runtime_1.jsx(remotion_1.Internals.DurationsContextProvider, { children: jsx_runtime_1.jsx(remotion_1.Internals.MediaVolumeContext.Provider, { value: mediaVolumeContextValue, children: jsx_runtime_1.jsx(remotion_1.Internals.SetMediaVolumeContext.Provider, { value: setMediaVolumeContextValue, children: jsx_runtime_1.jsx(remotion_1.Internals.BufferingProvider, { children: jsx_runtime_1.jsx(remotion_1.Internals.SharedAudioContextProvider, { audioLatencyHint: audioLatencyHint, audioEnabled: audioEnabled, children: jsx_runtime_1.jsx(remotion_1.Internals.SharedAudioTagsContextProvider, { numberOfAudioTags: numberOfSharedAudioTags, children: children }) }) }) }) }) }) }) }) }) }) }) }) }));
|
|
87
87
|
};
|
|
88
88
|
exports.SharedPlayerContexts = SharedPlayerContexts;
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
export declare const ALLOWED_GLOBAL_TIME_ANCHOR_SHIFT = 0.1;
|
|
2
|
+
export declare const setGlobalTimeAnchor: ({ audioContext, audioSyncAnchor, absoluteTimeInSeconds, globalPlaybackRate, logLevel, }: {
|
|
3
|
+
audioContext: AudioContext;
|
|
4
|
+
audioSyncAnchor: {
|
|
5
|
+
value: number;
|
|
6
|
+
};
|
|
7
|
+
absoluteTimeInSeconds: number;
|
|
8
|
+
globalPlaybackRate: number;
|
|
9
|
+
logLevel: "error" | "info" | "trace" | "verbose" | "warn";
|
|
10
|
+
}) => boolean;
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.setGlobalTimeAnchor = exports.ALLOWED_GLOBAL_TIME_ANCHOR_SHIFT = void 0;
|
|
4
|
+
const remotion_1 = require("remotion");
|
|
5
|
+
exports.ALLOWED_GLOBAL_TIME_ANCHOR_SHIFT = 0.1;
|
|
6
|
+
const setGlobalTimeAnchor = ({ audioContext, audioSyncAnchor, absoluteTimeInSeconds, globalPlaybackRate, logLevel, }) => {
|
|
7
|
+
const newAnchor = audioContext.currentTime - absoluteTimeInSeconds / globalPlaybackRate;
|
|
8
|
+
const shift = (newAnchor - audioSyncAnchor.value) * globalPlaybackRate;
|
|
9
|
+
const { outputLatency } = audioContext;
|
|
10
|
+
const safeOutputLatency = outputLatency === 0 ? 0.3 : outputLatency;
|
|
11
|
+
const latency = audioContext.baseLatency + safeOutputLatency;
|
|
12
|
+
// Skip small shifts to avoid audio glitches from frame-quantized re-anchoring
|
|
13
|
+
if (Math.abs(shift) < exports.ALLOWED_GLOBAL_TIME_ANCHOR_SHIFT + latency) {
|
|
14
|
+
return false;
|
|
15
|
+
}
|
|
16
|
+
remotion_1.Internals.Log.verbose({ logLevel, tag: 'audio-scheduling' }, 'Anchor changed from %s to %s with shift %s', audioSyncAnchor.value, newAnchor, shift);
|
|
17
|
+
audioSyncAnchor.value = newAnchor;
|
|
18
|
+
return true;
|
|
19
|
+
};
|
|
20
|
+
exports.setGlobalTimeAnchor = setGlobalTimeAnchor;
|
package/dist/cjs/use-playback.js
CHANGED
|
@@ -1,24 +1,29 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.usePlayback = void 0;
|
|
4
|
-
/* eslint-disable @typescript-eslint/no-use-before-define */
|
|
5
4
|
const react_1 = require("react");
|
|
5
|
+
/* eslint-disable @typescript-eslint/no-use-before-define */
|
|
6
|
+
const react_2 = require("react");
|
|
6
7
|
const remotion_1 = require("remotion");
|
|
7
8
|
const browser_mediasession_js_1 = require("./browser-mediasession.js");
|
|
8
9
|
const calculate_next_frame_js_1 = require("./calculate-next-frame.js");
|
|
9
10
|
const is_backgrounded_js_1 = require("./is-backgrounded.js");
|
|
11
|
+
const set_global_time_anchor_js_1 = require("./set-global-time-anchor.js");
|
|
10
12
|
const use_player_js_1 = require("./use-player.js");
|
|
11
13
|
const usePlayback = ({ loop, playbackRate, moveToBeginningWhenEnded, inFrame, outFrame, browserMediaControlsBehavior, getCurrentFrame, }) => {
|
|
12
14
|
const config = remotion_1.Internals.useUnsafeVideoConfig();
|
|
13
15
|
const frame = remotion_1.Internals.Timeline.useTimelinePosition();
|
|
14
16
|
const { playing, pause, emitter, isPlaying } = (0, use_player_js_1.usePlayer)();
|
|
15
17
|
const setFrame = remotion_1.Internals.Timeline.useTimelineSetFrame();
|
|
18
|
+
const sharedAudioContext = (0, react_2.useContext)(remotion_1.Internals.SharedAudioContext);
|
|
19
|
+
const logLevel = remotion_1.Internals.useLogLevel();
|
|
20
|
+
const timelineContext = remotion_1.Internals.useTimelineContext();
|
|
16
21
|
// requestAnimationFrame() does not work if the tab is not active.
|
|
17
22
|
// This means that audio will keep playing even if it has ended.
|
|
18
23
|
// In that case, we use setTimeout() instead.
|
|
19
24
|
const isBackgroundedRef = (0, is_backgrounded_js_1.useIsBackgrounded)();
|
|
20
|
-
const
|
|
21
|
-
const context = (0,
|
|
25
|
+
const lastTimeUpdateTimestamp = (0, react_2.useRef)(0);
|
|
26
|
+
const context = (0, react_2.useContext)(remotion_1.Internals.BufferingContextReact);
|
|
22
27
|
if (!context) {
|
|
23
28
|
throw new Error('Missing the buffering context. Most likely you have a Remotion version mismatch.');
|
|
24
29
|
}
|
|
@@ -27,12 +32,40 @@ const usePlayback = ({ loop, playbackRate, moveToBeginningWhenEnded, inFrame, ou
|
|
|
27
32
|
playbackRate,
|
|
28
33
|
videoConfig: config,
|
|
29
34
|
});
|
|
30
|
-
|
|
31
|
-
|
|
35
|
+
(0, react_1.useLayoutEffect)(() => {
|
|
36
|
+
if (!sharedAudioContext) {
|
|
37
|
+
return;
|
|
38
|
+
}
|
|
39
|
+
if (!sharedAudioContext.audioContext) {
|
|
40
|
+
return;
|
|
41
|
+
}
|
|
42
|
+
if (!config) {
|
|
43
|
+
return;
|
|
44
|
+
}
|
|
45
|
+
const changed = (0, set_global_time_anchor_js_1.setGlobalTimeAnchor)({
|
|
46
|
+
audioContext: sharedAudioContext.audioContext,
|
|
47
|
+
audioSyncAnchor: sharedAudioContext.audioSyncAnchor,
|
|
48
|
+
absoluteTimeInSeconds: frame / config.fps,
|
|
49
|
+
globalPlaybackRate: timelineContext.playbackRate,
|
|
50
|
+
logLevel,
|
|
51
|
+
});
|
|
52
|
+
if (changed) {
|
|
53
|
+
sharedAudioContext.audioSyncAnchorEmitter.dispatch('changed');
|
|
54
|
+
}
|
|
55
|
+
}, [
|
|
56
|
+
config,
|
|
57
|
+
frame,
|
|
58
|
+
logLevel,
|
|
59
|
+
sharedAudioContext,
|
|
60
|
+
timelineContext.playbackRate,
|
|
61
|
+
]);
|
|
62
|
+
(0, react_2.useEffect)(() => {
|
|
63
|
+
var _a;
|
|
32
64
|
if (!config) {
|
|
33
65
|
return;
|
|
34
66
|
}
|
|
35
67
|
if (!playing) {
|
|
68
|
+
(_a = sharedAudioContext === null || sharedAudioContext === void 0 ? void 0 : sharedAudioContext.suspend) === null || _a === void 0 ? void 0 : _a.call(sharedAudioContext);
|
|
36
69
|
return;
|
|
37
70
|
}
|
|
38
71
|
let hasBeenStopped = false;
|
|
@@ -54,12 +87,15 @@ const usePlayback = ({ loop, playbackRate, moveToBeginningWhenEnded, inFrame, ou
|
|
|
54
87
|
cancelQueuedFrame();
|
|
55
88
|
};
|
|
56
89
|
const callback = () => {
|
|
90
|
+
var _a, _b;
|
|
57
91
|
if (hasBeenStopped) {
|
|
58
92
|
return;
|
|
59
93
|
}
|
|
60
94
|
if (!isPlaying()) {
|
|
95
|
+
(_a = sharedAudioContext === null || sharedAudioContext === void 0 ? void 0 : sharedAudioContext.suspend) === null || _a === void 0 ? void 0 : _a.call(sharedAudioContext);
|
|
61
96
|
return;
|
|
62
97
|
}
|
|
98
|
+
(_b = sharedAudioContext === null || sharedAudioContext === void 0 ? void 0 : sharedAudioContext.resume) === null || _b === void 0 ? void 0 : _b.call(sharedAudioContext);
|
|
63
99
|
const time = performance.now() - startedTime;
|
|
64
100
|
const actualLastFrame = outFrame !== null && outFrame !== void 0 ? outFrame : config.durationInFrames - 1;
|
|
65
101
|
const actualFirstFrame = inFrame !== null && inFrame !== void 0 ? inFrame : 0;
|
|
@@ -88,7 +124,36 @@ const usePlayback = ({ loop, playbackRate, moveToBeginningWhenEnded, inFrame, ou
|
|
|
88
124
|
queueNextFrame();
|
|
89
125
|
};
|
|
90
126
|
const queueNextFrame = () => {
|
|
127
|
+
var _a, _b;
|
|
128
|
+
var _c;
|
|
129
|
+
const getIsResumingAudioContext = (_c = (_a = sharedAudioContext === null || sharedAudioContext === void 0 ? void 0 : sharedAudioContext.getIsResumingAudioContext) === null || _a === void 0 ? void 0 : _a.call(sharedAudioContext)) !== null && _c !== void 0 ? _c : null;
|
|
130
|
+
if (getIsResumingAudioContext !== null) {
|
|
131
|
+
getIsResumingAudioContext.then(() => {
|
|
132
|
+
if (!(sharedAudioContext === null || sharedAudioContext === void 0 ? void 0 : sharedAudioContext.audioContext)) {
|
|
133
|
+
return;
|
|
134
|
+
}
|
|
135
|
+
if (!sharedAudioContext.audioSyncAnchor) {
|
|
136
|
+
return;
|
|
137
|
+
}
|
|
138
|
+
// set it here and DON'T propagate an event
|
|
139
|
+
// the useLayoutEffect above is supposed to handle a user seek,
|
|
140
|
+
// this is a natural wait for the audio playback to start.
|
|
141
|
+
// we don't wanna destroy the iterators.
|
|
142
|
+
(0, set_global_time_anchor_js_1.setGlobalTimeAnchor)({
|
|
143
|
+
audioContext: sharedAudioContext.audioContext,
|
|
144
|
+
audioSyncAnchor: sharedAudioContext.audioSyncAnchor,
|
|
145
|
+
absoluteTimeInSeconds: getCurrentFrame() / config.fps,
|
|
146
|
+
globalPlaybackRate: timelineContext.playbackRate,
|
|
147
|
+
logLevel,
|
|
148
|
+
});
|
|
149
|
+
startedTime = performance.now();
|
|
150
|
+
framesAdvanced = 0;
|
|
151
|
+
queueNextFrame();
|
|
152
|
+
});
|
|
153
|
+
return;
|
|
154
|
+
}
|
|
91
155
|
if (context.buffering.current) {
|
|
156
|
+
(_b = sharedAudioContext === null || sharedAudioContext === void 0 ? void 0 : sharedAudioContext.suspend) === null || _b === void 0 ? void 0 : _b.call(sharedAudioContext);
|
|
92
157
|
const stopListening = context.listenForResume(() => {
|
|
93
158
|
stopListening.remove();
|
|
94
159
|
startedTime = performance.now();
|
|
@@ -137,18 +202,25 @@ const usePlayback = ({ loop, playbackRate, moveToBeginningWhenEnded, inFrame, ou
|
|
|
137
202
|
getCurrentFrame,
|
|
138
203
|
context,
|
|
139
204
|
isPlaying,
|
|
205
|
+
sharedAudioContext,
|
|
206
|
+
timelineContext.playbackRate,
|
|
207
|
+
logLevel,
|
|
140
208
|
]);
|
|
141
|
-
(0,
|
|
142
|
-
const
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
}
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
}
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
209
|
+
(0, react_2.useEffect)(() => {
|
|
210
|
+
const now = performance.now();
|
|
211
|
+
const timeSinceLastUpdate = now - lastTimeUpdateTimestamp.current;
|
|
212
|
+
if (timeSinceLastUpdate >= 250) {
|
|
213
|
+
emitter.dispatchTimeUpdate({ frame });
|
|
214
|
+
lastTimeUpdateTimestamp.current = now;
|
|
215
|
+
return;
|
|
216
|
+
}
|
|
217
|
+
const timeoutId = setTimeout(() => {
|
|
218
|
+
emitter.dispatchTimeUpdate({ frame });
|
|
219
|
+
lastTimeUpdateTimestamp.current = performance.now();
|
|
220
|
+
}, 250 - timeSinceLastUpdate);
|
|
221
|
+
return () => clearTimeout(timeoutId);
|
|
222
|
+
}, [emitter, frame]);
|
|
223
|
+
(0, react_2.useEffect)(() => {
|
|
152
224
|
emitter.dispatchFrameUpdate({ frame });
|
|
153
225
|
}, [emitter, frame]);
|
|
154
226
|
};
|
package/dist/cjs/use-player.js
CHANGED
|
@@ -13,6 +13,7 @@ const usePlayer = () => {
|
|
|
13
13
|
const setFrame = remotion_1.Internals.Timeline.useTimelineSetFrame();
|
|
14
14
|
const setTimelinePosition = remotion_1.Internals.Timeline.useTimelineSetFrame();
|
|
15
15
|
const audioContext = (0, react_1.useContext)(remotion_1.Internals.SharedAudioContext);
|
|
16
|
+
const audioTagsContext = (0, react_1.useContext)(remotion_1.Internals.SharedAudioTagsContext);
|
|
16
17
|
const { audioAndVideoTags } = remotion_1.Internals.useTimelineContext();
|
|
17
18
|
const frameRef = (0, react_1.useRef)(frame);
|
|
18
19
|
frameRef.current = frame;
|
|
@@ -38,7 +39,6 @@ const usePlayer = () => {
|
|
|
38
39
|
emitter.dispatchSeek(newFrame);
|
|
39
40
|
}, [emitter, setTimelinePosition, video === null || video === void 0 ? void 0 : video.id]);
|
|
40
41
|
const play = (0, react_1.useCallback)((e) => {
|
|
41
|
-
var _a;
|
|
42
42
|
if (imperativePlaying.current) {
|
|
43
43
|
return;
|
|
44
44
|
}
|
|
@@ -46,12 +46,12 @@ const usePlayer = () => {
|
|
|
46
46
|
if (isLastFrame) {
|
|
47
47
|
seek(0);
|
|
48
48
|
}
|
|
49
|
-
|
|
49
|
+
audioContext === null || audioContext === void 0 ? void 0 : audioContext.resume();
|
|
50
50
|
/**
|
|
51
51
|
* Play silent audio tags to warm them up for autoplay
|
|
52
52
|
*/
|
|
53
|
-
if (
|
|
54
|
-
|
|
53
|
+
if (audioTagsContext && audioTagsContext.numberOfAudioTags > 0 && e) {
|
|
54
|
+
audioTagsContext.playAllAudios();
|
|
55
55
|
}
|
|
56
56
|
/**
|
|
57
57
|
* Play audios and videos directly here so they can benefit from
|
|
@@ -66,18 +66,18 @@ const usePlayer = () => {
|
|
|
66
66
|
imperativePlaying,
|
|
67
67
|
isLastFrame,
|
|
68
68
|
audioContext,
|
|
69
|
+
audioTagsContext,
|
|
69
70
|
setPlaying,
|
|
70
71
|
emitter,
|
|
71
72
|
seek,
|
|
72
73
|
audioAndVideoTags,
|
|
73
74
|
]);
|
|
74
75
|
const pause = (0, react_1.useCallback)(() => {
|
|
75
|
-
var _a;
|
|
76
76
|
if (imperativePlaying.current) {
|
|
77
77
|
imperativePlaying.current = false;
|
|
78
78
|
setPlaying(false);
|
|
79
79
|
emitter.dispatchPause();
|
|
80
|
-
|
|
80
|
+
audioContext === null || audioContext === void 0 ? void 0 : audioContext.suspend();
|
|
81
81
|
}
|
|
82
82
|
}, [emitter, imperativePlaying, setPlaying, audioContext]);
|
|
83
83
|
const pauseAndReturnToPlayStart = (0, react_1.useCallback)(() => {
|
|
@@ -5,11 +5,11 @@ const validatePlaybackRate = (playbackRate) => {
|
|
|
5
5
|
if (playbackRate === undefined) {
|
|
6
6
|
return;
|
|
7
7
|
}
|
|
8
|
-
if (playbackRate >
|
|
9
|
-
throw new Error(`The highest possible playback rate is
|
|
8
|
+
if (playbackRate > 10) {
|
|
9
|
+
throw new Error(`The highest possible playback rate is 10. You passed: ${playbackRate}`);
|
|
10
10
|
}
|
|
11
|
-
if (playbackRate < -
|
|
12
|
-
throw new Error(`The lowest possible playback rate is -
|
|
11
|
+
if (playbackRate < -10) {
|
|
12
|
+
throw new Error(`The lowest possible playback rate is -10. You passed: ${playbackRate}`);
|
|
13
13
|
}
|
|
14
14
|
if (playbackRate === 0) {
|
|
15
15
|
throw new Error(`A playback rate of 0 is not supported.`);
|
package/dist/esm/index.mjs
CHANGED
|
@@ -552,8 +552,9 @@ var useHoverState = (ref, hideControlsWhenPointerDoesntMove) => {
|
|
|
552
552
|
};
|
|
553
553
|
|
|
554
554
|
// src/use-playback.ts
|
|
555
|
+
import { useLayoutEffect as useLayoutEffect2 } from "react";
|
|
555
556
|
import { useContext as useContext4, useEffect as useEffect5, useRef as useRef5 } from "react";
|
|
556
|
-
import { Internals as
|
|
557
|
+
import { Internals as Internals7 } from "remotion";
|
|
557
558
|
|
|
558
559
|
// src/browser-mediasession.ts
|
|
559
560
|
import { useEffect as useEffect3, useRef as useRef3 } from "react";
|
|
@@ -569,6 +570,7 @@ var usePlayer = () => {
|
|
|
569
570
|
const setFrame = Internals5.Timeline.useTimelineSetFrame();
|
|
570
571
|
const setTimelinePosition = Internals5.Timeline.useTimelineSetFrame();
|
|
571
572
|
const audioContext = useContext3(Internals5.SharedAudioContext);
|
|
573
|
+
const audioTagsContext = useContext3(Internals5.SharedAudioTagsContext);
|
|
572
574
|
const { audioAndVideoTags } = Internals5.useTimelineContext();
|
|
573
575
|
const frameRef = useRef2(frame);
|
|
574
576
|
frameRef.current = frame;
|
|
@@ -601,9 +603,9 @@ var usePlayer = () => {
|
|
|
601
603
|
if (isLastFrame) {
|
|
602
604
|
seek(0);
|
|
603
605
|
}
|
|
604
|
-
audioContext?.
|
|
605
|
-
if (
|
|
606
|
-
|
|
606
|
+
audioContext?.resume();
|
|
607
|
+
if (audioTagsContext && audioTagsContext.numberOfAudioTags > 0 && e) {
|
|
608
|
+
audioTagsContext.playAllAudios();
|
|
607
609
|
}
|
|
608
610
|
audioAndVideoTags.current.forEach((a) => a.play("player play() was called and playing audio from a click"));
|
|
609
611
|
imperativePlaying.current = true;
|
|
@@ -614,6 +616,7 @@ var usePlayer = () => {
|
|
|
614
616
|
imperativePlaying,
|
|
615
617
|
isLastFrame,
|
|
616
618
|
audioContext,
|
|
619
|
+
audioTagsContext,
|
|
617
620
|
setPlaying,
|
|
618
621
|
emitter,
|
|
619
622
|
seek,
|
|
@@ -624,7 +627,7 @@ var usePlayer = () => {
|
|
|
624
627
|
imperativePlaying.current = false;
|
|
625
628
|
setPlaying(false);
|
|
626
629
|
emitter.dispatchPause();
|
|
627
|
-
audioContext?.
|
|
630
|
+
audioContext?.suspend();
|
|
628
631
|
}
|
|
629
632
|
}, [emitter, imperativePlaying, setPlaying, audioContext]);
|
|
630
633
|
const pauseAndReturnToPlayStart = useCallback2(() => {
|
|
@@ -901,6 +904,29 @@ var useIsBackgrounded = () => {
|
|
|
901
904
|
return isBackgrounded;
|
|
902
905
|
};
|
|
903
906
|
|
|
907
|
+
// src/set-global-time-anchor.ts
|
|
908
|
+
import { Internals as Internals6 } from "remotion";
|
|
909
|
+
var ALLOWED_GLOBAL_TIME_ANCHOR_SHIFT = 0.1;
|
|
910
|
+
var setGlobalTimeAnchor = ({
|
|
911
|
+
audioContext,
|
|
912
|
+
audioSyncAnchor,
|
|
913
|
+
absoluteTimeInSeconds,
|
|
914
|
+
globalPlaybackRate,
|
|
915
|
+
logLevel
|
|
916
|
+
}) => {
|
|
917
|
+
const newAnchor = audioContext.currentTime - absoluteTimeInSeconds / globalPlaybackRate;
|
|
918
|
+
const shift = (newAnchor - audioSyncAnchor.value) * globalPlaybackRate;
|
|
919
|
+
const { outputLatency } = audioContext;
|
|
920
|
+
const safeOutputLatency = outputLatency === 0 ? 0.3 : outputLatency;
|
|
921
|
+
const latency = audioContext.baseLatency + safeOutputLatency;
|
|
922
|
+
if (Math.abs(shift) < ALLOWED_GLOBAL_TIME_ANCHOR_SHIFT + latency) {
|
|
923
|
+
return false;
|
|
924
|
+
}
|
|
925
|
+
Internals6.Log.verbose({ logLevel, tag: "audio-scheduling" }, "Anchor changed from %s to %s with shift %s", audioSyncAnchor.value, newAnchor, shift);
|
|
926
|
+
audioSyncAnchor.value = newAnchor;
|
|
927
|
+
return true;
|
|
928
|
+
};
|
|
929
|
+
|
|
904
930
|
// src/use-playback.ts
|
|
905
931
|
var usePlayback = ({
|
|
906
932
|
loop,
|
|
@@ -911,13 +937,16 @@ var usePlayback = ({
|
|
|
911
937
|
browserMediaControlsBehavior,
|
|
912
938
|
getCurrentFrame
|
|
913
939
|
}) => {
|
|
914
|
-
const config =
|
|
915
|
-
const frame =
|
|
940
|
+
const config = Internals7.useUnsafeVideoConfig();
|
|
941
|
+
const frame = Internals7.Timeline.useTimelinePosition();
|
|
916
942
|
const { playing, pause, emitter, isPlaying } = usePlayer();
|
|
917
|
-
const setFrame =
|
|
943
|
+
const setFrame = Internals7.Timeline.useTimelineSetFrame();
|
|
944
|
+
const sharedAudioContext = useContext4(Internals7.SharedAudioContext);
|
|
945
|
+
const logLevel = Internals7.useLogLevel();
|
|
946
|
+
const timelineContext = Internals7.useTimelineContext();
|
|
918
947
|
const isBackgroundedRef = useIsBackgrounded();
|
|
919
|
-
const
|
|
920
|
-
const context = useContext4(
|
|
948
|
+
const lastTimeUpdateTimestamp = useRef5(0);
|
|
949
|
+
const context = useContext4(Internals7.BufferingContextReact);
|
|
921
950
|
if (!context) {
|
|
922
951
|
throw new Error("Missing the buffering context. Most likely you have a Remotion version mismatch.");
|
|
923
952
|
}
|
|
@@ -926,11 +955,39 @@ var usePlayback = ({
|
|
|
926
955
|
playbackRate,
|
|
927
956
|
videoConfig: config
|
|
928
957
|
});
|
|
958
|
+
useLayoutEffect2(() => {
|
|
959
|
+
if (!sharedAudioContext) {
|
|
960
|
+
return;
|
|
961
|
+
}
|
|
962
|
+
if (!sharedAudioContext.audioContext) {
|
|
963
|
+
return;
|
|
964
|
+
}
|
|
965
|
+
if (!config) {
|
|
966
|
+
return;
|
|
967
|
+
}
|
|
968
|
+
const changed = setGlobalTimeAnchor({
|
|
969
|
+
audioContext: sharedAudioContext.audioContext,
|
|
970
|
+
audioSyncAnchor: sharedAudioContext.audioSyncAnchor,
|
|
971
|
+
absoluteTimeInSeconds: frame / config.fps,
|
|
972
|
+
globalPlaybackRate: timelineContext.playbackRate,
|
|
973
|
+
logLevel
|
|
974
|
+
});
|
|
975
|
+
if (changed) {
|
|
976
|
+
sharedAudioContext.audioSyncAnchorEmitter.dispatch("changed");
|
|
977
|
+
}
|
|
978
|
+
}, [
|
|
979
|
+
config,
|
|
980
|
+
frame,
|
|
981
|
+
logLevel,
|
|
982
|
+
sharedAudioContext,
|
|
983
|
+
timelineContext.playbackRate
|
|
984
|
+
]);
|
|
929
985
|
useEffect5(() => {
|
|
930
986
|
if (!config) {
|
|
931
987
|
return;
|
|
932
988
|
}
|
|
933
989
|
if (!playing) {
|
|
990
|
+
sharedAudioContext?.suspend?.();
|
|
934
991
|
return;
|
|
935
992
|
}
|
|
936
993
|
let hasBeenStopped = false;
|
|
@@ -955,8 +1012,10 @@ var usePlayback = ({
|
|
|
955
1012
|
return;
|
|
956
1013
|
}
|
|
957
1014
|
if (!isPlaying()) {
|
|
1015
|
+
sharedAudioContext?.suspend?.();
|
|
958
1016
|
return;
|
|
959
1017
|
}
|
|
1018
|
+
sharedAudioContext?.resume?.();
|
|
960
1019
|
const time = performance.now() - startedTime;
|
|
961
1020
|
const actualLastFrame = outFrame ?? config.durationInFrames - 1;
|
|
962
1021
|
const actualFirstFrame = inFrame ?? 0;
|
|
@@ -984,7 +1043,30 @@ var usePlayback = ({
|
|
|
984
1043
|
queueNextFrame();
|
|
985
1044
|
};
|
|
986
1045
|
const queueNextFrame = () => {
|
|
1046
|
+
const getIsResumingAudioContext = sharedAudioContext?.getIsResumingAudioContext?.() ?? null;
|
|
1047
|
+
if (getIsResumingAudioContext !== null) {
|
|
1048
|
+
getIsResumingAudioContext.then(() => {
|
|
1049
|
+
if (!sharedAudioContext?.audioContext) {
|
|
1050
|
+
return;
|
|
1051
|
+
}
|
|
1052
|
+
if (!sharedAudioContext.audioSyncAnchor) {
|
|
1053
|
+
return;
|
|
1054
|
+
}
|
|
1055
|
+
setGlobalTimeAnchor({
|
|
1056
|
+
audioContext: sharedAudioContext.audioContext,
|
|
1057
|
+
audioSyncAnchor: sharedAudioContext.audioSyncAnchor,
|
|
1058
|
+
absoluteTimeInSeconds: getCurrentFrame() / config.fps,
|
|
1059
|
+
globalPlaybackRate: timelineContext.playbackRate,
|
|
1060
|
+
logLevel
|
|
1061
|
+
});
|
|
1062
|
+
startedTime = performance.now();
|
|
1063
|
+
framesAdvanced = 0;
|
|
1064
|
+
queueNextFrame();
|
|
1065
|
+
});
|
|
1066
|
+
return;
|
|
1067
|
+
}
|
|
987
1068
|
if (context.buffering.current) {
|
|
1069
|
+
sharedAudioContext?.suspend?.();
|
|
988
1070
|
const stopListening = context.listenForResume(() => {
|
|
989
1071
|
stopListening.remove();
|
|
990
1072
|
startedTime = performance.now();
|
|
@@ -1029,18 +1111,25 @@ var usePlayback = ({
|
|
|
1029
1111
|
isBackgroundedRef,
|
|
1030
1112
|
getCurrentFrame,
|
|
1031
1113
|
context,
|
|
1032
|
-
isPlaying
|
|
1114
|
+
isPlaying,
|
|
1115
|
+
sharedAudioContext,
|
|
1116
|
+
timelineContext.playbackRate,
|
|
1117
|
+
logLevel
|
|
1033
1118
|
]);
|
|
1034
1119
|
useEffect5(() => {
|
|
1035
|
-
const
|
|
1036
|
-
|
|
1037
|
-
|
|
1038
|
-
}
|
|
1039
|
-
|
|
1040
|
-
|
|
1041
|
-
}
|
|
1042
|
-
|
|
1043
|
-
|
|
1120
|
+
const now = performance.now();
|
|
1121
|
+
const timeSinceLastUpdate = now - lastTimeUpdateTimestamp.current;
|
|
1122
|
+
if (timeSinceLastUpdate >= 250) {
|
|
1123
|
+
emitter.dispatchTimeUpdate({ frame });
|
|
1124
|
+
lastTimeUpdateTimestamp.current = now;
|
|
1125
|
+
return;
|
|
1126
|
+
}
|
|
1127
|
+
const timeoutId = setTimeout(() => {
|
|
1128
|
+
emitter.dispatchTimeUpdate({ frame });
|
|
1129
|
+
lastTimeUpdateTimestamp.current = performance.now();
|
|
1130
|
+
}, 250 - timeSinceLastUpdate);
|
|
1131
|
+
return () => clearTimeout(timeoutId);
|
|
1132
|
+
}, [emitter, frame]);
|
|
1044
1133
|
useEffect5(() => {
|
|
1045
1134
|
emitter.dispatchFrameUpdate({ frame });
|
|
1046
1135
|
}, [emitter, frame]);
|
|
@@ -1174,12 +1263,12 @@ import {
|
|
|
1174
1263
|
forwardRef as forwardRef2,
|
|
1175
1264
|
useEffect as useEffect13,
|
|
1176
1265
|
useImperativeHandle as useImperativeHandle2,
|
|
1177
|
-
useLayoutEffect as
|
|
1266
|
+
useLayoutEffect as useLayoutEffect3,
|
|
1178
1267
|
useMemo as useMemo14,
|
|
1179
1268
|
useRef as useRef12,
|
|
1180
1269
|
useState as useState13
|
|
1181
1270
|
} from "react";
|
|
1182
|
-
import { Composition, Internals as
|
|
1271
|
+
import { Composition, Internals as Internals16 } from "remotion";
|
|
1183
1272
|
|
|
1184
1273
|
// src/player-css-classname.ts
|
|
1185
1274
|
var playerCssClassname = (override) => {
|
|
@@ -1198,7 +1287,7 @@ import React10, {
|
|
|
1198
1287
|
useRef as useRef11,
|
|
1199
1288
|
useState as useState11
|
|
1200
1289
|
} from "react";
|
|
1201
|
-
import { Internals as
|
|
1290
|
+
import { Internals as Internals12 } from "remotion";
|
|
1202
1291
|
|
|
1203
1292
|
// src/error-boundary.tsx
|
|
1204
1293
|
import React3 from "react";
|
|
@@ -1341,7 +1430,7 @@ var DefaultPlayPauseButton = ({ playing, buffering }) => {
|
|
|
1341
1430
|
|
|
1342
1431
|
// src/MediaVolumeSlider.tsx
|
|
1343
1432
|
import { useCallback as useCallback5, useMemo as useMemo4, useRef as useRef6, useState as useState6 } from "react";
|
|
1344
|
-
import { Internals as
|
|
1433
|
+
import { Internals as Internals8 } from "remotion";
|
|
1345
1434
|
|
|
1346
1435
|
// src/render-volume-slider.tsx
|
|
1347
1436
|
import React5, { useCallback as useCallback4, useMemo as useMemo3, useState as useState5 } from "react";
|
|
@@ -1455,8 +1544,8 @@ var renderDefaultVolumeSlider = (props) => {
|
|
|
1455
1544
|
import { jsx as jsx8, jsxs as jsxs4 } from "react/jsx-runtime";
|
|
1456
1545
|
var VOLUME_SLIDER_WIDTH = 100;
|
|
1457
1546
|
var MediaVolumeSlider = ({ displayVerticalVolumeSlider, renderMuteButton, renderVolumeSlider }) => {
|
|
1458
|
-
const [mediaMuted, setMediaMuted] =
|
|
1459
|
-
const [mediaVolume, setMediaVolume] =
|
|
1547
|
+
const [mediaMuted, setMediaMuted] = Internals8.useMediaMutedState();
|
|
1548
|
+
const [mediaVolume, setMediaVolume] = Internals8.useMediaVolumeState();
|
|
1460
1549
|
const [focused, setFocused] = useState6(false);
|
|
1461
1550
|
const parentDivRef = useRef6(null);
|
|
1462
1551
|
const inputRef = useRef6(null);
|
|
@@ -1517,7 +1606,7 @@ var MediaVolumeSlider = ({ displayVerticalVolumeSlider, renderMuteButton, render
|
|
|
1517
1606
|
return renderMuteButton ? renderMuteButton({ muted: mediaMuted, volume: mediaVolume }) : renderDefaultMuteButton({ muted: mediaMuted, volume: mediaVolume });
|
|
1518
1607
|
}, [mediaMuted, mediaVolume, renderDefaultMuteButton, renderMuteButton]);
|
|
1519
1608
|
const volumeSlider = useMemo4(() => {
|
|
1520
|
-
return (focused || hover) && !mediaMuted && !
|
|
1609
|
+
return (focused || hover) && !mediaMuted && !Internals8.isIosSafari() ? (renderVolumeSlider ?? renderDefaultVolumeSlider)({
|
|
1521
1610
|
isVertical: displayVerticalVolumeSlider,
|
|
1522
1611
|
volume: mediaVolume,
|
|
1523
1612
|
onBlur: () => setFocused(false),
|
|
@@ -1545,7 +1634,7 @@ var MediaVolumeSlider = ({ displayVerticalVolumeSlider, renderMuteButton, render
|
|
|
1545
1634
|
|
|
1546
1635
|
// src/PlaybackrateControl.tsx
|
|
1547
1636
|
import { useCallback as useCallback6, useEffect as useEffect9, useMemo as useMemo5, useState as useState8 } from "react";
|
|
1548
|
-
import { Internals as
|
|
1637
|
+
import { Internals as Internals9 } from "remotion";
|
|
1549
1638
|
|
|
1550
1639
|
// src/utils/use-component-visible.ts
|
|
1551
1640
|
import { useEffect as useEffect8, useRef as useRef7, useState as useState7 } from "react";
|
|
@@ -1637,7 +1726,7 @@ var PlaybackrateOption = ({ rate, onSelect, selectedRate, keyboardSelectedRate }
|
|
|
1637
1726
|
}, rate);
|
|
1638
1727
|
};
|
|
1639
1728
|
var PlaybackPopup = ({ setIsComponentVisible, playbackRates, canvasSize }) => {
|
|
1640
|
-
const { setPlaybackRate, playbackRate } =
|
|
1729
|
+
const { setPlaybackRate, playbackRate } = Internals9.useTimelineContext();
|
|
1641
1730
|
const [keyboardSelectedRate, setKeyboardSelectedRate] = useState8(playbackRate);
|
|
1642
1731
|
useEffect9(() => {
|
|
1643
1732
|
const listener = (e) => {
|
|
@@ -1739,7 +1828,7 @@ var button = {
|
|
|
1739
1828
|
};
|
|
1740
1829
|
var PlaybackrateControl = ({ playbackRates, canvasSize }) => {
|
|
1741
1830
|
const { ref, isComponentVisible, setIsComponentVisible } = useComponentVisible(false);
|
|
1742
|
-
const { playbackRate } =
|
|
1831
|
+
const { playbackRate } = Internals9.useTimelineContext();
|
|
1743
1832
|
const onClick = useCallback6((e) => {
|
|
1744
1833
|
e.stopPropagation();
|
|
1745
1834
|
e.preventDefault();
|
|
@@ -1772,7 +1861,7 @@ var PlaybackrateControl = ({ playbackRates, canvasSize }) => {
|
|
|
1772
1861
|
|
|
1773
1862
|
// src/PlayerSeekBar.tsx
|
|
1774
1863
|
import { useCallback as useCallback7, useEffect as useEffect10, useMemo as useMemo6, useRef as useRef8, useState as useState9 } from "react";
|
|
1775
|
-
import { Internals as
|
|
1864
|
+
import { Internals as Internals10, interpolate } from "remotion";
|
|
1776
1865
|
import { jsx as jsx10, jsxs as jsxs6 } from "react/jsx-runtime";
|
|
1777
1866
|
var getFrameFromX = (clientX, durationInFrames, width) => {
|
|
1778
1867
|
const pos = clientX;
|
|
@@ -1816,7 +1905,7 @@ var PlayerSeekBar = ({ durationInFrames, onSeekEnd, onSeekStart, inFrame, outFra
|
|
|
1816
1905
|
shouldApplyCssTransforms: true
|
|
1817
1906
|
});
|
|
1818
1907
|
const { seek, play, pause, playing } = usePlayer();
|
|
1819
|
-
const frame =
|
|
1908
|
+
const frame = Internals10.Timeline.useTimelinePosition();
|
|
1820
1909
|
const [dragging, setDragging] = useState9({
|
|
1821
1910
|
dragging: false
|
|
1822
1911
|
});
|
|
@@ -1929,7 +2018,7 @@ var PlayerSeekBar = ({ durationInFrames, onSeekEnd, onSeekStart, inFrame, outFra
|
|
|
1929
2018
|
|
|
1930
2019
|
// src/PlayerTimeLabel.tsx
|
|
1931
2020
|
import { useMemo as useMemo7 } from "react";
|
|
1932
|
-
import { Internals as
|
|
2021
|
+
import { Internals as Internals11 } from "remotion";
|
|
1933
2022
|
|
|
1934
2023
|
// src/format-time.ts
|
|
1935
2024
|
var formatTime = (timeInSeconds) => {
|
|
@@ -1941,7 +2030,7 @@ var formatTime = (timeInSeconds) => {
|
|
|
1941
2030
|
// src/PlayerTimeLabel.tsx
|
|
1942
2031
|
import { jsxs as jsxs7 } from "react/jsx-runtime";
|
|
1943
2032
|
var PlayerTimeLabel = ({ durationInFrames, maxTimeLabelWidth, fps }) => {
|
|
1944
|
-
const frame =
|
|
2033
|
+
const frame = Internals11.Timeline.useTimelinePosition();
|
|
1945
2034
|
const timeLabel = useMemo7(() => {
|
|
1946
2035
|
return {
|
|
1947
2036
|
color: "white",
|
|
@@ -2429,8 +2518,8 @@ var PlayerUI = ({
|
|
|
2429
2518
|
overrideInternalClassName,
|
|
2430
2519
|
noSuspense
|
|
2431
2520
|
}, ref) => {
|
|
2432
|
-
const config =
|
|
2433
|
-
const video =
|
|
2521
|
+
const config = Internals12.useUnsafeVideoConfig();
|
|
2522
|
+
const video = Internals12.useVideo();
|
|
2434
2523
|
const container = useRef11(null);
|
|
2435
2524
|
const canvasSize = useElementSize(container, {
|
|
2436
2525
|
triggerOnWindowResize: false,
|
|
@@ -2550,8 +2639,8 @@ var PlayerUI = ({
|
|
|
2550
2639
|
}
|
|
2551
2640
|
player.emitter.dispatchScaleChange(scale);
|
|
2552
2641
|
}, [player.emitter, scale]);
|
|
2553
|
-
const { setMediaVolume, setMediaMuted } = useContext5(
|
|
2554
|
-
const { mediaMuted, mediaVolume } = useContext5(
|
|
2642
|
+
const { setMediaVolume, setMediaMuted } = useContext5(Internals12.SetMediaVolumeContext);
|
|
2643
|
+
const { mediaMuted, mediaVolume } = useContext5(Internals12.MediaVolumeContext);
|
|
2555
2644
|
useEffect12(() => {
|
|
2556
2645
|
player.emitter.dispatchVolumeChange(mediaVolume);
|
|
2557
2646
|
}, [player.emitter, mediaVolume]);
|
|
@@ -2786,7 +2875,7 @@ var PlayerUI = ({
|
|
|
2786
2875
|
VideoComponent ? /* @__PURE__ */ jsx12(ErrorBoundary, {
|
|
2787
2876
|
onError,
|
|
2788
2877
|
errorFallback,
|
|
2789
|
-
children: /* @__PURE__ */ jsx12(
|
|
2878
|
+
children: /* @__PURE__ */ jsx12(Internals12.CurrentScaleContext.Provider, {
|
|
2790
2879
|
value: currentScale,
|
|
2791
2880
|
children: /* @__PURE__ */ jsx12(VideoComponent, {
|
|
2792
2881
|
...video?.props ?? {},
|
|
@@ -2869,10 +2958,10 @@ var PlayerUI_default = forwardRef(PlayerUI);
|
|
|
2869
2958
|
|
|
2870
2959
|
// src/SharedPlayerContext.tsx
|
|
2871
2960
|
import { useCallback as useCallback12, useMemo as useMemo13, useState as useState12 } from "react";
|
|
2872
|
-
import { Internals as
|
|
2961
|
+
import { Internals as Internals14 } from "remotion";
|
|
2873
2962
|
|
|
2874
2963
|
// src/volume-persistence.ts
|
|
2875
|
-
import { Internals as
|
|
2964
|
+
import { Internals as Internals13 } from "remotion";
|
|
2876
2965
|
var DEFAULT_VOLUME_PERSISTENCE_KEY = "remotion.volumePreference";
|
|
2877
2966
|
var persistVolume = (volume, logLevel, volumePersistenceKey) => {
|
|
2878
2967
|
if (typeof window === "undefined") {
|
|
@@ -2881,7 +2970,7 @@ var persistVolume = (volume, logLevel, volumePersistenceKey) => {
|
|
|
2881
2970
|
try {
|
|
2882
2971
|
window.localStorage.setItem(volumePersistenceKey ?? DEFAULT_VOLUME_PERSISTENCE_KEY, String(volume));
|
|
2883
2972
|
} catch (e) {
|
|
2884
|
-
|
|
2973
|
+
Internals13.Log.error({ logLevel, tag: null }, "Could not persist volume", e);
|
|
2885
2974
|
}
|
|
2886
2975
|
};
|
|
2887
2976
|
var getPreferredVolume = (volumePersistenceKey) => {
|
|
@@ -2991,29 +3080,31 @@ var SharedPlayerContexts = ({
|
|
|
2991
3080
|
isReadOnlyStudio: false
|
|
2992
3081
|
};
|
|
2993
3082
|
}, []);
|
|
2994
|
-
return /* @__PURE__ */ jsx13(
|
|
3083
|
+
return /* @__PURE__ */ jsx13(Internals14.RemotionEnvironmentContext.Provider, {
|
|
2995
3084
|
value: env,
|
|
2996
|
-
children: /* @__PURE__ */ jsx13(
|
|
3085
|
+
children: /* @__PURE__ */ jsx13(Internals14.LogLevelContext.Provider, {
|
|
2997
3086
|
value: logLevelContext,
|
|
2998
|
-
children: /* @__PURE__ */ jsx13(
|
|
2999
|
-
children: /* @__PURE__ */ jsx13(
|
|
3087
|
+
children: /* @__PURE__ */ jsx13(Internals14.CanUseRemotionHooksProvider, {
|
|
3088
|
+
children: /* @__PURE__ */ jsx13(Internals14.AbsoluteTimeContext.Provider, {
|
|
3000
3089
|
value: timelineContext,
|
|
3001
|
-
children: /* @__PURE__ */ jsx13(
|
|
3090
|
+
children: /* @__PURE__ */ jsx13(Internals14.TimelineContext.Provider, {
|
|
3002
3091
|
value: timelineContext,
|
|
3003
|
-
children: /* @__PURE__ */ jsx13(
|
|
3092
|
+
children: /* @__PURE__ */ jsx13(Internals14.CompositionManager.Provider, {
|
|
3004
3093
|
value: compositionManagerContext,
|
|
3005
|
-
children: /* @__PURE__ */ jsx13(
|
|
3006
|
-
children: /* @__PURE__ */ jsx13(
|
|
3007
|
-
children: /* @__PURE__ */ jsx13(
|
|
3094
|
+
children: /* @__PURE__ */ jsx13(Internals14.PrefetchProvider, {
|
|
3095
|
+
children: /* @__PURE__ */ jsx13(Internals14.DurationsContextProvider, {
|
|
3096
|
+
children: /* @__PURE__ */ jsx13(Internals14.MediaVolumeContext.Provider, {
|
|
3008
3097
|
value: mediaVolumeContextValue,
|
|
3009
|
-
children: /* @__PURE__ */ jsx13(
|
|
3098
|
+
children: /* @__PURE__ */ jsx13(Internals14.SetMediaVolumeContext.Provider, {
|
|
3010
3099
|
value: setMediaVolumeContextValue,
|
|
3011
|
-
children: /* @__PURE__ */ jsx13(
|
|
3012
|
-
|
|
3013
|
-
|
|
3014
|
-
|
|
3015
|
-
|
|
3016
|
-
|
|
3100
|
+
children: /* @__PURE__ */ jsx13(Internals14.BufferingProvider, {
|
|
3101
|
+
children: /* @__PURE__ */ jsx13(Internals14.SharedAudioContextProvider, {
|
|
3102
|
+
audioLatencyHint,
|
|
3103
|
+
audioEnabled,
|
|
3104
|
+
children: /* @__PURE__ */ jsx13(Internals14.SharedAudioTagsContextProvider, {
|
|
3105
|
+
numberOfAudioTags: numberOfSharedAudioTags,
|
|
3106
|
+
children
|
|
3107
|
+
})
|
|
3017
3108
|
})
|
|
3018
3109
|
})
|
|
3019
3110
|
})
|
|
@@ -3029,7 +3120,7 @@ var SharedPlayerContexts = ({
|
|
|
3029
3120
|
};
|
|
3030
3121
|
|
|
3031
3122
|
// src/use-remotion-license-acknowledge.ts
|
|
3032
|
-
import { Internals as
|
|
3123
|
+
import { Internals as Internals15 } from "remotion";
|
|
3033
3124
|
var warningShown = false;
|
|
3034
3125
|
var acknowledgeRemotionLicenseMessage = (acknowledge, logLevel) => {
|
|
3035
3126
|
if (acknowledge) {
|
|
@@ -3039,7 +3130,7 @@ var acknowledgeRemotionLicenseMessage = (acknowledge, logLevel) => {
|
|
|
3039
3130
|
return;
|
|
3040
3131
|
}
|
|
3041
3132
|
warningShown = true;
|
|
3042
|
-
|
|
3133
|
+
Internals15.Log.warn({ logLevel, tag: null }, "Note: Some companies are required to obtain a license to use Remotion. See: https://remotion.dev/license\nPass the `acknowledgeRemotionLicense` prop to `<Player />` function to make this message disappear.");
|
|
3043
3134
|
};
|
|
3044
3135
|
|
|
3045
3136
|
// src/utils/validate-in-out-frame.ts
|
|
@@ -3121,11 +3212,11 @@ var validatePlaybackRate = (playbackRate) => {
|
|
|
3121
3212
|
if (playbackRate === undefined) {
|
|
3122
3213
|
return;
|
|
3123
3214
|
}
|
|
3124
|
-
if (playbackRate >
|
|
3125
|
-
throw new Error(`The highest possible playback rate is
|
|
3215
|
+
if (playbackRate > 10) {
|
|
3216
|
+
throw new Error(`The highest possible playback rate is 10. You passed: ${playbackRate}`);
|
|
3126
3217
|
}
|
|
3127
|
-
if (playbackRate < -
|
|
3128
|
-
throw new Error(`The lowest possible playback rate is -
|
|
3218
|
+
if (playbackRate < -10) {
|
|
3219
|
+
throw new Error(`The lowest possible playback rate is -10. You passed: ${playbackRate}`);
|
|
3129
3220
|
}
|
|
3130
3221
|
if (playbackRate === 0) {
|
|
3131
3222
|
throw new Error(`A playback rate of 0 is not supported.`);
|
|
@@ -3195,7 +3286,7 @@ var PlayerFn = ({
|
|
|
3195
3286
|
logLevel = "info",
|
|
3196
3287
|
noSuspense,
|
|
3197
3288
|
acknowledgeRemotionLicense,
|
|
3198
|
-
audioLatencyHint = "
|
|
3289
|
+
audioLatencyHint = "playback",
|
|
3199
3290
|
volumePersistenceKey,
|
|
3200
3291
|
...componentProps
|
|
3201
3292
|
}, ref) => {
|
|
@@ -3213,7 +3304,7 @@ var PlayerFn = ({
|
|
|
3213
3304
|
throw new TypeError(`'component' must not be the 'Composition' component. Pass your own React component directly, and set the duration, fps and dimensions as separate props. See https://www.remotion.dev/docs/player/examples for an example.`);
|
|
3214
3305
|
}
|
|
3215
3306
|
useState13(() => acknowledgeRemotionLicenseMessage(Boolean(acknowledgeRemotionLicense), logLevel));
|
|
3216
|
-
const component =
|
|
3307
|
+
const component = Internals16.useLazyComponent({
|
|
3217
3308
|
compProps: componentProps,
|
|
3218
3309
|
componentName: "Player",
|
|
3219
3310
|
noSuspense: Boolean(noSuspense)
|
|
@@ -3280,7 +3371,7 @@ var PlayerFn = ({
|
|
|
3280
3371
|
}, [playbackRate]);
|
|
3281
3372
|
useImperativeHandle2(ref, () => rootRef.current, []);
|
|
3282
3373
|
useState13(() => {
|
|
3283
|
-
|
|
3374
|
+
Internals16.playbackLogging({
|
|
3284
3375
|
logLevel,
|
|
3285
3376
|
message: `[player] Mounting <Player>. User agent = ${typeof navigator === "undefined" ? "server" : navigator.userAgent}`,
|
|
3286
3377
|
tag: "player",
|
|
@@ -3307,8 +3398,8 @@ var PlayerFn = ({
|
|
|
3307
3398
|
};
|
|
3308
3399
|
}, [setFrame]);
|
|
3309
3400
|
if (typeof window !== "undefined") {
|
|
3310
|
-
|
|
3311
|
-
|
|
3401
|
+
useLayoutEffect3(() => {
|
|
3402
|
+
Internals16.CSSUtils.injectCSS(Internals16.CSSUtils.makeDefaultPreviewCSS(`.${playerCssClassname(overrideInternalClassName)}`, "#fff"));
|
|
3312
3403
|
}, [overrideInternalClassName]);
|
|
3313
3404
|
}
|
|
3314
3405
|
const actualInputProps = useMemo14(() => inputProps ?? {}, [inputProps]);
|
|
@@ -3317,7 +3408,7 @@ var PlayerFn = ({
|
|
|
3317
3408
|
mode: "prevent-media-session"
|
|
3318
3409
|
};
|
|
3319
3410
|
}, [passedBrowserMediaControlsBehavior]);
|
|
3320
|
-
return /* @__PURE__ */ jsx14(
|
|
3411
|
+
return /* @__PURE__ */ jsx14(Internals16.IsPlayerContextProvider, {
|
|
3321
3412
|
children: /* @__PURE__ */ jsx14(SharedPlayerContexts, {
|
|
3322
3413
|
timelineContext: timelineContextValue,
|
|
3323
3414
|
component,
|
|
@@ -3332,7 +3423,7 @@ var PlayerFn = ({
|
|
|
3332
3423
|
volumePersistenceKey,
|
|
3333
3424
|
inputProps: actualInputProps,
|
|
3334
3425
|
audioEnabled: true,
|
|
3335
|
-
children: /* @__PURE__ */ jsx14(
|
|
3426
|
+
children: /* @__PURE__ */ jsx14(Internals16.SetTimelineContext.Provider, {
|
|
3336
3427
|
value: setTimelineContextValue,
|
|
3337
3428
|
children: /* @__PURE__ */ jsx14(PlayerEmitterProvider, {
|
|
3338
3429
|
currentPlaybackRate,
|
|
@@ -3388,12 +3479,12 @@ var Player = forward(PlayerFn);
|
|
|
3388
3479
|
import {
|
|
3389
3480
|
forwardRef as forwardRef4,
|
|
3390
3481
|
useImperativeHandle as useImperativeHandle4,
|
|
3391
|
-
useLayoutEffect as
|
|
3482
|
+
useLayoutEffect as useLayoutEffect4,
|
|
3392
3483
|
useMemo as useMemo17,
|
|
3393
3484
|
useRef as useRef14,
|
|
3394
3485
|
useState as useState14
|
|
3395
3486
|
} from "react";
|
|
3396
|
-
import { Internals as
|
|
3487
|
+
import { Internals as Internals18, random as random2 } from "remotion";
|
|
3397
3488
|
|
|
3398
3489
|
// src/ThumbnailUI.tsx
|
|
3399
3490
|
import React13, {
|
|
@@ -3404,7 +3495,7 @@ import React13, {
|
|
|
3404
3495
|
useMemo as useMemo16,
|
|
3405
3496
|
useRef as useRef13
|
|
3406
3497
|
} from "react";
|
|
3407
|
-
import { Internals as
|
|
3498
|
+
import { Internals as Internals17 } from "remotion";
|
|
3408
3499
|
|
|
3409
3500
|
// src/use-thumbnail.ts
|
|
3410
3501
|
import { useContext as useContext6, useMemo as useMemo15 } from "react";
|
|
@@ -3438,8 +3529,8 @@ var ThumbnailUI = ({
|
|
|
3438
3529
|
noSuspense,
|
|
3439
3530
|
overrideInternalClassName
|
|
3440
3531
|
}, ref) => {
|
|
3441
|
-
const config =
|
|
3442
|
-
const video =
|
|
3532
|
+
const config = Internals17.useUnsafeVideoConfig();
|
|
3533
|
+
const video = Internals17.useVideo();
|
|
3443
3534
|
const container = useRef13(null);
|
|
3444
3535
|
const canvasSize = useElementSize(container, {
|
|
3445
3536
|
triggerOnWindowResize: false,
|
|
@@ -3514,7 +3605,7 @@ var ThumbnailUI = ({
|
|
|
3514
3605
|
children: VideoComponent ? /* @__PURE__ */ jsx15(ErrorBoundary, {
|
|
3515
3606
|
onError,
|
|
3516
3607
|
errorFallback,
|
|
3517
|
-
children: /* @__PURE__ */ jsx15(
|
|
3608
|
+
children: /* @__PURE__ */ jsx15(Internals17.CurrentScaleContext.Provider, {
|
|
3518
3609
|
value: currentScaleContext,
|
|
3519
3610
|
children: /* @__PURE__ */ jsx15(VideoComponent, {
|
|
3520
3611
|
...video?.props ?? {},
|
|
@@ -3564,7 +3655,7 @@ var ThumbnailFn = ({
|
|
|
3564
3655
|
...componentProps
|
|
3565
3656
|
}, ref) => {
|
|
3566
3657
|
if (typeof window !== "undefined") {
|
|
3567
|
-
|
|
3658
|
+
useLayoutEffect4(() => {
|
|
3568
3659
|
window.remotion_isPlayer = true;
|
|
3569
3660
|
}, []);
|
|
3570
3661
|
}
|
|
@@ -3589,7 +3680,7 @@ var ThumbnailFn = ({
|
|
|
3589
3680
|
return value;
|
|
3590
3681
|
}, [frameToDisplay, thumbnailId]);
|
|
3591
3682
|
useImperativeHandle4(ref, () => rootRef.current, []);
|
|
3592
|
-
const Component =
|
|
3683
|
+
const Component = Internals18.useLazyComponent({
|
|
3593
3684
|
compProps: componentProps,
|
|
3594
3685
|
componentName: "Thumbnail",
|
|
3595
3686
|
noSuspense: Boolean(noSuspense)
|
|
@@ -3598,7 +3689,7 @@ var ThumbnailFn = ({
|
|
|
3598
3689
|
const passedInputProps = useMemo17(() => {
|
|
3599
3690
|
return inputProps ?? {};
|
|
3600
3691
|
}, [inputProps]);
|
|
3601
|
-
return /* @__PURE__ */ jsx16(
|
|
3692
|
+
return /* @__PURE__ */ jsx16(Internals18.IsPlayerContextProvider, {
|
|
3602
3693
|
children: /* @__PURE__ */ jsx16(SharedPlayerContexts, {
|
|
3603
3694
|
timelineContext: timelineState,
|
|
3604
3695
|
component: Component,
|
package/package.json
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
"url": "https://github.com/remotion-dev/remotion/tree/main/packages/player"
|
|
4
4
|
},
|
|
5
5
|
"name": "@remotion/player",
|
|
6
|
-
"version": "4.0.
|
|
6
|
+
"version": "4.0.452",
|
|
7
7
|
"description": "React component for embedding a Remotion preview into your app",
|
|
8
8
|
"main": "dist/cjs/index.js",
|
|
9
9
|
"types": "dist/cjs/index.d.ts",
|
|
@@ -36,7 +36,7 @@
|
|
|
36
36
|
],
|
|
37
37
|
"license": "SEE LICENSE IN LICENSE.md",
|
|
38
38
|
"dependencies": {
|
|
39
|
-
"remotion": "4.0.
|
|
39
|
+
"remotion": "4.0.452"
|
|
40
40
|
},
|
|
41
41
|
"peerDependencies": {
|
|
42
42
|
"react": ">=16.8.0",
|
|
@@ -50,7 +50,7 @@
|
|
|
50
50
|
"react-dom": "19.2.3",
|
|
51
51
|
"webpack": "5.105.0",
|
|
52
52
|
"zod": "4.3.6",
|
|
53
|
-
"@remotion/eslint-config-internal": "4.0.
|
|
53
|
+
"@remotion/eslint-config-internal": "4.0.452",
|
|
54
54
|
"eslint": "9.19.0",
|
|
55
55
|
"@typescript/native-preview": "7.0.0-dev.20260217.1"
|
|
56
56
|
},
|