sudo-archive/src/components/video/hooks/useVideoPlayer.ts

75 lines
2.0 KiB
TypeScript
Raw Normal View History

2023-01-08 14:37:16 +00:00
import React, { MutableRefObject, useEffect, useState } from "react";
import {
initialControls,
PlayerControls,
populateControls,
} from "./controlVideo";
export type PlayerState = {
isPlaying: boolean;
isPaused: boolean;
2023-01-08 15:23:42 +00:00
isSeeking: boolean;
isFullscreen: boolean;
2023-01-08 14:37:16 +00:00
} & PlayerControls;
2023-01-08 15:23:42 +00:00
export const initialPlayerState: PlayerState = {
2023-01-08 14:37:16 +00:00
isPlaying: false,
isPaused: true,
2023-01-08 15:23:42 +00:00
isFullscreen: false,
isSeeking: false,
2023-01-08 14:37:16 +00:00
...initialControls,
};
type SetPlayer = (s: React.SetStateAction<PlayerState>) => void;
function readState(player: HTMLVideoElement, update: SetPlayer) {
const state = {
...initialPlayerState,
};
state.isPaused = player.paused;
state.isPlaying = !player.paused;
2023-01-08 15:23:42 +00:00
state.isFullscreen = !!document.fullscreenElement;
state.isSeeking = player.seeking;
2023-01-08 14:37:16 +00:00
update(state);
}
function registerListeners(player: HTMLVideoElement, update: SetPlayer) {
player.addEventListener("pause", () => {
update((s) => ({ ...s, isPaused: true, isPlaying: false }));
});
player.addEventListener("play", () => {
update((s) => ({ ...s, isPaused: false, isPlaying: true }));
});
2023-01-08 15:23:42 +00:00
player.addEventListener("seeking", () => {
update((s) => ({ ...s, isSeeking: true }));
});
player.addEventListener("seeked", () => {
update((s) => ({ ...s, isSeeking: false }));
});
document.addEventListener("fullscreenchange", () => {
update((s) => ({ ...s, isFullscreen: !!document.fullscreenElement }));
});
2023-01-08 14:37:16 +00:00
}
2023-01-08 15:23:42 +00:00
export function useVideoPlayer(
ref: MutableRefObject<HTMLVideoElement | null>,
wrapperRef: MutableRefObject<HTMLDivElement | null>
) {
2023-01-08 14:37:16 +00:00
const [state, setState] = useState(initialPlayerState);
useEffect(() => {
const player = ref.current;
2023-01-08 15:23:42 +00:00
const wrapper = wrapperRef.current;
if (player && wrapper) {
2023-01-08 14:37:16 +00:00
readState(player, setState);
registerListeners(player, setState);
2023-01-08 15:23:42 +00:00
setState((s) => ({ ...s, ...populateControls(player, wrapper) }));
2023-01-08 14:37:16 +00:00
}
2023-01-08 15:23:42 +00:00
}, [ref, wrapperRef]);
2023-01-08 14:37:16 +00:00
return {
playerState: state,
};
}