You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
105 lines
2.3 KiB
105 lines
2.3 KiB
import type { MouseEvent } from 'react'
|
|
import {
|
|
useCallback,
|
|
useState,
|
|
useRef,
|
|
} from 'react'
|
|
import ReactPlayer from 'react-player'
|
|
|
|
import once from 'lodash/once'
|
|
import throttle from 'lodash/throttle'
|
|
|
|
import { useFullscreen } from './useFullscreen'
|
|
import { useVolume } from './useVolume'
|
|
|
|
type ProgressState = {
|
|
loaded: number,
|
|
loadedSeconds: number,
|
|
played: number,
|
|
playedSeconds: number,
|
|
}
|
|
|
|
export type Props = {
|
|
onPlayingChange: (playing: boolean) => void,
|
|
onProgressChange: (seconds: number) => void,
|
|
url: string,
|
|
}
|
|
|
|
export const useVideoPlayer = ({
|
|
onPlayingChange,
|
|
onProgressChange: progressChangeCallback,
|
|
}: Props) => {
|
|
const [ready, setReady] = useState(false)
|
|
const [playing, setPlaying] = useState(false)
|
|
const [duration, setDuration] = useState(0)
|
|
const [loadedProgress, setLoadedProgress] = useState(0)
|
|
const [playedProgress, setPlayedProgress] = useState(0)
|
|
const [playedSeconds, setPlayedSeconds] = useState(0)
|
|
const wrapperRef = useRef<HTMLDivElement>(null)
|
|
const playerRef = useRef<ReactPlayer>(null)
|
|
|
|
const startPlaying = useCallback(once(() => {
|
|
setReady(true)
|
|
setPlaying(true)
|
|
onPlayingChange(true)
|
|
}), [])
|
|
|
|
const togglePlaying = () => {
|
|
if (ready) {
|
|
setPlaying(!playing)
|
|
onPlayingChange(!playing)
|
|
}
|
|
}
|
|
|
|
const onPlayerClick = (e: MouseEvent<HTMLDivElement>) => {
|
|
if (e.target === playerRef.current?.getInternalPlayer()) {
|
|
togglePlaying()
|
|
}
|
|
}
|
|
|
|
const setPlayerProgress = useCallback(
|
|
throttle((value: number) => {
|
|
playerRef.current?.seekTo(value, 'fraction')
|
|
}, 100),
|
|
[],
|
|
)
|
|
|
|
const onProgressChange = useCallback((progress: number) => {
|
|
setPlayedProgress(progress * 100)
|
|
setPlayerProgress(progress)
|
|
}, [
|
|
setPlayedProgress,
|
|
setPlayerProgress,
|
|
])
|
|
|
|
const setProgress = ({
|
|
loaded,
|
|
played,
|
|
playedSeconds: seconds,
|
|
}: ProgressState) => {
|
|
setLoadedProgress(loaded * 100)
|
|
setPlayedProgress(played * 100)
|
|
setPlayedSeconds(seconds)
|
|
|
|
progressChangeCallback(seconds)
|
|
}
|
|
|
|
return {
|
|
duration,
|
|
loadedProgress,
|
|
onPlayerClick,
|
|
onProgressChange,
|
|
playedProgress,
|
|
playedSeconds,
|
|
playerRef,
|
|
playing,
|
|
setDuration,
|
|
setProgress,
|
|
setReady,
|
|
startPlaying,
|
|
togglePlaying,
|
|
wrapperRef,
|
|
...useFullscreen(wrapperRef),
|
|
...useVolume(),
|
|
}
|
|
}
|
|
|