summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--config/ampache.cfg.php.dist21
-rwxr-xr-xdocs/CHANGELOG4
-rw-r--r--lib/class/vainfo.class.php761
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)