芝麻web文件管理V1.00
编辑当前文件:/home/mgatv524/lot.mgaplay.com.br/vendor/james-heinrich/getid3/getid3/write.real.php
// // available at https://github.com/JamesHeinrich/getID3 // // or https://www.getid3.org // // or http://getid3.sourceforge.net // // see readme.txt for more details // ///////////////////////////////////////////////////////////////// // // // write.real.php // // module for writing RealAudio/RealVideo tags // // dependencies: module.tag.real.php // // /// ///////////////////////////////////////////////////////////////// class getid3_write_real { /** * @var string */ public $filename; /** * @var array */ public $tag_data = array(); /** * Read buffer size in bytes. * * @var int */ public $fread_buffer_size = 32768; /** * Any non-critical errors will be stored here. * * @var array */ public $warnings = array(); /** * Any critical errors will be stored here. * * @var array */ public $errors = array(); /** * Minimum length of CONT tag in bytes. * * @var int */ public $paddedlength = 512; public function __construct() { } /** * @return bool */ public function WriteReal() { // File MUST be writeable - CHMOD(646) at least if (getID3::is_writable($this->filename) && is_file($this->filename) && ($fp_source = fopen($this->filename, 'r+b'))) { // Initialize getID3 engine $getID3 = new getID3; $OldThisFileInfo = $getID3->analyze($this->filename); if (empty($OldThisFileInfo['real']['chunks']) && !empty($OldThisFileInfo['real']['old_ra_header'])) { $this->errors[] = 'Cannot write Real tags on old-style file format'; fclose($fp_source); return false; } if (empty($OldThisFileInfo['real']['chunks'])) { $this->errors[] = 'Cannot write Real tags because cannot find DATA chunk in file'; fclose($fp_source); return false; } $oldChunkInfo = array(); foreach ($OldThisFileInfo['real']['chunks'] as $chunknumber => $chunkarray) { $oldChunkInfo[$chunkarray['name']] = $chunkarray; } if (!empty($oldChunkInfo['CONT']['length'])) { $this->paddedlength = max($oldChunkInfo['CONT']['length'], $this->paddedlength); } $new_CONT_tag_data = $this->GenerateCONTchunk(); $new_PROP_tag_data = $this->GeneratePROPchunk($OldThisFileInfo['real']['chunks'], $new_CONT_tag_data); $new__RMF_tag_data = $this->GenerateRMFchunk($OldThisFileInfo['real']['chunks']); if (isset($oldChunkInfo['.RMF']['length']) && ($oldChunkInfo['.RMF']['length'] == strlen($new__RMF_tag_data))) { fseek($fp_source, $oldChunkInfo['.RMF']['offset']); fwrite($fp_source, $new__RMF_tag_data); } else { $this->errors[] = 'new .RMF tag ('.strlen($new__RMF_tag_data).' bytes) different length than old .RMF tag ('.$oldChunkInfo['.RMF']['length'].' bytes)'; fclose($fp_source); return false; } if (isset($oldChunkInfo['PROP']['length']) && ($oldChunkInfo['PROP']['length'] == strlen($new_PROP_tag_data))) { fseek($fp_source, $oldChunkInfo['PROP']['offset']); fwrite($fp_source, $new_PROP_tag_data); } else { $this->errors[] = 'new PROP tag ('.strlen($new_PROP_tag_data).' bytes) different length than old PROP tag ('.$oldChunkInfo['PROP']['length'].' bytes)'; fclose($fp_source); return false; } if (isset($oldChunkInfo['CONT']['length']) && ($oldChunkInfo['CONT']['length'] == strlen($new_CONT_tag_data))) { // new data length is same as old data length - just overwrite fseek($fp_source, $oldChunkInfo['CONT']['offset']); fwrite($fp_source, $new_CONT_tag_data); fclose($fp_source); return true; } else { if (empty($oldChunkInfo['CONT'])) { // no existing CONT chunk $BeforeOffset = $oldChunkInfo['DATA']['offset']; $AfterOffset = $oldChunkInfo['DATA']['offset']; } else { // new data is longer than old data $BeforeOffset = $oldChunkInfo['CONT']['offset']; $AfterOffset = $oldChunkInfo['CONT']['offset'] + $oldChunkInfo['CONT']['length']; } if ($tempfilename = tempnam(GETID3_TEMP_DIR, 'getID3')) { if (getID3::is_writable($tempfilename) && is_file($tempfilename) && ($fp_temp = fopen($tempfilename, 'wb'))) { rewind($fp_source); fwrite($fp_temp, fread($fp_source, $BeforeOffset)); fwrite($fp_temp, $new_CONT_tag_data); fseek($fp_source, $AfterOffset); while ($buffer = fread($fp_source, $this->fread_buffer_size)) { fwrite($fp_temp, $buffer, strlen($buffer)); } fclose($fp_temp); if (copy($tempfilename, $this->filename)) { unlink($tempfilename); fclose($fp_source); return true; } unlink($tempfilename); $this->errors[] = 'FAILED: copy('.$tempfilename.', '.$this->filename.')'; } else { $this->errors[] = 'Could not fopen("'.$tempfilename.'", "wb")'; } } fclose($fp_source); return false; } } $this->errors[] = 'Could not fopen("'.$this->filename.'", "r+b")'; return false; } /** * @param array $chunks * * @return string */ public function GenerateRMFchunk(&$chunks) { $oldCONTexists = false; $chunkNameKeys = array(); foreach ($chunks as $key => $chunk) { $chunkNameKeys[$chunk['name']] = $key; if ($chunk['name'] == 'CONT') { $oldCONTexists = true; } } $newHeadersCount = $chunks[$chunkNameKeys['.RMF']]['headers_count'] + ($oldCONTexists ? 0 : 1); $RMFchunk = "\x00\x00"; // object version $RMFchunk .= getid3_lib::BigEndian2String($chunks[$chunkNameKeys['.RMF']]['file_version'], 4); $RMFchunk .= getid3_lib::BigEndian2String($newHeadersCount, 4); $RMFchunk = '.RMF'.getid3_lib::BigEndian2String(strlen($RMFchunk) + 8, 4).$RMFchunk; // .RMF chunk identifier + chunk length return $RMFchunk; } /** * @param array $chunks * @param string $new_CONT_tag_data * * @return string */ public function GeneratePROPchunk(&$chunks, &$new_CONT_tag_data) { $old_CONT_length = 0; $old_DATA_offset = 0; $old_INDX_offset = 0; $chunkNameKeys = array(); foreach ($chunks as $key => $chunk) { $chunkNameKeys[$chunk['name']] = $key; if ($chunk['name'] == 'CONT') { $old_CONT_length = $chunk['length']; } elseif ($chunk['name'] == 'DATA') { if (!$old_DATA_offset) { $old_DATA_offset = $chunk['offset']; } } elseif ($chunk['name'] == 'INDX') { if (!$old_INDX_offset) { $old_INDX_offset = $chunk['offset']; } } } $CONTdelta = strlen($new_CONT_tag_data) - $old_CONT_length; $PROPchunk = "\x00\x00"; // object version $PROPchunk .= getid3_lib::BigEndian2String($chunks[$chunkNameKeys['PROP']]['max_bit_rate'], 4); $PROPchunk .= getid3_lib::BigEndian2String($chunks[$chunkNameKeys['PROP']]['avg_bit_rate'], 4); $PROPchunk .= getid3_lib::BigEndian2String($chunks[$chunkNameKeys['PROP']]['max_packet_size'], 4); $PROPchunk .= getid3_lib::BigEndian2String($chunks[$chunkNameKeys['PROP']]['avg_packet_size'], 4); $PROPchunk .= getid3_lib::BigEndian2String($chunks[$chunkNameKeys['PROP']]['num_packets'], 4); $PROPchunk .= getid3_lib::BigEndian2String($chunks[$chunkNameKeys['PROP']]['duration'], 4); $PROPchunk .= getid3_lib::BigEndian2String($chunks[$chunkNameKeys['PROP']]['preroll'], 4); $PROPchunk .= getid3_lib::BigEndian2String(max(0, $old_INDX_offset + $CONTdelta), 4); $PROPchunk .= getid3_lib::BigEndian2String(max(0, $old_DATA_offset + $CONTdelta), 4); $PROPchunk .= getid3_lib::BigEndian2String($chunks[$chunkNameKeys['PROP']]['num_streams'], 2); $PROPchunk .= getid3_lib::BigEndian2String($chunks[$chunkNameKeys['PROP']]['flags_raw'], 2); $PROPchunk = 'PROP'.getid3_lib::BigEndian2String(strlen($PROPchunk) + 8, 4).$PROPchunk; // PROP chunk identifier + chunk length return $PROPchunk; } /** * @return string */ public function GenerateCONTchunk() { foreach ($this->tag_data as $key => $value) { // limit each value to 0xFFFF bytes $this->tag_data[$key] = substr($value, 0, 65535); } $CONTchunk = "\x00\x00"; // object version $CONTchunk .= getid3_lib::BigEndian2String((!empty($this->tag_data['title']) ? strlen($this->tag_data['title']) : 0), 2); $CONTchunk .= (!empty($this->tag_data['title']) ? strlen($this->tag_data['title']) : ''); $CONTchunk .= getid3_lib::BigEndian2String((!empty($this->tag_data['artist']) ? strlen($this->tag_data['artist']) : 0), 2); $CONTchunk .= (!empty($this->tag_data['artist']) ? strlen($this->tag_data['artist']) : ''); $CONTchunk .= getid3_lib::BigEndian2String((!empty($this->tag_data['copyright']) ? strlen($this->tag_data['copyright']) : 0), 2); $CONTchunk .= (!empty($this->tag_data['copyright']) ? strlen($this->tag_data['copyright']) : ''); $CONTchunk .= getid3_lib::BigEndian2String((!empty($this->tag_data['comment']) ? strlen($this->tag_data['comment']) : 0), 2); $CONTchunk .= (!empty($this->tag_data['comment']) ? strlen($this->tag_data['comment']) : ''); if ($this->paddedlength > (strlen($CONTchunk) + 8)) { $CONTchunk .= str_repeat("\x00", $this->paddedlength - strlen($CONTchunk) - 8); } $CONTchunk = 'CONT'.getid3_lib::BigEndian2String(strlen($CONTchunk) + 8, 4).$CONTchunk; // CONT chunk identifier + chunk length return $CONTchunk; } /** * @return bool */ public function RemoveReal() { // File MUST be writeable - CHMOD(646) at least if (getID3::is_writable($this->filename) && is_file($this->filename) && ($fp_source = fopen($this->filename, 'r+b'))) { // Initialize getID3 engine $getID3 = new getID3; $OldThisFileInfo = $getID3->analyze($this->filename); if (empty($OldThisFileInfo['real']['chunks']) && !empty($OldThisFileInfo['real']['old_ra_header'])) { $this->errors[] = 'Cannot remove Real tags from old-style file format'; fclose($fp_source); return false; } if (empty($OldThisFileInfo['real']['chunks'])) { $this->errors[] = 'Cannot remove Real tags because cannot find DATA chunk in file'; fclose($fp_source); return false; } $oldChunkInfo = array(); foreach ($OldThisFileInfo['real']['chunks'] as $chunknumber => $chunkarray) { $oldChunkInfo[$chunkarray['name']] = $chunkarray; } if (empty($oldChunkInfo['CONT'])) { // no existing CONT chunk fclose($fp_source); return true; } $BeforeOffset = $oldChunkInfo['CONT']['offset']; $AfterOffset = $oldChunkInfo['CONT']['offset'] + $oldChunkInfo['CONT']['length']; if ($tempfilename = tempnam(GETID3_TEMP_DIR, 'getID3')) { if (getID3::is_writable($tempfilename) && is_file($tempfilename) && ($fp_temp = fopen($tempfilename, 'wb'))) { rewind($fp_source); fwrite($fp_temp, fread($fp_source, $BeforeOffset)); fseek($fp_source, $AfterOffset); while ($buffer = fread($fp_source, $this->fread_buffer_size)) { fwrite($fp_temp, $buffer, strlen($buffer)); } fclose($fp_temp); if (copy($tempfilename, $this->filename)) { unlink($tempfilename); fclose($fp_source); return true; } unlink($tempfilename); $this->errors[] = 'FAILED: copy('.$tempfilename.', '.$this->filename.')'; } else { $this->errors[] = 'Could not fopen("'.$tempfilename.'", "wb")'; } } fclose($fp_source); return false; } $this->errors[] = 'Could not fopen("'.$this->filename.'", "r+b")'; return false; } }