1
|
|
|
<?php |
2
|
|
|
|
3
|
|
|
namespace SRF; |
4
|
|
|
|
5
|
|
|
use SMW\ResultPrinter; |
6
|
|
|
use SMWQueryResult; |
7
|
|
|
use SMWDataItem; |
8
|
|
|
use SMWDataValue; |
9
|
|
|
use SMWOutputs; |
10
|
|
|
use SRFUtils; |
11
|
|
|
|
12
|
|
|
use FormatJson; |
13
|
|
|
use Skin; |
14
|
|
|
use Html; |
15
|
|
|
use Title; |
16
|
|
|
use File; |
17
|
|
|
|
18
|
|
|
/** |
19
|
|
|
* HTML5 Audio / Video media query printer |
20
|
|
|
* |
21
|
|
|
* This printer integrates jPlayer which is a HTML5 Audio / Video |
22
|
|
|
* Javascript libray under GPL/MIT license. |
23
|
|
|
* |
24
|
|
|
* @see http://www.semantic-mediawiki.org/wiki/Help:Media_format |
25
|
|
|
* |
26
|
|
|
* @since 1.9 |
27
|
|
|
* |
28
|
|
|
* @file |
29
|
|
|
* @ingroup SRF |
30
|
|
|
* @ingroup QueryPrinter |
31
|
|
|
* |
32
|
|
|
* @licence GNU GPL v2 or later |
33
|
|
|
* @author mwjames |
34
|
|
|
*/ |
35
|
|
|
|
36
|
|
|
/** |
37
|
|
|
* This printer integrates jPlayer which is a HTML5 Audio / Video |
38
|
|
|
* Javascript libray under GPL/MIT license. |
39
|
|
|
* |
40
|
|
|
* @ingroup SRF |
41
|
|
|
* @ingroup QueryPrinter |
42
|
|
|
*/ |
43
|
|
|
class MediaPlayer extends ResultPrinter { |
44
|
|
|
|
45
|
|
|
/** |
46
|
|
|
* Specifies valid mime types supported by jPlayer |
47
|
|
|
* @var array |
48
|
|
|
*/ |
49
|
|
|
protected $validMimeTypes = array( 'mp3', 'mp4', 'webm', 'webma', 'webmv', 'ogg', 'oga', 'ogv', 'm4v', 'm4a' ); |
50
|
|
|
|
51
|
|
|
/** |
52
|
|
|
* @see SMWResultPrinter::getName |
53
|
|
|
* @return string |
54
|
|
|
*/ |
55
|
|
|
public function getName() { |
56
|
|
|
return $this->msg( 'srf-printername-media' )->text(); |
57
|
|
|
} |
58
|
|
|
|
59
|
|
|
/** |
60
|
|
|
* @see SMWResultPrinter::getResultText |
61
|
|
|
* |
62
|
|
|
* @param SMWQueryResult $result |
63
|
|
|
* @param $outputMode |
64
|
|
|
* |
65
|
|
|
* @return string |
66
|
|
|
*/ |
67
|
|
|
protected function getResultText( SMWQueryResult $result, $outputMode ) { |
68
|
|
|
|
69
|
|
|
// Data processing |
70
|
|
|
$data = $this->getResultData( $result, $outputMode ); |
71
|
|
|
|
72
|
|
|
// Check if the data processing returned any results otherwise just bailout |
73
|
|
|
if ( $data === array() ) { |
74
|
|
|
if ( $this->params['default'] !== '' ) { |
75
|
|
|
return $this->params['default']; |
76
|
|
|
} else{ |
77
|
|
|
$result->addErrors( array( $this->msg( 'srf-no-results' )->inContentLanguage()->text() ) ); |
78
|
|
|
return ''; |
79
|
|
|
} |
80
|
|
|
} else { |
81
|
|
|
// Return formatted results |
82
|
|
|
return $this->getFormatOutput( $data ); |
83
|
|
|
} |
84
|
|
|
} |
85
|
|
|
|
86
|
|
|
/** |
87
|
|
|
* Returns an array with data |
88
|
|
|
* |
89
|
|
|
* @since 1.9 |
90
|
|
|
* |
91
|
|
|
* @param SMWQueryResult $result |
92
|
|
|
* @param $outputMode |
93
|
|
|
* |
94
|
|
|
* @return array |
95
|
|
|
*/ |
96
|
|
|
protected function getResultData( SMWQueryResult $result, $outputMode ) { |
97
|
|
|
|
98
|
|
|
$data = array(); |
99
|
|
|
|
100
|
|
|
/** |
101
|
|
|
* Get all values for all rows that belong to the result set |
102
|
|
|
* @var SMWResultArray $rows |
103
|
|
|
*/ |
104
|
|
|
while ( $rows = $result->getNext() ) { |
105
|
|
|
$rowData = array(); |
106
|
|
|
$mediaType = null; |
107
|
|
|
$mimeType = null; |
108
|
|
|
|
109
|
|
|
/** |
110
|
|
|
* @var SMWResultArray $field |
111
|
|
|
* @var SMWDataValue $dataValue |
112
|
|
|
*/ |
113
|
|
|
foreach ( $rows as $field ) { |
114
|
|
|
|
115
|
|
|
// Label for the current property |
116
|
|
|
$propertyLabel = $field->getPrintRequest()->getLabel(); |
117
|
|
|
|
118
|
|
|
// Label for the current subject |
119
|
|
|
$subjectLabel = $field->getResultSubject()->getTitle()->getFullText(); |
120
|
|
|
|
121
|
|
|
if ( $propertyLabel === '' || $propertyLabel === '-' ){ |
122
|
|
|
$propertyLabel = 'subject'; |
123
|
|
|
} elseif ( $propertyLabel === 'poster' ){ |
|
|
|
|
124
|
|
|
// Label "poster" is a special case where we set the media type to video in order |
125
|
|
|
// to use the same resources that can display video and cover art |
126
|
|
|
// $data['mediaTypes'][] = 'video'; |
127
|
|
|
} |
128
|
|
|
|
129
|
|
|
// Check if the subject itself is a media source |
130
|
|
|
if ( $field->getResultSubject()->getTitle()->getNamespace() === NS_FILE && $mimeType === null ){ |
131
|
|
|
list( $mediaType, $mimeType, $source ) = $this->getMediaSource( $field->getResultSubject()->getTitle() ); |
132
|
|
|
$rowData[$mimeType] = $source; |
133
|
|
|
} |
134
|
|
|
|
135
|
|
|
while ( ( $dataValue = $field->getNextDataValue() ) !== false ) { |
136
|
|
|
// Get other data value item details |
137
|
|
|
$value = $this->getDataValueItem( $propertyLabel, $dataValue->getDataItem()->getDIType(), $dataValue, $mediaType, $mimeType, $rowData ); |
138
|
|
|
$rowData[$propertyLabel] = $value; |
139
|
|
|
} |
140
|
|
|
} |
141
|
|
|
|
142
|
|
|
// Only select relevant source data that match the validMimeTypes |
143
|
|
|
if ( $mimeType !== '' && in_array( $mimeType, $this->validMimeTypes ) ){ |
144
|
|
|
$data['mimeTypes'][] = $mimeType; |
145
|
|
|
$data['mediaTypes'][] = $mediaType; |
146
|
|
|
$data[$subjectLabel] = $rowData; |
|
|
|
|
147
|
|
|
} |
148
|
|
|
} |
149
|
|
|
|
150
|
|
|
return $data; |
151
|
|
|
} |
152
|
|
|
|
153
|
|
|
/** |
154
|
|
|
* Returns media source information |
155
|
|
|
* |
156
|
|
|
* @since 1.9 |
157
|
|
|
* |
158
|
|
|
* @param Title $title |
159
|
|
|
*/ |
160
|
|
|
private function getMediaSource( Title $title ){ |
161
|
|
|
|
162
|
|
|
// Find the file source |
163
|
|
|
$source = wfFindFile ( $title ); |
164
|
|
|
if ( $source ){ |
165
|
|
|
// $source->getExtension() returns ogg even though it is a ogv/oga (same goes for m4p) file |
166
|
|
|
// this doesn't help much therefore we do it ourselves |
167
|
|
|
$extension = $source->getExtension(); |
168
|
|
|
|
169
|
|
|
if ( in_array( $extension, array( 'ogg', 'oga', 'ogv' ) ) ) { |
170
|
|
|
$extension = strtolower( substr( $source->getName(), strrpos( $source->getName(), '.' ) + 1 ) ); |
171
|
|
|
|
172
|
|
|
// Xiph.Org recommends that .ogg only be used for Ogg Vorbis audio files |
173
|
|
|
$extension = $extension === 'ogg' ? 'oga' : $extension; |
174
|
|
|
|
175
|
|
|
$params = array( $extension === 'ogv' ? 'video' : 'audio', $extension, $source->getUrl() ); |
176
|
|
|
} elseif ( in_array( $extension, array( 'm4v', 'm4a', 'm4p' ) ) ) { |
177
|
|
|
$params = array( $extension === 'm4v' ? 'video' : 'audio', $extension, $source->getUrl() ); |
178
|
|
|
} else { |
179
|
|
|
list( $major, $minor ) = File::splitMime( $source->getMimeType() ); |
|
|
|
|
180
|
|
|
$params = array( $major, $extension, $source->getUrl() ); |
181
|
|
|
} |
182
|
|
|
} else { |
183
|
|
|
$params = array(); |
184
|
|
|
} |
185
|
|
|
return $params; |
186
|
|
|
} |
187
|
|
|
|
188
|
|
|
/** |
189
|
|
|
* Returns single data value item |
190
|
|
|
* |
191
|
|
|
* @since 1.9 |
192
|
|
|
* |
193
|
|
|
* @param string $label |
194
|
|
|
* @param integer $type |
195
|
|
|
* @param SMWDataValue $dataValue |
196
|
|
|
* @param string $mediaType |
197
|
|
|
* @param string $mimeType |
198
|
|
|
* |
199
|
|
|
* @return mixed |
200
|
|
|
*/ |
201
|
|
|
private function getDataValueItem( &$label, $type, SMWDataValue $dataValue, &$mediaType, &$mimeType, &$rowData ) { |
202
|
|
|
|
203
|
|
|
if ( $type == SMWDataItem::TYPE_WIKIPAGE && $dataValue->getTitle()->getNamespace() === NS_FILE ) { |
|
|
|
|
204
|
|
|
|
205
|
|
|
if ( $label === 'source' && $mimeType === null ) { |
206
|
|
|
|
207
|
|
|
// Identify the media source |
208
|
|
|
// and get media information |
209
|
|
|
list( $mediaType, $mimeType, $source ) = $this->getMediaSource( $dataValue->getTitle() ); |
|
|
|
|
210
|
|
|
$label = $mimeType; |
211
|
|
|
return $source; |
212
|
|
|
} elseif ( $label === 'poster' ) { |
213
|
|
|
$mediaType = 'video'; |
214
|
|
|
|
215
|
|
|
// Get the cover art image url |
216
|
|
|
$source = wfFindFile ( $dataValue->getTitle() ); |
|
|
|
|
217
|
|
|
return $source->getUrl(); |
218
|
|
|
} |
219
|
|
|
} |
220
|
|
|
|
221
|
|
|
if ( $type == SMWDataItem::TYPE_URI ) { |
222
|
|
|
|
223
|
|
|
$source = $dataValue->getDataItem()->getURI(); |
|
|
|
|
224
|
|
|
$mimeType = ''; |
225
|
|
|
|
226
|
|
|
// Get file extension from the URI |
227
|
|
|
$extension = strtolower( substr( $source, strrpos( $source, '.' ) + 1 ) ); |
228
|
|
|
|
229
|
|
|
// Xiph.Org recommends that .ogg only be used for Ogg Vorbis audio files |
230
|
|
|
if ( in_array( $extension, array( 'ogg', 'oga', 'ogv' ) ) ) { |
231
|
|
|
$mimeType = $extension === 'ogg' ? 'oga' : $extension; |
232
|
|
|
$mediaType = $extension === 'ogv' ? 'video' : 'audio'; |
233
|
|
|
} elseif ( in_array( $extension, array( 'm4v', 'm4a', 'm4p' ) ) ) { |
234
|
|
|
$mimeType = $extension; |
235
|
|
|
$mediaType = $extension === 'm4v' ? 'video' : 'audio'; |
236
|
|
|
} else { |
237
|
|
|
$mimeType = $extension; |
238
|
|
|
$mediaType = strpos( $extension, 'v' ) !== false ? 'video' : 'audio'; |
239
|
|
|
} |
240
|
|
|
|
241
|
|
|
if ( $mimeType !== '' ) { |
242
|
|
|
$rowData[$mimeType] = $source; |
243
|
|
|
} |
244
|
|
|
|
245
|
|
|
return $source; |
246
|
|
|
} |
247
|
|
|
|
248
|
|
|
return $dataValue->getWikiValue(); |
249
|
|
|
} |
250
|
|
|
|
251
|
|
|
/** |
252
|
|
|
* Prepare data for the output |
253
|
|
|
* |
254
|
|
|
* @since 1.9 |
255
|
|
|
* |
256
|
|
|
* @param array $data |
257
|
|
|
* |
258
|
|
|
* @return string |
259
|
|
|
*/ |
260
|
|
|
protected function getFormatOutput( $data ) { |
261
|
|
|
|
262
|
|
|
$ID = 'srf-' . uniqid(); |
263
|
|
|
$this->isHTML = true; |
264
|
|
|
|
265
|
|
|
// Get the media/mime types |
266
|
|
|
if ( in_array( 'video', $data['mediaTypes'] ) ){ |
267
|
|
|
$mediaType = 'video'; |
268
|
|
|
} else { |
269
|
|
|
$mediaType = 'audio'; |
270
|
|
|
} |
271
|
|
|
unset( $data['mediaTypes'] ); |
272
|
|
|
|
273
|
|
|
$mimeTypes = array_unique( $data['mimeTypes'] ); |
274
|
|
|
unset( $data['mimeTypes'] ); |
275
|
|
|
|
276
|
|
|
// Reassign output array |
277
|
|
|
$output = array( |
278
|
|
|
'data' => $data, |
279
|
|
|
'count' => count( $data ), |
280
|
|
|
'mediaType' => $mediaType, |
281
|
|
|
'mimeTypes' => implode( ',', $mimeTypes ), |
282
|
|
|
'inspector' => $this->params['inspector'] |
283
|
|
|
); |
284
|
|
|
|
285
|
|
|
$requireHeadItem = array ( $ID => FormatJson::encode( $output ) ); |
286
|
|
|
SMWOutputs::requireHeadItem( $ID, Skin::makeVariablesScript( $requireHeadItem ) ); |
287
|
|
|
|
288
|
|
|
SMWOutputs::requireResource( 'ext.jquery.jplayer.skin.' . $this->params['theme'] ); |
289
|
|
|
SMWOutputs::requireResource( 'ext.srf.formats.media' ); |
290
|
|
|
|
291
|
|
|
$processing = SRFUtils::htmlProcessingElement(); |
292
|
|
|
|
293
|
|
|
return Html::rawElement( |
294
|
|
|
'div', |
295
|
|
|
array( |
296
|
|
|
'class' => $this->params['class'] !== '' ? 'srf-media ' . $this->params['class'] : 'srf-media' |
297
|
|
|
), |
298
|
|
|
$processing . Html::element( |
299
|
|
|
'div', |
300
|
|
|
array( |
301
|
|
|
'id' => $ID, |
302
|
|
|
'class' => 'media-container', |
303
|
|
|
'style' => 'display:none;' |
304
|
|
|
), |
305
|
|
|
null |
306
|
|
|
) |
307
|
|
|
); |
308
|
|
|
} |
309
|
|
|
|
310
|
|
|
/** |
311
|
|
|
* @see SMWResultPrinter::getParamDefinitions |
312
|
|
|
* |
313
|
|
|
* @since 1.9 |
314
|
|
|
* |
315
|
|
|
* @param $definitions array of IParamDefinition |
316
|
|
|
* |
317
|
|
|
* @return array of IParamDefinition|array |
318
|
|
|
*/ |
319
|
|
|
public function getParamDefinitions( array $definitions ) { |
320
|
|
|
$params = parent::getParamDefinitions( $definitions ); |
321
|
|
|
|
322
|
|
|
$params['class'] = array( |
323
|
|
|
'message' => 'srf-paramdesc-class', |
324
|
|
|
'default' => '', |
325
|
|
|
); |
326
|
|
|
|
327
|
|
|
$params['theme'] = array( |
328
|
|
|
'message' => 'srf-paramdesc-theme', |
329
|
|
|
'default' => 'blue.monday', |
330
|
|
|
'values' => array( 'blue.monday', 'morning.light' ), |
331
|
|
|
); |
332
|
|
|
|
333
|
|
|
$params['inspector'] = array( |
334
|
|
|
'type' => 'boolean', |
335
|
|
|
'message' => 'srf-paramdesc-mediainspector', |
336
|
|
|
'default' => false, |
337
|
|
|
); |
338
|
|
|
|
339
|
|
|
return $params; |
340
|
|
|
} |
341
|
|
|
} |
342
|
|
|
|
This check looks for the bodies of
elseif
statements that have no statements or where all statements have been commented out. This may be the result of changes for debugging or the code may simply be obsolete.These
elseif
bodies can be removed. If you have an empty elseif but statements in theelse
branch, consider inverting the condition.