@remotion/player 4.0.505 → 4.0.506

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.
@@ -6,6 +6,7 @@ const react_1 = require("react");
6
6
  const remotion_1 = require("remotion");
7
7
  const emitter_context_js_1 = require("./emitter-context.js");
8
8
  const event_emitter_js_1 = require("./event-emitter.js");
9
+ const timeline_imperative_context_js_1 = require("./timeline-imperative-context.js");
9
10
  const use_buffer_state_emitter_js_1 = require("./use-buffer-state-emitter.js");
10
11
  const PlayerEmitterProvider = ({ children, currentPlaybackRate }) => {
11
12
  const [emitter] = (0, react_1.useState)(() => new event_emitter_js_1.PlayerEmitter());
@@ -19,6 +20,6 @@ const PlayerEmitterProvider = ({ children, currentPlaybackRate }) => {
19
20
  }
20
21
  }, [emitter, currentPlaybackRate]);
21
22
  (0, use_buffer_state_emitter_js_1.useBufferStateEmitter)(emitter);
22
- return (jsx_runtime_1.jsx(emitter_context_js_1.PlayerEventEmitterContext.Provider, { value: emitter, children: children }));
23
+ return (jsx_runtime_1.jsx(timeline_imperative_context_js_1.TimelineImperativeCompatibilityProvider, { children: jsx_runtime_1.jsx(emitter_context_js_1.PlayerEventEmitterContext.Provider, { value: emitter, children: children }) }));
23
24
  };
24
25
  exports.PlayerEmitterProvider = PlayerEmitterProvider;
@@ -5,7 +5,7 @@ const jsx_runtime_1 = require("react/jsx-runtime");
5
5
  const react_1 = require("react");
6
6
  const remotion_1 = require("remotion");
7
7
  const use_hover_state_js_1 = require("./use-hover-state.js");
8
- const use_player_js_1 = require("./use-player.js");
8
+ const use_player_methods_js_1 = require("./use-player-methods.js");
9
9
  const use_element_size_js_1 = require("./utils/use-element-size.js");
10
10
  const getFrameFromX = (clientX, durationInFrames, width) => {
11
11
  const pos = clientX;
@@ -49,7 +49,7 @@ const PlayerSeekBar = ({ durationInFrames, onSeekEnd, onSeekStart, inFrame, outF
49
49
  triggerOnWindowResize: true,
50
50
  shouldApplyCssTransforms: true,
51
51
  });
52
- const { seek, play, pause, playing } = (0, use_player_js_1.usePlayer)();
52
+ const { seek, play, pause, isPlaying } = (0, use_player_methods_js_1.usePlayerMethods)();
53
53
  const frame = remotion_1.Internals.Timeline.useTimelinePosition();
54
54
  const [dragging, setDragging] = (0, react_1.useState)({
55
55
  dragging: false,
@@ -62,14 +62,15 @@ const PlayerSeekBar = ({ durationInFrames, onSeekEnd, onSeekStart, inFrame, outF
62
62
  }
63
63
  const posLeft = (_a = containerRef.current) === null || _a === void 0 ? void 0 : _a.getBoundingClientRect().left;
64
64
  const _frame = getFrameFromX(e.clientX - posLeft, durationInFrames, width);
65
+ const wasPlaying = isPlaying();
65
66
  pause();
66
67
  seek(_frame);
67
68
  setDragging({
68
69
  dragging: true,
69
- wasPlaying: playing,
70
+ wasPlaying,
70
71
  });
71
72
  onSeekStart();
72
- }, [durationInFrames, width, pause, seek, playing, onSeekStart]);
73
+ }, [durationInFrames, width, isPlaying, pause, seek, onSeekStart]);
73
74
  const onPointerMove = (0, react_1.useCallback)((e) => {
74
75
  var _a;
75
76
  if (!size) {
@@ -42,7 +42,7 @@ const license_blacklist_js_1 = require("./license-blacklist.js");
42
42
  const player_css_classname_js_1 = require("./player-css-classname.js");
43
43
  const PlayerControls_js_1 = require("./PlayerControls.js");
44
44
  const use_playback_js_1 = require("./use-playback.js");
45
- const use_player_js_1 = require("./use-player.js");
45
+ const use_player_methods_js_1 = require("./use-player-methods.js");
46
46
  const is_node_js_1 = require("./utils/is-node.js");
47
47
  const use_click_prevention_on_double_click_js_1 = require("./utils/use-click-prevention-on-double-click.js");
48
48
  const use_element_size_js_1 = require("./utils/use-element-size.js");
@@ -64,6 +64,7 @@ const PlayerUI = ({ controls, style, loop, autoPlay, allowFullscreen, inputProps
64
64
  const [shouldAutoplay, setShouldAutoPlay] = (0, react_1.useState)(autoPlay);
65
65
  const [isFullscreen, setIsFullscreen] = (0, react_1.useState)(() => false);
66
66
  const [seeking, setSeeking] = (0, react_1.useState)(false);
67
+ const [hasPlayed, setHasPlayed] = (0, react_1.useState)(false);
67
68
  const supportsFullScreen = (0, react_1.useMemo)(() => {
68
69
  if (typeof document === 'undefined') {
69
70
  return false;
@@ -72,8 +73,16 @@ const PlayerUI = ({ controls, style, loop, autoPlay, allowFullscreen, inputProps
72
73
  // @ts-expect-error Types not defined
73
74
  document.webkitFullscreenEnabled);
74
75
  }, []);
75
- const player = (0, use_player_js_1.usePlayer)();
76
- const playerToggle = player.toggle;
76
+ const player = (0, use_player_methods_js_1.usePlayerMethods)();
77
+ const [playing] = remotion_1.Internals.Timeline.usePlayingState();
78
+ const frame = remotion_1.Internals.Timeline.useTimelinePosition();
79
+ const play = (0, react_1.useCallback)((e) => {
80
+ if (player.isPlaying()) {
81
+ return;
82
+ }
83
+ setHasPlayed(true);
84
+ player.play(e);
85
+ }, [player]);
77
86
  const { playerMuted, mediaVolume } = (0, react_1.useContext)(remotion_1.Internals.MediaVolumeContext);
78
87
  (0, react_1.useEffect)(() => {
79
88
  player.emitter.dispatchVolumeChange(mediaVolume);
@@ -95,11 +104,11 @@ const PlayerUI = ({ controls, style, loop, autoPlay, allowFullscreen, inputProps
95
104
  muted: isMuted,
96
105
  });
97
106
  (0, react_1.useEffect)(() => {
98
- if (hasPausedToResume && !player.playing) {
107
+ if (hasPausedToResume && !playing) {
99
108
  setHasPausedToResume(false);
100
- player.play();
109
+ play();
101
110
  }
102
- }, [hasPausedToResume, player]);
111
+ }, [hasPausedToResume, play, playing]);
103
112
  (0, react_1.useEffect)(() => {
104
113
  const { current } = container;
105
114
  if (!current) {
@@ -119,8 +128,13 @@ const PlayerUI = ({ controls, style, loop, autoPlay, allowFullscreen, inputProps
119
128
  };
120
129
  }, []);
121
130
  const toggle = (0, react_1.useCallback)((e) => {
122
- playerToggle(e);
123
- }, [playerToggle]);
131
+ if (player.isPlaying()) {
132
+ player.pause();
133
+ }
134
+ else {
135
+ play(e);
136
+ }
137
+ }, [play, player]);
124
138
  const requestFullscreen = (0, react_1.useCallback)(() => {
125
139
  if (!allowFullscreen) {
126
140
  throw new Error('allowFullscreen is false');
@@ -244,7 +258,7 @@ const PlayerUI = ({ controls, style, loop, autoPlay, allowFullscreen, inputProps
244
258
  }, [bufferStateDelayInMilliseconds, player.emitter]);
245
259
  (0, react_1.useImperativeHandle)(ref, () => {
246
260
  const methods = {
247
- play: player.play,
261
+ play,
248
262
  pause: () => {
249
263
  // If, after .seek()-ing, the player was explicitly paused, we don't resume
250
264
  setHasPausedToResume(false);
@@ -318,6 +332,7 @@ const PlayerUI = ({ controls, style, loop, autoPlay, allowFullscreen, inputProps
318
332
  isMuted,
319
333
  mediaVolume,
320
334
  player,
335
+ play,
321
336
  requestFullscreen,
322
337
  setPlayerMuted,
323
338
  setMediaVolume,
@@ -384,10 +399,10 @@ const PlayerUI = ({ controls, style, loop, autoPlay, allowFullscreen, inputProps
384
399
  const { handlePointerDown, handleDoubleClick } = (0, use_click_prevention_on_double_click_js_1.useClickPreventionOnDoubleClick)(onSingleClick, onDoubleClick, doubleClickToFullscreen && allowFullscreen && supportsFullScreen);
385
400
  (0, react_1.useEffect)(() => {
386
401
  if (shouldAutoplay) {
387
- player.play();
402
+ play();
388
403
  setShouldAutoPlay(false);
389
404
  }
390
- }, [shouldAutoplay, player]);
405
+ }, [play, shouldAutoplay]);
391
406
  const loadingMarkup = (0, react_1.useMemo)(() => {
392
407
  return renderLoading
393
408
  ? renderLoading({
@@ -423,8 +438,10 @@ const PlayerUI = ({ controls, style, loop, autoPlay, allowFullscreen, inputProps
423
438
  const shouldShowPoster = poster &&
424
439
  [
425
440
  showPosterWhenPaused && !player.isPlaying() && !seeking,
426
- showPosterWhenEnded && player.isLastFrame && !player.isPlaying(),
427
- showPosterWhenUnplayed && !player.hasPlayed && !player.isPlaying(),
441
+ showPosterWhenEnded &&
442
+ frame === durationInFrames - 1 &&
443
+ !player.isPlaying(),
444
+ showPosterWhenUnplayed && !hasPlayed && !player.isPlaying(),
428
445
  showPosterWhenBuffering && showBufferIndicator && player.isPlaying(),
429
446
  showPosterWhenBufferingAndPaused &&
430
447
  showBufferIndicator &&
@@ -438,7 +455,7 @@ const PlayerUI = ({ controls, style, loop, autoPlay, allowFullscreen, inputProps
438
455
  width: config.width,
439
456
  height: config.height,
440
457
  }, onPointerDown: clickToPlay ? handlePointerDown : undefined, onDoubleClick: doubleClickToFullscreen ? handleDoubleClick : undefined, children: poster })) : null] }), jsx_runtime_1.jsx(license_blacklist_js_1.RenderWarningIfBlacklist, {})
441
- ] }), shouldShowPoster && posterFillMode === 'player-size' ? (jsx_runtime_1.jsx("div", { style: outer, onPointerDown: clickToPlay ? handlePointerDown : undefined, onDoubleClick: doubleClickToFullscreen ? handleDoubleClick : undefined, children: poster })) : null, controls ? (jsx_runtime_1.jsx(PlayerControls_js_1.Controls, { fps: config.fps, playing: player.playing, toggle: player.toggle, durationInFrames: config.durationInFrames, 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, hideControlsWhenPointerDoesntMove: hideControlsWhenPointerDoesntMove, onDoubleClick: doubleClickToFullscreen ? handleDoubleClick : undefined, onPointerDown: clickToPlay
458
+ ] }), shouldShowPoster && posterFillMode === 'player-size' ? (jsx_runtime_1.jsx("div", { style: outer, onPointerDown: clickToPlay ? handlePointerDown : undefined, onDoubleClick: doubleClickToFullscreen ? handleDoubleClick : undefined, children: poster })) : null, controls ? (jsx_runtime_1.jsx(PlayerControls_js_1.Controls, { fps: config.fps, playing: playing, toggle: toggle, durationInFrames: config.durationInFrames, 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, hideControlsWhenPointerDoesntMove: hideControlsWhenPointerDoesntMove, onDoubleClick: doubleClickToFullscreen ? handleDoubleClick : undefined, onPointerDown: clickToPlay
442
459
  ? handlePointerDown
443
460
  : undefined, renderMuteButton: renderMuteButton, renderVolumeSlider: renderVolumeSlider, renderCustomControls: renderCustomControls })) : null] }));
444
461
  if (noSuspense || (is_node_js_1.IS_NODE && !doesReactVersionSupportSuspense)) {
@@ -4,6 +4,7 @@ exports.SharedPlayerContexts = exports.PLAYER_COMP_ID = void 0;
4
4
  const jsx_runtime_1 = require("react/jsx-runtime");
5
5
  const react_1 = require("react");
6
6
  const remotion_1 = require("remotion");
7
+ const timeline_imperative_context_js_1 = require("./timeline-imperative-context.js");
7
8
  const volume_persistence_js_1 = require("./volume-persistence.js");
8
9
  exports.PLAYER_COMP_ID = 'player-comp';
9
10
  const SharedPlayerContexts = ({ children, timelineContext, playbackRateContext, fps, compositionHeight, compositionWidth, durationInFrames, component, numberOfSharedAudioTags, initiallyMuted, logLevel, audioLatencyHint, sampleRate, volumePersistenceKey, initialVolume, inputProps, audioEnabled, }) => {
@@ -92,6 +93,15 @@ const SharedPlayerContexts = ({ children, timelineContext, playbackRateContext,
92
93
  isReadOnlyStudio: false,
93
94
  };
94
95
  }, []);
95
- 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.PlaybackRateContext.Provider, { value: playbackRateContext, 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: shouldCreateAudioContext, previewSampleRate: sampleRate, children: jsx_runtime_1.jsx(remotion_1.Internals.SharedAudioTagsContextProvider, { numberOfAudioTags: numberOfSharedAudioTags, children: children }) }) }) }) }) }) }) }) }) }) }) }) }) }));
96
+ const frameRef = (0, react_1.useRef)(timelineContext.frame);
97
+ frameRef.current = timelineContext.frame;
98
+ const timelineImperativeContextValue = (0, react_1.useMemo)(() => {
99
+ return {
100
+ frameRef,
101
+ imperativePlaying: timelineContext.imperativePlaying,
102
+ audioAndVideoTags: timelineContext.audioAndVideoTags,
103
+ };
104
+ }, [timelineContext.audioAndVideoTags, timelineContext.imperativePlaying]);
105
+ 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.PlaybackRateContext.Provider, { value: playbackRateContext, children: jsx_runtime_1.jsx(timeline_imperative_context_js_1.CoreTimelineImperativeContextProvider, { value: timelineImperativeContextValue, 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: shouldCreateAudioContext, previewSampleRate: sampleRate, children: jsx_runtime_1.jsx(remotion_1.Internals.SharedAudioTagsContextProvider, { numberOfAudioTags: numberOfSharedAudioTags, children: children }) }) }) }) }) }) }) }) }) }) }) }) }) }) }));
96
106
  };
97
107
  exports.SharedPlayerContexts = SharedPlayerContexts;
@@ -19,16 +19,16 @@ const ThumbnailFn = ({ frameToDisplay, style, inputProps, compositionHeight, com
19
19
  }, []);
20
20
  }
21
21
  const rootRef = (0, react_1.useRef)(null);
22
+ const imperativePlaying = (0, react_1.useRef)(false);
23
+ const audioAndVideoTags = (0, react_1.useRef)([]);
22
24
  const timelineState = (0, react_1.useMemo)(() => {
23
25
  const value = {
24
26
  playing: false,
25
27
  frame: {
26
28
  [SharedPlayerContext_js_1.PLAYER_COMP_ID]: frameToDisplay,
27
29
  },
28
- imperativePlaying: {
29
- current: false,
30
- },
31
- audioAndVideoTags: { current: [] },
30
+ imperativePlaying,
31
+ audioAndVideoTags,
32
32
  };
33
33
  return value;
34
34
  }, [frameToDisplay]);
@@ -2,9 +2,11 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.useBrowserMediaSession = void 0;
4
4
  const react_1 = require("react");
5
- const use_player_js_1 = require("./use-player.js");
5
+ const remotion_1 = require("remotion");
6
+ const use_player_methods_js_1 = require("./use-player-methods.js");
6
7
  const useBrowserMediaSession = ({ browserMediaControlsBehavior, videoConfig, playbackRate, }) => {
7
- const { playing, pause, play, emitter, getCurrentFrame, seek } = (0, use_player_js_1.usePlayer)();
8
+ const [playing] = remotion_1.Internals.Timeline.usePlayingState();
9
+ const { pause, play, emitter, getCurrentFrame, seek } = (0, use_player_methods_js_1.usePlayerMethods)();
8
10
  const hasEverPlayed = (0, react_1.useRef)(false);
9
11
  (0, react_1.useEffect)(() => {
10
12
  if (playing) {
@@ -15,23 +15,7 @@ export type { CallbackListener, PlayerEventTypes as EventTypes };
15
15
  export declare const PlayerInternals: {
16
16
  PlayerEventEmitterContext: import("react").Context<PlayerEmitter | undefined>;
17
17
  PlayerEmitter: typeof PlayerEmitter;
18
- usePlayer: () => {
19
- frameBack: (frames: number) => void;
20
- frameForward: (frames: number) => void;
21
- isLastFrame: boolean;
22
- isFirstFrame: boolean;
23
- emitter: PlayerEmitter;
24
- playing: boolean;
25
- play: (e?: PointerEvent | import("react").SyntheticEvent<Element, Event> | undefined) => void;
26
- pause: () => void;
27
- pauseAndReturnToPlayStart: () => void;
28
- seek: (newFrame: number) => void;
29
- getCurrentFrame: () => number;
30
- isPlaying: () => boolean;
31
- hasPlayed: boolean;
32
- isBuffering: () => boolean;
33
- toggle: (e?: PointerEvent | import("react").SyntheticEvent<Element, Event> | undefined) => void;
34
- };
18
+ usePlayerMethods: () => import("./use-player-methods.js").UsePlayerMethods;
35
19
  usePlayback: ({ loop, playbackRate, moveToBeginningWhenEnded, inFrame, outFrame, browserMediaControlsBehavior, getCurrentFrame, muted, }: {
36
20
  loop: boolean;
37
21
  playbackRate: number;
package/dist/cjs/index.js CHANGED
@@ -9,7 +9,7 @@ const EmitterProvider_js_1 = require("./EmitterProvider.js");
9
9
  const event_emitter_js_1 = require("./event-emitter.js");
10
10
  const use_hover_state_js_1 = require("./use-hover-state.js");
11
11
  const use_playback_js_1 = require("./use-playback.js");
12
- const use_player_js_1 = require("./use-player.js");
12
+ const use_player_methods_js_1 = require("./use-player-methods.js");
13
13
  const use_element_size_js_1 = require("./utils/use-element-size.js");
14
14
  const Player_js_1 = require("./Player.js");
15
15
  Object.defineProperty(exports, "Player", { enumerable: true, get: function () { return Player_js_1.Player; } });
@@ -18,7 +18,7 @@ Object.defineProperty(exports, "Thumbnail", { enumerable: true, get: function ()
18
18
  exports.PlayerInternals = {
19
19
  PlayerEventEmitterContext: emitter_context_js_1.PlayerEventEmitterContext,
20
20
  PlayerEmitter: event_emitter_js_1.PlayerEmitter,
21
- usePlayer: use_player_js_1.usePlayer,
21
+ usePlayerMethods: use_player_methods_js_1.usePlayerMethods,
22
22
  usePlayback: use_playback_js_1.usePlayback,
23
23
  useElementSize: use_element_size_js_1.useElementSize,
24
24
  calculateCanvasTransformation: calculate_scale_js_1.calculateCanvasTransformation,
@@ -0,0 +1,11 @@
1
+ import type { Context } from 'react';
2
+ import React from 'react';
3
+ import type { TimelineImperativeContextValue } from 'remotion';
4
+ export declare const getTimelineImperativeContext: () => Context<TimelineImperativeContextValue | null>;
5
+ export declare const CoreTimelineImperativeContextProvider: React.FC<{
6
+ readonly children: React.ReactNode;
7
+ readonly value: TimelineImperativeContextValue;
8
+ }>;
9
+ export declare const TimelineImperativeCompatibilityProvider: React.FC<{
10
+ readonly children: React.ReactNode;
11
+ }>;
@@ -0,0 +1,76 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.TimelineImperativeCompatibilityProvider = exports.CoreTimelineImperativeContextProvider = exports.getTimelineImperativeContext = void 0;
37
+ const jsx_runtime_1 = require("react/jsx-runtime");
38
+ const react_1 = __importStar(require("react"));
39
+ const remotion_1 = require("remotion");
40
+ const PlayerTimelineImperativeContext = react_1.default.createContext(null);
41
+ const getCoreTimelineImperativeContext = () => {
42
+ return remotion_1.Internals.TimelineImperativeContext;
43
+ };
44
+ const getTimelineImperativeContext = () => {
45
+ var _a;
46
+ return (_a = getCoreTimelineImperativeContext()) !== null && _a !== void 0 ? _a : PlayerTimelineImperativeContext;
47
+ };
48
+ exports.getTimelineImperativeContext = getTimelineImperativeContext;
49
+ const CoreTimelineImperativeContextProvider = ({ children, value }) => {
50
+ const TimelineImperativeContext = getCoreTimelineImperativeContext();
51
+ if (!TimelineImperativeContext) {
52
+ return children;
53
+ }
54
+ return (jsx_runtime_1.jsx(TimelineImperativeContext.Provider, { value: value, children: children }));
55
+ };
56
+ exports.CoreTimelineImperativeContextProvider = CoreTimelineImperativeContextProvider;
57
+ const LegacyTimelineImperativeContextProvider = ({ children }) => {
58
+ const timelineContext = remotion_1.Internals.Timeline.useTimelineContext();
59
+ const frameRef = (0, react_1.useRef)(timelineContext.frame);
60
+ frameRef.current = timelineContext.frame;
61
+ const value = (0, react_1.useMemo)(() => {
62
+ return {
63
+ frameRef,
64
+ imperativePlaying: timelineContext.imperativePlaying,
65
+ audioAndVideoTags: timelineContext.audioAndVideoTags,
66
+ };
67
+ }, [timelineContext.audioAndVideoTags, timelineContext.imperativePlaying]);
68
+ return (jsx_runtime_1.jsx(PlayerTimelineImperativeContext.Provider, { value: value, children: children }));
69
+ };
70
+ const TimelineImperativeCompatibilityProvider = ({ children }) => {
71
+ if (getCoreTimelineImperativeContext()) {
72
+ return children;
73
+ }
74
+ return (jsx_runtime_1.jsx(LegacyTimelineImperativeContextProvider, { children: children }));
75
+ };
76
+ exports.TimelineImperativeCompatibilityProvider = TimelineImperativeCompatibilityProvider;
@@ -9,7 +9,7 @@ const browser_mediasession_js_1 = require("./browser-mediasession.js");
9
9
  const calculate_next_frame_js_1 = require("./calculate-next-frame.js");
10
10
  const is_backgrounded_js_1 = require("./is-backgrounded.js");
11
11
  const set_global_time_anchor_js_1 = require("./set-global-time-anchor.js");
12
- const use_player_js_1 = require("./use-player.js");
12
+ const use_player_methods_js_1 = require("./use-player-methods.js");
13
13
  const shouldForceAnchorChange = (newState) => {
14
14
  if (newState === 'suspended' || newState === 'running-to-suspended') {
15
15
  return true;
@@ -25,7 +25,8 @@ const shouldForceAnchorChange = (newState) => {
25
25
  const usePlayback = ({ loop, playbackRate, moveToBeginningWhenEnded, inFrame, outFrame, browserMediaControlsBehavior, getCurrentFrame, muted, }) => {
26
26
  const config = remotion_1.Internals.useUnsafeVideoConfig();
27
27
  const frame = remotion_1.Internals.Timeline.useTimelinePosition();
28
- const { playing, pause, emitter, isPlaying } = (0, use_player_js_1.usePlayer)();
28
+ const [playing] = remotion_1.Internals.Timeline.usePlayingState();
29
+ const { pause, emitter, isPlaying } = (0, use_player_methods_js_1.usePlayerMethods)();
29
30
  const setFrame = remotion_1.Internals.Timeline.useTimelineSetFrame();
30
31
  const sharedAudioContext = (0, react_2.useContext)(remotion_1.Internals.SharedAudioContext);
31
32
  const logLevel = remotion_1.Internals.useLogLevel();
@@ -0,0 +1,16 @@
1
+ import type { SyntheticEvent } from 'react';
2
+ import type { PlayerEmitter } from './event-emitter.js';
3
+ export type UsePlayerMethods = {
4
+ frameBack: (frames: number) => void;
5
+ frameForward: (frames: number) => void;
6
+ emitter: PlayerEmitter;
7
+ play: (e?: SyntheticEvent | PointerEvent) => void;
8
+ pause: () => void;
9
+ pauseAndReturnToPlayStart: () => void;
10
+ seek: (newFrame: number) => void;
11
+ getCurrentFrame: () => number;
12
+ isPlaying: () => boolean;
13
+ isBuffering: () => boolean;
14
+ toggle: (e?: SyntheticEvent | PointerEvent) => void;
15
+ };
16
+ export declare const usePlayerMethods: () => UsePlayerMethods;
@@ -0,0 +1,221 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.usePlayerMethods = void 0;
4
+ const react_1 = require("react");
5
+ const remotion_1 = require("remotion");
6
+ const emitter_context_js_1 = require("./emitter-context.js");
7
+ const timeline_imperative_context_js_1 = require("./timeline-imperative-context.js");
8
+ const usePlayerMethods = () => {
9
+ var _a;
10
+ const setFrame = remotion_1.Internals.Timeline.useTimelineSetFrame();
11
+ const setTimelinePosition = remotion_1.Internals.Timeline.useTimelineSetFrame();
12
+ const { setPlaying } = (0, react_1.useContext)(remotion_1.Internals.SetTimelineContext);
13
+ const timelineImperativeContext = (0, react_1.useContext)((0, timeline_imperative_context_js_1.getTimelineImperativeContext)());
14
+ const audioContext = (0, react_1.useContext)(remotion_1.Internals.SharedAudioContext);
15
+ const audioTagsContext = (0, react_1.useContext)(remotion_1.Internals.SharedAudioTagsContext);
16
+ const environment = (0, remotion_1.useRemotionEnvironment)();
17
+ const video = remotion_1.Internals.useVideo();
18
+ const config = remotion_1.Internals.useUnsafeVideoConfig();
19
+ const emitter = (0, react_1.useContext)(emitter_context_js_1.PlayerEventEmitterContext);
20
+ const playStart = (0, react_1.useRef)(0);
21
+ const fallbackFrame = (0, react_1.useRef)(null);
22
+ if (!timelineImperativeContext) {
23
+ throw new Error('Timeline imperative context is not available. This hook must be used inside a <Player> or the Remotion Studio.');
24
+ }
25
+ if (!emitter) {
26
+ throw new TypeError('Expected Player event emitter context');
27
+ }
28
+ const bufferingContext = (0, react_1.useContext)(remotion_1.Internals.BufferingContextReact);
29
+ if (!bufferingContext) {
30
+ throw new Error('Missing the buffering context. Most likely you have a Remotion version mismatch.');
31
+ }
32
+ const getCurrentFrame = (0, react_1.useCallback)(() => {
33
+ var _a, _b, _c;
34
+ if (!video) {
35
+ return ((_a = fallbackFrame.current) !== null && _a !== void 0 ? _a : (typeof window === 'undefined'
36
+ ? 0
37
+ : ((_b = window.remotion_initialFrame) !== null && _b !== void 0 ? _b : 0)));
38
+ }
39
+ const unclamped = (_c = timelineImperativeContext.frameRef.current[video.id]) !== null && _c !== void 0 ? _c : (environment.isPlayer
40
+ ? 0
41
+ : remotion_1.Internals.Timeline.getFrameForComposition(video.id));
42
+ return remotion_1.Internals.Timeline.clampFrameToCompositionRange(unclamped, video.durationInFrames);
43
+ }, [environment.isPlayer, timelineImperativeContext, video]);
44
+ const seek = (0, react_1.useCallback)((newFrame) => {
45
+ const frameToSeekTo = config
46
+ ? remotion_1.Internals.TimelinePosition.clampFrameToCompositionRange(newFrame, config.durationInFrames)
47
+ : Math.max(0, newFrame);
48
+ fallbackFrame.current = frameToSeekTo;
49
+ if (video === null || video === void 0 ? void 0 : video.id) {
50
+ if (timelineImperativeContext.frameRef.current[video.id] !== frameToSeekTo) {
51
+ timelineImperativeContext.frameRef.current = {
52
+ ...timelineImperativeContext.frameRef.current,
53
+ [video.id]: frameToSeekTo,
54
+ };
55
+ }
56
+ setTimelinePosition((currentFrames) => currentFrames[video.id] === frameToSeekTo
57
+ ? currentFrames
58
+ : { ...currentFrames, [video.id]: frameToSeekTo });
59
+ }
60
+ emitter.dispatchSeek(frameToSeekTo);
61
+ }, [
62
+ config,
63
+ emitter,
64
+ setTimelinePosition,
65
+ timelineImperativeContext,
66
+ video === null || video === void 0 ? void 0 : video.id,
67
+ ]);
68
+ const play = (0, react_1.useCallback)((e) => {
69
+ var _a;
70
+ if (timelineImperativeContext.imperativePlaying.current) {
71
+ return;
72
+ }
73
+ const lastFrameForPlayback = ((_a = config === null || config === void 0 ? void 0 : config.durationInFrames) !== null && _a !== void 0 ? _a : 1) - 1;
74
+ if (getCurrentFrame() === lastFrameForPlayback) {
75
+ seek(0);
76
+ }
77
+ audioContext === null || audioContext === void 0 ? void 0 : audioContext.resume();
78
+ /**
79
+ * Play silent audio tags to warm them up for autoplay
80
+ */
81
+ if (audioTagsContext && audioTagsContext.numberOfAudioTags > 0 && e) {
82
+ audioTagsContext.playAllAudios();
83
+ }
84
+ /**
85
+ * Play audios and videos directly here so they can benefit from
86
+ * being triggered by a click
87
+ */
88
+ timelineImperativeContext.audioAndVideoTags.current.forEach((tag) => tag.play('player play() was called and playing audio from a click'));
89
+ timelineImperativeContext.imperativePlaying.current = true;
90
+ setPlaying(true);
91
+ playStart.current = getCurrentFrame();
92
+ emitter.dispatchPlay();
93
+ }, [
94
+ audioContext,
95
+ audioTagsContext,
96
+ config === null || config === void 0 ? void 0 : config.durationInFrames,
97
+ emitter,
98
+ getCurrentFrame,
99
+ seek,
100
+ setPlaying,
101
+ timelineImperativeContext,
102
+ ]);
103
+ const pause = (0, react_1.useCallback)(() => {
104
+ if (timelineImperativeContext.imperativePlaying.current) {
105
+ timelineImperativeContext.imperativePlaying.current = false;
106
+ setPlaying(false);
107
+ emitter.dispatchPause();
108
+ audioContext === null || audioContext === void 0 ? void 0 : audioContext.suspend();
109
+ }
110
+ }, [audioContext, emitter, setPlaying, timelineImperativeContext]);
111
+ const pauseAndReturnToPlayStart = (0, react_1.useCallback)(() => {
112
+ if (timelineImperativeContext.imperativePlaying.current) {
113
+ timelineImperativeContext.imperativePlaying.current = false;
114
+ fallbackFrame.current = playStart.current;
115
+ if (config) {
116
+ timelineImperativeContext.frameRef.current = {
117
+ ...timelineImperativeContext.frameRef.current,
118
+ [config.id]: playStart.current,
119
+ };
120
+ setTimelinePosition((currentFrames) => ({
121
+ ...currentFrames,
122
+ [config.id]: playStart.current,
123
+ }));
124
+ setPlaying(false);
125
+ emitter.dispatchPause();
126
+ }
127
+ }
128
+ }, [
129
+ config,
130
+ emitter,
131
+ setPlaying,
132
+ setTimelinePosition,
133
+ timelineImperativeContext,
134
+ ]);
135
+ const videoId = video === null || video === void 0 ? void 0 : video.id;
136
+ const lastFrame = ((_a = config === null || config === void 0 ? void 0 : config.durationInFrames) !== null && _a !== void 0 ? _a : 1) - 1;
137
+ const frameBack = (0, react_1.useCallback)((frames) => {
138
+ var _a, _b;
139
+ if (!videoId) {
140
+ return null;
141
+ }
142
+ if (timelineImperativeContext.imperativePlaying.current) {
143
+ return;
144
+ }
145
+ const previousFrame = (_b = (_a = timelineImperativeContext.frameRef.current[videoId]) !== null && _a !== void 0 ? _a : window.remotion_initialFrame) !== null && _b !== void 0 ? _b : 0;
146
+ const newFrame = Math.max(0, previousFrame - frames);
147
+ if (previousFrame === newFrame) {
148
+ return;
149
+ }
150
+ timelineImperativeContext.frameRef.current = {
151
+ ...timelineImperativeContext.frameRef.current,
152
+ [videoId]: newFrame,
153
+ };
154
+ setFrame((currentFrames) => currentFrames[videoId] === newFrame
155
+ ? currentFrames
156
+ : { ...currentFrames, [videoId]: newFrame });
157
+ }, [setFrame, timelineImperativeContext, videoId]);
158
+ const frameForward = (0, react_1.useCallback)((frames) => {
159
+ var _a, _b;
160
+ if (!videoId) {
161
+ return null;
162
+ }
163
+ if (timelineImperativeContext.imperativePlaying.current) {
164
+ return;
165
+ }
166
+ const previousFrame = (_b = (_a = timelineImperativeContext.frameRef.current[videoId]) !== null && _a !== void 0 ? _a : window.remotion_initialFrame) !== null && _b !== void 0 ? _b : 0;
167
+ const newFrame = Math.min(lastFrame, previousFrame + frames);
168
+ if (previousFrame === newFrame) {
169
+ return;
170
+ }
171
+ timelineImperativeContext.frameRef.current = {
172
+ ...timelineImperativeContext.frameRef.current,
173
+ [videoId]: newFrame,
174
+ };
175
+ setFrame((currentFrames) => currentFrames[videoId] === newFrame
176
+ ? currentFrames
177
+ : { ...currentFrames, [videoId]: newFrame });
178
+ }, [lastFrame, setFrame, timelineImperativeContext, videoId]);
179
+ const toggle = (0, react_1.useCallback)((e) => {
180
+ if (timelineImperativeContext.imperativePlaying.current) {
181
+ pause();
182
+ }
183
+ else {
184
+ play(e);
185
+ }
186
+ }, [pause, play, timelineImperativeContext]);
187
+ const isPlaying = (0, react_1.useCallback)(() => {
188
+ return timelineImperativeContext.imperativePlaying.current;
189
+ }, [timelineImperativeContext]);
190
+ const isBuffering = (0, react_1.useCallback)(() => {
191
+ return bufferingContext.buffering.current;
192
+ }, [bufferingContext.buffering]);
193
+ return (0, react_1.useMemo)(() => {
194
+ return {
195
+ frameBack,
196
+ frameForward,
197
+ emitter,
198
+ play,
199
+ pause,
200
+ seek,
201
+ getCurrentFrame,
202
+ isPlaying,
203
+ isBuffering,
204
+ pauseAndReturnToPlayStart,
205
+ toggle,
206
+ };
207
+ }, [
208
+ emitter,
209
+ frameBack,
210
+ frameForward,
211
+ getCurrentFrame,
212
+ isBuffering,
213
+ isPlaying,
214
+ pause,
215
+ pauseAndReturnToPlayStart,
216
+ play,
217
+ seek,
218
+ toggle,
219
+ ]);
220
+ };
221
+ exports.usePlayerMethods = usePlayerMethods;