I am using react with typescript. I have one video component in which I am playing a video using a video tag.
I am trying to print the total duration and current duration of the video in a p tag but the updates are not reflacting.
Here is my code:
import "./styles.css";
import { useRef, useState, useEffect } from "react";
export default function App() {
const frames: number = 25;
const vRef = useRef<HTMLVideoElement>(null);
const [currentFrame, setCurrentFrame] = useState(0);
const [videoDur, setvideoTotalDuration] = useState(0);
const [curTime, setVideoCurrentTime] = useState(0);
useEffect(() => {
let ref = vRef.current;
if (ref) {
let videoTotalDuration: number = ref.duration;
let videoDuration: number = ref.currentTime;
let videoCurrentFrame: number = Math.floor(ref.currentTime * frames);
setCurrentFrame(videoCurrentFrame);
setvideoTotalDuration(videoTotalDuration);
setVideoCurrentTime(videoDuration);
}
}, [currentFrame, videoDur, curTime]);
return (
<div className="container">
<video className="video" ref={vRef} autoPlay muted>
<source src="https://www.w3schools.com/html/movie.mp4" />
</video>
<p>
{curTime}/{videoDur}
</p>
<label> {currentFrame} </label>
</div>
);
}
>Solution :
In the useEffect hook’s deps(the second argument that you pass) you are setting the arguments that you want to change, this is wrong, you have to pass arguments that you want the function to be called when those arguments change but in this case, the argument that you have passed is not going to change without calling the hook function and if it changes it is going to put you in a loop that will affect the efficiency of your program and eat computer’s ram.
Furthermore, the useEffect hook is not the right way to take this action you need to use the onTimeUpdate event handler on the video element like below:
import "./styles.css";
import { useRef, useState, useEffect } from "react";
export default function App() {
const frames: number = 25;
const vRef = useRef<HTMLVideoElement>(null);
const [currentFrame, setCurrentFrame] = useState(0);
const [videoDur, setvideoTotalDuration] = useState(0);
const [curTime, setVideoCurrentTime] = useState(0);
const onTimeUpdate = () => {
let ref = vRef.current;
if (ref) {
let videoTotalDuration: number = ref.duration;
let videoDuration: number = ref.currentTime;
let videoCurrentFrame: number = Math.floor(ref.currentTime * frames);
setCurrentFrame(videoCurrentFrame);
setvideoTotalDuration(videoTotalDuration);
setVideoCurrentTime(videoDuration);
}
};
return (
<div className="container">
<video className="video" ref={vRef} autoPlay muted onTimeUpdate={onTimeUpdate}>
<source src="https://www.w3schools.com/html/movie.mp4" />
</video>
<p>
{curTime}/{videoDur}
</p>
<label> {currentFrame} </label>
</div>
);
}