@remotion/player 4.0.110 → 4.0.112
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.rollup.cache/Users/jonathanburger/remotion/packages/player/dist/esm/Player.d.ts +2 -0
- package/.rollup.cache/Users/jonathanburger/remotion/packages/player/dist/esm/Player.js +4 -9
- package/.rollup.cache/Users/jonathanburger/remotion/packages/player/dist/esm/PlayerControls.d.ts +3 -1
- package/.rollup.cache/Users/jonathanburger/remotion/packages/player/dist/esm/PlayerControls.js +8 -5
- package/.rollup.cache/Users/jonathanburger/remotion/packages/player/dist/esm/PlayerUI.d.ts +3 -0
- package/.rollup.cache/Users/jonathanburger/remotion/packages/player/dist/esm/PlayerUI.js +51 -4
- package/.rollup.cache/Users/jonathanburger/remotion/packages/player/dist/esm/SharedPlayerContext.js +1 -1
- package/.rollup.cache/Users/jonathanburger/remotion/packages/player/dist/esm/ThumbnailUI.js +8 -1
- package/.rollup.cache/Users/jonathanburger/remotion/packages/player/dist/esm/calculate-scale.d.ts +1 -8
- package/.rollup.cache/Users/jonathanburger/remotion/packages/player/dist/esm/calculate-scale.js +2 -7
- package/.rollup.cache/Users/jonathanburger/remotion/packages/player/dist/esm/event-emitter.d.ts +6 -0
- package/.rollup.cache/Users/jonathanburger/remotion/packages/player/dist/esm/event-emitter.js +8 -0
- package/.rollup.cache/Users/jonathanburger/remotion/packages/player/dist/esm/icons.js +1 -1
- package/.rollup.cache/Users/jonathanburger/remotion/packages/player/dist/esm/index.d.ts +8 -7
- package/.rollup.cache/Users/jonathanburger/remotion/packages/player/dist/esm/index.js +5 -2
- package/.rollup.cache/Users/jonathanburger/remotion/packages/player/dist/esm/use-playback.js +35 -3
- package/.rollup.cache/Users/jonathanburger/remotion/packages/player/dist/esm/use-player.d.ts +1 -0
- package/.rollup.cache/Users/jonathanburger/remotion/packages/player/dist/esm/use-player.js +8 -1
- package/.rollup.cache/Users/jonathanburger/remotion/packages/player/dist/tsconfig-esm.tsbuildinfo +1 -1
- package/dist/cjs/Player.d.ts +2 -0
- package/dist/cjs/Player.js +4 -9
- package/dist/cjs/PlayerControls.d.ts +3 -1
- package/dist/cjs/PlayerControls.js +7 -4
- package/dist/cjs/PlayerUI.d.ts +3 -0
- package/dist/cjs/PlayerUI.js +51 -4
- package/dist/cjs/SharedPlayerContext.js +1 -1
- package/dist/cjs/ThumbnailUI.js +8 -1
- package/dist/cjs/calculate-scale.d.ts +1 -8
- package/dist/cjs/calculate-scale.js +3 -9
- package/dist/cjs/event-emitter.d.ts +6 -0
- package/dist/cjs/event-emitter.js +8 -0
- package/dist/cjs/icons.js +1 -1
- package/dist/cjs/index.d.ts +8 -8
- package/dist/cjs/index.js +4 -1
- package/dist/cjs/use-playback.js +34 -2
- package/dist/cjs/use-player.d.ts +1 -0
- package/dist/cjs/use-player.js +8 -1
- package/dist/esm/Player.d.ts +2 -0
- package/dist/esm/PlayerControls.d.ts +3 -1
- package/dist/esm/PlayerUI.d.ts +3 -0
- package/dist/esm/calculate-scale.d.ts +1 -8
- package/dist/esm/event-emitter.d.ts +6 -0
- package/dist/esm/index.d.ts +8 -7
- package/dist/esm/index.mjs +237 -69
- package/dist/esm/use-player.d.ts +1 -0
- package/package.json +2 -2
|
@@ -34,6 +34,7 @@ export type PlayerProps<Schema extends AnyZodObject, Props> = {
|
|
|
34
34
|
showPosterWhenPaused?: boolean;
|
|
35
35
|
showPosterWhenEnded?: boolean;
|
|
36
36
|
showPosterWhenUnplayed?: boolean;
|
|
37
|
+
showPosterWhenBuffering?: boolean;
|
|
37
38
|
inFrame?: number | null;
|
|
38
39
|
outFrame?: number | null;
|
|
39
40
|
initiallyShowControls?: number | boolean;
|
|
@@ -44,6 +45,7 @@ export type PlayerProps<Schema extends AnyZodObject, Props> = {
|
|
|
44
45
|
initiallyMuted?: boolean;
|
|
45
46
|
showPlaybackRateControl?: boolean | number[];
|
|
46
47
|
posterFillMode?: PosterFillMode;
|
|
48
|
+
bufferStateDelayInMilliseconds?: number;
|
|
47
49
|
} & CompProps<Props> & PropsIfHasProps<Schema, Props>;
|
|
48
50
|
export declare const componentOrNullIfLazy: <Props>(props: CompProps<Props>) => ComponentType<Props> | null;
|
|
49
51
|
/**
|
|
@@ -1,8 +1,7 @@
|
|
|
1
1
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
2
|
import { forwardRef, useEffect, useImperativeHandle, useLayoutEffect, useMemo, useRef, useState, } from 'react';
|
|
3
3
|
import { Composition, Internals } from 'remotion';
|
|
4
|
-
import {
|
|
5
|
-
import { PlayerEmitter } from './event-emitter.js';
|
|
4
|
+
import { PlayerEmitterProvider } from './EmitterProvider.js';
|
|
6
5
|
import { PLAYER_CSS_CLASSNAME } from './player-css-classname.js';
|
|
7
6
|
import PlayerUI from './PlayerUI.js';
|
|
8
7
|
import { PLAYER_COMP_ID, SharedPlayerContexts } from './SharedPlayerContext.js';
|
|
@@ -16,7 +15,7 @@ export const componentOrNullIfLazy = (props) => {
|
|
|
16
15
|
}
|
|
17
16
|
return null;
|
|
18
17
|
};
|
|
19
|
-
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, initialFrame, renderPoster, inFrame, outFrame, initiallyShowControls, renderFullscreenButton, renderPlayPauseButton, alwaysShowControls = false, initiallyMuted = false, showPlaybackRateControl = false, posterFillMode = 'player-size', ...componentProps }, ref) => {
|
|
18
|
+
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, initialFrame, renderPoster, inFrame, outFrame, initiallyShowControls, renderFullscreenButton, renderPlayPauseButton, alwaysShowControls = false, initiallyMuted = false, showPlaybackRateControl = false, posterFillMode = 'player-size', bufferStateDelayInMilliseconds, ...componentProps }, ref) => {
|
|
20
19
|
if (typeof window !== 'undefined') {
|
|
21
20
|
// eslint-disable-next-line react-hooks/rules-of-hooks
|
|
22
21
|
useLayoutEffect(() => {
|
|
@@ -42,7 +41,6 @@ const PlayerFn = ({ durationInFrames, compositionHeight, compositionWidth, fps,
|
|
|
42
41
|
}));
|
|
43
42
|
const [playing, setPlaying] = useState(false);
|
|
44
43
|
const [rootId] = useState('player-comp');
|
|
45
|
-
const [emitter] = useState(() => new PlayerEmitter());
|
|
46
44
|
const rootRef = useRef(null);
|
|
47
45
|
const audioAndVideoTags = useRef([]);
|
|
48
46
|
const imperativePlaying = useRef(false);
|
|
@@ -102,9 +100,6 @@ const PlayerFn = ({ durationInFrames, compositionHeight, compositionWidth, fps,
|
|
|
102
100
|
throw new TypeError(`'numberOfSharedAudioTags' must be an integer but got '${numberOfSharedAudioTags}' instead`);
|
|
103
101
|
}
|
|
104
102
|
validatePlaybackRate(currentPlaybackRate);
|
|
105
|
-
useEffect(() => {
|
|
106
|
-
emitter.dispatchRateChange(currentPlaybackRate);
|
|
107
|
-
}, [emitter, currentPlaybackRate]);
|
|
108
103
|
useEffect(() => {
|
|
109
104
|
setCurrentPlaybackRate(playbackRate);
|
|
110
105
|
}, [playbackRate]);
|
|
@@ -136,9 +131,9 @@ const PlayerFn = ({ durationInFrames, compositionHeight, compositionWidth, fps,
|
|
|
136
131
|
}, []);
|
|
137
132
|
}
|
|
138
133
|
const actualInputProps = useMemo(() => inputProps !== null && inputProps !== void 0 ? inputProps : {}, [inputProps]);
|
|
139
|
-
return (_jsx(Internals.IsPlayerContextProvider, { children: _jsx(SharedPlayerContexts, { timelineContext: timelineContextValue, component: component, compositionHeight: compositionHeight, compositionWidth: compositionWidth, durationInFrames: durationInFrames, fps: fps, numberOfSharedAudioTags: numberOfSharedAudioTags, initiallyMuted: initiallyMuted, children: _jsx(Internals.Timeline.SetTimelineContext.Provider, { value: setTimelineContextValue, children: _jsx(
|
|
134
|
+
return (_jsx(Internals.IsPlayerContextProvider, { children: _jsx(SharedPlayerContexts, { timelineContext: timelineContextValue, component: component, compositionHeight: compositionHeight, compositionWidth: compositionWidth, durationInFrames: durationInFrames, fps: fps, numberOfSharedAudioTags: numberOfSharedAudioTags, initiallyMuted: initiallyMuted, children: _jsx(Internals.Timeline.SetTimelineContext.Provider, { value: setTimelineContextValue, children: _jsx(PlayerEmitterProvider, { currentPlaybackRate: currentPlaybackRate, children: _jsx(PlayerUI, { ref: rootRef, posterFillMode: posterFillMode, renderLoading: renderLoading, autoPlay: Boolean(autoPlay), loop: Boolean(loop), controls: Boolean(controls), errorFallback: errorFallback, style: style, inputProps: actualInputProps, allowFullscreen: Boolean(allowFullscreen), moveToBeginningWhenEnded: Boolean(moveToBeginningWhenEnded), clickToPlay: typeof clickToPlay === 'boolean'
|
|
140
135
|
? clickToPlay
|
|
141
|
-
: Boolean(controls), showVolumeControls: Boolean(showVolumeControls), doubleClickToFullscreen: Boolean(doubleClickToFullscreen), spaceKeyToPlayOrPause: Boolean(spaceKeyToPlayOrPause), playbackRate: currentPlaybackRate, className: className !== null && className !== void 0 ? className : undefined, showPosterWhenUnplayed: Boolean(showPosterWhenUnplayed), showPosterWhenEnded: Boolean(showPosterWhenEnded), showPosterWhenPaused: Boolean(showPosterWhenPaused), renderPoster: renderPoster, inFrame: inFrame !== null && inFrame !== void 0 ? inFrame : null, outFrame: outFrame !== null && outFrame !== void 0 ? outFrame : null, initiallyShowControls: initiallyShowControls !== null && initiallyShowControls !== void 0 ? initiallyShowControls : true, renderFullscreen: renderFullscreenButton !== null && renderFullscreenButton !== void 0 ? renderFullscreenButton : null, renderPlayPauseButton: renderPlayPauseButton !== null && renderPlayPauseButton !== void 0 ? renderPlayPauseButton : null, alwaysShowControls: alwaysShowControls, showPlaybackRateControl: showPlaybackRateControl }) }) }) }) }));
|
|
136
|
+
: Boolean(controls), showVolumeControls: Boolean(showVolumeControls), doubleClickToFullscreen: Boolean(doubleClickToFullscreen), spaceKeyToPlayOrPause: Boolean(spaceKeyToPlayOrPause), playbackRate: currentPlaybackRate, className: className !== null && className !== void 0 ? className : undefined, showPosterWhenUnplayed: Boolean(showPosterWhenUnplayed), showPosterWhenEnded: Boolean(showPosterWhenEnded), showPosterWhenPaused: Boolean(showPosterWhenPaused), showPosterWhenBuffering: Boolean(showPosterWhenBuffering), renderPoster: renderPoster, inFrame: inFrame !== null && inFrame !== void 0 ? inFrame : null, outFrame: outFrame !== null && outFrame !== void 0 ? outFrame : null, initiallyShowControls: initiallyShowControls !== null && initiallyShowControls !== void 0 ? initiallyShowControls : true, renderFullscreen: renderFullscreenButton !== null && renderFullscreenButton !== void 0 ? renderFullscreenButton : null, renderPlayPauseButton: renderPlayPauseButton !== null && renderPlayPauseButton !== void 0 ? renderPlayPauseButton : null, alwaysShowControls: alwaysShowControls, showPlaybackRateControl: showPlaybackRateControl, bufferStateDelayInMilliseconds: bufferStateDelayInMilliseconds !== null && bufferStateDelayInMilliseconds !== void 0 ? bufferStateDelayInMilliseconds : 300 }) }) }) }) }));
|
|
142
137
|
};
|
|
143
138
|
const forward = forwardRef;
|
|
144
139
|
/**
|
package/.rollup.cache/Users/jonathanburger/remotion/packages/player/dist/esm/PlayerControls.d.ts
CHANGED
|
@@ -4,7 +4,8 @@ import type { usePlayer } from './use-player.js';
|
|
|
4
4
|
import type { Size } from './utils/use-element-size.js';
|
|
5
5
|
export type RenderPlayPauseButton = (props: {
|
|
6
6
|
playing: boolean;
|
|
7
|
-
|
|
7
|
+
isBuffering: boolean;
|
|
8
|
+
}) => ReactNode | null;
|
|
8
9
|
export type RenderFullscreenButton = (props: {
|
|
9
10
|
isFullscreen: boolean;
|
|
10
11
|
}) => ReactNode;
|
|
@@ -39,4 +40,5 @@ export declare const Controls: React.FC<{
|
|
|
39
40
|
alwaysShowControls: boolean;
|
|
40
41
|
showPlaybackRateControl: boolean | number[];
|
|
41
42
|
containerRef: React.RefObject<HTMLDivElement>;
|
|
43
|
+
buffering: boolean;
|
|
42
44
|
}>;
|
package/.rollup.cache/Users/jonathanburger/remotion/packages/player/dist/esm/PlayerControls.js
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
2
|
import { useEffect, useMemo, useRef, useState } from 'react';
|
|
3
3
|
import { Internals } from 'remotion';
|
|
4
|
+
import { DefaultPlayPauseButton } from './DefaultPlayPauseButton.js';
|
|
4
5
|
import { formatTime } from './format-time.js';
|
|
5
|
-
import { FullscreenIcon
|
|
6
|
+
import { FullscreenIcon } from './icons.js';
|
|
6
7
|
import { MediaVolumeSlider } from './MediaVolumeSlider.js';
|
|
7
8
|
import { PlaybackrateControl, playerButtonStyle } from './PlaybackrateControl.js';
|
|
8
9
|
import { PlayerSeekBar } from './PlayerSeekBar.js';
|
|
@@ -60,9 +61,8 @@ const flex1 = {
|
|
|
60
61
|
flex: 1,
|
|
61
62
|
};
|
|
62
63
|
const fullscreen = {};
|
|
63
|
-
const
|
|
64
|
-
|
|
65
|
-
var _a;
|
|
64
|
+
export const Controls = ({ durationInFrames, isFullscreen, fps, player, showVolumeControls, onFullscreenButtonClick, allowFullscreen, onExitFullscreenButtonClick, spaceKeyToPlayOrPause, onSeekEnd, onSeekStart, inFrame, outFrame, initiallyShowControls, canvasSize, renderPlayPauseButton, renderFullscreenButton, alwaysShowControls, showPlaybackRateControl, containerRef, buffering, }) => {
|
|
65
|
+
var _a, _b;
|
|
66
66
|
const playButtonRef = useRef(null);
|
|
67
67
|
const frame = Internals.Timeline.useTimelinePosition();
|
|
68
68
|
const [supportsFullscreen, setSupportsFullscreen] = useState(false);
|
|
@@ -153,7 +153,10 @@ export const Controls = ({ durationInFrames, isFullscreen, fps, player, showVolu
|
|
|
153
153
|
}
|
|
154
154
|
return null;
|
|
155
155
|
}, [showPlaybackRateControl]);
|
|
156
|
-
return (_jsxs("div", { style: containerCss, children: [_jsxs("div", { style: controlsRow, children: [_jsxs("div", { style: leftPartStyle, children: [_jsx("button", { ref: playButtonRef, type: "button", style: playerButtonStyle, onClick: player.playing ? player.pause : player.play, "aria-label": player.playing ? 'Pause video' : 'Play video', title: player.playing ? 'Pause video' : 'Play video', children: renderPlayPauseButton === null ? (_jsx(
|
|
156
|
+
return (_jsxs("div", { style: containerCss, children: [_jsxs("div", { style: controlsRow, children: [_jsxs("div", { style: leftPartStyle, children: [_jsx("button", { ref: playButtonRef, type: "button", style: playerButtonStyle, onClick: player.playing ? player.pause : player.play, "aria-label": player.playing ? 'Pause video' : 'Play video', title: player.playing ? 'Pause video' : 'Play video', children: renderPlayPauseButton === null ? (_jsx(DefaultPlayPauseButton, { buffering: buffering, playing: player.playing })) : ((_b = renderPlayPauseButton({
|
|
157
|
+
playing: player.playing,
|
|
158
|
+
isBuffering: buffering,
|
|
159
|
+
})) !== null && _b !== void 0 ? _b : (_jsx(DefaultPlayPauseButton, { buffering: buffering, playing: player.playing }))) }), showVolumeControls ? (_jsxs(_Fragment, { children: [_jsx("div", { style: xSpacer }), _jsx(MediaVolumeSlider, { displayVerticalVolumeSlider: displayVerticalVolumeSlider })] })) : null, _jsx("div", { style: xSpacer }), _jsxs("div", { style: timeLabel, children: [formatTime(frame / fps), " / ", formatTime(durationInFrames / fps)] }), _jsx("div", { style: xSpacer })] }), _jsx("div", { style: flex1 }), playbackRates && canvasSize && (_jsx(PlaybackrateControl, { canvasSize: canvasSize, playbackRates: playbackRates })), playbackRates && supportsFullscreen && allowFullscreen ? (_jsx("div", { style: xSpacer })) : null, _jsx("div", { style: fullscreen, children: supportsFullscreen && allowFullscreen ? (_jsx("button", { type: "button", "aria-label": isFullscreen ? 'Exit fullscreen' : 'Enter Fullscreen', title: isFullscreen ? 'Exit fullscreen' : 'Enter Fullscreen', style: playerButtonStyle, onClick: isFullscreen
|
|
157
160
|
? onExitFullscreenButtonClick
|
|
158
161
|
: onFullscreenButtonClick, children: renderFullscreenButton === null ? (_jsx(FullscreenIcon, { isFullscreen: isFullscreen })) : (renderFullscreenButton({ isFullscreen })) })) : null })] }), _jsx("div", { style: ySpacer }), _jsx(PlayerSeekBar, { onSeekEnd: onSeekEnd, onSeekStart: onSeekStart, durationInFrames: durationInFrames, inFrame: inFrame, outFrame: outFrame })] }));
|
|
159
162
|
};
|
|
@@ -7,6 +7,7 @@ export type ErrorFallback = (info: {
|
|
|
7
7
|
export type RenderLoading = (canvas: {
|
|
8
8
|
height: number;
|
|
9
9
|
width: number;
|
|
10
|
+
isBuffering: boolean;
|
|
10
11
|
}) => React.ReactNode;
|
|
11
12
|
export type RenderPoster = RenderLoading;
|
|
12
13
|
export type PosterFillMode = 'player-size' | 'composition-size';
|
|
@@ -30,6 +31,7 @@ declare const _default: React.ForwardRefExoticComponent<{
|
|
|
30
31
|
showPosterWhenPaused: boolean;
|
|
31
32
|
showPosterWhenEnded: boolean;
|
|
32
33
|
showPosterWhenUnplayed: boolean;
|
|
34
|
+
showPosterWhenBuffering: boolean;
|
|
33
35
|
inFrame: number | null;
|
|
34
36
|
outFrame: number | null;
|
|
35
37
|
initiallyShowControls: number | boolean;
|
|
@@ -38,5 +40,6 @@ declare const _default: React.ForwardRefExoticComponent<{
|
|
|
38
40
|
alwaysShowControls: boolean;
|
|
39
41
|
showPlaybackRateControl: boolean | number[];
|
|
40
42
|
posterFillMode: PosterFillMode;
|
|
43
|
+
bufferStateDelayInMilliseconds: number;
|
|
41
44
|
} & React.RefAttributes<PlayerRef>>;
|
|
42
45
|
export default _default;
|
|
@@ -15,7 +15,7 @@ if (reactVersion === '0') {
|
|
|
15
15
|
throw new Error(`Version ${reactVersion} of "react" is not supported by Remotion`);
|
|
16
16
|
}
|
|
17
17
|
const doesReactVersionSupportSuspense = parseInt(reactVersion, 10) >= 18;
|
|
18
|
-
const PlayerUI = ({ controls, style, loop, autoPlay, allowFullscreen, inputProps, clickToPlay, showVolumeControls, doubleClickToFullscreen, spaceKeyToPlayOrPause, errorFallback, playbackRate, renderLoading, renderPoster, className, moveToBeginningWhenEnded, showPosterWhenUnplayed, showPosterWhenEnded, showPosterWhenPaused, inFrame, outFrame, initiallyShowControls, renderFullscreen: renderFullscreenButton, renderPlayPauseButton, alwaysShowControls, showPlaybackRateControl, posterFillMode, }, ref) => {
|
|
18
|
+
const PlayerUI = ({ controls, style, loop, autoPlay, allowFullscreen, inputProps, clickToPlay, showVolumeControls, doubleClickToFullscreen, spaceKeyToPlayOrPause, errorFallback, playbackRate, renderLoading, renderPoster, className, moveToBeginningWhenEnded, showPosterWhenUnplayed, showPosterWhenEnded, showPosterWhenPaused, showPosterWhenBuffering, inFrame, outFrame, initiallyShowControls, renderFullscreen: renderFullscreenButton, renderPlayPauseButton, alwaysShowControls, showPlaybackRateControl, posterFillMode, bufferStateDelayInMilliseconds, }, ref) => {
|
|
19
19
|
var _a, _b, _c;
|
|
20
20
|
const config = Internals.useUnsafeVideoConfig();
|
|
21
21
|
const video = Internals.useVideo();
|
|
@@ -151,6 +151,44 @@ const PlayerUI = ({ controls, style, loop, autoPlay, allowFullscreen, inputProps
|
|
|
151
151
|
isMuted,
|
|
152
152
|
});
|
|
153
153
|
}, [player.emitter, isMuted]);
|
|
154
|
+
const [showBufferIndicator, setShowBufferState] = useState(false);
|
|
155
|
+
useEffect(() => {
|
|
156
|
+
let timeout = null;
|
|
157
|
+
let stopped = false;
|
|
158
|
+
const onBuffer = () => {
|
|
159
|
+
requestAnimationFrame(() => {
|
|
160
|
+
if (bufferStateDelayInMilliseconds === 0) {
|
|
161
|
+
setShowBufferState(true);
|
|
162
|
+
}
|
|
163
|
+
else {
|
|
164
|
+
timeout = setTimeout(() => {
|
|
165
|
+
if (!stopped) {
|
|
166
|
+
setShowBufferState(true);
|
|
167
|
+
}
|
|
168
|
+
}, bufferStateDelayInMilliseconds);
|
|
169
|
+
}
|
|
170
|
+
});
|
|
171
|
+
};
|
|
172
|
+
const onResume = () => {
|
|
173
|
+
requestAnimationFrame(() => {
|
|
174
|
+
setShowBufferState(false);
|
|
175
|
+
if (timeout) {
|
|
176
|
+
clearTimeout(timeout);
|
|
177
|
+
}
|
|
178
|
+
});
|
|
179
|
+
};
|
|
180
|
+
player.emitter.addEventListener('waiting', onBuffer);
|
|
181
|
+
player.emitter.addEventListener('resume', onResume);
|
|
182
|
+
return () => {
|
|
183
|
+
player.emitter.removeEventListener('waiting', onBuffer);
|
|
184
|
+
player.emitter.removeEventListener('resume', onResume);
|
|
185
|
+
setShowBufferState(false);
|
|
186
|
+
if (timeout) {
|
|
187
|
+
clearTimeout(timeout);
|
|
188
|
+
}
|
|
189
|
+
stopped = true;
|
|
190
|
+
};
|
|
191
|
+
}, [bufferStateDelayInMilliseconds, player.emitter]);
|
|
154
192
|
useImperativeHandle(ref, () => {
|
|
155
193
|
const methods = {
|
|
156
194
|
play: player.play,
|
|
@@ -278,9 +316,16 @@ const PlayerUI = ({ controls, style, loop, autoPlay, allowFullscreen, inputProps
|
|
|
278
316
|
? renderLoading({
|
|
279
317
|
height: outerStyle.height,
|
|
280
318
|
width: outerStyle.width,
|
|
319
|
+
isBuffering: showBufferIndicator,
|
|
281
320
|
})
|
|
282
321
|
: null;
|
|
283
|
-
}, [outerStyle.height, outerStyle.width, renderLoading]);
|
|
322
|
+
}, [outerStyle.height, outerStyle.width, renderLoading, showBufferIndicator]);
|
|
323
|
+
const currentScale = useMemo(() => {
|
|
324
|
+
return {
|
|
325
|
+
type: 'scale',
|
|
326
|
+
scale,
|
|
327
|
+
};
|
|
328
|
+
}, [scale]);
|
|
284
329
|
if (!config) {
|
|
285
330
|
return null;
|
|
286
331
|
}
|
|
@@ -292,6 +337,7 @@ const PlayerUI = ({ controls, style, loop, autoPlay, allowFullscreen, inputProps
|
|
|
292
337
|
width: posterFillMode === 'player-size'
|
|
293
338
|
? outerStyle.width
|
|
294
339
|
: config.width,
|
|
340
|
+
isBuffering: showBufferIndicator,
|
|
295
341
|
})
|
|
296
342
|
: null;
|
|
297
343
|
if (poster === undefined) {
|
|
@@ -302,13 +348,14 @@ const PlayerUI = ({ controls, style, loop, autoPlay, allowFullscreen, inputProps
|
|
|
302
348
|
showPosterWhenPaused && !player.isPlaying() && !seeking,
|
|
303
349
|
showPosterWhenEnded && player.isLastFrame && !player.isPlaying(),
|
|
304
350
|
showPosterWhenUnplayed && !player.hasPlayed && !player.isPlaying(),
|
|
351
|
+
showPosterWhenBuffering && showBufferIndicator && player.isPlaying(),
|
|
305
352
|
].some(Boolean);
|
|
306
353
|
const { left, top, width, height, ...outerWithoutScale } = outer;
|
|
307
|
-
const content = (_jsxs(_Fragment, { children: [_jsx("div", { style: outer, onClick: clickToPlay ? handleClick : undefined, onDoubleClick: doubleClickToFullscreen ? handleDoubleClick : undefined, children: _jsxs("div", { style: containerStyle, className: PLAYER_CSS_CLASSNAME, children: [VideoComponent ? (_jsx(ErrorBoundary, { onError: onError, errorFallback: errorFallback, children: _jsx(Internals.ClipComposition, { children: _jsx(VideoComponent, { ...((_c = video === null || video === void 0 ? void 0 : video.props) !== null && _c !== void 0 ? _c : {}), ...(inputProps !== null && inputProps !== void 0 ? inputProps : {}) }) }) })) : null, shouldShowPoster && posterFillMode === 'composition-size' ? (_jsx("div", { style: {
|
|
354
|
+
const content = (_jsxs(_Fragment, { children: [_jsx("div", { style: outer, onClick: clickToPlay ? handleClick : undefined, onDoubleClick: doubleClickToFullscreen ? handleDoubleClick : undefined, children: _jsxs("div", { style: containerStyle, className: PLAYER_CSS_CLASSNAME, children: [VideoComponent ? (_jsx(ErrorBoundary, { onError: onError, errorFallback: errorFallback, children: _jsx(Internals.ClipComposition, { children: _jsx(Internals.CurrentScaleContext.Provider, { value: currentScale, children: _jsx(VideoComponent, { ...((_c = video === null || video === void 0 ? void 0 : video.props) !== null && _c !== void 0 ? _c : {}), ...(inputProps !== null && inputProps !== void 0 ? inputProps : {}) }) }) }) })) : null, shouldShowPoster && posterFillMode === 'composition-size' ? (_jsx("div", { style: {
|
|
308
355
|
...outerWithoutScale,
|
|
309
356
|
width: config.width,
|
|
310
357
|
height: config.height,
|
|
311
|
-
}, onClick: clickToPlay ? handleClick : undefined, onDoubleClick: doubleClickToFullscreen ? handleDoubleClick : undefined, children: poster })) : null] }) }), shouldShowPoster && posterFillMode === 'player-size' ? (_jsx("div", { style: outer, onClick: clickToPlay ? handleClick : undefined, onDoubleClick: doubleClickToFullscreen ? handleDoubleClick : undefined, children: poster })) : null, controls ? (_jsx(Controls, { fps: config.fps, durationInFrames: config.durationInFrames, player: player, containerRef: container, onFullscreenButtonClick: onFullscreenButtonClick, isFullscreen: isFullscreen, allowFullscreen: allowFullscreen, showVolumeControls: showVolumeControls, onExitFullscreenButtonClick: onExitFullscreenButtonClick, spaceKeyToPlayOrPause: spaceKeyToPlayOrPause, onSeekEnd: onSeekEnd, onSeekStart: onSeekStart, inFrame: inFrame, outFrame: outFrame, initiallyShowControls: initiallyShowControls, canvasSize: canvasSize, renderFullscreenButton: renderFullscreenButton, renderPlayPauseButton: renderPlayPauseButton, alwaysShowControls: alwaysShowControls, showPlaybackRateControl: showPlaybackRateControl })) : null] }));
|
|
358
|
+
}, onClick: clickToPlay ? handleClick : undefined, onDoubleClick: doubleClickToFullscreen ? handleDoubleClick : undefined, children: poster })) : null] }) }), shouldShowPoster && posterFillMode === 'player-size' ? (_jsx("div", { style: outer, onClick: clickToPlay ? handleClick : undefined, onDoubleClick: doubleClickToFullscreen ? handleDoubleClick : undefined, children: poster })) : null, controls ? (_jsx(Controls, { fps: config.fps, durationInFrames: config.durationInFrames, player: player, containerRef: container, onFullscreenButtonClick: onFullscreenButtonClick, isFullscreen: isFullscreen, allowFullscreen: allowFullscreen, showVolumeControls: showVolumeControls, onExitFullscreenButtonClick: onExitFullscreenButtonClick, spaceKeyToPlayOrPause: spaceKeyToPlayOrPause, onSeekEnd: onSeekEnd, onSeekStart: onSeekStart, inFrame: inFrame, outFrame: outFrame, initiallyShowControls: initiallyShowControls, canvasSize: canvasSize, renderFullscreenButton: renderFullscreenButton, renderPlayPauseButton: renderPlayPauseButton, alwaysShowControls: alwaysShowControls, showPlaybackRateControl: showPlaybackRateControl, buffering: showBufferIndicator })) : null] }));
|
|
312
359
|
if (IS_NODE && !doesReactVersionSupportSuspense) {
|
|
313
360
|
return (_jsx("div", { ref: container, style: outerStyle, className: className, children: content }));
|
|
314
361
|
}
|
package/.rollup.cache/Users/jonathanburger/remotion/packages/player/dist/esm/SharedPlayerContext.js
CHANGED
|
@@ -51,5 +51,5 @@ export const SharedPlayerContexts = ({ children, timelineContext, fps, compositi
|
|
|
51
51
|
setMediaVolume: setMediaVolumeAndPersist,
|
|
52
52
|
};
|
|
53
53
|
}, [setMediaVolumeAndPersist]);
|
|
54
|
-
return (_jsx(Internals.CanUseRemotionHooksProvider, { children: _jsx(Internals.Timeline.TimelineContext.Provider, { value: timelineContext, children: _jsx(Internals.CompositionManager.Provider, { value: compositionManagerContext, children: _jsx(Internals.ResolveCompositionConfig, { children: _jsx(Internals.PrefetchProvider, { children: _jsx(Internals.DurationsContextProvider, { children: _jsx(Internals.MediaVolumeContext.Provider, { value: mediaVolumeContextValue, children: _jsx(Internals.NativeLayersProvider, { children: _jsx(Internals.SetMediaVolumeContext.Provider, { value: setMediaVolumeContextValue, children: _jsx(Internals.SharedAudioContextProvider, { numberOfAudioTags: numberOfSharedAudioTags, component: component, children: children }) }) }) }) }) }) }) }) }) }));
|
|
54
|
+
return (_jsx(Internals.CanUseRemotionHooksProvider, { children: _jsx(Internals.Timeline.TimelineContext.Provider, { value: timelineContext, children: _jsx(Internals.CompositionManager.Provider, { value: compositionManagerContext, children: _jsx(Internals.ResolveCompositionConfig, { children: _jsx(Internals.PrefetchProvider, { children: _jsx(Internals.DurationsContextProvider, { children: _jsx(Internals.MediaVolumeContext.Provider, { value: mediaVolumeContextValue, children: _jsx(Internals.NativeLayersProvider, { children: _jsx(Internals.SetMediaVolumeContext.Provider, { value: setMediaVolumeContextValue, children: _jsx(Internals.SharedAudioContextProvider, { numberOfAudioTags: numberOfSharedAudioTags, component: component, children: _jsx(Internals.BufferingProvider, { children: children }) }) }) }) }) }) }) }) }) }) }));
|
|
55
55
|
};
|
|
@@ -67,13 +67,20 @@ const ThumbnailUI = ({ style, inputProps, errorFallback, renderLoading, classNam
|
|
|
67
67
|
? renderLoading({
|
|
68
68
|
height: outerStyle.height,
|
|
69
69
|
width: outerStyle.width,
|
|
70
|
+
isBuffering: false,
|
|
70
71
|
})
|
|
71
72
|
: null;
|
|
72
73
|
}, [outerStyle.height, outerStyle.width, renderLoading]);
|
|
74
|
+
const currentScaleContext = useMemo(() => {
|
|
75
|
+
return {
|
|
76
|
+
type: 'scale',
|
|
77
|
+
scale,
|
|
78
|
+
};
|
|
79
|
+
}, [scale]);
|
|
73
80
|
if (!config) {
|
|
74
81
|
return null;
|
|
75
82
|
}
|
|
76
|
-
const content = (_jsx("div", { style: outer, children: _jsx("div", { style: containerStyle, className: PLAYER_CSS_CLASSNAME, children: VideoComponent ? (_jsx(ErrorBoundary, { onError: onError, errorFallback: errorFallback, children: _jsx(VideoComponent, { ...((_b = video === null || video === void 0 ? void 0 : video.props) !== null && _b !== void 0 ? _b : {}), ...(inputProps !== null && inputProps !== void 0 ? inputProps : {}) }) })) : null }) }));
|
|
83
|
+
const content = (_jsx("div", { style: outer, children: _jsx("div", { style: containerStyle, className: PLAYER_CSS_CLASSNAME, children: VideoComponent ? (_jsx(ErrorBoundary, { onError: onError, errorFallback: errorFallback, children: _jsx(Internals.CurrentScaleContext.Provider, { value: currentScaleContext, children: _jsx(VideoComponent, { ...((_b = video === null || video === void 0 ? void 0 : video.props) !== null && _b !== void 0 ? _b : {}), ...(inputProps !== null && inputProps !== void 0 ? inputProps : {}) }) }) })) : null }) }));
|
|
77
84
|
if (IS_NODE && !doesReactVersionSupportSuspense) {
|
|
78
85
|
return (_jsx("div", { ref: container, style: outerStyle, className: className, children: content }));
|
|
79
86
|
}
|
package/.rollup.cache/Users/jonathanburger/remotion/packages/player/dist/esm/calculate-scale.d.ts
CHANGED
|
@@ -1,12 +1,5 @@
|
|
|
1
|
-
import type { VideoConfig } from 'remotion';
|
|
2
|
-
import type { PreviewSize } from './utils/preview-size.js';
|
|
1
|
+
import type { PreviewSize, VideoConfig } from 'remotion';
|
|
3
2
|
import type { Size } from './utils/use-element-size.js';
|
|
4
|
-
export declare const calculateScale: ({ canvasSize, compositionHeight, compositionWidth, previewSize, }: {
|
|
5
|
-
previewSize: PreviewSize['size'];
|
|
6
|
-
compositionWidth: number;
|
|
7
|
-
compositionHeight: number;
|
|
8
|
-
canvasSize: Size;
|
|
9
|
-
}) => number;
|
|
10
3
|
type Layout = {
|
|
11
4
|
centerX: number;
|
|
12
5
|
centerY: number;
|
package/.rollup.cache/Users/jonathanburger/remotion/packages/player/dist/esm/calculate-scale.js
CHANGED
|
@@ -1,12 +1,7 @@
|
|
|
1
|
+
import { Internals } from 'remotion';
|
|
1
2
|
import { calculatePlayerSize } from './utils/calculate-player-size.js';
|
|
2
|
-
export const calculateScale = ({ canvasSize, compositionHeight, compositionWidth, previewSize, }) => {
|
|
3
|
-
const heightRatio = canvasSize.height / compositionHeight;
|
|
4
|
-
const widthRatio = canvasSize.width / compositionWidth;
|
|
5
|
-
const ratio = Math.min(heightRatio, widthRatio);
|
|
6
|
-
return previewSize === 'auto' ? ratio : Number(previewSize);
|
|
7
|
-
};
|
|
8
3
|
export const calculateCanvasTransformation = ({ previewSize, compositionWidth, compositionHeight, canvasSize, }) => {
|
|
9
|
-
const scale = calculateScale({
|
|
4
|
+
const scale = Internals.calculateScale({
|
|
10
5
|
canvasSize,
|
|
11
6
|
compositionHeight,
|
|
12
7
|
compositionWidth,
|
package/.rollup.cache/Users/jonathanburger/remotion/packages/player/dist/esm/event-emitter.d.ts
CHANGED
|
@@ -25,6 +25,8 @@ type FullscreenChangeEventPayload = {
|
|
|
25
25
|
type MuteChangeEventPayload = {
|
|
26
26
|
isMuted: boolean;
|
|
27
27
|
};
|
|
28
|
+
type WaitingEventPayload = {};
|
|
29
|
+
type ResumeEventPayload = {};
|
|
28
30
|
type PlayerStateEventMap = {
|
|
29
31
|
seeked: SeekPayload;
|
|
30
32
|
pause: undefined;
|
|
@@ -38,6 +40,8 @@ type PlayerStateEventMap = {
|
|
|
38
40
|
frameupdate: FrameUpdateEventPayload;
|
|
39
41
|
fullscreenchange: FullscreenChangeEventPayload;
|
|
40
42
|
mutechange: MuteChangeEventPayload;
|
|
43
|
+
waiting: WaitingEventPayload;
|
|
44
|
+
resume: ResumeEventPayload;
|
|
41
45
|
};
|
|
42
46
|
type ThumbnailStateEventMap = {
|
|
43
47
|
error: ErrorPayload;
|
|
@@ -70,6 +74,8 @@ export declare class PlayerEmitter {
|
|
|
70
74
|
dispatchFrameUpdate(event: FrameUpdateEventPayload): void;
|
|
71
75
|
dispatchFullscreenChange(event: FullscreenChangeEventPayload): void;
|
|
72
76
|
dispatchMuteChange(event: MuteChangeEventPayload): void;
|
|
77
|
+
dispatchWaiting(event: WaitingEventPayload): void;
|
|
78
|
+
dispatchResume(event: ResumeEventPayload): void;
|
|
73
79
|
}
|
|
74
80
|
export declare class ThumbnailEmitter {
|
|
75
81
|
listeners: ThumbnailListeners;
|
package/.rollup.cache/Users/jonathanburger/remotion/packages/player/dist/esm/event-emitter.js
CHANGED
|
@@ -13,6 +13,8 @@ export class PlayerEmitter {
|
|
|
13
13
|
fullscreenchange: [],
|
|
14
14
|
volumechange: [],
|
|
15
15
|
mutechange: [],
|
|
16
|
+
waiting: [],
|
|
17
|
+
resume: [],
|
|
16
18
|
};
|
|
17
19
|
}
|
|
18
20
|
addEventListener(name, callback) {
|
|
@@ -72,6 +74,12 @@ export class PlayerEmitter {
|
|
|
72
74
|
dispatchMuteChange(event) {
|
|
73
75
|
this.dispatchEvent('mutechange', event);
|
|
74
76
|
}
|
|
77
|
+
dispatchWaiting(event) {
|
|
78
|
+
this.dispatchEvent('waiting', event);
|
|
79
|
+
}
|
|
80
|
+
dispatchResume(event) {
|
|
81
|
+
this.dispatchEvent('resume', event);
|
|
82
|
+
}
|
|
75
83
|
}
|
|
76
84
|
export class ThumbnailEmitter {
|
|
77
85
|
constructor() {
|
|
@@ -2,7 +2,7 @@ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
|
2
2
|
export const ICON_SIZE = 25;
|
|
3
3
|
export const fullscreenIconSize = 16;
|
|
4
4
|
export const PlayIcon = () => {
|
|
5
|
-
return (_jsx("svg", { width: ICON_SIZE, height: ICON_SIZE, viewBox: "0 0 25 25", fill: "none",
|
|
5
|
+
return (_jsx("svg", { width: ICON_SIZE, height: ICON_SIZE, viewBox: "0 0 25 25", fill: "none", children: _jsx("path", { d: "M8 6.375C7.40904 8.17576 7.06921 10.2486 7.01438 12.3871C6.95955 14.5255 7.19163 16.6547 7.6875 18.5625C9.95364 18.2995 12.116 17.6164 14.009 16.5655C15.902 15.5147 17.4755 14.124 18.6088 12.5C17.5158 10.8949 15.9949 9.51103 14.1585 8.45082C12.3222 7.3906 10.2174 6.68116 8 6.375Z", fill: "white", stroke: "white", strokeWidth: "6.25", strokeLinejoin: "round" }) }));
|
|
6
6
|
};
|
|
7
7
|
export const PauseIcon = () => {
|
|
8
8
|
return (_jsxs("svg", { viewBox: "0 0 100 100", width: ICON_SIZE, height: ICON_SIZE, children: [_jsx("rect", { x: "25", y: "20", width: "20", height: "60", fill: "#fff", ry: "5", rx: "5" }), _jsx("rect", { x: "55", y: "20", width: "20", height: "60", fill: "#fff", ry: "5", rx: "5" })] }));
|
|
@@ -5,7 +5,6 @@ export { Player, PlayerProps } from './Player.js';
|
|
|
5
5
|
export type { RenderFullscreenButton, RenderPlayPauseButton, } from './PlayerControls.js';
|
|
6
6
|
export type { ErrorFallback, RenderLoading, RenderPoster } from './PlayerUI.js';
|
|
7
7
|
export { Thumbnail } from './Thumbnail.js';
|
|
8
|
-
export { PreviewSize, Translation } from './utils/preview-size.js';
|
|
9
8
|
export { Size } from './utils/use-element-size.js';
|
|
10
9
|
export type { CallbackListener, PlayerEventTypes as EventTypes };
|
|
11
10
|
export declare const PlayerInternals: {
|
|
@@ -25,6 +24,7 @@ export declare const PlayerInternals: {
|
|
|
25
24
|
getCurrentFrame: () => number;
|
|
26
25
|
isPlaying: () => boolean;
|
|
27
26
|
hasPlayed: boolean;
|
|
27
|
+
isBuffering: () => boolean;
|
|
28
28
|
remotionInternal_currentFrameRef: import("react").MutableRefObject<number>;
|
|
29
29
|
};
|
|
30
30
|
usePlayback: ({ loop, playbackRate, moveToBeginningWhenEnded, inFrame, outFrame, frameRef, }: {
|
|
@@ -53,10 +53,11 @@ export declare const PlayerInternals: {
|
|
|
53
53
|
};
|
|
54
54
|
useHoverState: (ref: import("react").RefObject<HTMLDivElement>) => boolean;
|
|
55
55
|
updateAllElementsSizes: () => void;
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
56
|
+
PlayerEmitterProvider: import("react").FC<{
|
|
57
|
+
children: import("react").ReactNode;
|
|
58
|
+
currentPlaybackRate: number | null;
|
|
59
|
+
}>;
|
|
60
|
+
BufferingIndicator: import("react").FC<{
|
|
61
|
+
type: "player" | "studio";
|
|
62
|
+
}>;
|
|
62
63
|
};
|
|
@@ -1,5 +1,7 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { BufferingIndicator } from './BufferingIndicator.js';
|
|
2
|
+
import { calculateCanvasTransformation } from './calculate-scale.js';
|
|
2
3
|
import { PlayerEventEmitterContext } from './emitter-context.js';
|
|
4
|
+
import { PlayerEmitterProvider } from './EmitterProvider.js';
|
|
3
5
|
import { PlayerEmitter } from './event-emitter.js';
|
|
4
6
|
import { useHoverState } from './use-hover-state.js';
|
|
5
7
|
import { usePlayback } from './use-playback.js';
|
|
@@ -16,5 +18,6 @@ export const PlayerInternals = {
|
|
|
16
18
|
calculateCanvasTransformation,
|
|
17
19
|
useHoverState,
|
|
18
20
|
updateAllElementsSizes,
|
|
19
|
-
|
|
21
|
+
PlayerEmitterProvider,
|
|
22
|
+
BufferingIndicator,
|
|
20
23
|
};
|
package/.rollup.cache/Users/jonathanburger/remotion/packages/player/dist/esm/use-playback.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/* eslint-disable @typescript-eslint/no-use-before-define */
|
|
2
|
-
import { useEffect, useRef } from 'react';
|
|
2
|
+
import { useContext, useEffect, useRef } from 'react';
|
|
3
3
|
import { Internals } from 'remotion';
|
|
4
4
|
import { calculateNextFrame } from './calculate-next-frame.js';
|
|
5
5
|
import { useIsBackgrounded } from './is-backgrounded.js';
|
|
@@ -9,11 +9,28 @@ export const usePlayback = ({ loop, playbackRate, moveToBeginningWhenEnded, inFr
|
|
|
9
9
|
const frame = Internals.Timeline.useTimelinePosition();
|
|
10
10
|
const { playing, pause, emitter } = usePlayer();
|
|
11
11
|
const setFrame = Internals.Timeline.useTimelineSetFrame();
|
|
12
|
+
const buffering = useRef(null);
|
|
12
13
|
// requestAnimationFrame() does not work if the tab is not active.
|
|
13
14
|
// This means that audio will keep playing even if it has ended.
|
|
14
15
|
// In that case, we use setTimeout() instead.
|
|
15
16
|
const isBackgroundedRef = useIsBackgrounded();
|
|
16
17
|
const lastTimeUpdateEvent = useRef(null);
|
|
18
|
+
const context = useContext(Internals.BufferingContextReact);
|
|
19
|
+
if (!context) {
|
|
20
|
+
throw new Error('Missing the buffering context. Most likely you have a Remotion version mismatch.');
|
|
21
|
+
}
|
|
22
|
+
useEffect(() => {
|
|
23
|
+
const onBufferClear = context.listenForBuffering(() => {
|
|
24
|
+
buffering.current = performance.now();
|
|
25
|
+
});
|
|
26
|
+
const onResumeClear = context.listenForResume(() => {
|
|
27
|
+
buffering.current = null;
|
|
28
|
+
});
|
|
29
|
+
return () => {
|
|
30
|
+
onBufferClear.remove();
|
|
31
|
+
onResumeClear.remove();
|
|
32
|
+
};
|
|
33
|
+
}, [context]);
|
|
17
34
|
useEffect(() => {
|
|
18
35
|
if (!config) {
|
|
19
36
|
return;
|
|
@@ -23,7 +40,7 @@ export const usePlayback = ({ loop, playbackRate, moveToBeginningWhenEnded, inFr
|
|
|
23
40
|
}
|
|
24
41
|
let hasBeenStopped = false;
|
|
25
42
|
let reqAnimFrameCall = null;
|
|
26
|
-
|
|
43
|
+
let startedTime = performance.now();
|
|
27
44
|
let framesAdvanced = 0;
|
|
28
45
|
const cancelQueuedFrame = () => {
|
|
29
46
|
if (reqAnimFrameCall !== null) {
|
|
@@ -43,9 +60,10 @@ export const usePlayback = ({ loop, playbackRate, moveToBeginningWhenEnded, inFr
|
|
|
43
60
|
const time = performance.now() - startedTime;
|
|
44
61
|
const actualLastFrame = outFrame !== null && outFrame !== void 0 ? outFrame : config.durationInFrames - 1;
|
|
45
62
|
const actualFirstFrame = inFrame !== null && inFrame !== void 0 ? inFrame : 0;
|
|
63
|
+
const currentFrame = frameRef.current;
|
|
46
64
|
const { nextFrame, framesToAdvance, hasEnded } = calculateNextFrame({
|
|
47
65
|
time,
|
|
48
|
-
currentFrame
|
|
66
|
+
currentFrame,
|
|
49
67
|
playbackSpeed: playbackRate,
|
|
50
68
|
fps: config.fps,
|
|
51
69
|
actualFirstFrame,
|
|
@@ -69,6 +87,18 @@ export const usePlayback = ({ loop, playbackRate, moveToBeginningWhenEnded, inFr
|
|
|
69
87
|
}
|
|
70
88
|
};
|
|
71
89
|
const queueNextFrame = () => {
|
|
90
|
+
if (buffering.current) {
|
|
91
|
+
const stopListening = context.listenForResume(() => {
|
|
92
|
+
stopListening.remove();
|
|
93
|
+
if (hasBeenStopped) {
|
|
94
|
+
return;
|
|
95
|
+
}
|
|
96
|
+
startedTime = performance.now();
|
|
97
|
+
framesAdvanced = 0;
|
|
98
|
+
callback();
|
|
99
|
+
});
|
|
100
|
+
return;
|
|
101
|
+
}
|
|
72
102
|
if (isBackgroundedRef.current) {
|
|
73
103
|
reqAnimFrameCall = {
|
|
74
104
|
type: 'timeout',
|
|
@@ -108,6 +138,8 @@ export const usePlayback = ({ loop, playbackRate, moveToBeginningWhenEnded, inFr
|
|
|
108
138
|
moveToBeginningWhenEnded,
|
|
109
139
|
isBackgroundedRef,
|
|
110
140
|
frameRef,
|
|
141
|
+
buffering,
|
|
142
|
+
context,
|
|
111
143
|
]);
|
|
112
144
|
useEffect(() => {
|
|
113
145
|
const interval = setInterval(() => {
|
|
@@ -22,6 +22,11 @@ export const usePlayer = () => {
|
|
|
22
22
|
if (!emitter) {
|
|
23
23
|
throw new TypeError('Expected Player event emitter context');
|
|
24
24
|
}
|
|
25
|
+
const bufferingContext = useContext(Internals.BufferingContextReact);
|
|
26
|
+
if (!bufferingContext) {
|
|
27
|
+
throw new Error('Missing the buffering context. Most likely you have a Remotion version mismatch.');
|
|
28
|
+
}
|
|
29
|
+
const { buffering } = bufferingContext;
|
|
25
30
|
const seek = useCallback((newFrame) => {
|
|
26
31
|
if (video === null || video === void 0 ? void 0 : video.id) {
|
|
27
32
|
setTimelinePosition((c) => ({ ...c, [video.id]: newFrame }));
|
|
@@ -128,6 +133,7 @@ export const usePlayer = () => {
|
|
|
128
133
|
isFirstFrame,
|
|
129
134
|
getCurrentFrame: () => frameRef.current,
|
|
130
135
|
isPlaying: () => imperativePlaying.current,
|
|
136
|
+
isBuffering: () => buffering.current,
|
|
131
137
|
pauseAndReturnToPlayStart,
|
|
132
138
|
hasPlayed,
|
|
133
139
|
remotionInternal_currentFrameRef: frameRef,
|
|
@@ -143,8 +149,9 @@ export const usePlayer = () => {
|
|
|
143
149
|
seek,
|
|
144
150
|
isFirstFrame,
|
|
145
151
|
pauseAndReturnToPlayStart,
|
|
146
|
-
imperativePlaying,
|
|
147
152
|
hasPlayed,
|
|
153
|
+
imperativePlaying,
|
|
154
|
+
buffering,
|
|
148
155
|
]);
|
|
149
156
|
return returnValue;
|
|
150
157
|
};
|