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.

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

References GetId3\Lib\Helper\BigEndian2String().

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

+ 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.

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 }

References GetId3\Lib\Helper\BigEndian2String().

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

+ 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.

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 }

References GetId3\Lib\Helper\BigEndian2String().

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

+ 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.

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 }

References GetId3\GetId3Core\getTempDir().

+ Here is the call graph for this function:

◆ WriteReal()

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

Definition at line 75 of file Real.php.

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 }
GenerateRMFchunk(&$chunks)
Definition: Real.php:189
GeneratePROPchunk(&$chunks, &$new_CONT_tag_data)
Definition: Real.php:215

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

+ 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: