diff options
-rw-r--r-- | config/ampache.cfg.php.dist | 21 | ||||
-rwxr-xr-x | docs/CHANGELOG | 4 | ||||
-rw-r--r-- | lib/class/vainfo.class.php | 761 |
3 files changed, 245 insertions, 541 deletions
diff --git a/config/ampache.cfg.php.dist b/config/ampache.cfg.php.dist index baf4d835..ac9b6dc2 100644 --- a/config/ampache.cfg.php.dist +++ b/config/ampache.cfg.php.dist @@ -215,12 +215,11 @@ require_localnet_session = "true" ; This determines the tag order for all cataloged ; music. If none of the listed tags are found then -; ampache will default to the first tag format -; that was found. -; POSSIBLE VALUES: ape asf avi id3v1 id3v2 lyrics3 mpeg quicktime riff +; ampache will randomly use whatever was found. +; POSSIBLE VALUES: ape asf avi id3v1 id3v2 lyrics3 matroska mpeg quicktime riff ; vorbiscomment -; DEFAULT: id3v2 id3v1 vorbiscomment quicktime ape asf avi mpeg riff -getid3_tag_order = "id3v2,id3v1,vorbiscomment,quicktime,ape,asf,avi,mpeg,riff" +; DEFAULT: id3v2 id3v1 vorbiscomment quicktime matroska ape asf avi mpeg riff +getid3_tag_order = "id3v2,id3v1,vorbiscomment,quicktime,matroska,ape,asf,avi,mpeg,riff" ; Determines whether we try to autodetect the encoding for id3v2 tags. ; May break valid tags. @@ -667,12 +666,8 @@ use_rss = true ;############################# ; Multibyte Settings # ;############################# -; Use Iconv or not -; DEFAULT: false -;use_iconv = false - -; mb_detect_order -; comma separated, available encodings are listed on php.net. -; see http://php.net/manual/mbstring.supported-encodings.php +; See http://php.net/manual/mbstring.supported-encodings.php +; If you want ID3v1 encoding detection to work, you should uncomment this line +; so that the ordering is sane. ; DEFAULT: auto -;mb_detect_order = "EUC-JP, SJIS, eucJP-win, SJIS-win, JIS, ISO-2022-JP, ASCII, UTF-8, UTF-7" +;mb_detect_order = "ASCII,UTF-8,EUC-JP,ISO-2022-JP,SJIS,JIS" diff --git a/docs/CHANGELOG b/docs/CHANGELOG index bcaf69d1..c0cec19a 100755 --- a/docs/CHANGELOG +++ b/docs/CHANGELOG @@ -4,6 +4,10 @@ -------------------------------------------------------------------------- v.3.6-FUTURE + - Fixed character set detection for ID3v1 tags + - Added matroska to the list of known tag types + - Made the getID3 metadata source work better with tag types that Ampache + doesn't recognise - Switched from the deprecated mysql extension to PDO - stderr from the transcode command is now logged for debugging - Made database updates more robust and verified that a fresh 3.3.3.5 import diff --git a/lib/class/vainfo.class.php b/lib/class/vainfo.class.php index 1244245c..3b2d6add 100644 --- a/lib/class/vainfo.class.php +++ b/lib/class/vainfo.class.php @@ -32,17 +32,16 @@ class vainfo { public $encoding_id3v1 = ''; public $encoding_id3v2 = ''; - public $filename = ''; - public $type = ''; - public $tags = array(); + public $filename = ''; + public $type = ''; + public $tags = array(); - protected $_raw = array(); - protected $_getID3 = ''; - protected $_iconv = false; + protected $_raw = array(); + protected $_getID3 = ''; - protected $_file_encoding = ''; - protected $_file_pattern = ''; - protected $_dir_pattern = ''; + protected $_file_encoding = ''; + protected $_file_pattern = ''; + protected $_dir_pattern = ''; private $_pathinfo; private $_broken = false; @@ -50,40 +49,20 @@ class vainfo { /** * Constructor * - * This function just sets up the class, it doesn't - * actually pull the information + * This function just sets up the class, it doesn't pull the information. * - * @param string $file filename - * @param string $encoding Target encode character set - * @param string $encoding_id3v1 Default id3v1 encode character set - * @param string $encoding_iv3v2 Default id3v2 encode character set - * @param string $dir_pattern Directory pattern - * @param string $file_pattern File pattern - * @return mixed If can't analyze file, return false. default return: void */ public function __construct($file, $encoding = null, $encoding_id3v1 = null, $encoding_id3v2 = null, $dir_pattern, $file_pattern) { - /* Check for ICONV */ - if (function_exists('iconv') && Config::get('use_iconv') == "1") { - $this->_iconv = true; - } - else { - $this->_iconv = false; - } - $this->filename = $file; - if ($encoding) { - $this->encoding = $encoding; - } - else { - $this->encoding = Config::get('site_charset'); - } + $this->encoding = $encoding ?: Config::get('site_charset'); /* These are needed for the filename mojo */ $this->_file_pattern = $file_pattern; $this->_dir_pattern = $dir_pattern; - if(strtoupper(substr(PHP_OS,0,3)) == 'WIN') { + // FIXME: This looks ugly and probably wrong + if(strtoupper(substr(PHP_OS, 0, 3)) == 'WIN') { $this->_pathinfo = str_replace('%3A', ':', urlencode($this->filename)); $this->_pathinfo = pathinfo(str_replace('%5C', '\\', $this->_pathinfo)); } @@ -95,25 +74,24 @@ class vainfo { // Initialize getID3 engine $this->_getID3 = new getID3(); - $this->_getID3->option_md5_data = false; - $this->_getID3->option_md5_data_source = false; - $this->_getID3->option_tags_html = false; - $this->_getID3->option_extra_info = true; - $this->_getID3->option_tag_lyrics3 = true; - $this->_getID3->option_tags_process = true; - $this->_getID3->encoding = $this->encoding; + $this->_getID3->option_md5_data = false; + $this->_getID3->option_md5_data_source = false; + $this->_getID3->option_tags_html = false; + $this->_getID3->option_extra_info = true; + $this->_getID3->option_tag_lyrics3 = true; + $this->_getID3->option_tags_process = true; + $this->_getID3->encoding = $this->encoding; // get id3tag encoding (try to work around off-spec id3v1 tags) try { $this->_raw = $this->_getID3->analyze($file); } catch (Exception $error) { - debug_event('Getid3()',"Broken file detected $file - " . $error->message,'1'); + debug_event('getID3', "Broken file detected: $file: " . $error->message, 1); $this->_broken = true; return false; } - /* Use default mb_detect_order in php.ini or not */ if (Config::get('mb_detect_order')) { $mb_order = Config::get('mb_detect_order'); } @@ -140,6 +118,7 @@ class vainfo { } if (Config::get('getid3_detect_id3v2_encoding')) { + // The user has told us to be moronic, so let's do that thing foreach ($test_tags as $tag) { if ($value = $this->_raw['id3v2']['comments'][$tag]) { $tags[$tag] = $value; @@ -151,18 +130,17 @@ class vainfo { } $this->_getID3->encoding_id3v1 = $this->encoding_id3v1; - - } // vainfo + } /** * _detect_encoding + * * Takes an array of tags and attempts to automatically detect their * encoding. */ private static function _detect_encoding($tags, $mb_order) { if (function_exists('mb_detect_encoding')) { $encodings = array(); - $tags = array('artist', 'album', 'genre', 'title'); foreach ($tags as $tag) { $encodings[mb_detect_encoding($tag, $mb_order, true)]++; } @@ -189,10 +167,10 @@ class vainfo { /** * get_info + * * This function runs the various steps to gathering the metadata */ public function get_info() { - // If this is broken, don't waste time figuring it out a second // time, just return their rotting carcass of a media file. if ($this->_broken) { @@ -200,12 +178,11 @@ class vainfo { return true; } - /* Get the Raw file information */ try { $this->_raw = $this->_getID3->analyze($this->filename); } catch (Exception $error) { - debug_event('Getid3()',"Unable to catalog file:" . $error->message,'1'); + debug_event('getID2', 'Unable to catalog file: ' . $error->message, 1); } /* Figure out what type of file we are dealing with */ @@ -227,49 +204,47 @@ class vainfo { /** * get_tag_type + * * This takes the result set and the tag_order defined in your config * file and tries to figure out which tag type(s) it should use. If your * tag_order doesn't match anything then it throws up its hands and uses - * everything. + * everything in random order. */ public static function get_tag_type($results, $config_key = 'metadata_order') { - $order = (array)Config::get($config_key); - /* Iterate through the defined key order adding them to an - * ordered array as we go. - */ - + // Iterate through the defined key order adding them to an ordered array. foreach($order as $key) { if ($results[$key]) { $returned_keys[] = $key; } } - /* If we didn't find anything then default to everything. - */ + // If we didn't find anything then default to everything. if (!isset($returned_keys)) { $returned_keys = array_keys($results); $returned_keys = sort($returned_keys); } - return $returned_keys; + // Unless they explicitly set it, add bitrate/mode/mime/etc. + if (!in_array('general', $returned_keys)) { + $returned_keys[] = 'general'; + } - } // get_tag_type + return $returned_keys; + } /** * clean_tag_info + * * This function takes the array from vainfo along with the * key we've decided on and the filename and returns it in a * sanitized format that ampache can actually use */ public static function clean_tag_info($results, $keys, $filename = null) { - $info = array(); - if ($filename) { - $info['file'] = $filename; - } + $info['file'] = $filename; // Iteration! foreach ($keys as $key) { @@ -286,14 +261,13 @@ class vainfo { $info['time'] = $info['time'] ?: intval($tags['time']); $info['channels'] = $info['channels'] ?: $tags['channels']; - /* These are used to generate the correct IDs later */ $info['title'] = $info['title'] ?: stripslashes(trim($tags['title'])); $info['year'] = $info['year'] ?: intval($tags['year']); $info['disk'] = $info['disk'] ?: intval($tags['disk']); - $info['totaldiscs'] = $info['totaldiscs'] ?: intval($tags['totaldiscs']); + $info['totaldisks'] = $info['totaldisks'] ?: intval($tags['totaldisks']); $info['artist'] = $info['artist'] ?: trim($tags['artist']); @@ -317,7 +291,6 @@ class vainfo { $info['mb_albumid'] = $info['mb_albumid'] ?: trim($tags['mb_albumid']); $info['mb_artistid'] = $info['mb_artistid'] ?: trim($tags['mb_artistid']); - /* @TODO language doesn't import from id3tag. @momo-i */ $info['language'] = $info['language'] ?: Dba::escape($tags['language']); $info['lyrics'] = $info['lyrics'] @@ -333,128 +306,118 @@ class vainfo { $info['video_codec'] = $info['video_codec'] ?: Dba::escape($tags['video_codec']); } - if ($info['totaldiscs'] == 1 && $info['disk'] == 1) { + // Some things set the disk number even though there aren't multiple + if ($info['totaldisks'] == 1 && $info['disk'] == 1) { unset($info['disk']); - unset($info['totaldiscs']); + unset($info['totaldisks']); } return $info; - - } // clean_tag_info + } /** * _get_type - * This function takes the raw information and figures out - * what type of file we are dealing with for use by the tag - * function + * + * This function takes the raw information and figures out what type of + * file we are dealing with. */ - public function _get_type() { - - /* There are a few places that the file type can - * come from, in the end we trust the encoding - * type - */ + private function _get_type() { + // There are a few places that the file type can come from, in the end + // we trust the encoding type. if ($type = $this->_raw['video']['dataformat']) { - $type = $this->_clean_type($type); - return $type; + return $this->_clean_type($type); } if ($type = $this->_raw['audio']['streams']['0']['dataformat']) { - $type = $this->_clean_type($type); - return $type; + return $this->_clean_type($type); } if ($type = $this->_raw['audio']['dataformat']) { - $type = $this->_clean_type($type); - return $type; + return $this->_clean_type($type); } if ($type = $this->_raw['fileformat']) { - $type = $this->_clean_type($type); - return $type; + return $this->_clean_type($type); } return false; - - } // _get_type + } /** * _get_tags - * This function takes the raw information and the type and - * attempts to gather the tags and then normalize them into - * ['tag_name']['var'] = value + * + * This processes the raw getID3 output and bakes it. */ - public function _get_tags() { + private function _get_tags() { $results = array(); - /* The tags can come in many different shapes and colors - * depending on the encoding time of day and phase of the moon. - */ + // The tags can come in many different shapes and colors + // depending on the encoding time of day and phase of the moon. + foreach ($this->_raw['tags'] as $key => $tag_array) { switch ($key) { + case 'ape': + case 'avi': + case 'flv': + case 'matroska': + debug_event('vainfo', 'Cleaning ' . $key, 5); + $parsed = $this->_cleanup_generic($tag_array); + break; case 'vorbiscomment': - debug_event('_get_tags', 'Parsing vorbis', '5'); - $results[$key] = $this->_parse_vorbiscomment($tag_array); + debug_event('vainfo', 'Cleaning vorbis', 5); + $parsed = $this->_cleanup_vorbiscomment($tag_array); break; case 'id3v1': - debug_event('_get_tags', 'Parsing id3v1', '5'); - $results[$key] = $this->_parse_id3v1($tag_array); + debug_event('vainfo', 'Cleaning id3v1', 5); + $parsed = $this->_cleanup_id3v1($tag_array); break; case 'id3v2': - debug_event('_get_tags', 'Parsing id3v2', '5'); - $results[$key] = $this->_parse_id3v2($tag_array); - break; - case 'ape': - debug_event('_get_tags', 'Parsing ape', '5'); - $results[$key] = $this->_parse_ape($tag_array); + debug_event('vainfo', 'Cleaning id3v2', 5); + $parsed = $this->_cleanup_id3v2($tag_array); break; case 'quicktime': - debug_event('_get_tags', 'Parsing quicktime', '5'); - $results[$key] = $this->_parse_quicktime($tag_array); + debug_event('vainfo', 'Cleaning quicktime', 5); + $parsed = $this->_cleanup_quicktime($tag_array); break; case 'riff': - debug_event('_get_tags', 'Parsing riff', '5'); - $results[$key] = $this->_parse_riff($tag_array); - break; - case 'flv': - debug_event('_get_tags', 'Parsing flv', '5'); - $results[$key] = $this->_parse_flv($this->_raw); + debug_event('vainfo', 'Cleaning riff', 5); + $parsed = $this->_cleanup_riff($tag_array); break; case 'mpg': case 'mpeg': - debug_event('_get_tags', 'Parsing MPEG', '5'); - $results['mpeg'] = $this->_parse_mpg($this->_raw); + $key = 'mpeg'; + debug_event('vainfo', 'Cleaning MPEG', 5); + $parsed = $this->_cleanup_generic($tag_array); break; case 'asf': case 'wmv': - debug_event('_get_tags', 'Parsing WMV/WMA/ASF', '5'); - $results['asf'] = $this->_parse_wmv($this->_raw); - break; - case 'avi': - debug_event('_get_tags', 'Parsing avi', '5'); - $results[$key] = $this->_parse_avi($this->_raw); + $key = 'asf'; + debug_event('vainfo', 'Cleaning WMV/WMA/ASF', 5); + $parsed = $this->_cleanup_generic($tag_array); break; case 'lyrics3': - debug_event('_get_tags', 'Parsing lyrics3', '5'); - $results[$key] = $this->_parse_lyrics($tag_array); + debug_event('vainfo', 'Cleaning lyrics3', 5); + $parsed = $this->_cleanup_lyrics($tag_array); break; default: - debug_event('vainfo','Error: Unable to determine tag type of ' . $key . ' for file ' . $this->filename . ' Assuming id3v2','5'); - $results[$key] = $this->_parse_id3v2($this->_raw['id3v2']['comments']); + debug_event('vainfo', 'Cleaning unrecognised tag type ' . $key . ' for file ' . $this->filename, 5); + $parsed = $this->_cleanup_generic($tag_array); break; - } // end switch - } // end foreach + } + + $results[$key] = $parsed; + } + $results['general'] = $this->_parse_general($this->_raw); $cleaned = self::clean_tag_info($results, self::get_tag_type($results, 'getid3_tag_order'), $this->filename); - $cleaned = array_merge($cleaned, $this->_get_info()); $cleaned['raw'] = $results; return $cleaned; - - } // _get_tags + } /** * _get_plugin_tags + * * Get additional metadata from plugins */ private function _get_plugin_tags() { @@ -464,7 +427,7 @@ class vainfo { } $plugin_names = Plugin::get_plugins('get_metadata'); - foreach ($tag_order as $key => $tag_source) { + foreach ($tag_order as $tag_source) { if (in_array($tag_source, $plugin_names)) { $plugin = new Plugin($tag_source); if ($plugin->load()) { @@ -472,51 +435,36 @@ class vainfo { } } } - } // _get_plugin_tags + } /** - * _get_info - * Gather and return the general information about a song (vbr/cbr, + * _parse_general + * + * Gather and return the general information about a file (vbr/cbr, * sample rate, channels, etc.) */ - private function _get_info() { - - $array = array(); - - /* Try to pull the information directly from - * the audio array - */ - if ($this->_raw['audio']['bitrate_mode']) { - $array['mode'] = $this->_raw['audio']['bitrate_mode']; - if ($array['mode'] == 'con') { - $array['mode'] = 'cbr'; - } - } - if ($this->_raw['audio']['bitrate']) { - $array['bitrate'] = $this->_raw['audio']['bitrate']; - } - if ($this->_raw['audio']['channels']) { - $array['channels'] = intval($this->_raw['audio']['channels']); - } - if ($this->_raw['audio']['sample_rate']) { - $array['rate'] = intval($this->_raw['audio']['sample_rate']); - } - if ($this->_raw['filesize']) { - $array['size'] = intval($this->_raw['filesize']); - } - if ($this->_raw['encoding']) { - $array['encoding'] = $this->_raw['encoding']; - } - if ($this->_raw['mime_type']) { - $array['mime'] = $this->_raw['mime_type']; - } - if ($this->_raw['playtime_seconds']) { - $array['time'] = $this->_raw['playtime_seconds']; - } - - return $array; - - } // _get_info + private function _parse_general($tags) { + $parsed = array(); + + $parsed['title'] = urldecode($this->_pathinfo['filename']); + $parsed['mode'] = $tags['audio']['bitrate_mode']; + if ($parsed['mode'] == 'con') { + $parsed['mode'] = 'cbr'; + } + $parsed['bitrate'] = $tags['audio']['bitrate']; + $parsed['channels'] = intval($tags['audio']['channels']); + $parsed['rate'] = intval($tags['audio']['sample_rate']); + $parsed['size'] = intval($tags['filesize']); + $parsed['encoding'] = $tags['encoding']; + $parsed['mime'] = $tags['mime_type']; + $parsed['time'] = $tags['playtime_seconds']; + $parsed['video_codec'] = $tags['video']['fourcc']; + $parsed['audio_codec'] = $tags['audio']['dataformat']; + $parsed['resolution_x'] = $tags['video']['resolution_x']; + $parsed['resolution_y'] = $tags['video']['resolution_y']; + + return $parsed; + } /** * _clean_type @@ -547,150 +495,139 @@ class vainfo { debug_event('vainfo','Unable to determine file type from ' . $type . ' on file ' . $this->filename,'5'); return $type; break; - } // end switch on type - - } // _clean_type + } + } /** - * _parse_lyrics - * This function takes a lyrics3 from getid3() - * nothing to do? + * _cleanup_generic + * + * This does generic cleanup. */ - private function _parse_lyrics($tags) { + private function _cleanup_generic($tags) { + $parsed = array(); + foreach ($tags as $tagname => $data) { + switch ($tagname) { + case 'genre': + // Pass the array through + $parsed[$tagname] = $data; + break; + default: + $parsed[$tagname] = $data[0]; + break; + } + } - /* Results array */ - $array = array(); + return $parsed; + } + + /** + * _cleanup_lyrics + * + * This is supposed to handle lyrics3. FIXME: does it? + */ + private function _cleanup_lyrics($tags) { + $parsed = array(); - /* go through them all! */ foreach ($tags as $tag => $data) { if ($tag == 'unsynchedlyrics' || $tag == 'unsynchronised lyric') { $tag = 'lyrics'; } - $array[$tag] = $this->_clean_tag($data['0']); - - } // end foreach - - return $array; - - } // _parse_lyrics + $parsed[$tag] = $data[0]; + } + return $parsed; + } /** - * _parse_vorbiscomment - * This function takes a vorbiscomment from getid3() and then - * returns the elements translated using iconv if needed in a - * pretty little format + * _cleanup_vorbiscomment + * + * Standardises tag names from vorbis. */ - private function _parse_vorbiscomment($tags) { - - /* Results array */ - $array = array(); + private function _cleanup_vorbiscomment($tags) { + $parsed = array(); - /* go through them all! */ - foreach ($tags as $tag=>$data) { - - /* We need to translate a few of these tags */ + foreach ($tags as $tag => $data) { switch ($tag) { - case 'genre': - // multiple genre support - foreach($data as $foo) { - $array['genre'][] = $this->_clean_tag($foo,''); - } + // Pass the array through + $parsed[$tag] = $data; break; case 'tracknumber': - $array['track'] = $this->_clean_tag($data['0']); + $parsed['track'] = $data[0]; break; case 'discnumber': - $el = explode('/', $data['0']); - $array['disk'] = $el[0]; + $elements = explode('/', $data[0]); + $parsed['disk'] = $elements[0]; + $parsed['totaldisks'] = $elements[1]; break; case 'date': - $array['year'] = $this->_clean_tag($data['0']); + $parsed['year'] = $data[0]; break; default: - $array[$tag] = $this->_clean_tag($data['0']); + $parsed[$tag] = $data[0]; break; - } // end switch - - } // end foreach - - return $array; + } + } - } // _parse_vorbiscomment + return $parsed; + } /** - * _parse_id3v1 - * This function takes an id3v1 tag set from getid3() and then - * returns the elements (translated using iconv if needed) in a - * pretty little format. + * _cleanup_id3v1 + * + * Doesn't do much. */ - private function _parse_id3v1($tags) { + private function _cleanup_id3v1($tags) { + $parsed = array(); - $array = array(); - - /* Go through all the tags */ - foreach ($tags as $tag=>$data) { - - /* This is our baseline for naming - * so no translation needed - */ - $array[$tag] = $this->_clean_tag($data['0']); - - } // end foreach - - return $array; + foreach ($tags as $tag => $data) { + // This is our baseline for naming so everything's already right, + // we just need to shuffle off the array. + $parsed[$tag] = $data[0]; + } - } // _parse_id3v1 + return $parsed; + } /** - * _parse_id3v2 - * This function takes an id3v2 tag set from getid3() and then - * returns the elements (translated using iconv if needed) in a - * pretty little format. + * _cleanup_id3v2 + * + * Whee, v2! */ - private function _parse_id3v2($tags) { - - $array = array(); + private function _cleanup_id3v2($tags) { + $parsed = array(); - /* Go through the tags */ - foreach ($tags as $tag=>$data) { + foreach ($tags as $tag => $data) { - /** - * the new getid3 handles this differently - * so we now need to account for it :( - */ switch ($tag) { case 'genre': - // multiple genre support - foreach($data as $genre) { - $array['genre'][] = $this->_clean_tag($genre); - } + // Pass the array through + $parsed[$tag] = $data; break; case 'part_of_a_set': - $el = explode('/', $data['0']); - $array['disk'] = $el[0]; - $array['totaldiscs'] = $el[1]; + $elements = explode('/', $data[0]); + $parsed['disk'] = $elements[0]; + $parsed['totaldisks'] = $elements[1]; break; case 'track_number': - $array['track'] = $this->_clean_tag($data['0']); + $parsed['track'] = $data[0]; break; case 'comments': - $array['comment'] = $this->_clean_tag($data['0']); + $parsed['comment'] = $data[0]; break; default: - $array[$tag] = $this->_clean_tag($data['0']); + $parsed[$tag] = $data[0]; break; - } // end switch on tag - - } // end foreach + } + } + // getID3 doesn't do all the parsing we need, so grab the raw data $id3v2 = $this->_raw['id3v2']; if(!empty($id3v2['UFID'])) { // Find the MBID for the track foreach ($id3v2['UFID'] as $ufid) { if ($ufid['ownerid'] == 'http://musicbrainz.org') { - $array['mb_trackid'] = $this->_clean_tag($ufid['data']); + $parsed['mb_trackid'] = $ufid['data']; } } @@ -698,10 +635,10 @@ class vainfo { foreach ($id3v2['TXXX'] as $txxx) { switch ($txxx['description']) { case 'MusicBrainz Album Id': - $array['mb_albumid'] = $this->_clean_tag($txxx['data']); + $parsed['mb_albumid'] = $txxx['data']; break; case 'MusicBrainz Artist Id': - $array['mb_artistid'] = $this->_clean_tag($txxx['data']); + $parsed['mb_artistid'] = $txxx['data']; break; } } @@ -713,225 +650,72 @@ class vainfo { if (array_key_exists('email', $popm) && $user = User::get_from_email($popm['email'])) { // Ratings are out of 255; scale it - $array['rating'][$user->id] = $popm['rating'] / 255 * 5; + $parsed['rating'][$user->id] = $popm['rating'] / 255 * 5; } } } - return $array; - - } // _parse_id3v2 - - /** - * _parse_ape - * This function takes ape tags set by getid3() and then - * returns the elements translated using iconv if needed in a - * pretty little format - */ - private function _parse_ape($tags) { - - foreach ($tags as $tag=>$data) { - switch ($tag) { - - case 'genre': - // multiple genre support - foreach($data as $genre) { - $array['genre'][] = $this->_clean_tag($genre); - } - break; - - default: - $array[$tag] = $this->_clean_tag($data['0'], $this->_file_encoding); - break; - } // end switch on tag - - } // end foreach tags - - return $array; - - } // _parse_ape + return $parsed; + } /** - * _parse_riff - * this function takes the riff take information passed by getid3() and - * then reformats it so that it matches the other formats. May require iconv + * _cleanup_riff */ - private function _parse_riff($tags) { - - foreach ($tags as $tag=>$data) { + private function _cleanup_riff($tags) { + $parsed = array(); + foreach ($tags as $tag => $data) { switch ($tag) { case 'product': - $array['album'] = $this->_clean_tag($data['0'], $this->_file_encoding); + $parsed['album'] = $data[0]; break; default: - $array[$tag] = $this->_clean_tag($data['0'], $this->_file_encoding); + $parsed[$tag] = $data[0]; break; - } // end switch on tag - - } // foreach tags - - return $array; + } + } - } // _parse_riff + return $parsed; + } /** - * _parse_quicktime - * this function takes the quicktime tags set by getid3() and then - * returns the elements translated using iconv if needed in a - * pretty little format + * _cleanup_quicktime */ - private function _parse_quicktime($tags) { + private function _cleanup_quicktime($tags) { + $parsed = array(); - /* Results array */ - $array = array(); - - /* go through them all! */ - foreach ($tags as $tag=>$data) { - - /* We need to translate a few of these tags */ + foreach ($tags as $tag => $data) { switch ($tag) { case 'creation_date': if (strlen($data['0']) > 4) { - /* Weird Date format, attempt to normalize */ - $data['0'] = date("Y",strtotime($data['0'])); + // Weird date format, attempt to normalize it + $data[0] = date('Y', strtotime($data[0])); } - $array['year'] = $this->_clean_tag($data['0']); + $parsed['year'] = $data[0]; break; case 'MusicBrainz Track Id': - $array['mb_trackid'] = $this->_clean_tag($data['0']); + $parsed['mb_trackid'] = $data[0]; break; case 'MusicBrainz Album Id': - $array['mb_albumid'] = $this->_clean_tag($data['0']); + $parsed['mb_albumid'] = $data[0]; break; case 'MusicBrainz Artist Id': - $array['mb_artistid'] = $this->_clean_tag($data['0']); + $parsed['mb_artistid'] = $data[0]; break; - } // end switch - - $array[$tag] = $this->_clean_tag($data['0']); - - } // end foreach - - // Also add in any video related stuff we might find - if (strpos($this->_raw['mime_type'], 'video') !== false) { - $info = $this->_parse_avi($this->_raw); - $info['video_codec'] = $this->_raw['quicktime']['ftyp']['fourcc']; - $array = array_merge($info, $array); - } - - return $array; - - } // _parse_quicktime - - /** - * _parse_avi - * This attempts to parse our the information on an avi file and present it in some - * kind of sane format, this is a little hard as these files don't have tags - */ - private function _parse_avi($tags) { - - $array = array(); - - $array['title'] = urldecode($this->_pathinfo['filename']); - $array['video_codec'] = $tags['video']['fourcc']; - $array['audio_codec'] = $tags['audio']['dataformat']; - $array['resolution_x'] = $tags['video']['resolution_x']; - $array['resolution_y'] = $tags['video']['resolution_y']; - $array['mime'] = $tags['mime_type']; - $array['comment'] = $tags['video']['codec']; - - return $array; - - } // _parse_avi - - /** - * _parse_mpg - * This attempts to parse our the information on a mpg file and present it in some - * kind of sane format, this is a little hard as these files don't have tags - */ - private function _parse_mpg($tags) { - - $array = array(); - - $array['title'] = urldecode($this->_pathinfo['filename']); - $array['video_codec'] = $tags['video']['codec']; - $array['audio_codec'] = $tags['audio']['dataformat']; - $array['resolution_x'] = $tags['video']['resolution_x']; - $array['resolution_y'] = $tags['video']['resolution_y']; - $array['mime'] = $tags['mime_type']; - $array['comment'] = $tags['video']['codec']; - - return $array; - - } // _parse_mpg - - /** - * _parse_wmv - * This attempts to parse our the information on a asf/wmv file and present it in some - * kind of sane format, this is a little hard as these files don't have tags - */ - private function _parse_wmv($tags) { - - $array = array(); - - $array['mime'] = $tags['mime_type']; - - switch($array['mime']) { - default: - case 'video/x-ms-wmv': - if(isset($tags['tags']['asf']['title']['0'])) { - $array['title'] = $tags['tags']['asf']['title']['0']; - } - else { - $array['title'] = urldecode($this->_pathinfo['filename']); - } - $array['video_codec'] = $tags['video']['streams']['2']['codec']; - $array['audio_codec'] = $tags['audio']['streams']['1']['codec']; - $array['resolution_x'] = $tags['video']['streams']['2']['resolution_x']; - $array['resolution_y'] = $tags['video']['streams']['2']['resolution_y']; - $array['comment'] = $tags['tags']['asf']['title']['1']; - break; - } - - foreach($tags['tags']['asf'] as $tag => $data) { - $array[$tag] = $this->_clean_tag($data['0']); + default: + $parsed[$tag] = $data[0]; + break; + } } - return $array; - - } // _parse_wmv - - /** - * _parse_flv - * This attempts to parse our the information on an flv file and present it in some - * kind of sane format, this is a little hard as these files don't have tags - */ - private function _parse_flv($tags) { - - $array = array(); - - $array['title'] = urldecode($this->_pathinfo['filename']); - $array['video_codec'] = $tags['video']['codec']; - $array['audio_codec'] = $tags['audio']['dataformat']; - $array['resolution_x'] = $tags['video']['resolution_x']; - $array['resolution_y'] = $tags['video']['resolution_y']; - $array['mime'] = $tags['mime_type']; - $array['comment'] = $tags['video']['codec']; - - return $array; - - } // _parse_flv + return $parsed; + } /** * _parse_filename * - * This function uses the passed file and dir patterns - * To pull out extra tag information and populate it into - * its own array - * - * @param string $filename Filename that want to parse - * @return array Parsed results + * This function uses the file and directory patterns to pull out extra tag + * information. */ private function _parse_filename($filename) { @@ -980,85 +764,6 @@ class vainfo { } /** - * _id3v2_tag_to_frame - * - * This translates the tag name to a frame, if there a many it returns the first - * one if finds that exists in the raw - * - * @param string $tag_name Tag name - * @return mixed If found id3v2 frame, return frame. If not found, return false. - */ - private function _id3v2_tag_to_frame($tag_name) { - - static $map = array( - 'comment'=>array('COM','COMM'), - 'cd_ident'=>array('MCDI','MCI'), - 'album'=>array('TAL','TALB'), - 'language'=>array('TLA','TLAN'), - 'mood'=>array('TMOO'), - 'artist'=>array('TPE1'), - 'year'=>array('TDRC')); - - foreach ($map[$tag_name] as $frame) { - if (isset($this->_raw['id3v2'][$frame])) { - return $frame; - } - } - - return false; - - } // _id3v2_tag_to_frame - - /** - * _clean_tag - * - * This function cleans up the tag that it's passed using Iconv - * if we've got it. It also takes an optional encoding param - * for the cases where we know what the tags source encoding - * is, and or if it's different then the encoding recorded - * in the file - * - * @param string $tag Encoding string - * @param string $encoding Encode charset - * @return string Return encoded string - */ - private function _clean_tag($tag, $encoding = null) { - - // Default to getID3's native encoding - if (!$encoding) { - $encoding = $this->_getID3->encoding; - } - // If we've got iconv then go ahead and clear her up - if ($encoding == $this->encoding) { - debug_event('vainfo', "\$encoding -> ${encoding}, \$this->encoding -> {$this->encoding}", 5); - return $tag; - } - if ($this->_iconv) { - debug_event('vainfo', 'Use iconv()',5); - - // Try GNU iconv //TRANSLIT extension first - $new_encoding = $this->encoding . '//TRANSLIT'; - $clean = iconv($encoding, $new_encoding, $tag); - - // If that fails, do a plain conversion - if(strcmp($clean, '') == 0) { - $clean = iconv($encoding, $this->encoding, $tag); - } - } - elseif (function_exists('mb_convert_encoding')) { - debug_event('vainfo', 'Use mbstring',5); - debug_event('vainfo', "Try to convert from {$this->encoding} to $encoding", 5); - $clean = mb_convert_encoding($tag, $encoding, $this->encoding); - } - else { - $clean = $tag; - } - - return $clean; - - } // _clean_tag - - /** * set_broken * * This fills all tag types with Unknown (Broken) |