https://www.mp3cruncher.org

This code accepts a URL to an MP3 file and a frameRate and outputs an XML list of Average Volume and Peak Volume by video frame as a floating point value between 0 and 1, with 0 being silence and 1 being full loudness.

URL to MP3 File:

Video Frame Rate (Frames Per Second):

"; if(isset($argv[1])) //Command-line mode { $mp3URL=$argv[1]; if(isset($argv[2])) $frameRate=$argv[2]; } if(!$mp3URL && !isset($_GET['mp3File'])) { echo "$form"; echo ""; exit(); } if(!$mp3URL) $mp3URL=$_GET['mp3File']; if(isset($_GET['frameRate'])) $frameRate=$_GET['frameRate']; $mp3URL=escapeshellcmd($mp3URL); if($mp3URL && substr(strtolower($mp3URL),-4,4)=='.mp3') { $headers=get_headers($mp3URL,1);//Follow Redirects and Use Last Content-Length if(!is_array($headers['Content-Length'])) { $filesize=$headers['Content-Length']; } else { $arraysize=sizeof($headers['Content-Length']); $filesize=$headers['Content-Length'][$arraysize-1]; } $filesizehuman=round($filesize/1024/1024); if($filesize>$maxfilesize) { echo $form; echo "

This file size ($filesizehuman MB) exceeds the max file size of $maxfilesizehuman MB.

"; echo ""; } if(!$mp3content=file_get_contents($mp3URL)) { echo $form; echo "

404 Not Found - Could not find the mp3 file at that URL. ($mp3URL)

"; exit(); } } else if($mp3URL) { echo $form; echo "

This does not appear to be an mp3 file. It must end in '.mp3'.

"; exit(); } $md5=md5($mp3URL); $mp3TEMP="$appPath/$md5.mp3"; $rawTEMP="$appPath/$md5.raw"; $fh=fopen($mp3TEMP,'w'); fwrite($fh,$mp3content); fclose($fh); unset($mp3content); //$cmd="sox $mp3TEMP -c 1 -b 16 -r{$sampleRate} -e signed -B $rawTEMP -V"; // SOX mono 16-bit signed big endian raw file $cmd="ffmpeg -y -i $mp3TEMP -f s16be -c:a pcm_s16be -ac 1 -ar $sampleRate $rawTEMP"; // FFMPEG mono 16-bit signed big endian raw file exec($cmd); if(file_exists($mp3TEMP)) unlink ($mp3TEMP); if(file_exists($rawTEMP)) { $audio=file_get_contents($rawTEMP); unlink ($rawTEMP); header("content-type:text/xml"); echo "\r\n"; } else { echo $form; echo "

No audio found.

"; exit(); } $samplesPerFrame=$sampleRate/$frameRate; $totalSamples=strlen($audio)/2; $totalFrames=ceil($totalSamples/$samplesPerFrame); $mp3LengthSeconds=number_format($totalSamples/$sampleRate,3); $mp3LengthSMPTE=getTimeCode($totalSamples/$sampleRate,$frameRate); echo "\t\r\n"; for($frame=0;$frame<$totalFrames;$frame++) { $time=$frame/$frameRate; $realFrame=substr("000000".($frame+1),-6); $timeCode=getTimeCode($time,$frameRate,0); $timeCodeSMPTE=getTimeCode($time,$frameRate,1); $secondsRnd=substr("00000".floor($time),-5); $secondsMilli=substr("000".round(1000*($time-$secondsRnd)),-3); $seconds="$secondsRnd.$secondsMilli"; $peakVolume=0; $totalAmplitude=0; for($sample=0;$sample<$samplesPerFrame;$sample++) { $absoluteSample=$frame*$samplesPerFrame+$sample; $high_byte=ord(substr($audio,$absoluteSample*2,1)); $low_byte=ord(substr($audio,$absoluteSample*2+1,1)); $amplitude=1-abs(($high_byte*255+$low_byte)-32768)/32768; //normalize with silence 0 and Full loud 1 if($amplitude>$peakVolume) $peakVolume=$amplitude; $totalAmplitude+=$amplitude; } $averageVolume=$totalAmplitude/$samplesPerFrame; $peakVolume=number_format($peakVolume,7); $averageVolume=number_format($averageVolume,7); echo "\t\t$peakVolume\r\n"; flush(); } echo "\t\r\n\r\n"; function getTimeCode($time, $inputFrameRate, $smpte=1) { $thisFrameNumber=floor($time*$inputFrameRate); $min = floor($time / 60); $hour = floor($min / 60); if ($min > 60) $min = $min - ($hour * 60); $sec = floor($time % 60); $milli = $time - floor($time); $frame = round($milli*$inputFrameRate); $shour = $hour; $smin = $min; $ssec = $sec; $sframe = $frame; if (strlen($shour) < 2) $shour = "0" . $shour; if (strlen($smin) < 2) $smin = "0" . $smin; if (strlen($ssec) < 2) $ssec = "0" . $ssec; if (strlen($sframe) < 2) $sframe = "0" . $sframe; $tcSMPTE = $shour . ":" . $smin . ":" . $ssec . ":" . $sframe; $tc = $shour . ":" . $smin . ":" . $ssec . number_format($milli,3); if($smpte) return $tcSMPTE; else return $tc; } ?>