Skip to content

Commit

Permalink
Merge pull request #1366 from remotion-dev/1360-allow-timeupdate-even…
Browse files Browse the repository at this point in the history
…t-frequency-to-be-increased
  • Loading branch information
JonnyBurger committed Oct 4, 2022
2 parents cbc5186 + b0bf6d5 commit 439419a
Show file tree
Hide file tree
Showing 4 changed files with 57 additions and 9 deletions.
35 changes: 32 additions & 3 deletions packages/docs/docs/player/api.md
Original file line number Diff line number Diff line change
Expand Up @@ -497,7 +497,7 @@ useEffect(() => {

### `seeked`

Fired when the time position changes. You may get the current frame by reading it from `e.detail.frame`.
Fired when the time position is changed by the user using the playback bar or using [`seek()`](#seek). You may get the current frame by reading it from `e.detail.frame`.

```tsx twoslash
import { PlayerRef } from "@remotion/player";
Expand All @@ -512,7 +512,9 @@ playerRef.current.addEventListener("seeked", (e) => {
});
```

This event fires on every single frame update. Don't update your UI based on this event as it will cause a lot of rerenders. Use the [`timeupdate`](#timeupdate) event instead.
This event fires on every single frame update. Prefer the [`timeupdate`](#timeupdate) event instead if the excessive rerenders cause slowdown.

This event is only fired during seeking. Use [`frameupdate`](#frameupdate) instead if you also want to get time updates during playback.

### `ended`

Expand All @@ -532,7 +534,7 @@ Fires when the video has paused or ended.

### `timeupdate`

Fires periodically when the video is playing. Unlike the [`seeked`](#seeked) event, frames are skipped, and the event is throttled to only fire a few times a second.
Fires periodic time updates when the video is playing. Unlike the [`seeked`](#seeked) event, frames are skipped, and the event is throttled to only fire a few times a second at most every 250ms.

```tsx twoslash
import { PlayerRef } from "@remotion/player";
Expand All @@ -547,6 +549,33 @@ playerRef.current.addEventListener("timeupdate", (e) => {
});
```

Prefer the [`seeked`](#seeked) event if you only want to get time updates during seeking.

Prefer the [`frameupdate`](#frameupdate) event if you need an update for every single frame.

### `frameupdate`

_Available from v3.2.26_

Fires whenever the current time has changed, during both playback and seeking.

```tsx twoslash
import { PlayerRef } from "@remotion/player";
import { useRef } from "react";
const playerRef = useRef<PlayerRef>(null);
if (!playerRef.current) {
throw new Error();
}
// ---cut---
playerRef.current.addEventListener("frameupdate", (e) => {
console.log("current frame is " + e.detail.frame); // current frame is 120
});
```

Prefer the [`seeked`](#seeked) event if you only want to get time updates during seeking.

Prefer the [`timeupdate`](#timeupdate) event if you only need periodical updates (at most every 250ms).

### `fullscreenchange`

_Available from v3.2.0_
Expand Down
17 changes: 11 additions & 6 deletions packages/player-example/src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,7 @@ const ControlsOnly: React.FC<{
setLogs((l) => [...l, 'pausing ' + Date.now()]);
};

const seekedCallbackLitener: CallbackListener<'seeked'> = (e) => {
const seekedCallbackListener: CallbackListener<'seeked'> = (e) => {
setLogs((l) => [...l, 'seeked to ' + e.detail.frame + ' ' + Date.now()]);
};

Expand All @@ -115,9 +115,12 @@ const ControlsOnly: React.FC<{
setLogs((l) => [...l, 'error ' + Date.now()]);
};

const timeupdateCallbackLitener: CallbackListener<'timeupdate'> = (e) => {
const timeupdateCallbackListener: CallbackListener<'timeupdate'> = (e) => {
setLogs((l) => [...l, 'timeupdate ' + e.detail.frame]);
};
const frameupdateCallbackListener: CallbackListener<'frameupdate'> = (e) => {
setLogs((l) => [...l, 'frameupdate ' + e.detail.frame]);
};

const ratechangeCallbackListener: CallbackListener<'ratechange'> = (e) => {
setLogs((l) => [
Expand All @@ -141,10 +144,11 @@ const ControlsOnly: React.FC<{

current.addEventListener('play', playCallbackListener);
current.addEventListener('pause', pausedCallbackLitener);
current.addEventListener('seeked', seekedCallbackLitener);
current.addEventListener('seeked', seekedCallbackListener);
current.addEventListener('ended', endedCallbackListener);
current.addEventListener('error', errorCallbackListener);
current.addEventListener('timeupdate', timeupdateCallbackLitener);
current.addEventListener('timeupdate', timeupdateCallbackListener);
current.addEventListener('frameupdate', frameupdateCallbackListener);
current.addEventListener('ratechange', ratechangeCallbackListener);
current.addEventListener(
'fullscreenchange',
Expand All @@ -154,10 +158,11 @@ const ControlsOnly: React.FC<{
return () => {
current.removeEventListener('play', playCallbackListener);
current.removeEventListener('pause', pausedCallbackLitener);
current.removeEventListener('seeked', seekedCallbackLitener);
current.removeEventListener('seeked', seekedCallbackListener);
current.removeEventListener('ended', endedCallbackListener);
current.removeEventListener('error', errorCallbackListener);
current.removeEventListener('timeupdate', timeupdateCallbackLitener);
current.removeEventListener('timeupdate', timeupdateCallbackListener);
current.removeEventListener('frameupdate', frameupdateCallbackListener);
current.removeEventListener('ratechange', ratechangeCallbackListener);
current.removeEventListener(
'fullscreenchange',
Expand Down
10 changes: 10 additions & 0 deletions packages/player/src/event-emitter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,10 @@ type TimeUpdateEventPayload = {
frame: number;
};

type FrameUpdateEventPayload = {
frame: number;
};

type RateChangeEventPayload = {
playbackRate: number;
};
Expand All @@ -26,6 +30,7 @@ type StateEventMap = {
ended: undefined;
error: ErrorPayload;
timeupdate: TimeUpdateEventPayload;
frameupdate: FrameUpdateEventPayload;
fullscreenchange: FullscreenChangeEventPayload;
};

Expand All @@ -46,6 +51,7 @@ export class PlayerEmitter {
ratechange: [],
seeked: [],
timeupdate: [],
frameupdate: [],
fullscreenchange: [],
};

Expand Down Expand Up @@ -110,6 +116,10 @@ export class PlayerEmitter {
this.dispatchEvent('timeupdate', event);
}

dispatchFrameUpdate(event: FrameUpdateEventPayload) {
this.dispatchEvent('frameupdate', event);
}

dispatchFullscreenChangeUpdate(event: FullscreenChangeEventPayload) {
this.dispatchEvent('fullscreenchange', event);
}
Expand Down
4 changes: 4 additions & 0 deletions packages/player/src/use-playback.ts
Original file line number Diff line number Diff line change
Expand Up @@ -113,4 +113,8 @@ export const usePlayback = ({

return () => clearInterval(interval);
}, [emitter]);

useEffect(() => {
emitter.dispatchFrameUpdate({frame});
}, [emitter, frame]);
};

1 comment on commit 439419a

@vercel
Copy link

@vercel vercel bot commented on 439419a Oct 4, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please sign in to comment.