changeset 16 | a86126ab1dd4 |
parent 7 | cf61fcea0001 |
child 19 | 3d72ae0968f4 |
15:3d4e9c994f10 | 16:a86126ab1dd4 |
---|---|
1 <?php |
1 <?php |
2 ///////////////////////////////////////////////////////////////// |
2 ///////////////////////////////////////////////////////////////// |
3 /// getID3() by James Heinrich <info@getid3.org> // |
3 /// getID3() by James Heinrich <info@getid3.org> // |
4 // available at http://getid3.sourceforge.net // |
4 // available at https://github.com/JamesHeinrich/getID3 // |
5 // or http://www.getid3.org // |
5 // or https://www.getid3.org // |
6 // also https://github.com/JamesHeinrich/getID3 // |
6 // or http://getid3.sourceforge.net // |
7 ///////////////////////////////////////////////////////////////// |
|
8 // // |
7 // // |
9 // Please see readme.txt for more information // |
8 // Please see readme.txt for more information // |
10 // /// |
9 // /// |
11 ///////////////////////////////////////////////////////////////// |
10 ///////////////////////////////////////////////////////////////// |
12 |
11 |
23 define('IMG_JPG', IMAGETYPE_JPEG); |
22 define('IMG_JPG', IMAGETYPE_JPEG); |
24 } |
23 } |
25 if (!defined('ENT_SUBSTITUTE')) { // PHP5.3 adds ENT_IGNORE, PHP5.4 adds ENT_SUBSTITUTE |
24 if (!defined('ENT_SUBSTITUTE')) { // PHP5.3 adds ENT_IGNORE, PHP5.4 adds ENT_SUBSTITUTE |
26 define('ENT_SUBSTITUTE', (defined('ENT_IGNORE') ? ENT_IGNORE : 8)); |
25 define('ENT_SUBSTITUTE', (defined('ENT_IGNORE') ? ENT_IGNORE : 8)); |
27 } |
26 } |
27 |
|
28 /* |
|
29 https://www.getid3.org/phpBB3/viewtopic.php?t=2114 |
|
30 If you are running into a the problem where filenames with special characters are being handled |
|
31 incorrectly by external helper programs (e.g. metaflac), notably with the special characters removed, |
|
32 and you are passing in the filename in UTF8 (typically via a HTML form), try uncommenting this line: |
|
33 */ |
|
34 //setlocale(LC_CTYPE, 'en_US.UTF-8'); |
|
28 |
35 |
29 // attempt to define temp dir as something flexible but reliable |
36 // attempt to define temp dir as something flexible but reliable |
30 $temp_dir = ini_get('upload_tmp_dir'); |
37 $temp_dir = ini_get('upload_tmp_dir'); |
31 if ($temp_dir && (!is_dir($temp_dir) || !is_readable($temp_dir))) { |
38 if ($temp_dir && (!is_dir($temp_dir) || !is_readable($temp_dir))) { |
32 $temp_dir = ''; |
39 $temp_dir = ''; |
72 // End: Defines |
79 // End: Defines |
73 |
80 |
74 |
81 |
75 class getID3 |
82 class getID3 |
76 { |
83 { |
77 // public: Settings |
84 /* |
78 public $encoding = 'UTF-8'; // CASE SENSITIVE! - i.e. (must be supported by iconv()). Examples: ISO-8859-1 UTF-8 UTF-16 UTF-16BE |
85 * Settings |
79 public $encoding_id3v1 = 'ISO-8859-1'; // Should always be 'ISO-8859-1', but some tags may be written in other encodings such as 'EUC-CN' or 'CP1252' |
86 */ |
80 |
87 |
81 // public: Optional tag checks - disable for speed. |
88 /** |
82 public $option_tag_id3v1 = true; // Read and process ID3v1 tags |
89 * CASE SENSITIVE! - i.e. (must be supported by iconv()). Examples: ISO-8859-1 UTF-8 UTF-16 UTF-16BE |
83 public $option_tag_id3v2 = true; // Read and process ID3v2 tags |
90 * |
84 public $option_tag_lyrics3 = true; // Read and process Lyrics3 tags |
91 * @var string |
85 public $option_tag_apetag = true; // Read and process APE tags |
92 */ |
86 public $option_tags_process = true; // Copy tags to root key 'tags' and encode to $this->encoding |
93 public $encoding = 'UTF-8'; |
87 public $option_tags_html = true; // Copy tags to root key 'tags_html' properly translated from various encodings to HTML entities |
94 |
88 |
95 /** |
89 // public: Optional tag/comment calucations |
96 * Should always be 'ISO-8859-1', but some tags may be written in other encodings such as 'EUC-CN' or 'CP1252' |
90 public $option_extra_info = true; // Calculate additional info such as bitrate, channelmode etc |
97 * |
91 |
98 * @var string |
92 // public: Optional handling of embedded attachments (e.g. images) |
99 */ |
93 public $option_save_attachments = true; // defaults to true (ATTACHMENTS_INLINE) for backward compatibility |
100 public $encoding_id3v1 = 'ISO-8859-1'; |
94 |
101 |
95 // public: Optional calculations |
102 /** |
96 public $option_md5_data = false; // Get MD5 sum of data part - slow |
103 * ID3v1 should always be 'ISO-8859-1', but some tags may be written in other encodings such as 'Windows-1251' or 'KOI8-R'. If true attempt to detect these encodings, but may return incorrect values for some tags actually in ISO-8859-1 encoding |
97 public $option_md5_data_source = false; // Use MD5 of source file if availble - only FLAC and OptimFROG |
104 * |
98 public $option_sha1_data = false; // Get SHA1 sum of data part - slow |
105 * @var bool |
99 public $option_max_2gb_check = null; // Check whether file is larger than 2GB and thus not supported by 32-bit PHP (null: auto-detect based on PHP_INT_MAX) |
106 */ |
100 |
107 public $encoding_id3v1_autodetect = false; |
101 // public: Read buffer size in bytes |
108 |
109 /* |
|
110 * Optional tag checks - disable for speed. |
|
111 */ |
|
112 |
|
113 /** |
|
114 * Read and process ID3v1 tags |
|
115 * |
|
116 * @var bool |
|
117 */ |
|
118 public $option_tag_id3v1 = true; |
|
119 |
|
120 /** |
|
121 * Read and process ID3v2 tags |
|
122 * |
|
123 * @var bool |
|
124 */ |
|
125 public $option_tag_id3v2 = true; |
|
126 |
|
127 /** |
|
128 * Read and process Lyrics3 tags |
|
129 * |
|
130 * @var bool |
|
131 */ |
|
132 public $option_tag_lyrics3 = true; |
|
133 |
|
134 /** |
|
135 * Read and process APE tags |
|
136 * |
|
137 * @var bool |
|
138 */ |
|
139 public $option_tag_apetag = true; |
|
140 |
|
141 /** |
|
142 * Copy tags to root key 'tags' and encode to $this->encoding |
|
143 * |
|
144 * @var bool |
|
145 */ |
|
146 public $option_tags_process = true; |
|
147 |
|
148 /** |
|
149 * Copy tags to root key 'tags_html' properly translated from various encodings to HTML entities |
|
150 * |
|
151 * @var bool |
|
152 */ |
|
153 public $option_tags_html = true; |
|
154 |
|
155 /* |
|
156 * Optional tag/comment calculations |
|
157 */ |
|
158 |
|
159 /** |
|
160 * Calculate additional info such as bitrate, channelmode etc |
|
161 * |
|
162 * @var bool |
|
163 */ |
|
164 public $option_extra_info = true; |
|
165 |
|
166 /* |
|
167 * Optional handling of embedded attachments (e.g. images) |
|
168 */ |
|
169 |
|
170 /** |
|
171 * Defaults to true (ATTACHMENTS_INLINE) for backward compatibility |
|
172 * |
|
173 * @var bool|string |
|
174 */ |
|
175 public $option_save_attachments = true; |
|
176 |
|
177 /* |
|
178 * Optional calculations |
|
179 */ |
|
180 |
|
181 /** |
|
182 * Get MD5 sum of data part - slow |
|
183 * |
|
184 * @var bool |
|
185 */ |
|
186 public $option_md5_data = false; |
|
187 |
|
188 /** |
|
189 * Use MD5 of source file if availble - only FLAC and OptimFROG |
|
190 * |
|
191 * @var bool |
|
192 */ |
|
193 public $option_md5_data_source = false; |
|
194 |
|
195 /** |
|
196 * Get SHA1 sum of data part - slow |
|
197 * |
|
198 * @var bool |
|
199 */ |
|
200 public $option_sha1_data = false; |
|
201 |
|
202 /** |
|
203 * Check whether file is larger than 2GB and thus not supported by 32-bit PHP (null: auto-detect based on |
|
204 * PHP_INT_MAX) |
|
205 * |
|
206 * @var bool|null |
|
207 */ |
|
208 public $option_max_2gb_check; |
|
209 |
|
210 /** |
|
211 * Read buffer size in bytes |
|
212 * |
|
213 * @var int |
|
214 */ |
|
102 public $option_fread_buffer_size = 32768; |
215 public $option_fread_buffer_size = 32768; |
103 |
216 |
104 // Public variables |
217 // Public variables |
105 public $filename; // Filename of file being analysed. |
218 |
106 public $fp; // Filepointer to file being analysed. |
219 /** |
107 public $info; // Result array. |
220 * Filename of file being analysed. |
221 * |
|
222 * @var string |
|
223 */ |
|
224 public $filename; |
|
225 |
|
226 /** |
|
227 * Filepointer to file being analysed. |
|
228 * |
|
229 * @var resource |
|
230 */ |
|
231 public $fp; |
|
232 |
|
233 /** |
|
234 * Result array. |
|
235 * |
|
236 * @var array |
|
237 */ |
|
238 public $info; |
|
239 |
|
240 /** |
|
241 * @var string |
|
242 */ |
|
108 public $tempdir = GETID3_TEMP_DIR; |
243 public $tempdir = GETID3_TEMP_DIR; |
244 |
|
245 /** |
|
246 * @var int |
|
247 */ |
|
109 public $memory_limit = 0; |
248 public $memory_limit = 0; |
110 |
249 |
111 // Protected variables |
250 /** |
251 * @var string |
|
252 */ |
|
112 protected $startup_error = ''; |
253 protected $startup_error = ''; |
254 |
|
255 /** |
|
256 * @var string |
|
257 */ |
|
113 protected $startup_warning = ''; |
258 protected $startup_warning = ''; |
114 |
259 |
115 const VERSION = '1.9.14-201706111222'; |
260 const VERSION = '1.9.20-202006061653'; |
116 const FREAD_BUFFER_SIZE = 32768; |
261 const FREAD_BUFFER_SIZE = 32768; |
117 |
262 |
118 const ATTACHMENTS_NONE = false; |
263 const ATTACHMENTS_NONE = false; |
119 const ATTACHMENTS_INLINE = true; |
264 const ATTACHMENTS_INLINE = true; |
120 |
265 |
121 // public: constructor |
|
122 public function __construct() { |
266 public function __construct() { |
123 |
267 |
268 // Check for PHP version |
|
269 $required_php_version = '5.3.0'; |
|
270 if (version_compare(PHP_VERSION, $required_php_version, '<')) { |
|
271 $this->startup_error .= 'getID3() requires PHP v'.$required_php_version.' or higher - you are running v'.PHP_VERSION."\n"; |
|
272 return; |
|
273 } |
|
274 |
|
124 // Check memory |
275 // Check memory |
125 $this->memory_limit = ini_get('memory_limit'); |
276 $memoryLimit = ini_get('memory_limit'); |
126 if (preg_match('#([0-9]+) ?M#i', $this->memory_limit, $matches)) { |
277 if (preg_match('#([0-9]+) ?M#i', $memoryLimit, $matches)) { |
127 // could be stored as "16M" rather than 16777216 for example |
278 // could be stored as "16M" rather than 16777216 for example |
128 $this->memory_limit = $matches[1] * 1048576; |
279 $memoryLimit = $matches[1] * 1048576; |
129 } elseif (preg_match('#([0-9]+) ?G#i', $this->memory_limit, $matches)) { // The 'G' modifier is available since PHP 5.1.0 |
280 } elseif (preg_match('#([0-9]+) ?G#i', $memoryLimit, $matches)) { // The 'G' modifier is available since PHP 5.1.0 |
130 // could be stored as "2G" rather than 2147483648 for example |
281 // could be stored as "2G" rather than 2147483648 for example |
131 $this->memory_limit = $matches[1] * 1073741824; |
282 $memoryLimit = $matches[1] * 1073741824; |
132 } |
283 } |
284 $this->memory_limit = $memoryLimit; |
|
285 |
|
133 if ($this->memory_limit <= 0) { |
286 if ($this->memory_limit <= 0) { |
134 // memory limits probably disabled |
287 // memory limits probably disabled |
135 } elseif ($this->memory_limit <= 4194304) { |
288 } elseif ($this->memory_limit <= 4194304) { |
136 $this->startup_error .= 'PHP has less than 4MB available memory and will very likely run out. Increase memory_limit in php.ini'."\n"; |
289 $this->startup_error .= 'PHP has less than 4MB available memory and will very likely run out. Increase memory_limit in php.ini'."\n"; |
137 } elseif ($this->memory_limit <= 12582912) { |
290 } elseif ($this->memory_limit <= 12582912) { |
138 $this->startup_warning .= 'PHP has less than 12MB available memory and might run out if all modules are loaded. Increase memory_limit in php.ini'."\n"; |
291 $this->startup_warning .= 'PHP has less than 12MB available memory and might run out if all modules are loaded. Increase memory_limit in php.ini'."\n"; |
139 } |
292 } |
140 |
293 |
141 // Check safe_mode off |
294 // Check safe_mode off |
142 if (preg_match('#(1|ON)#i', ini_get('safe_mode'))) { |
295 if (preg_match('#(1|ON)#i', ini_get('safe_mode'))) { // phpcs:ignore PHPCompatibility.IniDirectives.RemovedIniDirectives.safe_modeDeprecatedRemoved |
143 $this->warning('WARNING: Safe mode is on, shorten support disabled, md5data/sha1data for ogg vorbis disabled, ogg vorbos/flac tag writing disabled.'); |
296 $this->warning('WARNING: Safe mode is on, shorten support disabled, md5data/sha1data for ogg vorbis disabled, ogg vorbos/flac tag writing disabled.'); |
144 } |
297 } |
145 |
298 |
146 if (($mbstring_func_overload = ini_get('mbstring.func_overload')) && ($mbstring_func_overload & 0x02)) { |
299 // phpcs:ignore PHPCompatibility.IniDirectives.RemovedIniDirectives.mbstring_func_overloadDeprecated |
300 if (($mbstring_func_overload = (int) ini_get('mbstring.func_overload')) && ($mbstring_func_overload & 0x02)) { |
|
147 // http://php.net/manual/en/mbstring.overload.php |
301 // http://php.net/manual/en/mbstring.overload.php |
148 // "mbstring.func_overload in php.ini is a positive value that represents a combination of bitmasks specifying the categories of functions to be overloaded. It should be set to 1 to overload the mail() function. 2 for string functions, 4 for regular expression functions" |
302 // "mbstring.func_overload in php.ini is a positive value that represents a combination of bitmasks specifying the categories of functions to be overloaded. It should be set to 1 to overload the mail() function. 2 for string functions, 4 for regular expression functions" |
149 // getID3 cannot run when string functions are overloaded. It doesn't matter if mail() or ereg* functions are overloaded since getID3 does not use those. |
303 // getID3 cannot run when string functions are overloaded. It doesn't matter if mail() or ereg* functions are overloaded since getID3 does not use those. |
304 // phpcs:ignore PHPCompatibility.IniDirectives.RemovedIniDirectives.mbstring_func_overloadDeprecated |
|
150 $this->startup_error .= 'WARNING: php.ini contains "mbstring.func_overload = '.ini_get('mbstring.func_overload').'", getID3 cannot run with this setting (bitmask 2 (string functions) cannot be set). Recommended to disable entirely.'."\n"; |
305 $this->startup_error .= 'WARNING: php.ini contains "mbstring.func_overload = '.ini_get('mbstring.func_overload').'", getID3 cannot run with this setting (bitmask 2 (string functions) cannot be set). Recommended to disable entirely.'."\n"; |
151 } |
306 } |
152 |
307 |
153 // Check for magic_quotes_runtime |
308 // check for magic quotes in PHP < 7.4.0 (when these functions became deprecated) |
154 if (function_exists('get_magic_quotes_runtime')) { |
309 if (version_compare(PHP_VERSION, '7.4.0', '<')) { |
155 if (get_magic_quotes_runtime()) { |
310 // Check for magic_quotes_runtime |
156 $this->startup_error .= 'magic_quotes_runtime must be disabled before running getID3(). Surround getid3 block by set_magic_quotes_runtime(0) and set_magic_quotes_runtime(1).'."\n"; |
311 if (function_exists('get_magic_quotes_runtime')) { |
157 } |
312 // phpcs:ignore PHPCompatibility.FunctionUse.RemovedFunctions.get_magic_quotes_runtimeDeprecated |
158 } |
313 if (get_magic_quotes_runtime()) { |
159 |
314 $this->startup_error .= 'magic_quotes_runtime must be disabled before running getID3(). Surround getid3 block by set_magic_quotes_runtime(0) and set_magic_quotes_runtime(1).'."\n"; |
160 // Check for magic_quotes_gpc |
315 } |
161 if (function_exists('magic_quotes_gpc')) { |
316 } |
162 if (get_magic_quotes_gpc()) { |
317 // Check for magic_quotes_gpc |
163 $this->startup_error .= 'magic_quotes_gpc must be disabled before running getID3(). Surround getid3 block by set_magic_quotes_gpc(0) and set_magic_quotes_gpc(1).'."\n"; |
318 if (function_exists('get_magic_quotes_gpc')) { |
319 // phpcs:ignore PHPCompatibility.FunctionUse.RemovedFunctions.get_magic_quotes_gpcDeprecated |
|
320 if (get_magic_quotes_gpc()) { |
|
321 $this->startup_error .= 'magic_quotes_gpc must be disabled before running getID3(). Surround getid3 block by set_magic_quotes_gpc(0) and set_magic_quotes_gpc(1).'."\n"; |
|
322 } |
|
164 } |
323 } |
165 } |
324 } |
166 |
325 |
167 // Load support library |
326 // Load support library |
168 if (!include_once(GETID3_INCLUDEPATH.'getid3.lib.php')) { |
327 if (!include_once(GETID3_INCLUDEPATH.'getid3.lib.php')) { |
174 } |
333 } |
175 |
334 |
176 |
335 |
177 // Needed for Windows only: |
336 // Needed for Windows only: |
178 // Define locations of helper applications for Shorten, VorbisComment, MetaFLAC |
337 // Define locations of helper applications for Shorten, VorbisComment, MetaFLAC |
179 // as well as other helper functions such as head, tail, md5sum, etc |
338 // as well as other helper functions such as head, etc |
180 // This path cannot contain spaces, but the below code will attempt to get the |
339 // This path cannot contain spaces, but the below code will attempt to get the |
181 // 8.3-equivalent path automatically |
340 // 8.3-equivalent path automatically |
182 // IMPORTANT: This path must include the trailing slash |
341 // IMPORTANT: This path must include the trailing slash |
183 if (GETID3_OS_ISWINDOWS && !defined('GETID3_HELPERAPPSDIR')) { |
342 if (GETID3_OS_ISWINDOWS && !defined('GETID3_HELPERAPPSDIR')) { |
184 |
343 |
217 |
376 |
218 if (!empty($this->startup_error)) { |
377 if (!empty($this->startup_error)) { |
219 echo $this->startup_error; |
378 echo $this->startup_error; |
220 throw new getid3_exception($this->startup_error); |
379 throw new getid3_exception($this->startup_error); |
221 } |
380 } |
222 |
381 } |
223 return true; |
382 |
224 } |
383 /** |
225 |
384 * @return string |
385 */ |
|
226 public function version() { |
386 public function version() { |
227 return self::VERSION; |
387 return self::VERSION; |
228 } |
388 } |
229 |
389 |
390 /** |
|
391 * @return int |
|
392 */ |
|
230 public function fread_buffer_size() { |
393 public function fread_buffer_size() { |
231 return $this->option_fread_buffer_size; |
394 return $this->option_fread_buffer_size; |
232 } |
395 } |
233 |
396 |
234 |
397 /** |
235 // public: setOption |
398 * @param array $optArray |
399 * |
|
400 * @return bool |
|
401 */ |
|
236 public function setOption($optArray) { |
402 public function setOption($optArray) { |
237 if (!is_array($optArray) || empty($optArray)) { |
403 if (!is_array($optArray) || empty($optArray)) { |
238 return false; |
404 return false; |
239 } |
405 } |
240 foreach ($optArray as $opt => $val) { |
406 foreach ($optArray as $opt => $val) { |
244 $this->$opt = $val; |
410 $this->$opt = $val; |
245 } |
411 } |
246 return true; |
412 return true; |
247 } |
413 } |
248 |
414 |
249 |
415 /** |
250 public function openfile($filename, $filesize=null) { |
416 * @param string $filename |
417 * @param int $filesize |
|
418 * @param resource $fp |
|
419 * |
|
420 * @return bool |
|
421 * |
|
422 * @throws getid3_exception |
|
423 */ |
|
424 public function openfile($filename, $filesize=null, $fp=null) { |
|
251 try { |
425 try { |
252 if (!empty($this->startup_error)) { |
426 if (!empty($this->startup_error)) { |
253 throw new getid3_exception($this->startup_error); |
427 throw new getid3_exception($this->startup_error); |
254 } |
428 } |
255 if (!empty($this->startup_warning)) { |
429 if (!empty($this->startup_warning)) { |
268 if (preg_match('#^(ht|f)tp://#', $filename)) { |
442 if (preg_match('#^(ht|f)tp://#', $filename)) { |
269 throw new getid3_exception('Remote files are not supported - please copy the file locally first'); |
443 throw new getid3_exception('Remote files are not supported - please copy the file locally first'); |
270 } |
444 } |
271 |
445 |
272 $filename = str_replace('/', DIRECTORY_SEPARATOR, $filename); |
446 $filename = str_replace('/', DIRECTORY_SEPARATOR, $filename); |
273 $filename = preg_replace('#(?<!gs:)('.preg_quote(DIRECTORY_SEPARATOR).'{2,})#', DIRECTORY_SEPARATOR, $filename); |
447 //$filename = preg_replace('#(?<!gs:)('.preg_quote(DIRECTORY_SEPARATOR).'{2,})#', DIRECTORY_SEPARATOR, $filename); |
274 |
448 |
275 // open local file |
449 // open local file |
276 //if (is_readable($filename) && is_file($filename) && ($this->fp = fopen($filename, 'rb'))) { // see http://www.getid3.org/phpBB3/viewtopic.php?t=1720 |
450 //if (is_readable($filename) && is_file($filename) && ($this->fp = fopen($filename, 'rb'))) { // see https://www.getid3.org/phpBB3/viewtopic.php?t=1720 |
277 if ((is_readable($filename) || file_exists($filename)) && is_file($filename) && ($this->fp = fopen($filename, 'rb'))) { |
451 if (($fp != null) && ((get_resource_type($fp) == 'file') || (get_resource_type($fp) == 'stream'))) { |
452 $this->fp = $fp; |
|
453 } elseif ((is_readable($filename) || file_exists($filename)) && is_file($filename) && ($this->fp = fopen($filename, 'rb'))) { |
|
278 // great |
454 // great |
279 } else { |
455 } else { |
280 $errormessagelist = array(); |
456 $errormessagelist = array(); |
281 if (!is_readable($filename)) { |
457 if (!is_readable($filename)) { |
282 $errormessagelist[] = '!is_readable'; |
458 $errormessagelist[] = '!is_readable'; |
329 fclose($this->fp); |
505 fclose($this->fp); |
330 throw new getid3_exception('Unable to determine actual filesize. File is most likely larger than '.round(PHP_INT_MAX / 1073741824).'GB and is not supported by PHP.'); |
506 throw new getid3_exception('Unable to determine actual filesize. File is most likely larger than '.round(PHP_INT_MAX / 1073741824).'GB and is not supported by PHP.'); |
331 } elseif (getid3_lib::intValueSupported($real_filesize)) { |
507 } elseif (getid3_lib::intValueSupported($real_filesize)) { |
332 unset($this->info['filesize']); |
508 unset($this->info['filesize']); |
333 fclose($this->fp); |
509 fclose($this->fp); |
334 throw new getid3_exception('PHP seems to think the file is larger than '.round(PHP_INT_MAX / 1073741824).'GB, but filesystem reports it as '.number_format($real_filesize, 3).'GB, please report to info@getid3.org'); |
510 throw new getid3_exception('PHP seems to think the file is larger than '.round(PHP_INT_MAX / 1073741824).'GB, but filesystem reports it as '.number_format($real_filesize / 1073741824, 3).'GB, please report to info@getid3.org'); |
335 } |
511 } |
336 $this->info['filesize'] = $real_filesize; |
512 $this->info['filesize'] = $real_filesize; |
337 $this->warning('File is larger than '.round(PHP_INT_MAX / 1073741824).'GB (filesystem reports it as '.number_format($real_filesize, 3).'GB) and is not properly supported by PHP.'); |
513 $this->warning('File is larger than '.round(PHP_INT_MAX / 1073741824).'GB (filesystem reports it as '.number_format($real_filesize / 1073741824, 3).'GB) and is not properly supported by PHP.'); |
338 } |
514 } |
339 } |
515 } |
340 |
516 |
341 return true; |
517 return true; |
342 |
518 |
344 $this->error($e->getMessage()); |
520 $this->error($e->getMessage()); |
345 } |
521 } |
346 return false; |
522 return false; |
347 } |
523 } |
348 |
524 |
349 // public: analyze file |
525 /** |
350 public function analyze($filename, $filesize=null, $original_filename='') { |
526 * analyze file |
527 * |
|
528 * @param string $filename |
|
529 * @param int $filesize |
|
530 * @param string $original_filename |
|
531 * @param resource $fp |
|
532 * |
|
533 * @return array |
|
534 */ |
|
535 public function analyze($filename, $filesize=null, $original_filename='', $fp=null) { |
|
351 try { |
536 try { |
352 if (!$this->openfile($filename, $filesize)) { |
537 if (!$this->openfile($filename, $filesize, $fp)) { |
353 return $this->info; |
538 return $this->info; |
354 } |
539 } |
355 |
540 |
356 // Handle tags |
541 // Handle tags |
357 foreach (array('id3v2'=>'id3v2', 'id3v1'=>'id3v1', 'apetag'=>'ape', 'lyrics3'=>'lyrics3') as $tag_name => $tag_key) { |
542 foreach (array('id3v2'=>'id3v2', 'id3v1'=>'id3v1', 'apetag'=>'ape', 'lyrics3'=>'lyrics3') as $tag_name => $tag_key) { |
381 if (!$this->option_tag_id3v2) { |
566 if (!$this->option_tag_id3v2) { |
382 fseek($this->fp, 0); |
567 fseek($this->fp, 0); |
383 $header = fread($this->fp, 10); |
568 $header = fread($this->fp, 10); |
384 if ((substr($header, 0, 3) == 'ID3') && (strlen($header) == 10)) { |
569 if ((substr($header, 0, 3) == 'ID3') && (strlen($header) == 10)) { |
385 $this->info['id3v2']['header'] = true; |
570 $this->info['id3v2']['header'] = true; |
386 $this->info['id3v2']['majorversion'] = ord($header{3}); |
571 $this->info['id3v2']['majorversion'] = ord($header[3]); |
387 $this->info['id3v2']['minorversion'] = ord($header{4}); |
572 $this->info['id3v2']['minorversion'] = ord($header[4]); |
388 $this->info['avdataoffset'] += getid3_lib::BigEndian2Int(substr($header, 6, 4), 1) + 10; // length of ID3v2 tag in 10-byte header doesn't include 10-byte header length |
573 $this->info['avdataoffset'] += getid3_lib::BigEndian2Int(substr($header, 6, 4), 1) + 10; // length of ID3v2 tag in 10-byte header doesn't include 10-byte header length |
389 } |
574 } |
390 } |
575 } |
391 |
576 |
392 // read 32 kb file data |
577 // read 32 kb file data |
495 // return info array |
680 // return info array |
496 return $this->info; |
681 return $this->info; |
497 } |
682 } |
498 |
683 |
499 |
684 |
500 // private: error handling |
685 /** |
686 * Error handling. |
|
687 * |
|
688 * @param string $message |
|
689 * |
|
690 * @return array |
|
691 */ |
|
501 public function error($message) { |
692 public function error($message) { |
502 $this->CleanUp(); |
693 $this->CleanUp(); |
503 if (!isset($this->info['error'])) { |
694 if (!isset($this->info['error'])) { |
504 $this->info['error'] = array(); |
695 $this->info['error'] = array(); |
505 } |
696 } |
506 $this->info['error'][] = $message; |
697 $this->info['error'][] = $message; |
507 return $this->info; |
698 return $this->info; |
508 } |
699 } |
509 |
700 |
510 |
701 |
511 // private: warning handling |
702 /** |
703 * Warning handling. |
|
704 * |
|
705 * @param string $message |
|
706 * |
|
707 * @return bool |
|
708 */ |
|
512 public function warning($message) { |
709 public function warning($message) { |
513 $this->info['warning'][] = $message; |
710 $this->info['warning'][] = $message; |
514 return true; |
711 return true; |
515 } |
712 } |
516 |
713 |
517 |
714 |
518 // private: CleanUp |
715 /** |
716 * @return bool |
|
717 */ |
|
519 private function CleanUp() { |
718 private function CleanUp() { |
520 |
719 |
521 // remove possible empty keys |
720 // remove possible empty keys |
522 $AVpossibleEmptyKeys = array('dataformat', 'bits_per_sample', 'encoder_options', 'streams', 'bitrate'); |
721 $AVpossibleEmptyKeys = array('dataformat', 'bits_per_sample', 'encoder_options', 'streams', 'bitrate'); |
523 foreach ($AVpossibleEmptyKeys as $dummy => $key) { |
722 foreach ($AVpossibleEmptyKeys as $dummy => $key) { |
560 unset($this->info['php_memory_limit']); |
759 unset($this->info['php_memory_limit']); |
561 |
760 |
562 return true; |
761 return true; |
563 } |
762 } |
564 |
763 |
565 |
764 /** |
566 // return array containing information about all supported formats |
765 * Return array containing information about all supported formats. |
766 * |
|
767 * @return array |
|
768 */ |
|
567 public function GetFileFormatArray() { |
769 public function GetFileFormatArray() { |
568 static $format_info = array(); |
770 static $format_info = array(); |
569 if (empty($format_info)) { |
771 if (empty($format_info)) { |
570 $format_info = array( |
772 $format_info = array( |
571 |
773 |
582 // AAC - audio - Advanced Audio Coding (AAC) - ADIF format |
784 // AAC - audio - Advanced Audio Coding (AAC) - ADIF format |
583 'adif' => array( |
785 'adif' => array( |
584 'pattern' => '^ADIF', |
786 'pattern' => '^ADIF', |
585 'group' => 'audio', |
787 'group' => 'audio', |
586 'module' => 'aac', |
788 'module' => 'aac', |
587 'mime_type' => 'application/octet-stream', |
789 'mime_type' => 'audio/aac', |
588 'fail_ape' => 'WARNING', |
790 'fail_ape' => 'WARNING', |
589 ), |
791 ), |
590 |
792 |
591 /* |
793 /* |
592 // AA - audio - Audible Audiobook |
794 // AA - audio - Audible Audiobook |
600 // AAC - audio - Advanced Audio Coding (AAC) - ADTS format (very similar to MP3) |
802 // AAC - audio - Advanced Audio Coding (AAC) - ADTS format (very similar to MP3) |
601 'adts' => array( |
803 'adts' => array( |
602 'pattern' => '^\\xFF[\\xF0-\\xF1\\xF8-\\xF9]', |
804 'pattern' => '^\\xFF[\\xF0-\\xF1\\xF8-\\xF9]', |
603 'group' => 'audio', |
805 'group' => 'audio', |
604 'module' => 'aac', |
806 'module' => 'aac', |
605 'mime_type' => 'application/octet-stream', |
807 'mime_type' => 'audio/aac', |
606 'fail_ape' => 'WARNING', |
808 'fail_ape' => 'WARNING', |
607 ), |
809 ), |
608 |
810 |
609 |
811 |
610 // AU - audio - NeXT/Sun AUdio (AU) |
812 // AU - audio - NeXT/Sun AUdio (AU) |
647 'mime_type' => 'audio/dsd', |
849 'mime_type' => 'audio/dsd', |
648 ), |
850 ), |
649 |
851 |
650 // DSS - audio - Digital Speech Standard |
852 // DSS - audio - Digital Speech Standard |
651 'dss' => array( |
853 'dss' => array( |
652 'pattern' => '^[\\x02-\\x06]ds[s2]', |
854 'pattern' => '^[\\x02-\\x08]ds[s2]', |
653 'group' => 'audio', |
855 'group' => 'audio', |
654 'module' => 'dss', |
856 'module' => 'dss', |
655 'mime_type' => 'application/octet-stream', |
857 'mime_type' => 'application/octet-stream', |
858 ), |
|
859 |
|
860 // DSDIFF - audio - Direct Stream Digital Interchange File Format |
|
861 'dsdiff' => array( |
|
862 'pattern' => '^FRM8', |
|
863 'group' => 'audio', |
|
864 'module' => 'dsdiff', |
|
865 'mime_type' => 'audio/dsd', |
|
656 ), |
866 ), |
657 |
867 |
658 // DTS - audio - Dolby Theatre System |
868 // DTS - audio - Dolby Theatre System |
659 'dts' => array( |
869 'dts' => array( |
660 'pattern' => '^\\x7F\\xFE\\x80\\x01', |
870 'pattern' => '^\\x7F\\xFE\\x80\\x01', |
666 // FLAC - audio - Free Lossless Audio Codec |
876 // FLAC - audio - Free Lossless Audio Codec |
667 'flac' => array( |
877 'flac' => array( |
668 'pattern' => '^fLaC', |
878 'pattern' => '^fLaC', |
669 'group' => 'audio', |
879 'group' => 'audio', |
670 'module' => 'flac', |
880 'module' => 'flac', |
671 'mime_type' => 'audio/x-flac', |
881 'mime_type' => 'audio/flac', |
672 ), |
882 ), |
673 |
883 |
674 // LA - audio - Lossless Audio (LA) |
884 // LA - audio - Lossless Audio (LA) |
675 'la' => array( |
885 'la' => array( |
676 'pattern' => '^LA0[2-4]', |
886 'pattern' => '^LA0[2-4]', |
698 // MAC - audio - Monkey's Audio Compressor |
908 // MAC - audio - Monkey's Audio Compressor |
699 'mac' => array( |
909 'mac' => array( |
700 'pattern' => '^MAC ', |
910 'pattern' => '^MAC ', |
701 'group' => 'audio', |
911 'group' => 'audio', |
702 'module' => 'monkey', |
912 'module' => 'monkey', |
703 'mime_type' => 'application/octet-stream', |
913 'mime_type' => 'audio/x-monkeys-audio', |
704 ), |
914 ), |
705 |
915 |
706 // has been known to produce false matches in random files (e.g. JPEGs), leave out until more precise matching available |
916 // has been known to produce false matches in random files (e.g. JPEGs), leave out until more precise matching available |
707 // // MOD - audio - MODule (assorted sub-formats) |
917 // // MOD - audio - MODule (assorted sub-formats) |
708 // 'mod' => array( |
918 // 'mod' => array( |
780 'mime_type' => 'audio/xmms-shn', |
990 'mime_type' => 'audio/xmms-shn', |
781 'fail_id3' => 'ERROR', |
991 'fail_id3' => 'ERROR', |
782 'fail_ape' => 'ERROR', |
992 'fail_ape' => 'ERROR', |
783 ), |
993 ), |
784 |
994 |
995 // TAK - audio - Tom's lossless Audio Kompressor |
|
996 'tak' => array( |
|
997 'pattern' => '^tBaK', |
|
998 'group' => 'audio', |
|
999 'module' => 'tak', |
|
1000 'mime_type' => 'application/octet-stream', |
|
1001 ), |
|
1002 |
|
785 // TTA - audio - TTA Lossless Audio Compressor (http://tta.corecodec.org) |
1003 // TTA - audio - TTA Lossless Audio Compressor (http://tta.corecodec.org) |
786 'tta' => array( |
1004 'tta' => array( |
787 'pattern' => '^TTA', // could also be '^TTA(\\x01|\\x02|\\x03|2|1)' |
1005 'pattern' => '^TTA', // could also be '^TTA(\\x01|\\x02|\\x03|2|1)' |
788 'group' => 'audio', |
1006 'group' => 'audio', |
789 'module' => 'tta', |
1007 'module' => 'tta', |
840 'group' => 'audio-video', |
1058 'group' => 'audio-video', |
841 'module' => 'flv', |
1059 'module' => 'flv', |
842 'mime_type' => 'video/x-flv', |
1060 'mime_type' => 'video/x-flv', |
843 ), |
1061 ), |
844 |
1062 |
1063 // IVF - audio/video - IVF |
|
1064 'ivf' => array( |
|
1065 'pattern' => '^DKIF', |
|
1066 'group' => 'audio-video', |
|
1067 'module' => 'ivf', |
|
1068 'mime_type' => 'video/x-ivf', |
|
1069 ), |
|
1070 |
|
845 // MKAV - audio/video - Mastroka |
1071 // MKAV - audio/video - Mastroka |
846 'matroska' => array( |
1072 'matroska' => array( |
847 'pattern' => '^\\x1A\\x45\\xDF\\xA3', |
1073 'pattern' => '^\\x1A\\x45\\xDF\\xA3', |
848 'group' => 'audio-video', |
1074 'group' => 'audio-video', |
849 'module' => 'matroska', |
1075 'module' => 'matroska', |
887 // RIFF - audio/video - Resource Interchange File Format (RIFF) / WAV / AVI / CD-audio / SDSS = renamed variant used by SmartSound QuickTracks (www.smartsound.com) / FORM = Audio Interchange File Format (AIFF) |
1113 // RIFF - audio/video - Resource Interchange File Format (RIFF) / WAV / AVI / CD-audio / SDSS = renamed variant used by SmartSound QuickTracks (www.smartsound.com) / FORM = Audio Interchange File Format (AIFF) |
888 'riff' => array( |
1114 'riff' => array( |
889 'pattern' => '^(RIFF|SDSS|FORM)', |
1115 'pattern' => '^(RIFF|SDSS|FORM)', |
890 'group' => 'audio-video', |
1116 'group' => 'audio-video', |
891 'module' => 'riff', |
1117 'module' => 'riff', |
892 'mime_type' => 'audio/x-wav', |
1118 'mime_type' => 'audio/wav', |
893 'fail_ape' => 'WARNING', |
1119 'fail_ape' => 'WARNING', |
894 ), |
1120 ), |
895 |
1121 |
896 // Real - audio/video - RealAudio, RealVideo |
1122 // Real - audio/video - RealAudio, RealVideo |
897 'real' => array( |
1123 'real' => array( |
913 'ts' => array( |
1139 'ts' => array( |
914 'pattern' => '^(\\x47.{187}){10,}', // packets are 188 bytes long and start with 0x47 "G". Check for at least 10 packets matching this pattern |
1140 'pattern' => '^(\\x47.{187}){10,}', // packets are 188 bytes long and start with 0x47 "G". Check for at least 10 packets matching this pattern |
915 'group' => 'audio-video', |
1141 'group' => 'audio-video', |
916 'module' => 'ts', |
1142 'module' => 'ts', |
917 'mime_type' => 'video/MP2T', |
1143 'mime_type' => 'video/MP2T', |
1144 ), |
|
1145 |
|
1146 // WTV - audio/video - Windows Recorded TV Show |
|
1147 'wtv' => array( |
|
1148 'pattern' => '^\\xB7\\xD8\\x00\\x20\\x37\\x49\\xDA\\x11\\xA6\\x4E\\x00\\x07\\xE9\\x5E\\xAD\\x8D', |
|
1149 'group' => 'audio-video', |
|
1150 'module' => 'wtv', |
|
1151 'mime_type' => 'video/x-ms-wtv', |
|
918 ), |
1152 ), |
919 |
1153 |
920 |
1154 |
921 // Still-Image formats |
1155 // Still-Image formats |
922 |
1156 |
1016 'fail_id3' => 'ERROR', |
1250 'fail_id3' => 'ERROR', |
1017 'fail_ape' => 'ERROR', |
1251 'fail_ape' => 'ERROR', |
1018 'iconv_req' => false, |
1252 'iconv_req' => false, |
1019 ), |
1253 ), |
1020 |
1254 |
1255 // HPK - data - HPK compressed data |
|
1256 'hpk' => array( |
|
1257 'pattern' => '^BPUL', |
|
1258 'group' => 'archive', |
|
1259 'module' => 'hpk', |
|
1260 'mime_type' => 'application/octet-stream', |
|
1261 'fail_id3' => 'ERROR', |
|
1262 'fail_ape' => 'ERROR', |
|
1263 ), |
|
1264 |
|
1021 // RAR - data - RAR compressed data |
1265 // RAR - data - RAR compressed data |
1022 'rar' => array( |
1266 'rar' => array( |
1023 'pattern' => '^Rar\\!', |
1267 'pattern' => '^Rar\\!', |
1024 'group' => 'archive', |
1268 'group' => 'archive', |
1025 'module' => 'rar', |
1269 'module' => 'rar', |
1026 'mime_type' => 'application/octet-stream', |
1270 'mime_type' => 'application/vnd.rar', |
1027 'fail_id3' => 'ERROR', |
1271 'fail_id3' => 'ERROR', |
1028 'fail_ape' => 'ERROR', |
1272 'fail_ape' => 'ERROR', |
1029 ), |
1273 ), |
1030 |
1274 |
1031 // SZIP - audio/data - SZIP compressed data |
1275 // SZIP - audio/data - SZIP compressed data |
1051 // GZIP - data - GZIP compressed data |
1295 // GZIP - data - GZIP compressed data |
1052 'gz' => array( |
1296 'gz' => array( |
1053 'pattern' => '^\\x1F\\x8B\\x08', |
1297 'pattern' => '^\\x1F\\x8B\\x08', |
1054 'group' => 'archive', |
1298 'group' => 'archive', |
1055 'module' => 'gzip', |
1299 'module' => 'gzip', |
1056 'mime_type' => 'application/x-gzip', |
1300 'mime_type' => 'application/gzip', |
1057 'fail_id3' => 'ERROR', |
1301 'fail_id3' => 'ERROR', |
1058 'fail_ape' => 'ERROR', |
1302 'fail_ape' => 'ERROR', |
1059 ), |
1303 ), |
1060 |
1304 |
1061 // ZIP - data - ZIP compressed data |
1305 // ZIP - data - ZIP compressed data |
1066 'mime_type' => 'application/zip', |
1310 'mime_type' => 'application/zip', |
1067 'fail_id3' => 'ERROR', |
1311 'fail_id3' => 'ERROR', |
1068 'fail_ape' => 'ERROR', |
1312 'fail_ape' => 'ERROR', |
1069 ), |
1313 ), |
1070 |
1314 |
1315 // XZ - data - XZ compressed data |
|
1316 'xz' => array( |
|
1317 'pattern' => '^\\xFD7zXZ\\x00', |
|
1318 'group' => 'archive', |
|
1319 'module' => 'xz', |
|
1320 'mime_type' => 'application/x-xz', |
|
1321 'fail_id3' => 'ERROR', |
|
1322 'fail_ape' => 'ERROR', |
|
1323 ), |
|
1324 |
|
1071 |
1325 |
1072 // Misc other formats |
1326 // Misc other formats |
1073 |
1327 |
1074 // PAR2 - data - Parity Volume Set Specification 2.0 |
1328 // PAR2 - data - Parity Volume Set Specification 2.0 |
1075 'par2' => array ( |
1329 'par2' => array ( |
1113 } |
1367 } |
1114 |
1368 |
1115 return $format_info; |
1369 return $format_info; |
1116 } |
1370 } |
1117 |
1371 |
1118 |
1372 /** |
1119 |
1373 * @param string $filedata |
1374 * @param string $filename |
|
1375 * |
|
1376 * @return mixed|false |
|
1377 */ |
|
1120 public function GetFileFormat(&$filedata, $filename='') { |
1378 public function GetFileFormat(&$filedata, $filename='') { |
1121 // this function will determine the format of a file based on usually |
1379 // this function will determine the format of a file based on usually |
1122 // the first 2-4 bytes of the file (8 bytes for PNG, 16 bytes for JPG, |
1380 // the first 2-4 bytes of the file (8 bytes for PNG, 16 bytes for JPG, |
1123 // and in the case of ISO CD image, 6 bytes offset 32kb from the start |
1381 // and in the case of ISO CD image, 6 bytes offset 32kb from the start |
1124 // of the file). |
1382 // of the file). |
1133 } |
1391 } |
1134 } |
1392 } |
1135 |
1393 |
1136 |
1394 |
1137 if (preg_match('#\\.mp[123a]$#i', $filename)) { |
1395 if (preg_match('#\\.mp[123a]$#i', $filename)) { |
1138 // Too many mp3 encoders on the market put gabage in front of mpeg files |
1396 // Too many mp3 encoders on the market put garbage in front of mpeg files |
1139 // use assume format on these if format detection failed |
1397 // use assume format on these if format detection failed |
1140 $GetFileFormatArray = $this->GetFileFormatArray(); |
1398 $GetFileFormatArray = $this->GetFileFormatArray(); |
1141 $info = $GetFileFormatArray['mp3']; |
1399 $info = $GetFileFormatArray['mp3']; |
1142 $info['include'] = 'module.'.$info['group'].'.'.$info['module'].'.php'; |
1400 $info['include'] = 'module.'.$info['group'].'.'.$info['module'].'.php'; |
1143 return $info; |
1401 return $info; |
1152 } |
1410 } |
1153 |
1411 |
1154 return false; |
1412 return false; |
1155 } |
1413 } |
1156 |
1414 |
1157 |
1415 /** |
1158 // converts array to $encoding charset from $this->encoding |
1416 * Converts array to $encoding charset from $this->encoding. |
1417 * |
|
1418 * @param array $array |
|
1419 * @param string $encoding |
|
1420 */ |
|
1159 public function CharConvert(&$array, $encoding) { |
1421 public function CharConvert(&$array, $encoding) { |
1160 |
1422 |
1161 // identical encoding - end here |
1423 // identical encoding - end here |
1162 if ($encoding == $this->encoding) { |
1424 if ($encoding == $this->encoding) { |
1163 return; |
1425 return; |
1176 $array[$key] = trim(getid3_lib::iconv_fallback($encoding, $this->encoding, $value)); |
1438 $array[$key] = trim(getid3_lib::iconv_fallback($encoding, $this->encoding, $value)); |
1177 } |
1439 } |
1178 } |
1440 } |
1179 } |
1441 } |
1180 |
1442 |
1181 |
1443 /** |
1444 * @return bool |
|
1445 */ |
|
1182 public function HandleAllTags() { |
1446 public function HandleAllTags() { |
1183 |
1447 |
1184 // key name => array (tag name, character encoding) |
1448 // key name => array (tag name, character encoding) |
1185 static $tags; |
1449 static $tags; |
1186 if (empty($tags)) { |
1450 if (empty($tags)) { |
1203 'cue' => array('cue' , 'ISO-8859-1'), |
1467 'cue' => array('cue' , 'ISO-8859-1'), |
1204 'matroska' => array('matroska' , 'UTF-8'), |
1468 'matroska' => array('matroska' , 'UTF-8'), |
1205 'flac' => array('vorbiscomment' , 'UTF-8'), |
1469 'flac' => array('vorbiscomment' , 'UTF-8'), |
1206 'divxtag' => array('divx' , 'ISO-8859-1'), |
1470 'divxtag' => array('divx' , 'ISO-8859-1'), |
1207 'iptc' => array('iptc' , 'ISO-8859-1'), |
1471 'iptc' => array('iptc' , 'ISO-8859-1'), |
1472 'dsdiff' => array('dsdiff' , 'ISO-8859-1'), |
|
1208 ); |
1473 ); |
1209 } |
1474 } |
1210 |
1475 |
1211 // loop through comments array |
1476 // loop through comments array |
1212 foreach ($tags as $comment_name => $tagname_encoding_array) { |
1477 foreach ($tags as $comment_name => $tagname_encoding_array) { |
1231 $this->info['tags'][trim($tag_name)][trim($tag_key)][] = $value; |
1496 $this->info['tags'][trim($tag_name)][trim($tag_key)][] = $value; |
1232 } |
1497 } |
1233 } |
1498 } |
1234 } |
1499 } |
1235 if ($tag_key == 'picture') { |
1500 if ($tag_key == 'picture') { |
1501 // pictures can take up a lot of space, and we don't need multiple copies of them; let there be a single copy in [comments][picture], and not elsewhere |
|
1236 unset($this->info[$comment_name]['comments'][$tag_key]); |
1502 unset($this->info[$comment_name]['comments'][$tag_key]); |
1237 } |
1503 } |
1238 } |
1504 } |
1239 |
1505 |
1240 if (!isset($this->info['tags'][$tag_name])) { |
1506 if (!isset($this->info['tags'][$tag_name])) { |
1244 |
1510 |
1245 $this->CharConvert($this->info['tags'][$tag_name], $this->info[$comment_name]['encoding']); // only copy gets converted! |
1511 $this->CharConvert($this->info['tags'][$tag_name], $this->info[$comment_name]['encoding']); // only copy gets converted! |
1246 |
1512 |
1247 if ($this->option_tags_html) { |
1513 if ($this->option_tags_html) { |
1248 foreach ($this->info['tags'][$tag_name] as $tag_key => $valuearray) { |
1514 foreach ($this->info['tags'][$tag_name] as $tag_key => $valuearray) { |
1515 if ($tag_key == 'picture') { |
|
1516 // Do not to try to convert binary picture data to HTML |
|
1517 // https://github.com/JamesHeinrich/getID3/issues/178 |
|
1518 continue; |
|
1519 } |
|
1249 $this->info['tags_html'][$tag_name][$tag_key] = getid3_lib::recursiveMultiByteCharString2HTML($valuearray, $this->info[$comment_name]['encoding']); |
1520 $this->info['tags_html'][$tag_name][$tag_key] = getid3_lib::recursiveMultiByteCharString2HTML($valuearray, $this->info[$comment_name]['encoding']); |
1250 } |
1521 } |
1251 } |
1522 } |
1252 |
1523 |
1253 } |
1524 } |
1254 |
1525 |
1255 } |
1526 } |
1256 |
1527 |
1257 // pictures can take up a lot of space, and we don't need multiple copies of them |
1528 // pictures can take up a lot of space, and we don't need multiple copies of them; let there be a single copy in [comments][picture], and not elsewhere |
1258 // let there be a single copy in [comments][picture], and not elsewhere |
|
1259 if (!empty($this->info['tags'])) { |
1529 if (!empty($this->info['tags'])) { |
1260 $unset_keys = array('tags', 'tags_html'); |
1530 $unset_keys = array('tags', 'tags_html'); |
1261 foreach ($this->info['tags'] as $tagtype => $tagarray) { |
1531 foreach ($this->info['tags'] as $tagtype => $tagarray) { |
1262 foreach ($tagarray as $tagname => $tagdata) { |
1532 foreach ($tagarray as $tagname => $tagdata) { |
1263 if ($tagname == 'picture') { |
1533 if ($tagname == 'picture') { |
1299 } |
1569 } |
1300 } |
1570 } |
1301 return true; |
1571 return true; |
1302 } |
1572 } |
1303 |
1573 |
1574 /** |
|
1575 * Calls getid3_lib::CopyTagsToComments() but passes in the option_tags_html setting from this instance of getID3 |
|
1576 * |
|
1577 * @param array $ThisFileInfo |
|
1578 * |
|
1579 * @return bool |
|
1580 */ |
|
1581 public function CopyTagsToComments(&$ThisFileInfo) { |
|
1582 return getid3_lib::CopyTagsToComments($ThisFileInfo, $this->option_tags_html); |
|
1583 } |
|
1584 |
|
1585 /** |
|
1586 * @param string $algorithm |
|
1587 * |
|
1588 * @return array|bool |
|
1589 */ |
|
1304 public function getHashdata($algorithm) { |
1590 public function getHashdata($algorithm) { |
1305 switch ($algorithm) { |
1591 switch ($algorithm) { |
1306 case 'md5': |
1592 case 'md5': |
1307 case 'sha1': |
1593 case 'sha1': |
1308 break; |
1594 break; |
1309 |
1595 |
1310 default: |
1596 default: |
1311 return $this->error('bad algorithm "'.$algorithm.'" in getHashdata()'); |
1597 return $this->error('bad algorithm "'.$algorithm.'" in getHashdata()'); |
1312 break; |
|
1313 } |
1598 } |
1314 |
1599 |
1315 if (!empty($this->info['fileformat']) && !empty($this->info['dataformat']) && ($this->info['fileformat'] == 'ogg') && ($this->info['audio']['dataformat'] == 'vorbis')) { |
1600 if (!empty($this->info['fileformat']) && !empty($this->info['dataformat']) && ($this->info['fileformat'] == 'ogg') && ($this->info['audio']['dataformat'] == 'vorbis')) { |
1316 |
1601 |
1317 // We cannot get an identical md5_data value for Ogg files where the comments |
1602 // We cannot get an identical md5_data value for Ogg files where the comments |
1330 |
1615 |
1331 // The above-mentioned problem of comments spanning multiple pages and changing |
1616 // The above-mentioned problem of comments spanning multiple pages and changing |
1332 // page sequence numbers likely happens for OggSpeex and OggFLAC as well, but |
1617 // page sequence numbers likely happens for OggSpeex and OggFLAC as well, but |
1333 // currently vorbiscomment only works on OggVorbis files. |
1618 // currently vorbiscomment only works on OggVorbis files. |
1334 |
1619 |
1620 // phpcs:ignore PHPCompatibility.IniDirectives.RemovedIniDirectives.safe_modeDeprecatedRemoved |
|
1335 if (preg_match('#(1|ON)#i', ini_get('safe_mode'))) { |
1621 if (preg_match('#(1|ON)#i', ini_get('safe_mode'))) { |
1336 |
1622 |
1337 $this->warning('Failed making system call to vorbiscomment.exe - '.$algorithm.'_data is incorrect - error returned: PHP running in Safe Mode (backtick operator not available)'); |
1623 $this->warning('Failed making system call to vorbiscomment.exe - '.$algorithm.'_data is incorrect - error returned: PHP running in Safe Mode (backtick operator not available)'); |
1338 $this->info[$algorithm.'_data'] = false; |
1624 $this->info[$algorithm.'_data'] = false; |
1339 |
1625 |
1363 |
1649 |
1364 } |
1650 } |
1365 |
1651 |
1366 } else { |
1652 } else { |
1367 |
1653 |
1368 $commandline = 'vorbiscomment -w -c "'.$empty.'" "'.$file.'" "'.$temp.'" 2>&1'; |
|
1369 $commandline = 'vorbiscomment -w -c '.escapeshellarg($empty).' '.escapeshellarg($file).' '.escapeshellarg($temp).' 2>&1'; |
1654 $commandline = 'vorbiscomment -w -c '.escapeshellarg($empty).' '.escapeshellarg($file).' '.escapeshellarg($temp).' 2>&1'; |
1370 $VorbisCommentError = `$commandline`; |
1655 $VorbisCommentError = `$commandline`; |
1371 |
1656 |
1372 } |
1657 } |
1373 |
1658 |
1421 } |
1706 } |
1422 |
1707 |
1423 } |
1708 } |
1424 return true; |
1709 return true; |
1425 } |
1710 } |
1426 |
|
1427 |
1711 |
1428 public function ChannelsBitratePlaytimeCalculations() { |
1712 public function ChannelsBitratePlaytimeCalculations() { |
1429 |
1713 |
1430 // set channelmode on audio |
1714 // set channelmode on audio |
1431 if (!empty($this->info['audio']['channelmode']) || !isset($this->info['audio']['channels'])) { |
1715 if (!empty($this->info['audio']['channelmode']) || !isset($this->info['audio']['channels'])) { |
1487 if (!empty($this->info['playtime_seconds']) && empty($this->info['playtime_string'])) { |
1771 if (!empty($this->info['playtime_seconds']) && empty($this->info['playtime_string'])) { |
1488 $this->info['playtime_string'] = getid3_lib::PlaytimeString($this->info['playtime_seconds']); |
1772 $this->info['playtime_string'] = getid3_lib::PlaytimeString($this->info['playtime_seconds']); |
1489 } |
1773 } |
1490 } |
1774 } |
1491 |
1775 |
1492 |
1776 /** |
1777 * @return bool |
|
1778 */ |
|
1493 public function CalculateCompressionRatioVideo() { |
1779 public function CalculateCompressionRatioVideo() { |
1494 if (empty($this->info['video'])) { |
1780 if (empty($this->info['video'])) { |
1495 return false; |
1781 return false; |
1496 } |
1782 } |
1497 if (empty($this->info['video']['resolution_x']) || empty($this->info['video']['resolution_y'])) { |
1783 if (empty($this->info['video']['resolution_x']) || empty($this->info['video']['resolution_y'])) { |
1535 |
1821 |
1536 $this->info['video']['compression_ratio'] = $BitrateCompressed / $BitrateUncompressed; |
1822 $this->info['video']['compression_ratio'] = $BitrateCompressed / $BitrateUncompressed; |
1537 return true; |
1823 return true; |
1538 } |
1824 } |
1539 |
1825 |
1540 |
1826 /** |
1827 * @return bool |
|
1828 */ |
|
1541 public function CalculateCompressionRatioAudio() { |
1829 public function CalculateCompressionRatioAudio() { |
1542 if (empty($this->info['audio']['bitrate']) || empty($this->info['audio']['channels']) || empty($this->info['audio']['sample_rate']) || !is_numeric($this->info['audio']['sample_rate'])) { |
1830 if (empty($this->info['audio']['bitrate']) || empty($this->info['audio']['channels']) || empty($this->info['audio']['sample_rate']) || !is_numeric($this->info['audio']['sample_rate'])) { |
1543 return false; |
1831 return false; |
1544 } |
1832 } |
1545 $this->info['audio']['compression_ratio'] = $this->info['audio']['bitrate'] / ($this->info['audio']['channels'] * $this->info['audio']['sample_rate'] * (!empty($this->info['audio']['bits_per_sample']) ? $this->info['audio']['bits_per_sample'] : 16)); |
1833 $this->info['audio']['compression_ratio'] = $this->info['audio']['bitrate'] / ($this->info['audio']['channels'] * $this->info['audio']['sample_rate'] * (!empty($this->info['audio']['bits_per_sample']) ? $this->info['audio']['bits_per_sample'] : 16)); |
1552 } |
1840 } |
1553 } |
1841 } |
1554 return true; |
1842 return true; |
1555 } |
1843 } |
1556 |
1844 |
1557 |
1845 /** |
1846 * @return bool |
|
1847 */ |
|
1558 public function CalculateReplayGain() { |
1848 public function CalculateReplayGain() { |
1559 if (isset($this->info['replay_gain'])) { |
1849 if (isset($this->info['replay_gain'])) { |
1560 if (!isset($this->info['replay_gain']['reference_volume'])) { |
1850 if (!isset($this->info['replay_gain']['reference_volume'])) { |
1561 $this->info['replay_gain']['reference_volume'] = (double) 89.0; |
1851 $this->info['replay_gain']['reference_volume'] = 89.0; |
1562 } |
1852 } |
1563 if (isset($this->info['replay_gain']['track']['adjustment'])) { |
1853 if (isset($this->info['replay_gain']['track']['adjustment'])) { |
1564 $this->info['replay_gain']['track']['volume'] = $this->info['replay_gain']['reference_volume'] - $this->info['replay_gain']['track']['adjustment']; |
1854 $this->info['replay_gain']['track']['volume'] = $this->info['replay_gain']['reference_volume'] - $this->info['replay_gain']['track']['adjustment']; |
1565 } |
1855 } |
1566 if (isset($this->info['replay_gain']['album']['adjustment'])) { |
1856 if (isset($this->info['replay_gain']['album']['adjustment'])) { |
1575 } |
1865 } |
1576 } |
1866 } |
1577 return true; |
1867 return true; |
1578 } |
1868 } |
1579 |
1869 |
1870 /** |
|
1871 * @return bool |
|
1872 */ |
|
1580 public function ProcessAudioStreams() { |
1873 public function ProcessAudioStreams() { |
1581 if (!empty($this->info['audio']['bitrate']) || !empty($this->info['audio']['channels']) || !empty($this->info['audio']['sample_rate'])) { |
1874 if (!empty($this->info['audio']['bitrate']) || !empty($this->info['audio']['channels']) || !empty($this->info['audio']['sample_rate'])) { |
1582 if (!isset($this->info['audio']['streams'])) { |
1875 if (!isset($this->info['audio']['streams'])) { |
1583 foreach ($this->info['audio'] as $key => $value) { |
1876 foreach ($this->info['audio'] as $key => $value) { |
1584 if ($key != 'streams') { |
1877 if ($key != 'streams') { |
1588 } |
1881 } |
1589 } |
1882 } |
1590 return true; |
1883 return true; |
1591 } |
1884 } |
1592 |
1885 |
1886 /** |
|
1887 * @return string|bool |
|
1888 */ |
|
1593 public function getid3_tempnam() { |
1889 public function getid3_tempnam() { |
1594 return tempnam($this->tempdir, 'gI3'); |
1890 return tempnam($this->tempdir, 'gI3'); |
1595 } |
1891 } |
1596 |
1892 |
1893 /** |
|
1894 * @param string $name |
|
1895 * |
|
1896 * @return bool |
|
1897 * |
|
1898 * @throws getid3_exception |
|
1899 */ |
|
1597 public function include_module($name) { |
1900 public function include_module($name) { |
1598 //if (!file_exists($this->include_path.'module.'.$name.'.php')) { |
1901 //if (!file_exists($this->include_path.'module.'.$name.'.php')) { |
1599 if (!file_exists(GETID3_INCLUDEPATH.'module.'.$name.'.php')) { |
1902 if (!file_exists(GETID3_INCLUDEPATH.'module.'.$name.'.php')) { |
1600 throw new getid3_exception('Required module.'.$name.'.php is missing.'); |
1903 throw new getid3_exception('Required module.'.$name.'.php is missing.'); |
1601 } |
1904 } |
1602 include_once(GETID3_INCLUDEPATH.'module.'.$name.'.php'); |
1905 include_once(GETID3_INCLUDEPATH.'module.'.$name.'.php'); |
1603 return true; |
1906 return true; |
1604 } |
1907 } |
1605 |
1908 |
1606 public static function is_writable ($filename) { |
1909 /** |
1607 $ret = is_writable($filename); |
1910 * @param string $filename |
1608 |
1911 * |
1609 if (!$ret) { |
1912 * @return bool |
1610 $perms = fileperms($filename); |
1913 */ |
1611 $ret = ($perms & 0x0080) || ($perms & 0x0010) || ($perms & 0x0002); |
1914 public static function is_writable ($filename) { |
1612 } |
1915 $ret = is_writable($filename); |
1613 |
1916 if (!$ret) { |
1614 return $ret; |
1917 $perms = fileperms($filename); |
1615 } |
1918 $ret = ($perms & 0x0080) || ($perms & 0x0010) || ($perms & 0x0002); |
1919 } |
|
1920 return $ret; |
|
1921 } |
|
1616 |
1922 |
1617 } |
1923 } |
1618 |
1924 |
1619 |
1925 |
1620 abstract class getid3_handler { |
1926 abstract class getid3_handler |
1927 { |
|
1621 |
1928 |
1622 /** |
1929 /** |
1623 * @var getID3 |
1930 * @var getID3 |
1624 */ |
1931 */ |
1625 protected $getid3; // pointer |
1932 protected $getid3; // pointer |
1626 |
1933 |
1627 protected $data_string_flag = false; // analyzing filepointer or string |
1934 /** |
1628 protected $data_string = ''; // string to analyze |
1935 * Analyzing filepointer or string. |
1629 protected $data_string_position = 0; // seek position in string |
1936 * |
1630 protected $data_string_length = 0; // string length |
1937 * @var bool |
1631 |
1938 */ |
1632 private $dependency_to = null; |
1939 protected $data_string_flag = false; |
1633 |
1940 |
1634 |
1941 /** |
1942 * String to analyze. |
|
1943 * |
|
1944 * @var string |
|
1945 */ |
|
1946 protected $data_string = ''; |
|
1947 |
|
1948 /** |
|
1949 * Seek position in string. |
|
1950 * |
|
1951 * @var int |
|
1952 */ |
|
1953 protected $data_string_position = 0; |
|
1954 |
|
1955 /** |
|
1956 * String length. |
|
1957 * |
|
1958 * @var int |
|
1959 */ |
|
1960 protected $data_string_length = 0; |
|
1961 |
|
1962 /** |
|
1963 * @var string |
|
1964 */ |
|
1965 private $dependency_to; |
|
1966 |
|
1967 /** |
|
1968 * getid3_handler constructor. |
|
1969 * |
|
1970 * @param getID3 $getid3 |
|
1971 * @param string $call_module |
|
1972 */ |
|
1635 public function __construct(getID3 $getid3, $call_module=null) { |
1973 public function __construct(getID3 $getid3, $call_module=null) { |
1636 $this->getid3 = $getid3; |
1974 $this->getid3 = $getid3; |
1637 |
1975 |
1638 if ($call_module) { |
1976 if ($call_module) { |
1639 $this->dependency_to = str_replace('getid3_', '', $call_module); |
1977 $this->dependency_to = str_replace('getid3_', '', $call_module); |
1640 } |
1978 } |
1641 } |
1979 } |
1642 |
1980 |
1643 |
1981 /** |
1644 // Analyze from file pointer |
1982 * Analyze from file pointer. |
1983 * |
|
1984 * @return bool |
|
1985 */ |
|
1645 abstract public function Analyze(); |
1986 abstract public function Analyze(); |
1646 |
1987 |
1647 |
1988 /** |
1648 // Analyze from string instead |
1989 * Analyze from string instead. |
1990 * |
|
1991 * @param string $string |
|
1992 */ |
|
1649 public function AnalyzeString($string) { |
1993 public function AnalyzeString($string) { |
1650 // Enter string mode |
1994 // Enter string mode |
1651 $this->setStringMode($string); |
1995 $this->setStringMode($string); |
1652 |
1996 |
1653 // Save info |
1997 // Save info |
1669 |
2013 |
1670 // Exit string mode |
2014 // Exit string mode |
1671 $this->data_string_flag = false; |
2015 $this->data_string_flag = false; |
1672 } |
2016 } |
1673 |
2017 |
2018 /** |
|
2019 * @param string $string |
|
2020 */ |
|
1674 public function setStringMode($string) { |
2021 public function setStringMode($string) { |
1675 $this->data_string_flag = true; |
2022 $this->data_string_flag = true; |
1676 $this->data_string = $string; |
2023 $this->data_string = $string; |
1677 $this->data_string_length = strlen($string); |
2024 $this->data_string_length = strlen($string); |
1678 } |
2025 } |
1679 |
2026 |
2027 /** |
|
2028 * @return int|bool |
|
2029 */ |
|
1680 protected function ftell() { |
2030 protected function ftell() { |
1681 if ($this->data_string_flag) { |
2031 if ($this->data_string_flag) { |
1682 return $this->data_string_position; |
2032 return $this->data_string_position; |
1683 } |
2033 } |
1684 return ftell($this->getid3->fp); |
2034 return ftell($this->getid3->fp); |
1685 } |
2035 } |
1686 |
2036 |
2037 /** |
|
2038 * @param int $bytes |
|
2039 * |
|
2040 * @return string|false |
|
2041 * |
|
2042 * @throws getid3_exception |
|
2043 */ |
|
1687 protected function fread($bytes) { |
2044 protected function fread($bytes) { |
1688 if ($this->data_string_flag) { |
2045 if ($this->data_string_flag) { |
1689 $this->data_string_position += $bytes; |
2046 $this->data_string_position += $bytes; |
1690 return substr($this->data_string, $this->data_string_position - $bytes, $bytes); |
2047 return substr($this->data_string, $this->data_string_position - $bytes, $bytes); |
1691 } |
2048 } |
1694 throw new getid3_exception('cannot fread('.$bytes.' from '.$this->ftell().') because beyond PHP filesystem limit', 10); |
2051 throw new getid3_exception('cannot fread('.$bytes.' from '.$this->ftell().') because beyond PHP filesystem limit', 10); |
1695 } |
2052 } |
1696 |
2053 |
1697 //return fread($this->getid3->fp, $bytes); |
2054 //return fread($this->getid3->fp, $bytes); |
1698 /* |
2055 /* |
1699 * http://www.getid3.org/phpBB3/viewtopic.php?t=1930 |
2056 * https://www.getid3.org/phpBB3/viewtopic.php?t=1930 |
1700 * "I found out that the root cause for the problem was how getID3 uses the PHP system function fread(). |
2057 * "I found out that the root cause for the problem was how getID3 uses the PHP system function fread(). |
1701 * It seems to assume that fread() would always return as many bytes as were requested. |
2058 * It seems to assume that fread() would always return as many bytes as were requested. |
1702 * However, according the PHP manual (http://php.net/manual/en/function.fread.php), this is the case only with regular local files, but not e.g. with Linux pipes. |
2059 * However, according the PHP manual (http://php.net/manual/en/function.fread.php), this is the case only with regular local files, but not e.g. with Linux pipes. |
1703 * The call may return only part of the requested data and a new call is needed to get more." |
2060 * The call may return only part of the requested data and a new call is needed to get more." |
1704 */ |
2061 */ |
1705 $contents = ''; |
2062 $contents = ''; |
1706 do { |
2063 do { |
2064 //if (($this->getid3->memory_limit > 0) && ($bytes > $this->getid3->memory_limit)) { |
|
2065 if (($this->getid3->memory_limit > 0) && (($bytes / $this->getid3->memory_limit) > 0.99)) { // enable a more-fuzzy match to prevent close misses generating errors like "PHP Fatal error: Allowed memory size of 33554432 bytes exhausted (tried to allocate 33554464 bytes)" |
|
2066 throw new getid3_exception('cannot fread('.$bytes.' from '.$this->ftell().') that is more than available PHP memory ('.$this->getid3->memory_limit.')', 10); |
|
2067 } |
|
1707 $part = fread($this->getid3->fp, $bytes); |
2068 $part = fread($this->getid3->fp, $bytes); |
1708 $partLength = strlen($part); |
2069 $partLength = strlen($part); |
1709 $bytes -= $partLength; |
2070 $bytes -= $partLength; |
1710 $contents .= $part; |
2071 $contents .= $part; |
1711 } while (($bytes > 0) && ($partLength > 0)); |
2072 } while (($bytes > 0) && ($partLength > 0)); |
1712 return $contents; |
2073 return $contents; |
1713 } |
2074 } |
1714 |
2075 |
2076 /** |
|
2077 * @param int $bytes |
|
2078 * @param int $whence |
|
2079 * |
|
2080 * @return int |
|
2081 * |
|
2082 * @throws getid3_exception |
|
2083 */ |
|
1715 protected function fseek($bytes, $whence=SEEK_SET) { |
2084 protected function fseek($bytes, $whence=SEEK_SET) { |
1716 if ($this->data_string_flag) { |
2085 if ($this->data_string_flag) { |
1717 switch ($whence) { |
2086 switch ($whence) { |
1718 case SEEK_SET: |
2087 case SEEK_SET: |
1719 $this->data_string_position = $bytes; |
2088 $this->data_string_position = $bytes; |
1740 } |
2109 } |
1741 } |
2110 } |
1742 return fseek($this->getid3->fp, $bytes, $whence); |
2111 return fseek($this->getid3->fp, $bytes, $whence); |
1743 } |
2112 } |
1744 |
2113 |
2114 /** |
|
2115 * @return string|false |
|
2116 * |
|
2117 * @throws getid3_exception |
|
2118 */ |
|
2119 protected function fgets() { |
|
2120 // must be able to handle CR/LF/CRLF but not read more than one lineend |
|
2121 $buffer = ''; // final string we will return |
|
2122 $prevchar = ''; // save previously-read character for end-of-line checking |
|
2123 if ($this->data_string_flag) { |
|
2124 while (true) { |
|
2125 $thischar = substr($this->data_string, $this->data_string_position++, 1); |
|
2126 if (($prevchar == "\r") && ($thischar != "\n")) { |
|
2127 // read one byte too many, back up |
|
2128 $this->data_string_position--; |
|
2129 break; |
|
2130 } |
|
2131 $buffer .= $thischar; |
|
2132 if ($thischar == "\n") { |
|
2133 break; |
|
2134 } |
|
2135 if ($this->data_string_position >= $this->data_string_length) { |
|
2136 // EOF |
|
2137 break; |
|
2138 } |
|
2139 $prevchar = $thischar; |
|
2140 } |
|
2141 |
|
2142 } else { |
|
2143 |
|
2144 // Ideally we would just use PHP's fgets() function, however... |
|
2145 // it does not behave consistently with regards to mixed line endings, may be system-dependent |
|
2146 // and breaks entirely when given a file with mixed \r vs \n vs \r\n line endings (e.g. some PDFs) |
|
2147 //return fgets($this->getid3->fp); |
|
2148 while (true) { |
|
2149 $thischar = fgetc($this->getid3->fp); |
|
2150 if (($prevchar == "\r") && ($thischar != "\n")) { |
|
2151 // read one byte too many, back up |
|
2152 fseek($this->getid3->fp, -1, SEEK_CUR); |
|
2153 break; |
|
2154 } |
|
2155 $buffer .= $thischar; |
|
2156 if ($thischar == "\n") { |
|
2157 break; |
|
2158 } |
|
2159 if (feof($this->getid3->fp)) { |
|
2160 break; |
|
2161 } |
|
2162 $prevchar = $thischar; |
|
2163 } |
|
2164 |
|
2165 } |
|
2166 return $buffer; |
|
2167 } |
|
2168 |
|
2169 /** |
|
2170 * @return bool |
|
2171 */ |
|
1745 protected function feof() { |
2172 protected function feof() { |
1746 if ($this->data_string_flag) { |
2173 if ($this->data_string_flag) { |
1747 return $this->data_string_position >= $this->data_string_length; |
2174 return $this->data_string_position >= $this->data_string_length; |
1748 } |
2175 } |
1749 return feof($this->getid3->fp); |
2176 return feof($this->getid3->fp); |
1750 } |
2177 } |
1751 |
2178 |
2179 /** |
|
2180 * @param string $module |
|
2181 * |
|
2182 * @return bool |
|
2183 */ |
|
1752 final protected function isDependencyFor($module) { |
2184 final protected function isDependencyFor($module) { |
1753 return $this->dependency_to == $module; |
2185 return $this->dependency_to == $module; |
1754 } |
2186 } |
1755 |
2187 |
2188 /** |
|
2189 * @param string $text |
|
2190 * |
|
2191 * @return bool |
|
2192 */ |
|
1756 protected function error($text) { |
2193 protected function error($text) { |
1757 $this->getid3->info['error'][] = $text; |
2194 $this->getid3->info['error'][] = $text; |
1758 |
2195 |
1759 return false; |
2196 return false; |
1760 } |
2197 } |
1761 |
2198 |
2199 /** |
|
2200 * @param string $text |
|
2201 * |
|
2202 * @return bool |
|
2203 */ |
|
1762 protected function warning($text) { |
2204 protected function warning($text) { |
1763 return $this->getid3->warning($text); |
2205 return $this->getid3->warning($text); |
1764 } |
2206 } |
1765 |
2207 |
2208 /** |
|
2209 * @param string $text |
|
2210 */ |
|
1766 protected function notice($text) { |
2211 protected function notice($text) { |
1767 // does nothing for now |
2212 // does nothing for now |
1768 } |
2213 } |
1769 |
2214 |
2215 /** |
|
2216 * @param string $name |
|
2217 * @param int $offset |
|
2218 * @param int $length |
|
2219 * @param string $image_mime |
|
2220 * |
|
2221 * @return string|null |
|
2222 * |
|
2223 * @throws Exception |
|
2224 * @throws getid3_exception |
|
2225 */ |
|
1770 public function saveAttachment($name, $offset, $length, $image_mime=null) { |
2226 public function saveAttachment($name, $offset, $length, $image_mime=null) { |
1771 try { |
2227 try { |
1772 |
2228 |
1773 // do not extract at all |
2229 // do not extract at all |
1774 if ($this->getid3->option_save_attachments === getID3::ATTACHMENTS_NONE) { |
2230 if ($this->getid3->option_save_attachments === getID3::ATTACHMENTS_NONE) { |
1818 } catch (Exception $e) { |
2274 } catch (Exception $e) { |
1819 |
2275 |
1820 // close and remove dest file if created |
2276 // close and remove dest file if created |
1821 if (isset($fp_dest) && is_resource($fp_dest)) { |
2277 if (isset($fp_dest) && is_resource($fp_dest)) { |
1822 fclose($fp_dest); |
2278 fclose($fp_dest); |
2279 } |
|
2280 |
|
2281 if (isset($dest) && file_exists($dest)) { |
|
1823 unlink($dest); |
2282 unlink($dest); |
1824 } |
2283 } |
1825 |
2284 |
1826 // do not set any is case of error |
2285 // do not set any is case of error |
1827 $attachment = null; |
2286 $attachment = null; |