I have a React project where I'm having a slider between 0 and 700 and depending on which step is chosen it gets value between 1 and 8 (so 700 is obviously 8).
<div className={styles.slider_container}>
<input type='range' className={styles.slider} step={100} min={0} max={700} value={value} onChange={(e) => setValue(parseInt(e.target.value))} />
</div>
I also have an frames array which consists of bunch of objects which look like:
const [frames, setFrames] = useState([
{
id: 1,
title: 'Touch',
start: 0,
idle: 5.82,
end: 7.10,
},
{
id: 2,
title: 'Display',
start: 7.11,
idle: 8.5,
end: 10.12,
},
...
];
and I call my VideoPlayer component as:
<div className={styles.content}>
<VideoPlayer frames={frames} currentComponent={selectedComponent} prevComponent={prevComponent} startTime={frames.find((item) => item.id === selectedComponent).start} endTime={frames.find((item) => item.id === selectedComponent).end} idleTime={frames.find((item) => item.id === selectedComponent).idle} />
</div>
VideoPlayer component is just using react-video library to display the video and play/pause/seek through it. and it is just like:
const [currentTime, setCurrentTime] = useState(startTime);
const playerRef = useRef(null);
useEffect(() => {
if (currentTime >= idleTime) {
playerRef.current.pause();
}
}, [currentTime]);
useEffect(() => {
if (prevComponent) {
if (prevComponent < currentComponent) {
const time = (frames.find(item => item.id === prevComponent).end); // endTime of previous component;
if (currentTime <= time) {
playerRef.current.play();
if (time - currentTime <= 0.3) {
playerRef.current.pause();
playerRef.current.seek(startTime);
playerRef.current.play();
}
}
}
}
}, [currentTime, currentComponent]);
useEffect(() => {
if (prevComponent > currentComponent) {
playerRef.current.seek(startTime);
playerRef.current.play();
}
}, [currentComponent]);
return (
<Player
ref={playerRef}
autoPlay
startTime={0}
muted={true}
onTimeUpdate={(e) => {
setCurrentTime(parseFloat(e.target.currentTime));
}}
>
<source src="./video.mp4" style={{ height: '100vh' }} />
<ControlBar autoHide={false} disableCompletely={true} disableDefaultControls={true} />
</Player>
It works fine with going forward (I mean from step 2 to step 3 or step 4), but I have a problem in
useEffect(() => {
if (prevComponent > currentComponent) {
playerRef.current.seek(startTime);
playerRef.current.play();
}
}, [currentComponent]);
where if I select a component (or step) 2 after step 3 (if we go back), it should play the video till endTime of the prevComponent and then just back to startTime of currentComponent and continue playing till idleTime of the currentComponent.
I would apply the
whileloop toif (prevComponent > currentComponent)condition, so it would just play the video till the difference betweentimeandcurrentTimeis less or equal to zero, if so, just break out from the loop and then useseek()function to jump to another frame/time you want.