Video (HTMLMediaElement) duration property does not return full length of video

I would like to display the total duration of a video in a <video> HTML Media element. The only way to get this as far I can see is by using the duration property:

HTML

<video src="/videos/test.mp4">This is a 47 second video</video>

Script

  const video = document.querySelector("video");
    
    video.addEventListener("loadedmetadata", ()=>{
      console.log(video.duration); // returns only 5 seconds
    });
    
    video.addEventListener("loadeddata", ()=>{
      console.log(video.duration); // returns only 5 seconds
    });
    
    video.addEventListener("durationchange", ()=>{
      console.log(video.duration); // increases as video starts plays
    });

However, the duration will only show 0:05 when the page loads (using a formatTime() function not shown in code above).

The HTMLMediaElement spec says duration is “A read-only double-precision floating-point value indicating the total duration of the media in seconds”. https://developer.mozilla.org/en-US/docs/Web/API/HTMLMediaElement/duration

The time only starts updating when the user clicks on play, and increases like this:

0:05
0:06
...
0:34
0:37
...
0:42
0:47

Cleary video.duration is only returning the first 5 seconds that has been loaded and then starts increasing as more data is loaded. Why does it not return the total length of the video as its supposed to from the metadata?

This causes more problems than just showing the correct total duration. The video playhead keeps skipping back each time more data is loaded because it doesn’t know how long the video will be until starts playing/loading.

Any suggestions on what’s going on?