1

The HTML5 <audio> and <video> tags support a duration property. I am curious how, without downloading the entire audio/video source file is the browser able to determine the duration of the media?

I am asking because I would like to implement the same functionality in a backend service I am writing that will:

  1. Accept a url for an mp3
  2. Determine the length (in seconds) of the file, without downloading the entire file
ThaDon
  • 7,826
  • 9
  • 52
  • 84

1 Answers1

1

Most video containers contain both the visual and audio elements and also a metadata block that describes things like the duration, the colorspace, the codecs used and the offset for each frame (useful when seeking). In a typical video encoded for the web as MP4 this block (aka the MOOV atom) defaults to the end of the file (as the frame location won't be known until the end) unless a second pass has been performed to move it to the front eg:

ffmpeg -i source.mp4 -c:a copy -c:v copy -movflags faststart destination.mp4

(copies the audio and video unchanged, just moves the metadata to the start to enable faster access)

You might have experienced some web video where you can seek almost immediately with an MP4 and some where you can't accurately seek until the file has been fully loaded... this is because the browser has to make 'guesses' until it receives that metadata

For mp3 files specifically you could use something like this - to request the server gives you just the ID3 Tag and eTag data (last 127 and the 227 bytes) without having to download the whole file

Offbeatmammal
  • 7,970
  • 2
  • 33
  • 52
  • I could see that working for a file on disk, but how about one that is out on a webserver somewhere? The ` – ThaDon Dec 24 '18 at 22:40
  • if the server that the file is hosted on supports byte range requests you can ask for the specific block you want. Because the mp3 tag location is known then it's possible the browser already does that (grabs metadata first, then continues) – Offbeatmammal Dec 24 '18 at 22:43
  • thanks. I’m now wondering if I should have my front-end just load the ` – ThaDon Dec 24 '18 at 23:10