alexcrichton / AudioStreamer

A streaming audio player class (AudioStreamer) for Mac OS X and iPhone.
69 stars 22 forks source link

Duration fluctuates during playback of MP4/AAC+ #20

Closed daegloe closed 6 years ago

daegloe commented 12 years ago

The duration of the song fluctuates during the first few seconds of MP4/AAC+ playback, and sometimes longer.

I can see why this might happen with an MP3 file that may not contain the appropriate/correct headers and/or may be truncated, but an MP4 should have the necessary atoms (mvhd, tkhd), to calculate an exact duration in advance of the actual audio playback.

Thoughts?

alexcrichton commented 12 years ago

I'm not 100% familiar with the formats of different streams. Right now the duration is just a calculation based off the bit rate the file length. The file length is always known, but the bit rate is the factor which is calculated. It's a combination of the sample rate, frames per packet, and the running average of the size of packets.

The fluctuation happens when the average size of the packets goes up or down, and that takes awhile to stabilize. Again, I'm not very familiar with audio formats. This is what mattgalagher's code did, and I just cleaned it up a bit.

If you know where to find these things in the structures that the audio framework provides, then I'd be more than happy to add it in!

daegloe commented 12 years ago

OK, I'll dig into this a bit.

Bo98 commented 10 years ago

I've improved the duration calculation so it tries not to rely on the bitrate which can vary.

It first asks the AudioFileStream for an audio data packet count. If it returns without error, then this is used to give an accurate reading immediately.

If the AudioFileStream returns an error, it then tries to fetch the audio data packet count from our own calculations.

Lastly it will fallback to use the bitrate if all else fails. Currently, this will always happen with .aac files (.m4a files work fine). MP3s will fallback to this too but it works well for them.

There's still a half-second margin of error but that could be a bug elsewhere (eg. the progress method) rather than incorrect duration calculation. I've yet to look into this.

Bo98 commented 9 years ago

Progress and duration calculations should now be very accurate for the files we can get the data for. There should be no margin of error or fluctuation anymore for files with the proper headers (eg. M4A) or if they are CBR (constant bitrate). Even for raw AAC files where it does not contain the duration in the headers there is a lot less fluctuation now. From my testing it only fluctuates by up to 0.4 seconds depending on how even the stream starts. On a perfect stream the fluctuation can be just up to 0.1 seconds. If you do not show fractions of seconds then the fluctuation should be invisible in most cases. There is a couple second margin of error however because we don't get the data offsets for raw AAC. I'm not sure if much can be done about it. How we nearly get the duration is quite good. iTunes and such don't even show it.

Seeking has also drastically improved. It should work just about perfect now.

Bo98 commented 6 years ago

There's been a few more improvements since then. Most recently including a fix for large files due to an inaccuracy caused by integer division.

I'm happy with the amount of improvements here. Should I find anything else by chance, I will address it. But unless anyone is aware of a specific file which there are still issues with, I will close this issue for now as the issue has been resolved for most files I've come across.