'How to Map the Buffer TimeRange Data From an HTML5 Video Player Ref to a Progress Bar?
I'm basically just trying to emulate the buffer bar from the default HTML5 video player or like on YouTube.
I am making a custom JSX HTML5 video player control-bar but have gotten stuck because I am not sure how to get/use the buffer progress data object from the videoRef
. It seems like I am supposed to use the buffers end()
function and the TimeRanges
object from the video's ref, but I haven't seen any examples or documentation on how it can be used to calculate the buffer bar.
Question: How can I use the buffer object in the videoRef
from the video player and map the data to my custom video control-bar's buffer progress-bar?
Do I somehow detect the progress of the stream's buffer, is there some kind of event?
Example code:
export default function App() {
const videoRef = React.useRef();
const [videoProgress, setVideoProgress] = useState(0);
const [videoBufferProgress, setVideoBufferProgress] = useState(0);
const [videoTime, setVideoTime] = useState(0);
//updates the video progress bar 1-100%, works fine
function updateTime() {
setVideoProgress(
(videoRef.current.currentTime / videoRef.current.duration) * 100
);
setVideoTime(videoRef.current.currentTime);
}
//get buffer information so that I can use it to fill the buffer progress bar, it doesnt work rn
function updateBuffer() {
//setVideoBufferProgress()
console.log(videoRef.current.buffered.end(0));
}
useEffect(() => {
videoRef.current.addEventListener("loadeddata", () => updateBuffer());
videoRef.current.addEventListener("timeupdate", () => updateTime());
return () => {
videoRef.current.removeEventListener("loadeddata", () => updateBuffer());
videoRef.current.removeEventListener("timeupdate", () => updateTime());
};
}, []);
return (
<div>
<video ref={videoRef}>
<source src={`/api/video/stream/480/624593ba5a88168159a56169`} type="video/mp4"/>
</video>
<div>
//video timeline bar, this works fine
<ProgressBar
now={videoProgress}
/>
//video buffer bar, this doesnt work
<ProgressBar
now={videoBufferProgress}
/>
</div>
</div>
);
}
Solution 1:[1]
I figured it out. You just listen for the progress
event.
function updateBuffer() {
setVideoBufferProgress((videoRef.current.buffered.end(0) / videoRef.current.duration) * 100); //provides the last second of the video that has been loaded/buffered
}
//use the progress event to update the buffer for when new data is loaded
useEffect(() => {
videoRef.current &&
videoRef.current.addEventListener("loadeddata", () => updateBuffer());
videoRef.current &&
videoRef.current.addEventListener("progress", () => updateBuffer());
videoRef.current &&
videoRef.current.addEventListener("timeupdate", () => updateTime());
}, [videoRef.current]);
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 |