Solution 1:

The funny thing is I wrote a php media gallery for all my musics 2 days ago. I had a similar problem. I'm using http://musicplayer.sourceforge.net/ for the player. And the playlist is built via php. All music requests go to a script called xfer.php?file=WHATEVER

$filename = base64_url_decode($_REQUEST['file']);
header("Cache-Control: public");
header('Content-disposition: attachment; filename='.basename($filename));
header("Content-Transfer-Encoding: binary");
header('Content-Length: '. filesize($filename));

//  Put either file counting code here, either a db or static files
//
readfile($filename);  //and spit the user the file

function base64_url_decode($input) {
    return base64_decode(strtr($input, '-_,', '+/='));
}

And when you call files use something like:

function base64_url_encode($input) {
     return strtr(base64_encode($input), '+/=', '-_,');
}

http://us.php.net/manual/en/function.base64-encode.php

If you are using some JavaScript or a flash player (JW player for example) that requires the actual link of an mp3 file or whatever, you can append the text "&type=.mp3" so the final link becomes something like: "www.example.com/xfer.php?file=34842ffjfjxfh&type=.mp3". That way it looks like it ends with an mp3 extension without affecting the file link.

Solution 2:

Use your httpd log files. Install http://awstats.sourceforge.net/

Solution 3:

Use bash:

grep mp3 /var/log/httpd/access_log | wc

Solution 4:

If your song / binary file was served by apache, you can easily grep the access_log to find out the number of downloads. A simple post-logrotate script can grep the logs and maintain your count statistics in a db. This has the performance advantage by not being in your live request code path. Doing non-critical things like stats offline is a good idea to scale your website to large number of users.