parent
56b5df1d4b
commit
3c93cc1056
9 changed files with 142 additions and 67 deletions
@ -1,96 +1,115 @@ |
||||
import { useRef, useMemo, useEffect, useState, useReducer, useContext } from 'react'; |
||||
import { useRef, useMemo, useEffect, useState, useReducer, useContext, useCallback } from 'react'; |
||||
import useMandatoryUpdate from '@/utils/useMandatoryUpdate'; |
||||
import { FlowContext } from '@/core/context'; |
||||
|
||||
export const useVideo = (videoEle: HTMLVideoElement | null) => { |
||||
export const useVideo = ({ onPause, onPlay, onTimeChange, onEndEd }: any) => { |
||||
const forceUpdate = useMandatoryUpdate(); |
||||
|
||||
const reviceProps = useContext(FlowContext); |
||||
|
||||
const videoRef = useRef<HTMLVideoElement | null>(null); |
||||
|
||||
const [isPlay, setIsPlay] = useState<boolean>(false); |
||||
|
||||
const [currentTime, setCurrentTime] = useState<number>(0); |
||||
const { videoRef: videoEle, dispatch, videoFlow } = reviceProps; |
||||
|
||||
const [duration, setDuration] = useState<number>(0); |
||||
|
||||
const [bufferedTime, setBufferedTime] = useState<number>(0); |
||||
const videoParameter = useRef<any>({ |
||||
isPlay: false, |
||||
currentTime: 0, |
||||
duration: 0, |
||||
bufferedTime: 0, |
||||
isPictureinpicture: false, |
||||
}); |
||||
|
||||
const [isPictureinpicture, setIsPictureinpicture] = useState<boolean>(false); |
||||
const videoRef = useRef<HTMLVideoElement | null>(null); |
||||
|
||||
const interval = useRef<any>(null); |
||||
const interval = useRef<NodeJS.Timeout | null>(null!); |
||||
|
||||
videoRef.current = videoEle; |
||||
|
||||
useEffect(() => { |
||||
// forceUpdate();
|
||||
if (videoRef.current) { |
||||
/** |
||||
* @description 监听总时长 |
||||
*/ |
||||
videoRef.current.addEventListener('canplay', () => { |
||||
setDuration(videoRef.current!.duration); |
||||
videoParameter.current = { |
||||
...videoParameter.current, |
||||
duration: videoRef.current!.duration, |
||||
}; |
||||
}); |
||||
/** |
||||
* @description 监听缓冲 |
||||
*/ |
||||
videoRef.current.addEventListener('progress', () => { |
||||
if (videoRef.current!.buffered.length >= 1) { |
||||
setBufferedTime(videoRef.current!.buffered.end(0)); |
||||
videoParameter.current = { |
||||
...videoParameter.current, |
||||
bufferedTime: videoRef.current!.buffered.end(0), |
||||
}; |
||||
} |
||||
}); |
||||
/** |
||||
* @description 已经进入画中画 |
||||
*/ |
||||
videoRef.current.addEventListener('enterpictureinpicture', () => { |
||||
setIsPictureinpicture(true); |
||||
videoParameter.current = { |
||||
...videoParameter.current, |
||||
isPictureinpicture: true, |
||||
}; |
||||
}); |
||||
/** |
||||
* @description 已退出画中画模式 |
||||
*/ |
||||
videoRef.current.addEventListener('leavepictureinpicture', () => { |
||||
setIsPictureinpicture(false); |
||||
videoParameter.current = { |
||||
...videoParameter.current, |
||||
isPictureinpicture: false, |
||||
}; |
||||
}); |
||||
// 定时器用于更新当前视频时间
|
||||
interval.current = setInterval(() => { |
||||
setIsPlay(videoRef.current!.paused ? false : true); |
||||
setCurrentTime(videoRef.current!.currentTime); |
||||
/** |
||||
* 强制更新 |
||||
*/ |
||||
forceUpdate(); |
||||
videoParameter.current = { |
||||
...videoParameter.current, |
||||
currentTime: videoRef.current!.currentTime, |
||||
isPlay: videoRef.current!.paused ? false : true, |
||||
}; |
||||
}, 1); |
||||
videoRef.current.addEventListener('pause', () => playChange('pause')); |
||||
videoRef.current.addEventListener('play', () => playChange('play')); |
||||
videoRef.current.addEventListener('pause', pauseChange); |
||||
videoRef.current.addEventListener('play', playChange); |
||||
videoRef.current.addEventListener('timeupdate', timeupdate); |
||||
videoRef.current.addEventListener('ended', endedChange); |
||||
} |
||||
return () => { |
||||
interval.current && clearInterval(interval.current); |
||||
}; |
||||
}, [videoEle, videoRef.current]); |
||||
|
||||
const playChange = (status: string) => { |
||||
// console.log(`status`, status);
|
||||
const pauseChange = () => { |
||||
onPause && onPause(videoParameter.current); |
||||
}; |
||||
const playChange = () => { |
||||
onPlay && onPlay(videoParameter.current); |
||||
}; |
||||
|
||||
const timeupdate = () => { |
||||
// console.log(`2222222`, videoRef.current!.currentTime);
|
||||
onTimeChange && onTimeChange(videoParameter.current); |
||||
}; |
||||
const endedChange = () => { |
||||
onEndEd && onEndEd(videoParameter.current); |
||||
}; |
||||
|
||||
const handleChangePlayState = () => { |
||||
setIsPlay((pre) => { |
||||
if (isPlay) { |
||||
if (videoParameter.current.isPlay) { |
||||
videoRef.current!.pause(); |
||||
} else { |
||||
videoRef.current!.play(); |
||||
} |
||||
return !pre; |
||||
}); |
||||
videoParameter.current = { |
||||
...videoParameter.current, |
||||
isPlay: videoRef.current!.paused ? false : true, |
||||
}; |
||||
}; |
||||
return { |
||||
isPlay, |
||||
setIsPlay, |
||||
handleChangePlayState, |
||||
currentTime, |
||||
duration, |
||||
bufferedTime, |
||||
isPictureinpicture, |
||||
...videoParameter.current, |
||||
}; |
||||
}; |
||||
|
Loading…
Reference in new issue