mirror of
https://github.com/Poniverse/Pony.fm.git
synced 2024-11-25 06:27:59 +01:00
Updated getID3() to the latest version.
This commit is contained in:
parent
c99ec8fc54
commit
476e6b4800
111 changed files with 730 additions and 305 deletions
0
app/Library/getid3/.gitattributes
vendored
Executable file → Normal file
0
app/Library/getid3/.gitattributes
vendored
Executable file → Normal file
7
app/Library/getid3/.gitignore
vendored
Executable file → Normal file
7
app/Library/getid3/.gitignore
vendored
Executable file → Normal file
|
@ -1,4 +1,4 @@
|
|||
helperapps/sha1sum.exe
|
||||
helperapps/*.exe
|
||||
helperapps/*.dll
|
||||
|
||||
|
||||
|
@ -110,7 +110,9 @@ ClientBin
|
|||
stylecop.*
|
||||
~$*
|
||||
*.dbmdl
|
||||
Generated_Code #added for RIA/Silverlight projects
|
||||
|
||||
#added for RIA/Silverlight projects
|
||||
Generated_Code
|
||||
|
||||
# Backup & report files from converting an old project file to a newer
|
||||
# Visual Studio version. Backup files are not needed, because we have git ;-)
|
||||
|
@ -165,3 +167,4 @@ pip-log.txt
|
|||
|
||||
# Mac crap
|
||||
.DS_Store
|
||||
demos/php_error.log
|
||||
|
|
2
app/Library/getid3/README.md
Executable file → Normal file
2
app/Library/getid3/README.md
Executable file → Normal file
|
@ -186,7 +186,7 @@ if ($fp_remote = fopen($remotefilename, 'rb')) {
|
|||
fclose($fp_local);
|
||||
// Initialize getID3 engine
|
||||
$getID3 = new getID3;
|
||||
$ThisFileInfo = $getID3->analyze($filename);
|
||||
$ThisFileInfo = $getID3->analyze($localtempfilename);
|
||||
// Delete temporary file
|
||||
unlink($localtempfilename);
|
||||
}
|
||||
|
|
11
app/Library/getid3/changelog.txt
Executable file → Normal file
11
app/Library/getid3/changelog.txt
Executable file → Normal file
|
@ -18,6 +18,17 @@
|
|||
Version History
|
||||
===============
|
||||
|
||||
1.9.10: [2015-09-14] James Heinrich
|
||||
* bugfix (G:49): Declaration of getID3_cached_sqlite3
|
||||
* bugfix (#1892): extension.cache.mysql
|
||||
* bugfix (#1891): duplicate default clause [Quicktime]
|
||||
* bugfix (G:41): incorrect MP3 playtime
|
||||
* bugfix: iconv problems on musl with //TRANSLIT
|
||||
* Add arguments to analyze() for original filesize (and filename)
|
||||
* ID3v2 simplify handling of multiple genres
|
||||
* Corrected merging of multiple genres for ID3v2
|
||||
* getid3_lib::GetDataImageSize return false on error
|
||||
|
||||
1.9.9: [2014-12-18] James Heinrich
|
||||
» Added basic support for OggOpus
|
||||
» Add ID3v2 CHAP + CTOC support
|
||||
|
|
0
app/Library/getid3/composer.json
Executable file → Normal file
0
app/Library/getid3/composer.json
Executable file → Normal file
0
app/Library/getid3/demos/demo.audioinfo.class.php
Executable file → Normal file
0
app/Library/getid3/demos/demo.audioinfo.class.php
Executable file → Normal file
0
app/Library/getid3/demos/demo.basic.php
Executable file → Normal file
0
app/Library/getid3/demos/demo.basic.php
Executable file → Normal file
10
app/Library/getid3/demos/demo.browse.php
Executable file → Normal file
10
app/Library/getid3/demos/demo.browse.php
Executable file → Normal file
|
@ -480,8 +480,11 @@ function table_var_dump($variable, $wrap_in_td=false, $encoding='ISO-8859-1') {
|
|||
//if (($key == 'data') && isset($variable['image_mime']) && isset($variable['dataoffset'])) {
|
||||
if (($key == 'data') && isset($variable['image_mime'])) {
|
||||
$imageinfo = array();
|
||||
$imagechunkcheck = getid3_lib::GetDataImageSize($value, $imageinfo);
|
||||
$returnstring .= '</td>'."\n".'<td><img src="data:'.$variable['image_mime'].';base64,'.base64_encode($value).'" width="'.$imagechunkcheck[0].'" height="'.$imagechunkcheck[1].'"></td></tr>'."\n";
|
||||
if ($imagechunkcheck = getid3_lib::GetDataImageSize($value, $imageinfo)) {
|
||||
$returnstring .= '</td>'."\n".'<td><img src="data:'.$variable['image_mime'].';base64,'.base64_encode($value).'" width="'.$imagechunkcheck[0].'" height="'.$imagechunkcheck[1].'"></td></tr>'."\n";
|
||||
} else {
|
||||
$returnstring .= '</td>'."\n".'<td><i>invalid image data</i></td></tr>'."\n";
|
||||
}
|
||||
} else {
|
||||
$returnstring .= '</td>'."\n".table_var_dump($value, true, $encoding).'</tr>'."\n";
|
||||
}
|
||||
|
@ -515,8 +518,7 @@ function table_var_dump($variable, $wrap_in_td=false, $encoding='ISO-8859-1') {
|
|||
|
||||
default:
|
||||
$imageinfo = array();
|
||||
$imagechunkcheck = getid3_lib::GetDataImageSize($variable, $imageinfo);
|
||||
if (($imagechunkcheck[2] >= 1) && ($imagechunkcheck[2] <= 3)) {
|
||||
if (($imagechunkcheck = getid3_lib::GetDataImageSize($variable, $imageinfo)) && ($imagechunkcheck[2] >= 1) && ($imagechunkcheck[2] <= 3)) {
|
||||
$returnstring .= ($wrap_in_td ? '<td>' : '');
|
||||
$returnstring .= '<table class="dump" cellspacing="0" cellpadding="2">';
|
||||
$returnstring .= '<tr><td><b>type</b></td><td>'.getid3_lib::ImageTypesLookup($imagechunkcheck[2]).'</td></tr>'."\n";
|
||||
|
|
0
app/Library/getid3/demos/demo.cache.dbm.php
Executable file → Normal file
0
app/Library/getid3/demos/demo.cache.dbm.php
Executable file → Normal file
1
app/Library/getid3/demos/demo.cache.mysql.php
Executable file → Normal file
1
app/Library/getid3/demos/demo.cache.mysql.php
Executable file → Normal file
|
@ -17,6 +17,7 @@ die('Due to a security issue, this demo has been disabled. It can be enabled by
|
|||
|
||||
|
||||
require_once('../getid3/getid3.php');
|
||||
require_once('../getid3/getid3.lib.php');
|
||||
getid3_lib::IncludeDependency(GETID3_INCLUDEPATH.'extension.cache.mysql.php', __FILE__, true);
|
||||
|
||||
$getID3 = new getID3_cached_mysql('localhost', 'database', 'username', 'password');
|
||||
|
|
72
app/Library/getid3/demos/demo.joinmp3.php
Executable file → Normal file
72
app/Library/getid3/demos/demo.joinmp3.php
Executable file → Normal file
|
@ -9,37 +9,47 @@
|
|||
// /demo/demo.joinmp3.php - part of getID3() //
|
||||
// Sample script for splicing two or more MP3s together into //
|
||||
// one file. Does not attempt to fix VBR header frames. //
|
||||
// Can also be used to extract portion from single file. //
|
||||
// See readme.txt for more details //
|
||||
// ///
|
||||
/////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
// sample usage:
|
||||
// $FilenameOut = 'combined.mp3';
|
||||
// $FilenamesIn[] = 'file1.mp3';
|
||||
// $FilenamesIn[] = 'file2.mp3';
|
||||
// $FilenamesIn[] = 'file3.mp3';
|
||||
// $FilenameOut = 'combined.mp3';
|
||||
// $FilenamesIn[] = 'first.mp3'; // filename with no start/length parameters
|
||||
// $FilenamesIn[] = array('second.mp3', 0, 0); // filename with zero for start/length is the same as not specified (start = beginning, length = full duration)
|
||||
// $FilenamesIn[] = array('third.mp3', 0, 10); // extract first 10 seconds of audio
|
||||
// $FilenamesIn[] = array('fourth.mp3', -10, 0); // extract last 10 seconds of audio
|
||||
// $FilenamesIn[] = array('fifth.mp3', 10, 0); // extract everything except first 10 seconds of audio
|
||||
// $FilenamesIn[] = array('sixth.mp3', 0, -10); // extract everything except last 10 seconds of audio
|
||||
// if (CombineMultipleMP3sTo($FilenameOut, $FilenamesIn)) {
|
||||
// echo 'Successfully copied '.implode(' + ', $FilenamesIn).' to '.$FilenameOut;
|
||||
// } else {
|
||||
// echo 'Failed to copy '.implode(' + ', $FilenamesIn).' to '.$FilenameOut;
|
||||
// }
|
||||
//
|
||||
// if (CombineMultipleMP3sTo($FilenameOut, $FilenamesIn)) {
|
||||
// echo 'Successfully copied '.implode(' + ', $FilenamesIn).' to '.$FilenameOut;
|
||||
// } else {
|
||||
// echo 'Failed to copy '.implode(' + ', $FilenamesIn).' to '.$FilenameOut;
|
||||
// }
|
||||
// Could also be called like this to extract portion from single file:
|
||||
// CombineMultipleMP3sTo('sample.mp3', array(array('input.mp3', 0, 30))); // extract first 30 seconds of audio
|
||||
|
||||
|
||||
function CombineMultipleMP3sTo($FilenameOut, $FilenamesIn) {
|
||||
|
||||
foreach ($FilenamesIn as $nextinputfilename) {
|
||||
if (is_array($nextinputfilename)) {
|
||||
$nextinputfilename = $nextinputfilename[0];
|
||||
}
|
||||
if (!is_readable($nextinputfilename)) {
|
||||
echo 'Cannot read "'.$nextinputfilename.'"<BR>';
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if (!is_writeable($FilenameOut)) {
|
||||
if ((file_exists($FilenameOut) && !is_writeable($FilenameOut)) || (!file_exists($FilenameOut) && !is_writeable(dirname($FilenameOut)))) {
|
||||
echo 'Cannot write "'.$FilenameOut.'"<BR>';
|
||||
return false;
|
||||
}
|
||||
|
||||
require_once('../getid3/getid3.php');
|
||||
require_once(dirname(__FILE__).'/../getid3/getid3.php');
|
||||
ob_start();
|
||||
if ($fp_output = fopen($FilenameOut, 'wb')) {
|
||||
|
||||
|
@ -47,7 +57,11 @@ function CombineMultipleMP3sTo($FilenameOut, $FilenamesIn) {
|
|||
// Initialize getID3 engine
|
||||
$getID3 = new getID3;
|
||||
foreach ($FilenamesIn as $nextinputfilename) {
|
||||
|
||||
$startoffset = 0;
|
||||
$length_seconds = 0;
|
||||
if (is_array($nextinputfilename)) {
|
||||
@list($nextinputfilename, $startoffset, $length_seconds) = $nextinputfilename;
|
||||
}
|
||||
$CurrentFileInfo = $getID3->analyze($nextinputfilename);
|
||||
if ($CurrentFileInfo['fileformat'] == 'mp3') {
|
||||
|
||||
|
@ -58,17 +72,35 @@ function CombineMultipleMP3sTo($FilenameOut, $FilenamesIn) {
|
|||
$CurrentOutputPosition = ftell($fp_output);
|
||||
|
||||
// copy audio data from first file
|
||||
fseek($fp_source, $CurrentFileInfo['avdataoffset'], SEEK_SET);
|
||||
while (!feof($fp_source) && (ftell($fp_source) < $CurrentFileInfo['avdataend'])) {
|
||||
fwrite($fp_output, fread($fp_source, 32768));
|
||||
$start_offset_bytes = $CurrentFileInfo['avdataoffset'];
|
||||
if ($startoffset > 0) { // start X seconds from start of audio
|
||||
$start_offset_bytes = $CurrentFileInfo['avdataoffset'] + round($CurrentFileInfo['bitrate'] / 8 * $startoffset);
|
||||
} elseif ($startoffset < 0) { // start X seconds from end of audio
|
||||
$start_offset_bytes = $CurrentFileInfo['avdataend'] + round($CurrentFileInfo['bitrate'] / 8 * $startoffset);
|
||||
}
|
||||
$start_offset_bytes = max($CurrentFileInfo['avdataoffset'], min($CurrentFileInfo['avdataend'], $start_offset_bytes));
|
||||
|
||||
$end_offset_bytes = $CurrentFileInfo['avdataend'];
|
||||
if ($length_seconds > 0) { // seconds from start of audio
|
||||
$end_offset_bytes = $start_offset_bytes + round($CurrentFileInfo['bitrate'] / 8 * $length_seconds);
|
||||
} elseif ($length_seconds < 0) { // seconds from start of audio
|
||||
$end_offset_bytes = $CurrentFileInfo['avdataend'] + round($CurrentFileInfo['bitrate'] / 8 * $startoffset);
|
||||
}
|
||||
$end_offset_bytes = max($CurrentFileInfo['avdataoffset'], min($CurrentFileInfo['avdataend'], $end_offset_bytes));
|
||||
|
||||
if ($end_offset_bytes <= $start_offset_bytes) {
|
||||
echo 'failed to copy '.$nextinputfilename.' from '.$startoffset.'-seconds start for '.$length_seconds.'-seconds length (not enough data)';
|
||||
fclose($fp_source);
|
||||
fclose($fp_output);
|
||||
return false;
|
||||
}
|
||||
|
||||
fseek($fp_source, $start_offset_bytes, SEEK_SET);
|
||||
while (!feof($fp_source) && (ftell($fp_source) < $end_offset_bytes)) {
|
||||
fwrite($fp_output, fread($fp_source, min(32768, $end_offset_bytes - ftell($fp_source))));
|
||||
}
|
||||
fclose($fp_source);
|
||||
|
||||
// trim post-audio data (if any) copied from first file that we don't need or want
|
||||
$EndOfFileOffset = $CurrentOutputPosition + ($CurrentFileInfo['avdataend'] - $CurrentFileInfo['avdataoffset']);
|
||||
fseek($fp_output, $EndOfFileOffset, SEEK_SET);
|
||||
ftruncate($fp_output, $EndOfFileOffset);
|
||||
|
||||
} else {
|
||||
|
||||
$errormessage = ob_get_contents();
|
||||
|
|
0
app/Library/getid3/demos/demo.mimeonly.php
Executable file → Normal file
0
app/Library/getid3/demos/demo.mimeonly.php
Executable file → Normal file
29
app/Library/getid3/demos/demo.mp3header.php
Executable file → Normal file
29
app/Library/getid3/demos/demo.mp3header.php
Executable file → Normal file
|
@ -29,10 +29,10 @@ if (!function_exists('table_var_dump')) {
|
|||
$returnstring = '';
|
||||
switch (gettype($variable)) {
|
||||
case 'array':
|
||||
$returnstring .= '<TABLE BORDER="1" CELLSPACING="0" CELLPADDING="2">';
|
||||
$returnstring .= '<table border="1" cellspacing="0" cellpadding="2">';
|
||||
foreach ($variable as $key => $value) {
|
||||
$returnstring .= '<TR><TD VALIGN="TOP"><B>'.str_replace(chr(0), ' ', $key).'</B></TD>';
|
||||
$returnstring .= '<TD VALIGN="TOP">'.gettype($value);
|
||||
$returnstring .= '<tr><td valign="top"><b>'.str_replace(chr(0), ' ', $key).'</b></td>';
|
||||
$returnstring .= '<td valign="top">'.gettype($value);
|
||||
if (is_array($value)) {
|
||||
$returnstring .= ' ('.count($value).')';
|
||||
} elseif (is_string($value)) {
|
||||
|
@ -41,18 +41,21 @@ if (!function_exists('table_var_dump')) {
|
|||
if (($key == 'data') && isset($variable['image_mime']) && isset($variable['dataoffset'])) {
|
||||
require_once(GETID3_INCLUDEPATH.'getid3.getimagesize.php');
|
||||
$imageinfo = array();
|
||||
$imagechunkcheck = GetDataImageSize($value, $imageinfo);
|
||||
$DumpedImageSRC = (!empty($_REQUEST['filename']) ? $_REQUEST['filename'] : '.getid3').'.'.$variable['dataoffset'].'.'.ImageTypesLookup($imagechunkcheck[2]);
|
||||
if ($tempimagefile = fopen($DumpedImageSRC, 'wb')) {
|
||||
fwrite($tempimagefile, $value);
|
||||
fclose($tempimagefile);
|
||||
if ($imagechunkcheck = GetDataImageSize($value, $imageinfo)) {
|
||||
$DumpedImageSRC = (!empty($_REQUEST['filename']) ? $_REQUEST['filename'] : '.getid3').'.'.$variable['dataoffset'].'.'.ImageTypesLookup($imagechunkcheck[2]);
|
||||
if ($tempimagefile = fopen($DumpedImageSRC, 'wb')) {
|
||||
fwrite($tempimagefile, $value);
|
||||
fclose($tempimagefile);
|
||||
}
|
||||
$returnstring .= '</td><td><img src="'.$DumpedImageSRC.'" width="'.$imagechunkcheck[0].'" height="'.$imagechunkcheck[1].'"></td></tr>';
|
||||
} else {
|
||||
$returnstring .= '</td><td><i>invalid image data</i></td></tr>';
|
||||
}
|
||||
$returnstring .= '</TD><TD><IMG SRC="'.$DumpedImageSRC.'" WIDTH="'.$imagechunkcheck[0].'" HEIGHT="'.$imagechunkcheck[1].'"></TD></TR>';
|
||||
} else {
|
||||
$returnstring .= '</TD><TD>'.table_var_dump($value).'</TD></TR>';
|
||||
$returnstring .= '</td><td>'.table_var_dump($value).'</td></tr>';
|
||||
}
|
||||
}
|
||||
$returnstring .= '</TABLE>';
|
||||
$returnstring .= '</table>';
|
||||
break;
|
||||
|
||||
case 'boolean':
|
||||
|
@ -86,9 +89,7 @@ if (!function_exists('table_var_dump')) {
|
|||
default:
|
||||
require_once(GETID3_INCLUDEPATH.'getid3.getimagesize.php');
|
||||
$imageinfo = array();
|
||||
$imagechunkcheck = GetDataImageSize(substr($variable, 0, 32768), $imageinfo);
|
||||
|
||||
if (($imagechunkcheck[2] >= 1) && ($imagechunkcheck[2] <= 3)) {
|
||||
if (($imagechunkcheck = GetDataImageSize(substr($variable, 0, 32768), $imageinfo)) && ($imagechunkcheck[2] >= 1) && ($imagechunkcheck[2] <= 3)) {
|
||||
$returnstring .= '<table border="1" cellspacing="0" cellpadding="2">';
|
||||
$returnstring .= '<tr><td><b>type</b></td><td>'.ImageTypesLookup($imagechunkcheck[2]).'</td></tr>';
|
||||
$returnstring .= '<tr><td><b>width</b></td><td>'.number_format($imagechunkcheck[0]).' px</td></tr>';
|
||||
|
|
0
app/Library/getid3/demos/demo.mysql.php
Executable file → Normal file
0
app/Library/getid3/demos/demo.mysql.php
Executable file → Normal file
0
app/Library/getid3/demos/demo.simple.php
Executable file → Normal file
0
app/Library/getid3/demos/demo.simple.php
Executable file → Normal file
0
app/Library/getid3/demos/demo.simple.write.php
Executable file → Normal file
0
app/Library/getid3/demos/demo.simple.write.php
Executable file → Normal file
0
app/Library/getid3/demos/demo.write.php
Executable file → Normal file
0
app/Library/getid3/demos/demo.write.php
Executable file → Normal file
0
app/Library/getid3/demos/demo.zip.php
Executable file → Normal file
0
app/Library/getid3/demos/demo.zip.php
Executable file → Normal file
0
app/Library/getid3/demos/getid3.css
vendored
Executable file → Normal file
0
app/Library/getid3/demos/getid3.css
vendored
Executable file → Normal file
0
app/Library/getid3/demos/getid3.demo.dirscan.php
Executable file → Normal file
0
app/Library/getid3/demos/getid3.demo.dirscan.php
Executable file → Normal file
0
app/Library/getid3/demos/index.php
Executable file → Normal file
0
app/Library/getid3/demos/index.php
Executable file → Normal file
0
app/Library/getid3/dependencies.txt
Executable file → Normal file
0
app/Library/getid3/dependencies.txt
Executable file → Normal file
0
app/Library/getid3/getid3/extension.cache.dbm.php
Executable file → Normal file
0
app/Library/getid3/getid3/extension.cache.dbm.php
Executable file → Normal file
8
app/Library/getid3/getid3/extension.cache.mysql.php
Executable file → Normal file
8
app/Library/getid3/getid3/extension.cache.mysql.php
Executable file → Normal file
|
@ -134,7 +134,7 @@ class getID3_cached_mysql extends getID3
|
|||
|
||||
|
||||
// public: analyze file
|
||||
public function analyze($filename) {
|
||||
public function analyze($filename, $filesize=null, $original_filename='') {
|
||||
|
||||
if (file_exists($filename)) {
|
||||
|
||||
|
@ -157,7 +157,7 @@ class getID3_cached_mysql extends getID3
|
|||
}
|
||||
|
||||
// Miss
|
||||
$analysis = parent::analyze($filename);
|
||||
$analysis = parent::analyze($filename, $filesize, $original_filename);
|
||||
|
||||
// Save result
|
||||
if (file_exists($filename)) {
|
||||
|
@ -178,11 +178,11 @@ class getID3_cached_mysql extends getID3
|
|||
private function create_table($drop=false) {
|
||||
|
||||
$SQLquery = 'CREATE TABLE IF NOT EXISTS `'.mysql_real_escape_string($this->table).'` (';
|
||||
$SQLquery .= '`filename` VARCHAR(255) NOT NULL DEFAULT \'\'';
|
||||
$SQLquery .= '`filename` VARCHAR(500) NOT NULL DEFAULT \'\'';
|
||||
$SQLquery .= ', `filesize` INT(11) NOT NULL DEFAULT \'0\'';
|
||||
$SQLquery .= ', `filetime` INT(11) NOT NULL DEFAULT \'0\'';
|
||||
$SQLquery .= ', `analyzetime` INT(11) NOT NULL DEFAULT \'0\'';
|
||||
$SQLquery .= ', `value` TEXT NOT NULL';
|
||||
$SQLquery .= ', `value` LONGTEXT NOT NULL';
|
||||
$SQLquery .= ', PRIMARY KEY (`filename`, `filesize`, `filetime`)) ENGINE=MyISAM';
|
||||
$this->cursor = mysql_query($SQLquery, $this->connection);
|
||||
echo mysql_error($this->connection);
|
||||
|
|
55
app/Library/getid3/getid3/extension.cache.sqlite3.php
Executable file → Normal file
55
app/Library/getid3/getid3/extension.cache.sqlite3.php
Executable file → Normal file
|
@ -49,20 +49,20 @@
|
|||
*
|
||||
* sqlite3 table='getid3_cache', hide=false (PHP5)
|
||||
*
|
||||
|
||||
*** database file will be stored in the same directory as this script,
|
||||
*** webserver must have write access to that directory!
|
||||
*** set $hide to TRUE to prefix db file with .ht to pervent access from web client
|
||||
*** this is a default setting in the Apache configuration:
|
||||
|
||||
# The following lines prevent .htaccess and .htpasswd files from being viewed by Web clients.
|
||||
|
||||
<Files ~ "^\.ht">
|
||||
Order allow,deny
|
||||
Deny from all
|
||||
Satisfy all
|
||||
</Files>
|
||||
|
||||
*
|
||||
* *** database file will be stored in the same directory as this script,
|
||||
* *** webserver must have write access to that directory!
|
||||
* *** set $hide to TRUE to prefix db file with .ht to pervent access from web client
|
||||
* *** this is a default setting in the Apache configuration:
|
||||
*
|
||||
* The following lines prevent .htaccess and .htpasswd files from being viewed by Web clients.
|
||||
*
|
||||
* <Files ~ "^\.ht">
|
||||
* Order allow,deny
|
||||
* Deny from all
|
||||
* Satisfy all
|
||||
* </Files>
|
||||
*
|
||||
********************************************************************************
|
||||
*
|
||||
* -------------------------------------------------------------------
|
||||
|
@ -159,13 +159,13 @@ class getID3_cached_sqlite3 extends getID3 {
|
|||
* @param type $filename
|
||||
* @return boolean
|
||||
*/
|
||||
public function analyze($filename) {
|
||||
public function analyze($filename, $filesize=null, $original_filename='') {
|
||||
if (!file_exists($filename)) {
|
||||
return false;
|
||||
}
|
||||
// items to track for caching
|
||||
$filetime = filemtime($filename);
|
||||
$filesize = filesize($filename);
|
||||
$filesize_real = filesize($filename);
|
||||
// this will be saved for a quick directory lookup of analized files
|
||||
// ... why do 50 seperate sql quries when you can do 1 for the same result
|
||||
$dirname = dirname($filename);
|
||||
|
@ -173,25 +173,25 @@ class getID3_cached_sqlite3 extends getID3 {
|
|||
$db = $this->db;
|
||||
$sql = $this->get_id3_data;
|
||||
$stmt = $db->prepare($sql);
|
||||
$stmt->bindValue(':filename', $filename, SQLITE3_TEXT);
|
||||
$stmt->bindValue(':filesize', $filesize, SQLITE3_INTEGER);
|
||||
$stmt->bindValue(':filetime', $filetime, SQLITE3_INTEGER);
|
||||
$stmt->bindValue(':filename', $filename, SQLITE3_TEXT);
|
||||
$stmt->bindValue(':filesize', $filesize_real, SQLITE3_INTEGER);
|
||||
$stmt->bindValue(':filetime', $filetime, SQLITE3_INTEGER);
|
||||
$res = $stmt->execute();
|
||||
list($result) = $res->fetchArray();
|
||||
if (count($result) > 0 ) {
|
||||
return unserialize(base64_decode($result));
|
||||
}
|
||||
// if it hasn't been analyzed before, then do it now
|
||||
$analysis = parent::analyze($filename);
|
||||
$analysis = parent::analyze($filename, $filesize, $original_filename);
|
||||
// Save result
|
||||
$sql = $this->cache_file;
|
||||
$stmt = $db->prepare($sql);
|
||||
$stmt->bindValue(':filename', $filename, SQLITE3_TEXT);
|
||||
$stmt->bindValue(':dirname', $dirname, SQLITE3_TEXT);
|
||||
$stmt->bindValue(':filesize', $filesize, SQLITE3_INTEGER);
|
||||
$stmt->bindValue(':filetime', $filetime, SQLITE3_INTEGER);
|
||||
$stmt->bindValue(':atime', time(), SQLITE3_INTEGER);
|
||||
$stmt->bindValue(':val', base64_encode(serialize($analysis)), SQLITE3_TEXT);
|
||||
$stmt->bindValue(':filename', $filename, SQLITE3_TEXT);
|
||||
$stmt->bindValue(':dirname', $dirname, SQLITE3_TEXT);
|
||||
$stmt->bindValue(':filesize', $filesize_real, SQLITE3_INTEGER);
|
||||
$stmt->bindValue(':filetime', $filetime, SQLITE3_INTEGER);
|
||||
$stmt->bindValue(':atime', time(), SQLITE3_INTEGER);
|
||||
$stmt->bindValue(':val', base64_encode(serialize($analysis)), SQLITE3_TEXT);
|
||||
$res = $stmt->execute();
|
||||
return $analysis;
|
||||
}
|
||||
|
@ -253,7 +253,8 @@ class getID3_cached_sqlite3 extends getID3 {
|
|||
return "INSERT INTO $this->table (filename, dirname, filesize, filetime, analyzetime, val) VALUES (:filename, :dirname, :filesize, :filetime, :atime, :val)";
|
||||
break;
|
||||
case 'make_table':
|
||||
return "CREATE TABLE IF NOT EXISTS $this->table (filename VARCHAR(255) NOT NULL DEFAULT '', dirname VARCHAR(255) NOT NULL DEFAULT '', filesize INT(11) NOT NULL DEFAULT '0', filetime INT(11) NOT NULL DEFAULT '0', analyzetime INT(11) NOT NULL DEFAULT '0', val text not null, PRIMARY KEY (filename, filesize, filetime))";
|
||||
//return "CREATE TABLE IF NOT EXISTS $this->table (filename VARCHAR(255) NOT NULL DEFAULT '', dirname VARCHAR(255) NOT NULL DEFAULT '', filesize INT(11) NOT NULL DEFAULT '0', filetime INT(11) NOT NULL DEFAULT '0', analyzetime INT(11) NOT NULL DEFAULT '0', val text not null, PRIMARY KEY (filename, filesize, filetime))";
|
||||
return "CREATE TABLE IF NOT EXISTS $this->table (filename VARCHAR(255) DEFAULT '', dirname VARCHAR(255) DEFAULT '', filesize INT(11) DEFAULT '0', filetime INT(11) DEFAULT '0', analyzetime INT(11) DEFAULT '0', val text, PRIMARY KEY (filename, filesize, filetime))";
|
||||
break;
|
||||
case 'get_cached_dir':
|
||||
return "SELECT val FROM $this->table WHERE dirname = :dirname";
|
||||
|
|
35
app/Library/getid3/getid3/getid3.lib.php
Executable file → Normal file
35
app/Library/getid3/getid3/getid3.lib.php
Executable file → Normal file
|
@ -414,6 +414,20 @@ class getid3_lib
|
|||
return $newarray;
|
||||
}
|
||||
|
||||
public static function flipped_array_merge_noclobber($array1, $array2) {
|
||||
if (!is_array($array1) || !is_array($array2)) {
|
||||
return false;
|
||||
}
|
||||
# naturally, this only works non-recursively
|
||||
$newarray = array_flip($array1);
|
||||
foreach (array_flip($array2) as $key => $val) {
|
||||
if (!isset($newarray[$key])) {
|
||||
$newarray[$key] = count($newarray);
|
||||
}
|
||||
}
|
||||
return array_flip($newarray);
|
||||
}
|
||||
|
||||
|
||||
public static function ksort_recursive(&$theArray) {
|
||||
ksort($theArray);
|
||||
|
@ -606,7 +620,7 @@ class getid3_lib
|
|||
|
||||
if (empty($tempdir)) {
|
||||
// yes this is ugly, feel free to suggest a better way
|
||||
require_once(dirname(__FILE__) . '/getid3.php');
|
||||
require_once(dirname(__FILE__).'/getid3.php');
|
||||
$getid3_temp = new getID3();
|
||||
$tempdir = $getid3_temp->tempdir;
|
||||
unset($getid3_temp);
|
||||
|
@ -1153,11 +1167,19 @@ class getid3_lib
|
|||
public static function GetDataImageSize($imgData, &$imageinfo=array()) {
|
||||
static $tempdir = '';
|
||||
if (empty($tempdir)) {
|
||||
if (function_exists('sys_get_temp_dir')) {
|
||||
$tempdir = sys_get_temp_dir(); // https://github.com/JamesHeinrich/getID3/issues/52
|
||||
}
|
||||
|
||||
// yes this is ugly, feel free to suggest a better way
|
||||
require_once(dirname(__FILE__) . '/getid3.php');
|
||||
$getid3_temp = new getID3();
|
||||
$tempdir = $getid3_temp->tempdir;
|
||||
unset($getid3_temp);
|
||||
if (include_once(dirname(__FILE__).'/getid3.php')) {
|
||||
if ($getid3_temp = new getID3()) {
|
||||
if ($getid3_temp_tempdir = $getid3_temp->tempdir) {
|
||||
$tempdir = $getid3_temp_tempdir;
|
||||
}
|
||||
unset($getid3_temp, $getid3_temp_tempdir);
|
||||
}
|
||||
}
|
||||
}
|
||||
$GetDataImageSize = false;
|
||||
if ($tempfilename = tempnam($tempdir, 'gI3')) {
|
||||
|
@ -1165,6 +1187,9 @@ class getid3_lib
|
|||
fwrite($tmp, $imgData);
|
||||
fclose($tmp);
|
||||
$GetDataImageSize = @getimagesize($tempfilename, $imageinfo);
|
||||
if (($GetDataImageSize === false) || !isset($GetDataImageSize[0]) || !isset($GetDataImageSize[1])) {
|
||||
return false;
|
||||
}
|
||||
$GetDataImageSize['height'] = $GetDataImageSize[0];
|
||||
$GetDataImageSize['width'] = $GetDataImageSize[1];
|
||||
}
|
||||
|
|
39
app/Library/getid3/getid3/getid3.php
Executable file → Normal file
39
app/Library/getid3/getid3/getid3.php
Executable file → Normal file
|
@ -109,7 +109,7 @@ class getID3
|
|||
protected $startup_error = '';
|
||||
protected $startup_warning = '';
|
||||
|
||||
const VERSION = '1.9.9-20141121';
|
||||
const VERSION = '1.9.10-201511241457';
|
||||
const FREAD_BUFFER_SIZE = 32768;
|
||||
|
||||
const ATTACHMENTS_NONE = false;
|
||||
|
@ -166,7 +166,7 @@ class getID3
|
|||
}
|
||||
|
||||
// Load support library
|
||||
if (!include_once(GETID3_INCLUDEPATH . 'getid3.lib.php')) {
|
||||
if (!include_once(GETID3_INCLUDEPATH.'getid3.lib.php')) {
|
||||
$this->startup_error .= 'getid3.lib.php is missing or corrupt';
|
||||
}
|
||||
|
||||
|
@ -243,7 +243,7 @@ class getID3
|
|||
}
|
||||
|
||||
|
||||
public function openfile($filename) {
|
||||
public function openfile($filename, $filesize=null) {
|
||||
try {
|
||||
if (!empty($this->startup_error)) {
|
||||
throw new getid3_exception($this->startup_error);
|
||||
|
@ -287,7 +287,7 @@ class getID3
|
|||
throw new getid3_exception('Could not open "'.$filename.'" ('.implode('; ', $errormessagelist).')');
|
||||
}
|
||||
|
||||
$this->info['filesize'] = filesize($filename);
|
||||
$this->info['filesize'] = (!is_null($filesize) ? $filesize : filesize($filename));
|
||||
// set redundant parameters - might be needed in some include file
|
||||
// filenames / filepaths in getID3 are always expressed with forward slashes (unix-style) for both Windows and other to try and minimize confusion
|
||||
$filename = str_replace('\\', '/', $filename);
|
||||
|
@ -342,9 +342,9 @@ class getID3
|
|||
}
|
||||
|
||||
// public: analyze file
|
||||
public function analyze($filename) {
|
||||
public function analyze($filename, $filesize=null, $original_filename='') {
|
||||
try {
|
||||
if (!$this->openfile($filename)) {
|
||||
if (!$this->openfile($filename, $filesize)) {
|
||||
return $this->info;
|
||||
}
|
||||
|
||||
|
@ -389,7 +389,7 @@ class getID3
|
|||
$formattest = fread($this->fp, 32774);
|
||||
|
||||
// determine format
|
||||
$determined_format = $this->GetFileFormat($formattest, $filename);
|
||||
$determined_format = $this->GetFileFormat($formattest, ($original_filename ? $original_filename : $filename));
|
||||
|
||||
// unable to determine file format
|
||||
if (!$determined_format) {
|
||||
|
@ -876,7 +876,7 @@ class getID3
|
|||
'pattern' => '^(RIFF|SDSS|FORM)',
|
||||
'group' => 'audio-video',
|
||||
'module' => 'riff',
|
||||
'mime_type' => 'audio/x-wave',
|
||||
'mime_type' => 'audio/x-wav',
|
||||
'fail_ape' => 'WARNING',
|
||||
),
|
||||
|
||||
|
@ -1235,6 +1235,29 @@ class getID3
|
|||
}
|
||||
}
|
||||
|
||||
// ID3v1 encoding detection hack start
|
||||
// ID3v1 is defined as always using ISO-8859-1 encoding, but it is not uncommon to find files tagged with ID3v1 using Windows-1251 or other character sets
|
||||
// Since ID3v1 has no concept of character sets there is no certain way to know we have the correct non-ISO-8859-1 character set, but we can guess
|
||||
if ($comment_name == 'id3v1') {
|
||||
if ($encoding == 'ISO-8859-1') {
|
||||
if (function_exists('iconv')) {
|
||||
foreach ($this->info['tags'][$tag_name] as $tag_key => $valuearray) {
|
||||
foreach ($valuearray as $key => $value) {
|
||||
if (preg_match('#^[\\x80-\\xFF]+$#', $value)) {
|
||||
foreach (array('windows-1251', 'KOI8-R') as $id3v1_bad_encoding) {
|
||||
if (@iconv($id3v1_bad_encoding, $id3v1_bad_encoding, $value) === $value) {
|
||||
$encoding = $id3v1_bad_encoding;
|
||||
break 3;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// ID3v1 encoding detection hack end
|
||||
|
||||
$this->CharConvert($this->info['tags'][$tag_name], $encoding); // only copy gets converted!
|
||||
}
|
||||
|
||||
|
|
0
app/Library/getid3/getid3/module.archive.gzip.php
Executable file → Normal file
0
app/Library/getid3/getid3/module.archive.gzip.php
Executable file → Normal file
0
app/Library/getid3/getid3/module.archive.rar.php
Executable file → Normal file
0
app/Library/getid3/getid3/module.archive.rar.php
Executable file → Normal file
0
app/Library/getid3/getid3/module.archive.szip.php
Executable file → Normal file
0
app/Library/getid3/getid3/module.archive.szip.php
Executable file → Normal file
0
app/Library/getid3/getid3/module.archive.tar.php
Executable file → Normal file
0
app/Library/getid3/getid3/module.archive.tar.php
Executable file → Normal file
0
app/Library/getid3/getid3/module.archive.zip.php
Executable file → Normal file
0
app/Library/getid3/getid3/module.archive.zip.php
Executable file → Normal file
0
app/Library/getid3/getid3/module.audio-video.asf.php
Executable file → Normal file
0
app/Library/getid3/getid3/module.audio-video.asf.php
Executable file → Normal file
0
app/Library/getid3/getid3/module.audio-video.bink.php
Executable file → Normal file
0
app/Library/getid3/getid3/module.audio-video.bink.php
Executable file → Normal file
2
app/Library/getid3/getid3/module.audio-video.flv.php
Executable file → Normal file
2
app/Library/getid3/getid3/module.audio-video.flv.php
Executable file → Normal file
|
@ -541,7 +541,7 @@ class AMFReader {
|
|||
// Long string
|
||||
default:
|
||||
$value = '(unknown or unsupported data type)';
|
||||
break;
|
||||
break;
|
||||
}
|
||||
|
||||
return $value;
|
||||
|
|
33
app/Library/getid3/getid3/module.audio-video.matroska.php
Executable file → Normal file
33
app/Library/getid3/getid3/module.audio-video.matroska.php
Executable file → Normal file
|
@ -457,6 +457,7 @@ class getid3_matroska extends getid3_handler
|
|||
|
||||
default:
|
||||
$this->warning('Unhandled audio type "'.(isset($trackarray['CodecID']) ? $trackarray['CodecID'] : '').'"');
|
||||
break;
|
||||
}
|
||||
|
||||
$info['audio']['streams'][] = $track_info;
|
||||
|
@ -524,6 +525,7 @@ class getid3_matroska extends getid3_handler
|
|||
|
||||
default:
|
||||
$this->unhandledElement('header', __LINE__, $element_data);
|
||||
break;
|
||||
}
|
||||
|
||||
unset($element_data['offset'], $element_data['end']);
|
||||
|
@ -562,6 +564,7 @@ class getid3_matroska extends getid3_handler
|
|||
|
||||
default:
|
||||
$this->unhandledElement('seekhead.seek', __LINE__, $sub_seek_entry); }
|
||||
break;
|
||||
}
|
||||
|
||||
if ($seek_entry['target_id'] != EBML_ID_CLUSTER || !self::$hide_clusters) { // collect clusters only if required
|
||||
|
@ -571,6 +574,7 @@ class getid3_matroska extends getid3_handler
|
|||
|
||||
default:
|
||||
$this->unhandledElement('seekhead', __LINE__, $seek_entry);
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
@ -653,6 +657,7 @@ class getid3_matroska extends getid3_handler
|
|||
|
||||
default:
|
||||
$this->unhandledElement('track.video', __LINE__, $sub_subelement);
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
@ -678,6 +683,7 @@ class getid3_matroska extends getid3_handler
|
|||
|
||||
default:
|
||||
$this->unhandledElement('track.audio', __LINE__, $sub_subelement);
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
@ -713,6 +719,7 @@ class getid3_matroska extends getid3_handler
|
|||
|
||||
default:
|
||||
$this->unhandledElement('track.contentencodings.contentencoding.contentcompression', __LINE__, $sub_sub_sub_subelement);
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
@ -736,24 +743,28 @@ class getid3_matroska extends getid3_handler
|
|||
|
||||
default:
|
||||
$this->unhandledElement('track.contentencodings.contentencoding.contentcompression', __LINE__, $sub_sub_sub_subelement);
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
$this->unhandledElement('track.contentencodings.contentencoding', __LINE__, $sub_sub_subelement);
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
$this->unhandledElement('track.contentencodings', __LINE__, $sub_subelement);
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
$this->unhandledElement('track', __LINE__, $subelement);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -762,6 +773,7 @@ class getid3_matroska extends getid3_handler
|
|||
|
||||
default:
|
||||
$this->unhandledElement('tracks', __LINE__, $track_entry);
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
@ -825,6 +837,7 @@ class getid3_matroska extends getid3_handler
|
|||
|
||||
default:
|
||||
$this->unhandledElement('info.chaptertranslate', __LINE__, $sub_subelement);
|
||||
break;
|
||||
}
|
||||
}
|
||||
$info_entry[$subelement['id_name']] = $chaptertranslate_entry;
|
||||
|
@ -832,6 +845,7 @@ class getid3_matroska extends getid3_handler
|
|||
|
||||
default:
|
||||
$this->unhandledElement('info', __LINE__, $subelement);
|
||||
break;
|
||||
}
|
||||
}
|
||||
$info['matroska']['info'][] = $info_entry;
|
||||
|
@ -868,6 +882,7 @@ class getid3_matroska extends getid3_handler
|
|||
|
||||
default:
|
||||
$this->unhandledElement('cues.cuepoint.cuetrackpositions', __LINE__, $sub_sub_subelement);
|
||||
break;
|
||||
}
|
||||
}
|
||||
$cuepoint_entry[$sub_subelement['id_name']][] = $cuetrackpositions_entry;
|
||||
|
@ -879,6 +894,7 @@ class getid3_matroska extends getid3_handler
|
|||
|
||||
default:
|
||||
$this->unhandledElement('cues.cuepoint', __LINE__, $sub_subelement);
|
||||
break;
|
||||
}
|
||||
}
|
||||
$cues_entry[] = $cuepoint_entry;
|
||||
|
@ -886,6 +902,7 @@ class getid3_matroska extends getid3_handler
|
|||
|
||||
default:
|
||||
$this->unhandledElement('cues', __LINE__, $subelement);
|
||||
break;
|
||||
}
|
||||
}
|
||||
$info['matroska']['cues'] = $cues_entry;
|
||||
|
@ -927,6 +944,7 @@ class getid3_matroska extends getid3_handler
|
|||
|
||||
default:
|
||||
$this->unhandledElement('tags.tag.targets', __LINE__, $sub_sub_subelement);
|
||||
break;
|
||||
}
|
||||
}
|
||||
$tag_entry[$sub_subelement['id_name']] = $targets_entry;
|
||||
|
@ -938,6 +956,7 @@ class getid3_matroska extends getid3_handler
|
|||
|
||||
default:
|
||||
$this->unhandledElement('tags.tag', __LINE__, $sub_subelement);
|
||||
break;
|
||||
}
|
||||
}
|
||||
$tags_entry[] = $tag_entry;
|
||||
|
@ -945,6 +964,7 @@ class getid3_matroska extends getid3_handler
|
|||
|
||||
default:
|
||||
$this->unhandledElement('tags', __LINE__, $subelement);
|
||||
break;
|
||||
}
|
||||
}
|
||||
$info['matroska']['tags'] = $tags_entry;
|
||||
|
@ -985,6 +1005,7 @@ class getid3_matroska extends getid3_handler
|
|||
|
||||
default:
|
||||
$this->unhandledElement('attachments.attachedfile', __LINE__, $sub_subelement);
|
||||
break;
|
||||
}
|
||||
}
|
||||
$info['matroska']['attachments'][] = $attachedfile_entry;
|
||||
|
@ -992,6 +1013,7 @@ class getid3_matroska extends getid3_handler
|
|||
|
||||
default:
|
||||
$this->unhandledElement('attachments', __LINE__, $subelement);
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
@ -1051,6 +1073,7 @@ class getid3_matroska extends getid3_handler
|
|||
|
||||
default:
|
||||
$this->unhandledElement('chapters.editionentry.chapteratom.chaptertrack', __LINE__, $sub_sub_sub_subelement);
|
||||
break;
|
||||
}
|
||||
}
|
||||
$chapteratom_entry[$sub_sub_subelement['id_name']][] = $chaptertrack_entry;
|
||||
|
@ -1070,6 +1093,7 @@ class getid3_matroska extends getid3_handler
|
|||
|
||||
default:
|
||||
$this->unhandledElement('chapters.editionentry.chapteratom.chapterdisplay', __LINE__, $sub_sub_sub_subelement);
|
||||
break;
|
||||
}
|
||||
}
|
||||
$chapteratom_entry[$sub_sub_subelement['id_name']][] = $chapterdisplay_entry;
|
||||
|
@ -1077,6 +1101,7 @@ class getid3_matroska extends getid3_handler
|
|||
|
||||
default:
|
||||
$this->unhandledElement('chapters.editionentry.chapteratom', __LINE__, $sub_sub_subelement);
|
||||
break;
|
||||
}
|
||||
}
|
||||
$editionentry_entry[$sub_subelement['id_name']][] = $chapteratom_entry;
|
||||
|
@ -1084,6 +1109,7 @@ class getid3_matroska extends getid3_handler
|
|||
|
||||
default:
|
||||
$this->unhandledElement('chapters.editionentry', __LINE__, $sub_subelement);
|
||||
break;
|
||||
}
|
||||
}
|
||||
$info['matroska']['chapters'][] = $editionentry_entry;
|
||||
|
@ -1091,6 +1117,7 @@ class getid3_matroska extends getid3_handler
|
|||
|
||||
default:
|
||||
$this->unhandledElement('chapters', __LINE__, $subelement);
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
@ -1119,6 +1146,7 @@ class getid3_matroska extends getid3_handler
|
|||
|
||||
default:
|
||||
$this->unhandledElement('cluster.silenttracks', __LINE__, $sub_subelement);
|
||||
break;
|
||||
}
|
||||
}
|
||||
$cluster_entry[$subelement['id_name']][] = $cluster_silent_tracks;
|
||||
|
@ -1149,6 +1177,7 @@ class getid3_matroska extends getid3_handler
|
|||
|
||||
default:
|
||||
$this->unhandledElement('clusters.blockgroup', __LINE__, $sub_subelement);
|
||||
break;
|
||||
}
|
||||
}
|
||||
$cluster_entry[$subelement['id_name']][] = $cluster_block_group;
|
||||
|
@ -1160,6 +1189,7 @@ class getid3_matroska extends getid3_handler
|
|||
|
||||
default:
|
||||
$this->unhandledElement('cluster', __LINE__, $subelement);
|
||||
break;
|
||||
}
|
||||
$this->current_offset = $subelement['end'];
|
||||
}
|
||||
|
@ -1181,12 +1211,14 @@ class getid3_matroska extends getid3_handler
|
|||
|
||||
default:
|
||||
$this->unhandledElement('segment', __LINE__, $element_data);
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
$this->unhandledElement('root', __LINE__, $top_element);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1339,6 +1371,7 @@ class getid3_matroska extends getid3_handler
|
|||
|
||||
default:
|
||||
$this->unhandledElement('tag.simpletag', __LINE__, $element);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
0
app/Library/getid3/getid3/module.audio-video.mpeg.php
Executable file → Normal file
0
app/Library/getid3/getid3/module.audio-video.mpeg.php
Executable file → Normal file
0
app/Library/getid3/getid3/module.audio-video.nsv.php
Executable file → Normal file
0
app/Library/getid3/getid3/module.audio-video.nsv.php
Executable file → Normal file
563
app/Library/getid3/getid3/module.audio-video.quicktime.php
Executable file → Normal file
563
app/Library/getid3/getid3/module.audio-video.quicktime.php
Executable file → Normal file
|
@ -81,6 +81,81 @@ class getid3_quicktime extends getid3_handler
|
|||
unset($info['avdataend_tmp']);
|
||||
}
|
||||
|
||||
if (!empty($info['quicktime']['comments']['chapters']) && is_array($info['quicktime']['comments']['chapters']) && (count($info['quicktime']['comments']['chapters']) > 0)) {
|
||||
$durations = $this->quicktime_time_to_sample_table($info);
|
||||
for ($i = 0; $i < count($info['quicktime']['comments']['chapters']); $i++) {
|
||||
$bookmark = array();
|
||||
$bookmark['title'] = $info['quicktime']['comments']['chapters'][$i];
|
||||
if (isset($durations[$i])) {
|
||||
$bookmark['duration_sample'] = $durations[$i]['sample_duration'];
|
||||
if ($i > 0) {
|
||||
$bookmark['start_sample'] = $info['quicktime']['bookmarks'][($i - 1)]['start_sample'] + $info['quicktime']['bookmarks'][($i - 1)]['duration_sample'];
|
||||
} else {
|
||||
$bookmark['start_sample'] = 0;
|
||||
}
|
||||
if ($time_scale = $this->quicktime_bookmark_time_scale($info)) {
|
||||
$bookmark['duration_seconds'] = $bookmark['duration_sample'] / $time_scale;
|
||||
$bookmark['start_seconds'] = $bookmark['start_sample'] / $time_scale;
|
||||
}
|
||||
}
|
||||
$info['quicktime']['bookmarks'][] = $bookmark;
|
||||
}
|
||||
}
|
||||
|
||||
if (isset($info['quicktime']['temp_meta_key_names'])) {
|
||||
unset($info['quicktime']['temp_meta_key_names']);
|
||||
}
|
||||
|
||||
if (!empty($info['quicktime']['comments']['location.ISO6709'])) {
|
||||
// https://en.wikipedia.org/wiki/ISO_6709
|
||||
foreach ($info['quicktime']['comments']['location.ISO6709'] as $ISO6709string) {
|
||||
$latitude = false;
|
||||
$longitude = false;
|
||||
$altitude = false;
|
||||
if (preg_match('#^([\\+\\-])([0-9]{2}|[0-9]{4}|[0-9]{6})(\\.[0-9]+)?([\\+\\-])([0-9]{3}|[0-9]{5}|[0-9]{7})(\\.[0-9]+)?(([\\+\\-])([0-9]{3}|[0-9]{5}|[0-9]{7})(\\.[0-9]+)?)?/$#', $ISO6709string, $matches)) {
|
||||
@list($dummy, $lat_sign, $lat_deg, $lat_deg_dec, $lon_sign, $lon_deg, $lon_deg_dec, $dummy, $alt_sign, $alt_deg, $alt_deg_dec) = $matches;
|
||||
|
||||
if (strlen($lat_deg) == 2) { // [+-]DD.D
|
||||
$latitude = floatval(ltrim($lat_deg, '0').$lat_deg_dec);
|
||||
} elseif (strlen($lat_deg) == 4) { // [+-]DDMM.M
|
||||
$latitude = floatval(ltrim(substr($lat_deg, 0, 2), '0')) + floatval(ltrim(substr($lat_deg, 2, 2), '0').$lat_deg_dec / 60);
|
||||
} elseif (strlen($lat_deg) == 6) { // [+-]DDMMSS.S
|
||||
$latitude = floatval(ltrim(substr($lat_deg, 0, 2), '0')) + floatval(ltrim(substr($lat_deg, 2, 2), '0') / 60) + floatval(ltrim(substr($lat_deg, 4, 2), '0').$lat_deg_dec / 3600);
|
||||
}
|
||||
|
||||
if (strlen($lon_deg) == 3) { // [+-]DDD.D
|
||||
$longitude = floatval(ltrim($lon_deg, '0').$lon_deg_dec);
|
||||
} elseif (strlen($lon_deg) == 5) { // [+-]DDDMM.M
|
||||
$longitude = floatval(ltrim(substr($lon_deg, 0, 2), '0')) + floatval(ltrim(substr($lon_deg, 2, 2), '0').$lon_deg_dec / 60);
|
||||
} elseif (strlen($lon_deg) == 7) { // [+-]DDDMMSS.S
|
||||
$longitude = floatval(ltrim(substr($lon_deg, 0, 2), '0')) + floatval(ltrim(substr($lon_deg, 2, 2), '0') / 60) + floatval(ltrim(substr($lon_deg, 4, 2), '0').$lon_deg_dec / 3600);
|
||||
}
|
||||
|
||||
if (strlen($alt_deg) == 3) { // [+-]DDD.D
|
||||
$altitude = floatval(ltrim($alt_deg, '0').$alt_deg_dec);
|
||||
} elseif (strlen($alt_deg) == 5) { // [+-]DDDMM.M
|
||||
$altitude = floatval(ltrim(substr($alt_deg, 0, 2), '0')) + floatval(ltrim(substr($alt_deg, 2, 2), '0').$alt_deg_dec / 60);
|
||||
} elseif (strlen($alt_deg) == 7) { // [+-]DDDMMSS.S
|
||||
$altitude = floatval(ltrim(substr($alt_deg, 0, 2), '0')) + floatval(ltrim(substr($alt_deg, 2, 2), '0') / 60) + floatval(ltrim(substr($alt_deg, 4, 2), '0').$alt_deg_dec / 3600);
|
||||
}
|
||||
|
||||
if ($latitude !== false) {
|
||||
$info['quicktime']['comments']['gps_latitude'][] = (($lat_sign == '-') ? -1 : 1) * floatval($latitude);
|
||||
}
|
||||
if ($longitude !== false) {
|
||||
$info['quicktime']['comments']['gps_longitude'][] = (($lon_sign == '-') ? -1 : 1) * floatval($longitude);
|
||||
}
|
||||
if ($altitude !== false) {
|
||||
$info['quicktime']['comments']['gps_altitude'][] = (($alt_sign == '-') ? -1 : 1) * floatval($altitude);
|
||||
}
|
||||
}
|
||||
if ($latitude === false) {
|
||||
$info['warning'][] = 'location.ISO6709 string not parsed correctly: "'.$ISO6709string.'", please submit as a bug';
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!isset($info['bitrate']) && isset($info['playtime_seconds'])) {
|
||||
$info['bitrate'] = (($info['avdataend'] - $info['avdataoffset']) * 8) / $info['playtime_seconds'];
|
||||
}
|
||||
|
@ -120,6 +195,7 @@ class getid3_quicktime extends getid3_handler
|
|||
|
||||
public function QuicktimeParseAtom($atomname, $atomsize, $atom_data, $baseoffset, &$atomHierarchy, $ParseAllPossibleAtoms) {
|
||||
// http://developer.apple.com/techpubs/quicktime/qtdevdocs/APIREF/INDEX/atomalphaindex.htm
|
||||
// https://code.google.com/p/mp4v2/wiki/iTunesMetadata
|
||||
|
||||
$info = &$this->getid3->info;
|
||||
|
||||
|
@ -222,81 +298,88 @@ class getid3_quicktime extends getid3_handler
|
|||
break;
|
||||
|
||||
|
||||
case "\xA9".'alb': // ALBum
|
||||
case "\xA9".'ART': //
|
||||
case "\xA9".'art': // ARTist
|
||||
case "\xA9".'aut': //
|
||||
case "\xA9".'cmt': // CoMmenT
|
||||
case "\xA9".'com': // COMposer
|
||||
case "\xA9".'cpy': //
|
||||
case "\xA9".'day': // content created year
|
||||
case "\xA9".'dir': //
|
||||
case "\xA9".'ed1': //
|
||||
case "\xA9".'ed2': //
|
||||
case "\xA9".'ed3': //
|
||||
case "\xA9".'ed4': //
|
||||
case "\xA9".'ed5': //
|
||||
case "\xA9".'ed6': //
|
||||
case "\xA9".'ed7': //
|
||||
case "\xA9".'ed8': //
|
||||
case "\xA9".'ed9': //
|
||||
case "\xA9".'enc': //
|
||||
case "\xA9".'fmt': //
|
||||
case "\xA9".'gen': // GENre
|
||||
case "\xA9".'grp': // GRouPing
|
||||
case "\xA9".'hst': //
|
||||
case "\xA9".'inf': //
|
||||
case "\xA9".'lyr': // LYRics
|
||||
case "\xA9".'mak': //
|
||||
case "\xA9".'mod': //
|
||||
case "\xA9".'nam': // full NAMe
|
||||
case "\xA9".'ope': //
|
||||
case "\xA9".'PRD': //
|
||||
case "\xA9".'prf': //
|
||||
case "\xA9".'req': //
|
||||
case "\xA9".'src': //
|
||||
case "\xA9".'swr': //
|
||||
case "\xA9".'too': // encoder
|
||||
case "\xA9".'trk': // TRacK
|
||||
case "\xA9".'url': //
|
||||
case "\xA9".'wrn': //
|
||||
case "\xA9".'wrt': // WRiTer
|
||||
case '----': // itunes specific
|
||||
case 'aART': // Album ARTist
|
||||
case 'akID': // iTunes store account type
|
||||
case 'apID': // Purchase Account
|
||||
case 'atID': //
|
||||
case 'catg': // CaTeGory
|
||||
case 'cmID': //
|
||||
case 'cnID': //
|
||||
case 'covr': // COVeR artwork
|
||||
case 'cpil': // ComPILation
|
||||
case 'cprt': // CoPyRighT
|
||||
case 'desc': // DESCription
|
||||
case 'disk': // DISK number
|
||||
case 'egid': // Episode Global ID
|
||||
case 'geID': //
|
||||
case 'gnre': // GeNRE
|
||||
case 'hdvd': // HD ViDeo
|
||||
case 'keyw': // KEYWord
|
||||
case 'ldes':
|
||||
case 'ldes': // Long DEScription
|
||||
case 'pcst': // PodCaST
|
||||
case 'pgap': // GAPless Playback
|
||||
case 'plID': //
|
||||
case 'purd': // PURchase Date
|
||||
case 'purl': // Podcast URL
|
||||
case 'rati':
|
||||
case 'rndu':
|
||||
case 'rpdu':
|
||||
case 'rati': //
|
||||
case 'rndu': //
|
||||
case 'rpdu': //
|
||||
case 'rtng': // RaTiNG
|
||||
case 'stik':
|
||||
case 'sfID': // iTunes store country
|
||||
case 'soaa': // SOrt Album Artist
|
||||
case 'soal': // SOrt ALbum
|
||||
case 'soar': // SOrt ARtist
|
||||
case 'soco': // SOrt COmposer
|
||||
case 'sonm': // SOrt NaMe
|
||||
case 'sosn': // SOrt Show Name
|
||||
case 'stik': //
|
||||
case 'tmpo': // TeMPO (BPM)
|
||||
case 'trkn': // TRacK Number
|
||||
case 'tven': // tvEpisodeID
|
||||
case 'tves': // TV EpiSode
|
||||
case 'tvnn': // TV Network Name
|
||||
case 'tvsh': // TV SHow Name
|
||||
case 'tvsn': // TV SeasoN
|
||||
case 'akID': // iTunes store account type
|
||||
case 'apID':
|
||||
case 'atID':
|
||||
case 'cmID':
|
||||
case 'cnID':
|
||||
case 'geID':
|
||||
case 'plID':
|
||||
case 'sfID': // iTunes store country
|
||||
case "\xA9".'alb': // ALBum
|
||||
case "\xA9".'art': // ARTist
|
||||
case "\xA9".'ART':
|
||||
case "\xA9".'aut':
|
||||
case "\xA9".'cmt': // CoMmenT
|
||||
case "\xA9".'com': // COMposer
|
||||
case "\xA9".'cpy':
|
||||
case "\xA9".'day': // content created year
|
||||
case "\xA9".'dir':
|
||||
case "\xA9".'ed1':
|
||||
case "\xA9".'ed2':
|
||||
case "\xA9".'ed3':
|
||||
case "\xA9".'ed4':
|
||||
case "\xA9".'ed5':
|
||||
case "\xA9".'ed6':
|
||||
case "\xA9".'ed7':
|
||||
case "\xA9".'ed8':
|
||||
case "\xA9".'ed9':
|
||||
case "\xA9".'enc':
|
||||
case "\xA9".'fmt':
|
||||
case "\xA9".'gen': // GENre
|
||||
case "\xA9".'grp': // GRouPing
|
||||
case "\xA9".'hst':
|
||||
case "\xA9".'inf':
|
||||
case "\xA9".'lyr': // LYRics
|
||||
case "\xA9".'mak':
|
||||
case "\xA9".'mod':
|
||||
case "\xA9".'nam': // full NAMe
|
||||
case "\xA9".'ope':
|
||||
case "\xA9".'PRD':
|
||||
case "\xA9".'prd':
|
||||
case "\xA9".'prf':
|
||||
case "\xA9".'req':
|
||||
case "\xA9".'src':
|
||||
case "\xA9".'swr':
|
||||
case "\xA9".'too': // encoder
|
||||
case "\xA9".'trk': // TRacK
|
||||
case "\xA9".'url':
|
||||
case "\xA9".'wrn':
|
||||
case "\xA9".'wrt': // WRiTer
|
||||
case '----': // itunes specific
|
||||
if ($atom_parent == 'udta') {
|
||||
// User data atom handler
|
||||
$atom_structure['data_length'] = getid3_lib::BigEndian2Int(substr($atom_data, 0, 2));
|
||||
|
@ -361,17 +444,21 @@ class getid3_quicktime extends getid3_handler
|
|||
case 21: // tmpo/cpil flag
|
||||
switch ($atomname) {
|
||||
case 'cpil':
|
||||
case 'hdvd':
|
||||
case 'pcst':
|
||||
case 'pgap':
|
||||
// 8-bit integer (boolean)
|
||||
$atom_structure['data'] = getid3_lib::BigEndian2Int(substr($boxdata, 8, 1));
|
||||
break;
|
||||
|
||||
case 'tmpo':
|
||||
// 16-bit integer
|
||||
$atom_structure['data'] = getid3_lib::BigEndian2Int(substr($boxdata, 8, 2));
|
||||
break;
|
||||
|
||||
case 'disk':
|
||||
case 'trkn':
|
||||
// binary
|
||||
$num = getid3_lib::BigEndian2Int(substr($boxdata, 10, 2));
|
||||
$num_total = getid3_lib::BigEndian2Int(substr($boxdata, 12, 2));
|
||||
$atom_structure['data'] = empty($num) ? '' : $num;
|
||||
|
@ -379,21 +466,25 @@ class getid3_quicktime extends getid3_handler
|
|||
break;
|
||||
|
||||
case 'gnre':
|
||||
// enum
|
||||
$GenreID = getid3_lib::BigEndian2Int(substr($boxdata, 8, 4));
|
||||
$atom_structure['data'] = getid3_id3v1::LookupGenreName($GenreID - 1);
|
||||
break;
|
||||
|
||||
case 'rtng':
|
||||
// 8-bit integer
|
||||
$atom_structure[$atomname] = getid3_lib::BigEndian2Int(substr($boxdata, 8, 1));
|
||||
$atom_structure['data'] = $this->QuicktimeContentRatingLookup($atom_structure[$atomname]);
|
||||
break;
|
||||
|
||||
case 'stik':
|
||||
// 8-bit integer (enum)
|
||||
$atom_structure[$atomname] = getid3_lib::BigEndian2Int(substr($boxdata, 8, 1));
|
||||
$atom_structure['data'] = $this->QuicktimeSTIKLookup($atom_structure[$atomname]);
|
||||
break;
|
||||
|
||||
case 'sfID':
|
||||
// 32-bit integer
|
||||
$atom_structure[$atomname] = getid3_lib::BigEndian2Int(substr($boxdata, 8, 4));
|
||||
$atom_structure['data'] = $this->QuicktimeStoreFrontCodeLookup($atom_structure[$atomname]);
|
||||
break;
|
||||
|
@ -403,7 +494,18 @@ class getid3_quicktime extends getid3_handler
|
|||
$atom_structure['data'] = substr($boxdata, 8);
|
||||
break;
|
||||
|
||||
case 'plID':
|
||||
// 64-bit integer
|
||||
$atom_structure['data'] = getid3_lib::BigEndian2Int(substr($boxdata, 8, 8));
|
||||
break;
|
||||
|
||||
case 'atID':
|
||||
case 'cnID':
|
||||
case 'geID':
|
||||
case 'tves':
|
||||
case 'tvsn':
|
||||
default:
|
||||
// 32-bit integer
|
||||
$atom_structure['data'] = getid3_lib::BigEndian2Int(substr($boxdata, 8, 4));
|
||||
}
|
||||
break;
|
||||
|
@ -928,13 +1030,13 @@ if (!empty($atom_structure['sample_description_table'][$i]['width']) && !empty($
|
|||
for ($i = 0; $i < $atom_structure['number_entries']; $i++) {
|
||||
$atom_structure['data_references'][$i]['size'] = getid3_lib::BigEndian2Int(substr($atom_data, $drefDataOffset, 4));
|
||||
$drefDataOffset += 4;
|
||||
$atom_structure['data_references'][$i]['type'] = substr($atom_data, $drefDataOffset, 4);
|
||||
$atom_structure['data_references'][$i]['type'] = substr($atom_data, $drefDataOffset, 4);
|
||||
$drefDataOffset += 4;
|
||||
$atom_structure['data_references'][$i]['version'] = getid3_lib::BigEndian2Int(substr($atom_data, $drefDataOffset, 1));
|
||||
$drefDataOffset += 1;
|
||||
$atom_structure['data_references'][$i]['flags_raw'] = getid3_lib::BigEndian2Int(substr($atom_data, $drefDataOffset, 3)); // hardcoded: 0x0000
|
||||
$drefDataOffset += 3;
|
||||
$atom_structure['data_references'][$i]['data'] = substr($atom_data, $drefDataOffset, ($atom_structure['data_references'][$i]['size'] - 4 - 4 - 1 - 3));
|
||||
$atom_structure['data_references'][$i]['data'] = substr($atom_data, $drefDataOffset, ($atom_structure['data_references'][$i]['size'] - 4 - 4 - 1 - 3));
|
||||
$drefDataOffset += ($atom_structure['data_references'][$i]['size'] - 4 - 4 - 1 - 3);
|
||||
|
||||
$atom_structure['data_references'][$i]['flags']['self_reference'] = (bool) ($atom_structure['data_references'][$i]['flags_raw'] & 0x001);
|
||||
|
@ -1004,7 +1106,7 @@ if (!empty($atom_structure['sample_description_table'][$i]['width']) && !empty($
|
|||
$info['error'][] = 'Corrupt Quicktime file: mdhd.time_scale == zero';
|
||||
return false;
|
||||
}
|
||||
$info['quicktime']['time_scale'] = (isset($info['quicktime']['time_scale']) ? max($info['quicktime']['time_scale'], $atom_structure['time_scale']) : $atom_structure['time_scale']);
|
||||
$info['quicktime']['time_scale'] = ((isset($info['quicktime']['time_scale']) && ($info['quicktime']['time_scale'] < 1000)) ? max($info['quicktime']['time_scale'], $atom_structure['time_scale']) : $atom_structure['time_scale']);
|
||||
|
||||
$atom_structure['creation_time_unix'] = getid3_lib::DateMac2Unix($atom_structure['creation_time']);
|
||||
$atom_structure['modify_time_unix'] = getid3_lib::DateMac2Unix($atom_structure['modify_time']);
|
||||
|
@ -1019,7 +1121,7 @@ if (!empty($atom_structure['sample_description_table'][$i]['width']) && !empty($
|
|||
case 'pnot': // Preview atom
|
||||
$atom_structure['modification_date'] = getid3_lib::BigEndian2Int(substr($atom_data, 0, 4)); // "standard Macintosh format"
|
||||
$atom_structure['version_number'] = getid3_lib::BigEndian2Int(substr($atom_data, 4, 2)); // hardcoded: 0x00
|
||||
$atom_structure['atom_type'] = substr($atom_data, 6, 4); // usually: 'PICT'
|
||||
$atom_structure['atom_type'] = substr($atom_data, 6, 4); // usually: 'PICT'
|
||||
$atom_structure['atom_index'] = getid3_lib::BigEndian2Int(substr($atom_data, 10, 2)); // usually: 0x01
|
||||
|
||||
$atom_structure['modification_date_unix'] = getid3_lib::DateMac2Unix($atom_structure['modification_date']);
|
||||
|
@ -1029,7 +1131,7 @@ if (!empty($atom_structure['sample_description_table'][$i]['width']) && !empty($
|
|||
case 'crgn': // Clipping ReGioN atom
|
||||
$atom_structure['region_size'] = getid3_lib::BigEndian2Int(substr($atom_data, 0, 2)); // The Region size, Region boundary box,
|
||||
$atom_structure['boundary_box'] = getid3_lib::BigEndian2Int(substr($atom_data, 2, 8)); // and Clipping region data fields
|
||||
$atom_structure['clipping_data'] = substr($atom_data, 10); // constitute a QuickDraw region.
|
||||
$atom_structure['clipping_data'] = substr($atom_data, 10); // constitute a QuickDraw region.
|
||||
break;
|
||||
|
||||
|
||||
|
@ -1120,7 +1222,7 @@ if (!empty($atom_structure['sample_description_table'][$i]['width']) && !empty($
|
|||
}
|
||||
$atom_structure['creation_time_unix'] = getid3_lib::DateMac2Unix($atom_structure['creation_time']);
|
||||
$atom_structure['modify_time_unix'] = getid3_lib::DateMac2Unix($atom_structure['modify_time']);
|
||||
$info['quicktime']['time_scale'] = (isset($info['quicktime']['time_scale']) ? max($info['quicktime']['time_scale'], $atom_structure['time_scale']) : $atom_structure['time_scale']);
|
||||
$info['quicktime']['time_scale'] = ((isset($info['quicktime']['time_scale']) && ($info['quicktime']['time_scale'] < 1000)) ? max($info['quicktime']['time_scale'], $atom_structure['time_scale']) : $atom_structure['time_scale']);
|
||||
$info['quicktime']['display_scale'] = $atom_structure['matrix_a'];
|
||||
$info['playtime_seconds'] = $atom_structure['duration'] / $atom_structure['time_scale'];
|
||||
break;
|
||||
|
@ -1240,14 +1342,20 @@ if (!empty($atom_structure['sample_description_table'][$i]['width']) && !empty($
|
|||
}
|
||||
|
||||
// check to see if it looks like chapter titles, in the form of unterminated strings with a leading 16-bit size field
|
||||
while (($chapter_string_length = getid3_lib::BigEndian2Int(substr($atom_data, $mdat_offset, 2)))
|
||||
while (($mdat_offset < (strlen($atom_data) - 8))
|
||||
&& ($chapter_string_length = getid3_lib::BigEndian2Int(substr($atom_data, $mdat_offset, 2)))
|
||||
&& ($chapter_string_length < 1000)
|
||||
&& ($chapter_string_length <= (strlen($atom_data) - $mdat_offset - 2))
|
||||
&& preg_match('#^[\x20-\xFF]+$#', substr($atom_data, $mdat_offset + 2, $chapter_string_length), $chapter_matches)) {
|
||||
&& preg_match('#^([\x00-\xFF]{2})([\x20-\xFF]+)$#', substr($atom_data, $mdat_offset, $chapter_string_length + 2), $chapter_matches)) {
|
||||
list($dummy, $chapter_string_length_hex, $chapter_string) = $chapter_matches;
|
||||
$mdat_offset += (2 + $chapter_string_length);
|
||||
@$info['quicktime']['comments']['chapters'][] = $chapter_matches[0];
|
||||
}
|
||||
@$info['quicktime']['comments']['chapters'][] = $chapter_string;
|
||||
|
||||
// "encd" atom specifies encoding. In theory could be anything, almost always UTF-8, but may be UTF-16 with BOM (not currently handled)
|
||||
if (substr($atom_data, $mdat_offset, 12) == "\x00\x00\x00\x0C\x65\x6E\x63\x64\x00\x00\x01\x00") { // UTF-8
|
||||
$mdat_offset += 12;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (($atomsize > 8) && (!isset($info['avdataend_tmp']) || ($info['quicktime'][$atomname]['size'] > ($info['avdataend_tmp'] - $info['avdataoffset'])))) {
|
||||
|
@ -1397,22 +1505,53 @@ if (!empty($atom_structure['sample_description_table'][$i]['width']) && !empty($
|
|||
break;
|
||||
|
||||
case "\x00\x00\x00\x00":
|
||||
case 'meta': // METAdata atom
|
||||
// some kind of metacontainer, may contain a big data dump such as:
|
||||
// mdta keys \005 mdtacom.apple.quicktime.make (mdtacom.apple.quicktime.creationdate ,mdtacom.apple.quicktime.location.ISO6709 $mdtacom.apple.quicktime.software !mdtacom.apple.quicktime.model ilst \01D \001 \015data \001DE\010Apple 0 \002 (data \001DE\0102011-05-11T17:54:04+0200 2 \003 *data \001DE\010+52.4936+013.3897+040.247/ \01D \004 \015data \001DE\0104.3.1 \005 \018data \001DE\010iPhone 4
|
||||
// http://www.geocities.com/xhelmboyx/quicktime/formats/qti-layout.txt
|
||||
|
||||
$atom_structure['version'] = getid3_lib::BigEndian2Int(substr($atom_data, 0, 1));
|
||||
$atom_structure['flags_raw'] = getid3_lib::BigEndian2Int(substr($atom_data, 1, 3));
|
||||
$atom_structure['subatoms'] = $this->QuicktimeParseContainerAtom(substr($atom_data, 4), $baseoffset + 8, $atomHierarchy, $ParseAllPossibleAtoms);
|
||||
$atom_structure['version'] = getid3_lib::BigEndian2Int(substr($atom_data, 0, 1));
|
||||
$atom_structure['flags_raw'] = getid3_lib::BigEndian2Int(substr($atom_data, 1, 3));
|
||||
$atom_structure['subatoms'] = $this->QuicktimeParseContainerAtom(substr($atom_data, 4), $baseoffset + 8, $atomHierarchy, $ParseAllPossibleAtoms);
|
||||
//$atom_structure['subatoms'] = $this->QuicktimeParseContainerAtom($atom_data, $baseoffset + 8, $atomHierarchy, $ParseAllPossibleAtoms);
|
||||
break;
|
||||
|
||||
case 'meta': // METAdata atom
|
||||
// https://developer.apple.com/library/mac/documentation/QuickTime/QTFF/Metadata/Metadata.html
|
||||
|
||||
$atom_structure['version'] = getid3_lib::BigEndian2Int(substr($atom_data, 0, 1));
|
||||
$atom_structure['flags_raw'] = getid3_lib::BigEndian2Int(substr($atom_data, 1, 3));
|
||||
$atom_structure['subatoms'] = $this->QuicktimeParseContainerAtom($atom_data, $baseoffset + 8, $atomHierarchy, $ParseAllPossibleAtoms);
|
||||
break;
|
||||
|
||||
case 'data': // metaDATA atom
|
||||
static $metaDATAkey = 1; // real ugly, but so is the QuickTime structure that stores keys and values in different multinested locations that are hard to relate to each other
|
||||
// seems to be 2 bytes language code (ASCII), 2 bytes unknown (set to 0x10B5 in sample I have), remainder is useful data
|
||||
$atom_structure['language'] = substr($atom_data, 4 + 0, 2);
|
||||
$atom_structure['unknown'] = getid3_lib::BigEndian2Int(substr($atom_data, 4 + 2, 2));
|
||||
$atom_structure['data'] = substr($atom_data, 4 + 4);
|
||||
$atom_structure['key_name'] = @$info['quicktime']['temp_meta_key_names'][$metaDATAkey++];
|
||||
|
||||
if ($atom_structure['key_name'] && $atom_structure['data']) {
|
||||
@$info['quicktime']['comments'][str_replace('com.apple.quicktime.', '', $atom_structure['key_name'])][] = $atom_structure['data'];
|
||||
}
|
||||
break;
|
||||
|
||||
case 'keys': // KEYS that may be present in the metadata atom.
|
||||
// https://developer.apple.com/library/mac/documentation/QuickTime/QTFF/Metadata/Metadata.html#//apple_ref/doc/uid/TP40000939-CH1-SW21
|
||||
// The metadata item keys atom holds a list of the metadata keys that may be present in the metadata atom.
|
||||
// This list is indexed starting with 1; 0 is a reserved index value. The metadata item keys atom is a full atom with an atom type of "keys".
|
||||
$atom_structure['version'] = getid3_lib::BigEndian2Int(substr($atom_data, 0, 1));
|
||||
$atom_structure['flags_raw'] = getid3_lib::BigEndian2Int(substr($atom_data, 1, 3));
|
||||
$atom_structure['entry_count'] = getid3_lib::BigEndian2Int(substr($atom_data, 4, 4));
|
||||
$keys_atom_offset = 8;
|
||||
for ($i = 1; $i <= $atom_structure['entry_count']; $i++) {
|
||||
$atom_structure['keys'][$i]['key_size'] = getid3_lib::BigEndian2Int(substr($atom_data, $keys_atom_offset + 0, 4));
|
||||
$atom_structure['keys'][$i]['key_namespace'] = substr($atom_data, $keys_atom_offset + 4, 4);
|
||||
$atom_structure['keys'][$i]['key_value'] = substr($atom_data, $keys_atom_offset + 8, $atom_structure['keys'][$i]['key_size'] - 8);
|
||||
$keys_atom_offset += $atom_structure['keys'][$i]['key_size']; // key_size includes the 4+4 bytes for key_size and key_namespace
|
||||
|
||||
$info['quicktime']['temp_meta_key_names'][$i] = $atom_structure['keys'][$i]['key_value'];
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
|
@ -1753,56 +1892,56 @@ if (!empty($atom_structure['sample_description_table'][$i]['width']) && !empty($
|
|||
static $QuicktimeIODSaudioProfileNameLookup = array();
|
||||
if (empty($QuicktimeIODSaudioProfileNameLookup)) {
|
||||
$QuicktimeIODSaudioProfileNameLookup = array(
|
||||
0x00 => 'ISO Reserved (0x00)',
|
||||
0x01 => 'Main Audio Profile @ Level 1',
|
||||
0x02 => 'Main Audio Profile @ Level 2',
|
||||
0x03 => 'Main Audio Profile @ Level 3',
|
||||
0x04 => 'Main Audio Profile @ Level 4',
|
||||
0x05 => 'Scalable Audio Profile @ Level 1',
|
||||
0x06 => 'Scalable Audio Profile @ Level 2',
|
||||
0x07 => 'Scalable Audio Profile @ Level 3',
|
||||
0x08 => 'Scalable Audio Profile @ Level 4',
|
||||
0x09 => 'Speech Audio Profile @ Level 1',
|
||||
0x0A => 'Speech Audio Profile @ Level 2',
|
||||
0x0B => 'Synthetic Audio Profile @ Level 1',
|
||||
0x0C => 'Synthetic Audio Profile @ Level 2',
|
||||
0x0D => 'Synthetic Audio Profile @ Level 3',
|
||||
0x0E => 'High Quality Audio Profile @ Level 1',
|
||||
0x0F => 'High Quality Audio Profile @ Level 2',
|
||||
0x10 => 'High Quality Audio Profile @ Level 3',
|
||||
0x11 => 'High Quality Audio Profile @ Level 4',
|
||||
0x12 => 'High Quality Audio Profile @ Level 5',
|
||||
0x13 => 'High Quality Audio Profile @ Level 6',
|
||||
0x14 => 'High Quality Audio Profile @ Level 7',
|
||||
0x15 => 'High Quality Audio Profile @ Level 8',
|
||||
0x16 => 'Low Delay Audio Profile @ Level 1',
|
||||
0x17 => 'Low Delay Audio Profile @ Level 2',
|
||||
0x18 => 'Low Delay Audio Profile @ Level 3',
|
||||
0x19 => 'Low Delay Audio Profile @ Level 4',
|
||||
0x1A => 'Low Delay Audio Profile @ Level 5',
|
||||
0x1B => 'Low Delay Audio Profile @ Level 6',
|
||||
0x1C => 'Low Delay Audio Profile @ Level 7',
|
||||
0x1D => 'Low Delay Audio Profile @ Level 8',
|
||||
0x1E => 'Natural Audio Profile @ Level 1',
|
||||
0x1F => 'Natural Audio Profile @ Level 2',
|
||||
0x20 => 'Natural Audio Profile @ Level 3',
|
||||
0x21 => 'Natural Audio Profile @ Level 4',
|
||||
0x22 => 'Mobile Audio Internetworking Profile @ Level 1',
|
||||
0x23 => 'Mobile Audio Internetworking Profile @ Level 2',
|
||||
0x24 => 'Mobile Audio Internetworking Profile @ Level 3',
|
||||
0x25 => 'Mobile Audio Internetworking Profile @ Level 4',
|
||||
0x26 => 'Mobile Audio Internetworking Profile @ Level 5',
|
||||
0x27 => 'Mobile Audio Internetworking Profile @ Level 6',
|
||||
0x28 => 'AAC Profile @ Level 1',
|
||||
0x29 => 'AAC Profile @ Level 2',
|
||||
0x2A => 'AAC Profile @ Level 4',
|
||||
0x2B => 'AAC Profile @ Level 5',
|
||||
0x2C => 'High Efficiency AAC Profile @ Level 2',
|
||||
0x2D => 'High Efficiency AAC Profile @ Level 3',
|
||||
0x2E => 'High Efficiency AAC Profile @ Level 4',
|
||||
0x2F => 'High Efficiency AAC Profile @ Level 5',
|
||||
0xFE => 'Not part of MPEG-4 audio profiles',
|
||||
0xFF => 'No audio capability required',
|
||||
0x00 => 'ISO Reserved (0x00)',
|
||||
0x01 => 'Main Audio Profile @ Level 1',
|
||||
0x02 => 'Main Audio Profile @ Level 2',
|
||||
0x03 => 'Main Audio Profile @ Level 3',
|
||||
0x04 => 'Main Audio Profile @ Level 4',
|
||||
0x05 => 'Scalable Audio Profile @ Level 1',
|
||||
0x06 => 'Scalable Audio Profile @ Level 2',
|
||||
0x07 => 'Scalable Audio Profile @ Level 3',
|
||||
0x08 => 'Scalable Audio Profile @ Level 4',
|
||||
0x09 => 'Speech Audio Profile @ Level 1',
|
||||
0x0A => 'Speech Audio Profile @ Level 2',
|
||||
0x0B => 'Synthetic Audio Profile @ Level 1',
|
||||
0x0C => 'Synthetic Audio Profile @ Level 2',
|
||||
0x0D => 'Synthetic Audio Profile @ Level 3',
|
||||
0x0E => 'High Quality Audio Profile @ Level 1',
|
||||
0x0F => 'High Quality Audio Profile @ Level 2',
|
||||
0x10 => 'High Quality Audio Profile @ Level 3',
|
||||
0x11 => 'High Quality Audio Profile @ Level 4',
|
||||
0x12 => 'High Quality Audio Profile @ Level 5',
|
||||
0x13 => 'High Quality Audio Profile @ Level 6',
|
||||
0x14 => 'High Quality Audio Profile @ Level 7',
|
||||
0x15 => 'High Quality Audio Profile @ Level 8',
|
||||
0x16 => 'Low Delay Audio Profile @ Level 1',
|
||||
0x17 => 'Low Delay Audio Profile @ Level 2',
|
||||
0x18 => 'Low Delay Audio Profile @ Level 3',
|
||||
0x19 => 'Low Delay Audio Profile @ Level 4',
|
||||
0x1A => 'Low Delay Audio Profile @ Level 5',
|
||||
0x1B => 'Low Delay Audio Profile @ Level 6',
|
||||
0x1C => 'Low Delay Audio Profile @ Level 7',
|
||||
0x1D => 'Low Delay Audio Profile @ Level 8',
|
||||
0x1E => 'Natural Audio Profile @ Level 1',
|
||||
0x1F => 'Natural Audio Profile @ Level 2',
|
||||
0x20 => 'Natural Audio Profile @ Level 3',
|
||||
0x21 => 'Natural Audio Profile @ Level 4',
|
||||
0x22 => 'Mobile Audio Internetworking Profile @ Level 1',
|
||||
0x23 => 'Mobile Audio Internetworking Profile @ Level 2',
|
||||
0x24 => 'Mobile Audio Internetworking Profile @ Level 3',
|
||||
0x25 => 'Mobile Audio Internetworking Profile @ Level 4',
|
||||
0x26 => 'Mobile Audio Internetworking Profile @ Level 5',
|
||||
0x27 => 'Mobile Audio Internetworking Profile @ Level 6',
|
||||
0x28 => 'AAC Profile @ Level 1',
|
||||
0x29 => 'AAC Profile @ Level 2',
|
||||
0x2A => 'AAC Profile @ Level 4',
|
||||
0x2B => 'AAC Profile @ Level 5',
|
||||
0x2C => 'High Efficiency AAC Profile @ Level 2',
|
||||
0x2D => 'High Efficiency AAC Profile @ Level 3',
|
||||
0x2E => 'High Efficiency AAC Profile @ Level 4',
|
||||
0x2F => 'High Efficiency AAC Profile @ Level 5',
|
||||
0xFE => 'Not part of MPEG-4 audio profiles',
|
||||
0xFF => 'No audio capability required',
|
||||
);
|
||||
}
|
||||
return (isset($QuicktimeIODSaudioProfileNameLookup[$audio_profile_id]) ? $QuicktimeIODSaudioProfileNameLookup[$audio_profile_id] : 'ISO Reserved / User Private');
|
||||
|
@ -2111,8 +2250,18 @@ echo 'QuicktimeParseNikonNCTG()::unknown $data_size_type: '.$data_size_type.'<br
|
|||
public function CopyToAppropriateCommentsSection($keyname, $data, $boxname='') {
|
||||
static $handyatomtranslatorarray = array();
|
||||
if (empty($handyatomtranslatorarray)) {
|
||||
// http://www.geocities.com/xhelmboyx/quicktime/formats/qtm-layout.txt
|
||||
// http://www.geocities.com/xhelmboyx/quicktime/formats/mp4-layout.txt
|
||||
// http://atomicparsley.sourceforge.net/mpeg-4files.html
|
||||
// https://code.google.com/p/mp4v2/wiki/iTunesMetadata
|
||||
$handyatomtranslatorarray["\xA9".'alb'] = 'album'; // iTunes 4.0
|
||||
$handyatomtranslatorarray["\xA9".'ART'] = 'artist';
|
||||
$handyatomtranslatorarray["\xA9".'art'] = 'artist'; // iTunes 4.0
|
||||
$handyatomtranslatorarray["\xA9".'aut'] = 'author';
|
||||
$handyatomtranslatorarray["\xA9".'cmt'] = 'comment'; // iTunes 4.0
|
||||
$handyatomtranslatorarray["\xA9".'com'] = 'comment';
|
||||
$handyatomtranslatorarray["\xA9".'cpy'] = 'copyright';
|
||||
$handyatomtranslatorarray["\xA9".'day'] = 'creation_date'; // iTunes 4.0
|
||||
$handyatomtranslatorarray["\xA9".'day'] = 'creation_date'; // iTunes 4.0
|
||||
$handyatomtranslatorarray["\xA9".'dir'] = 'director';
|
||||
$handyatomtranslatorarray["\xA9".'ed1'] = 'edit1';
|
||||
$handyatomtranslatorarray["\xA9".'ed2'] = 'edit2';
|
||||
|
@ -2123,64 +2272,60 @@ echo 'QuicktimeParseNikonNCTG()::unknown $data_size_type: '.$data_size_type.'<br
|
|||
$handyatomtranslatorarray["\xA9".'ed7'] = 'edit7';
|
||||
$handyatomtranslatorarray["\xA9".'ed8'] = 'edit8';
|
||||
$handyatomtranslatorarray["\xA9".'ed9'] = 'edit9';
|
||||
$handyatomtranslatorarray["\xA9".'enc'] = 'encoded_by';
|
||||
$handyatomtranslatorarray["\xA9".'fmt'] = 'format';
|
||||
$handyatomtranslatorarray["\xA9".'gen'] = 'genre'; // iTunes 4.0
|
||||
$handyatomtranslatorarray["\xA9".'grp'] = 'grouping'; // iTunes 4.2
|
||||
$handyatomtranslatorarray["\xA9".'hst'] = 'host_computer';
|
||||
$handyatomtranslatorarray["\xA9".'inf'] = 'information';
|
||||
$handyatomtranslatorarray["\xA9".'lyr'] = 'lyrics'; // iTunes 5.0
|
||||
$handyatomtranslatorarray["\xA9".'mak'] = 'make';
|
||||
$handyatomtranslatorarray["\xA9".'mod'] = 'model';
|
||||
$handyatomtranslatorarray["\xA9".'nam'] = 'title'; // iTunes 4.0
|
||||
$handyatomtranslatorarray["\xA9".'ope'] = 'composer';
|
||||
$handyatomtranslatorarray["\xA9".'prd'] = 'producer';
|
||||
$handyatomtranslatorarray["\xA9".'PRD'] = 'product';
|
||||
$handyatomtranslatorarray["\xA9".'prf'] = 'performers';
|
||||
$handyatomtranslatorarray["\xA9".'req'] = 'system_requirements';
|
||||
$handyatomtranslatorarray["\xA9".'src'] = 'source_credit';
|
||||
$handyatomtranslatorarray["\xA9".'wrt'] = 'writer';
|
||||
|
||||
// http://www.geocities.com/xhelmboyx/quicktime/formats/qtm-layout.txt
|
||||
$handyatomtranslatorarray["\xA9".'nam'] = 'title'; // iTunes 4.0
|
||||
$handyatomtranslatorarray["\xA9".'cmt'] = 'comment'; // iTunes 4.0
|
||||
$handyatomtranslatorarray["\xA9".'wrn'] = 'warning';
|
||||
$handyatomtranslatorarray["\xA9".'hst'] = 'host_computer';
|
||||
$handyatomtranslatorarray["\xA9".'mak'] = 'make';
|
||||
$handyatomtranslatorarray["\xA9".'mod'] = 'model';
|
||||
$handyatomtranslatorarray["\xA9".'PRD'] = 'product';
|
||||
$handyatomtranslatorarray["\xA9".'swr'] = 'software';
|
||||
$handyatomtranslatorarray["\xA9".'aut'] = 'author';
|
||||
$handyatomtranslatorarray["\xA9".'ART'] = 'artist';
|
||||
$handyatomtranslatorarray["\xA9".'too'] = 'encoding_tool'; // iTunes 4.0
|
||||
$handyatomtranslatorarray["\xA9".'trk'] = 'track';
|
||||
$handyatomtranslatorarray["\xA9".'alb'] = 'album'; // iTunes 4.0
|
||||
$handyatomtranslatorarray["\xA9".'com'] = 'comment';
|
||||
$handyatomtranslatorarray["\xA9".'gen'] = 'genre'; // iTunes 4.0
|
||||
$handyatomtranslatorarray["\xA9".'ope'] = 'composer';
|
||||
$handyatomtranslatorarray["\xA9".'url'] = 'url';
|
||||
$handyatomtranslatorarray["\xA9".'enc'] = 'encoder';
|
||||
|
||||
// http://atomicparsley.sourceforge.net/mpeg-4files.html
|
||||
$handyatomtranslatorarray["\xA9".'art'] = 'artist'; // iTunes 4.0
|
||||
$handyatomtranslatorarray["\xA9".'wrn'] = 'warning';
|
||||
$handyatomtranslatorarray["\xA9".'wrt'] = 'composer';
|
||||
$handyatomtranslatorarray['aART'] = 'album_artist';
|
||||
$handyatomtranslatorarray['trkn'] = 'track_number'; // iTunes 4.0
|
||||
$handyatomtranslatorarray['disk'] = 'disc_number'; // iTunes 4.0
|
||||
$handyatomtranslatorarray['gnre'] = 'genre'; // iTunes 4.0
|
||||
$handyatomtranslatorarray["\xA9".'too'] = 'encoder'; // iTunes 4.0
|
||||
$handyatomtranslatorarray['tmpo'] = 'bpm'; // iTunes 4.0
|
||||
$handyatomtranslatorarray['cprt'] = 'copyright'; // iTunes 4.0?
|
||||
$handyatomtranslatorarray['cpil'] = 'compilation'; // iTunes 4.0
|
||||
$handyatomtranslatorarray['covr'] = 'picture'; // iTunes 4.0
|
||||
$handyatomtranslatorarray['rtng'] = 'rating'; // iTunes 4.0
|
||||
$handyatomtranslatorarray["\xA9".'grp'] = 'grouping'; // iTunes 4.2
|
||||
$handyatomtranslatorarray['stik'] = 'stik'; // iTunes 4.9
|
||||
$handyatomtranslatorarray['pcst'] = 'podcast'; // iTunes 4.9
|
||||
$handyatomtranslatorarray['catg'] = 'category'; // iTunes 4.9
|
||||
$handyatomtranslatorarray['keyw'] = 'keyword'; // iTunes 4.9
|
||||
$handyatomtranslatorarray['purl'] = 'podcast_url'; // iTunes 4.9
|
||||
$handyatomtranslatorarray['egid'] = 'episode_guid'; // iTunes 4.9
|
||||
$handyatomtranslatorarray['desc'] = 'description'; // iTunes 5.0
|
||||
$handyatomtranslatorarray["\xA9".'lyr'] = 'lyrics'; // iTunes 5.0
|
||||
$handyatomtranslatorarray['tvnn'] = 'tv_network_name'; // iTunes 6.0
|
||||
$handyatomtranslatorarray['tvsh'] = 'tv_show_name'; // iTunes 6.0
|
||||
$handyatomtranslatorarray['tvsn'] = 'tv_season'; // iTunes 6.0
|
||||
$handyatomtranslatorarray['tves'] = 'tv_episode'; // iTunes 6.0
|
||||
$handyatomtranslatorarray['purd'] = 'purchase_date'; // iTunes 6.0.2
|
||||
$handyatomtranslatorarray['pgap'] = 'gapless_playback'; // iTunes 7.0
|
||||
|
||||
// http://www.geocities.com/xhelmboyx/quicktime/formats/mp4-layout.txt
|
||||
|
||||
|
||||
$handyatomtranslatorarray['apID'] = 'purchase_account';
|
||||
$handyatomtranslatorarray['catg'] = 'category'; // iTunes 4.9
|
||||
$handyatomtranslatorarray['covr'] = 'picture'; // iTunes 4.0
|
||||
$handyatomtranslatorarray['cpil'] = 'compilation'; // iTunes 4.0
|
||||
$handyatomtranslatorarray['cprt'] = 'copyright'; // iTunes 4.0?
|
||||
$handyatomtranslatorarray['desc'] = 'description'; // iTunes 5.0
|
||||
$handyatomtranslatorarray['disk'] = 'disc_number'; // iTunes 4.0
|
||||
$handyatomtranslatorarray['egid'] = 'episode_guid'; // iTunes 4.9
|
||||
$handyatomtranslatorarray['gnre'] = 'genre'; // iTunes 4.0
|
||||
$handyatomtranslatorarray['hdvd'] = 'hd_video'; // iTunes 4.0
|
||||
$handyatomtranslatorarray['ldes'] = 'description_long'; //
|
||||
$handyatomtranslatorarray['keyw'] = 'keyword'; // iTunes 4.9
|
||||
$handyatomtranslatorarray['pcst'] = 'podcast'; // iTunes 4.9
|
||||
$handyatomtranslatorarray['pgap'] = 'gapless_playback'; // iTunes 7.0
|
||||
$handyatomtranslatorarray['purd'] = 'purchase_date'; // iTunes 6.0.2
|
||||
$handyatomtranslatorarray['purl'] = 'podcast_url'; // iTunes 4.9
|
||||
$handyatomtranslatorarray['rtng'] = 'rating'; // iTunes 4.0
|
||||
$handyatomtranslatorarray['soaa'] = 'sort_album_artist'; //
|
||||
$handyatomtranslatorarray['soal'] = 'sort_album'; //
|
||||
$handyatomtranslatorarray['soar'] = 'sort_artist'; //
|
||||
$handyatomtranslatorarray['soco'] = 'sort_composer'; //
|
||||
$handyatomtranslatorarray['sonm'] = 'sort_title'; //
|
||||
$handyatomtranslatorarray['sosn'] = 'sort_show'; //
|
||||
$handyatomtranslatorarray['stik'] = 'stik'; // iTunes 4.9
|
||||
$handyatomtranslatorarray['tmpo'] = 'bpm'; // iTunes 4.0
|
||||
$handyatomtranslatorarray['trkn'] = 'track_number'; // iTunes 4.0
|
||||
$handyatomtranslatorarray['tven'] = 'tv_episode_id'; //
|
||||
$handyatomtranslatorarray['tves'] = 'tv_episode'; // iTunes 6.0
|
||||
$handyatomtranslatorarray['tvnn'] = 'tv_network_name'; // iTunes 6.0
|
||||
$handyatomtranslatorarray['tvsh'] = 'tv_show_name'; // iTunes 6.0
|
||||
$handyatomtranslatorarray['tvsn'] = 'tv_season'; // iTunes 6.0
|
||||
|
||||
// boxnames:
|
||||
/*
|
||||
|
@ -2225,7 +2370,14 @@ echo 'QuicktimeParseNikonNCTG()::unknown $data_size_type: '.$data_size_type.'<br
|
|||
$data = array('data'=>$data, 'image_mime'=>$image_mime);
|
||||
}
|
||||
}
|
||||
$info['quicktime']['comments'][$comment_key][] = $data;
|
||||
$gooddata = array($data);
|
||||
if ($comment_key == 'genre') {
|
||||
// some other taggers separate multiple genres with semicolon, e.g. "Heavy Metal;Thrash Metal;Metal"
|
||||
$gooddata = explode(';', $data);
|
||||
}
|
||||
foreach ($gooddata as $data) {
|
||||
$info['quicktime']['comments'][$comment_key][] = $data;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
@ -2243,4 +2395,79 @@ echo 'QuicktimeParseNikonNCTG()::unknown $data_size_type: '.$data_size_type.'<br
|
|||
return substr($pascalstring, 1);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
// helper functions for m4b audiobook chapters
|
||||
// code by Steffen Hartmann 2015-Nov-08
|
||||
*/
|
||||
public function search_tag_by_key($info, $tag, $history, &$result) {
|
||||
foreach ($info as $key => $value) {
|
||||
$key_history = $history.'/'.$key;
|
||||
if ($key === $tag) {
|
||||
$result[] = array($key_history, $info);
|
||||
} else {
|
||||
if (is_array($value)) {
|
||||
$this->search_tag_by_key($value, $tag, $key_history, $result);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public function search_tag_by_pair($info, $k, $v, $history, &$result) {
|
||||
foreach ($info as $key => $value) {
|
||||
$key_history = $history.'/'.$key;
|
||||
if (($key === $k) && ($value === $v)) {
|
||||
$result[] = array($key_history, $info);
|
||||
} else {
|
||||
if (is_array($value)) {
|
||||
$this->search_tag_by_pair($value, $k, $v, $key_history, $result);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public function quicktime_time_to_sample_table($info) {
|
||||
$res = array();
|
||||
$this->search_tag_by_pair($info['quicktime']['moov'], 'name', 'stbl', 'quicktime/moov', $res);
|
||||
foreach ($res as $value) {
|
||||
$stbl_res = array();
|
||||
$this->search_tag_by_pair($value[1], 'data_format', 'text', $value[0], $stbl_res);
|
||||
if (count($stbl_res) > 0) {
|
||||
$stts_res = array();
|
||||
$this->search_tag_by_key($value[1], 'time_to_sample_table', $value[0], $stts_res);
|
||||
if (count($stts_res) > 0) {
|
||||
return $stts_res[0][1]['time_to_sample_table'];
|
||||
}
|
||||
}
|
||||
}
|
||||
return array();
|
||||
}
|
||||
|
||||
function quicktime_bookmark_time_scale($info) {
|
||||
$time_scale = '';
|
||||
$ts_prefix_len = 0;
|
||||
$res = array();
|
||||
$this->search_tag_by_pair($info['quicktime']['moov'], 'name', 'stbl', 'quicktime/moov', $res);
|
||||
foreach ($res as $value) {
|
||||
$stbl_res = array();
|
||||
$this->search_tag_by_pair($value[1], 'data_format', 'text', $value[0], $stbl_res);
|
||||
if (count($stbl_res) > 0) {
|
||||
$ts_res = array();
|
||||
$this->search_tag_by_key($info['quicktime']['moov'], 'time_scale', 'quicktime/moov', $ts_res);
|
||||
foreach ($ts_res as $value) {
|
||||
$prefix = substr($value[0], 0, -12);
|
||||
if ((substr($stbl_res[0][0], 0, strlen($prefix)) === $prefix) && ($ts_prefix_len < strlen($prefix))) {
|
||||
$time_scale = $value[1]['time_scale'];
|
||||
$ts_prefix_len = strlen($prefix);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return $time_scale;
|
||||
}
|
||||
/*
|
||||
// END helper functions for m4b audiobook chapters
|
||||
*/
|
||||
|
||||
|
||||
}
|
||||
|
|
0
app/Library/getid3/getid3/module.audio-video.real.php
Executable file → Normal file
0
app/Library/getid3/getid3/module.audio-video.real.php
Executable file → Normal file
0
app/Library/getid3/getid3/module.audio-video.riff.php
Executable file → Normal file
0
app/Library/getid3/getid3/module.audio-video.riff.php
Executable file → Normal file
0
app/Library/getid3/getid3/module.audio-video.swf.php
Executable file → Normal file
0
app/Library/getid3/getid3/module.audio-video.swf.php
Executable file → Normal file
0
app/Library/getid3/getid3/module.audio-video.ts.php
Executable file → Normal file
0
app/Library/getid3/getid3/module.audio-video.ts.php
Executable file → Normal file
0
app/Library/getid3/getid3/module.audio.aa.php
Executable file → Normal file
0
app/Library/getid3/getid3/module.audio.aa.php
Executable file → Normal file
0
app/Library/getid3/getid3/module.audio.aac.php
Executable file → Normal file
0
app/Library/getid3/getid3/module.audio.aac.php
Executable file → Normal file
0
app/Library/getid3/getid3/module.audio.ac3.php
Executable file → Normal file
0
app/Library/getid3/getid3/module.audio.ac3.php
Executable file → Normal file
0
app/Library/getid3/getid3/module.audio.amr.php
Executable file → Normal file
0
app/Library/getid3/getid3/module.audio.amr.php
Executable file → Normal file
0
app/Library/getid3/getid3/module.audio.au.php
Executable file → Normal file
0
app/Library/getid3/getid3/module.audio.au.php
Executable file → Normal file
0
app/Library/getid3/getid3/module.audio.avr.php
Executable file → Normal file
0
app/Library/getid3/getid3/module.audio.avr.php
Executable file → Normal file
0
app/Library/getid3/getid3/module.audio.bonk.php
Executable file → Normal file
0
app/Library/getid3/getid3/module.audio.bonk.php
Executable file → Normal file
0
app/Library/getid3/getid3/module.audio.dss.php
Executable file → Normal file
0
app/Library/getid3/getid3/module.audio.dss.php
Executable file → Normal file
0
app/Library/getid3/getid3/module.audio.dts.php
Executable file → Normal file
0
app/Library/getid3/getid3/module.audio.dts.php
Executable file → Normal file
0
app/Library/getid3/getid3/module.audio.flac.php
Executable file → Normal file
0
app/Library/getid3/getid3/module.audio.flac.php
Executable file → Normal file
0
app/Library/getid3/getid3/module.audio.la.php
Executable file → Normal file
0
app/Library/getid3/getid3/module.audio.la.php
Executable file → Normal file
0
app/Library/getid3/getid3/module.audio.lpac.php
Executable file → Normal file
0
app/Library/getid3/getid3/module.audio.lpac.php
Executable file → Normal file
0
app/Library/getid3/getid3/module.audio.midi.php
Executable file → Normal file
0
app/Library/getid3/getid3/module.audio.midi.php
Executable file → Normal file
0
app/Library/getid3/getid3/module.audio.mod.php
Executable file → Normal file
0
app/Library/getid3/getid3/module.audio.mod.php
Executable file → Normal file
0
app/Library/getid3/getid3/module.audio.monkey.php
Executable file → Normal file
0
app/Library/getid3/getid3/module.audio.monkey.php
Executable file → Normal file
18
app/Library/getid3/getid3/module.audio.mp3.php
Executable file → Normal file
18
app/Library/getid3/getid3/module.audio.mp3.php
Executable file → Normal file
|
@ -437,7 +437,6 @@ class getid3_mp3 extends getid3_handler
|
|||
// and $cc... is the audio data
|
||||
|
||||
$head4 = substr($headerstring, 0, 4);
|
||||
|
||||
static $MPEGaudioHeaderDecodeCache = array();
|
||||
if (isset($MPEGaudioHeaderDecodeCache[$head4])) {
|
||||
$MPEGheaderRawArray = $MPEGaudioHeaderDecodeCache[$head4];
|
||||
|
@ -648,9 +647,20 @@ class getid3_mp3 extends getid3_handler
|
|||
}
|
||||
|
||||
//if (($thisfile_mpeg_audio['bitrate'] == 'free') && !empty($thisfile_mpeg_audio['VBR_frames']) && !empty($thisfile_mpeg_audio['VBR_bytes'])) {
|
||||
if (!empty($thisfile_mpeg_audio['VBR_frames']) && !empty($thisfile_mpeg_audio['VBR_bytes'])) {
|
||||
//if (!empty($thisfile_mpeg_audio['VBR_frames']) && !empty($thisfile_mpeg_audio['VBR_bytes'])) {
|
||||
if (!empty($thisfile_mpeg_audio['VBR_frames'])) {
|
||||
$used_filesize = 0;
|
||||
if (!empty($thisfile_mpeg_audio['VBR_bytes'])) {
|
||||
$used_filesize = $thisfile_mpeg_audio['VBR_bytes'];
|
||||
} elseif (!empty($info['filesize'])) {
|
||||
$used_filesize = $info['filesize'];
|
||||
$used_filesize -= intval(@$info['id3v2']['headerlength']);
|
||||
$used_filesize -= (isset($info['id3v1']) ? 128 : 0);
|
||||
$used_filesize -= (isset($info['tag_offset_end']) ? $info['tag_offset_end'] - $info['tag_offset_start'] : 0);
|
||||
$info['warning'][] = 'MP3.Xing header missing VBR_bytes, assuming MPEG audio portion of file is '.number_format($used_filesize).' bytes';
|
||||
}
|
||||
|
||||
$framelengthfloat = $thisfile_mpeg_audio['VBR_bytes'] / $thisfile_mpeg_audio['VBR_frames'];
|
||||
$framelengthfloat = $used_filesize / $thisfile_mpeg_audio['VBR_frames'];
|
||||
|
||||
if ($thisfile_mpeg_audio['layer'] == '1') {
|
||||
// BitRate = (((FrameLengthInBytes / 4) - Padding) * SampleRate) / 12
|
||||
|
@ -948,7 +958,7 @@ class getid3_mp3 extends getid3_handler
|
|||
}
|
||||
$thisfile_mpeg_audio['VBR_bitrate'] = (isset($thisfile_mpeg_audio['VBR_bytes']) ? (($thisfile_mpeg_audio['VBR_bytes'] / $thisfile_mpeg_audio['VBR_frames']) * 8) * ($info['audio']['sample_rate'] / $bytes_per_frame) : 0);
|
||||
if ($thisfile_mpeg_audio['VBR_bitrate'] > 0) {
|
||||
$info['audio']['bitrate'] = $thisfile_mpeg_audio['VBR_bitrate'];
|
||||
$info['audio']['bitrate'] = $thisfile_mpeg_audio['VBR_bitrate'];
|
||||
$thisfile_mpeg_audio['bitrate'] = $thisfile_mpeg_audio['VBR_bitrate']; // to avoid confusion
|
||||
}
|
||||
break;
|
||||
|
|
0
app/Library/getid3/getid3/module.audio.mpc.php
Executable file → Normal file
0
app/Library/getid3/getid3/module.audio.mpc.php
Executable file → Normal file
1
app/Library/getid3/getid3/module.audio.ogg.php
Executable file → Normal file
1
app/Library/getid3/getid3/module.audio.ogg.php
Executable file → Normal file
|
@ -562,6 +562,7 @@ $info['warning'][] = 'Ogg Theora (v3) not fully supported in this version of get
|
|||
|
||||
default:
|
||||
return false;
|
||||
break;
|
||||
}
|
||||
|
||||
$VendorSize = getid3_lib::LittleEndian2Int(substr($commentdata, $commentdataoffset, 4));
|
||||
|
|
0
app/Library/getid3/getid3/module.audio.optimfrog.php
Executable file → Normal file
0
app/Library/getid3/getid3/module.audio.optimfrog.php
Executable file → Normal file
0
app/Library/getid3/getid3/module.audio.rkau.php
Executable file → Normal file
0
app/Library/getid3/getid3/module.audio.rkau.php
Executable file → Normal file
0
app/Library/getid3/getid3/module.audio.shorten.php
Executable file → Normal file
0
app/Library/getid3/getid3/module.audio.shorten.php
Executable file → Normal file
0
app/Library/getid3/getid3/module.audio.tta.php
Executable file → Normal file
0
app/Library/getid3/getid3/module.audio.tta.php
Executable file → Normal file
0
app/Library/getid3/getid3/module.audio.voc.php
Executable file → Normal file
0
app/Library/getid3/getid3/module.audio.voc.php
Executable file → Normal file
0
app/Library/getid3/getid3/module.audio.vqf.php
Executable file → Normal file
0
app/Library/getid3/getid3/module.audio.vqf.php
Executable file → Normal file
0
app/Library/getid3/getid3/module.audio.wavpack.php
Executable file → Normal file
0
app/Library/getid3/getid3/module.audio.wavpack.php
Executable file → Normal file
0
app/Library/getid3/getid3/module.graphic.bmp.php
Executable file → Normal file
0
app/Library/getid3/getid3/module.graphic.bmp.php
Executable file → Normal file
0
app/Library/getid3/getid3/module.graphic.efax.php
Executable file → Normal file
0
app/Library/getid3/getid3/module.graphic.efax.php
Executable file → Normal file
0
app/Library/getid3/getid3/module.graphic.gif.php
Executable file → Normal file
0
app/Library/getid3/getid3/module.graphic.gif.php
Executable file → Normal file
0
app/Library/getid3/getid3/module.graphic.jpg.php
Executable file → Normal file
0
app/Library/getid3/getid3/module.graphic.jpg.php
Executable file → Normal file
0
app/Library/getid3/getid3/module.graphic.pcd.php
Executable file → Normal file
0
app/Library/getid3/getid3/module.graphic.pcd.php
Executable file → Normal file
32
app/Library/getid3/getid3/module.graphic.png.php
Executable file → Normal file
32
app/Library/getid3/getid3/module.graphic.png.php
Executable file → Normal file
|
@ -17,8 +17,10 @@
|
|||
|
||||
class getid3_png extends getid3_handler
|
||||
{
|
||||
public $max_data_bytes = 10000000; // if data chunk is larger than this do not read it completely (getID3 only needs the first few dozen bytes for parsing)
|
||||
|
||||
public function Analyze() {
|
||||
|
||||
$info = &$this->getid3->info;
|
||||
|
||||
// shortcut
|
||||
|
@ -44,14 +46,24 @@ class getid3_png extends getid3_handler
|
|||
|
||||
while ((($this->ftell() - (strlen($PNGfiledata) - $offset)) < $info['filesize'])) {
|
||||
$chunk['data_length'] = getid3_lib::BigEndian2Int(substr($PNGfiledata, $offset, 4));
|
||||
$offset += 4;
|
||||
while (((strlen($PNGfiledata) - $offset) < ($chunk['data_length'] + 4)) && ($this->ftell() < $info['filesize'])) {
|
||||
$PNGfiledata .= $this->fread($this->getid3->fread_buffer_size());
|
||||
if ($chunk['data_length'] === false) {
|
||||
$info['error'][] = 'Failed to read data_length at offset '.$offset;
|
||||
return false;
|
||||
}
|
||||
$chunk['type_text'] = substr($PNGfiledata, $offset, 4);
|
||||
$offset += 4;
|
||||
$truncated_data = false;
|
||||
while (((strlen($PNGfiledata) - $offset) < ($chunk['data_length'] + 4)) && ($this->ftell() < $info['filesize'])) {
|
||||
if (strlen($PNGfiledata) < $this->max_data_bytes) {
|
||||
$PNGfiledata .= $this->fread($this->getid3->fread_buffer_size());
|
||||
} else {
|
||||
$info['warning'][] = 'At offset '.$offset.' chunk "'.substr($PNGfiledata, $offset, 4).'" exceeded max_data_bytes value of '.$this->max_data_bytes.', data chunk will be truncated at '.(strlen($PNGfiledata) - 8).' bytes';
|
||||
break;
|
||||
}
|
||||
}
|
||||
$chunk['type_text'] = substr($PNGfiledata, $offset, 4);
|
||||
$offset += 4;
|
||||
$chunk['type_raw'] = getid3_lib::BigEndian2Int($chunk['type_text']);
|
||||
$chunk['data'] = substr($PNGfiledata, $offset, $chunk['data_length']);
|
||||
$chunk['data'] = substr($PNGfiledata, $offset, $chunk['data_length']);
|
||||
$offset += $chunk['data_length'];
|
||||
$chunk['crc'] = getid3_lib::BigEndian2Int(substr($PNGfiledata, $offset, 4));
|
||||
$offset += 4;
|
||||
|
@ -162,7 +174,7 @@ class getid3_png extends getid3_handler
|
|||
|
||||
case 'iCCP': // Embedded ICC Profile
|
||||
$thisfile_png_chunk_type_text['header'] = $chunk;
|
||||
list($profilename, $compressiondata) = explode("\x00", $chunk['data'], 2);
|
||||
list($profilename, $compressiondata) = explode("\x00", $chunk['data'], 2);
|
||||
$thisfile_png_chunk_type_text['profile_name'] = $profilename;
|
||||
$thisfile_png_chunk_type_text['compression_method'] = getid3_lib::BigEndian2Int(substr($compressiondata, 0, 1));
|
||||
$thisfile_png_chunk_type_text['compression_profile'] = substr($compressiondata, 1);
|
||||
|
@ -173,7 +185,7 @@ class getid3_png extends getid3_handler
|
|||
|
||||
case 'tEXt': // Textual Data
|
||||
$thisfile_png_chunk_type_text['header'] = $chunk;
|
||||
list($keyword, $text) = explode("\x00", $chunk['data'], 2);
|
||||
list($keyword, $text) = explode("\x00", $chunk['data'], 2);
|
||||
$thisfile_png_chunk_type_text['keyword'] = $keyword;
|
||||
$thisfile_png_chunk_type_text['text'] = $text;
|
||||
|
||||
|
@ -183,7 +195,7 @@ class getid3_png extends getid3_handler
|
|||
|
||||
case 'zTXt': // Compressed Textual Data
|
||||
$thisfile_png_chunk_type_text['header'] = $chunk;
|
||||
list($keyword, $otherdata) = explode("\x00", $chunk['data'], 2);
|
||||
list($keyword, $otherdata) = explode("\x00", $chunk['data'], 2);
|
||||
$thisfile_png_chunk_type_text['keyword'] = $keyword;
|
||||
$thisfile_png_chunk_type_text['compression_method'] = getid3_lib::BigEndian2Int(substr($otherdata, 0, 1));
|
||||
$thisfile_png_chunk_type_text['compressed_text'] = substr($otherdata, 1);
|
||||
|
@ -206,7 +218,7 @@ class getid3_png extends getid3_handler
|
|||
|
||||
case 'iTXt': // International Textual Data
|
||||
$thisfile_png_chunk_type_text['header'] = $chunk;
|
||||
list($keyword, $otherdata) = explode("\x00", $chunk['data'], 2);
|
||||
list($keyword, $otherdata) = explode("\x00", $chunk['data'], 2);
|
||||
$thisfile_png_chunk_type_text['keyword'] = $keyword;
|
||||
$thisfile_png_chunk_type_text['compression'] = (bool) getid3_lib::BigEndian2Int(substr($otherdata, 0, 1));
|
||||
$thisfile_png_chunk_type_text['compression_method'] = getid3_lib::BigEndian2Int(substr($otherdata, 1, 1));
|
||||
|
@ -307,7 +319,7 @@ class getid3_png extends getid3_handler
|
|||
|
||||
case 'sPLT': // Suggested Palette
|
||||
$thisfile_png_chunk_type_text['header'] = $chunk;
|
||||
list($palettename, $otherdata) = explode("\x00", $chunk['data'], 2);
|
||||
list($palettename, $otherdata) = explode("\x00", $chunk['data'], 2);
|
||||
$thisfile_png_chunk_type_text['palette_name'] = $palettename;
|
||||
$sPLToffset = 0;
|
||||
$thisfile_png_chunk_type_text['sample_depth_bits'] = getid3_lib::BigEndian2Int(substr($otherdata, $sPLToffset, 1));
|
||||
|
|
0
app/Library/getid3/getid3/module.graphic.svg.php
Executable file → Normal file
0
app/Library/getid3/getid3/module.graphic.svg.php
Executable file → Normal file
0
app/Library/getid3/getid3/module.graphic.tiff.php
Executable file → Normal file
0
app/Library/getid3/getid3/module.graphic.tiff.php
Executable file → Normal file
0
app/Library/getid3/getid3/module.misc.cue.php
Executable file → Normal file
0
app/Library/getid3/getid3/module.misc.cue.php
Executable file → Normal file
0
app/Library/getid3/getid3/module.misc.exe.php
Executable file → Normal file
0
app/Library/getid3/getid3/module.misc.exe.php
Executable file → Normal file
0
app/Library/getid3/getid3/module.misc.iso.php
Executable file → Normal file
0
app/Library/getid3/getid3/module.misc.iso.php
Executable file → Normal file
0
app/Library/getid3/getid3/module.misc.msoffice.php
Executable file → Normal file
0
app/Library/getid3/getid3/module.misc.msoffice.php
Executable file → Normal file
0
app/Library/getid3/getid3/module.misc.par2.php
Executable file → Normal file
0
app/Library/getid3/getid3/module.misc.par2.php
Executable file → Normal file
0
app/Library/getid3/getid3/module.misc.pdf.php
Executable file → Normal file
0
app/Library/getid3/getid3/module.misc.pdf.php
Executable file → Normal file
14
app/Library/getid3/getid3/module.tag.apetag.php
Executable file → Normal file
14
app/Library/getid3/getid3/module.tag.apetag.php
Executable file → Normal file
|
@ -260,12 +260,16 @@ class getid3_apetag extends getid3_handler
|
|||
$thisfile_ape_items_current['data_offset'] = $thisfile_ape_items_current['offset'] + strlen($thisfile_ape_items_current['filename']."\x00");
|
||||
$thisfile_ape_items_current['data_length'] = strlen($thisfile_ape_items_current['data']);
|
||||
|
||||
$thisfile_ape_items_current['image_mime'] = '';
|
||||
$imageinfo = array();
|
||||
$imagechunkcheck = getid3_lib::GetDataImageSize($thisfile_ape_items_current['data'], $imageinfo);
|
||||
$thisfile_ape_items_current['image_mime'] = image_type_to_mime_type($imagechunkcheck[2]);
|
||||
|
||||
do {
|
||||
$thisfile_ape_items_current['image_mime'] = '';
|
||||
$imageinfo = array();
|
||||
$imagechunkcheck = getid3_lib::GetDataImageSize($thisfile_ape_items_current['data'], $imageinfo);
|
||||
if (($imagechunkcheck === false) || !isset($imagechunkcheck[2])) {
|
||||
$info['warning'][] = 'APEtag "'.$item_key.'" contains invalid image data';
|
||||
break;
|
||||
}
|
||||
$thisfile_ape_items_current['image_mime'] = image_type_to_mime_type($imagechunkcheck[2]);
|
||||
|
||||
if ($this->inline_attachments === false) {
|
||||
// skip entirely
|
||||
unset($thisfile_ape_items_current['data']);
|
||||
|
|
0
app/Library/getid3/getid3/module.tag.id3v1.php
Executable file → Normal file
0
app/Library/getid3/getid3/module.tag.id3v1.php
Executable file → Normal file
63
app/Library/getid3/getid3/module.tag.id3v2.php
Executable file → Normal file
63
app/Library/getid3/getid3/module.tag.id3v2.php
Executable file → Normal file
|
@ -442,10 +442,14 @@ class getid3_id3v2 extends getid3_handler
|
|||
} // end footer
|
||||
|
||||
if (isset($thisfile_id3v2['comments']['genre'])) {
|
||||
$genres = array();
|
||||
foreach ($thisfile_id3v2['comments']['genre'] as $key => $value) {
|
||||
unset($thisfile_id3v2['comments']['genre'][$key]);
|
||||
$thisfile_id3v2['comments'] = getid3_lib::array_merge_noclobber($thisfile_id3v2['comments'], array('genre'=>$this->ParseID3v2GenreString($value)));
|
||||
foreach ($this->ParseID3v2GenreString($value) as $genre) {
|
||||
$genres[] = $genre;
|
||||
}
|
||||
}
|
||||
$thisfile_id3v2['comments']['genre'] = array_unique($genres);
|
||||
unset($key, $value, $genres, $genre);
|
||||
}
|
||||
|
||||
if (isset($thisfile_id3v2['comments']['track'])) {
|
||||
|
@ -503,6 +507,16 @@ class getid3_id3v2 extends getid3_handler
|
|||
if (strpos($genrestring, "\x00") === false) {
|
||||
$genrestring = preg_replace('#\(([0-9]{1,3})\)#', '$1'."\x00", $genrestring);
|
||||
}
|
||||
|
||||
// note: MusicBrainz Picard incorrectly stores plaintext genres separated by "/" when writing in ID3v2.3 mode, hack-fix here:
|
||||
// replace / with NULL, then replace back the two ID3v1 genres that legitimately have "/" as part of the single genre name
|
||||
$genrestring = str_replace('/', "\x00", $genrestring);
|
||||
$genrestring = str_replace('Pop'."\x00".'Funk', 'Pop/Funk', $genrestring);
|
||||
$genrestring = str_replace('Rock'."\x00".'Rock', 'Folk/Rock', $genrestring);
|
||||
|
||||
// some other taggers separate multiple genres with semicolon, e.g. "Heavy Metal;Thrash Metal;Metal"
|
||||
$genrestring = str_replace(';', "\x00", $genrestring);
|
||||
|
||||
$genre_elements = explode("\x00", $genrestring);
|
||||
foreach ($genre_elements as $element) {
|
||||
$element = trim($element);
|
||||
|
@ -635,7 +649,8 @@ class getid3_id3v2 extends getid3_handler
|
|||
$frame_terminatorpos++; // strpos() fooled because 2nd byte of Unicode chars are often 0x00
|
||||
}
|
||||
$frame_description = substr($parsedFrame['data'], $frame_offset, $frame_terminatorpos - $frame_offset);
|
||||
if (ord($frame_description) === 0) {
|
||||
if (in_array($frame_description, array("\x00", "\x00\x00", "\xFF\xFE", "\xFE\xFF"))) {
|
||||
// if description only contains a BOM or terminator then make it blank
|
||||
$frame_description = '';
|
||||
}
|
||||
$parsedFrame['encodingid'] = $frame_textencoding;
|
||||
|
@ -728,8 +743,8 @@ class getid3_id3v2 extends getid3_handler
|
|||
$frame_terminatorpos++; // strpos() fooled because 2nd byte of Unicode chars are often 0x00
|
||||
}
|
||||
$frame_description = substr($parsedFrame['data'], $frame_offset, $frame_terminatorpos - $frame_offset);
|
||||
|
||||
if (ord($frame_description) === 0) {
|
||||
if (in_array($frame_description, array("\x00", "\x00\x00", "\xFF\xFE", "\xFE\xFF"))) {
|
||||
// if description only contains a BOM or terminator then make it blank
|
||||
$frame_description = '';
|
||||
}
|
||||
$parsedFrame['data'] = substr($parsedFrame['data'], $frame_terminatorpos + strlen($frame_textencoding_terminator));
|
||||
|
@ -971,7 +986,8 @@ class getid3_id3v2 extends getid3_handler
|
|||
$frame_terminatorpos++; // strpos() fooled because 2nd byte of Unicode chars are often 0x00
|
||||
}
|
||||
$frame_description = substr($parsedFrame['data'], $frame_offset, $frame_terminatorpos - $frame_offset);
|
||||
if (ord($frame_description) === 0) {
|
||||
if (in_array($frame_description, array("\x00", "\x00\x00", "\xFF\xFE", "\xFE\xFF"))) {
|
||||
// if description only contains a BOM or terminator then make it blank
|
||||
$frame_description = '';
|
||||
}
|
||||
$parsedFrame['data'] = substr($parsedFrame['data'], $frame_terminatorpos + strlen($frame_textencoding_terminator));
|
||||
|
@ -979,7 +995,6 @@ class getid3_id3v2 extends getid3_handler
|
|||
$parsedFrame['encodingid'] = $frame_textencoding;
|
||||
$parsedFrame['encoding'] = $this->TextEncodingNameLookup($frame_textencoding);
|
||||
|
||||
$parsedFrame['data'] = $parsedFrame['data'];
|
||||
$parsedFrame['language'] = $frame_language;
|
||||
$parsedFrame['languagename'] = $this->LanguageLookup($frame_language, false);
|
||||
$parsedFrame['description'] = $frame_description;
|
||||
|
@ -1079,7 +1094,8 @@ class getid3_id3v2 extends getid3_handler
|
|||
$frame_terminatorpos++; // strpos() fooled because 2nd byte of Unicode chars are often 0x00
|
||||
}
|
||||
$frame_description = substr($parsedFrame['data'], $frame_offset, $frame_terminatorpos - $frame_offset);
|
||||
if (ord($frame_description) === 0) {
|
||||
if (in_array($frame_description, array("\x00", "\x00\x00", "\xFF\xFE", "\xFE\xFF"))) {
|
||||
// if description only contains a BOM or terminator then make it blank
|
||||
$frame_description = '';
|
||||
}
|
||||
$frame_text = (string) substr($parsedFrame['data'], $frame_terminatorpos + strlen($frame_textencoding_terminator));
|
||||
|
@ -1383,7 +1399,8 @@ class getid3_id3v2 extends getid3_handler
|
|||
$frame_terminatorpos++; // strpos() fooled because 2nd byte of Unicode chars are often 0x00
|
||||
}
|
||||
$frame_description = substr($parsedFrame['data'], $frame_offset, $frame_terminatorpos - $frame_offset);
|
||||
if (ord($frame_description) === 0) {
|
||||
if (in_array($frame_description, array("\x00", "\x00\x00", "\xFF\xFE", "\xFE\xFF"))) {
|
||||
// if description only contains a BOM or terminator then make it blank
|
||||
$frame_description = '';
|
||||
}
|
||||
$parsedFrame['encodingid'] = $frame_textencoding;
|
||||
|
@ -1402,14 +1419,15 @@ class getid3_id3v2 extends getid3_handler
|
|||
|
||||
$parsedFrame['image_mime'] = '';
|
||||
$imageinfo = array();
|
||||
$imagechunkcheck = getid3_lib::GetDataImageSize($parsedFrame['data'], $imageinfo);
|
||||
if (($imagechunkcheck[2] >= 1) && ($imagechunkcheck[2] <= 3)) {
|
||||
$parsedFrame['image_mime'] = 'image/'.getid3_lib::ImageTypesLookup($imagechunkcheck[2]);
|
||||
if ($imagechunkcheck[0]) {
|
||||
$parsedFrame['image_width'] = $imagechunkcheck[0];
|
||||
}
|
||||
if ($imagechunkcheck[1]) {
|
||||
$parsedFrame['image_height'] = $imagechunkcheck[1];
|
||||
if ($imagechunkcheck = getid3_lib::GetDataImageSize($parsedFrame['data'], $imageinfo)) {
|
||||
if (($imagechunkcheck[2] >= 1) && ($imagechunkcheck[2] <= 3)) {
|
||||
$parsedFrame['image_mime'] = 'image/'.getid3_lib::ImageTypesLookup($imagechunkcheck[2]);
|
||||
if ($imagechunkcheck[0]) {
|
||||
$parsedFrame['image_width'] = $imagechunkcheck[0];
|
||||
}
|
||||
if ($imagechunkcheck[1]) {
|
||||
$parsedFrame['image_height'] = $imagechunkcheck[1];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1507,7 +1525,8 @@ class getid3_id3v2 extends getid3_handler
|
|||
$frame_terminatorpos++; // strpos() fooled because 2nd byte of Unicode chars are often 0x00
|
||||
}
|
||||
$frame_description = substr($parsedFrame['data'], $frame_offset, $frame_terminatorpos - $frame_offset);
|
||||
if (ord($frame_description) === 0) {
|
||||
if (in_array($frame_description, array("\x00", "\x00\x00", "\xFF\xFE", "\xFE\xFF"))) {
|
||||
// if description only contains a BOM or terminator then make it blank
|
||||
$frame_description = '';
|
||||
}
|
||||
$frame_offset = $frame_terminatorpos + strlen($frame_textencoding_terminator);
|
||||
|
@ -1589,7 +1608,8 @@ class getid3_id3v2 extends getid3_handler
|
|||
|
||||
$frame_terminatorpos = strpos($parsedFrame['data'], "\x00", $frame_offset);
|
||||
$frame_description = substr($parsedFrame['data'], $frame_offset, $frame_terminatorpos - $frame_offset);
|
||||
if (ord($frame_description) === 0) {
|
||||
if (in_array($frame_description, array("\x00", "\x00\x00", "\xFF\xFE", "\xFE\xFF"))) {
|
||||
// if description only contains a BOM or terminator then make it blank
|
||||
$frame_description = '';
|
||||
}
|
||||
$frame_offset = $frame_terminatorpos + strlen("\x00");
|
||||
|
@ -1614,7 +1634,7 @@ class getid3_id3v2 extends getid3_handler
|
|||
$frame_terminatorpos = strpos($parsedFrame['data'], "\x00", $frame_offset);
|
||||
$frame_ownerid = substr($parsedFrame['data'], $frame_offset, $frame_terminatorpos - $frame_offset);
|
||||
if (ord($frame_ownerid) === 0) {
|
||||
$frame_ownerid == '';
|
||||
$frame_ownerid = '';
|
||||
}
|
||||
$frame_offset = $frame_terminatorpos + strlen("\x00");
|
||||
$parsedFrame['ownerid'] = $frame_ownerid;
|
||||
|
@ -1789,7 +1809,8 @@ class getid3_id3v2 extends getid3_handler
|
|||
$frame_terminatorpos++; // strpos() fooled because 2nd byte of Unicode chars are often 0x00
|
||||
}
|
||||
$frame_description = substr($parsedFrame['data'], $frame_offset, $frame_terminatorpos - $frame_offset);
|
||||
if (ord($frame_description) === 0) {
|
||||
if (in_array($frame_description, array("\x00", "\x00\x00", "\xFF\xFE", "\xFE\xFF"))) {
|
||||
// if description only contains a BOM or terminator then make it blank
|
||||
$frame_description = '';
|
||||
}
|
||||
$frame_offset = $frame_terminatorpos + strlen($frame_textencoding_terminator);
|
||||
|
|
0
app/Library/getid3/getid3/module.tag.lyrics3.php
Executable file → Normal file
0
app/Library/getid3/getid3/module.tag.lyrics3.php
Executable file → Normal file
0
app/Library/getid3/getid3/module.tag.xmp.php
Executable file → Normal file
0
app/Library/getid3/getid3/module.tag.xmp.php
Executable file → Normal file
0
app/Library/getid3/getid3/write.apetag.php
Executable file → Normal file
0
app/Library/getid3/getid3/write.apetag.php
Executable file → Normal file
0
app/Library/getid3/getid3/write.id3v1.php
Executable file → Normal file
0
app/Library/getid3/getid3/write.id3v1.php
Executable file → Normal file
13
app/Library/getid3/getid3/write.id3v2.php
Executable file → Normal file
13
app/Library/getid3/getid3/write.id3v2.php
Executable file → Normal file
|
@ -1759,10 +1759,15 @@ class getid3_write_id3v2
|
|||
}
|
||||
|
||||
public function ID3v2IsValidTextEncoding($textencodingbyte) {
|
||||
// 0 = ISO-8859-1
|
||||
// 1 = UTF-16 with BOM
|
||||
// 2 = UTF-16BE without BOM
|
||||
// 3 = UTF-8
|
||||
static $ID3v2IsValidTextEncoding_cache = array(
|
||||
2 => array(true, true),
|
||||
3 => array(true, true),
|
||||
4 => array(true, true, true, true));
|
||||
2 => array(true, true), // ID3v2.2 - allow 0=ISO-8859-1, 1=UTF-16
|
||||
3 => array(true, true), // ID3v2.3 - allow 0=ISO-8859-1, 1=UTF-16
|
||||
4 => array(true, true, true, true), // ID3v2.4 - allow 0=ISO-8859-1, 1=UTF-16, 2=UTF-16BE, 3=UTF-8
|
||||
);
|
||||
return isset($ID3v2IsValidTextEncoding_cache[$this->majorversion][$textencodingbyte]);
|
||||
}
|
||||
|
||||
|
@ -1906,6 +1911,7 @@ class getid3_write_id3v2
|
|||
$ID3v2ShortFrameNameLookup[2]['comment'] = 'COM';
|
||||
$ID3v2ShortFrameNameLookup[2]['album'] = 'TAL';
|
||||
$ID3v2ShortFrameNameLookup[2]['beats_per_minute'] = 'TBP';
|
||||
$ID3v2ShortFrameNameLookup[2]['bpm'] = 'TBP';
|
||||
$ID3v2ShortFrameNameLookup[2]['composer'] = 'TCM';
|
||||
$ID3v2ShortFrameNameLookup[2]['genre'] = 'TCO';
|
||||
$ID3v2ShortFrameNameLookup[2]['itunescompilation'] = 'TCP';
|
||||
|
@ -1966,6 +1972,7 @@ class getid3_write_id3v2
|
|||
$ID3v2ShortFrameNameLookup[3]['synchronised_tempo_codes'] = 'SYTC';
|
||||
$ID3v2ShortFrameNameLookup[3]['album'] = 'TALB';
|
||||
$ID3v2ShortFrameNameLookup[3]['beats_per_minute'] = 'TBPM';
|
||||
$ID3v2ShortFrameNameLookup[3]['bpm'] = 'TBPM';
|
||||
$ID3v2ShortFrameNameLookup[3]['itunescompilation'] = 'TCMP';
|
||||
$ID3v2ShortFrameNameLookup[3]['composer'] = 'TCOM';
|
||||
$ID3v2ShortFrameNameLookup[3]['genre'] = 'TCON';
|
||||
|
|
0
app/Library/getid3/getid3/write.lyrics3.php
Executable file → Normal file
0
app/Library/getid3/getid3/write.lyrics3.php
Executable file → Normal file
0
app/Library/getid3/getid3/write.metaflac.php
Executable file → Normal file
0
app/Library/getid3/getid3/write.metaflac.php
Executable file → Normal file
2
app/Library/getid3/getid3/write.php
Executable file → Normal file
2
app/Library/getid3/getid3/write.php
Executable file → Normal file
|
@ -23,7 +23,7 @@
|
|||
if (!defined('GETID3_INCLUDEPATH')) {
|
||||
throw new Exception('getid3.php MUST be included before calling getid3_writetags');
|
||||
}
|
||||
if (!include_once(GETID3_INCLUDEPATH . 'getid3.lib.php')) {
|
||||
if (!include_once(GETID3_INCLUDEPATH.'getid3.lib.php')) {
|
||||
throw new Exception('write.php depends on getid3.lib.php, which is missing.');
|
||||
}
|
||||
|
||||
|
|
0
app/Library/getid3/getid3/write.real.php
Executable file → Normal file
0
app/Library/getid3/getid3/write.real.php
Executable file → Normal file
0
app/Library/getid3/getid3/write.vorbiscomment.php
Executable file → Normal file
0
app/Library/getid3/getid3/write.vorbiscomment.php
Executable file → Normal file
0
app/Library/getid3/helperapps/head.exe
Executable file → Normal file
0
app/Library/getid3/helperapps/head.exe
Executable file → Normal file
0
app/Library/getid3/helperapps/md5sum.exe
Executable file → Normal file
0
app/Library/getid3/helperapps/md5sum.exe
Executable file → Normal file
0
app/Library/getid3/helperapps/metaflac.exe
Executable file → Normal file
0
app/Library/getid3/helperapps/metaflac.exe
Executable file → Normal file
0
app/Library/getid3/helperapps/readme.helperapps.txt
Executable file → Normal file
0
app/Library/getid3/helperapps/readme.helperapps.txt
Executable file → Normal file
0
app/Library/getid3/helperapps/shorten.exe
Executable file → Normal file
0
app/Library/getid3/helperapps/shorten.exe
Executable file → Normal file
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue