<?
/**

 * @name MP3Tool class
 * @author SkyFire aka XeOn
 * @icq 2666440
 * @readme readme.txt
 * @copyright (c)2012 SkyTech :)

**/
class MP3Tool {
    private static $root;
    private static $includePath;
        
    /**
     * Получаем расширение файла
    **/
    
    private function ext($filepath)
    {
        $ext = pathinfo($filepath, PATHINFO_EXTENSION);
        return $ext;
    }
    
    /**
     * Конструктор класса
    **/
    
    function __construct($file = false)
    {
        self::$includePath = dirname(__FILE__);
        self::$root = $_SERVER['DOCUMENT_ROOT'];
    }
    
    /**
     * Фильтрация строки
    **/
    
    private function clean($string)
    {
        $string = htmlspecialchars(trim($string));
        return $string;
    }
    
    /**
     * Получаем информацию о мп3 файле
    **/
    
    public function GetMp3Info($file, $mode = false)
    {
        $file = self::$root . '/' . $file;
        if(empty($file)) {
            exit('Error! Path to file is empty');
        }
        if(!file_exists($file)) {
            exit('Error! File '.$file.' not exists');
        }
        if(self::ext($file) != 'mp3') {
            exit('Error! Valid format files only mp3!');
        }
        require_once(self::$includePath.'/getid3/getid3.php');
        $ID3 = new getID3;
        $ID3->encoding = 'UTF-8';
        $analyze = $ID3->analyze($file);
        $audio = $analyze['audio'];
        $info['bitrate'] = $audio['bitrate'];
        $info['samplerate'] = $audio['sample_rate'];
        $info['cannels'] = $audio['channels'];
        $info['duration'] = ceil($analyze['playtime_seconds']);
        $info['filesize'] = $analyze['filesize'];
        if(!empty($analyze['tags']['id3v2'])) {
            $tags = $analyze['tags']['id3v2'];
        }
        elseif(!empty($analyze['tags']['id3v1'])) {
            $tags = $analyze['tags']['id3v1'];
        }
        else { 
            $tags['artist'][0] = 'Unkown artist';
            $tags['title'][0] = 'No name';
            $tags['genre'][0] = 'Other';
            $tags['year'][0] = '1970';
            $tags['comment'][0] = '';
            $tags['album'][0] = 'Unkown';
        }
        if($mode != false) {
            return $tags;
        }
        $info['artist'] = isset($tags['artist'][0]) ? self::clean($tags['artist'][0]) : false;
        $info['title'] = isset($tags['title'][0]) ? self::clean($tags['title'][0]) : false;
        $info['genre'] = isset($tags['genre'][0]) ? self::clean($tags['genre'][0]) : false;
        $info['year'] = isset($tags['year'][0]) ? self::clean($tags['year'][0]) : false;
        $info['comment'] = isset($tags['comment'][0]) ? self::clean($tags['comment'][0]) : false;
        $info['album'] = isset($tags['album'][0]) ? self::clean($tags['album'][0]) : false;
        if(isset($analyze['id3v2']['APIC'][0]['data'])) {
            $info['cover'] = $analyze['id3v2']['APIC'][0]['data'];
        }
        return $info;
        
    }
    
    /**
     * Записываем обложку
    **/
    
    public function Write($ffile, $tags = false, $cover = false)
    {
        $file = self::$root . '/' . $ffile;
        if(empty($file)) {
            exit('Error! Path to file is empty');
        }
        if(!file_exists($file)) {
            exit('Error! File '.$file.' not exists');
        }
        if($cover == false || !is_array($tags) || !is_string($cover)) {
            exit('Error! There are no required parameters!');
        }
        $tagArr = self::GetMp3Info($ffile, true);
        if(!empty($cover)) {
            $cover = self::$root . '/' . $cover;
            if(!file_exists($cover)) {
                exit('File of cover not exists!' . $cover);
            }
            if(self::ext($cover) != 'jpg' && self::ext($cover) != 'jpeg') {
                exit('Invalid mime type of cover image. Allowed mime type is jpeg!');
            }
            if(filesize($cover) > 100 * 1024) {
                exit('File size of cover image is big. Max allowed file size is 100kb!');
            }
            $data['attached_picture'][] = array(
                                               'data' => file_get_contents($cover),
                                               'description' => 'cover',
                                               'picturetypeid' => '1',
                                               'mime' => 'image/jpeg');
        }
        if(!empty($tags)) {
            if(!is_array($tags)) {
                exit('Error! Tags must be an array!');
            }
            foreach($tags as $key => $value) {
                $data[$key][0] = $value;
            }
        }
        if(!empty($tags)) {
            $tagArr = array_merge($tagArr, $data);
        }
        require_once(self::$includePath . '/getid3/write.php');
        $write = new getid3_writetags;
        $write->filename = $file;
        $write->remove_other_tags = false;
        $write->overwrite_tags = true;
        $write->tag_encoding = 'UTF-8';
        $write->tag_data = $tagArr;
        $write->tagformats = array('id3v1', 'id3v2.3');
        return $write->WriteTags();
    }
    
    /**
     * Обезаем мелодию, если передан параметр
    **/
    
    private function Cut($time = array())
    {
        if(!is_array($time)) {
            exit('Error! Time parameters must be an array!');
        }
        $start = gmdate('H:i:s', $time[0]);
        $end = gmdate('H:i:s', floor($time[1] - $time[0]));
        if($start > $end) {
            exit('Error! Start time should not be greater than the final time');
        }
        return '-ss ' . $start . ' -t ' . $end;
    }
    
    /**
     * Конвертация 
    **/
    
    public function Convert ($file, $bit, $outFile, $time = false)
    {
        if(empty($file)) {
            exit('Error! Path to file is empty');
        }
        if(!file_exists($file)) {
            exit('Error! File '.$file.' not exists');
        }
        $ext = self::ext($outFile);
        $outFile = self::$root. '/' . $outFile;
        $codecs = array(
                        'mp3' => 'libmp3lame',
                        'wav' => 'adpcm_ima_wav',
                        'aac' => 'libfaac',
                        'm4a' => 'libfaac',
                        'wma' => 'wmav1'
                       );
        $sampleRate = array(
                            '320' => '44100',
                            '256' => '44100',
                            '192' => '44100',
                            '160' => '44100',
                            '128' => '44100',
                            '64'  => '22050',
                            '32'  => '22050'
                           );
        $info = self::GetMp3Info($file);
        if((ceil($info['bitrate'] / 1000) < $bit) || (ceil($info['bitrate'] / 1000) == $bit && $ext == 'mp3')) {
            exit('Error! The new bitrate can not exceed the bitrate of the original file!');
        }
        if($time != false) {
            $cut = self::Cut($time);
        }
        if(file_exists($outFile)) {
            return true;
        }
        if(exec('ffmpeg -i ' . self::$root . '/' . $file . ' -acodec ' . $codecs[$ext] . ' -ar ' . $sampleRate[$bit] . ' -ab ' . $bit . 'K' . (isset($cut) ? ' ' . $cut : '') . ' -ac 2 ' . $outFile . ' && id3cp ' . $file . ' ' . $outFile))
            return true;
        else
            return false;
    }
}