示例#1
0
 /**
  *
  * @return boolean
  */
 public function WriteVorbisComment()
 {
     if (preg_match('#(1|ON)#i', ini_get('safe_mode'))) {
         $this->errors[] = 'PHP running in Safe Mode (backtick operator not available) - cannot call vorbiscomment, tags not written';
         return false;
     }
     // Create file with new comments
     $tempcommentsfilename = tempnam(GetId3_GetId3::getTempDir(), 'getID3');
     if (is_writable($tempcommentsfilename) && is_file($tempcommentsfilename) && ($fpcomments = fopen($tempcommentsfilename, 'wb'))) {
         foreach ($this->tag_data as $key => $value) {
             foreach ($value as $commentdata) {
                 fwrite($fpcomments, $this->CleanVorbisCommentName($key) . '=' . $commentdata . "\n");
             }
         }
         fclose($fpcomments);
     } else {
         $this->errors[] = 'failed to open temporary tags file "' . $tempcommentsfilename . '", tags not written';
         return false;
     }
     $oldignoreuserabort = ignore_user_abort(true);
     if (GetId3_GetId3::environmentIsWindows()) {
         if (file_exists(GetId3_GetId3::getHelperAppsDir() . 'vorbiscomment.exe')) {
             //$commandline = '"'.GetId3::getHelperAppsDir().'vorbiscomment.exe" -w --raw -c "'.$tempcommentsfilename.'" "'.str_replace('/', '\\', $this->filename).'"';
             //  vorbiscomment works fine if you copy-paste the above commandline into a command prompt,
             //  but refuses to work with `backtick` if there are "doublequotes" present around BOTH
             //  the metaflac pathname and the target filename. For whatever reason...??
             //  The solution is simply ensure that the metaflac pathname has no spaces,
             //  and therefore does not need to be quoted
             // On top of that, if error messages are not always captured properly under Windows
             // To at least see if there was a problem, compare file modification timestamps before and after writing
             clearstatcache();
             $timestampbeforewriting = filemtime($this->filename);
             $commandline = GetId3_GetId3::getHelperAppsDir() . 'vorbiscomment.exe -w --raw -c "' . $tempcommentsfilename . '" "' . $this->filename . '" 2>&1';
             $VorbiscommentError = `{$commandline}`;
             if (empty($VorbiscommentError)) {
                 clearstatcache();
                 if ($timestampbeforewriting == filemtime($this->filename)) {
                     $VorbiscommentError = 'File modification timestamp has not changed - it looks like the tags were not written';
                 }
             }
         } else {
             $VorbiscommentError = 'vorbiscomment.exe not found in ' . GetId3_GetId3::getHelperAppsDir();
         }
     } else {
         $commandline = 'vorbiscomment -w --raw -c "' . $tempcommentsfilename . '" "' . $this->filename . '" 2>&1';
         $VorbiscommentError = `{$commandline}`;
     }
     // Remove temporary comments file
     unlink($tempcommentsfilename);
     ignore_user_abort($oldignoreuserabort);
     if (!empty($VorbiscommentError)) {
         $this->errors[] = 'system call to vorbiscomment failed with message: ' . "\n\n" . $VorbiscommentError;
         return false;
     }
     return true;
 }
示例#2
0
 /**
  *
  * @staticvar type $shorten_present
  * @return boolean
  */
 public function Analyze()
 {
     $info =& $this->getid3->info;
     fseek($this->getid3->fp, $info['avdataoffset'], SEEK_SET);
     $ShortenHeader = fread($this->getid3->fp, 8);
     $magic = 'ajkg';
     if (substr($ShortenHeader, 0, 4) != $magic) {
         $info['error'][] = 'Expecting "' . GetId3_Lib_Helper::PrintHexBytes($magic) . '" at offset ' . $info['avdataoffset'] . ', found "' . GetId3_Lib_Helper::PrintHexBytes(substr($ShortenHeader, 0, 4)) . '"';
         return false;
     }
     $info['fileformat'] = 'shn';
     $info['audio']['dataformat'] = 'shn';
     $info['audio']['lossless'] = true;
     $info['audio']['bitrate_mode'] = 'vbr';
     $info['shn']['version'] = GetId3_Lib_Helper::LittleEndian2Int(substr($ShortenHeader, 4, 1));
     fseek($this->getid3->fp, $info['avdataend'] - 12, SEEK_SET);
     $SeekTableSignatureTest = fread($this->getid3->fp, 12);
     $info['shn']['seektable']['present'] = (bool) (substr($SeekTableSignatureTest, 4, 8) == 'SHNAMPSK');
     if ($info['shn']['seektable']['present']) {
         $info['shn']['seektable']['length'] = GetId3_Lib_Helper::LittleEndian2Int(substr($SeekTableSignatureTest, 0, 4));
         $info['shn']['seektable']['offset'] = $info['avdataend'] - $info['shn']['seektable']['length'];
         fseek($this->getid3->fp, $info['shn']['seektable']['offset'], SEEK_SET);
         $SeekTableMagic = fread($this->getid3->fp, 4);
         $magic = 'SEEK';
         if ($SeekTableMagic != $magic) {
             $info['error'][] = 'Expecting "' . GetId3_Lib_Helper::PrintHexBytes($magic) . '" at offset ' . $info['shn']['seektable']['offset'] . ', found "' . GetId3_Lib_Helper::PrintHexBytes($SeekTableMagic) . '"';
             return false;
         } else {
             // typedef struct tag_TSeekEntry
             // {
             //   unsigned long SampleNumber;
             //   unsigned long SHNFileByteOffset;
             //   unsigned long SHNLastBufferReadPosition;
             //   unsigned short SHNByteGet;
             //   unsigned short SHNBufferOffset;
             //   unsigned short SHNFileBitOffset;
             //   unsigned long SHNGBuffer;
             //   unsigned short SHNBitShift;
             //   long CBuf0[3];
             //   long CBuf1[3];
             //   long Offset0[4];
             //   long Offset1[4];
             // }TSeekEntry;
             $SeekTableData = fread($this->getid3->fp, $info['shn']['seektable']['length'] - 16);
             $info['shn']['seektable']['entry_count'] = floor(strlen($SeekTableData) / 80);
             //$info['shn']['seektable']['entries'] = array();
             //$SeekTableOffset = 0;
             //for ($i = 0; $i < $info['shn']['seektable']['entry_count']; $i++) {
             //	$SeekTableEntry['sample_number'] = GetId3_lib::LittleEndian2Int(substr($SeekTableData, $SeekTableOffset, 4));
             //	$SeekTableOffset += 4;
             //	$SeekTableEntry['shn_file_byte_offset'] = GetId3_lib::LittleEndian2Int(substr($SeekTableData, $SeekTableOffset, 4));
             //	$SeekTableOffset += 4;
             //	$SeekTableEntry['shn_last_buffer_read_position'] = GetId3_lib::LittleEndian2Int(substr($SeekTableData, $SeekTableOffset, 4));
             //	$SeekTableOffset += 4;
             //	$SeekTableEntry['shn_byte_get'] = GetId3_lib::LittleEndian2Int(substr($SeekTableData, $SeekTableOffset, 2));
             //	$SeekTableOffset += 2;
             //	$SeekTableEntry['shn_buffer_offset'] = GetId3_lib::LittleEndian2Int(substr($SeekTableData, $SeekTableOffset, 2));
             //	$SeekTableOffset += 2;
             //	$SeekTableEntry['shn_file_bit_offset'] = GetId3_lib::LittleEndian2Int(substr($SeekTableData, $SeekTableOffset, 2));
             //	$SeekTableOffset += 2;
             //	$SeekTableEntry['shn_gbuffer'] = GetId3_lib::LittleEndian2Int(substr($SeekTableData, $SeekTableOffset, 4));
             //	$SeekTableOffset += 4;
             //	$SeekTableEntry['shn_bit_shift'] = GetId3_lib::LittleEndian2Int(substr($SeekTableData, $SeekTableOffset, 2));
             //	$SeekTableOffset += 2;
             //	for ($j = 0; $j < 3; $j++) {
             //		$SeekTableEntry['cbuf0'][$j] = GetId3_lib::LittleEndian2Int(substr($SeekTableData, $SeekTableOffset, 4));
             //		$SeekTableOffset += 4;
             //	}
             //	for ($j = 0; $j < 3; $j++) {
             //		$SeekTableEntry['cbuf1'][$j] = GetId3_lib::LittleEndian2Int(substr($SeekTableData, $SeekTableOffset, 4));
             //		$SeekTableOffset += 4;
             //	}
             //	for ($j = 0; $j < 4; $j++) {
             //		$SeekTableEntry['offset0'][$j] = GetId3_lib::LittleEndian2Int(substr($SeekTableData, $SeekTableOffset, 4));
             //		$SeekTableOffset += 4;
             //	}
             //	for ($j = 0; $j < 4; $j++) {
             //		$SeekTableEntry['offset1'][$j] = GetId3_lib::LittleEndian2Int(substr($SeekTableData, $SeekTableOffset, 4));
             //		$SeekTableOffset += 4;
             //	}
             //
             //	$info['shn']['seektable']['entries'][] = $SeekTableEntry;
             //}
         }
     }
     if (preg_match('#(1|ON)#i', ini_get('safe_mode'))) {
         $info['error'][] = 'PHP running in Safe Mode - backtick operator not available, cannot run shntool to analyze Shorten files';
         return false;
     }
     if (GetId3_GetId3::environmentIsWindows()) {
         $RequiredFiles = array('shorten.exe', 'cygwin1.dll', 'head.exe');
         foreach ($RequiredFiles as $required_file) {
             if (!is_readable(GetId3_GetId3::getHelperAppsDir() . $required_file)) {
                 $info['error'][] = GetId3_GetId3::getHelperAppsDir() . $required_file . ' does not exist';
                 return false;
             }
         }
         $commandline = GetId3_GetId3::getHelperAppsDir() . 'shorten.exe -x "' . $info['filenamepath'] . '" - | ' . GetId3_GetId3::getHelperAppsDir() . 'head.exe -c 64';
         $commandline = str_replace('/', '\\', $commandline);
     } else {
         static $shorten_present;
         if (!isset($shorten_present)) {
             $shorten_present = file_exists('/usr/local/bin/shorten') || `which shorten`;
         }
         if (!$shorten_present) {
             $info['error'][] = 'shorten binary was not found in path or /usr/local/bin';
             return false;
         }
         $commandline = (file_exists('/usr/local/bin/shorten') ? '/usr/local/bin/' : '') . 'shorten -x ' . escapeshellarg($info['filenamepath']) . ' - | head -c 64';
     }
     $output = `{$commandline}`;
     if (!empty($output) && substr($output, 12, 4) == 'fmt ') {
         $fmt_size = GetId3_Lib_Helper::LittleEndian2Int(substr($output, 16, 4));
         $DecodedWAVFORMATEX = GetId3_Module_AudioVideo_Riff::RIFFparseWAVEFORMATex(substr($output, 20, $fmt_size));
         $info['audio']['channels'] = $DecodedWAVFORMATEX['channels'];
         $info['audio']['bits_per_sample'] = $DecodedWAVFORMATEX['bits_per_sample'];
         $info['audio']['sample_rate'] = $DecodedWAVFORMATEX['sample_rate'];
         if (substr($output, 20 + $fmt_size, 4) == 'data') {
             $info['playtime_seconds'] = GetId3_Lib_Helper::LittleEndian2Int(substr($output, 20 + 4 + $fmt_size, 4)) / $DecodedWAVFORMATEX['raw']['nAvgBytesPerSec'];
         } else {
             $info['error'][] = 'shorten failed to decode DATA chunk to expected location, cannot determine playtime';
             return false;
         }
         $info['audio']['bitrate'] = ($info['avdataend'] - $info['avdataoffset']) / $info['playtime_seconds'] * 8;
     } else {
         $info['error'][] = 'shorten failed to decode file to WAV for parsing';
         return false;
     }
     return true;
 }
示例#3
0
 /**
  *
  * @return boolean
  */
 public function Analyze()
 {
     $info =& $this->getid3->info;
     $info['fileformat'] = 'jpg';
     $info['video']['dataformat'] = 'jpg';
     $info['video']['lossless'] = false;
     $info['video']['bits_per_sample'] = 24;
     $info['video']['pixel_aspect_ratio'] = (double) 1;
     fseek($this->getid3->fp, $info['avdataoffset'], SEEK_SET);
     $imageinfo = array();
     list($width, $height, $type) = GetId3_Lib_Helper::GetDataImageSize(fread($this->getid3->fp, $info['filesize']), $imageinfo);
     if (isset($imageinfo['APP13'])) {
         // http://php.net/iptcparse
         // http://www.sno.phy.queensu.ca/~phil/exiftool/TagNames/IPTC.html
         $iptc_parsed = iptcparse($imageinfo['APP13']);
         if (is_array($iptc_parsed)) {
             foreach ($iptc_parsed as $iptc_key_raw => $iptc_values) {
                 list($iptc_record, $iptc_tagkey) = explode('#', $iptc_key_raw);
                 $iptc_tagkey = intval(ltrim($iptc_tagkey, '0'));
                 foreach ($iptc_values as $key => $value) {
                     $IPTCrecordName = $this->IPTCrecordName($iptc_record);
                     $IPTCrecordTagName = $this->IPTCrecordTagName($iptc_record, $iptc_tagkey);
                     if (isset($info['iptc'][$IPTCrecordName][$IPTCrecordTagName])) {
                         $info['iptc'][$IPTCrecordName][$IPTCrecordTagName][] = $value;
                     } else {
                         $info['iptc'][$IPTCrecordName][$IPTCrecordTagName] = array($value);
                     }
                 }
             }
         }
     }
     $returnOK = false;
     switch ($type) {
         case IMG_JPG:
             $info['video']['resolution_x'] = $width;
             $info['video']['resolution_y'] = $height;
             if (isset($imageinfo['APP1'])) {
                 if (function_exists('exif_read_data')) {
                     if (substr($imageinfo['APP1'], 0, 4) == 'Exif') {
                         $info['jpg']['exif'] = @exif_read_data($info['filenamepath'], '', true, false);
                     } else {
                         $info['warning'][] = 'exif_read_data() cannot parse non-EXIF data in APP1 (expected "Exif", found "' . substr($imageinfo['APP1'], 0, 4) . '")';
                     }
                 } else {
                     $info['warning'][] = 'EXIF parsing only available when ' . (GetId3_GetId3::environmentIsWindows() ? 'php_exif.dll enabled' : 'compiled with --enable-exif');
                 }
             }
             $returnOK = true;
             break;
         default:
             break;
     }
     $cast_as_appropriate_keys = array('EXIF', 'IFD0', 'THUMBNAIL');
     foreach ($cast_as_appropriate_keys as $exif_key) {
         if (isset($info['jpg']['exif'][$exif_key])) {
             foreach ($info['jpg']['exif'][$exif_key] as $key => $value) {
                 $info['jpg']['exif'][$exif_key][$key] = $this->CastAsAppropriate($value);
             }
         }
     }
     if (isset($info['jpg']['exif']['GPS'])) {
         if (isset($info['jpg']['exif']['GPS']['GPSVersion'])) {
             for ($i = 0; $i < 4; $i++) {
                 $version_subparts[$i] = ord(substr($info['jpg']['exif']['GPS']['GPSVersion'], $i, 1));
             }
             $info['jpg']['exif']['GPS']['computed']['version'] = 'v' . implode('.', $version_subparts);
         }
         if (isset($info['jpg']['exif']['GPS']['GPSDateStamp'])) {
             $explodedGPSDateStamp = explode(':', $info['jpg']['exif']['GPS']['GPSDateStamp']);
             $computed_time[5] = isset($explodedGPSDateStamp[0]) ? $explodedGPSDateStamp[0] : '';
             $computed_time[3] = isset($explodedGPSDateStamp[1]) ? $explodedGPSDateStamp[1] : '';
             $computed_time[4] = isset($explodedGPSDateStamp[2]) ? $explodedGPSDateStamp[2] : '';
             if (function_exists('date_default_timezone_set')) {
                 date_default_timezone_set('UTC');
             } else {
                 ini_set('date.timezone', 'UTC');
             }
             $computed_time = array(0 => 0, 1 => 0, 2 => 0, 3 => 0, 4 => 0, 5 => 0);
             if (isset($info['jpg']['exif']['GPS']['GPSTimeStamp']) && is_array($info['jpg']['exif']['GPS']['GPSTimeStamp'])) {
                 foreach ($info['jpg']['exif']['GPS']['GPSTimeStamp'] as $key => $value) {
                     $computed_time[$key] = GetId3_Lib_Helper::DecimalizeFraction($value);
                 }
             }
             $info['jpg']['exif']['GPS']['computed']['timestamp'] = mktime($computed_time[0], $computed_time[1], $computed_time[2], $computed_time[3], $computed_time[4], $computed_time[5]);
         }
         if (isset($info['jpg']['exif']['GPS']['GPSLatitude']) && is_array($info['jpg']['exif']['GPS']['GPSLatitude'])) {
             $direction_multiplier = isset($info['jpg']['exif']['GPS']['GPSLatitudeRef']) && $info['jpg']['exif']['GPS']['GPSLatitudeRef'] == 'S' ? -1 : 1;
             foreach ($info['jpg']['exif']['GPS']['GPSLatitude'] as $key => $value) {
                 $computed_latitude[$key] = GetId3_Lib_Helper::DecimalizeFraction($value);
             }
             $info['jpg']['exif']['GPS']['computed']['latitude'] = $direction_multiplier * ($computed_latitude[0] + $computed_latitude[1] / 60 + $computed_latitude[2] / 3600);
         }
         if (isset($info['jpg']['exif']['GPS']['GPSLongitude']) && is_array($info['jpg']['exif']['GPS']['GPSLongitude'])) {
             $direction_multiplier = isset($info['jpg']['exif']['GPS']['GPSLongitudeRef']) && $info['jpg']['exif']['GPS']['GPSLongitudeRef'] == 'W' ? -1 : 1;
             foreach ($info['jpg']['exif']['GPS']['GPSLongitude'] as $key => $value) {
                 $computed_longitude[$key] = GetId3_Lib_Helper::DecimalizeFraction($value);
             }
             $info['jpg']['exif']['GPS']['computed']['longitude'] = $direction_multiplier * ($computed_longitude[0] + $computed_longitude[1] / 60 + $computed_longitude[2] / 3600);
         }
         if (isset($info['jpg']['exif']['GPS']['GPSAltitude'])) {
             $direction_multiplier = isset($info['jpg']['exif']['GPS']['GPSAltitudeRef']) && $info['jpg']['exif']['GPS']['GPSAltitudeRef'] === chr(1) ? -1 : 1;
             $info['jpg']['exif']['GPS']['computed']['altitude'] = $direction_multiplier * GetId3_Lib_Helper::DecimalizeFraction($info['jpg']['exif']['GPS']['GPSAltitude']);
         }
     }
     if (class_exists('GetId3_Module_Tag_Xmp')) {
         if (isset($info['filenamepath'])) {
             $image_xmp = new GetId3_Module_Tag_Xmp($info['filenamepath']);
             $xmp_raw = $image_xmp->getAllTags();
             foreach ($xmp_raw as $key => $value) {
                 list($subsection, $tagname) = explode(':', $key);
                 $info['xmp'][$subsection][$tagname] = $this->CastAsAppropriate($value);
             }
         }
     }
     if (!$returnOK) {
         unset($info['fileformat']);
         return false;
     }
     return true;
 }
示例#4
0
 /**
  *
  * @return boolean
  */
 public function DeleteMetaFLAC()
 {
     if (preg_match('#(1|ON)#i', ini_get('safe_mode'))) {
         $this->errors[] = 'PHP running in Safe Mode (backtick operator not available) - cannot call metaflac, tags not deleted';
         return false;
     }
     $oldignoreuserabort = ignore_user_abort(true);
     if (GetId3_GetId3::environmentIsWindows()) {
         if (file_exists(GetId3_GetId3::getHelperAppsDir() . 'metaflac.exe')) {
             // To at least see if there was a problem, compare file modification timestamps before and after writing
             clearstatcache();
             $timestampbeforewriting = filemtime($this->filename);
             $commandline = GetId3_GetId3::getHelperAppsDir() . 'metaflac.exe --remove-all-tags "' . $this->filename . '" 2>&1';
             $metaflacError = `{$commandline}`;
             if (empty($metaflacError)) {
                 clearstatcache();
                 if ($timestampbeforewriting == filemtime($this->filename)) {
                     $metaflacError = 'File modification timestamp has not changed - it looks like the tags were not deleted';
                 }
             }
         } else {
             $metaflacError = 'metaflac.exe not found in ' . GetId3_GetId3::getHelperAppsDir();
         }
     } else {
         // It's simpler on *nix
         $commandline = 'metaflac --remove-all-tags "' . $this->filename . '" 2>&1';
         $metaflacError = `{$commandline}`;
     }
     ignore_user_abort($oldignoreuserabort);
     if (!empty($metaflacError)) {
         $this->errors[] = 'System call to metaflac failed with this message returned: ' . "\n\n" . $metaflacError;
         return false;
     }
     return true;
 }