Code Coverage |
||||||||||
Lines |
Functions and Methods |
Classes and Traits |
||||||||
Total | |
0.00% |
0 / 37 |
|
0.00% |
0 / 10 |
CRAP | |
0.00% |
0 / 1 |
File_Ogg_Media | |
0.00% |
0 / 37 |
|
0.00% |
0 / 10 |
506 | |
0.00% |
0 / 1 |
getType | n/a |
0 / 0 |
n/a |
0 / 0 |
0 | |||||
getIdentificationString | |
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
2 | |||
_decodeCommonHeader | |
0.00% |
0 / 8 |
|
0.00% |
0 / 1 |
30 | |||
_decodeBareCommentsHeader | |
0.00% |
0 / 17 |
|
0.00% |
0 / 1 |
56 | |||
getCommentList | |
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
2 | |||
getField | |
0.00% |
0 / 5 |
|
0.00% |
0 / 1 |
12 | |||
getComments | |
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
2 | |||
getVendor | |
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
2 | |||
getHeader | |
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
2 | |||
getLength | |
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
2 | |||
getStartOffset | |
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
2 |
1 | <?php |
2 | /* vim: set expandtab tabstop=4 shiftwidth=4: */ |
3 | // +----------------------------------------------------------------------------+ |
4 | // | File_Ogg PEAR Package for Accessing Ogg Bitstreams | |
5 | // | Copyright (c) 2005-2007 | |
6 | // | David Grant <david@grant.org.uk> | |
7 | // | Tim Starling <tstarling@wikimedia.org> | |
8 | // +----------------------------------------------------------------------------+ |
9 | // | This library is free software; you can redistribute it and/or | |
10 | // | modify it under the terms of the GNU Lesser General Public | |
11 | // | License as published by the Free Software Foundation; either | |
12 | // | version 2.1 of the License, or (at your option) any later version. | |
13 | // | | |
14 | // | This library is distributed in the hope that it will be useful, | |
15 | // | but WITHOUT ANY WARRANTY; without even the implied warranty of | |
16 | // | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
17 | // | Lesser General Public License for more details. | |
18 | // | | |
19 | // | You should have received a copy of the GNU Lesser General Public | |
20 | // | License along with this library; if not, write to the Free Software | |
21 | // | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | |
22 | // +----------------------------------------------------------------------------+ |
23 | use MediaWiki\TimedMediaHandler\Handlers\OggHandler\OggException; |
24 | |
25 | /** |
26 | * Parent class for media bitstreams |
27 | * Contains some functions common to various media formats |
28 | */ |
29 | abstract class File_Ogg_Media extends File_Ogg_Bitstream |
30 | { |
31 | /** |
32 | * Maximum size of header comment to parse. |
33 | * Set to 1 MB by default. Make sure this is less than your PHP memory_limit. |
34 | */ |
35 | private const COMMENT_MAX_SIZE = 1000000; |
36 | |
37 | /** |
38 | * Array to hold each of the comments. |
39 | * |
40 | * @access private |
41 | * @var array |
42 | */ |
43 | var $_comments = array(); |
44 | |
45 | /** |
46 | * Vendor string for the stream. |
47 | * |
48 | * @access private |
49 | * @var string |
50 | */ |
51 | var $_vendor; |
52 | |
53 | /** |
54 | * Length of the stream in seconds |
55 | */ |
56 | var $_streamLength; |
57 | |
58 | /* Start offset of the stream in seconds */ |
59 | var $_startOffset = 0; |
60 | |
61 | /** |
62 | * Average bitrate for the stream. |
63 | * |
64 | * @access private |
65 | * @var float |
66 | */ |
67 | var $_avgBitrate; |
68 | |
69 | /** |
70 | * Get a short string describing the type of the stream |
71 | * @return string |
72 | */ |
73 | abstract function getType(); |
74 | |
75 | /** |
76 | * Get the 6-byte identification string expected in the common header |
77 | * @return string |
78 | */ |
79 | function getIdentificationString() |
80 | { |
81 | return ''; |
82 | } |
83 | |
84 | /** |
85 | * @access private |
86 | * @param int|false $packetType |
87 | * @param int $pageOffset |
88 | */ |
89 | function _decodeCommonHeader($packetType, $pageOffset) |
90 | { |
91 | fseek($this->_filePointer, $this->_streamData['pages'][$pageOffset]['body_offset'], SEEK_SET); |
92 | if ($packetType !== false) { |
93 | // Check if this is the correct header. |
94 | $packet = unpack("Cdata", fread($this->_filePointer, 1)); |
95 | if ($packet['data'] != $packetType) |
96 | throw new OggException("Stream Undecodable", OGG_ERROR_UNDECODABLE); |
97 | |
98 | // The following six characters should be equal to getIdentificationString() |
99 | $id = $this->getIdentificationString(); |
100 | if ($id !== '' && fread($this->_filePointer, strlen($id)) !== $id) |
101 | throw new OggException("Stream is undecodable due to a malformed header.", OGG_ERROR_UNDECODABLE); |
102 | } // else seek only, no common header |
103 | } |
104 | |
105 | /** |
106 | * Parse a Vorbis-style comments header. |
107 | * |
108 | * This function parses the comments header. The comments header contains a series of |
109 | * UTF-8 comments related to the audio encoded in the stream. This header also contains |
110 | * a string to identify the encoding software. More details on the comments header can |
111 | * be found at the following location: http://xiph.org/vorbis/doc/v-comment.html |
112 | * |
113 | * @access private |
114 | */ |
115 | function _decodeBareCommentsHeader() |
116 | { |
117 | // Decode the vendor string length as a 32-bit unsigned integer. |
118 | $vendor_len = unpack("Vdata", fread($this->_filePointer, 4)); |
119 | if ( $vendor_len['data'] > 0 ) { |
120 | // Retrieve the vendor string from the stream. |
121 | $this->_vendor = fread($this->_filePointer, $vendor_len['data']); |
122 | } else { |
123 | $this->_vendor = ''; |
124 | } |
125 | // Decode the size of the comments list as a 32-bit unsigned integer. |
126 | $comment_list_length = unpack("Vdata", fread($this->_filePointer, 4)); |
127 | // Iterate through the comments list. |
128 | for ($i = 0; $i < $comment_list_length['data']; ++$i) { |
129 | // Unpack the length of this comment. |
130 | $comment_length = unpack("Vdata", fread($this->_filePointer, 4)); |
131 | |
132 | if ( $comment_length['data'] <= 0 || $comment_length['data'] > self::COMMENT_MAX_SIZE ) { |
133 | continue; |
134 | } |
135 | |
136 | // Comments are in the format 'ARTIST=Super Furry Animals', so split it on the equals character. |
137 | // NOTE: Equals characters are strictly prohibited in the title part of a comment |
138 | $comment = explode("=", fread($this->_filePointer, $comment_length['data']), 2); |
139 | $comment_title = (string) $comment[0]; |
140 | $comment_value = (string)( $comment[1] ?? '' ); |
141 | |
142 | // Check if the comment type (e.g. ARTIST) already exists. If it does, |
143 | // take the new value, and the existing value (or array) and insert it |
144 | // into a new array. This is important, since each comment type may have |
145 | // multiple instances (e.g. ARTIST for a collaboration) and we should not |
146 | // overwrite the previous value. |
147 | if (isset($this->_comments[$comment_title])) { |
148 | if (is_array($this->_comments[$comment_title])) |
149 | $this->_comments[$comment_title][] = $comment_value; |
150 | else |
151 | $this->_comments[$comment_title] = array($this->_comments[$comment_title], $comment_value); |
152 | } else |
153 | $this->_comments[$comment_title] = $comment_value; |
154 | } |
155 | } |
156 | |
157 | /** |
158 | * Provides a list of the comments extracted from the Vorbis stream. |
159 | * |
160 | * It is recommended that the user fully inspect the array returned by this function |
161 | * rather than blindly requesting a comment in false belief that it will always |
162 | * be present. Whilst the Vorbis specification dictates a number of popular |
163 | * comments (e.g. TITLE, ARTIST, etc.) for use in Vorbis streams, they are not |
164 | * guaranteed to appear. |
165 | * |
166 | * @access public |
167 | * @return array |
168 | */ |
169 | function getCommentList() |
170 | { |
171 | return (array_keys($this->_comments)); |
172 | } |
173 | |
174 | /** |
175 | * Provides an interface to the numerous comments located with a Vorbis stream. |
176 | * |
177 | * A Vorbis stream may contain one or more instances of each comment, so the user |
178 | * should check the variable type before printing out the result of this method. |
179 | * The situation in which multiple instances of a comment occurring are not as |
180 | * rare as one might think, since they are conceivable at least for ARTIST comments |
181 | * in the situation where a track is a duet. |
182 | * |
183 | * @access public |
184 | * @param string $commentTitle Comment title to search for, e.g. TITLE. |
185 | * @param string $separator String to separate multiple values. |
186 | * @return string |
187 | */ |
188 | function getField($commentTitle, $separator = ", ") |
189 | { |
190 | if (isset($this->_comments[$commentTitle])) { |
191 | if (is_array($this->_comments[$commentTitle])) |
192 | return (implode($separator, $this->_comments[$commentTitle])); |
193 | else |
194 | return ($this->_comments[$commentTitle]); |
195 | } else |
196 | // The comment doesn't exist in this file. The user should've called getCommentList first. |
197 | return (""); |
198 | } |
199 | |
200 | /** |
201 | * Get the entire comments array. |
202 | * May return an empty array if the bitstream does not support comments. |
203 | * |
204 | * @access public |
205 | * @return array |
206 | */ |
207 | function getComments() { |
208 | return $this->_comments; |
209 | } |
210 | |
211 | /** |
212 | * Vendor of software used to encode this stream. |
213 | * |
214 | * Gives the vendor string for the software used to encode this stream. |
215 | * It is common to find libVorbis here. The majority of encoders appear |
216 | * to use libvorbis from Xiph.org. |
217 | * |
218 | * @access public |
219 | * @return string |
220 | */ |
221 | function getVendor() |
222 | { |
223 | return ($this->_vendor); |
224 | } |
225 | |
226 | /** |
227 | * Get an associative array containing header information about the stream |
228 | * @access public |
229 | * @return array |
230 | */ |
231 | function getHeader() |
232 | { |
233 | return array(); |
234 | } |
235 | |
236 | /** |
237 | * Get the length of the stream in seconds |
238 | * @return float |
239 | */ |
240 | function getLength() |
241 | { |
242 | return $this->_streamLength; |
243 | } |
244 | /** |
245 | * Get the start offset of the stream in seconds |
246 | * |
247 | * @return float |
248 | */ |
249 | function getStartOffset(){ |
250 | return $this->_startOffset; |
251 | } |
252 | } |