PowerPress Podcasting plugin by Blubrry - Version 5.0.6

Version Description

  • Released on 4/3/3014
  • Added logic to deal with the WP Super Cache plugin adding HTML comments at the bottom of feeds. Setting to allow HTML comments with a note have been added to the Feed settings page.
  • Added logic to deal with the W3 Total Cache plugin adding HTML comments at the bottom of feeds. Uses same setting as above.
  • Added logic for Verify feature to ignore PHP Warning messages caused by other plugins.
  • Added minified versions of the player and mejs javascript files. (Thanks idleberg for the suggestion)
  • Added the riff module to getid3 library (thanks Kathy for reporting the riff error)
  • Fixed bug with Blubrry media hosting screen, selecting already published media not returning to the post edit screen (Thanks Paul for making us aware of the bug)
  • Fixed notice message found in powerpressadmin-defaults.php (thanks sbmorrissey for bringing to our attention)
  • Added support for future MultiSite features.
  • Tested compatibility with WordPress 3.9.
Download this release

Release Info

Developer amandato
Plugin Icon 128x128 PowerPress Podcasting plugin by Blubrry
Version 5.0.6
Comparing to
See all releases

Code changes from version 5.0.5 to 5.0.6

getid3/module.audio-video.riff.php ADDED
@@ -0,0 +1,2409 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /////////////////////////////////////////////////////////////////
3
+ /// getID3() by James Heinrich <info@getid3.org> //
4
+ // available at http://getid3.sourceforge.net //
5
+ // or http://www.getid3.org //
6
+ /////////////////////////////////////////////////////////////////
7
+ // See readme.txt for more details //
8
+ /////////////////////////////////////////////////////////////////
9
+ // //
10
+ // module.audio-video.riff.php //
11
+ // module for analyzing RIFF files //
12
+ // multiple formats supported by this module: //
13
+ // Wave, AVI, AIFF/AIFC, (MP3,AC3)/RIFF, Wavpack v3, 8SVX //
14
+ // dependencies: module.audio.mp3.php //
15
+ // module.audio.ac3.php (optional) //
16
+ // module.audio.dts.php (optional) //
17
+ // ///
18
+ /////////////////////////////////////////////////////////////////
19
+
20
+ getid3_lib::IncludeDependency(GETID3_INCLUDEPATH.'module.audio.mp3.php', __FILE__, true);
21
+
22
+ class getid3_riff extends getid3_handler
23
+ {
24
+
25
+ function Analyze() {
26
+ $info = &$this->getid3->info;
27
+
28
+ // initialize these values to an empty array, otherwise they default to NULL
29
+ // and you can't append array values to a NULL value
30
+ $info['riff'] = array('raw'=>array());
31
+
32
+ // Shortcuts
33
+ $thisfile_riff = &$info['riff'];
34
+ $thisfile_riff_raw = &$thisfile_riff['raw'];
35
+ $thisfile_audio = &$info['audio'];
36
+ $thisfile_video = &$info['video'];
37
+ $thisfile_audio_dataformat = &$thisfile_audio['dataformat'];
38
+ $thisfile_riff_audio = &$thisfile_riff['audio'];
39
+ $thisfile_riff_video = &$thisfile_riff['video'];
40
+
41
+
42
+ $Original['avdataoffset'] = $info['avdataoffset'];
43
+ $Original['avdataend'] = $info['avdataend'];
44
+
45
+ fseek($this->getid3->fp, $info['avdataoffset'], SEEK_SET);
46
+ $RIFFheader = fread($this->getid3->fp, 12);
47
+ $RIFFsubtype = substr($RIFFheader, 8, 4);
48
+ switch (substr($RIFFheader, 0, 4)) {
49
+ case 'FORM':
50
+ $info['fileformat'] = 'aiff';
51
+ $thisfile_riff['header_size'] = $this->EitherEndian2Int(substr($RIFFheader, 4, 4));
52
+ $thisfile_riff[$RIFFsubtype] = $this->ParseRIFF($info['avdataoffset'] + 12, $info['avdataoffset'] + $thisfile_riff['header_size']);
53
+ break;
54
+
55
+ case 'RIFF': // AVI, WAV, etc
56
+ case 'SDSS': // SDSS is identical to RIFF, just renamed. Used by SmartSound QuickTracks (www.smartsound.com)
57
+ case 'RMP3': // RMP3 is identical to RIFF, just renamed. Used by [unknown program] when creating RIFF-MP3s
58
+ $info['fileformat'] = 'riff';
59
+ $thisfile_riff['header_size'] = $this->EitherEndian2Int(substr($RIFFheader, 4, 4));
60
+ if ($RIFFsubtype == 'RMP3') {
61
+ // RMP3 is identical to WAVE, just renamed. Used by [unknown program] when creating RIFF-MP3s
62
+ $RIFFsubtype = 'WAVE';
63
+ }
64
+ $thisfile_riff[$RIFFsubtype] = $this->ParseRIFF($info['avdataoffset'] + 12, $info['avdataoffset'] + $thisfile_riff['header_size']);
65
+ if (($info['avdataend'] - $info['filesize']) == 1) {
66
+ // LiteWave appears to incorrectly *not* pad actual output file
67
+ // to nearest WORD boundary so may appear to be short by one
68
+ // byte, in which case - skip warning
69
+ $info['avdataend'] = $info['filesize'];
70
+ }
71
+
72
+ $nextRIFFoffset = $Original['avdataoffset'] + 8 + $thisfile_riff['header_size']; // 8 = "RIFF" + 32-bit offset
73
+ while ($nextRIFFoffset < min($info['filesize'], $info['avdataend'])) {
74
+ if (!getid3_lib::intValueSupported($nextRIFFoffset + 1024)) {
75
+ $info['error'][] = 'AVI extends beyond '.round(PHP_INT_MAX / 1073741824).'GB and PHP filesystem functions cannot read that far, playtime is probably wrong';
76
+ $info['warning'][] = '[avdataend] value may be incorrect, multiple AVIX chunks may be present';
77
+ break;
78
+ } else {
79
+ fseek($this->getid3->fp, $nextRIFFoffset, SEEK_SET);
80
+ $nextRIFFheader = fread($this->getid3->fp, 12);
81
+ if ($nextRIFFoffset == ($info['avdataend'] - 1)) {
82
+ if (substr($nextRIFFheader, 0, 1) == "\x00") {
83
+ // RIFF padded to WORD boundary, we're actually already at the end
84
+ break;
85
+ }
86
+ }
87
+ $nextRIFFheaderID = substr($nextRIFFheader, 0, 4);
88
+ $nextRIFFsize = $this->EitherEndian2Int(substr($nextRIFFheader, 4, 4));
89
+ $nextRIFFtype = substr($nextRIFFheader, 8, 4);
90
+ $chunkdata = array();
91
+ $chunkdata['offset'] = $nextRIFFoffset + 8;
92
+ $chunkdata['size'] = $nextRIFFsize;
93
+ $nextRIFFoffset = $chunkdata['offset'] + $chunkdata['size'];
94
+ switch ($nextRIFFheaderID) {
95
+ case 'RIFF':
96
+ $info['avdataend'] = $nextRIFFoffset;
97
+ if (!getid3_lib::intValueSupported($info['avdataend'])) {
98
+ $info['error'][] = 'AVI extends beyond '.round(PHP_INT_MAX / 1073741824).'GB and PHP filesystem functions cannot read that far, playtime is probably wrong';
99
+ $info['warning'][] = '[avdataend] value may be incorrect, multiple AVIX chunks may be present';
100
+ }
101
+ $chunkdata['chunks'] = $this->ParseRIFF($chunkdata['offset'] + 4, $chunkdata['offset'] + $chunkdata['size']);
102
+
103
+ if (!isset($thisfile_riff[$nextRIFFtype])) {
104
+ $thisfile_riff[$nextRIFFtype] = array();
105
+ }
106
+ $thisfile_riff[$nextRIFFtype][] = $chunkdata;
107
+ break;
108
+ case 'JUNK':
109
+ // ignore
110
+ $thisfile_riff[$nextRIFFheaderID][] = $chunkdata;
111
+ break;
112
+ default:
113
+ if ($info['filesize'] == ($chunkdata['offset'] - 8 + 128)) {
114
+ $DIVXTAG = $nextRIFFheader.fread($this->getid3->fp, 128 - 12);
115
+ if (substr($DIVXTAG, -7) == 'DIVXTAG') {
116
+ // DIVXTAG is supposed to be inside an IDVX chunk in a LIST chunk, but some bad encoders just slap it on the end of a file
117
+ $info['warning'][] = 'Found wrongly-structured DIVXTAG at offset '.(ftell($this->getid3->fp) - 128 + 12).', parsing anyway';
118
+ $thisfile_riff['DIVXTAG'] = $this->ParseDIVXTAG($DIVXTAG);
119
+ foreach ($thisfile_riff['DIVXTAG'] as $key => $value) {
120
+ if ($value && !preg_match('#_id$#', $key)) {
121
+ $thisfile_riff['comments'][$key][] = $value;
122
+ }
123
+ }
124
+ break 2;
125
+ }
126
+ }
127
+ $info['warning'][] = 'expecting "RIFF" or "JUNK" at '.$nextRIFFoffset.', found '.getid3_lib::PrintHexBytes(substr($nextRIFFheader, 0, 4)).' - skipping rest of file';
128
+ break 2;
129
+ }
130
+ }
131
+ }
132
+ if ($RIFFsubtype == 'WAVE') {
133
+ $thisfile_riff_WAVE = &$thisfile_riff['WAVE'];
134
+ }
135
+ break;
136
+
137
+ default:
138
+ $info['error'][] = 'Cannot parse RIFF (this is maybe not a RIFF / WAV / AVI file?) - expecting "FORM|RIFF|SDSS|RMP3" found "'.$RIFFsubtype.'" instead';
139
+ unset($info['fileformat']);
140
+ return false;
141
+ break;
142
+ }
143
+
144
+ $streamindex = 0;
145
+ switch ($RIFFsubtype) {
146
+ case 'WAVE':
147
+ if (empty($thisfile_audio['bitrate_mode'])) {
148
+ $thisfile_audio['bitrate_mode'] = 'cbr';
149
+ }
150
+ if (empty($thisfile_audio_dataformat)) {
151
+ $thisfile_audio_dataformat = 'wav';
152
+ }
153
+
154
+ if (isset($thisfile_riff_WAVE['data'][0]['offset'])) {
155
+ $info['avdataoffset'] = $thisfile_riff_WAVE['data'][0]['offset'] + 8;
156
+ $info['avdataend'] = $info['avdataoffset'] + $thisfile_riff_WAVE['data'][0]['size'];
157
+ }
158
+ if (isset($thisfile_riff_WAVE['fmt '][0]['data'])) {
159
+
160
+ $thisfile_riff_audio[$streamindex] = getid3_riff::RIFFparseWAVEFORMATex($thisfile_riff_WAVE['fmt '][0]['data']);
161
+ $thisfile_audio['wformattag'] = $thisfile_riff_audio[$streamindex]['raw']['wFormatTag'];
162
+ if (!isset($thisfile_riff_audio[$streamindex]['bitrate']) || ($thisfile_riff_audio[$streamindex]['bitrate'] == 0)) {
163
+ $info['error'][] = 'Corrupt RIFF file: bitrate_audio == zero';
164
+ return false;
165
+ }
166
+ $thisfile_riff_raw['fmt '] = $thisfile_riff_audio[$streamindex]['raw'];
167
+ unset($thisfile_riff_audio[$streamindex]['raw']);
168
+ $thisfile_audio['streams'][$streamindex] = $thisfile_riff_audio[$streamindex];
169
+
170
+ $thisfile_audio = getid3_lib::array_merge_noclobber($thisfile_audio, $thisfile_riff_audio[$streamindex]);
171
+ if (substr($thisfile_audio['codec'], 0, strlen('unknown: 0x')) == 'unknown: 0x') {
172
+ $info['warning'][] = 'Audio codec = '.$thisfile_audio['codec'];
173
+ }
174
+ $thisfile_audio['bitrate'] = $thisfile_riff_audio[$streamindex]['bitrate'];
175
+
176
+ $info['playtime_seconds'] = (float) ((($info['avdataend'] - $info['avdataoffset']) * 8) / $thisfile_audio['bitrate']);
177
+
178
+ $thisfile_audio['lossless'] = false;
179
+ if (isset($thisfile_riff_WAVE['data'][0]['offset']) && isset($thisfile_riff_raw['fmt ']['wFormatTag'])) {
180
+ switch ($thisfile_riff_raw['fmt ']['wFormatTag']) {
181
+
182
+ case 0x0001: // PCM
183
+ $thisfile_audio['lossless'] = true;
184
+ break;
185
+
186
+ case 0x2000: // AC-3
187
+ $thisfile_audio_dataformat = 'ac3';
188
+ break;
189
+
190
+ default:
191
+ // do nothing
192
+ break;
193
+
194
+ }
195
+ }
196
+ $thisfile_audio['streams'][$streamindex]['wformattag'] = $thisfile_audio['wformattag'];
197
+ $thisfile_audio['streams'][$streamindex]['bitrate_mode'] = $thisfile_audio['bitrate_mode'];
198
+ $thisfile_audio['streams'][$streamindex]['lossless'] = $thisfile_audio['lossless'];
199
+ $thisfile_audio['streams'][$streamindex]['dataformat'] = $thisfile_audio_dataformat;
200
+ }
201
+
202
+ if (isset($thisfile_riff_WAVE['rgad'][0]['data'])) {
203
+
204
+ // shortcuts
205
+ $rgadData = &$thisfile_riff_WAVE['rgad'][0]['data'];
206
+ $thisfile_riff_raw['rgad'] = array('track'=>array(), 'album'=>array());
207
+ $thisfile_riff_raw_rgad = &$thisfile_riff_raw['rgad'];
208
+ $thisfile_riff_raw_rgad_track = &$thisfile_riff_raw_rgad['track'];
209
+ $thisfile_riff_raw_rgad_album = &$thisfile_riff_raw_rgad['album'];
210
+
211
+ $thisfile_riff_raw_rgad['fPeakAmplitude'] = getid3_lib::LittleEndian2Float(substr($rgadData, 0, 4));
212
+ $thisfile_riff_raw_rgad['nRadioRgAdjust'] = $this->EitherEndian2Int(substr($rgadData, 4, 2));
213
+ $thisfile_riff_raw_rgad['nAudiophileRgAdjust'] = $this->EitherEndian2Int(substr($rgadData, 6, 2));
214
+
215
+ $nRadioRgAdjustBitstring = str_pad(getid3_lib::Dec2Bin($thisfile_riff_raw_rgad['nRadioRgAdjust']), 16, '0', STR_PAD_LEFT);
216
+ $nAudiophileRgAdjustBitstring = str_pad(getid3_lib::Dec2Bin($thisfile_riff_raw_rgad['nAudiophileRgAdjust']), 16, '0', STR_PAD_LEFT);
217
+ $thisfile_riff_raw_rgad_track['name'] = getid3_lib::Bin2Dec(substr($nRadioRgAdjustBitstring, 0, 3));
218
+ $thisfile_riff_raw_rgad_track['originator'] = getid3_lib::Bin2Dec(substr($nRadioRgAdjustBitstring, 3, 3));
219
+ $thisfile_riff_raw_rgad_track['signbit'] = getid3_lib::Bin2Dec(substr($nRadioRgAdjustBitstring, 6, 1));
220
+ $thisfile_riff_raw_rgad_track['adjustment'] = getid3_lib::Bin2Dec(substr($nRadioRgAdjustBitstring, 7, 9));
221
+ $thisfile_riff_raw_rgad_album['name'] = getid3_lib::Bin2Dec(substr($nAudiophileRgAdjustBitstring, 0, 3));
222
+ $thisfile_riff_raw_rgad_album['originator'] = getid3_lib::Bin2Dec(substr($nAudiophileRgAdjustBitstring, 3, 3));
223
+ $thisfile_riff_raw_rgad_album['signbit'] = getid3_lib::Bin2Dec(substr($nAudiophileRgAdjustBitstring, 6, 1));
224
+ $thisfile_riff_raw_rgad_album['adjustment'] = getid3_lib::Bin2Dec(substr($nAudiophileRgAdjustBitstring, 7, 9));
225
+
226
+ $thisfile_riff['rgad']['peakamplitude'] = $thisfile_riff_raw_rgad['fPeakAmplitude'];
227
+ if (($thisfile_riff_raw_rgad_track['name'] != 0) && ($thisfile_riff_raw_rgad_track['originator'] != 0)) {
228
+ $thisfile_riff['rgad']['track']['name'] = getid3_lib::RGADnameLookup($thisfile_riff_raw_rgad_track['name']);
229
+ $thisfile_riff['rgad']['track']['originator'] = getid3_lib::RGADoriginatorLookup($thisfile_riff_raw_rgad_track['originator']);
230
+ $thisfile_riff['rgad']['track']['adjustment'] = getid3_lib::RGADadjustmentLookup($thisfile_riff_raw_rgad_track['adjustment'], $thisfile_riff_raw_rgad_track['signbit']);
231
+ }
232
+ if (($thisfile_riff_raw_rgad_album['name'] != 0) && ($thisfile_riff_raw_rgad_album['originator'] != 0)) {
233
+ $thisfile_riff['rgad']['album']['name'] = getid3_lib::RGADnameLookup($thisfile_riff_raw_rgad_album['name']);
234
+ $thisfile_riff['rgad']['album']['originator'] = getid3_lib::RGADoriginatorLookup($thisfile_riff_raw_rgad_album['originator']);
235
+ $thisfile_riff['rgad']['album']['adjustment'] = getid3_lib::RGADadjustmentLookup($thisfile_riff_raw_rgad_album['adjustment'], $thisfile_riff_raw_rgad_album['signbit']);
236
+ }
237
+ }
238
+
239
+ if (isset($thisfile_riff_WAVE['fact'][0]['data'])) {
240
+ $thisfile_riff_raw['fact']['NumberOfSamples'] = $this->EitherEndian2Int(substr($thisfile_riff_WAVE['fact'][0]['data'], 0, 4));
241
+
242
+ // This should be a good way of calculating exact playtime,
243
+ // but some sample files have had incorrect number of samples,
244
+ // so cannot use this method
245
+
246
+ // if (!empty($thisfile_riff_raw['fmt ']['nSamplesPerSec'])) {
247
+ // $info['playtime_seconds'] = (float) $thisfile_riff_raw['fact']['NumberOfSamples'] / $thisfile_riff_raw['fmt ']['nSamplesPerSec'];
248
+ // }
249
+ }
250
+ if (!empty($thisfile_riff_raw['fmt ']['nAvgBytesPerSec'])) {
251
+ $thisfile_audio['bitrate'] = getid3_lib::CastAsInt($thisfile_riff_raw['fmt ']['nAvgBytesPerSec'] * 8);
252
+ }
253
+
254
+ if (isset($thisfile_riff_WAVE['bext'][0]['data'])) {
255
+ // shortcut
256
+ $thisfile_riff_WAVE_bext_0 = &$thisfile_riff_WAVE['bext'][0];
257
+
258
+ $thisfile_riff_WAVE_bext_0['title'] = trim(substr($thisfile_riff_WAVE_bext_0['data'], 0, 256));
259
+ $thisfile_riff_WAVE_bext_0['author'] = trim(substr($thisfile_riff_WAVE_bext_0['data'], 256, 32));
260
+ $thisfile_riff_WAVE_bext_0['reference'] = trim(substr($thisfile_riff_WAVE_bext_0['data'], 288, 32));
261
+ $thisfile_riff_WAVE_bext_0['origin_date'] = substr($thisfile_riff_WAVE_bext_0['data'], 320, 10);
262
+ $thisfile_riff_WAVE_bext_0['origin_time'] = substr($thisfile_riff_WAVE_bext_0['data'], 330, 8);
263
+ $thisfile_riff_WAVE_bext_0['time_reference'] = getid3_lib::LittleEndian2Int(substr($thisfile_riff_WAVE_bext_0['data'], 338, 8));
264
+ $thisfile_riff_WAVE_bext_0['bwf_version'] = getid3_lib::LittleEndian2Int(substr($thisfile_riff_WAVE_bext_0['data'], 346, 1));
265
+ $thisfile_riff_WAVE_bext_0['reserved'] = substr($thisfile_riff_WAVE_bext_0['data'], 347, 254);
266
+ $thisfile_riff_WAVE_bext_0['coding_history'] = explode("\r\n", trim(substr($thisfile_riff_WAVE_bext_0['data'], 601)));
267
+ if (preg_match('#^([0-9]{4}).([0-9]{2}).([0-9]{2})$#', $thisfile_riff_WAVE_bext_0['origin_date'], $matches_bext_date)) {
268
+ if (preg_match('#^([0-9]{2}).([0-9]{2}).([0-9]{2})$#', $thisfile_riff_WAVE_bext_0['origin_time'], $matches_bext_time)) {
269
+ list($dummy, $bext_timestamp['year'], $bext_timestamp['month'], $bext_timestamp['day']) = $matches_bext_date;
270
+ list($dummy, $bext_timestamp['hour'], $bext_timestamp['minute'], $bext_timestamp['second']) = $matches_bext_time;
271
+ $thisfile_riff_WAVE_bext_0['origin_date_unix'] = gmmktime($bext_timestamp['hour'], $bext_timestamp['minute'], $bext_timestamp['second'], $bext_timestamp['month'], $bext_timestamp['day'], $bext_timestamp['year']);
272
+ } else {
273
+ $info['warning'][] = 'RIFF.WAVE.BEXT.origin_time is invalid';
274
+ }
275
+ } else {
276
+ $info['warning'][] = 'RIFF.WAVE.BEXT.origin_date is invalid';
277
+ }
278
+ $thisfile_riff['comments']['author'][] = $thisfile_riff_WAVE_bext_0['author'];
279
+ $thisfile_riff['comments']['title'][] = $thisfile_riff_WAVE_bext_0['title'];
280
+ }
281
+
282
+ if (isset($thisfile_riff_WAVE['MEXT'][0]['data'])) {
283
+ // shortcut
284
+ $thisfile_riff_WAVE_MEXT_0 = &$thisfile_riff_WAVE['MEXT'][0];
285
+
286
+ $thisfile_riff_WAVE_MEXT_0['raw']['sound_information'] = getid3_lib::LittleEndian2Int(substr($thisfile_riff_WAVE_MEXT_0['data'], 0, 2));
287
+ $thisfile_riff_WAVE_MEXT_0['flags']['homogenous'] = (bool) ($thisfile_riff_WAVE_MEXT_0['raw']['sound_information'] & 0x0001);
288
+ if ($thisfile_riff_WAVE_MEXT_0['flags']['homogenous']) {
289
+ $thisfile_riff_WAVE_MEXT_0['flags']['padding'] = ($thisfile_riff_WAVE_MEXT_0['raw']['sound_information'] & 0x0002) ? false : true;
290
+ $thisfile_riff_WAVE_MEXT_0['flags']['22_or_44'] = (bool) ($thisfile_riff_WAVE_MEXT_0['raw']['sound_information'] & 0x0004);
291
+ $thisfile_riff_WAVE_MEXT_0['flags']['free_format'] = (bool) ($thisfile_riff_WAVE_MEXT_0['raw']['sound_information'] & 0x0008);
292
+
293
+ $thisfile_riff_WAVE_MEXT_0['nominal_frame_size'] = getid3_lib::LittleEndian2Int(substr($thisfile_riff_WAVE_MEXT_0['data'], 2, 2));
294
+ }
295
+ $thisfile_riff_WAVE_MEXT_0['anciliary_data_length'] = getid3_lib::LittleEndian2Int(substr($thisfile_riff_WAVE_MEXT_0['data'], 6, 2));
296
+ $thisfile_riff_WAVE_MEXT_0['raw']['anciliary_data_def'] = getid3_lib::LittleEndian2Int(substr($thisfile_riff_WAVE_MEXT_0['data'], 8, 2));
297
+ $thisfile_riff_WAVE_MEXT_0['flags']['anciliary_data_left'] = (bool) ($thisfile_riff_WAVE_MEXT_0['raw']['anciliary_data_def'] & 0x0001);
298
+ $thisfile_riff_WAVE_MEXT_0['flags']['anciliary_data_free'] = (bool) ($thisfile_riff_WAVE_MEXT_0['raw']['anciliary_data_def'] & 0x0002);
299
+ $thisfile_riff_WAVE_MEXT_0['flags']['anciliary_data_right'] = (bool) ($thisfile_riff_WAVE_MEXT_0['raw']['anciliary_data_def'] & 0x0004);
300
+ }
301
+
302
+ if (isset($thisfile_riff_WAVE['cart'][0]['data'])) {
303
+ // shortcut
304
+ $thisfile_riff_WAVE_cart_0 = &$thisfile_riff_WAVE['cart'][0];
305
+
306
+ $thisfile_riff_WAVE_cart_0['version'] = substr($thisfile_riff_WAVE_cart_0['data'], 0, 4);
307
+ $thisfile_riff_WAVE_cart_0['title'] = trim(substr($thisfile_riff_WAVE_cart_0['data'], 4, 64));
308
+ $thisfile_riff_WAVE_cart_0['artist'] = trim(substr($thisfile_riff_WAVE_cart_0['data'], 68, 64));
309
+ $thisfile_riff_WAVE_cart_0['cut_id'] = trim(substr($thisfile_riff_WAVE_cart_0['data'], 132, 64));
310
+ $thisfile_riff_WAVE_cart_0['client_id'] = trim(substr($thisfile_riff_WAVE_cart_0['data'], 196, 64));
311
+ $thisfile_riff_WAVE_cart_0['category'] = trim(substr($thisfile_riff_WAVE_cart_0['data'], 260, 64));
312
+ $thisfile_riff_WAVE_cart_0['classification'] = trim(substr($thisfile_riff_WAVE_cart_0['data'], 324, 64));
313
+ $thisfile_riff_WAVE_cart_0['out_cue'] = trim(substr($thisfile_riff_WAVE_cart_0['data'], 388, 64));
314
+ $thisfile_riff_WAVE_cart_0['start_date'] = trim(substr($thisfile_riff_WAVE_cart_0['data'], 452, 10));
315
+ $thisfile_riff_WAVE_cart_0['start_time'] = trim(substr($thisfile_riff_WAVE_cart_0['data'], 462, 8));
316
+ $thisfile_riff_WAVE_cart_0['end_date'] = trim(substr($thisfile_riff_WAVE_cart_0['data'], 470, 10));
317
+ $thisfile_riff_WAVE_cart_0['end_time'] = trim(substr($thisfile_riff_WAVE_cart_0['data'], 480, 8));
318
+ $thisfile_riff_WAVE_cart_0['producer_app_id'] = trim(substr($thisfile_riff_WAVE_cart_0['data'], 488, 64));
319
+ $thisfile_riff_WAVE_cart_0['producer_app_version'] = trim(substr($thisfile_riff_WAVE_cart_0['data'], 552, 64));
320
+ $thisfile_riff_WAVE_cart_0['user_defined_text'] = trim(substr($thisfile_riff_WAVE_cart_0['data'], 616, 64));
321
+ $thisfile_riff_WAVE_cart_0['zero_db_reference'] = getid3_lib::LittleEndian2Int(substr($thisfile_riff_WAVE_cart_0['data'], 680, 4), true);
322
+ for ($i = 0; $i < 8; $i++) {
323
+ $thisfile_riff_WAVE_cart_0['post_time'][$i]['usage_fourcc'] = substr($thisfile_riff_WAVE_cart_0['data'], 684 + ($i * 8), 4);
324
+ $thisfile_riff_WAVE_cart_0['post_time'][$i]['timer_value'] = getid3_lib::LittleEndian2Int(substr($thisfile_riff_WAVE_cart_0['data'], 684 + ($i * 8) + 4, 4));
325
+ }
326
+ $thisfile_riff_WAVE_cart_0['url'] = trim(substr($thisfile_riff_WAVE_cart_0['data'], 748, 1024));
327
+ $thisfile_riff_WAVE_cart_0['tag_text'] = explode("\r\n", trim(substr($thisfile_riff_WAVE_cart_0['data'], 1772)));
328
+
329
+ $thisfile_riff['comments']['artist'][] = $thisfile_riff_WAVE_cart_0['artist'];
330
+ $thisfile_riff['comments']['title'][] = $thisfile_riff_WAVE_cart_0['title'];
331
+ }
332
+
333
+ if (isset($thisfile_riff_WAVE['SNDM'][0]['data'])) {
334
+ // SoundMiner metadata
335
+
336
+ // shortcuts
337
+ $thisfile_riff_WAVE_SNDM_0 = &$thisfile_riff_WAVE['SNDM'][0];
338
+ $thisfile_riff_WAVE_SNDM_0_data = &$thisfile_riff_WAVE_SNDM_0['data'];
339
+ $SNDM_startoffset = 0;
340
+ $SNDM_endoffset = $thisfile_riff_WAVE_SNDM_0['size'];
341
+
342
+ while ($SNDM_startoffset < $SNDM_endoffset) {
343
+ $SNDM_thisTagOffset = 0;
344
+ $SNDM_thisTagSize = getid3_lib::BigEndian2Int(substr($thisfile_riff_WAVE_SNDM_0_data, $SNDM_startoffset + $SNDM_thisTagOffset, 4));
345
+ $SNDM_thisTagOffset += 4;
346
+ $SNDM_thisTagKey = substr($thisfile_riff_WAVE_SNDM_0_data, $SNDM_startoffset + $SNDM_thisTagOffset, 4);
347
+ $SNDM_thisTagOffset += 4;
348
+ $SNDM_thisTagDataSize = getid3_lib::BigEndian2Int(substr($thisfile_riff_WAVE_SNDM_0_data, $SNDM_startoffset + $SNDM_thisTagOffset, 2));
349
+ $SNDM_thisTagOffset += 2;
350
+ $SNDM_thisTagDataFlags = getid3_lib::BigEndian2Int(substr($thisfile_riff_WAVE_SNDM_0_data, $SNDM_startoffset + $SNDM_thisTagOffset, 2));
351
+ $SNDM_thisTagOffset += 2;
352
+ $SNDM_thisTagDataText = substr($thisfile_riff_WAVE_SNDM_0_data, $SNDM_startoffset + $SNDM_thisTagOffset, $SNDM_thisTagDataSize);
353
+ $SNDM_thisTagOffset += $SNDM_thisTagDataSize;
354
+
355
+ if ($SNDM_thisTagSize != (4 + 4 + 2 + 2 + $SNDM_thisTagDataSize)) {
356
+ $info['warning'][] = 'RIFF.WAVE.SNDM.data contains tag not expected length (expected: '.$SNDM_thisTagSize.', found: '.(4 + 4 + 2 + 2 + $SNDM_thisTagDataSize).') at offset '.$SNDM_startoffset.' (file offset '.($thisfile_riff_WAVE_SNDM_0['offset'] + $SNDM_startoffset).')';
357
+ break;
358
+ } elseif ($SNDM_thisTagSize <= 0) {
359
+ $info['warning'][] = 'RIFF.WAVE.SNDM.data contains zero-size tag at offset '.$SNDM_startoffset.' (file offset '.($thisfile_riff_WAVE_SNDM_0['offset'] + $SNDM_startoffset).')';
360
+ break;
361
+ }
362
+ $SNDM_startoffset += $SNDM_thisTagSize;
363
+
364
+ $thisfile_riff_WAVE_SNDM_0['parsed_raw'][$SNDM_thisTagKey] = $SNDM_thisTagDataText;
365
+ if ($parsedkey = $this->RIFFwaveSNDMtagLookup($SNDM_thisTagKey)) {
366
+ $thisfile_riff_WAVE_SNDM_0['parsed'][$parsedkey] = $SNDM_thisTagDataText;
367
+ } else {
368
+ $info['warning'][] = 'RIFF.WAVE.SNDM contains unknown tag "'.$SNDM_thisTagKey.'" at offset '.$SNDM_startoffset.' (file offset '.($thisfile_riff_WAVE_SNDM_0['offset'] + $SNDM_startoffset).')';
369
+ }
370
+ }
371
+
372
+ $tagmapping = array(
373
+ 'tracktitle'=>'title',
374
+ 'category' =>'genre',
375
+ 'cdtitle' =>'album',
376
+ 'tracktitle'=>'title',
377
+ );
378
+ foreach ($tagmapping as $fromkey => $tokey) {
379
+ if (isset($thisfile_riff_WAVE_SNDM_0['parsed'][$fromkey])) {
380
+ $thisfile_riff['comments'][$tokey][] = $thisfile_riff_WAVE_SNDM_0['parsed'][$fromkey];
381
+ }
382
+ }
383
+ }
384
+
385
+ if (isset($thisfile_riff_WAVE['iXML'][0]['data'])) {
386
+ // requires functions simplexml_load_string and get_object_vars
387
+ if ($parsedXML = getid3_lib::XML2array($thisfile_riff_WAVE['iXML'][0]['data'])) {
388
+ $thisfile_riff_WAVE['iXML'][0]['parsed'] = $parsedXML;
389
+ if (isset($parsedXML['SPEED']['MASTER_SPEED'])) {
390
+ @list($numerator, $denominator) = explode('/', $parsedXML['SPEED']['MASTER_SPEED']);
391
+ $thisfile_riff_WAVE['iXML'][0]['master_speed'] = $numerator / ($denominator ? $denominator : 1000);
392
+ }
393
+ if (isset($parsedXML['SPEED']['TIMECODE_RATE'])) {
394
+ @list($numerator, $denominator) = explode('/', $parsedXML['SPEED']['TIMECODE_RATE']);
395
+ $thisfile_riff_WAVE['iXML'][0]['timecode_rate'] = $numerator / ($denominator ? $denominator : 1000);
396
+ }
397
+ if (isset($parsedXML['SPEED']['TIMESTAMP_SAMPLES_SINCE_MIDNIGHT_LO']) && !empty($parsedXML['SPEED']['TIMESTAMP_SAMPLE_RATE']) && !empty($thisfile_riff_WAVE['iXML'][0]['timecode_rate'])) {
398
+ $samples_since_midnight = floatval(ltrim($parsedXML['SPEED']['TIMESTAMP_SAMPLES_SINCE_MIDNIGHT_HI'].$parsedXML['SPEED']['TIMESTAMP_SAMPLES_SINCE_MIDNIGHT_LO'], '0'));
399
+ $thisfile_riff_WAVE['iXML'][0]['timecode_seconds'] = $samples_since_midnight / $parsedXML['SPEED']['TIMESTAMP_SAMPLE_RATE'];
400
+ $h = floor( $thisfile_riff_WAVE['iXML'][0]['timecode_seconds'] / 3600);
401
+ $m = floor(($thisfile_riff_WAVE['iXML'][0]['timecode_seconds'] - ($h * 3600)) / 60);
402
+ $s = floor( $thisfile_riff_WAVE['iXML'][0]['timecode_seconds'] - ($h * 3600) - ($m * 60));
403
+ $f = ($thisfile_riff_WAVE['iXML'][0]['timecode_seconds'] - ($h * 3600) - ($m * 60) - $s) * $thisfile_riff_WAVE['iXML'][0]['timecode_rate'];
404
+ $thisfile_riff_WAVE['iXML'][0]['timecode_string'] = sprintf('%02d:%02d:%02d:%05.2f', $h, $m, $s, $f);
405
+ $thisfile_riff_WAVE['iXML'][0]['timecode_string_round'] = sprintf('%02d:%02d:%02d:%02d', $h, $m, $s, round($f));
406
+ }
407
+ unset($parsedXML);
408
+ }
409
+ }
410
+
411
+
412
+
413
+ if (!isset($thisfile_audio['bitrate']) && isset($thisfile_riff_audio[$streamindex]['bitrate'])) {
414
+ $thisfile_audio['bitrate'] = $thisfile_riff_audio[$streamindex]['bitrate'];
415
+ $info['playtime_seconds'] = (float) ((($info['avdataend'] - $info['avdataoffset']) * 8) / $thisfile_audio['bitrate']);
416
+ }
417
+
418
+ if (!empty($info['wavpack'])) {
419
+ $thisfile_audio_dataformat = 'wavpack';
420
+ $thisfile_audio['bitrate_mode'] = 'vbr';
421
+ $thisfile_audio['encoder'] = 'WavPack v'.$info['wavpack']['version'];
422
+
423
+ // Reset to the way it was - RIFF parsing will have messed this up
424
+ $info['avdataend'] = $Original['avdataend'];
425
+ $thisfile_audio['bitrate'] = (($info['avdataend'] - $info['avdataoffset']) * 8) / $info['playtime_seconds'];
426
+
427
+ fseek($this->getid3->fp, $info['avdataoffset'] - 44, SEEK_SET);
428
+ $RIFFdata = fread($this->getid3->fp, 44);
429
+ $OrignalRIFFheaderSize = getid3_lib::LittleEndian2Int(substr($RIFFdata, 4, 4)) + 8;
430
+ $OrignalRIFFdataSize = getid3_lib::LittleEndian2Int(substr($RIFFdata, 40, 4)) + 44;
431
+
432
+ if ($OrignalRIFFheaderSize > $OrignalRIFFdataSize) {
433
+ $info['avdataend'] -= ($OrignalRIFFheaderSize - $OrignalRIFFdataSize);
434
+ fseek($this->getid3->fp, $info['avdataend'], SEEK_SET);
435
+ $RIFFdata .= fread($this->getid3->fp, $OrignalRIFFheaderSize - $OrignalRIFFdataSize);
436
+ }
437
+
438
+ // move the data chunk after all other chunks (if any)
439
+ // so that the RIFF parser doesn't see EOF when trying
440
+ // to skip over the data chunk
441
+ $RIFFdata = substr($RIFFdata, 0, 36).substr($RIFFdata, 44).substr($RIFFdata, 36, 8);
442
+ $getid3_riff = new getid3_riff($this->getid3);
443
+ $getid3_riff->ParseRIFFdata($RIFFdata);
444
+ unset($getid3_riff);
445
+ }
446
+
447
+ if (isset($thisfile_riff_raw['fmt ']['wFormatTag'])) {
448
+ switch ($thisfile_riff_raw['fmt ']['wFormatTag']) {
449
+ case 0x0001: // PCM
450
+ if (!empty($info['ac3'])) {
451
+ // Dolby Digital WAV files masquerade as PCM-WAV, but they're not
452
+ $thisfile_audio['wformattag'] = 0x2000;
453
+ $thisfile_audio['codec'] = $this->RIFFwFormatTagLookup($thisfile_audio['wformattag']);
454
+ $thisfile_audio['lossless'] = false;
455
+ $thisfile_audio['bitrate'] = $info['ac3']['bitrate'];
456
+ $thisfile_audio['sample_rate'] = $info['ac3']['sample_rate'];
457
+ }
458
+ break;
459
+ case 0x08AE: // ClearJump LiteWave
460
+ $thisfile_audio['bitrate_mode'] = 'vbr';
461
+ $thisfile_audio_dataformat = 'litewave';
462
+
463
+ //typedef struct tagSLwFormat {
464
+ // WORD m_wCompFormat; // low byte defines compression method, high byte is compression flags
465
+ // DWORD m_dwScale; // scale factor for lossy compression
466
+ // DWORD m_dwBlockSize; // number of samples in encoded blocks
467
+ // WORD m_wQuality; // alias for the scale factor
468
+ // WORD m_wMarkDistance; // distance between marks in bytes
469
+ // WORD m_wReserved;
470
+ //
471
+ // //following paramters are ignored if CF_FILESRC is not set
472
+ // DWORD m_dwOrgSize; // original file size in bytes
473
+ // WORD m_bFactExists; // indicates if 'fact' chunk exists in the original file
474
+ // DWORD m_dwRiffChunkSize; // riff chunk size in the original file
475
+ //
476
+ // PCMWAVEFORMAT m_OrgWf; // original wave format
477
+ // }SLwFormat, *PSLwFormat;
478
+
479
+ // shortcut
480
+ $thisfile_riff['litewave']['raw'] = array();
481
+ $thisfile_riff_litewave = &$thisfile_riff['litewave'];
482
+ $thisfile_riff_litewave_raw = &$thisfile_riff_litewave['raw'];
483
+
484
+ $thisfile_riff_litewave_raw['compression_method'] = getid3_lib::LittleEndian2Int(substr($thisfile_riff_WAVE['fmt '][0]['data'], 18, 1));
485
+ $thisfile_riff_litewave_raw['compression_flags'] = getid3_lib::LittleEndian2Int(substr($thisfile_riff_WAVE['fmt '][0]['data'], 19, 1));
486
+ $thisfile_riff_litewave_raw['m_dwScale'] = getid3_lib::LittleEndian2Int(substr($thisfile_riff_WAVE['fmt '][0]['data'], 20, 4));
487
+ $thisfile_riff_litewave_raw['m_dwBlockSize'] = getid3_lib::LittleEndian2Int(substr($thisfile_riff_WAVE['fmt '][0]['data'], 24, 4));
488
+ $thisfile_riff_litewave_raw['m_wQuality'] = getid3_lib::LittleEndian2Int(substr($thisfile_riff_WAVE['fmt '][0]['data'], 28, 2));
489
+ $thisfile_riff_litewave_raw['m_wMarkDistance'] = getid3_lib::LittleEndian2Int(substr($thisfile_riff_WAVE['fmt '][0]['data'], 30, 2));
490
+ $thisfile_riff_litewave_raw['m_wReserved'] = getid3_lib::LittleEndian2Int(substr($thisfile_riff_WAVE['fmt '][0]['data'], 32, 2));
491
+ $thisfile_riff_litewave_raw['m_dwOrgSize'] = getid3_lib::LittleEndian2Int(substr($thisfile_riff_WAVE['fmt '][0]['data'], 34, 4));
492
+ $thisfile_riff_litewave_raw['m_bFactExists'] = getid3_lib::LittleEndian2Int(substr($thisfile_riff_WAVE['fmt '][0]['data'], 38, 2));
493
+ $thisfile_riff_litewave_raw['m_dwRiffChunkSize'] = getid3_lib::LittleEndian2Int(substr($thisfile_riff_WAVE['fmt '][0]['data'], 40, 4));
494
+
495
+ //$thisfile_riff_litewave['quality_factor'] = intval(round((2000 - $thisfile_riff_litewave_raw['m_dwScale']) / 20));
496
+ $thisfile_riff_litewave['quality_factor'] = $thisfile_riff_litewave_raw['m_wQuality'];
497
+
498
+ $thisfile_riff_litewave['flags']['raw_source'] = ($thisfile_riff_litewave_raw['compression_flags'] & 0x01) ? false : true;
499
+ $thisfile_riff_litewave['flags']['vbr_blocksize'] = ($thisfile_riff_litewave_raw['compression_flags'] & 0x02) ? false : true;
500
+ $thisfile_riff_litewave['flags']['seekpoints'] = (bool) ($thisfile_riff_litewave_raw['compression_flags'] & 0x04);
501
+
502
+ $thisfile_audio['lossless'] = (($thisfile_riff_litewave_raw['m_wQuality'] == 100) ? true : false);
503
+ $thisfile_audio['encoder_options'] = '-q'.$thisfile_riff_litewave['quality_factor'];
504
+ break;
505
+
506
+ default:
507
+ break;
508
+ }
509
+ }
510
+ if ($info['avdataend'] > $info['filesize']) {
511
+ switch (!empty($thisfile_audio_dataformat) ? $thisfile_audio_dataformat : '') {
512
+ case 'wavpack': // WavPack
513
+ case 'lpac': // LPAC
514
+ case 'ofr': // OptimFROG
515
+ case 'ofs': // OptimFROG DualStream
516
+ // lossless compressed audio formats that keep original RIFF headers - skip warning
517
+ break;
518
+
519
+ case 'litewave':
520
+ if (($info['avdataend'] - $info['filesize']) == 1) {
521
+ // LiteWave appears to incorrectly *not* pad actual output file
522
+ // to nearest WORD boundary so may appear to be short by one
523
+ // byte, in which case - skip warning
524
+ } else {
525
+ // Short by more than one byte, throw warning
526
+ $info['warning'][] = 'Probably truncated file - expecting '.$thisfile_riff[$RIFFsubtype]['data'][0]['size'].' bytes of data, only found '.($info['filesize'] - $info['avdataoffset']).' (short by '.($thisfile_riff[$RIFFsubtype]['data'][0]['size'] - ($info['filesize'] - $info['avdataoffset'])).' bytes)';
527
+ $info['avdataend'] = $info['filesize'];
528
+ }
529
+ break;
530
+
531
+ default:
532
+ if ((($info['avdataend'] - $info['filesize']) == 1) && (($thisfile_riff[$RIFFsubtype]['data'][0]['size'] % 2) == 0) && ((($info['filesize'] - $info['avdataoffset']) % 2) == 1)) {
533
+ // output file appears to be incorrectly *not* padded to nearest WORD boundary
534
+ // Output less severe warning
535
+ $info['warning'][] = 'File should probably be padded to nearest WORD boundary, but it is not (expecting '.$thisfile_riff[$RIFFsubtype]['data'][0]['size'].' bytes of data, only found '.($info['filesize'] - $info['avdataoffset']).' therefore short by '.($thisfile_riff[$RIFFsubtype]['data'][0]['size'] - ($info['filesize'] - $info['avdataoffset'])).' bytes)';
536
+ $info['avdataend'] = $info['filesize'];
537
+ } else {
538
+ // Short by more than one byte, throw warning
539
+ $info['warning'][] = 'Probably truncated file - expecting '.$thisfile_riff[$RIFFsubtype]['data'][0]['size'].' bytes of data, only found '.($info['filesize'] - $info['avdataoffset']).' (short by '.($thisfile_riff[$RIFFsubtype]['data'][0]['size'] - ($info['filesize'] - $info['avdataoffset'])).' bytes)';
540
+ $info['avdataend'] = $info['filesize'];
541
+ }
542
+ break;
543
+ }
544
+ }
545
+ if (!empty($info['mpeg']['audio']['LAME']['audio_bytes'])) {
546
+ if ((($info['avdataend'] - $info['avdataoffset']) - $info['mpeg']['audio']['LAME']['audio_bytes']) == 1) {
547
+ $info['avdataend']--;
548
+ $info['warning'][] = 'Extra null byte at end of MP3 data assumed to be RIFF padding and therefore ignored';
549
+ }
550
+ }
551
+ if (isset($thisfile_audio_dataformat) && ($thisfile_audio_dataformat == 'ac3')) {
552
+ unset($thisfile_audio['bits_per_sample']);
553
+ if (!empty($info['ac3']['bitrate']) && ($info['ac3']['bitrate'] != $thisfile_audio['bitrate'])) {
554
+ $thisfile_audio['bitrate'] = $info['ac3']['bitrate'];
555
+ }
556
+ }
557
+ break;
558
+
559
+ case 'AVI ':
560
+ $thisfile_video['bitrate_mode'] = 'vbr'; // maybe not, but probably
561
+ $thisfile_video['dataformat'] = 'avi';
562
+ $info['mime_type'] = 'video/avi';
563
+
564
+ if (isset($thisfile_riff[$RIFFsubtype]['movi']['offset'])) {
565
+ $info['avdataoffset'] = $thisfile_riff[$RIFFsubtype]['movi']['offset'] + 8;
566
+ if (isset($thisfile_riff['AVIX'])) {
567
+ $info['avdataend'] = $thisfile_riff['AVIX'][(count($thisfile_riff['AVIX']) - 1)]['chunks']['movi']['offset'] + $thisfile_riff['AVIX'][(count($thisfile_riff['AVIX']) - 1)]['chunks']['movi']['size'];
568
+ } else {
569
+ $info['avdataend'] = $thisfile_riff['AVI ']['movi']['offset'] + $thisfile_riff['AVI ']['movi']['size'];
570
+ }
571
+ if ($info['avdataend'] > $info['filesize']) {
572
+ $info['warning'][] = 'Probably truncated file - expecting '.($info['avdataend'] - $info['avdataoffset']).' bytes of data, only found '.($info['filesize'] - $info['avdataoffset']).' (short by '.($info['avdataend'] - $info['filesize']).' bytes)';
573
+ $info['avdataend'] = $info['filesize'];
574
+ }
575
+ }
576
+
577
+ if (isset($thisfile_riff['AVI ']['hdrl']['strl']['indx'])) {
578
+ //$bIndexType = array(
579
+ // 0x00 => 'AVI_INDEX_OF_INDEXES',
580
+ // 0x01 => 'AVI_INDEX_OF_CHUNKS',
581
+ // 0x80 => 'AVI_INDEX_IS_DATA',
582
+ //);
583
+ //$bIndexSubtype = array(
584
+ // 0x01 => array(
585
+ // 0x01 => 'AVI_INDEX_2FIELD',
586
+ // ),
587
+ //);
588
+ foreach ($thisfile_riff['AVI ']['hdrl']['strl']['indx'] as $streamnumber => $steamdataarray) {
589
+ $thisfile_riff_avi_hdrl_strl_indx_stream_data = &$thisfile_riff['AVI ']['hdrl']['strl']['indx'][$streamnumber]['data'];
590
+
591
+ $thisfile_riff_raw['indx'][$streamnumber]['wLongsPerEntry'] = $this->EitherEndian2Int(substr($thisfile_riff_avi_hdrl_strl_indx_stream_data, 0, 2));
592
+ $thisfile_riff_raw['indx'][$streamnumber]['bIndexSubType'] = $this->EitherEndian2Int(substr($thisfile_riff_avi_hdrl_strl_indx_stream_data, 2, 1));
593
+ $thisfile_riff_raw['indx'][$streamnumber]['bIndexType'] = $this->EitherEndian2Int(substr($thisfile_riff_avi_hdrl_strl_indx_stream_data, 3, 1));
594
+ $thisfile_riff_raw['indx'][$streamnumber]['nEntriesInUse'] = $this->EitherEndian2Int(substr($thisfile_riff_avi_hdrl_strl_indx_stream_data, 4, 4));
595
+ $thisfile_riff_raw['indx'][$streamnumber]['dwChunkId'] = substr($thisfile_riff_avi_hdrl_strl_indx_stream_data, 8, 4);
596
+ $thisfile_riff_raw['indx'][$streamnumber]['dwReserved'] = $this->EitherEndian2Int(substr($thisfile_riff_avi_hdrl_strl_indx_stream_data, 12, 4));
597
+
598
+ //$thisfile_riff_raw['indx'][$streamnumber]['bIndexType_name'] = $bIndexType[$thisfile_riff_raw['indx'][$streamnumber]['bIndexType']];
599
+ //$thisfile_riff_raw['indx'][$streamnumber]['bIndexSubType_name'] = $bIndexSubtype[$thisfile_riff_raw['indx'][$streamnumber]['bIndexType']][$thisfile_riff_raw['indx'][$streamnumber]['bIndexSubType']];
600
+
601
+ unset($thisfile_riff_avi_hdrl_strl_indx_stream_data);
602
+ }
603
+ }
604
+ if (isset($thisfile_riff['AVI ']['hdrl']['avih'][$streamindex]['data'])) {
605
+ $avihData = $thisfile_riff['AVI ']['hdrl']['avih'][$streamindex]['data'];
606
+
607
+ // shortcut
608
+ $thisfile_riff_raw['avih'] = array();
609
+ $thisfile_riff_raw_avih = &$thisfile_riff_raw['avih'];
610
+
611
+ $thisfile_riff_raw_avih['dwMicroSecPerFrame'] = $this->EitherEndian2Int(substr($avihData, 0, 4)); // frame display rate (or 0L)
612
+ if ($thisfile_riff_raw_avih['dwMicroSecPerFrame'] == 0) {
613
+ $info['error'][] = 'Corrupt RIFF file: avih.dwMicroSecPerFrame == zero';
614
+ return false;
615
+ }
616
+ $thisfile_riff_raw_avih['dwMaxBytesPerSec'] = $this->EitherEndian2Int(substr($avihData, 4, 4)); // max. transfer rate
617
+ $thisfile_riff_raw_avih['dwPaddingGranularity'] = $this->EitherEndian2Int(substr($avihData, 8, 4)); // pad to multiples of this size; normally 2K.
618
+ $thisfile_riff_raw_avih['dwFlags'] = $this->EitherEndian2Int(substr($avihData, 12, 4)); // the ever-present flags
619
+ $thisfile_riff_raw_avih['dwTotalFrames'] = $this->EitherEndian2Int(substr($avihData, 16, 4)); // # frames in file
620
+ $thisfile_riff_raw_avih['dwInitialFrames'] = $this->EitherEndian2Int(substr($avihData, 20, 4));
621
+ $thisfile_riff_raw_avih['dwStreams'] = $this->EitherEndian2Int(substr($avihData, 24, 4));
622
+ $thisfile_riff_raw_avih['dwSuggestedBufferSize'] = $this->EitherEndian2Int(substr($avihData, 28, 4));
623
+ $thisfile_riff_raw_avih['dwWidth'] = $this->EitherEndian2Int(substr($avihData, 32, 4));
624
+ $thisfile_riff_raw_avih['dwHeight'] = $this->EitherEndian2Int(substr($avihData, 36, 4));
625
+ $thisfile_riff_raw_avih['dwScale'] = $this->EitherEndian2Int(substr($avihData, 40, 4));
626
+ $thisfile_riff_raw_avih['dwRate'] = $this->EitherEndian2Int(substr($avihData, 44, 4));
627
+ $thisfile_riff_raw_avih['dwStart'] = $this->EitherEndian2Int(substr($avihData, 48, 4));
628
+ $thisfile_riff_raw_avih['dwLength'] = $this->EitherEndian2Int(substr($avihData, 52, 4));
629
+
630
+ $thisfile_riff_raw_avih['flags']['hasindex'] = (bool) ($thisfile_riff_raw_avih['dwFlags'] & 0x00000010);
631
+ $thisfile_riff_raw_avih['flags']['mustuseindex'] = (bool) ($thisfile_riff_raw_avih['dwFlags'] & 0x00000020);
632
+ $thisfile_riff_raw_avih['flags']['interleaved'] = (bool) ($thisfile_riff_raw_avih['dwFlags'] & 0x00000100);
633
+ $thisfile_riff_raw_avih['flags']['trustcktype'] = (bool) ($thisfile_riff_raw_avih['dwFlags'] & 0x00000800);
634
+ $thisfile_riff_raw_avih['flags']['capturedfile'] = (bool) ($thisfile_riff_raw_avih['dwFlags'] & 0x00010000);
635
+ $thisfile_riff_raw_avih['flags']['copyrighted'] = (bool) ($thisfile_riff_raw_avih['dwFlags'] & 0x00020010);
636
+
637
+ // shortcut
638
+ $thisfile_riff_video[$streamindex] = array();
639
+ $thisfile_riff_video_current = &$thisfile_riff_video[$streamindex];
640
+
641
+ if ($thisfile_riff_raw_avih['dwWidth'] > 0) {
642
+ $thisfile_riff_video_current['frame_width'] = $thisfile_riff_raw_avih['dwWidth'];
643
+ $thisfile_video['resolution_x'] = $thisfile_riff_video_current['frame_width'];
644
+ }
645
+ if ($thisfile_riff_raw_avih['dwHeight'] > 0) {
646
+ $thisfile_riff_video_current['frame_height'] = $thisfile_riff_raw_avih['dwHeight'];
647
+ $thisfile_video['resolution_y'] = $thisfile_riff_video_current['frame_height'];
648
+ }
649
+ if ($thisfile_riff_raw_avih['dwTotalFrames'] > 0) {
650
+ $thisfile_riff_video_current['total_frames'] = $thisfile_riff_raw_avih['dwTotalFrames'];
651
+ $thisfile_video['total_frames'] = $thisfile_riff_video_current['total_frames'];
652
+ }
653
+
654
+ $thisfile_riff_video_current['frame_rate'] = round(1000000 / $thisfile_riff_raw_avih['dwMicroSecPerFrame'], 3);
655
+ $thisfile_video['frame_rate'] = $thisfile_riff_video_current['frame_rate'];
656
+ }
657
+ if (isset($thisfile_riff['AVI ']['hdrl']['strl']['strh'][0]['data'])) {
658
+ if (is_array($thisfile_riff['AVI ']['hdrl']['strl']['strh'])) {
659
+ for ($i = 0; $i < count($thisfile_riff['AVI ']['hdrl']['strl']['strh']); $i++) {
660
+ if (isset($thisfile_riff['AVI ']['hdrl']['strl']['strh'][$i]['data'])) {
661
+ $strhData = $thisfile_riff['AVI ']['hdrl']['strl']['strh'][$i]['data'];
662
+ $strhfccType = substr($strhData, 0, 4);
663
+
664
+ if (isset($thisfile_riff['AVI ']['hdrl']['strl']['strf'][$i]['data'])) {
665
+ $strfData = $thisfile_riff['AVI ']['hdrl']['strl']['strf'][$i]['data'];
666
+
667
+ // shortcut
668
+ $thisfile_riff_raw_strf_strhfccType_streamindex = &$thisfile_riff_raw['strf'][$strhfccType][$streamindex];
669
+
670
+ switch ($strhfccType) {
671
+ case 'auds':
672
+ $thisfile_audio['bitrate_mode'] = 'cbr';
673
+ $thisfile_audio_dataformat = 'wav';
674
+ if (isset($thisfile_riff_audio) && is_array($thisfile_riff_audio)) {
675
+ $streamindex = count($thisfile_riff_audio);
676
+ }
677
+
678
+ $thisfile_riff_audio[$streamindex] = getid3_riff::RIFFparseWAVEFORMATex($strfData);
679
+ $thisfile_audio['wformattag'] = $thisfile_riff_audio[$streamindex]['raw']['wFormatTag'];
680
+
681
+ // shortcut
682
+ $thisfile_audio['streams'][$streamindex] = $thisfile_riff_audio[$streamindex];
683
+ $thisfile_audio_streams_currentstream = &$thisfile_audio['streams'][$streamindex];
684
+
685
+ if ($thisfile_audio_streams_currentstream['bits_per_sample'] == 0) {
686
+ unset($thisfile_audio_streams_currentstream['bits_per_sample']);
687
+ }
688
+ $thisfile_audio_streams_currentstream['wformattag'] = $thisfile_audio_streams_currentstream['raw']['wFormatTag'];
689
+ unset($thisfile_audio_streams_currentstream['raw']);
690
+
691
+ // shortcut
692
+ $thisfile_riff_raw['strf'][$strhfccType][$streamindex] = $thisfile_riff_audio[$streamindex]['raw'];
693
+
694
+ unset($thisfile_riff_audio[$streamindex]['raw']);
695
+ $thisfile_audio = getid3_lib::array_merge_noclobber($thisfile_audio, $thisfile_riff_audio[$streamindex]);
696
+
697
+ $thisfile_audio['lossless'] = false;
698
+ switch ($thisfile_riff_raw_strf_strhfccType_streamindex['wFormatTag']) {
699
+ case 0x0001: // PCM
700
+ $thisfile_audio_dataformat = 'wav';
701
+ $thisfile_audio['lossless'] = true;
702
+ break;
703
+
704
+ case 0x0050: // MPEG Layer 2 or Layer 1
705
+ $thisfile_audio_dataformat = 'mp2'; // Assume Layer-2
706
+ break;
707
+
708
+ case 0x0055: // MPEG Layer 3
709
+ $thisfile_audio_dataformat = 'mp3';
710
+ break;
711
+
712
+ case 0x00FF: // AAC
713
+ $thisfile_audio_dataformat = 'aac';
714
+ break;
715
+
716
+ case 0x0161: // Windows Media v7 / v8 / v9
717
+ case 0x0162: // Windows Media Professional v9
718
+ case 0x0163: // Windows Media Lossess v9
719
+ $thisfile_audio_dataformat = 'wma';
720
+ break;
721
+
722
+ case 0x2000: // AC-3
723
+ $thisfile_audio_dataformat = 'ac3';
724
+ break;
725
+
726
+ case 0x2001: // DTS
727
+ $thisfile_audio_dataformat = 'dts';
728
+ break;
729
+
730
+ default:
731
+ $thisfile_audio_dataformat = 'wav';
732
+ break;
733
+ }
734
+ $thisfile_audio_streams_currentstream['dataformat'] = $thisfile_audio_dataformat;
735
+ $thisfile_audio_streams_currentstream['lossless'] = $thisfile_audio['lossless'];
736
+ $thisfile_audio_streams_currentstream['bitrate_mode'] = $thisfile_audio['bitrate_mode'];
737
+ break;
738
+
739
+
740
+ case 'iavs':
741
+ case 'vids':
742
+ // shortcut
743
+ $thisfile_riff_raw['strh'][$i] = array();
744
+ $thisfile_riff_raw_strh_current = &$thisfile_riff_raw['strh'][$i];
745
+
746
+ $thisfile_riff_raw_strh_current['fccType'] = substr($strhData, 0, 4); // same as $strhfccType;
747
+ $thisfile_riff_raw_strh_current['fccHandler'] = substr($strhData, 4, 4);
748
+ $thisfile_riff_raw_strh_current['dwFlags'] = $this->EitherEndian2Int(substr($strhData, 8, 4)); // Contains AVITF_* flags
749
+ $thisfile_riff_raw_strh_current['wPriority'] = $this->EitherEndian2Int(substr($strhData, 12, 2));
750
+ $thisfile_riff_raw_strh_current['wLanguage'] = $this->EitherEndian2Int(substr($strhData, 14, 2));
751
+ $thisfile_riff_raw_strh_current['dwInitialFrames'] = $this->EitherEndian2Int(substr($strhData, 16, 4));
752
+ $thisfile_riff_raw_strh_current['dwScale'] = $this->EitherEndian2Int(substr($strhData, 20, 4));
753
+ $thisfile_riff_raw_strh_current['dwRate'] = $this->EitherEndian2Int(substr($strhData, 24, 4));
754
+ $thisfile_riff_raw_strh_current['dwStart'] = $this->EitherEndian2Int(substr($strhData, 28, 4));
755
+ $thisfile_riff_raw_strh_current['dwLength'] = $this->EitherEndian2Int(substr($strhData, 32, 4));
756
+ $thisfile_riff_raw_strh_current['dwSuggestedBufferSize'] = $this->EitherEndian2Int(substr($strhData, 36, 4));
757
+ $thisfile_riff_raw_strh_current['dwQuality'] = $this->EitherEndian2Int(substr($strhData, 40, 4));
758
+ $thisfile_riff_raw_strh_current['dwSampleSize'] = $this->EitherEndian2Int(substr($strhData, 44, 4));
759
+ $thisfile_riff_raw_strh_current['rcFrame'] = $this->EitherEndian2Int(substr($strhData, 48, 4));
760
+
761
+ $thisfile_riff_video_current['codec'] = getid3_riff::RIFFfourccLookup($thisfile_riff_raw_strh_current['fccHandler']);
762
+ $thisfile_video['fourcc'] = $thisfile_riff_raw_strh_current['fccHandler'];
763
+ if (!$thisfile_riff_video_current['codec'] && isset($thisfile_riff_raw_strf_strhfccType_streamindex['fourcc']) && getid3_riff::RIFFfourccLookup($thisfile_riff_raw_strf_strhfccType_streamindex['fourcc'])) {
764
+ $thisfile_riff_video_current['codec'] = getid3_riff::RIFFfourccLookup($thisfile_riff_raw_strf_strhfccType_streamindex['fourcc']);
765
+ $thisfile_video['fourcc'] = $thisfile_riff_raw_strf_strhfccType_streamindex['fourcc'];
766
+ }
767
+ $thisfile_video['codec'] = $thisfile_riff_video_current['codec'];
768
+ $thisfile_video['pixel_aspect_ratio'] = (float) 1;
769
+ switch ($thisfile_riff_raw_strh_current['fccHandler']) {
770
+ case 'HFYU': // Huffman Lossless Codec
771
+ case 'IRAW': // Intel YUV Uncompressed
772
+ case 'YUY2': // Uncompressed YUV 4:2:2
773
+ $thisfile_video['lossless'] = true;
774
+ break;
775
+
776
+ default:
777
+ $thisfile_video['lossless'] = false;
778
+ break;
779
+ }
780
+
781
+ switch ($strhfccType) {
782
+ case 'vids':
783
+ $thisfile_riff_raw_strf_strhfccType_streamindex = getid3_riff::ParseBITMAPINFOHEADER(substr($strfData, 0, 40), ($info['fileformat'] == 'riff'));
784
+ //echo '<pre>'.print_r($thisfile_riff_raw_strf_strhfccType_streamindex, true).'</pre>';
785
+ $thisfile_video['bits_per_sample'] = $thisfile_riff_raw_strf_strhfccType_streamindex['biBitCount'];
786
+
787
+ if ($thisfile_riff_video_current['codec'] == 'DV') {
788
+ $thisfile_riff_video_current['dv_type'] = 2;
789
+ }
790
+ break;
791
+
792
+ case 'iavs':
793
+ $thisfile_riff_video_current['dv_type'] = 1;
794
+ break;
795
+ }
796
+ break;
797
+
798
+ default:
799
+ $info['warning'][] = 'Unhandled fccType for stream ('.$i.'): "'.$strhfccType.'"';
800
+ break;
801
+
802
+ }
803
+ }
804
+ }
805
+
806
+ if (isset($thisfile_riff_raw_strf_strhfccType_streamindex['fourcc'])) {
807
+
808
+ $thisfile_video['fourcc'] = $thisfile_riff_raw_strf_strhfccType_streamindex['fourcc'];
809
+ if (getid3_riff::RIFFfourccLookup($thisfile_video['fourcc'])) {
810
+ $thisfile_riff_video_current['codec'] = getid3_riff::RIFFfourccLookup($thisfile_video['fourcc']);
811
+ $thisfile_video['codec'] = $thisfile_riff_video_current['codec'];
812
+ }
813
+
814
+ switch ($thisfile_riff_raw_strf_strhfccType_streamindex['fourcc']) {
815
+ case 'HFYU': // Huffman Lossless Codec
816
+ case 'IRAW': // Intel YUV Uncompressed
817
+ case 'YUY2': // Uncompressed YUV 4:2:2
818
+ $thisfile_video['lossless'] = true;
819
+ //$thisfile_video['bits_per_sample'] = 24;
820
+ break;
821
+
822
+ default:
823
+ $thisfile_video['lossless'] = false;
824
+ //$thisfile_video['bits_per_sample'] = 24;
825
+ break;
826
+ }
827
+
828
+ }
829
+ }
830
+ }
831
+ }
832
+ break;
833
+
834
+ case 'CDDA':
835
+ $thisfile_audio['bitrate_mode'] = 'cbr';
836
+ $thisfile_audio_dataformat = 'cda';
837
+ $thisfile_audio['lossless'] = true;
838
+ unset($info['mime_type']);
839
+
840
+ $info['avdataoffset'] = 44;
841
+
842
+ if (isset($thisfile_riff['CDDA']['fmt '][0]['data'])) {
843
+ // shortcut
844
+ $thisfile_riff_CDDA_fmt_0 = &$thisfile_riff['CDDA']['fmt '][0];
845
+
846
+ $thisfile_riff_CDDA_fmt_0['unknown1'] = $this->EitherEndian2Int(substr($thisfile_riff_CDDA_fmt_0['data'], 0, 2));
847
+ $thisfile_riff_CDDA_fmt_0['track_num'] = $this->EitherEndian2Int(substr($thisfile_riff_CDDA_fmt_0['data'], 2, 2));
848
+ $thisfile_riff_CDDA_fmt_0['disc_id'] = $this->EitherEndian2Int(substr($thisfile_riff_CDDA_fmt_0['data'], 4, 4));
849
+ $thisfile_riff_CDDA_fmt_0['start_offset_frame'] = $this->EitherEndian2Int(substr($thisfile_riff_CDDA_fmt_0['data'], 8, 4));
850
+ $thisfile_riff_CDDA_fmt_0['playtime_frames'] = $this->EitherEndian2Int(substr($thisfile_riff_CDDA_fmt_0['data'], 12, 4));
851
+ $thisfile_riff_CDDA_fmt_0['unknown6'] = $this->EitherEndian2Int(substr($thisfile_riff_CDDA_fmt_0['data'], 16, 4));
852
+ $thisfile_riff_CDDA_fmt_0['unknown7'] = $this->EitherEndian2Int(substr($thisfile_riff_CDDA_fmt_0['data'], 20, 4));
853
+
854
+ $thisfile_riff_CDDA_fmt_0['start_offset_seconds'] = (float) $thisfile_riff_CDDA_fmt_0['start_offset_frame'] / 75;
855
+ $thisfile_riff_CDDA_fmt_0['playtime_seconds'] = (float) $thisfile_riff_CDDA_fmt_0['playtime_frames'] / 75;
856
+ $info['comments']['track'] = $thisfile_riff_CDDA_fmt_0['track_num'];
857
+ $info['playtime_seconds'] = $thisfile_riff_CDDA_fmt_0['playtime_seconds'];
858
+
859
+ // hardcoded data for CD-audio
860
+ $thisfile_audio['sample_rate'] = 44100;
861
+ $thisfile_audio['channels'] = 2;
862
+ $thisfile_audio['bits_per_sample'] = 16;
863
+ $thisfile_audio['bitrate'] = $thisfile_audio['sample_rate'] * $thisfile_audio['channels'] * $thisfile_audio['bits_per_sample'];
864
+ $thisfile_audio['bitrate_mode'] = 'cbr';
865
+ }
866
+ break;
867
+
868
+
869
+ case 'AIFF':
870
+ case 'AIFC':
871
+ $thisfile_audio['bitrate_mode'] = 'cbr';
872
+ $thisfile_audio_dataformat = 'aiff';
873
+ $thisfile_audio['lossless'] = true;
874
+ $info['mime_type'] = 'audio/x-aiff';
875
+
876
+ if (isset($thisfile_riff[$RIFFsubtype]['SSND'][0]['offset'])) {
877
+ $info['avdataoffset'] = $thisfile_riff[$RIFFsubtype]['SSND'][0]['offset'] + 8;
878
+ $info['avdataend'] = $info['avdataoffset'] + $thisfile_riff[$RIFFsubtype]['SSND'][0]['size'];
879
+ if ($info['avdataend'] > $info['filesize']) {
880
+ if (($info['avdataend'] == ($info['filesize'] + 1)) && (($info['filesize'] % 2) == 1)) {
881
+ // structures rounded to 2-byte boundary, but dumb encoders
882
+ // forget to pad end of file to make this actually work
883
+ } else {
884
+ $info['warning'][] = 'Probable truncated AIFF file: expecting '.$thisfile_riff[$RIFFsubtype]['SSND'][0]['size'].' bytes of audio data, only '.($info['filesize'] - $info['avdataoffset']).' bytes found';
885
+ }
886
+ $info['avdataend'] = $info['filesize'];
887
+ }
888
+ }
889
+
890
+ if (isset($thisfile_riff[$RIFFsubtype]['COMM'][0]['data'])) {
891
+
892
+ // shortcut
893
+ $thisfile_riff_RIFFsubtype_COMM_0_data = &$thisfile_riff[$RIFFsubtype]['COMM'][0]['data'];
894
+
895
+ $thisfile_riff_audio['channels'] = getid3_lib::BigEndian2Int(substr($thisfile_riff_RIFFsubtype_COMM_0_data, 0, 2), true);
896
+ $thisfile_riff_audio['total_samples'] = getid3_lib::BigEndian2Int(substr($thisfile_riff_RIFFsubtype_COMM_0_data, 2, 4), false);
897
+ $thisfile_riff_audio['bits_per_sample'] = getid3_lib::BigEndian2Int(substr($thisfile_riff_RIFFsubtype_COMM_0_data, 6, 2), true);
898
+ $thisfile_riff_audio['sample_rate'] = (int) getid3_lib::BigEndian2Float(substr($thisfile_riff_RIFFsubtype_COMM_0_data, 8, 10));
899
+
900
+ if ($thisfile_riff[$RIFFsubtype]['COMM'][0]['size'] > 18) {
901
+ $thisfile_riff_audio['codec_fourcc'] = substr($thisfile_riff_RIFFsubtype_COMM_0_data, 18, 4);
902
+ $CodecNameSize = getid3_lib::BigEndian2Int(substr($thisfile_riff_RIFFsubtype_COMM_0_data, 22, 1), false);
903
+ $thisfile_riff_audio['codec_name'] = substr($thisfile_riff_RIFFsubtype_COMM_0_data, 23, $CodecNameSize);
904
+ switch ($thisfile_riff_audio['codec_name']) {
905
+ case 'NONE':
906
+ $thisfile_audio['codec'] = 'Pulse Code Modulation (PCM)';
907
+ $thisfile_audio['lossless'] = true;
908
+ break;
909
+
910
+ case '':
911
+ switch ($thisfile_riff_audio['codec_fourcc']) {
912
+ // http://developer.apple.com/qa/snd/snd07.html
913
+ case 'sowt':
914
+ $thisfile_riff_audio['codec_name'] = 'Two\'s Compliment Little-Endian PCM';
915
+ $thisfile_audio['lossless'] = true;
916
+ break;
917
+
918
+ case 'twos':
919
+ $thisfile_riff_audio['codec_name'] = 'Two\'s Compliment Big-Endian PCM';
920
+ $thisfile_audio['lossless'] = true;
921
+ break;
922
+
923
+ default:
924
+ break;
925
+ }
926
+ break;
927
+
928
+ default:
929
+ $thisfile_audio['codec'] = $thisfile_riff_audio['codec_name'];
930
+ $thisfile_audio['lossless'] = false;
931
+ break;
932
+ }
933
+ }
934
+
935
+ $thisfile_audio['channels'] = $thisfile_riff_audio['channels'];
936
+ if ($thisfile_riff_audio['bits_per_sample'] > 0) {
937
+ $thisfile_audio['bits_per_sample'] = $thisfile_riff_audio['bits_per_sample'];
938
+ }
939
+ $thisfile_audio['sample_rate'] = $thisfile_riff_audio['sample_rate'];
940
+ if ($thisfile_audio['sample_rate'] == 0) {
941
+ $info['error'][] = 'Corrupted AIFF file: sample_rate == zero';
942
+ return false;
943
+ }
944
+ $info['playtime_seconds'] = $thisfile_riff_audio['total_samples'] / $thisfile_audio['sample_rate'];
945
+ }
946
+
947
+ if (isset($thisfile_riff[$RIFFsubtype]['COMT'])) {
948
+ $offset = 0;
949
+ $CommentCount = getid3_lib::BigEndian2Int(substr($thisfile_riff[$RIFFsubtype]['COMT'][0]['data'], $offset, 2), false);
950
+ $offset += 2;
951
+ for ($i = 0; $i < $CommentCount; $i++) {
952
+ $info['comments_raw'][$i]['timestamp'] = getid3_lib::BigEndian2Int(substr($thisfile_riff[$RIFFsubtype]['COMT'][0]['data'], $offset, 4), false);
953
+ $offset += 4;
954
+ $info['comments_raw'][$i]['marker_id'] = getid3_lib::BigEndian2Int(substr($thisfile_riff[$RIFFsubtype]['COMT'][0]['data'], $offset, 2), true);
955
+ $offset += 2;
956
+ $CommentLength = getid3_lib::BigEndian2Int(substr($thisfile_riff[$RIFFsubtype]['COMT'][0]['data'], $offset, 2), false);
957
+ $offset += 2;
958
+ $info['comments_raw'][$i]['comment'] = substr($thisfile_riff[$RIFFsubtype]['COMT'][0]['data'], $offset, $CommentLength);
959
+ $offset += $CommentLength;
960
+
961
+ $info['comments_raw'][$i]['timestamp_unix'] = getid3_lib::DateMac2Unix($info['comments_raw'][$i]['timestamp']);
962
+ $thisfile_riff['comments']['comment'][] = $info['comments_raw'][$i]['comment'];
963
+ }
964
+ }
965
+
966
+ $CommentsChunkNames = array('NAME'=>'title', 'author'=>'artist', '(c) '=>'copyright', 'ANNO'=>'comment');
967
+ foreach ($CommentsChunkNames as $key => $value) {
968
+ if (isset($thisfile_riff[$RIFFsubtype][$key][0]['data'])) {
969
+ $thisfile_riff['comments'][$value][] = $thisfile_riff[$RIFFsubtype][$key][0]['data'];
970
+ }
971
+ }
972
+
973
+ if (isset($thisfile_riff[$RIFFsubtype]['ID3 '])) {
974
+ getid3_lib::IncludeDependency(GETID3_INCLUDEPATH.'module.tag.id3v2.php', __FILE__, true);
975
+ $getid3_temp = new getID3();
976
+ $getid3_temp->openfile($this->getid3->filename);
977
+ $getid3_id3v2 = new getid3_id3v2($getid3_temp);
978
+ $getid3_id3v2->StartingOffset = $thisfile_riff[$RIFFsubtype]['ID3 '][0]['offset'] + 8;
979
+ if ($thisfile_riff[$RIFFsubtype]['ID3 '][0]['valid'] = $getid3_id3v2->Analyze()) {
980
+ $info['id3v2'] = $getid3_temp->info['id3v2'];
981
+ }
982
+ unset($getid3_temp, $getid3_id3v2);
983
+ }
984
+ break;
985
+
986
+ case '8SVX':
987
+ $thisfile_audio['bitrate_mode'] = 'cbr';
988
+ $thisfile_audio_dataformat = '8svx';
989
+ $thisfile_audio['bits_per_sample'] = 8;
990
+ $thisfile_audio['channels'] = 1; // overridden below, if need be
991
+ $info['mime_type'] = 'audio/x-aiff';
992
+
993
+ if (isset($thisfile_riff[$RIFFsubtype]['BODY'][0]['offset'])) {
994
+ $info['avdataoffset'] = $thisfile_riff[$RIFFsubtype]['BODY'][0]['offset'] + 8;
995
+ $info['avdataend'] = $info['avdataoffset'] + $thisfile_riff[$RIFFsubtype]['BODY'][0]['size'];
996
+ if ($info['avdataend'] > $info['filesize']) {
997
+ $info['warning'][] = 'Probable truncated AIFF file: expecting '.$thisfile_riff[$RIFFsubtype]['BODY'][0]['size'].' bytes of audio data, only '.($info['filesize'] - $info['avdataoffset']).' bytes found';
998
+ }
999
+ }
1000
+
1001
+ if (isset($thisfile_riff[$RIFFsubtype]['VHDR'][0]['offset'])) {
1002
+ // shortcut
1003
+ $thisfile_riff_RIFFsubtype_VHDR_0 = &$thisfile_riff[$RIFFsubtype]['VHDR'][0];
1004
+
1005
+ $thisfile_riff_RIFFsubtype_VHDR_0['oneShotHiSamples'] = getid3_lib::BigEndian2Int(substr($thisfile_riff_RIFFsubtype_VHDR_0['data'], 0, 4));
1006
+ $thisfile_riff_RIFFsubtype_VHDR_0['repeatHiSamples'] = getid3_lib::BigEndian2Int(substr($thisfile_riff_RIFFsubtype_VHDR_0['data'], 4, 4));
1007
+ $thisfile_riff_RIFFsubtype_VHDR_0['samplesPerHiCycle'] = getid3_lib::BigEndian2Int(substr($thisfile_riff_RIFFsubtype_VHDR_0['data'], 8, 4));
1008
+ $thisfile_riff_RIFFsubtype_VHDR_0['samplesPerSec'] = getid3_lib::BigEndian2Int(substr($thisfile_riff_RIFFsubtype_VHDR_0['data'], 12, 2));
1009
+ $thisfile_riff_RIFFsubtype_VHDR_0['ctOctave'] = getid3_lib::BigEndian2Int(substr($thisfile_riff_RIFFsubtype_VHDR_0['data'], 14, 1));
1010
+ $thisfile_riff_RIFFsubtype_VHDR_0['sCompression'] = getid3_lib::BigEndian2Int(substr($thisfile_riff_RIFFsubtype_VHDR_0['data'], 15, 1));
1011
+ $thisfile_riff_RIFFsubtype_VHDR_0['Volume'] = getid3_lib::FixedPoint16_16(substr($thisfile_riff_RIFFsubtype_VHDR_0['data'], 16, 4));
1012
+
1013
+ $thisfile_audio['sample_rate'] = $thisfile_riff_RIFFsubtype_VHDR_0['samplesPerSec'];
1014
+
1015
+ switch ($thisfile_riff_RIFFsubtype_VHDR_0['sCompression']) {
1016
+ case 0:
1017
+ $thisfile_audio['codec'] = 'Pulse Code Modulation (PCM)';
1018
+ $thisfile_audio['lossless'] = true;
1019
+ $ActualBitsPerSample = 8;
1020
+ break;
1021
+
1022
+ case 1:
1023
+ $thisfile_audio['codec'] = 'Fibonacci-delta encoding';
1024
+ $thisfile_audio['lossless'] = false;
1025
+ $ActualBitsPerSample = 4;
1026
+ break;
1027
+
1028
+ default:
1029
+ $info['warning'][] = 'Unexpected sCompression value in 8SVX.VHDR chunk - expecting 0 or 1, found "'.sCompression.'"';
1030
+ break;
1031
+ }
1032
+ }
1033
+
1034
+ if (isset($thisfile_riff[$RIFFsubtype]['CHAN'][0]['data'])) {
1035
+ $ChannelsIndex = getid3_lib::BigEndian2Int(substr($thisfile_riff[$RIFFsubtype]['CHAN'][0]['data'], 0, 4));
1036
+ switch ($ChannelsIndex) {
1037
+ case 6: // Stereo
1038
+ $thisfile_audio['channels'] = 2;
1039
+ break;
1040
+
1041
+ case 2: // Left channel only
1042
+ case 4: // Right channel only
1043
+ $thisfile_audio['channels'] = 1;
1044
+ break;
1045
+
1046
+ default:
1047
+ $info['warning'][] = 'Unexpected value in 8SVX.CHAN chunk - expecting 2 or 4 or 6, found "'.$ChannelsIndex.'"';
1048
+ break;
1049
+ }
1050
+
1051
+ }
1052
+
1053
+ $CommentsChunkNames = array('NAME'=>'title', 'author'=>'artist', '(c) '=>'copyright', 'ANNO'=>'comment');
1054
+ foreach ($CommentsChunkNames as $key => $value) {
1055
+ if (isset($thisfile_riff[$RIFFsubtype][$key][0]['data'])) {
1056
+ $thisfile_riff['comments'][$value][] = $thisfile_riff[$RIFFsubtype][$key][0]['data'];
1057
+ }
1058
+ }
1059
+
1060
+ $thisfile_audio['bitrate'] = $thisfile_audio['sample_rate'] * $ActualBitsPerSample * $thisfile_audio['channels'];
1061
+ if (!empty($thisfile_audio['bitrate'])) {
1062
+ $info['playtime_seconds'] = ($info['avdataend'] - $info['avdataoffset']) / ($thisfile_audio['bitrate'] / 8);
1063
+ }
1064
+ break;
1065
+
1066
+
1067
+ case 'CDXA':
1068
+ $info['mime_type'] = 'video/mpeg';
1069
+ if (!empty($thisfile_riff['CDXA']['data'][0]['size'])) {
1070
+ if (getid3_lib::IncludeDependency(GETID3_INCLUDEPATH.'module.audio-video.mpeg.php', __FILE__, false)) {
1071
+ $getid3_temp = new getID3();
1072
+ $getid3_temp->openfile($this->getid3->filename);
1073
+ $getid3_mpeg = new getid3_mpeg($getid3_temp);
1074
+ $getid3_mpeg->Analyze();
1075
+ if (empty($getid3_temp->info['error'])) {
1076
+ $info['audio'] = $getid3_temp->info['audio'];
1077
+ $info['video'] = $getid3_temp->info['video'];
1078
+ $info['mpeg'] = $getid3_temp->info['mpeg'];
1079
+ $info['warning'] = $getid3_temp->info['warning'];
1080
+ }
1081
+ unset($getid3_temp, $getid3_mpeg);
1082
+ }
1083
+ }
1084
+ break;
1085
+
1086
+
1087
+ default:
1088
+ $info['error'][] = 'Unknown RIFF type: expecting one of (WAVE|RMP3|AVI |CDDA|AIFF|AIFC|8SVX|CDXA), found "'.$RIFFsubtype.'" instead';
1089
+ unset($info['fileformat']);
1090
+ break;
1091
+ }
1092
+
1093
+ if (isset($thisfile_riff_raw['fmt ']['wFormatTag']) && ($thisfile_riff_raw['fmt ']['wFormatTag'] == 1)) {
1094
+ // http://www.mega-nerd.com/erikd/Blog/Windiots/dts.html
1095
+ fseek($this->getid3->fp, $info['avdataoffset'], SEEK_SET);
1096
+ $FirstFourBytes = fread($this->getid3->fp, 4);
1097
+ if (preg_match('/^\xFF\x1F\x00\xE8/s', $FirstFourBytes)) {
1098
+ // DTSWAV
1099
+ $thisfile_audio_dataformat = 'dts';
1100
+ } elseif (preg_match('/^\x7F\xFF\x80\x01/s', $FirstFourBytes)) {
1101
+ // DTS, but this probably shouldn't happen
1102
+ $thisfile_audio_dataformat = 'dts';
1103
+ }
1104
+ }
1105
+
1106
+
1107
+ if (isset($thisfile_riff_WAVE['DISP']) && is_array($thisfile_riff_WAVE['DISP'])) {
1108
+ $thisfile_riff['comments']['title'][] = trim(substr($thisfile_riff_WAVE['DISP'][count($thisfile_riff_WAVE['DISP']) - 1]['data'], 4));
1109
+ }
1110
+ if (isset($thisfile_riff_WAVE['INFO']) && is_array($thisfile_riff_WAVE['INFO'])) {
1111
+ $this->RIFFcommentsParse($thisfile_riff_WAVE['INFO'], $thisfile_riff['comments']);
1112
+ }
1113
+ if (isset($thisfile_riff['AVI ']['INFO']) && is_array($thisfile_riff['AVI ']['INFO'])) {
1114
+ $this->RIFFcommentsParse($thisfile_riff['AVI ']['INFO'], $thisfile_riff['comments']);
1115
+ }
1116
+
1117
+ if (empty($thisfile_audio['encoder']) && !empty($info['mpeg']['audio']['LAME']['short_version'])) {
1118
+ $thisfile_audio['encoder'] = $info['mpeg']['audio']['LAME']['short_version'];
1119
+ }
1120
+
1121
+ if (!isset($info['playtime_seconds'])) {
1122
+ $info['playtime_seconds'] = 0;
1123
+ }
1124
+ if (isset($thisfile_riff_raw['strh'][0]['dwLength']) && isset($thisfile_riff_raw['avih']['dwMicroSecPerFrame'])) {
1125
+ // needed for >2GB AVIs where 'avih' chunk only lists number of frames in that chunk, not entire movie
1126
+ $info['playtime_seconds'] = $thisfile_riff_raw['strh'][0]['dwLength'] * ($thisfile_riff_raw['avih']['dwMicroSecPerFrame'] / 1000000);
1127
+ } elseif (isset($thisfile_riff_raw['avih']['dwTotalFrames']) && isset($thisfile_riff_raw['avih']['dwMicroSecPerFrame'])) {
1128
+ $info['playtime_seconds'] = $thisfile_riff_raw['avih']['dwTotalFrames'] * ($thisfile_riff_raw['avih']['dwMicroSecPerFrame'] / 1000000);
1129
+ }
1130
+
1131
+ if ($info['playtime_seconds'] > 0) {
1132
+ if (isset($thisfile_riff_audio) && isset($thisfile_riff_video)) {
1133
+
1134
+ if (!isset($info['bitrate'])) {
1135
+ $info['bitrate'] = ((($info['avdataend'] - $info['avdataoffset']) / $info['playtime_seconds']) * 8);
1136
+ }
1137
+
1138
+ } elseif (isset($thisfile_riff_audio) && !isset($thisfile_riff_video)) {
1139
+
1140
+ if (!isset($thisfile_audio['bitrate'])) {
1141
+ $thisfile_audio['bitrate'] = ((($info['avdataend'] - $info['avdataoffset']) / $info['playtime_seconds']) * 8);
1142
+ }
1143
+
1144
+ } elseif (!isset($thisfile_riff_audio) && isset($thisfile_riff_video)) {
1145
+
1146
+ if (!isset($thisfile_video['bitrate'])) {
1147
+ $thisfile_video['bitrate'] = ((($info['avdataend'] - $info['avdataoffset']) / $info['playtime_seconds']) * 8);
1148
+ }
1149
+
1150
+ }
1151
+ }
1152
+
1153
+
1154
+ if (isset($thisfile_riff_video) && isset($thisfile_audio['bitrate']) && ($thisfile_audio['bitrate'] > 0) && ($info['playtime_seconds'] > 0)) {
1155
+
1156
+ $info['bitrate'] = ((($info['avdataend'] - $info['avdataoffset']) / $info['playtime_seconds']) * 8);
1157
+ $thisfile_audio['bitrate'] = 0;
1158
+ $thisfile_video['bitrate'] = $info['bitrate'];
1159
+ foreach ($thisfile_riff_audio as $channelnumber => $audioinfoarray) {
1160
+ $thisfile_video['bitrate'] -= $audioinfoarray['bitrate'];
1161
+ $thisfile_audio['bitrate'] += $audioinfoarray['bitrate'];
1162
+ }
1163
+ if ($thisfile_video['bitrate'] <= 0) {
1164
+ unset($thisfile_video['bitrate']);
1165
+ }
1166
+ if ($thisfile_audio['bitrate'] <= 0) {
1167
+ unset($thisfile_audio['bitrate']);
1168
+ }
1169
+ }
1170
+
1171
+ if (isset($info['mpeg']['audio'])) {
1172
+ $thisfile_audio_dataformat = 'mp'.$info['mpeg']['audio']['layer'];
1173
+ $thisfile_audio['sample_rate'] = $info['mpeg']['audio']['sample_rate'];
1174
+ $thisfile_audio['channels'] = $info['mpeg']['audio']['channels'];
1175
+ $thisfile_audio['bitrate'] = $info['mpeg']['audio']['bitrate'];
1176
+ $thisfile_audio['bitrate_mode'] = strtolower($info['mpeg']['audio']['bitrate_mode']);
1177
+ if (!empty($info['mpeg']['audio']['codec'])) {
1178
+ $thisfile_audio['codec'] = $info['mpeg']['audio']['codec'].' '.$thisfile_audio['codec'];
1179
+ }
1180
+ if (!empty($thisfile_audio['streams'])) {
1181
+ foreach ($thisfile_audio['streams'] as $streamnumber => $streamdata) {
1182
+ if ($streamdata['dataformat'] == $thisfile_audio_dataformat) {
1183
+ $thisfile_audio['streams'][$streamnumber]['sample_rate'] = $thisfile_audio['sample_rate'];
1184
+ $thisfile_audio['streams'][$streamnumber]['channels'] = $thisfile_audio['channels'];
1185
+ $thisfile_audio['streams'][$streamnumber]['bitrate'] = $thisfile_audio['bitrate'];
1186
+ $thisfile_audio['streams'][$streamnumber]['bitrate_mode'] = $thisfile_audio['bitrate_mode'];
1187
+ $thisfile_audio['streams'][$streamnumber]['codec'] = $thisfile_audio['codec'];
1188
+ }
1189
+ }
1190
+ }
1191
+ $getid3_mp3 = new getid3_mp3($this->getid3);
1192
+ $thisfile_audio['encoder_options'] = $getid3_mp3->GuessEncoderOptions();
1193
+ unset($getid3_mp3);
1194
+ }
1195
+
1196
+
1197
+ if (!empty($thisfile_riff_raw['fmt ']['wBitsPerSample']) && ($thisfile_riff_raw['fmt ']['wBitsPerSample'] > 0)) {
1198
+ switch ($thisfile_audio_dataformat) {
1199
+ case 'ac3':
1200
+ // ignore bits_per_sample
1201
+ break;
1202
+
1203
+ default:
1204
+ $thisfile_audio['bits_per_sample'] = $thisfile_riff_raw['fmt ']['wBitsPerSample'];
1205
+ break;
1206
+ }
1207
+ }
1208
+
1209
+
1210
+ if (empty($thisfile_riff_raw)) {
1211
+ unset($thisfile_riff['raw']);
1212
+ }
1213
+ if (empty($thisfile_riff_audio)) {
1214
+ unset($thisfile_riff['audio']);
1215
+ }
1216
+ if (empty($thisfile_riff_video)) {
1217
+ unset($thisfile_riff['video']);
1218
+ }
1219
+
1220
+ return true;
1221
+ }
1222
+
1223
+
1224
+ static function RIFFcommentsParse(&$RIFFinfoArray, &$CommentsTargetArray) {
1225
+ $RIFFinfoKeyLookup = array(
1226
+ 'IARL'=>'archivallocation',
1227
+ 'IART'=>'artist',
1228
+ 'ICDS'=>'costumedesigner',
1229
+ 'ICMS'=>'commissionedby',
1230
+ 'ICMT'=>'comment',
1231
+ 'ICNT'=>'country',
1232
+ 'ICOP'=>'copyright',
1233
+ 'ICRD'=>'creationdate',
1234
+ 'IDIM'=>'dimensions',
1235
+ 'IDIT'=>'digitizationdate',
1236
+ 'IDPI'=>'resolution',
1237
+ 'IDST'=>'distributor',
1238
+ 'IEDT'=>'editor',
1239
+ 'IENG'=>'engineers',
1240
+ 'IFRM'=>'accountofparts',
1241
+ 'IGNR'=>'genre',
1242
+ 'IKEY'=>'keywords',
1243
+ 'ILGT'=>'lightness',
1244
+ 'ILNG'=>'language',
1245
+ 'IMED'=>'orignalmedium',
1246
+ 'IMUS'=>'composer',
1247
+ 'INAM'=>'title',
1248
+ 'IPDS'=>'productiondesigner',
1249
+ 'IPLT'=>'palette',
1250
+ 'IPRD'=>'product',
1251
+ 'IPRO'=>'producer',
1252
+ 'IPRT'=>'part',
1253
+ 'IRTD'=>'rating',
1254
+ 'ISBJ'=>'subject',
1255
+ 'ISFT'=>'software',
1256
+ 'ISGN'=>'secondarygenre',
1257
+ 'ISHP'=>'sharpness',
1258
+ 'ISRC'=>'sourcesupplier',
1259
+ 'ISRF'=>'digitizationsource',
1260
+ 'ISTD'=>'productionstudio',
1261
+ 'ISTR'=>'starring',
1262
+ 'ITCH'=>'encoded_by',
1263
+ 'IWEB'=>'url',
1264
+ 'IWRI'=>'writer'
1265
+ );
1266
+ foreach ($RIFFinfoKeyLookup as $key => $value) {
1267
+ if (isset($RIFFinfoArray[$key])) {
1268
+ foreach ($RIFFinfoArray[$key] as $commentid => $commentdata) {
1269
+ if (trim($commentdata['data']) != '') {
1270
+ if (isset($CommentsTargetArray[$value])) {
1271
+ $CommentsTargetArray[$value][] = trim($commentdata['data']);
1272
+ } else {
1273
+ $CommentsTargetArray[$value] = array(trim($commentdata['data']));
1274
+ }
1275
+ }
1276
+ }
1277
+ }
1278
+ }
1279
+ return true;
1280
+ }
1281
+
1282
+ function ParseRIFF($startoffset, $maxoffset) {
1283
+ $info = &$this->getid3->info;
1284
+
1285
+ $maxoffset = min($maxoffset, $info['avdataend']);
1286
+
1287
+ $RIFFchunk = false;
1288
+ $FoundAllChunksWeNeed = false;
1289
+
1290
+ if (($startoffset < 0) || !getid3_lib::intValueSupported($startoffset)) {
1291
+ $info['warning'][] = 'Unable to ParseRIFF() at '.$startoffset.' because beyond '.round(PHP_INT_MAX / 1073741824).'GB limit of PHP filesystem functions';
1292
+ return false;
1293
+ }
1294
+ $max_usable_offset = min(PHP_INT_MAX - 1024, $maxoffset);
1295
+ if ($maxoffset > $max_usable_offset) {
1296
+ $info['warning'][] = 'ParseRIFF() may return incomplete data for chunk starting at '.$startoffset.' because beyond it extends to '.$maxoffset.', which is beyond the '.round(PHP_INT_MAX / 1073741824).'GB limit of PHP filesystem functions';
1297
+ }
1298
+ fseek($this->getid3->fp, $startoffset, SEEK_SET);
1299
+
1300
+ while (ftell($this->getid3->fp) < $max_usable_offset) {
1301
+ $chunknamesize = fread($this->getid3->fp, 8);
1302
+ $chunkname = substr($chunknamesize, 0, 4);
1303
+ $chunksize = $this->EitherEndian2Int(substr($chunknamesize, 4, 4));
1304
+ if (strlen($chunkname) < 4) {
1305
+ $info['error'][] = 'Expecting chunk name at offset '.(ftell($this->getid3->fp) - 4).' but found nothing. Aborting RIFF parsing.';
1306
+ break;
1307
+ }
1308
+ if ($chunksize == 0) {
1309
+ if ($chunkname == 'JUNK') {
1310
+ // we'll allow zero-size JUNK frames
1311
+ } else {
1312
+ $info['warning'][] = 'Chunk size at offset '.(ftell($this->getid3->fp) - 4).' is zero. Aborting RIFF parsing.';
1313
+ break;
1314
+ }
1315
+ }
1316
+ if (($chunksize % 2) != 0) {
1317
+ // all structures are packed on word boundaries
1318
+ $chunksize++;
1319
+ }
1320
+
1321
+ switch ($chunkname) {
1322
+ case 'LIST':
1323
+ $listname = fread($this->getid3->fp, 4);
1324
+ if (preg_match('#^(movi|rec )$#i', $listname)) {
1325
+ $RIFFchunk[$listname]['offset'] = ftell($this->getid3->fp) - 4;
1326
+ $RIFFchunk[$listname]['size'] = $chunksize;
1327
+
1328
+ if ($FoundAllChunksWeNeed) {
1329
+
1330
+ // skip over
1331
+
1332
+ } else {
1333
+
1334
+ $WhereWeWere = ftell($this->getid3->fp);
1335
+ $AudioChunkHeader = fread($this->getid3->fp, 12);
1336
+ $AudioChunkStreamNum = substr($AudioChunkHeader, 0, 2);
1337
+ $AudioChunkStreamType = substr($AudioChunkHeader, 2, 2);
1338
+ $AudioChunkSize = getid3_lib::LittleEndian2Int(substr($AudioChunkHeader, 4, 4));
1339
+
1340
+ if ($AudioChunkStreamType == 'wb') {
1341
+ $FirstFourBytes = substr($AudioChunkHeader, 8, 4);
1342
+ if (preg_match('/^\xFF[\xE2-\xE7\xF2-\xF7\xFA-\xFF][\x00-\xEB]/s', $FirstFourBytes)) {
1343
+ // MP3
1344
+ if (getid3_mp3::MPEGaudioHeaderBytesValid($FirstFourBytes)) {
1345
+ $getid3_temp = new getID3();
1346
+ $getid3_temp->openfile($this->getid3->filename);
1347
+ $getid3_temp->info['avdataoffset'] = ftell($this->getid3->fp) - 4;
1348
+ $getid3_temp->info['avdataend'] = ftell($this->getid3->fp) + $AudioChunkSize;
1349
+ $getid3_mp3 = new getid3_mp3($getid3_temp);
1350
+ $getid3_mp3->getOnlyMPEGaudioInfo($getid3_temp->info['avdataoffset'], false);
1351
+ if (isset($getid3_temp->info['mpeg']['audio'])) {
1352
+ $info['mpeg']['audio'] = $getid3_temp->info['mpeg']['audio'];
1353
+ $info['audio'] = $getid3_temp->info['audio'];
1354
+ $info['audio']['dataformat'] = 'mp'.$info['mpeg']['audio']['layer'];
1355
+ $info['audio']['sample_rate'] = $info['mpeg']['audio']['sample_rate'];
1356
+ $info['audio']['channels'] = $info['mpeg']['audio']['channels'];
1357
+ $info['audio']['bitrate'] = $info['mpeg']['audio']['bitrate'];
1358
+ $info['audio']['bitrate_mode'] = strtolower($info['mpeg']['audio']['bitrate_mode']);
1359
+ //$info['bitrate'] = $info['audio']['bitrate'];
1360
+ }
1361
+ unset($getid3_temp, $getid3_mp3);
1362
+ }
1363
+
1364
+ } elseif (preg_match('/^\x0B\x77/s', $FirstFourBytes)) {
1365
+
1366
+ // AC3
1367
+ if (getid3_lib::IncludeDependency(GETID3_INCLUDEPATH.'module.audio.ac3.php', __FILE__, false)) {
1368
+ $getid3_temp = new getID3();
1369
+ $getid3_temp->openfile($this->getid3->filename);
1370
+ $getid3_temp->info['avdataoffset'] = ftell($this->getid3->fp) - 4;
1371
+ $getid3_temp->info['avdataend'] = ftell($this->getid3->fp) + $AudioChunkSize;
1372
+ $getid3_ac3 = new getid3_ac3($getid3_temp);
1373
+ $getid3_ac3->Analyze();
1374
+ if (empty($getid3_temp->info['error'])) {
1375
+ $info['audio'] = $getid3_temp->info['audio'];
1376
+ $info['ac3'] = $getid3_temp->info['ac3'];
1377
+ if (!empty($getid3_temp->info['warning'])) {
1378
+ foreach ($getid3_temp->info['warning'] as $key => $value) {
1379
+ $info['warning'][] = $value;
1380
+ }
1381
+ }
1382
+ }
1383
+ unset($getid3_temp, $getid3_ac3);
1384
+ }
1385
+
1386
+ }
1387
+
1388
+ }
1389
+
1390
+ $FoundAllChunksWeNeed = true;
1391
+ fseek($this->getid3->fp, $WhereWeWere, SEEK_SET);
1392
+
1393
+ }
1394
+ fseek($this->getid3->fp, $chunksize - 4, SEEK_CUR);
1395
+
1396
+ //} elseif (preg_match('#^[0-9]{2}(wb|pc|dc|db)$#i', $listname)) {
1397
+ //
1398
+ // // data chunk, ignore
1399
+ //
1400
+ } else {
1401
+
1402
+ if (!isset($RIFFchunk[$listname])) {
1403
+ $RIFFchunk[$listname] = array();
1404
+ }
1405
+ $LISTchunkParent = $listname;
1406
+ $LISTchunkMaxOffset = ftell($this->getid3->fp) - 4 + $chunksize;
1407
+ if ($parsedChunk = $this->ParseRIFF(ftell($this->getid3->fp), ftell($this->getid3->fp) + $chunksize - 4)) {
1408
+ $RIFFchunk[$listname] = array_merge_recursive($RIFFchunk[$listname], $parsedChunk);
1409
+ }
1410
+
1411
+ }
1412
+ break;
1413
+
1414
+ default:
1415
+ if (preg_match('#^[0-9]{2}(wb|pc|dc|db)$#', $chunkname)) {
1416
+ $nextoffset = ftell($this->getid3->fp) + $chunksize;
1417
+ if (($nextoffset < 0) || !getid3_lib::intValueSupported($nextoffset)) {
1418
+ $info['warning'][] = 'Unable to parse chunk at offset '.$nextoffset.' because beyond '.round(PHP_INT_MAX / 1073741824).'GB limit of PHP filesystem functions';
1419
+ break 2;
1420
+ }
1421
+ fseek($this->getid3->fp, $nextoffset, SEEK_SET);
1422
+ break;
1423
+ }
1424
+ $thisindex = 0;
1425
+ if (isset($RIFFchunk[$chunkname]) && is_array($RIFFchunk[$chunkname])) {
1426
+ $thisindex = count($RIFFchunk[$chunkname]);
1427
+ }
1428
+ $RIFFchunk[$chunkname][$thisindex]['offset'] = ftell($this->getid3->fp) - 8;
1429
+ $RIFFchunk[$chunkname][$thisindex]['size'] = $chunksize;
1430
+ switch ($chunkname) {
1431
+ case 'data':
1432
+ $info['avdataoffset'] = ftell($this->getid3->fp);
1433
+ $info['avdataend'] = $info['avdataoffset'] + $chunksize;
1434
+
1435
+ $RIFFdataChunkContentsTest = fread($this->getid3->fp, 36);
1436
+
1437
+ if ((strlen($RIFFdataChunkContentsTest) > 0) && preg_match('/^\xFF[\xE2-\xE7\xF2-\xF7\xFA-\xFF][\x00-\xEB]/s', substr($RIFFdataChunkContentsTest, 0, 4))) {
1438
+
1439
+ // Probably is MP3 data
1440
+ if (getid3_mp3::MPEGaudioHeaderBytesValid(substr($RIFFdataChunkContentsTest, 0, 4))) {
1441
+ $getid3_temp = new getID3();
1442
+ $getid3_temp->openfile($this->getid3->filename);
1443
+ $getid3_temp->info['avdataoffset'] = $RIFFchunk[$chunkname][$thisindex]['offset'];
1444
+ $getid3_temp->info['avdataend'] = $RIFFchunk[$chunkname][$thisindex]['offset'] + $RIFFchunk[$chunkname][$thisindex]['size'];
1445
+ $getid3_mp3 = new getid3_mp3($getid3_temp);
1446
+ $getid3_mp3->getOnlyMPEGaudioInfo($RIFFchunk[$chunkname][$thisindex]['offset'], false);
1447
+ if (empty($getid3_temp->info['error'])) {
1448
+ $info['mpeg'] = $getid3_temp->info['mpeg'];
1449
+ $info['audio'] = $getid3_temp->info['audio'];
1450
+ }
1451
+ unset($getid3_temp, $getid3_mp3);
1452
+ }
1453
+
1454
+ } elseif ((strlen($RIFFdataChunkContentsTest) > 0) && (substr($RIFFdataChunkContentsTest, 0, 2) == "\x0B\x77")) {
1455
+
1456
+ // This is probably AC-3 data
1457
+ if (getid3_lib::IncludeDependency(GETID3_INCLUDEPATH.'module.audio.ac3.php', __FILE__, false)) {
1458
+ $getid3_temp = new getID3();
1459
+ $getid3_temp->openfile($this->getid3->filename);
1460
+ $getid3_temp->info['avdataoffset'] = $RIFFchunk[$chunkname][$thisindex]['offset'];
1461
+ $getid3_temp->info['avdataend'] = $RIFFchunk[$chunkname][$thisindex]['offset'] + $RIFFchunk[$chunkname][$thisindex]['size'];
1462
+ $getid3_ac3 = new getid3_ac3($getid3_temp);
1463
+ $getid3_ac3->Analyze();
1464
+ if (empty($getid3_temp->info['error'])) {
1465
+ $info['audio'] = $getid3_temp->info['audio'];
1466
+ $info['ac3'] = $getid3_temp->info['ac3'];
1467
+ $info['warning'] = $getid3_temp->info['warning'];
1468
+ }
1469
+ unset($getid3_temp, $getid3_ac3);
1470
+ }
1471
+
1472
+ } elseif ((strlen($RIFFdataChunkContentsTest) > 0) && (substr($RIFFdataChunkContentsTest, 8, 2) == "\x77\x0B")) {
1473
+
1474
+ // Dolby Digital WAV
1475
+ // AC-3 content, but not encoded in same format as normal AC-3 file
1476
+ // For one thing, byte order is swapped
1477
+
1478
+ if (getid3_lib::IncludeDependency(GETID3_INCLUDEPATH.'module.audio.ac3.php', __FILE__, false)) {
1479
+
1480
+ // ok to use tmpfile here - only 56 bytes
1481
+ if ($RIFFtempfilename = tempnam(GETID3_TEMP_DIR, 'id3')) {
1482
+ if ($fd_temp = fopen($RIFFtempfilename, 'wb')) {
1483
+ for ($i = 0; $i < 28; $i += 2) {
1484
+ // swap byte order
1485
+ fwrite($fd_temp, substr($RIFFdataChunkContentsTest, 8 + $i + 1, 1));
1486
+ fwrite($fd_temp, substr($RIFFdataChunkContentsTest, 8 + $i + 0, 1));
1487
+ }
1488
+ fclose($fd_temp);
1489
+
1490
+ $getid3_temp = new getID3();
1491
+ $getid3_temp->openfile($RIFFtempfilename);
1492
+ $getid3_temp->info['avdataend'] = 20;
1493
+ $getid3_ac3 = new getid3_ac3($getid3_temp);
1494
+ $getid3_ac3->Analyze();
1495
+ if (empty($getid3_temp->info['error'])) {
1496
+ $info['audio'] = $getid3_temp->info['audio'];
1497
+ $info['ac3'] = $getid3_temp->info['ac3'];
1498
+ $info['warning'] = $getid3_temp->info['warning'];
1499
+ } else {
1500
+ $info['error'][] = 'Error parsing Dolby Digital WAV (AC3-in-RIFF): '.implode(';', $getid3_temp->info['error']);
1501
+ }
1502
+ unset($getid3_ac3, $getid3_temp);
1503
+ } else {
1504
+ $info['error'][] = 'Error parsing Dolby Digital WAV (AC3-in-RIFF): failed to write temp file';
1505
+ }
1506
+ unlink($RIFFtempfilename);
1507
+
1508
+ } else {
1509
+ $info['error'][] = 'Error parsing Dolby Digital WAV (AC3-in-RIFF): failed to write temp file';
1510
+ }
1511
+
1512
+ }
1513
+
1514
+ } elseif ((strlen($RIFFdataChunkContentsTest) > 0) && (substr($RIFFdataChunkContentsTest, 0, 4) == 'wvpk')) {
1515
+
1516
+ // This is WavPack data
1517
+ $info['wavpack']['offset'] = $RIFFchunk[$chunkname][$thisindex]['offset'];
1518
+ $info['wavpack']['size'] = getid3_lib::LittleEndian2Int(substr($RIFFdataChunkContentsTest, 4, 4));
1519
+ $this->RIFFparseWavPackHeader(substr($RIFFdataChunkContentsTest, 8, 28));
1520
+
1521
+ } else {
1522
+
1523
+ // This is some other kind of data (quite possibly just PCM)
1524
+ // do nothing special, just skip it
1525
+
1526
+ }
1527
+ $nextoffset = $RIFFchunk[$chunkname][$thisindex]['offset'] + 8 + $chunksize;
1528
+ if (($nextoffset < 0) || !getid3_lib::intValueSupported($nextoffset)) {
1529
+ $info['warning'][] = 'Unable to parse chunk at offset '.$nextoffset.' because beyond '.round(PHP_INT_MAX / 1073741824).'GB limit of PHP filesystem functions';
1530
+ break 3;
1531
+ }
1532
+ fseek($this->getid3->fp, $RIFFchunk[$chunkname][$thisindex]['offset'] + 8 + $chunksize, SEEK_SET);
1533
+ break;
1534
+
1535
+ case 'iXML':
1536
+ case 'bext':
1537
+ case 'cart':
1538
+ case 'fmt ':
1539
+ case 'strh':
1540
+ case 'strf':
1541
+ case 'indx':
1542
+ case 'MEXT':
1543
+ case 'DISP':
1544
+ // always read data in
1545
+ case 'JUNK':
1546
+ // should be: never read data in
1547
+ // but some programs write their version strings in a JUNK chunk (e.g. VirtualDub, AVIdemux, etc)
1548
+ if ($chunksize < 1048576) {
1549
+ if ($chunksize > 0) {
1550
+ $RIFFchunk[$chunkname][$thisindex]['data'] = fread($this->getid3->fp, $chunksize);
1551
+ if ($chunkname == 'JUNK') {
1552
+ if (preg_match('#^([\\x20-\\x7F]+)#', $RIFFchunk[$chunkname][$thisindex]['data'], $matches)) {
1553
+ // only keep text characters [chr(32)-chr(127)]
1554
+ $info['riff']['comments']['junk'][] = trim($matches[1]);
1555
+ }
1556
+ // but if nothing there, ignore
1557
+ // remove the key in either case
1558
+ unset($RIFFchunk[$chunkname][$thisindex]['data']);
1559
+ }
1560
+ }
1561
+ } else {
1562
+ $info['warning'][] = 'chunk "'.$chunkname.'" at offset '.ftell($this->getid3->fp).' is unexpectedly larger than 1MB (claims to be '.number_format($chunksize).' bytes), skipping data';
1563
+ $nextoffset = ftell($this->getid3->fp) + $chunksize;
1564
+ if (($nextoffset < 0) || !getid3_lib::intValueSupported($nextoffset)) {
1565
+ $info['warning'][] = 'Unable to parse chunk at offset '.$nextoffset.' because beyond '.round(PHP_INT_MAX / 1073741824).'GB limit of PHP filesystem functions';
1566
+ break 3;
1567
+ }
1568
+ fseek($this->getid3->fp, $nextoffset, SEEK_SET);
1569
+ }
1570
+ break;
1571
+
1572
+ default:
1573
+ if (!preg_match('#^[0-9]{2}(wb|pc|dc|db)$#', $chunkname) && !empty($LISTchunkParent) && (($RIFFchunk[$chunkname][$thisindex]['offset'] + $RIFFchunk[$chunkname][$thisindex]['size']) <= $LISTchunkMaxOffset)) {
1574
+ $RIFFchunk[$LISTchunkParent][$chunkname][$thisindex]['offset'] = $RIFFchunk[$chunkname][$thisindex]['offset'];
1575
+ $RIFFchunk[$LISTchunkParent][$chunkname][$thisindex]['size'] = $RIFFchunk[$chunkname][$thisindex]['size'];
1576
+ unset($RIFFchunk[$chunkname][$thisindex]['offset']);
1577
+ unset($RIFFchunk[$chunkname][$thisindex]['size']);
1578
+ if (isset($RIFFchunk[$chunkname][$thisindex]) && empty($RIFFchunk[$chunkname][$thisindex])) {
1579
+ unset($RIFFchunk[$chunkname][$thisindex]);
1580
+ }
1581
+ if (isset($RIFFchunk[$chunkname]) && empty($RIFFchunk[$chunkname])) {
1582
+ unset($RIFFchunk[$chunkname]);
1583
+ }
1584
+ $RIFFchunk[$LISTchunkParent][$chunkname][$thisindex]['data'] = fread($this->getid3->fp, $chunksize);
1585
+ //} elseif (in_array($chunkname, array('ID3 ')) || (($chunksize > 0) && ($chunksize < 2048))) {
1586
+ } elseif (($chunksize > 0) && ($chunksize < 2048)) {
1587
+ // only read data in if smaller than 2kB
1588
+ $RIFFchunk[$chunkname][$thisindex]['data'] = fread($this->getid3->fp, $chunksize);
1589
+ } else {
1590
+ $nextoffset = ftell($this->getid3->fp) + $chunksize;
1591
+ if (($nextoffset < 0) || !getid3_lib::intValueSupported($nextoffset)) {
1592
+ $info['warning'][] = 'Unable to parse chunk at offset '.$nextoffset.' because beyond '.round(PHP_INT_MAX / 1073741824).'GB limit of PHP filesystem functions';
1593
+ break 3;
1594
+ }
1595
+ fseek($this->getid3->fp, $nextoffset, SEEK_SET);
1596
+ }
1597
+ break;
1598
+ }
1599
+ break;
1600
+
1601
+ }
1602
+
1603
+ }
1604
+
1605
+ return $RIFFchunk;
1606
+ }
1607
+
1608
+
1609
+ function ParseRIFFdata(&$RIFFdata) {
1610
+ $info = &$this->getid3->info;
1611
+ if ($RIFFdata) {
1612
+ $tempfile = tempnam(GETID3_TEMP_DIR, 'getID3');
1613
+ $fp_temp = fopen($tempfile, 'wb');
1614
+ $RIFFdataLength = strlen($RIFFdata);
1615
+ $NewLengthString = getid3_lib::LittleEndian2String($RIFFdataLength, 4);
1616
+ for ($i = 0; $i < 4; $i++) {
1617
+ $RIFFdata{$i + 4} = $NewLengthString{$i};
1618
+ }
1619
+ fwrite($fp_temp, $RIFFdata);
1620
+ fclose($fp_temp);
1621
+
1622
+ $getid3_temp = new getID3();
1623
+ $getid3_temp->openfile($tempfile);
1624
+ $getid3_temp->info['filesize'] = $RIFFdataLength;
1625
+ $getid3_temp->info['filenamepath'] = $info['filenamepath'];
1626
+ $getid3_temp->info['tags'] = $info['tags'];
1627
+ $getid3_temp->info['warning'] = $info['warning'];
1628
+ $getid3_temp->info['error'] = $info['error'];
1629
+ $getid3_temp->info['comments'] = $info['comments'];
1630
+ $getid3_temp->info['audio'] = (isset($info['audio']) ? $info['audio'] : array());
1631
+ $getid3_temp->info['video'] = (isset($info['video']) ? $info['video'] : array());
1632
+ $getid3_riff = new getid3_riff($getid3_temp);
1633
+ $getid3_riff->Analyze();
1634
+
1635
+ $info['riff'] = $getid3_temp->info['riff'];
1636
+ $info['warning'] = $getid3_temp->info['warning'];
1637
+ $info['error'] = $getid3_temp->info['error'];
1638
+ $info['tags'] = $getid3_temp->info['tags'];
1639
+ $info['comments'] = $getid3_temp->info['comments'];
1640
+ unset($getid3_riff, $getid3_temp);
1641
+ unlink($tempfile);
1642
+ }
1643
+ return false;
1644
+ }
1645
+
1646
+
1647
+ public static function RIFFparseWAVEFORMATex($WaveFormatExData) {
1648
+ // shortcut
1649
+ $WaveFormatEx['raw'] = array();
1650
+ $WaveFormatEx_raw = &$WaveFormatEx['raw'];
1651
+
1652
+ $WaveFormatEx_raw['wFormatTag'] = getid3_lib::LittleEndian2Int(substr($WaveFormatExData, 0, 2));
1653
+ $WaveFormatEx_raw['nChannels'] = getid3_lib::LittleEndian2Int(substr($WaveFormatExData, 2, 2));
1654
+ $WaveFormatEx_raw['nSamplesPerSec'] = getid3_lib::LittleEndian2Int(substr($WaveFormatExData, 4, 4));
1655
+ $WaveFormatEx_raw['nAvgBytesPerSec'] = getid3_lib::LittleEndian2Int(substr($WaveFormatExData, 8, 4));
1656
+ $WaveFormatEx_raw['nBlockAlign'] = getid3_lib::LittleEndian2Int(substr($WaveFormatExData, 12, 2));
1657
+ $WaveFormatEx_raw['wBitsPerSample'] = getid3_lib::LittleEndian2Int(substr($WaveFormatExData, 14, 2));
1658
+ if (strlen($WaveFormatExData) > 16) {
1659
+ $WaveFormatEx_raw['cbSize'] = getid3_lib::LittleEndian2Int(substr($WaveFormatExData, 16, 2));
1660
+ }
1661
+
1662
+ $WaveFormatEx['codec'] = getid3_riff::RIFFwFormatTagLookup($WaveFormatEx_raw['wFormatTag']);
1663
+ $WaveFormatEx['channels'] = $WaveFormatEx_raw['nChannels'];
1664
+ $WaveFormatEx['sample_rate'] = $WaveFormatEx_raw['nSamplesPerSec'];
1665
+ $WaveFormatEx['bitrate'] = $WaveFormatEx_raw['nAvgBytesPerSec'] * 8;
1666
+ $WaveFormatEx['bits_per_sample'] = $WaveFormatEx_raw['wBitsPerSample'];
1667
+
1668
+ return $WaveFormatEx;
1669
+ }
1670
+
1671
+
1672
+ function RIFFparseWavPackHeader($WavPackChunkData) {
1673
+ // typedef struct {
1674
+ // char ckID [4];
1675
+ // long ckSize;
1676
+ // short version;
1677
+ // short bits; // added for version 2.00
1678
+ // short flags, shift; // added for version 3.00
1679
+ // long total_samples, crc, crc2;
1680
+ // char extension [4], extra_bc, extras [3];
1681
+ // } WavpackHeader;
1682
+
1683
+ // shortcut
1684
+ $info = &$this->getid3->info;
1685
+ $info['wavpack'] = array();
1686
+ $thisfile_wavpack = &$info['wavpack'];
1687
+
1688
+ $thisfile_wavpack['version'] = getid3_lib::LittleEndian2Int(substr($WavPackChunkData, 0, 2));
1689
+ if ($thisfile_wavpack['version'] >= 2) {
1690
+ $thisfile_wavpack['bits'] = getid3_lib::LittleEndian2Int(substr($WavPackChunkData, 2, 2));
1691
+ }
1692
+ if ($thisfile_wavpack['version'] >= 3) {
1693
+ $thisfile_wavpack['flags_raw'] = getid3_lib::LittleEndian2Int(substr($WavPackChunkData, 4, 2));
1694
+ $thisfile_wavpack['shift'] = getid3_lib::LittleEndian2Int(substr($WavPackChunkData, 6, 2));
1695
+ $thisfile_wavpack['total_samples'] = getid3_lib::LittleEndian2Int(substr($WavPackChunkData, 8, 4));
1696
+ $thisfile_wavpack['crc1'] = getid3_lib::LittleEndian2Int(substr($WavPackChunkData, 12, 4));
1697
+ $thisfile_wavpack['crc2'] = getid3_lib::LittleEndian2Int(substr($WavPackChunkData, 16, 4));
1698
+ $thisfile_wavpack['extension'] = substr($WavPackChunkData, 20, 4);
1699
+ $thisfile_wavpack['extra_bc'] = getid3_lib::LittleEndian2Int(substr($WavPackChunkData, 24, 1));
1700
+ for ($i = 0; $i <= 2; $i++) {
1701
+ $thisfile_wavpack['extras'][] = getid3_lib::LittleEndian2Int(substr($WavPackChunkData, 25 + $i, 1));
1702
+ }
1703
+
1704
+ // shortcut
1705
+ $thisfile_wavpack['flags'] = array();
1706
+ $thisfile_wavpack_flags = &$thisfile_wavpack['flags'];
1707
+
1708
+ $thisfile_wavpack_flags['mono'] = (bool) ($thisfile_wavpack['flags_raw'] & 0x000001);
1709
+ $thisfile_wavpack_flags['fast_mode'] = (bool) ($thisfile_wavpack['flags_raw'] & 0x000002);
1710
+ $thisfile_wavpack_flags['raw_mode'] = (bool) ($thisfile_wavpack['flags_raw'] & 0x000004);
1711
+ $thisfile_wavpack_flags['calc_noise'] = (bool) ($thisfile_wavpack['flags_raw'] & 0x000008);
1712
+ $thisfile_wavpack_flags['high_quality'] = (bool) ($thisfile_wavpack['flags_raw'] & 0x000010);
1713
+ $thisfile_wavpack_flags['3_byte_samples'] = (bool) ($thisfile_wavpack['flags_raw'] & 0x000020);
1714
+ $thisfile_wavpack_flags['over_20_bits'] = (bool) ($thisfile_wavpack['flags_raw'] & 0x000040);
1715
+ $thisfile_wavpack_flags['use_wvc'] = (bool) ($thisfile_wavpack['flags_raw'] & 0x000080);
1716
+ $thisfile_wavpack_flags['noiseshaping'] = (bool) ($thisfile_wavpack['flags_raw'] & 0x000100);
1717
+ $thisfile_wavpack_flags['very_fast_mode'] = (bool) ($thisfile_wavpack['flags_raw'] & 0x000200);
1718
+ $thisfile_wavpack_flags['new_high_quality'] = (bool) ($thisfile_wavpack['flags_raw'] & 0x000400);
1719
+ $thisfile_wavpack_flags['cancel_extreme'] = (bool) ($thisfile_wavpack['flags_raw'] & 0x000800);
1720
+ $thisfile_wavpack_flags['cross_decorrelation'] = (bool) ($thisfile_wavpack['flags_raw'] & 0x001000);
1721
+ $thisfile_wavpack_flags['new_decorrelation'] = (bool) ($thisfile_wavpack['flags_raw'] & 0x002000);
1722
+ $thisfile_wavpack_flags['joint_stereo'] = (bool) ($thisfile_wavpack['flags_raw'] & 0x004000);
1723
+ $thisfile_wavpack_flags['extra_decorrelation'] = (bool) ($thisfile_wavpack['flags_raw'] & 0x008000);
1724
+ $thisfile_wavpack_flags['override_noiseshape'] = (bool) ($thisfile_wavpack['flags_raw'] & 0x010000);
1725
+ $thisfile_wavpack_flags['override_jointstereo'] = (bool) ($thisfile_wavpack['flags_raw'] & 0x020000);
1726
+ $thisfile_wavpack_flags['copy_source_filetime'] = (bool) ($thisfile_wavpack['flags_raw'] & 0x040000);
1727
+ $thisfile_wavpack_flags['create_exe'] = (bool) ($thisfile_wavpack['flags_raw'] & 0x080000);
1728
+ }
1729
+
1730
+ return true;
1731
+ }
1732
+
1733
+ public static function ParseBITMAPINFOHEADER($BITMAPINFOHEADER, $littleEndian=true) {
1734
+
1735
+ $functionname = ($littleEndian ? 'LittleEndian2Int' : 'BigEndian2Int');
1736
+ $parsed['biSize'] = getid3_lib::$functionname(substr($BITMAPINFOHEADER, 0, 4)); // number of bytes required by the BITMAPINFOHEADER structure
1737
+ $parsed['biWidth'] = getid3_lib::$functionname(substr($BITMAPINFOHEADER, 4, 4)); // width of the bitmap in pixels
1738
+ $parsed['biHeight'] = getid3_lib::$functionname(substr($BITMAPINFOHEADER, 8, 4)); // height of the bitmap in pixels. If biHeight is positive, the bitmap is a 'bottom-up' DIB and its origin is the lower left corner. If biHeight is negative, the bitmap is a 'top-down' DIB and its origin is the upper left corner
1739
+ $parsed['biPlanes'] = getid3_lib::$functionname(substr($BITMAPINFOHEADER, 12, 2)); // number of color planes on the target device. In most cases this value must be set to 1
1740
+ $parsed['biBitCount'] = getid3_lib::$functionname(substr($BITMAPINFOHEADER, 14, 2)); // Specifies the number of bits per pixels
1741
+ $parsed['fourcc'] = substr($BITMAPINFOHEADER, 16, 4); // compression identifier
1742
+ $parsed['biSizeImage'] = getid3_lib::$functionname(substr($BITMAPINFOHEADER, 20, 4)); // size of the bitmap data section of the image (the actual pixel data, excluding BITMAPINFOHEADER and RGBQUAD structures)
1743
+ $parsed['biXPelsPerMeter'] = getid3_lib::$functionname(substr($BITMAPINFOHEADER, 24, 4)); // horizontal resolution, in pixels per metre, of the target device
1744
+ $parsed['biYPelsPerMeter'] = getid3_lib::$functionname(substr($BITMAPINFOHEADER, 28, 4)); // vertical resolution, in pixels per metre, of the target device
1745
+ $parsed['biClrUsed'] = getid3_lib::$functionname(substr($BITMAPINFOHEADER, 32, 4)); // actual number of color indices in the color table used by the bitmap. If this value is zero, the bitmap uses the maximum number of colors corresponding to the value of the biBitCount member for the compression mode specified by biCompression
1746
+ $parsed['biClrImportant'] = getid3_lib::$functionname(substr($BITMAPINFOHEADER, 36, 4)); // number of color indices that are considered important for displaying the bitmap. If this value is zero, all colors are important
1747
+
1748
+ return $parsed;
1749
+ }
1750
+
1751
+ static function ParseDIVXTAG($DIVXTAG) {
1752
+ // structure from "IDivX" source, Form1.frm, by "Greg Frazier of Daemonic Software Group", email: gfrazier@icestorm.net, web: http://dsg.cjb.net/
1753
+ // source available at http://files.divx-digest.com/download/c663efe7ef8ad2e90bf4af4d3ea6188a/on0SWN2r/edit/IDivX.zip
1754
+ // 'Byte Layout: '1111111111111111
1755
+ // '32 for Movie - 1 '1111111111111111
1756
+ // '28 for Author - 6 '6666666666666666
1757
+ // '4 for year - 2 '6666666666662222
1758
+ // '3 for genre - 3 '7777777777777777
1759
+ // '48 for Comments - 7 '7777777777777777
1760
+ // '1 for Rating - 4 '7777777777777777
1761
+ // '5 for Future Additions - 0 '333400000DIVXTAG
1762
+ // '128 bytes total
1763
+
1764
+ static $DIVXTAGgenre = array(
1765
+ 0 => 'Action',
1766
+ 1 => 'Action/Adventure',
1767
+ 2 => 'Adventure',
1768
+ 3 => 'Adult',
1769
+ 4 => 'Anime',
1770
+ 5 => 'Cartoon',
1771
+ 6 => 'Claymation',
1772
+ 7 => 'Comedy',
1773
+ 8 => 'Commercial',
1774
+ 9 => 'Documentary',
1775
+ 10 => 'Drama',
1776
+ 11 => 'Home Video',
1777
+ 12 => 'Horror',
1778
+ 13 => 'Infomercial',
1779
+ 14 => 'Interactive',
1780
+ 15 => 'Mystery',
1781
+ 16 => 'Music Video',
1782
+ 17 => 'Other',
1783
+ 18 => 'Religion',
1784
+ 19 => 'Sci Fi',
1785
+ 20 => 'Thriller',
1786
+ 21 => 'Western',
1787
+ );
1788
+ static $DIVXTAGrating = array(
1789
+ 0=>'Unrated',
1790
+ 1=>'G',
1791
+ 2=>'PG',
1792
+ 3=>'PG-13',
1793
+ 4=>'R',
1794
+ 5=>'NC-17'
1795
+ );
1796
+
1797
+ $parsed['title'] = trim(substr($DIVXTAG, 0, 32));
1798
+ $parsed['artist'] = trim(substr($DIVXTAG, 32, 28));
1799
+ $parsed['year'] = intval(trim(substr($DIVXTAG, 60, 4)));
1800
+ $parsed['comment'] = trim(substr($DIVXTAG, 64, 48));
1801
+ $parsed['genre_id'] = intval(trim(substr($DIVXTAG, 112, 3)));
1802
+ $parsed['rating_id'] = ord(substr($DIVXTAG, 115, 1));
1803
+ //$parsed['padding'] = substr($DIVXTAG, 116, 5); // 5-byte null
1804
+ //$parsed['magic'] = substr($DIVXTAG, 121, 7); // "DIVXTAG"
1805
+
1806
+ $parsed['genre'] = (isset($DIVXTAGgenre[$parsed['genre_id']]) ? $DIVXTAGgenre[$parsed['genre_id']] : $parsed['genre_id']);
1807
+ $parsed['rating'] = (isset($DIVXTAGrating[$parsed['rating_id']]) ? $DIVXTAGrating[$parsed['rating_id']] : $parsed['rating_id']);
1808
+ return $parsed;
1809
+ }
1810
+
1811
+ static function RIFFwaveSNDMtagLookup($tagshortname) {
1812
+ $begin = __LINE__;
1813
+
1814
+ /** This is not a comment!
1815
+
1816
+ �kwd keywords
1817
+ �BPM bpm
1818
+ �trt tracktitle
1819
+ �des description
1820
+ �gen category
1821
+ �fin featuredinstrument
1822
+ �LID longid
1823
+ �bex bwdescription
1824
+ �pub publisher
1825
+ �cdt cdtitle
1826
+ �alb library
1827
+ �com composer
1828
+
1829
+ */
1830
+
1831
+ return getid3_lib::EmbeddedLookup($tagshortname, $begin, __LINE__, __FILE__, 'riff-sndm');
1832
+ }
1833
+
1834
+ static function RIFFwFormatTagLookup($wFormatTag) {
1835
+
1836
+ $begin = __LINE__;
1837
+
1838
+ /** This is not a comment!
1839
+
1840
+ 0x0000 Microsoft Unknown Wave Format
1841
+ 0x0001 Pulse Code Modulation (PCM)
1842
+ 0x0002 Microsoft ADPCM
1843
+ 0x0003 IEEE Float
1844
+ 0x0004 Compaq Computer VSELP
1845
+ 0x0005 IBM CVSD
1846
+ 0x0006 Microsoft A-Law
1847
+ 0x0007 Microsoft mu-Law
1848
+ 0x0008 Microsoft DTS
1849
+ 0x0010 OKI ADPCM
1850
+ 0x0011 Intel DVI/IMA ADPCM
1851
+ 0x0012 Videologic MediaSpace ADPCM
1852
+ 0x0013 Sierra Semiconductor ADPCM
1853
+ 0x0014 Antex Electronics G.723 ADPCM
1854
+ 0x0015 DSP Solutions DigiSTD
1855
+ 0x0016 DSP Solutions DigiFIX
1856
+ 0x0017 Dialogic OKI ADPCM
1857
+ 0x0018 MediaVision ADPCM
1858
+ 0x0019 Hewlett-Packard CU
1859
+ 0x0020 Yamaha ADPCM
1860
+ 0x0021 Speech Compression Sonarc
1861
+ 0x0022 DSP Group TrueSpeech
1862
+ 0x0023 Echo Speech EchoSC1
1863
+ 0x0024 Audiofile AF36
1864
+ 0x0025 Audio Processing Technology APTX
1865
+ 0x0026 AudioFile AF10
1866
+ 0x0027 Prosody 1612
1867
+ 0x0028 LRC
1868
+ 0x0030 Dolby AC2
1869
+ 0x0031 Microsoft GSM 6.10
1870
+ 0x0032 MSNAudio
1871
+ 0x0033 Antex Electronics ADPCME
1872
+ 0x0034 Control Resources VQLPC
1873
+ 0x0035 DSP Solutions DigiREAL
1874
+ 0x0036 DSP Solutions DigiADPCM
1875
+ 0x0037 Control Resources CR10
1876
+ 0x0038 Natural MicroSystems VBXADPCM
1877
+ 0x0039 Crystal Semiconductor IMA ADPCM
1878
+ 0x003A EchoSC3
1879
+ 0x003B Rockwell ADPCM
1880
+ 0x003C Rockwell Digit LK
1881
+ 0x003D Xebec
1882
+ 0x0040 Antex Electronics G.721 ADPCM
1883
+ 0x0041 G.728 CELP
1884
+ 0x0042 MSG723
1885
+ 0x0050 MPEG Layer-2 or Layer-1
1886
+ 0x0052 RT24
1887
+ 0x0053 PAC
1888
+ 0x0055 MPEG Layer-3
1889
+ 0x0059 Lucent G.723
1890
+ 0x0060 Cirrus
1891
+ 0x0061 ESPCM
1892
+ 0x0062 Voxware
1893
+ 0x0063 Canopus Atrac
1894
+ 0x0064 G.726 ADPCM
1895
+ 0x0065 G.722 ADPCM
1896
+ 0x0066 DSAT
1897
+ 0x0067 DSAT Display
1898
+ 0x0069 Voxware Byte Aligned
1899
+ 0x0070 Voxware AC8
1900
+ 0x0071 Voxware AC10
1901
+ 0x0072 Voxware AC16
1902
+ 0x0073 Voxware AC20
1903
+ 0x0074 Voxware MetaVoice
1904
+ 0x0075 Voxware MetaSound
1905
+ 0x0076 Voxware RT29HW
1906
+ 0x0077 Voxware VR12
1907
+ 0x0078 Voxware VR18
1908
+ 0x0079 Voxware TQ40
1909
+ 0x0080 Softsound
1910
+ 0x0081 Voxware TQ60
1911
+ 0x0082 MSRT24
1912
+ 0x0083 G.729A
1913
+ 0x0084 MVI MV12
1914
+ 0x0085 DF G.726
1915
+ 0x0086 DF GSM610
1916
+ 0x0088 ISIAudio
1917
+ 0x0089 Onlive
1918
+ 0x0091 SBC24
1919
+ 0x0092 Dolby AC3 SPDIF
1920
+ 0x0093 MediaSonic G.723
1921
+ 0x0094 Aculab PLC Prosody 8kbps
1922
+ 0x0097 ZyXEL ADPCM
1923
+ 0x0098 Philips LPCBB
1924
+ 0x0099 Packed
1925
+ 0x00FF AAC
1926
+ 0x0100 Rhetorex ADPCM
1927
+ 0x0101 IBM mu-law
1928
+ 0x0102 IBM A-law
1929
+ 0x0103 IBM AVC Adaptive Differential Pulse Code Modulation (ADPCM)
1930
+ 0x0111 Vivo G.723
1931
+ 0x0112 Vivo Siren
1932
+ 0x0123 Digital G.723
1933
+ 0x0125 Sanyo LD ADPCM
1934
+ 0x0130 Sipro Lab Telecom ACELP NET
1935
+ 0x0131 Sipro Lab Telecom ACELP 4800
1936
+ 0x0132 Sipro Lab Telecom ACELP 8V3
1937
+ 0x0133 Sipro Lab Telecom G.729
1938
+ 0x0134 Sipro Lab Telecom G.729A
1939
+ 0x0135 Sipro Lab Telecom Kelvin
1940
+ 0x0140 Windows Media Video V8
1941
+ 0x0150 Qualcomm PureVoice
1942
+ 0x0151 Qualcomm HalfRate
1943
+ 0x0155 Ring Zero Systems TUB GSM
1944
+ 0x0160 Microsoft Audio 1
1945
+ 0x0161 Windows Media Audio V7 / V8 / V9
1946
+ 0x0162 Windows Media Audio Professional V9
1947
+ 0x0163 Windows Media Audio Lossless V9
1948
+ 0x0200 Creative Labs ADPCM
1949
+ 0x0202 Creative Labs Fastspeech8
1950
+ 0x0203 Creative Labs Fastspeech10
1951
+ 0x0210 UHER Informatic GmbH ADPCM
1952
+ 0x0220 Quarterdeck
1953
+ 0x0230 I-link Worldwide VC
1954
+ 0x0240 Aureal RAW Sport
1955
+ 0x0250 Interactive Products HSX
1956
+ 0x0251 Interactive Products RPELP
1957
+ 0x0260 Consistent Software CS2
1958
+ 0x0270 Sony SCX
1959
+ 0x0300 Fujitsu FM Towns Snd
1960
+ 0x0400 BTV Digital
1961
+ 0x0401 Intel Music Coder
1962
+ 0x0450 QDesign Music
1963
+ 0x0680 VME VMPCM
1964
+ 0x0681 AT&T Labs TPC
1965
+ 0x08AE ClearJump LiteWave
1966
+ 0x1000 Olivetti GSM
1967
+ 0x1001 Olivetti ADPCM
1968
+ 0x1002 Olivetti CELP
1969
+ 0x1003 Olivetti SBC
1970
+ 0x1004 Olivetti OPR
1971
+ 0x1100 Lernout & Hauspie Codec (0x1100)
1972
+ 0x1101 Lernout & Hauspie CELP Codec (0x1101)
1973
+ 0x1102 Lernout & Hauspie SBC Codec (0x1102)
1974
+ 0x1103 Lernout & Hauspie SBC Codec (0x1103)
1975
+ 0x1104 Lernout & Hauspie SBC Codec (0x1104)
1976
+ 0x1400 Norris
1977
+ 0x1401 AT&T ISIAudio
1978
+ 0x1500 Soundspace Music Compression
1979
+ 0x181C VoxWare RT24 Speech
1980
+ 0x1FC4 NCT Soft ALF2CD (www.nctsoft.com)
1981
+ 0x2000 Dolby AC3
1982
+ 0x2001 Dolby DTS
1983
+ 0x2002 WAVE_FORMAT_14_4
1984
+ 0x2003 WAVE_FORMAT_28_8
1985
+ 0x2004 WAVE_FORMAT_COOK
1986
+ 0x2005 WAVE_FORMAT_DNET
1987
+ 0x674F Ogg Vorbis 1
1988
+ 0x6750 Ogg Vorbis 2
1989
+ 0x6751 Ogg Vorbis 3
1990
+ 0x676F Ogg Vorbis 1+
1991
+ 0x6770 Ogg Vorbis 2+
1992
+ 0x6771 Ogg Vorbis 3+
1993
+ 0x7A21 GSM-AMR (CBR, no SID)
1994
+ 0x7A22 GSM-AMR (VBR, including SID)
1995
+ 0xFFFE WAVE_FORMAT_EXTENSIBLE
1996
+ 0xFFFF WAVE_FORMAT_DEVELOPMENT
1997
+
1998
+ */
1999
+
2000
+ return getid3_lib::EmbeddedLookup('0x'.str_pad(strtoupper(dechex($wFormatTag)), 4, '0', STR_PAD_LEFT), $begin, __LINE__, __FILE__, 'riff-wFormatTag');
2001
+
2002
+ }
2003
+
2004
+
2005
+ public static function RIFFfourccLookup($fourcc) {
2006
+
2007
+ $begin = __LINE__;
2008
+
2009
+ /** This is not a comment!
2010
+
2011
+ swot http://developer.apple.com/qa/snd/snd07.html
2012
+ ____ No Codec (____)
2013
+ _BIT BI_BITFIELDS (Raw RGB)
2014
+ _JPG JPEG compressed
2015
+ _PNG PNG compressed W3C/ISO/IEC (RFC-2083)
2016
+ _RAW Full Frames (Uncompressed)
2017
+ _RGB Raw RGB Bitmap
2018
+ _RL4 RLE 4bpp RGB
2019
+ _RL8 RLE 8bpp RGB
2020
+ 3IV1 3ivx MPEG-4 v1
2021
+ 3IV2 3ivx MPEG-4 v2
2022
+ 3IVX 3ivx MPEG-4
2023
+ AASC Autodesk Animator
2024
+ ABYR Kensington ?ABYR?
2025
+ AEMI Array Microsystems VideoONE MPEG1-I Capture
2026
+ AFLC Autodesk Animator FLC
2027
+ AFLI Autodesk Animator FLI
2028
+ AMPG Array Microsystems VideoONE MPEG
2029
+ ANIM Intel RDX (ANIM)
2030
+ AP41 AngelPotion Definitive
2031
+ ASV1 Asus Video v1
2032
+ ASV2 Asus Video v2
2033
+ ASVX Asus Video 2.0 (audio)
2034
+ AUR2 AuraVision Aura 2 Codec - YUV 4:2:2
2035
+ AURA AuraVision Aura 1 Codec - YUV 4:1:1
2036
+ AVDJ Independent JPEG Group\'s codec (AVDJ)
2037
+ AVRN Independent JPEG Group\'s codec (AVRN)
2038
+ AYUV 4:4:4 YUV (AYUV)
2039
+ AZPR Quicktime Apple Video (AZPR)
2040
+ BGR Raw RGB32
2041
+ BLZ0 Blizzard DivX MPEG-4
2042
+ BTVC Conexant Composite Video
2043
+ BINK RAD Game Tools Bink Video
2044
+ BT20 Conexant Prosumer Video
2045
+ BTCV Conexant Composite Video Codec
2046
+ BW10 Data Translation Broadway MPEG Capture
2047
+ CC12 Intel YUV12
2048
+ CDVC Canopus DV
2049
+ CFCC Digital Processing Systems DPS Perception
2050
+ CGDI Microsoft Office 97 Camcorder Video
2051
+ CHAM Winnov Caviara Champagne
2052
+ CJPG Creative WebCam JPEG
2053
+ CLJR Cirrus Logic YUV 4:1:1
2054
+ CMYK Common Data Format in Printing (Colorgraph)
2055
+ CPLA Weitek 4:2:0 YUV Planar
2056
+ CRAM Microsoft Video 1 (CRAM)
2057
+ cvid Radius Cinepak
2058
+ CVID Radius Cinepak
2059
+ CWLT Microsoft Color WLT DIB
2060
+ CYUV Creative Labs YUV
2061
+ CYUY ATI YUV
2062
+ D261 H.261
2063
+ D263 H.263
2064
+ DIB Device Independent Bitmap
2065
+ DIV1 FFmpeg OpenDivX
2066
+ DIV2 Microsoft MPEG-4 v1/v2
2067
+ DIV3 DivX ;-) MPEG-4 v3.x Low-Motion
2068
+ DIV4 DivX ;-) MPEG-4 v3.x Fast-Motion
2069
+ DIV5 DivX MPEG-4 v5.x
2070
+ DIV6 DivX ;-) (MS MPEG-4 v3.x)
2071
+ DIVX DivX MPEG-4 v4 (OpenDivX / Project Mayo)
2072
+ divx DivX MPEG-4
2073
+ DMB1 Matrox Rainbow Runner hardware MJPEG
2074
+ DMB2 Paradigm MJPEG
2075
+ DSVD ?DSVD?
2076
+ DUCK Duck TrueMotion 1.0
2077
+ DPS0 DPS/Leitch Reality Motion JPEG
2078
+ DPSC DPS/Leitch PAR Motion JPEG
2079
+ DV25 Matrox DVCPRO codec
2080
+ DV50 Matrox DVCPRO50 codec
2081
+ DVC IEC 61834 and SMPTE 314M (DVC/DV Video)
2082
+ DVCP IEC 61834 and SMPTE 314M (DVC/DV Video)
2083
+ DVHD IEC Standard DV 1125 lines @ 30fps / 1250 lines @ 25fps
2084
+ DVMA Darim Vision DVMPEG (dummy for MPEG compressor) (www.darvision.com)
2085
+ DVSL IEC Standard DV compressed in SD (SDL)
2086
+ DVAN ?DVAN?
2087
+ DVE2 InSoft DVE-2 Videoconferencing
2088
+ dvsd IEC 61834 and SMPTE 314M DVC/DV Video
2089
+ DVSD IEC 61834 and SMPTE 314M DVC/DV Video
2090
+ DVX1 Lucent DVX1000SP Video Decoder
2091
+ DVX2 Lucent DVX2000S Video Decoder
2092
+ DVX3 Lucent DVX3000S Video Decoder
2093
+ DX50 DivX v5
2094
+ DXT1 Microsoft DirectX Compressed Texture (DXT1)
2095
+ DXT2 Microsoft DirectX Compressed Texture (DXT2)
2096
+ DXT3 Microsoft DirectX Compressed Texture (DXT3)
2097
+ DXT4 Microsoft DirectX Compressed Texture (DXT4)
2098
+ DXT5 Microsoft DirectX Compressed Texture (DXT5)
2099
+ DXTC Microsoft DirectX Compressed Texture (DXTC)
2100
+ DXTn Microsoft DirectX Compressed Texture (DXTn)
2101
+ EM2V Etymonix MPEG-2 I-frame (www.etymonix.com)
2102
+ EKQ0 Elsa ?EKQ0?
2103
+ ELK0 Elsa ?ELK0?
2104
+ ESCP Eidos Escape
2105
+ ETV1 eTreppid Video ETV1
2106
+ ETV2 eTreppid Video ETV2
2107
+ ETVC eTreppid Video ETVC
2108
+ FLIC Autodesk FLI/FLC Animation
2109
+ FLV1 Sorenson Spark
2110
+ FLV4 On2 TrueMotion VP6
2111
+ FRWT Darim Vision Forward Motion JPEG (www.darvision.com)
2112
+ FRWU Darim Vision Forward Uncompressed (www.darvision.com)
2113
+ FLJP D-Vision Field Encoded Motion JPEG
2114
+ FPS1 FRAPS v1
2115
+ FRWA SoftLab-Nsk Forward Motion JPEG w/ alpha channel
2116
+ FRWD SoftLab-Nsk Forward Motion JPEG
2117
+ FVF1 Iterated Systems Fractal Video Frame
2118
+ GLZW Motion LZW (gabest@freemail.hu)
2119
+ GPEG Motion JPEG (gabest@freemail.hu)
2120
+ GWLT Microsoft Greyscale WLT DIB
2121
+ H260 Intel ITU H.260 Videoconferencing
2122
+ H261 Intel ITU H.261 Videoconferencing
2123
+ H262 Intel ITU H.262 Videoconferencing
2124
+ H263 Intel ITU H.263 Videoconferencing
2125
+ H264 Intel ITU H.264 Videoconferencing
2126
+ H265 Intel ITU H.265 Videoconferencing
2127
+ H266 Intel ITU H.266 Videoconferencing
2128
+ H267 Intel ITU H.267 Videoconferencing
2129
+ H268 Intel ITU H.268 Videoconferencing
2130
+ H269 Intel ITU H.269 Videoconferencing
2131
+ HFYU Huffman Lossless Codec
2132
+ HMCR Rendition Motion Compensation Format (HMCR)
2133
+ HMRR Rendition Motion Compensation Format (HMRR)
2134
+ I263 FFmpeg I263 decoder
2135
+ IF09 Indeo YVU9 ("YVU9 with additional delta-frame info after the U plane")
2136
+ IUYV Interlaced version of UYVY (www.leadtools.com)
2137
+ IY41 Interlaced version of Y41P (www.leadtools.com)
2138
+ IYU1 12 bit format used in mode 2 of the IEEE 1394 Digital Camera 1.04 spec IEEE standard
2139
+ IYU2 24 bit format used in mode 2 of the IEEE 1394 Digital Camera 1.04 spec IEEE standard
2140
+ IYUV Planar YUV format (8-bpp Y plane, followed by 8-bpp 2�2 U and V planes)
2141
+ i263 Intel ITU H.263 Videoconferencing (i263)
2142
+ I420 Intel Indeo 4
2143
+ IAN Intel Indeo 4 (RDX)
2144
+ ICLB InSoft CellB Videoconferencing
2145
+ IGOR Power DVD
2146
+ IJPG Intergraph JPEG
2147
+ ILVC Intel Layered Video
2148
+ ILVR ITU-T H.263+
2149
+ IPDV I-O Data Device Giga AVI DV Codec
2150
+ IR21 Intel Indeo 2.1
2151
+ IRAW Intel YUV Uncompressed
2152
+ IV30 Intel Indeo 3.0
2153
+ IV31 Intel Indeo 3.1
2154
+ IV32 Ligos Indeo 3.2
2155
+ IV33 Ligos Indeo 3.3
2156
+ IV34 Ligos Indeo 3.4
2157
+ IV35 Ligos Indeo 3.5
2158
+ IV36 Ligos Indeo 3.6
2159
+ IV37 Ligos Indeo 3.7
2160
+ IV38 Ligos Indeo 3.8
2161
+ IV39 Ligos Indeo 3.9
2162
+ IV40 Ligos Indeo Interactive 4.0
2163
+ IV41 Ligos Indeo Interactive 4.1
2164
+ IV42 Ligos Indeo Interactive 4.2
2165
+ IV43 Ligos Indeo Interactive 4.3
2166
+ IV44 Ligos Indeo Interactive 4.4
2167
+ IV45 Ligos Indeo Interactive 4.5
2168
+ IV46 Ligos Indeo Interactive 4.6
2169
+ IV47 Ligos Indeo Interactive 4.7
2170
+ IV48 Ligos Indeo Interactive 4.8
2171
+ IV49 Ligos Indeo Interactive 4.9
2172
+ IV50 Ligos Indeo Interactive 5.0
2173
+ JBYR Kensington ?JBYR?
2174
+ JPEG Still Image JPEG DIB
2175
+ JPGL Pegasus Lossless Motion JPEG
2176
+ KMVC Team17 Software Karl Morton\'s Video Codec
2177
+ LSVM Vianet Lighting Strike Vmail (Streaming) (www.vianet.com)
2178
+ LEAD LEAD Video Codec
2179
+ Ljpg LEAD MJPEG Codec
2180
+ MDVD Alex MicroDVD Video (hacked MS MPEG-4) (www.tiasoft.de)
2181
+ MJPA Morgan Motion JPEG (MJPA) (www.morgan-multimedia.com)
2182
+ MJPB Morgan Motion JPEG (MJPB) (www.morgan-multimedia.com)
2183
+ MMES Matrox MPEG-2 I-frame
2184
+ MP2v Microsoft S-Mpeg 4 version 1 (MP2v)
2185
+ MP42 Microsoft S-Mpeg 4 version 2 (MP42)
2186
+ MP43 Microsoft S-Mpeg 4 version 3 (MP43)
2187
+ MP4S Microsoft S-Mpeg 4 version 3 (MP4S)
2188
+ MP4V FFmpeg MPEG-4
2189
+ MPG1 FFmpeg MPEG 1/2
2190
+ MPG2 FFmpeg MPEG 1/2
2191
+ MPG3 FFmpeg DivX ;-) (MS MPEG-4 v3)
2192
+ MPG4 Microsoft MPEG-4
2193
+ MPGI Sigma Designs MPEG
2194
+ MPNG PNG images decoder
2195
+ MSS1 Microsoft Windows Screen Video
2196
+ MSZH LCL (Lossless Codec Library) (www.geocities.co.jp/Playtown-Denei/2837/LRC.htm)
2197
+ M261 Microsoft H.261
2198
+ M263 Microsoft H.263
2199
+ M4S2 Microsoft Fully Compliant MPEG-4 v2 simple profile (M4S2)
2200
+ m4s2 Microsoft Fully Compliant MPEG-4 v2 simple profile (m4s2)
2201
+ MC12 ATI Motion Compensation Format (MC12)
2202
+ MCAM ATI Motion Compensation Format (MCAM)
2203
+ MJ2C Morgan Multimedia Motion JPEG2000
2204
+ mJPG IBM Motion JPEG w/ Huffman Tables
2205
+ MJPG Microsoft Motion JPEG DIB
2206
+ MP42 Microsoft MPEG-4 (low-motion)
2207
+ MP43 Microsoft MPEG-4 (fast-motion)
2208
+ MP4S Microsoft MPEG-4 (MP4S)
2209
+ mp4s Microsoft MPEG-4 (mp4s)
2210
+ MPEG Chromatic Research MPEG-1 Video I-Frame
2211
+ MPG4 Microsoft MPEG-4 Video High Speed Compressor
2212
+ MPGI Sigma Designs MPEG
2213
+ MRCA FAST Multimedia Martin Regen Codec
2214
+ MRLE Microsoft Run Length Encoding
2215
+ MSVC Microsoft Video 1
2216
+ MTX1 Matrox ?MTX1?
2217
+ MTX2 Matrox ?MTX2?
2218
+ MTX3 Matrox ?MTX3?
2219
+ MTX4 Matrox ?MTX4?
2220
+ MTX5 Matrox ?MTX5?
2221
+ MTX6 Matrox ?MTX6?
2222
+ MTX7 Matrox ?MTX7?
2223
+ MTX8 Matrox ?MTX8?
2224
+ MTX9 Matrox ?MTX9?
2225
+ MV12 Motion Pixels Codec (old)
2226
+ MWV1 Aware Motion Wavelets
2227
+ nAVI SMR Codec (hack of Microsoft MPEG-4) (IRC #shadowrealm)
2228
+ NT00 NewTek LightWave HDTV YUV w/ Alpha (www.newtek.com)
2229
+ NUV1 NuppelVideo
2230
+ NTN1 Nogatech Video Compression 1
2231
+ NVS0 nVidia GeForce Texture (NVS0)
2232
+ NVS1 nVidia GeForce Texture (NVS1)
2233
+ NVS2 nVidia GeForce Texture (NVS2)
2234
+ NVS3 nVidia GeForce Texture (NVS3)
2235
+ NVS4 nVidia GeForce Texture (NVS4)
2236
+ NVS5 nVidia GeForce Texture (NVS5)
2237
+ NVT0 nVidia GeForce Texture (NVT0)
2238
+ NVT1 nVidia GeForce Texture (NVT1)
2239
+ NVT2 nVidia GeForce Texture (NVT2)
2240
+ NVT3 nVidia GeForce Texture (NVT3)
2241
+ NVT4 nVidia GeForce Texture (NVT4)
2242
+ NVT5 nVidia GeForce Texture (NVT5)
2243
+ PIXL MiroXL, Pinnacle PCTV
2244
+ PDVC I-O Data Device Digital Video Capture DV codec
2245
+ PGVV Radius Video Vision
2246
+ PHMO IBM Photomotion
2247
+ PIM1 MPEG Realtime (Pinnacle Cards)
2248
+ PIM2 Pegasus Imaging ?PIM2?
2249
+ PIMJ Pegasus Imaging Lossless JPEG
2250
+ PVEZ Horizons Technology PowerEZ
2251
+ PVMM PacketVideo Corporation MPEG-4
2252
+ PVW2 Pegasus Imaging Wavelet Compression
2253
+ Q1.0 Q-Team\'s QPEG 1.0 (www.q-team.de)
2254
+ Q1.1 Q-Team\'s QPEG 1.1 (www.q-team.de)
2255
+ QPEG Q-Team QPEG 1.0
2256
+ qpeq Q-Team QPEG 1.1
2257
+ RGB Raw BGR32
2258
+ RGBA Raw RGB w/ Alpha
2259
+ RMP4 REALmagic MPEG-4 (unauthorized XVID copy) (www.sigmadesigns.com)
2260
+ ROQV Id RoQ File Video Decoder
2261
+ RPZA Quicktime Apple Video (RPZA)
2262
+ RUD0 Rududu video codec (http://rududu.ifrance.com/rududu/)
2263
+ RV10 RealVideo 1.0 (aka RealVideo 5.0)
2264
+ RV13 RealVideo 1.0 (RV13)
2265
+ RV20 RealVideo G2
2266
+ RV30 RealVideo 8
2267
+ RV40 RealVideo 9
2268
+ RGBT Raw RGB w/ Transparency
2269
+ RLE Microsoft Run Length Encoder
2270
+ RLE4 Run Length Encoded (4bpp, 16-color)
2271
+ RLE8 Run Length Encoded (8bpp, 256-color)
2272
+ RT21 Intel Indeo RealTime Video 2.1
2273
+ rv20 RealVideo G2
2274
+ rv30 RealVideo 8
2275
+ RVX Intel RDX (RVX )
2276
+ SMC Apple Graphics (SMC )
2277
+ SP54 Logitech Sunplus Sp54 Codec for Mustek GSmart Mini 2
2278
+ SPIG Radius Spigot
2279
+ SVQ3 Sorenson Video 3 (Apple Quicktime 5)
2280
+ s422 Tekram VideoCap C210 YUV 4:2:2
2281
+ SDCC Sun Communication Digital Camera Codec
2282
+ SFMC CrystalNet Surface Fitting Method
2283
+ SMSC Radius SMSC
2284
+ SMSD Radius SMSD
2285
+ smsv WorldConnect Wavelet Video
2286
+ SPIG Radius Spigot
2287
+ SPLC Splash Studios ACM Audio Codec (www.splashstudios.net)
2288
+ SQZ2 Microsoft VXTreme Video Codec V2
2289
+ STVA ST Microelectronics CMOS Imager Data (Bayer)
2290
+ STVB ST Microelectronics CMOS Imager Data (Nudged Bayer)
2291
+ STVC ST Microelectronics CMOS Imager Data (Bunched)
2292
+ STVX ST Microelectronics CMOS Imager Data (Extended CODEC Data Format)
2293
+ STVY ST Microelectronics CMOS Imager Data (Extended CODEC Data Format with Correction Data)
2294
+ SV10 Sorenson Video R1
2295
+ SVQ1 Sorenson Video
2296
+ T420 Toshiba YUV 4:2:0
2297
+ TM2A Duck TrueMotion Archiver 2.0 (www.duck.com)
2298
+ TVJP Pinnacle/Truevision Targa 2000 board (TVJP)
2299
+ TVMJ Pinnacle/Truevision Targa 2000 board (TVMJ)
2300
+ TY0N Tecomac Low-Bit Rate Codec (www.tecomac.com)
2301
+ TY2C Trident Decompression Driver
2302
+ TLMS TeraLogic Motion Intraframe Codec (TLMS)
2303
+ TLST TeraLogic Motion Intraframe Codec (TLST)
2304
+ TM20 Duck TrueMotion 2.0
2305
+ TM2X Duck TrueMotion 2X
2306
+ TMIC TeraLogic Motion Intraframe Codec (TMIC)
2307
+ TMOT Horizons Technology TrueMotion S
2308
+ tmot Horizons TrueMotion Video Compression
2309
+ TR20 Duck TrueMotion RealTime 2.0
2310
+ TSCC TechSmith Screen Capture Codec
2311
+ TV10 Tecomac Low-Bit Rate Codec
2312
+ TY2N Trident ?TY2N?
2313
+ U263 UB Video H.263/H.263+/H.263++ Decoder
2314
+ UMP4 UB Video MPEG 4 (www.ubvideo.com)
2315
+ UYNV Nvidia UYVY packed 4:2:2
2316
+ UYVP Evans & Sutherland YCbCr 4:2:2 extended precision
2317
+ UCOD eMajix.com ClearVideo
2318
+ ULTI IBM Ultimotion
2319
+ UYVY UYVY packed 4:2:2
2320
+ V261 Lucent VX2000S
2321
+ VIFP VFAPI Reader Codec (www.yks.ne.jp/~hori/)
2322
+ VIV1 FFmpeg H263+ decoder
2323
+ VIV2 Vivo H.263
2324
+ VQC2 Vector-quantised codec 2 (research) http://eprints.ecs.soton.ac.uk/archive/00001310/01/VTC97-js.pdf)
2325
+ VTLP Alaris VideoGramPiX
2326
+ VYU9 ATI YUV (VYU9)
2327
+ VYUY ATI YUV (VYUY)
2328
+ V261 Lucent VX2000S
2329
+ V422 Vitec Multimedia 24-bit YUV 4:2:2 Format
2330
+ V655 Vitec Multimedia 16-bit YUV 4:2:2 Format
2331
+ VCR1 ATI Video Codec 1
2332
+ VCR2 ATI Video Codec 2
2333
+ VCR3 ATI VCR 3.0
2334
+ VCR4 ATI VCR 4.0
2335
+ VCR5 ATI VCR 5.0
2336
+ VCR6 ATI VCR 6.0
2337
+ VCR7 ATI VCR 7.0
2338
+ VCR8 ATI VCR 8.0
2339
+ VCR9 ATI VCR 9.0
2340
+ VDCT Vitec Multimedia Video Maker Pro DIB
2341
+ VDOM VDOnet VDOWave
2342
+ VDOW VDOnet VDOLive (H.263)
2343
+ VDTZ Darim Vison VideoTizer YUV
2344
+ VGPX Alaris VideoGramPiX
2345
+ VIDS Vitec Multimedia YUV 4:2:2 CCIR 601 for V422
2346
+ VIVO Vivo H.263 v2.00
2347
+ vivo Vivo H.263
2348
+ VIXL Miro/Pinnacle Video XL
2349
+ VLV1 VideoLogic/PURE Digital Videologic Capture
2350
+ VP30 On2 VP3.0
2351
+ VP31 On2 VP3.1
2352
+ VP6F On2 TrueMotion VP6
2353
+ VX1K Lucent VX1000S Video Codec
2354
+ VX2K Lucent VX2000S Video Codec
2355
+ VXSP Lucent VX1000SP Video Codec
2356
+ WBVC Winbond W9960
2357
+ WHAM Microsoft Video 1 (WHAM)
2358
+ WINX Winnov Software Compression
2359
+ WJPG AverMedia Winbond JPEG
2360
+ WMV1 Windows Media Video V7
2361
+ WMV2 Windows Media Video V8
2362
+ WMV3 Windows Media Video V9
2363
+ WNV1 Winnov Hardware Compression
2364
+ XYZP Extended PAL format XYZ palette (www.riff.org)
2365
+ x263 Xirlink H.263
2366
+ XLV0 NetXL Video Decoder
2367
+ XMPG Xing MPEG (I-Frame only)
2368
+ XVID XviD MPEG-4 (www.xvid.org)
2369
+ XXAN ?XXAN?
2370
+ YU92 Intel YUV (YU92)
2371
+ YUNV Nvidia Uncompressed YUV 4:2:2
2372
+ YUVP Extended PAL format YUV palette (www.riff.org)
2373
+ Y211 YUV 2:1:1 Packed
2374
+ Y411 YUV 4:1:1 Packed
2375
+ Y41B Weitek YUV 4:1:1 Planar
2376
+ Y41P Brooktree PC1 YUV 4:1:1 Packed
2377
+ Y41T Brooktree PC1 YUV 4:1:1 with transparency
2378
+ Y42B Weitek YUV 4:2:2 Planar
2379
+ Y42T Brooktree UYUV 4:2:2 with transparency
2380
+ Y422 ADS Technologies Copy of UYVY used in Pyro WebCam firewire camera
2381
+ Y800 Simple, single Y plane for monochrome images
2382
+ Y8 Grayscale video
2383
+ YC12 Intel YUV 12 codec
2384
+ YUV8 Winnov Caviar YUV8
2385
+ YUV9 Intel YUV9
2386
+ YUY2 Uncompressed YUV 4:2:2
2387
+ YUYV Canopus YUV
2388
+ YV12 YVU12 Planar
2389
+ YVU9 Intel YVU9 Planar (8-bpp Y plane, followed by 8-bpp 4x4 U and V planes)
2390
+ YVYU YVYU 4:2:2 Packed
2391
+ ZLIB Lossless Codec Library zlib compression (www.geocities.co.jp/Playtown-Denei/2837/LRC.htm)
2392
+ ZPEG Metheus Video Zipper
2393
+
2394
+ */
2395
+
2396
+ return getid3_lib::EmbeddedLookup($fourcc, $begin, __LINE__, __FILE__, 'riff-fourcc');
2397
+ }
2398
+
2399
+
2400
+ function EitherEndian2Int($byteword, $signed=false) {
2401
+ if ($this->getid3->info['fileformat'] == 'riff') {
2402
+ return getid3_lib::LittleEndian2Int($byteword, $signed);
2403
+ }
2404
+ return getid3_lib::BigEndian2Int($byteword, false, $signed);
2405
+ }
2406
+
2407
+ }
2408
+
2409
+ ?>
player.min.js ADDED
@@ -0,0 +1 @@
 
1
+ function powerpress_embed_quicktime(e,t,n,r,i){if(document.getElementById(e)){var s="video/mpeg";if(t.indexOf(".m4v")>-1)s="video/x-m4v";if(t.indexOf(".mp4")>-1)s="video/mp4";else if(t.indexOf(".m4a")>-1)s="audio/x-m4a";else if(t.indexOf(".avi")>-1)s="video/avi";else if(t.indexOf(".qt")>-1)s="video/quicktime";else if(t.indexOf(".mov")>-1)s="video/quicktime";var o="";if(s=="video/mp4"||s=="video/x-m4v")o+='<video src="'+t+'" width="'+n+'" height="'+r+'" controls autoplay>';o+='<object classid="clsid:02BF25D5-8C17-4B23-BC80-D3488ABDDC6B" width="'+n+'" height="'+r+'" codebase="http://www.apple.com/qtactivex/qtplugin.cab">\n';o+=' <param name="src" value="'+t+'" />\n';o+=' <param name="href" value="'+t+'" />\n';o+=' <param name="scale" value="'+i+'" />\n';o+=' <param name="controller" value="true" />\n';o+=' <param name="autoplay" value="true" />\n';o+=' <param name="pluginspage" value="http://www.apple.com/quicktime/download/" />\n';o+=' <embed type="'+s+'" src="'+t+'" width="'+n+'" height="'+r+'" scale="'+i+'" correction="full" cache="true" autoplay="true" controller="true" pluginspage="http://www.apple.com/quicktime/download/"></embed>';o+="</object>\n";if(s=="video/mp4"||s=="video/x-m4v")o+="</video>";document.getElementById(e).innerHTML=o;return false}return true}function powerpress_show_embed(e){if(document.getElementById("powerpress_embed_"+e)){document.getElementById("powerpress_embed_"+e).style.display="block";document.getElementById("powerpress_embed_"+e+"_t").select()}return false}function powerpress_embed_html5iframe(e,t,n,r){if(document.getElementById("powerpress_player_"+e)){var i="";i+="<iframe";i+=' class="powerpress-player-embed"';i+=' width="'+n+'"';i+=' height="'+r+'"';i+=' src="'+t+'"';i+=' frameborder="0"';i+="></iframe>";document.getElementById("powerpress_player_"+e).innerHTML=i;return false}return true}function powerpress_embed_html5v(e,t,n,r,i){if(document.getElementById("powerpress_player_"+e)){var s="";if(document.getElementById("powerpress_player_"+e).getElementsByTagName){var o=document.getElementById("powerpress_player_"+e).getElementsByTagName("img");if(o.length&&o[0].src)s=o[0].src}var u="video/mp4";if(t.indexOf(".webm")>-1)u="video/webm";if(t.indexOf(".ogg")>-1||t.indexOf(".ogv")>-1)u="video/ogg";var a=document.createElement("video");var f=false;if(!!a.canPlayType){var l=a.canPlayType(u);if(l=="probably"||l=="maybe"){f=true}else if(i){l=a.canPlayType("video/webm");if(l=="probably"||l=="maybe"){f=true}}}if(f){var c=document.createElement("source");a.width=n;a.height=r;a.controls=true;if(s)a.poster=s;c.src=t;c.type=u;a.appendChild(c);if(i){var h=document.createElement("source");h.src=i;h.type='video/webm; codecs="vp8, vorbis"';a.appendChild(h)}document.getElementById("powerpress_player_"+e).innerHTML="";document.getElementById("powerpress_player_"+e).appendChild(a);a.play()}else{delete a;pp_flashembed("powerpress_player_"+e,{src:powerpress_url+"FlowPlayerClassic.swf",width:n,height:r,wmode:"transparent"},{config:{autoPlay:true,autoBuffering:true,showFullScreenButton:true,showMenu:false,videoFile:t,loop:false,autoRewind:true,splashImageFile:s}})}if(window.powerpress_resize_player)powerpress_resize_player();return false}return true}function powerpress_embed_html5a(e,t){if(document.getElementById("powerpress_player_"+e)){var n="";if(document.getElementById("powerpress_player_"+e).getElementsByTagName){var r=document.getElementById("powerpress_player_"+e).getElementsByTagName("img");if(r.length&&r[0].src)n=r[0].src}var i="audio/mpeg";if(t.indexOf(".m4a")>-1)i="audio/x-m4a";if(t.indexOf(".ogg")>-1||t.indexOf(".oga")>-1)i="audio/ogg";var s=document.createElement("audio");var o=false;if(!!s.canPlayType){var u=s.canPlayType(i);if(u=="probably"||u=="maybe"){o=true}}if(o){var a=document.createElement("source");s.controls=true;a.src=t;a.type=i;s.appendChild(a);document.getElementById("powerpress_player_"+e).innerHTML="";document.getElementById("powerpress_player_"+e).appendChild(s);s.play()}else{delete s;if(i!="audio/ogg"){pp_flashembed("powerpress_player_"+e,{src:powerpress_url+"FlowPlayerClassic.swf",width:320,height:24,wmode:"transparent"},{config:{autoPlay:true,autoBuffering:true,showFullScreenButton:false,showMenu:false,videoFile:t,loop:false,autoRewind:true}})}else{return true}}return false}return true}function powerpress_embed_winplayer(e,t,n,r){if(document.getElementById(e)){var i="";i+='<object id="winplayer" classid="clsid:6BF52A52-394A-11d3-B153-00C04F79FAA6" width="'+n+'" height="'+r+'" standby="loading..." type="application/x-oleobject">\n';i+=' <param name="url" value="'+t+'" />\n';i+=' <param name="AutoStart" value="true" />\n';i+=' <param name="AutoSize" value="true" />\n';i+=' <param name="AllowChangeDisplaySize" value="true" />\n';i+=' <param name="standby" value="Media is loading..." />\n';i+=' <param name="AnimationAtStart" value="true" />\n';i+=' <param name="scale" value="aspect" />\n';i+=' <param name="ShowControls" value="true" />\n';i+=' <param name="ShowCaptioning" value="false" />\n';i+=' <param name="ShowDisplay" value="false" />\n';i+=' <param name="ShowStatusBar" value="false" />\n';i+=' <embed type="application/x-mplayer2" src="'+t+'" width="'+n+'" height="'+r+'" scale="aspect" AutoStart="true" ShowDisplay="0" ShowStatusBar="0" AutoSize="1" AnimationAtStart="1" AllowChangeDisplaySize="1" ShowControls="1"></embed>\n';i+="</object>\n";document.getElementById(e).innerHTML=i;return false}return true}function powerpress_embed_swf(e,t,n,r){if(document.getElementById(e)){var i="";i+='<object classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=6,0,29,0" width="'+n+'" height="'+r+'" menu="true">\n';i+=' <param name="movie" value="'+t+'" />\n';i+=' <param name="quality" value="high" />\n';i+=' <param name="menu" value="true" />\n';i+=' <param name="scale" value="noorder" />\n';i+=' <param name="quality" value="high" />\n';i+=' <embed src="'+t+'" quality="high" pluginspage="http://www.macromedia.com/go/getflashplayer" type="application/x-shockwave-flash" width="'+n+'" height="'+r+'" menu="true"></embed>';i+="</object>\n";document.getElementById(e).innerHTML=i;return false}return true}function pp_flashembed(e,t,n){function r(){var e="";if(typeof n=="function"){n=n()}if(navigator.plugins&&navigator.mimeTypes&&navigator.mimeTypes.length){e='<embed type="application/x-shockwave-flash" ';if(o.id){s(o,{name:o.id})}for(var t in o){if(o[t]!==null){e+=[t]+'="'+o[t]+'"\n '}}if(n){e+="flashvars='"+p(n)+"'"}e+="/>"}else{e='<object classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" ';e+='width="'+o.width+'" height="'+o.height+'"';if(!o.id&&document.all){o.id="_"+(""+Math.random()).substring(5)}if(o.id){e+=' id="'+o.id+'"'}e+=">";e+='\n <param name="movie" value="'+o.src+'" />';o.id=o.src=o.width=o.height=null;for(var r in o){if(o[r]!==null){e+='\n <param name="'+r+'" value="'+o[r]+'" />'}}if(n){e+='\n <param name="flashvars" value=\''+p(n)+"' />"}e+="</object>";if(l){alert(e)}}return e}function i(e){var r=setInterval(function(){var i=document;var s=i.getElementById(e);if(s){pp_flashembed(s,t,n);clearInterval(r)}else if(i&&i.getElementsByTagName&&i.getElementById&&i.body){clearInterval(r)}},13);return true}function s(e,t){if(t){for(key in t){if(t.hasOwnProperty(key)){e[key]=t[key]}}}}function p(e){var t="";for(var n in e){if(e[n]){t+=[n]+"="+d(e[n])+"&"}}return t.substring(0,t.length-1)}function d(e){switch(v(e)){case"string":return'"'+e.replace(new RegExp('(["\\\\])',"g"),"\\$1")+'"';case"array":return"["+m(e,function(e){return d(e)}).join(",")+"]";case"function":return'"function()"';case"object":var t=[];for(var n in e){if(e.hasOwnProperty(n)){t.push('"'+n+'":'+d(e[n]))}}return"{"+t.join(",")+"}"}return String(e).replace(/\s/g," ").replace(/\'/g,'"')}function v(e){if(e===null||e===undefined){return false}var t=typeof e;return t=="object"&&e.push?"array":t}function m(e,t){var n=[];for(var r in e){if(e.hasOwnProperty(r)){n[r]=t(e[r])}}return n}var o={src:"#",width:"100%",height:"100%",version:null,onFail:null,expressInstall:null,debug:false,bgcolor:"#ffffff",allowfullscreen:true,allowscriptaccess:"always",quality:"high",type:"application/x-shockwave-flash",pluginspage:"http://www.adobe.com/go/getflashplayer"};if(typeof t=="string"){t={src:t}}s(o,t);var u=pp_flashembed.getVersion();var a=o.version;var f=o.expressInstall;var l=o.debug;if(typeof e=="string"){var c=document.getElementById(e);if(c){e=c}else{return i(e)}}if(!e){return}if(!a||pp_flashembed.isSupported(a)){o.onFail=o.version=o.expressInstall=o.debug=null;e.innerHTML=r();return e.firstChild}else if(o.onFail){var h=o.onFail.call(o,pp_flashembed.getVersion(),n);if(h){e.innerHTML=h}}else if(a&&f&&pp_flashembed.isSupported([6,65])){s(o,{src:f});n={MMredirectURL:location.href,MMplayerType:"PlugIn",MMdoctitle:document.title};e.innerHTML=r()}else{if(e.innerHTML.replace(/\s/g,"")!==""){}else{e.innerHTML="<h2>Flash version "+a+" or greater is required</h2>"+"<h3>"+(u[0]>0?"Your version is "+u:"You have no flash plugin installed")+"</h3>"+"<p>Download latest version from <a href='"+o.pluginspage+"'>here</a></p>"}}if(window.attachEvent){window.attachEvent("onbeforeunload",function(){__flash_unloadHandler=function(){};__flash_savedUnloadHandler=function(){}})}return e}if(typeof jQuery=="function"){(function(e){e.fn.extend({pp_flashembed:function(e,t){return this.each(function(){pp_flashembed(this,e,t)})}})})(jQuery)}pp_flashembed=pp_flashembed||{};pp_flashembed.getVersion=function(){var e=[0,0];if(navigator.plugins&&typeof navigator.plugins["Shockwave Flash"]=="object"){var t=navigator.plugins["Shockwave Flash"].description;if(typeof t!="undefined"){t=t.replace(/^.*\s+(\S+\s+\S+$)/,"$1");var n=parseInt(t.replace(/^(.*)\..*$/,"$1"),10);var r=/r/.test(t)?parseInt(t.replace(/^.*r(.*)$/,"$1"),10):0;e=[n,r]}}else if(window.ActiveXObject){try{var i=new ActiveXObject("ShockwaveFlash.ShockwaveFlash.7")}catch(s){try{i=new ActiveXObject("ShockwaveFlash.ShockwaveFlash.6");e=[6,0];i.AllowScriptAccess="always"}catch(o){if(e[0]==6){return}}try{i=new ActiveXObject("ShockwaveFlash.ShockwaveFlash")}catch(u){}}if(typeof i=="object"){t=i.GetVariable("$version");if(typeof t!="undefined"){t=t.replace(/^\S+\s+(.*)$/,"$1").split(",");e=[parseInt(t[0],10),parseInt(t[2],10)]}}}return e};pp_flashembed.isSupported=function(e){var t=pp_flashembed.getVersion();var n=t[0]>e[0]||t[0]==e[0]&&t[1]>=e[1];return n}
powerpress-mejs.min.js ADDED
@@ -0,0 +1 @@
 
1
+ (function(e){jQuery(document).ready(function(e){if(jQuery.fn.mediaelementplayer){jQuery(".powerpress-mejs-audio, .powerpress-mejs-video").mediaelementplayer();jQuery(".mejs-play button, .mejs-overlay-play").click(function(e){var t=jQuery(this).closest(".mejs-container");var n=t.find("video,audio");if(n.attr("src")){var r=n.attr("src");if(r.indexOf("#")!=-1){var i=r.replace(/^[^#]*#/,"");if(i!=r){e.preventDefault();var s=jQuery(n)[0];if(s){s.setAttribute("src",i);s.load();setTimeout(function(){s.play()},900);return false}}}}})}})})(jQuery)
powerpress-player.php CHANGED
@@ -51,7 +51,10 @@ function powerpressplayer_init($GeneralSettings)
51
 
52
 
53
  // include what's needed for each plaer
54
- wp_enqueue_script( 'powerpress-player', powerpress_get_root_url() .'player.js');
 
 
 
55
 
56
 
57
  $enqueue_mejs = false;
@@ -442,7 +445,10 @@ function do_powerpressplayer_embed($player, $media_url, $EpisodeData = array())
442
  wp_print_scripts();
443
 
444
  $content = '';
445
- $content .= '<script type="text/javascript" src="'. powerpress_get_root_url() .'player.js"></script>'. PHP_EOL;
 
 
 
446
 
447
  $content .= '<script language="javascript" type="text/javascript"><!--'. PHP_EOL;
448
  $content .= 'powerpress_url = \''. powerpress_get_root_url() .'\''. PHP_EOL;
@@ -1129,8 +1135,11 @@ function powerpress_do_pinw($pinw, $process_podpress)
1129
  <title><?php echo __('Blubrry PowerPress Player', 'powerpress'); ?></title>
1130
  <meta name="robots" content="noindex" />
1131
  <?php
1132
-
1133
- wp_enqueue_script( 'powerpress-player', powerpress_get_root_url() .'player.js');
 
 
 
1134
 
1135
  if( version_compare($GLOBALS['wp_version'], '3.6-alpha', '>') )
1136
  {
@@ -1149,7 +1158,10 @@ function powerpress_do_pinw($pinw, $process_podpress)
1149
  wp_enqueue_style('mediaelement');
1150
  wp_enqueue_style('wp-mediaelement');
1151
  wp_enqueue_script('mediaelement');
1152
- wp_enqueue_script( 'powerpress-mejs', powerpress_get_root_url() .'powerpress-mejs.js');
 
 
 
1153
  }
1154
  }
1155
 
@@ -1450,7 +1462,7 @@ function powerpressplayer_build_mediaelementaudio($media_url, $EpisodeData=array
1450
  $content .= '<audio class="powerpress-mejs-audio" controls="controls"';
1451
 
1452
  // Set the type if required
1453
- $extension = powerpressplayer_get_extension($EpisodeData['url']);
1454
  switch( $extension )
1455
  {
1456
  case 'm4a': {
51
 
52
 
53
  // include what's needed for each plaer
54
+ if( defined('POWERPRESS_JS_DEBUG') )
55
+ wp_enqueue_script( 'powerpress-player', powerpress_get_root_url() .'player.js');
56
+ else
57
+ wp_enqueue_script( 'powerpress-player', powerpress_get_root_url() .'player.min.js');
58
 
59
 
60
  $enqueue_mejs = false;
445
  wp_print_scripts();
446
 
447
  $content = '';
448
+ if( defined('POWERPRESS_JS_DEBUG') )
449
+ $content .= '<script type="text/javascript" src="'. powerpress_get_root_url() .'player.js"></script>'. PHP_EOL;
450
+ else
451
+ $content .= '<script type="text/javascript" src="'. powerpress_get_root_url() .'player.min.js"></script>'. PHP_EOL;
452
 
453
  $content .= '<script language="javascript" type="text/javascript"><!--'. PHP_EOL;
454
  $content .= 'powerpress_url = \''. powerpress_get_root_url() .'\''. PHP_EOL;
1135
  <title><?php echo __('Blubrry PowerPress Player', 'powerpress'); ?></title>
1136
  <meta name="robots" content="noindex" />
1137
  <?php
1138
+
1139
+ if( defined('POWERPRESS_JS_DEBUG') )
1140
+ wp_enqueue_script( 'powerpress-player', powerpress_get_root_url() .'player.js');
1141
+ else
1142
+ wp_enqueue_script( 'powerpress-player', powerpress_get_root_url() .'player.min.js');
1143
 
1144
  if( version_compare($GLOBALS['wp_version'], '3.6-alpha', '>') )
1145
  {
1158
  wp_enqueue_style('mediaelement');
1159
  wp_enqueue_style('wp-mediaelement');
1160
  wp_enqueue_script('mediaelement');
1161
+ if( defined('POWERPRESS_JS_DEBUG') )
1162
+ wp_enqueue_script( 'powerpress-mejs', powerpress_get_root_url() .'powerpress-mejs.js');
1163
+ else
1164
+ wp_enqueue_script( 'powerpress-mejs', powerpress_get_root_url() .'powerpress-mejs.min.js');
1165
  }
1166
  }
1167
 
1462
  $content .= '<audio class="powerpress-mejs-audio" controls="controls"';
1463
 
1464
  // Set the type if required
1465
+ $extension = powerpressplayer_get_extension($media_url);
1466
  switch( $extension )
1467
  {
1468
  case 'm4a': {
powerpress.php CHANGED
@@ -3,7 +3,7 @@
3
  Plugin Name: Blubrry PowerPress
4
  Plugin URI: http://create.blubrry.com/resources/powerpress/
5
  Description: <a href="http://create.blubrry.com/resources/powerpress/" target="_blank">Blubrry PowerPress</a> adds podcasting support to your blog. Features include: media player, 3rd party statistics, iTunes integration, Blubrry Services (Media Statistics and Hosting) integration and a lot more.
6
- Version: 5.0.5
7
  Author: Blubrry
8
  Author URI: http://www.blubrry.com/
9
  Change Log:
@@ -32,7 +32,7 @@ if( !function_exists('add_action') )
32
  die("access denied.");
33
 
34
  // WP_PLUGIN_DIR (REMEMBER TO USE THIS DEFINE IF NEEDED)
35
- define('POWERPRESS_VERSION', '5.0.5' );
36
 
37
  // Translation support:
38
  if ( !defined('POWERPRESS_ABSPATH') )
@@ -1215,7 +1215,9 @@ function powerpress_init()
1215
 
1216
  // Add the podcast feeds;
1217
  if( !defined('POWERPRESS_NO_PODCAST_FEED') )
 
1218
  add_feed('podcast', 'powerpress_do_podcast_feed');
 
1219
 
1220
  if( $GeneralSettings && isset($GeneralSettings['custom_feeds']) && is_array($GeneralSettings['custom_feeds']) )
1221
  {
@@ -1332,7 +1334,17 @@ function powerpress_load_general_feed_settings()
1332
  if( $GeneralSettings )
1333
  {
1334
  $FeedSettingsBasic = get_option('powerpress_feed'); // Get overall feed settings
1335
-
 
 
 
 
 
 
 
 
 
 
1336
  // If we're in advanced mode and we're dealing with a category feed we're extending, lets work with it...
1337
  if( is_category() && isset($GeneralSettings['custom_cat_feeds']) && is_array($GeneralSettings['custom_cat_feeds']) && in_array( get_query_var('cat'), $GeneralSettings['custom_cat_feeds']) )
1338
  {
@@ -1414,7 +1426,7 @@ function powerpress_load_general_feed_settings()
1414
  }
1415
  }
1416
  }
1417
-
1418
  $feed_slug = get_query_var('feed');
1419
  // Are we dealing with a custom podcast channel or a custom post type podcast feed...
1420
  if( !empty($GeneralSettings['posttype_podcasting']) || !empty($GeneralSettings['custom_feeds'][ $feed_slug ]) )
3
  Plugin Name: Blubrry PowerPress
4
  Plugin URI: http://create.blubrry.com/resources/powerpress/
5
  Description: <a href="http://create.blubrry.com/resources/powerpress/" target="_blank">Blubrry PowerPress</a> adds podcasting support to your blog. Features include: media player, 3rd party statistics, iTunes integration, Blubrry Services (Media Statistics and Hosting) integration and a lot more.
6
+ Version: 5.0.6
7
  Author: Blubrry
8
  Author URI: http://www.blubrry.com/
9
  Change Log:
32
  die("access denied.");
33
 
34
  // WP_PLUGIN_DIR (REMEMBER TO USE THIS DEFINE IF NEEDED)
35
+ define('POWERPRESS_VERSION', '5.0.6' );
36
 
37
  // Translation support:
38
  if ( !defined('POWERPRESS_ABSPATH') )
1215
 
1216
  // Add the podcast feeds;
1217
  if( !defined('POWERPRESS_NO_PODCAST_FEED') )
1218
+ {
1219
  add_feed('podcast', 'powerpress_do_podcast_feed');
1220
+ }
1221
 
1222
  if( $GeneralSettings && isset($GeneralSettings['custom_feeds']) && is_array($GeneralSettings['custom_feeds']) )
1223
  {
1334
  if( $GeneralSettings )
1335
  {
1336
  $FeedSettingsBasic = get_option('powerpress_feed'); // Get overall feed settings
1337
+ if( is_feed() && defined( 'WPCACHEHOME' ) && empty($GeneralSettings['allow_feed_comments']) )
1338
+ {
1339
+ global $wp_super_cache_comments;
1340
+ $wp_super_cache_comments = 0;
1341
+ }
1342
+
1343
+ if( is_feed() && defined('W3TC') && empty($GeneralSettings['allow_feed_comments']) )
1344
+ {
1345
+ add_filter( 'w3tc_can_print_comment', function( $setting ) { return false; }, 10, 1 );
1346
+ }
1347
+
1348
  // If we're in advanced mode and we're dealing with a category feed we're extending, lets work with it...
1349
  if( is_category() && isset($GeneralSettings['custom_cat_feeds']) && is_array($GeneralSettings['custom_cat_feeds']) && in_array( get_query_var('cat'), $GeneralSettings['custom_cat_feeds']) )
1350
  {
1426
  }
1427
  }
1428
  }
1429
+
1430
  $feed_slug = get_query_var('feed');
1431
  // Are we dealing with a custom podcast channel or a custom post type podcast feed...
1432
  if( !empty($GeneralSettings['posttype_podcasting']) || !empty($GeneralSettings['custom_feeds'][ $feed_slug ]) )
powerpressadmin-basic.php CHANGED
@@ -20,6 +20,16 @@ function powerpress_admin_basic()
20
  $FeedAttribs['channel_podcast'] = true;
21
  }
22
 
 
 
 
 
 
 
 
 
 
 
23
  ?>
24
  <script type="text/javascript"><!--
25
  function CheckRedirect(obj)
@@ -158,8 +168,15 @@ jQuery(document).ready(function($) {
158
 
159
  <div id="tab2" class="powerpress_tab">
160
  <?php
 
 
 
 
 
 
161
  powerpressadmin_edit_blubrry_services($General);
162
  powerpressadmin_edit_media_statistics($General);
 
163
  ?>
164
  </div>
165
 
@@ -698,21 +715,26 @@ function powerpressadmin_edit_itunes_general($FeedSettings, $General, $FeedAttri
698
  <?php
699
  } // end itunes general
700
 
701
- function powerpressadmin_edit_blubrry_services($General)
702
  {
703
  $DisableStatsInDashboard = false;
704
  if( !empty($General['disable_dashboard_stats']) )
705
  $DisableStatsInDashboard = true;
706
 
 
 
 
 
 
707
  ?>
708
- <h3><?php echo __('Integrate Blubrry Services', 'powerpress'); ?> &nbsp; <span style="color: #CC0000; font-size: 11px;"><?php echo __('optional', 'powerpress'); ?></span></h3>
709
  <ul><li><ul>
710
  <li style="margin-left: 30px; font-size:115%;"><?php echo sprintf(__('Track your podcast downloads with Blubrry\'s <a href="%s" target="_blank">FREE Basic Statistics</a> or <a href="%s" target="_blank">Professional Media Statistics</a>.','powerpress'), 'http://create.blubrry.com/resources/podcast-media-download-statistics/basic-statistics/', 'http://create.blubrry.com/resources/podcast-media-download-statistics/'); ?></li>
711
  <li style="margin-left: 30px; font-size:115%;"><?php echo sprintf(__('Upload and publish podcast media directly from your blog with <a href="%s" target="_blank">Blubrry Media Hosting</a>.','powerpress'), 'http://create.blubrry.com/resources/podcast-media-hosting/'); ?></li>
712
  </ul></li></ul>
713
  <div style="margin-left: 40px;">
714
  <p style="font-size: 125%;">
715
- <strong><a class="button-primary thickbox" href="<?php echo admin_url(); echo wp_nonce_url( "admin.php?action=powerpress-jquery-account", 'powerpress-jquery-account'); ?>&amp;KeepThis=true&amp;TB_iframe=true&amp;width=600&amp;height=400&amp;modal=true" target="_blank"><?php echo __('Click here to configure Blubrry Statistics and Hosting services', 'powerpress'); ?></a></strong>
716
  </p>
717
  <?php
718
  if( !empty($General['blubrry_program_keyword']) )
20
  $FeedAttribs['channel_podcast'] = true;
21
  }
22
 
23
+ $MultiSiteServiceSettings = false;
24
+ if( is_multisite() )
25
+ {
26
+ $MultiSiteSettings = get_site_option('powerpress_multisite');
27
+ if( !empty($MultiSiteSettings['services_multisite_only']) )
28
+ {
29
+ $MultiSiteServiceSettings = true;
30
+ }
31
+ }
32
+
33
  ?>
34
  <script type="text/javascript"><!--
35
  function CheckRedirect(obj)
168
 
169
  <div id="tab2" class="powerpress_tab">
170
  <?php
171
+ if( $MultiSiteServiceSettings && defined('POWERPRESS_MULTISITE_VERSION') )
172
+ {
173
+ PowerPressMultiSitePlugin::edit_blubrry_services($General);
174
+ }
175
+ else
176
+ {
177
  powerpressadmin_edit_blubrry_services($General);
178
  powerpressadmin_edit_media_statistics($General);
179
+ }
180
  ?>
181
  </div>
182
 
715
  <?php
716
  } // end itunes general
717
 
718
+ function powerpressadmin_edit_blubrry_services($General, $action_url = false, $action = false)
719
  {
720
  $DisableStatsInDashboard = false;
721
  if( !empty($General['disable_dashboard_stats']) )
722
  $DisableStatsInDashboard = true;
723
 
724
+
725
+ if( $action_url == false )
726
+ $action_url = admin_url('admin.php?action=powerpress-jquery-account');
727
+ if( $action == false )
728
+ $action = 'powerpress-jquery-account';
729
  ?>
730
+ <h3><?php echo __('Integrate Blubrry Services', 'powerpress'); ?></h3>
731
  <ul><li><ul>
732
  <li style="margin-left: 30px; font-size:115%;"><?php echo sprintf(__('Track your podcast downloads with Blubrry\'s <a href="%s" target="_blank">FREE Basic Statistics</a> or <a href="%s" target="_blank">Professional Media Statistics</a>.','powerpress'), 'http://create.blubrry.com/resources/podcast-media-download-statistics/basic-statistics/', 'http://create.blubrry.com/resources/podcast-media-download-statistics/'); ?></li>
733
  <li style="margin-left: 30px; font-size:115%;"><?php echo sprintf(__('Upload and publish podcast media directly from your blog with <a href="%s" target="_blank">Blubrry Media Hosting</a>.','powerpress'), 'http://create.blubrry.com/resources/podcast-media-hosting/'); ?></li>
734
  </ul></li></ul>
735
  <div style="margin-left: 40px;">
736
  <p style="font-size: 125%;">
737
+ <strong><a class="button-primary thickbox" href="<?php echo wp_nonce_url( $action_url, $action); ?>&amp;KeepThis=true&amp;TB_iframe=true&amp;width=600&amp;height=400&amp;modal=true" target="_blank"><?php echo __('Click here to configure Blubrry Statistics and Hosting services', 'powerpress'); ?></a></strong>
738
  </p>
739
  <?php
740
  if( !empty($General['blubrry_program_keyword']) )
powerpressadmin-dashboard.php CHANGED
@@ -33,7 +33,7 @@ function powerpress_get_news($feed_url, $limit=10)
33
 
34
  function powerpress_dashboard_head()
35
  {
36
- echo "<script type=\"text/javascript\" src=\"". powerpress_get_root_url() ."player.js\"></script>\n";
37
  ?>
38
  <style type="text/css">
39
  #blubrry_stats_summary {
33
 
34
  function powerpress_dashboard_head()
35
  {
36
+ echo "<script type=\"text/javascript\" src=\"". powerpress_get_root_url() ."player.min.js\"></script>\n";
37
  ?>
38
  <style type="text/css">
39
  #blubrry_stats_summary {
powerpressadmin-defaults.php CHANGED
@@ -55,6 +55,10 @@ function powerpress_admin_defaults()
55
  $FeedSettings = powerpress_get_settings('powerpress_feed');
56
  $FeedSettings = powerpress_default_settings($FeedSettings, 'editfeed');
57
 
 
 
 
 
58
  $Step = 0;
59
  if( !empty($FeedSettings['itunes_cat_1']) && !empty($FeedSettings['email']) && !empty($FeedSettings['itunes_image']) )
60
  $Step = 1;
@@ -69,6 +73,16 @@ function powerpress_admin_defaults()
69
 
70
  if( $Step == 2 && !empty($FeedSettings['itunes_url']) )
71
  $Step = 3;
 
 
 
 
 
 
 
 
 
 
72
 
73
  ?>
74
  <script type="text/javascript"><!--
@@ -97,7 +111,14 @@ jQuery(document).ready(function($) {
97
 
98
  powerpressadmin_default_steps($FeedSettings, $General, $Step);
99
 
100
- powerpressadmin_edit_blubrry_services($General);
 
 
 
 
 
 
 
101
  ?>
102
  <h3><?php echo __('Podcast Settings', 'powerpress'); ?></h3>
103
  <table class="form-table">
55
  $FeedSettings = powerpress_get_settings('powerpress_feed');
56
  $FeedSettings = powerpress_default_settings($FeedSettings, 'editfeed');
57
 
58
+ // Make sure variables are set
59
+ if( empty($FeedSettings['title']) )
60
+ $FeedSettings['title'] = '';
61
+
62
  $Step = 0;
63
  if( !empty($FeedSettings['itunes_cat_1']) && !empty($FeedSettings['email']) && !empty($FeedSettings['itunes_image']) )
64
  $Step = 1;
73
 
74
  if( $Step == 2 && !empty($FeedSettings['itunes_url']) )
75
  $Step = 3;
76
+
77
+ $MultiSiteServiceSettings = false;
78
+ if( is_multisite() )
79
+ {
80
+ $MultiSiteSettings = get_site_option('powerpress_multisite');
81
+ if( !empty($MultiSiteSettings['services_multisite_only']) )
82
+ {
83
+ $MultiSiteServiceSettings = true;
84
+ }
85
+ }
86
 
87
  ?>
88
  <script type="text/javascript"><!--
111
 
112
  powerpressadmin_default_steps($FeedSettings, $General, $Step);
113
 
114
+ if( $MultiSiteServiceSettings && defined('POWERPRESS_MULTISITE_VERSION') )
115
+ {
116
+ PowerPressMultiSitePlugin::edit_blubrry_services($General);
117
+ }
118
+ else
119
+ {
120
+ powerpressadmin_edit_blubrry_services($General);
121
+ }
122
  ?>
123
  <h3><?php echo __('Podcast Settings', 'powerpress'); ?></h3>
124
  <table class="form-table">
powerpressadmin-editfeed.php CHANGED
@@ -650,6 +650,19 @@ if( isset($Languages[ $rss_language ]) )
650
  <input type="text" name="Feed[copyright]" style="width: 60%;" value="<?php echo $FeedSettings['copyright']; ?>" maxlength="250" />
651
  </td>
652
  </tr>
 
 
 
 
 
 
 
 
 
 
 
 
 
653
  <!-- end advanced features -->
654
  <?php } ?>
655
  </table>
650
  <input type="text" name="Feed[copyright]" style="width: 60%;" value="<?php echo $FeedSettings['copyright']; ?>" maxlength="250" />
651
  </td>
652
  </tr>
653
+ <tr valign="top">
654
+ <th scope="row">
655
+ <?php echo __('Caching Debug Comments', 'powerpress'); ?>
656
+ </th>
657
+ <td>
658
+ <label><input type="checkbox" name="General[allow_feed_comments]" value="1" <?php if( !empty($General['allow_feed_comments']) ) echo 'checked'; ?> />
659
+ <?php echo __('Allow WP Super Cache or W3 Total Cache to add HTML Comments to the bottom of your feeds', 'powerpress'); ?></label>
660
+ (<?php echo __('Recommended unchecked', 'powerpress'); ?>)
661
+ <p><?php echo __('iTunes is known to have issues with feeds that have HTML comments at the bottom.', 'powerpress'); ?></p>
662
+ <p style="margin-bottomd: 0;" class="description"><?php echo __('NOTE: This setting should only be enabled for debugging purposes.', 'powerpress'); ?></p>
663
+ </td>
664
+ </tr>
665
+
666
  <!-- end advanced features -->
667
  <?php } ?>
668
  </table>
powerpressadmin-jquery.php CHANGED
@@ -229,7 +229,7 @@ function SelectURL(url)
229
  self.parent.document.getElementById('powerpress_url_<?php echo $FeedSlug; ?>').readOnly=false;
230
  self.parent.document.getElementById('powerpress_hosting_note_<?php echo $FeedSlug; ?>').style.display='none';
231
  if( self.parent.powerpress_update_for_video )
232
- self.parent.powerpress_update_for_video(File, '<?php echo $FeedSlug; ?>');
233
  self.parent.tb_remove();
234
  }
235
  function DeleteMedia(File)
229
  self.parent.document.getElementById('powerpress_url_<?php echo $FeedSlug; ?>').readOnly=false;
230
  self.parent.document.getElementById('powerpress_hosting_note_<?php echo $FeedSlug; ?>').style.display='none';
231
  if( self.parent.powerpress_update_for_video )
232
+ self.parent.powerpress_update_for_video(url, '<?php echo $FeedSlug; ?>');
233
  self.parent.tb_remove();
234
  }
235
  function DeleteMedia(File)
powerpressadmin-player-page.php CHANGED
@@ -115,7 +115,7 @@ function powerpress_admin_players($type='audio')
115
  ?>
116
  <link rel="stylesheet" href="<?php echo powerpress_get_root_url(); ?>3rdparty/colorpicker/css/colorpicker.css" type="text/css" />
117
  <script type="text/javascript" src="<?php echo powerpress_get_root_url(); ?>3rdparty/colorpicker/js/colorpicker.js"></script>
118
- <script type="text/javascript" src="<?php echo powerpress_get_root_url(); ?>player.js"></script>
119
  <script type="text/javascript"><!--
120
 
121
  powerpress_url = '<?php echo powerpress_get_root_url(); ?>';
115
  ?>
116
  <link rel="stylesheet" href="<?php echo powerpress_get_root_url(); ?>3rdparty/colorpicker/css/colorpicker.css" type="text/css" />
117
  <script type="text/javascript" src="<?php echo powerpress_get_root_url(); ?>3rdparty/colorpicker/js/colorpicker.js"></script>
118
+ <script type="text/javascript" src="<?php echo powerpress_get_root_url(); ?>player.min.js"></script>
119
  <script type="text/javascript"><!--
120
 
121
  powerpress_url = '<?php echo powerpress_get_root_url(); ?>';
powerpressadmin.php CHANGED
@@ -437,7 +437,8 @@ function powerpress_admin_init()
437
  else
438
  $General['episode_box_order'] = 0;
439
 
440
-
 
441
 
442
  if( !isset($General['feed_links']) )
443
  $General['feed_links'] = 0;
@@ -763,7 +764,7 @@ function powerpress_admin_init()
763
  else if( $taxonomy_type == 'category' )
764
  {
765
  $Settings = get_option('powerpress_general');
766
- if( !is_array($Settings['custom_cat_feeds']) )
767
  $Settings['custom_cat_feeds'] = array();
768
 
769
  if( !in_array($term_ID, $Settings['custom_cat_feeds']) )
@@ -1265,6 +1266,8 @@ function powerpress_save_settings($SettingsNew=false, $field = 'powerpress_gener
1265
  unset($Settings['itunes_complete']);
1266
  if( isset($Settings['maximize_feed'] ) && $Settings['maximize_feed'] == 0 )
1267
  unset($Settings['maximize_feed']);
 
 
1268
  if( empty($Settings['episode_itunes_image']) )
1269
  unset($Settings['episode_itunes_image']);
1270
  }
@@ -1893,7 +1896,7 @@ function powerpress_admin_head()
1893
  // Powerpress page
1894
  if( isset($_GET['page']) && strstr($_GET['page'], 'powerpress' ) !== false )
1895
  {
1896
- echo "<script type=\"text/javascript\" src=\"". powerpress_get_root_url() ."player.js\"></script>\n";
1897
  ?>
1898
  <script type="text/javascript"><!--
1899
  function powerpress_show_field(id, show) {
@@ -2111,12 +2114,20 @@ function powerpress_get_media_info(FeedSlug)
2111
  if( defined('POWERPRESS_AJAX_DEBUG') )
2112
  echo "\t\t\t\talert(response);\n";
2113
  ?>
 
 
 
 
 
 
 
 
2114
  var Parts = response.split("\n", 5);
2115
- var FinishFeedSlug = Parts[0];
2116
 
2117
  jQuery('#powerpress_check_'+FeedSlug).css("display", 'none');
2118
 
2119
- if( FeedSlug == FinishFeedSlug && Parts[1] == 'OK' )
2120
  {
2121
  var durationChecked = jQuery('#powerpress_set_duration_0_'+FeedSlug).attr('checked');
2122
  if(typeof jQuery.prop === 'function') {
@@ -2354,7 +2365,6 @@ function powerpress_media_info_ajax()
2354
  $hosting = $_POST['hosting'];
2355
  $size = 0;
2356
  $duration = '';
2357
- $status = 'OK';
2358
  $GeneralSettings = get_option('powerpress_general');
2359
 
2360
  if( !empty($GeneralSettings['default_url']) && defined('POWERPRESS_ENABLE_HTTPS_MEDIA') )
@@ -2396,8 +2406,9 @@ function powerpress_media_info_ajax()
2396
 
2397
  if( !isset($MediaInfo['error']) && !empty($MediaInfo['length']) )
2398
  {
2399
- echo "$feed_slug\n";
2400
- echo "OK\n";
 
2401
  echo "{$MediaInfo['length']}\n";
2402
  echo powerpress_readable_duration($MediaInfo['duration'], true) ."\n";
2403
  if( isset($MediaInfo['warnings']) )
437
  else
438
  $General['episode_box_order'] = 0;
439
 
440
+ if( !isset($General['allow_feed_comments'] ) )
441
+ $General['allow_feed_comments'] = 0;
442
 
443
  if( !isset($General['feed_links']) )
444
  $General['feed_links'] = 0;
764
  else if( $taxonomy_type == 'category' )
765
  {
766
  $Settings = get_option('powerpress_general');
767
+ if( empty($Settings['custom_cat_feeds']) )
768
  $Settings['custom_cat_feeds'] = array();
769
 
770
  if( !in_array($term_ID, $Settings['custom_cat_feeds']) )
1266
  unset($Settings['itunes_complete']);
1267
  if( isset($Settings['maximize_feed'] ) && $Settings['maximize_feed'] == 0 )
1268
  unset($Settings['maximize_feed']);
1269
+ if( isset($Settings['allow_feed_comments'] ) && $Settings['allow_feed_comments'] == 0 )
1270
+ unset($Settings['allow_feed_comments']);
1271
  if( empty($Settings['episode_itunes_image']) )
1272
  unset($Settings['episode_itunes_image']);
1273
  }
1896
  // Powerpress page
1897
  if( isset($_GET['page']) && strstr($_GET['page'], 'powerpress' ) !== false )
1898
  {
1899
+ echo "<script type=\"text/javascript\" src=\"". powerpress_get_root_url() ."player.min.js\"></script>\n";
1900
  ?>
1901
  <script type="text/javascript"><!--
1902
  function powerpress_show_field(id, show) {
2114
  if( defined('POWERPRESS_AJAX_DEBUG') )
2115
  echo "\t\t\t\talert(response);\n";
2116
  ?>
2117
+ // This logic will parse beyond warning messages generated by the server that we don't know about
2118
+
2119
+ var foundAt = response.indexOf('VERIFY-OK');
2120
+ if( foundAt > 0 )
2121
+ {
2122
+ response = response.substring( foundAt );
2123
+ }
2124
+
2125
  var Parts = response.split("\n", 5);
2126
+ var FinishFeedSlug = Parts[1];
2127
 
2128
  jQuery('#powerpress_check_'+FeedSlug).css("display", 'none');
2129
 
2130
+ if( FeedSlug == FinishFeedSlug && Parts[0] == 'VERIFY-OK' )
2131
  {
2132
  var durationChecked = jQuery('#powerpress_set_duration_0_'+FeedSlug).attr('checked');
2133
  if(typeof jQuery.prop === 'function') {
2365
  $hosting = $_POST['hosting'];
2366
  $size = 0;
2367
  $duration = '';
 
2368
  $GeneralSettings = get_option('powerpress_general');
2369
 
2370
  if( !empty($GeneralSettings['default_url']) && defined('POWERPRESS_ENABLE_HTTPS_MEDIA') )
2406
 
2407
  if( !isset($MediaInfo['error']) && !empty($MediaInfo['length']) )
2408
  {
2409
+ substr('', 'abc');
2410
+ echo "VERIFY-OK\n";
2411
+ echo "$feed_slug\n"; // swap positions
2412
  echo "{$MediaInfo['length']}\n";
2413
  echo powerpress_readable_duration($MediaInfo['duration'], true) ."\n";
2414
  if( isset($MediaInfo['warnings']) )
readme.txt CHANGED
@@ -2,8 +2,8 @@
2
  Contributors: amandato, blubrry
3
  Tags: podcasting, podcast, podcaster, itunes, enclosure, zune, iphone, youtube, viddler, blip.tv, ustream, podcasting, audio, video, rss2, feed, player, media, rss, mp3, music, embed, feedburner, statistics, stats, flv, flash, id3, episodes, blubrry, webm, mp4, m4v, wordpressmu, mu, wordpress mu, multisite, multi site, mediacaster, post, plugin, posts, simple, social, dashboard, TSG, Buzzsprout, MTR, WP-boxCast, CastMyBlog, simple podcasting, seriously simple podcasting, seriously-simple-podcasting, podlove, podcast.de
4
  Requires at least: 3.0
5
- Tested up to: 3.8.1
6
- Stable tag: 5.0.5
7
  Donate link: http://create.blubrry.com/
8
  License: GPLv2 or later
9
 
@@ -174,6 +174,20 @@ To install Blubrry PowerPress manually, follow these steps:
174
  * Translation support will change in PowerPress 6.0+. Translations will be packaged in a separate plugin made available on WordPress.org. This will allow us to release translations separately and more often.
175
  * We are looking for beta testers! If you would like to beta test future versions of PowerPress, please [contact us](http://www.blubrry.com/contact.php) with your name and email.
176
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
177
  = 5.0.5 =
178
  * Released on 3/2/2014
179
  * Added logic for Blubrry Services to use alternative API servers to address random issues with session errors.
2
  Contributors: amandato, blubrry
3
  Tags: podcasting, podcast, podcaster, itunes, enclosure, zune, iphone, youtube, viddler, blip.tv, ustream, podcasting, audio, video, rss2, feed, player, media, rss, mp3, music, embed, feedburner, statistics, stats, flv, flash, id3, episodes, blubrry, webm, mp4, m4v, wordpressmu, mu, wordpress mu, multisite, multi site, mediacaster, post, plugin, posts, simple, social, dashboard, TSG, Buzzsprout, MTR, WP-boxCast, CastMyBlog, simple podcasting, seriously simple podcasting, seriously-simple-podcasting, podlove, podcast.de
4
  Requires at least: 3.0
5
+ Tested up to: 3.9
6
+ Stable tag: 5.0.6
7
  Donate link: http://create.blubrry.com/
8
  License: GPLv2 or later
9
 
174
  * Translation support will change in PowerPress 6.0+. Translations will be packaged in a separate plugin made available on WordPress.org. This will allow us to release translations separately and more often.
175
  * We are looking for beta testers! If you would like to beta test future versions of PowerPress, please [contact us](http://www.blubrry.com/contact.php) with your name and email.
176
 
177
+
178
+ = 5.0.6 =
179
+ * Released on 4/3/3014
180
+ * Added logic to deal with the WP Super Cache plugin adding HTML comments at the bottom of feeds. Setting to allow HTML comments with a note have been added to the Feed settings page.
181
+ * Added logic to deal with the W3 Total Cache plugin adding HTML comments at the bottom of feeds. Uses same setting as above.
182
+ * Added logic for Verify feature to ignore PHP Warning messages caused by other plugins.
183
+ * Added minified versions of the player and mejs javascript files. (Thanks idleberg for the suggestion)
184
+ * Added the riff module to getid3 library (thanks Kathy for reporting the riff error)
185
+ * Fixed bug with Blubrry media hosting screen, selecting already published media not returning to the post edit screen (Thanks Paul for making us aware of the bug)
186
+ * Fixed notice message found in powerpressadmin-defaults.php (thanks sbmorrissey for bringing to our attention)
187
+ * Added support for future MultiSite features.
188
+ * Tested compatibility with WordPress 3.9.
189
+
190
+
191
  = 5.0.5 =
192
  * Released on 3/2/2014
193
  * Added logic for Blubrry Services to use alternative API servers to address random issues with session errors.