ILIAS  release_5-2 Revision v5.2.25-18-g3f80b828510
GetId3\Write\Real Class Reference

GetId3() by James Heinrich info@.nosp@m.geti.nosp@m.d3.or.nosp@m.g //. More...

+ Collaboration diagram for GetId3\Write\Real:

Public Member Functions

 __construct ()
 
 WriteReal ()
 
 GenerateRMFchunk (&$chunks)
 
 GeneratePROPchunk (&$chunks, &$new_CONT_tag_data)
 
 GenerateCONTchunk ()
 
 RemoveReal ()
 

Data Fields

 $filename
 
 $tag_data = array()
 
 $fread_buffer_size = 32768
 
 $warnings = array()
 
 $errors = array()
 
 $paddedlength = 512
 

Detailed Description

GetId3() by James Heinrich info@.nosp@m.geti.nosp@m.d3.or.nosp@m.g //.

module for writing RealAudio/RealVideo tags

Author
James Heinrich info@.nosp@m.geti.nosp@m.d3.or.nosp@m.g http://www.getid3.org

Definition at line 29 of file Real.php.

Constructor & Destructor Documentation

◆ __construct()

GetId3\Write\Real::__construct ( )
Returns
boolean

Definition at line 66 of file Real.php.

67  {
68  return true;
69  }

Member Function Documentation

◆ GenerateCONTchunk()

GetId3\Write\Real::GenerateCONTchunk ( )
Returns
string

Definition at line 258 of file Real.php.

References GetId3\Lib\Helper\BigEndian2String().

Referenced by GetId3\Write\Real\WriteReal().

259  {
260  foreach ($this->tag_data as $key => $value) {
261  // limit each value to 0xFFFF bytes
262  $this->tag_data[$key] = substr($value, 0, 65535);
263  }
264 
265  $CONTchunk = "\x00\x00"; // object version
266 
267  $CONTchunk .= Helper::BigEndian2String((!empty($this->tag_data['title']) ? strlen($this->tag_data['title']) : 0), 2);
268  $CONTchunk .= (!empty($this->tag_data['title']) ? strlen($this->tag_data['title']) : '');
269 
270  $CONTchunk .= Helper::BigEndian2String((!empty($this->tag_data['artist']) ? strlen($this->tag_data['artist']) : 0), 2);
271  $CONTchunk .= (!empty($this->tag_data['artist']) ? strlen($this->tag_data['artist']) : '');
272 
273  $CONTchunk .= Helper::BigEndian2String((!empty($this->tag_data['copyright']) ? strlen($this->tag_data['copyright']) : 0), 2);
274  $CONTchunk .= (!empty($this->tag_data['copyright']) ? strlen($this->tag_data['copyright']) : '');
275 
276  $CONTchunk .= Helper::BigEndian2String((!empty($this->tag_data['comment']) ? strlen($this->tag_data['comment']) : 0), 2);
277  $CONTchunk .= (!empty($this->tag_data['comment']) ? strlen($this->tag_data['comment']) : '');
278 
279  if ($this->paddedlength > (strlen($CONTchunk) + 8)) {
280  $CONTchunk .= str_repeat("\x00", $this->paddedlength - strlen($CONTchunk) - 8);
281  }
282 
283  $CONTchunk = 'CONT'.Helper::BigEndian2String(strlen($CONTchunk) + 8, 4).$CONTchunk; // CONT chunk identifier + chunk length
284 
285  return $CONTchunk;
286  }
static BigEndian2String($number, $minbytes=1, $synchsafe=false, $signed=false)
Definition: Helper.php:444
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ GeneratePROPchunk()

GetId3\Write\Real::GeneratePROPchunk ( $chunks,
$new_CONT_tag_data 
)
Parameters
type$chunks
type$new_CONT_tag_data
Returns
string

Definition at line 215 of file Real.php.

References GetId3\Lib\Helper\BigEndian2String().

Referenced by GetId3\Write\Real\WriteReal().

216  {
217  $old_CONT_length = 0;
218  $old_DATA_offset = 0;
219  $old_INDX_offset = 0;
220  foreach ($chunks as $key => $chunk) {
221  $chunkNameKeys[$chunk['name']] = $key;
222  if ($chunk['name'] == 'CONT') {
223  $old_CONT_length = $chunk['length'];
224  } elseif ($chunk['name'] == 'DATA') {
225  if (!$old_DATA_offset) {
226  $old_DATA_offset = $chunk['offset'];
227  }
228  } elseif ($chunk['name'] == 'INDX') {
229  if (!$old_INDX_offset) {
230  $old_INDX_offset = $chunk['offset'];
231  }
232  }
233  }
234  $CONTdelta = strlen($new_CONT_tag_data) - $old_CONT_length;
235 
236  $PROPchunk = "\x00\x00"; // object version
237  $PROPchunk .= Helper::BigEndian2String($chunks[$chunkNameKeys['PROP']]['max_bit_rate'], 4);
238  $PROPchunk .= Helper::BigEndian2String($chunks[$chunkNameKeys['PROP']]['avg_bit_rate'], 4);
239  $PROPchunk .= Helper::BigEndian2String($chunks[$chunkNameKeys['PROP']]['max_packet_size'], 4);
240  $PROPchunk .= Helper::BigEndian2String($chunks[$chunkNameKeys['PROP']]['avg_packet_size'], 4);
241  $PROPchunk .= Helper::BigEndian2String($chunks[$chunkNameKeys['PROP']]['num_packets'], 4);
242  $PROPchunk .= Helper::BigEndian2String($chunks[$chunkNameKeys['PROP']]['duration'], 4);
243  $PROPchunk .= Helper::BigEndian2String($chunks[$chunkNameKeys['PROP']]['preroll'], 4);
244  $PROPchunk .= Helper::BigEndian2String(max(0, $old_INDX_offset + $CONTdelta), 4);
245  $PROPchunk .= Helper::BigEndian2String(max(0, $old_DATA_offset + $CONTdelta), 4);
246  $PROPchunk .= Helper::BigEndian2String($chunks[$chunkNameKeys['PROP']]['num_streams'], 2);
247  $PROPchunk .= Helper::BigEndian2String($chunks[$chunkNameKeys['PROP']]['flags_raw'], 2);
248 
249  $PROPchunk = 'PROP'.Helper::BigEndian2String(strlen($PROPchunk) + 8, 4).$PROPchunk; // PROP chunk identifier + chunk length
250 
251  return $PROPchunk;
252  }
static BigEndian2String($number, $minbytes=1, $synchsafe=false, $signed=false)
Definition: Helper.php:444
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ GenerateRMFchunk()

GetId3\Write\Real::GenerateRMFchunk ( $chunks)
Parameters
type$chunks
Returns
string

Definition at line 189 of file Real.php.

References GetId3\Lib\Helper\BigEndian2String().

Referenced by GetId3\Write\Real\WriteReal().

190  {
191  $oldCONTexists = false;
192  foreach ($chunks as $key => $chunk) {
193  $chunkNameKeys[$chunk['name']] = $key;
194  if ($chunk['name'] == 'CONT') {
195  $oldCONTexists = true;
196  }
197  }
198  $newHeadersCount = $chunks[$chunkNameKeys['.RMF']]['headers_count'] + ($oldCONTexists ? 0 : 1);
199 
200  $RMFchunk = "\x00\x00"; // object version
201  $RMFchunk .= Helper::BigEndian2String($chunks[$chunkNameKeys['.RMF']]['file_version'], 4);
202  $RMFchunk .= Helper::BigEndian2String($newHeadersCount, 4);
203 
204  $RMFchunk = '.RMF'.Helper::BigEndian2String(strlen($RMFchunk) + 8, 4).$RMFchunk; // .RMF chunk identifier + chunk length
205 
206  return $RMFchunk;
207  }
static BigEndian2String($number, $minbytes=1, $synchsafe=false, $signed=false)
Definition: Helper.php:444
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ RemoveReal()

GetId3\Write\Real::RemoveReal ( )
Returns
boolean

Definition at line 292 of file Real.php.

References GetId3\GetId3Core\getTempDir().

293  {
294  // File MUST be writeable - CHMOD(646) at least
295  if (is_writeable($this->filename) && is_file($this->filename) && ($fp_source = fopen($this->filename, 'r+b'))) {
296 
297  // Initialize GetId3 engine
298  $getID3 = new GetId3Core();
299  $OldThisFileInfo = $getID3->analyze($this->filename);
300  if (empty($OldThisFileInfo['real']['chunks']) && !empty($OldThisFileInfo['real']['old_ra_header'])) {
301  $this->errors[] = 'Cannot remove Real tags from old-style file format';
302  fclose($fp_source);
303 
304  return false;
305  }
306 
307  if (empty($OldThisFileInfo['real']['chunks'])) {
308  $this->errors[] = 'Cannot remove Real tags because cannot find DATA chunk in file';
309  fclose($fp_source);
310 
311  return false;
312  }
313  foreach ($OldThisFileInfo['real']['chunks'] as $chunknumber => $chunkarray) {
314  $oldChunkInfo[$chunkarray['name']] = $chunkarray;
315  }
316 
317  if (empty($oldChunkInfo['CONT'])) {
318  // no existing CONT chunk
319  fclose($fp_source);
320 
321  return true;
322  }
323 
324  $BeforeOffset = $oldChunkInfo['CONT']['offset'];
325  $AfterOffset = $oldChunkInfo['CONT']['offset'] + $oldChunkInfo['CONT']['length'];
326  if ($tempfilename = tempnam(GetId3Core::getTempDir(), 'getID3')) {
327  if (is_writable($tempfilename) && is_file($tempfilename) && ($fp_temp = fopen($tempfilename, 'wb'))) {
328 
329  rewind($fp_source);
330  fwrite($fp_temp, fread($fp_source, $BeforeOffset));
331  fseek($fp_source, $AfterOffset, SEEK_SET);
332  while ($buffer = fread($fp_source, $this->fread_buffer_size)) {
333  fwrite($fp_temp, $buffer, strlen($buffer));
334  }
335  fclose($fp_temp);
336 
337  if (copy($tempfilename, $this->filename)) {
338  unlink($tempfilename);
339  fclose($fp_source);
340 
341  return true;
342  }
343  unlink($tempfilename);
344  $this->errors[] = 'FAILED: copy('.$tempfilename.', '.$this->filename.')';
345 
346  } else {
347  $this->errors[] = 'Could not fopen("'.$tempfilename.'", "wb")';
348  }
349  }
350  fclose($fp_source);
351 
352  return false;
353  }
354  $this->errors[] = 'Could not fopen("'.$this->filename.'", "r+b")';
355 
356  return false;
357  }
+ Here is the call graph for this function:

◆ WriteReal()

GetId3\Write\Real::WriteReal ( )
Returns
boolean

Definition at line 75 of file Real.php.

References GetId3\Write\Real\GenerateCONTchunk(), GetId3\Write\Real\GeneratePROPchunk(), GetId3\Write\Real\GenerateRMFchunk(), and GetId3\GetId3Core\getTempDir().

76  {
77  // File MUST be writeable - CHMOD(646) at least
78  if (is_writeable($this->filename) && is_file($this->filename) && ($fp_source = fopen($this->filename, 'r+b'))) {
79 
80  // Initialize GetId3 engine
81  $getID3 = new GetId3Core();
82  $OldThisFileInfo = $getID3->analyze($this->filename);
83  if (empty($OldThisFileInfo['real']['chunks']) && !empty($OldThisFileInfo['real']['old_ra_header'])) {
84  $this->errors[] = 'Cannot write Real tags on old-style file format';
85  fclose($fp_source);
86 
87  return false;
88  }
89 
90  if (empty($OldThisFileInfo['real']['chunks'])) {
91  $this->errors[] = 'Cannot write Real tags because cannot find DATA chunk in file';
92  fclose($fp_source);
93 
94  return false;
95  }
96  foreach ($OldThisFileInfo['real']['chunks'] as $chunknumber => $chunkarray) {
97  $oldChunkInfo[$chunkarray['name']] = $chunkarray;
98  }
99  if (!empty($oldChunkInfo['CONT']['length'])) {
100  $this->paddedlength = max($oldChunkInfo['CONT']['length'], $this->paddedlength);
101  }
102 
103  $new_CONT_tag_data = $this->GenerateCONTchunk();
104  $new_PROP_tag_data = $this->GeneratePROPchunk($OldThisFileInfo['real']['chunks'], $new_CONT_tag_data);
105  $new__RMF_tag_data = $this->GenerateRMFchunk($OldThisFileInfo['real']['chunks']);
106 
107  if (isset($oldChunkInfo['.RMF']['length']) && ($oldChunkInfo['.RMF']['length'] == strlen($new__RMF_tag_data))) {
108  fseek($fp_source, $oldChunkInfo['.RMF']['offset'], SEEK_SET);
109  fwrite($fp_source, $new__RMF_tag_data);
110  } else {
111  $this->errors[] = 'new .RMF tag ('.strlen($new__RMF_tag_data).' bytes) different length than old .RMF tag ('.$oldChunkInfo['.RMF']['length'].' bytes)';
112  fclose($fp_source);
113 
114  return false;
115  }
116 
117  if (isset($oldChunkInfo['PROP']['length']) && ($oldChunkInfo['PROP']['length'] == strlen($new_PROP_tag_data))) {
118  fseek($fp_source, $oldChunkInfo['PROP']['offset'], SEEK_SET);
119  fwrite($fp_source, $new_PROP_tag_data);
120  } else {
121  $this->errors[] = 'new PROP tag ('.strlen($new_PROP_tag_data).' bytes) different length than old PROP tag ('.$oldChunkInfo['PROP']['length'].' bytes)';
122  fclose($fp_source);
123 
124  return false;
125  }
126 
127  if (isset($oldChunkInfo['CONT']['length']) && ($oldChunkInfo['CONT']['length'] == strlen($new_CONT_tag_data))) {
128 
129  // new data length is same as old data length - just overwrite
130  fseek($fp_source, $oldChunkInfo['CONT']['offset'], SEEK_SET);
131  fwrite($fp_source, $new_CONT_tag_data);
132  fclose($fp_source);
133 
134  return true;
135 
136  } else {
137 
138  if (empty($oldChunkInfo['CONT'])) {
139  // no existing CONT chunk
140  $BeforeOffset = $oldChunkInfo['DATA']['offset'];
141  $AfterOffset = $oldChunkInfo['DATA']['offset'];
142  } else {
143  // new data is longer than old data
144  $BeforeOffset = $oldChunkInfo['CONT']['offset'];
145  $AfterOffset = $oldChunkInfo['CONT']['offset'] + $oldChunkInfo['CONT']['length'];
146  }
147  if ($tempfilename = tempnam(GetId3Core::getTempDir(), 'getID3')) {
148  if (is_writable($tempfilename) && is_file($tempfilename) && ($fp_temp = fopen($tempfilename, 'wb'))) {
149 
150  rewind($fp_source);
151  fwrite($fp_temp, fread($fp_source, $BeforeOffset));
152  fwrite($fp_temp, $new_CONT_tag_data);
153  fseek($fp_source, $AfterOffset, SEEK_SET);
154  while ($buffer = fread($fp_source, $this->fread_buffer_size)) {
155  fwrite($fp_temp, $buffer, strlen($buffer));
156  }
157  fclose($fp_temp);
158 
159  if (copy($tempfilename, $this->filename)) {
160  unlink($tempfilename);
161  fclose($fp_source);
162 
163  return true;
164  }
165  unlink($tempfilename);
166  $this->errors[] = 'FAILED: copy('.$tempfilename.', '.$this->filename.')';
167 
168  } else {
169  $this->errors[] = 'Could not fopen("'.$tempfilename.'", "wb")';
170  }
171  }
172  fclose($fp_source);
173 
174  return false;
175 
176  }
177 
178  }
179  $this->errors[] = 'Could not fopen("'.$this->filename.'", "r+b")';
180 
181  return false;
182  }
GeneratePROPchunk(&$chunks, &$new_CONT_tag_data)
Definition: Real.php:215
GenerateRMFchunk(&$chunks)
Definition: Real.php:189
+ Here is the call graph for this function:

Field Documentation

◆ $errors

GetId3\Write\Real::$errors = array()

Definition at line 55 of file Real.php.

◆ $filename

GetId3\Write\Real::$filename

Definition at line 35 of file Real.php.

◆ $fread_buffer_size

GetId3\Write\Real::$fread_buffer_size = 32768

Definition at line 45 of file Real.php.

◆ $paddedlength

GetId3\Write\Real::$paddedlength = 512

Definition at line 60 of file Real.php.

◆ $tag_data

GetId3\Write\Real::$tag_data = array()

Definition at line 40 of file Real.php.

◆ $warnings

GetId3\Write\Real::$warnings = array()

Definition at line 50 of file Real.php.


The documentation for this class was generated from the following file: