The chronicles of my wanderings through the world of programming, computers, and the little issues with scarcely documented solutions.

Wednesday, May 20, 2009

Calculating the length of MP3 files in PHP

Hi there,

When I discovered Jonathan Coulton's website and saw his preview option, I thought "I can do something like that" and went about writing my own. I used the Ming SWF library to create the resulting SWF file which is available in the Debian package repository as php5-ming (which also installs the libraries it needs).

Once I set it up to stream the files, I realised something else - to stream an entire file you need to pad the output SWF file with enough frames to play the entire song, or it just cuts off and loops. To do this, I set the frame rate to 1 frame per second with a mind to set the number of frames to the number of seconds in the song. But how to find this out?

At first I simply took the bitrate, divided by 8 and divided the size of the file by the result. So for a 256kbit file, I would divide the size by 32. This was very inaccurate and led to the test song being cut off about 20 seconds before its end. I needed a new plan.

I had a look at getID3() but found it to be very bloated with features I didn't need. Being the enterprising hacker that I was, I sought to figure out how to do it myself.

A quick googling found the MPEG header definition, which also told you how to figure out the frame length. With the frame length and the frame size (384 for MPEG Layer 1, 1152 for Layers 2 and 3) I was able to calculate the duration of MP3 files on the fly.

I have uploaded a sample of the code in action using the OpenBSD songs as a test, as well as the code itself, both the streamer and the MP3 length calculator. Enjoy!