0
votes

I started using AAC audio files instead of MP3 to avoid time drift but now I see myself with a problem in Chrome that reports an incorrect audio duration.

I have a sample audio that can help illustrate the problem. The real duration of the audio is 22:01 but instead Chrome shows a duration of 20:13 but if you actually play the end of the audio, the duration starts changing until it gets to be the correct one.

Sample AAC audio here!

What can be the source of the problem? I read that maybe it can be solved by inputting the correct metadata, but it seems to be correct...

Some interesting data:

MP3 in Chrome shows 21:58.

AAC in Safari shows 22:10.

MP3 in Safari shows the exact duration 22:01.

Is there any chance to make it work everywhere the same??

I leave the MP3 file just in case here

2

2 Answers

8
votes

Cause

The problem is that AAC is a streamed format. This means that no global file header is provided as with a container format (for example like "mp4"), so the browser has to guess the time based on bit-rate from the initially loaded packet headers (ADTS) and file length provided by the server.

Since the browser doesn't know the actual sample length until the entire stream is consumed the result will vary depending on how the browser (or the underlying system) try to predict the duration time.

AAC can also be encoded with variable bit rate (VBR) which makes it very hard to correctly predict the duration since the bit-rate found at the beginning may not be the bit-rate used for other sample packets later on.

There is of course also the chance that the file/encoding is corrupt or faulty.

These same challenges also applies to MP3 files btw. which is why they sometimes are shown with an incorrect duration as well.

Workarounds

The first is to encode the AAC using constant bit-rate (CBR). This will allow the browser to predict the time more reliable as VBR can throw off the calculations at any point if the variations are noticable. This will most likely affect the file size.

If CBR is not an option, one workaround is to supply a container format for the AAC stream such as MP4 which can store the duration in the global header which is loaded at the beginning - MP4s can be consumed as buffered audio by the Audio element. When doing this you will get the correct time (with perhaps some rounding error for the minor digit):

AAC loaded in MP4 container in Firefox:
snapshot using mp4 container in firefox

AAC loaded in MP4 container in Chrome
snapshot using mp4 container in chrome

To produce a MP4 container for AAC you can use for example the free ffmpeg with these arguments which will copy the AAC as-is (no re-encoding takes place so the result will be of the same quality and bit-rate as before):

ffmpeg.exe -i "Lesson+53-A.aac" -c:a copy "Lesson+53-A.mp4"

you will also see ffmpeg point out this issue:

[aac @ 0000000001c624a0] Estimating duration from bitrate, this may be inaccurate [...]

Another perhaps less convenient workaround is to provide the duration as metadata in for example the filename itself (something like "myfile_MMSS.aac") or as a hash-tag/argument in the url, or side-load the metadata separately.

This latter will have certain implications though as we can not override the native player's duration field (in a cross-browser friendly way) which may require you to build a custom player interface so you can show the metadata as duration instead of the browser predicted one.

2
votes

Your audio encoding is bad. It's the audio file itself, not the browser. Make sure you're saving your original file as 44.1KHz/16-bit WAV, and use a dependable AAC encoder.

I took your AAC file, opened it in Adobe Audition, saved as 44/16 WAV, used XLD (MacOS) to encode to AAC. I dragged the AAC file into Chrome and it properly reported the duration.

So I would try different encoders till you find one that works properly.