| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295 | 
							- <?php
 
- /////////////////////////////////////////////////////////////////
 
- /// getID3() by James Heinrich <info@getid3.org>               //
 
- //  available at http://getid3.sourceforge.net                 //
 
- //            or http://www.getid3.org                         //
 
- /////////////////////////////////////////////////////////////////
 
- // 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 $filename;
 
- 	var $tag_data     = array();
 
- 	var $warnings     = array(); // any non-critical errors will be stored here
 
- 	var $errors       = array(); // any critical errors will be stored here
 
- 	var $paddedlength = 512;     // minimum length of CONT tag in bytes
 
- 	function getid3_write_real() {
 
- 		return true;
 
- 	}
 
- 	function WriteReal() {
 
- 		// File MUST be writeable - CHMOD(646) at least
 
- 		if (is_writeable($this->filename)) {
 
- 			if ($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;
 
- 				}
 
- 				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 (@$oldChunkInfo['.RMF']['length'] == strlen($new__RMF_tag_data)) {
 
- 					fseek($fp_source, $oldChunkInfo['.RMF']['offset'], SEEK_SET);
 
- 					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 (@$oldChunkInfo['PROP']['length'] == strlen($new_PROP_tag_data)) {
 
- 					fseek($fp_source, $oldChunkInfo['PROP']['offset'], SEEK_SET);
 
- 					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 (@$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'], SEEK_SET);
 
- 					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')) {
 
- 						ob_start();
 
- 						if ($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, SEEK_SET);
 
- 							while ($buffer = fread($fp_source, GETID3_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.') - '.strip_tags(ob_get_contents());
 
- 						} else {
 
- 							$this->errors[] = 'Could not open '.$tempfilename.' mode "wb" - '.strip_tags(ob_get_contents());
 
- 						}
 
- 						ob_end_clean();
 
- 					}
 
- 					fclose($fp_source);
 
- 					return false;
 
- 				}
 
- 			} else {
 
- 				$this->errors[] = 'Could not open '.$this->filename.' mode "r+b"';
 
- 				return false;
 
- 			}
 
- 		}
 
- 		$this->errors[] = 'File is not writeable: '.$this->filename;
 
- 		return false;
 
- 	}
 
- 	function GenerateRMFchunk(&$chunks) {
 
- 		$oldCONTexists = false;
 
- 		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;
 
- 	}
 
- 	function GeneratePROPchunk(&$chunks, &$new_CONT_tag_data) {
 
- 		$old_CONT_length = 0;
 
- 		$old_DATA_offset = 0;
 
- 		$old_INDX_offset = 0;
 
- 		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;
 
- 	}
 
- 	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(strlen(@$this->tag_data['title']), 2);
 
- 		$CONTchunk .= @$this->tag_data['title'];
 
- 		$CONTchunk .= getid3_lib::BigEndian2String(strlen(@$this->tag_data['artist']), 2);
 
- 		$CONTchunk .= @$this->tag_data['artist'];
 
- 		$CONTchunk .= getid3_lib::BigEndian2String(strlen(@$this->tag_data['copyright']), 2);
 
- 		$CONTchunk .= @$this->tag_data['copyright'];
 
- 		$CONTchunk .= getid3_lib::BigEndian2String(strlen(@$this->tag_data['comment']), 2);
 
- 		$CONTchunk .= @$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;
 
- 	}
 
- 	function RemoveReal() {
 
- 		// File MUST be writeable - CHMOD(646) at least
 
- 		if (is_writeable($this->filename)) {
 
- 			if ($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;
 
- 				}
 
- 				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')) {
 
- 					ob_start();
 
- 					if ($fp_temp = fopen($tempfilename, 'wb')) {
 
- 						rewind($fp_source);
 
- 						fwrite($fp_temp, fread($fp_source, $BeforeOffset));
 
- 						fseek($fp_source, $AfterOffset, SEEK_SET);
 
- 						while ($buffer = fread($fp_source, GETID3_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.') - '.strip_tags(ob_get_contents());
 
- 					} else {
 
- 						$this->errors[] = 'Could not open '.$tempfilename.' mode "wb" - '.strip_tags(ob_get_contents());
 
- 					}
 
- 					ob_end_clean();
 
- 				}
 
- 				fclose($fp_source);
 
- 				return false;
 
- 			} else {
 
- 				$this->errors[] = 'Could not open '.$this->filename.' mode "r+b"';
 
- 				return false;
 
- 			}
 
- 		}
 
- 		$this->errors[] = 'File is not writeable: '.$this->filename;
 
- 		return false;
 
- 	}
 
- }
 
- ?>
 
 
  |