Index: trunk/extensions/TimedMediaHandler/handlers/WebMHandler/WebMHandler.php |
— | — | @@ -88,7 +88,10 @@ |
89 | 89 | |
90 | 90 | return $streamTypes; |
91 | 91 | } |
92 | | - |
| 92 | + function getBitrate($file ){ |
| 93 | + $metadata = self::unpackMetadata( $file->getMetadata() ); |
| 94 | + return $metadata['bitrate']; |
| 95 | + } |
93 | 96 | function getLength( $file ) { |
94 | 97 | $metadata = $this->unpackMetadata( $file->getMetadata() ); |
95 | 98 | if ( !$metadata || isset( $metadata['error'] ) ) { |
— | — | @@ -110,7 +113,15 @@ |
111 | 114 | } |
112 | 115 | |
113 | 116 | function getLongDesc( $file ) { |
114 | | - return 'long desc'; |
| 117 | + global $wgLang; |
| 118 | + return wfMsg('timedmedia-webm-long-video', |
| 119 | + implode( '/', $this->getStreamTypes( $file ) ), |
| 120 | + $wgLang->formatTimePeriod( $this->getLength($file) ), |
| 121 | + $wgLang->formatBitrate( $this->getBitRate( $file ) ), |
| 122 | + $wgLang->formatNum( $file->getWidth() ), |
| 123 | + $wgLang->formatNum( $file->getHeight() ) |
| 124 | + ); |
| 125 | + |
115 | 126 | } |
116 | 127 | |
117 | 128 | } |
\ No newline at end of file |
Index: trunk/extensions/TimedMediaHandler/handlers/OggHandler/OggHandler.php |
— | — | @@ -159,13 +159,27 @@ |
160 | 160 | $size += $stream['size']; |
161 | 161 | } |
162 | 162 | } |
163 | | - $bitrate = $length == 0 ? 0 : $size / $length * 8; |
164 | 163 | return wfMsg( $msg, implode( '/', $streamTypes ), |
165 | 164 | $wgLang->formatTimePeriod( $length ), |
166 | | - $wgLang->formatBitrate( $bitrate ), |
| 165 | + $wgLang->formatBitrate( $this->getBitRate( $file ) ), |
167 | 166 | $wgLang->formatNum( $file->getWidth() ), |
168 | 167 | $wgLang->formatNum( $file->getHeight() ) |
169 | 168 | ); |
170 | 169 | } |
171 | 170 | |
| 171 | + function getBitRate( &$file ){ |
| 172 | + $size = 0; |
| 173 | + $unpacked = $this->unpackMetadata( $file->getMetadata() ); |
| 174 | + if ( !$unpacked || isset( $metadata['error'] ) ) { |
| 175 | + $length = 0; |
| 176 | + } else { |
| 177 | + $length = $this->getLength( $file ); |
| 178 | + foreach ( $unpacked['streams'] as $stream ) { |
| 179 | + if( isset( $stream['size'] ) ) |
| 180 | + $size += $stream['size']; |
| 181 | + } |
| 182 | + } |
| 183 | + return $length == 0 ? 0 : $size / $length * 8; |
| 184 | + } |
| 185 | + |
172 | 186 | } |
\ No newline at end of file |
Index: trunk/extensions/TimedMediaHandler/TimedMediaHandler_body.php |
— | — | @@ -111,11 +111,13 @@ |
112 | 112 | function isMetadataValid( $image, $metadata ) { |
113 | 113 | return $this->unpackMetadata( $metadata ) !== false; |
114 | 114 | } |
115 | | - |
116 | 115 | function getThumbType( $ext, $mime, $params = null ) { |
117 | 116 | return array( 'jpg', 'image/jpeg' ); |
118 | 117 | } |
119 | | - |
| 118 | + // checks if a given file is an audio file |
| 119 | + function isAudio( $file ){ |
| 120 | + return ( $file->getWidth() == 0 && $file->getHeight() == 0 ); |
| 121 | + } |
120 | 122 | function doTransform( $file, $dstPath, $dstUrl, $params, $flags = 0 ) { |
121 | 123 | global $wgFFmpegLocation, $wgEnabledDerivatives; |
122 | 124 | |
— | — | @@ -128,11 +130,12 @@ |
129 | 131 | 'offset' => $this->getOffset( $file ), |
130 | 132 | 'width' => $params['width'], |
131 | 133 | 'height' => $srcWidth == 0 ? $srcHeight : $params['width']* $srcHeight / $srcWidth, |
132 | | - 'isVideo' => ( $srcHeight != 0 && $srcWidth != 0 ), |
| 134 | + 'isVideo' => !$this->isAudio( $file ), |
133 | 135 | 'thumbtime' => ( isset( $params['thumbtime'] ) )? $params['thumbtime'] : false, |
134 | 136 | 'start' => ( isset( $params['start'] ) )? $params['start'] : false, |
135 | 137 | 'end' => ( isset( $params['end'] ) )? $params['end'] : false |
136 | 138 | ); |
| 139 | + |
137 | 140 | // No thumbs for audio |
138 | 141 | if( $baseConfig['isVideo'] === false ){ |
139 | 142 | return new TimedMediaTransformOutput( $baseConfig ); |
Index: trunk/extensions/TimedMediaHandler/TimedMediaHandler.i18n.php |
— | — | @@ -32,21 +32,28 @@ |
33 | 33 | 'timedmedia-oggThumb-version' => 'OggHandler requires oggThumb version $1 or later.', |
34 | 34 | 'timedmedia-oggThumb-failed' => 'oggThumb failed to create the thumbnail.', |
35 | 35 | |
36 | | - // derivative |
37 | | - 'timedmedia-derivative-200_200kbs_ogv' => 'Ogg 200', |
38 | | - 'timedmedia-derivative-desc-200_200kbs_ogv' => 'Low bandwith Ogg video (200 kbs)', |
| 36 | + // source |
| 37 | + 'timedmedia-source-file' => 'Source', |
| 38 | + 'timedmedia-source-file-desc' => 'Source $1, $2 x $3 ($4)', |
| 39 | + |
| 40 | + // derivative timedmedia-derivative-desc-220_200kbs.ogv |
| 41 | + 'timedmedia-derivative-220_200kbs.ogv' => 'Ogg 200', |
| 42 | + 'timedmedia-derivative-desc-220_200kbs.ogv' => 'Low bandwith Ogg video (200 kbs)', |
| 43 | + |
39 | 44 | 'timedmedia-derivative-360_400kbs.ogv' => 'Ogg 360P', |
40 | 45 | 'timedmedia-derivative-desc-360_400kbs.ogv' => 'Web streamable Ogg video (360P)', |
| 46 | + |
41 | 47 | 'timedmedia-derivative-480_600kbs.ogv' => 'Ogg 480P', |
42 | 48 | 'timedmedia-derivative-desc-480_600kbs.ogv' => 'Web streamable Ogg video (480P)', |
| 49 | + |
43 | 50 | 'timedmedia-derivative-720_VBR.ogv' => 'Ogg HQ', |
44 | 51 | 'timedmedia-derivative-desc-720_VBR.ogv' => 'High quality downloadable Ogg video (720P)', |
45 | 52 | |
46 | 53 | // WebM profiles: |
47 | 54 | 'timedmedia-derivative-480_600kbs.webm' => 'WebM 480P', |
48 | | - 'timedmedia-derivative-480_600kbs.webm' => 'Web stremable WebM (480P)', |
| 55 | + 'timedmedia-derivative-desc-480_600kbs.webm' => 'Web stremable WebM (480P)', |
49 | 56 | 'timedmedia-derivative-720_VBR.webm' => 'WebM HQ', |
50 | | - 'timedmedia-derivative-480_600kbs.webm' => 'High quality downloadable WebM (720P)', |
| 57 | + 'timedmedia-derivative-desc720_VBR.webm' => 'High quality downloadable WebM (720P)', |
51 | 58 | |
52 | 59 | ); |
53 | 60 | |
— | — | @@ -64,6 +71,13 @@ |
65 | 72 | */ |
66 | 73 | $messages['qqq'] = array( |
67 | 74 | 'timedmedia-desc' => '{{desc}}', |
| 75 | + 'timedmedia-source-file-desc' => 'Source file description |
| 76 | +Paramaters are: |
| 77 | +* $1 file type ie webm or ogg |
| 78 | +* $2 resolution width |
| 79 | +* $3 resolution height |
| 80 | +* $3 human readable bitrate', |
| 81 | + |
68 | 82 | 'timedmedia-ogg-short-general' => 'File details for generic (non-audio, non-video) Ogg files, short version. |
69 | 83 | Parameters are: |
70 | 84 | * $1 file type, e.g. Vorbis, Speex |
— | — | @@ -272,7 +286,7 @@ |
273 | 287 | 'timedmedia-desc-link' => 'Інфармацыя пра гэты файл', |
274 | 288 | 'timedmedia-oggThumb-version' => 'OggHandler патрабуе oggThumb вэрсіі $1 ці больш позьняй.', |
275 | 289 | 'timedmedia-oggThumb-failed' => 'oggThumb не атрымалася стварыць мініятуру.', |
276 | | - 'timedmedia-derivative-desc-200_200kbs_ogv' => 'Нізкапаточнае Ogg-відэа (200 кб/с)', |
| 290 | + 'timedmedia-derivative-desc-220_200kbs.ogv' => 'Нізкапаточнае Ogg-відэа (200 кб/с)', |
277 | 291 | 'timedmedia-derivative-desc-360_400kbs.ogv' => 'Паточнае Ogg-відэа (360 пкс)', |
278 | 292 | 'timedmedia-derivative-desc-480_600kbs.ogv' => 'Паточнае Ogg-відэа (480 пкс)', |
279 | 293 | 'timedmedia-derivative-desc-720_VBR.ogv' => 'Высакаякаснае Ogg-відэа для загрузкі (720 пкс)', |
— | — | @@ -468,7 +482,7 @@ |
469 | 483 | 'timedmedia-desc-link' => 'Über diese Datei', |
470 | 484 | 'timedmedia-oggThumb-version' => 'OggHandler erfordert oggThumb in der Version $1 oder höher.', |
471 | 485 | 'timedmedia-oggThumb-failed' => 'oggThumb konnte kein Miniaturbild erstellen.', |
472 | | - 'timedmedia-derivative-desc-200_200kbs_ogv' => 'Ogg-Videodatei mit niedriger Datenübertragungsrate (200 kbit/s)', |
| 486 | + 'timedmedia-derivative-desc-220_200kbs.ogv' => 'Ogg-Videodatei mit niedriger Datenübertragungsrate (200 kbit/s)', |
473 | 487 | 'timedmedia-derivative-desc-360_400kbs.ogv' => 'Webstreamingfähige Ogg-Videodatei (360p)', |
474 | 488 | 'timedmedia-derivative-desc-480_600kbs.ogv' => 'Webstreamingfähige Ogg-Videodatei (480p)', |
475 | 489 | 'timedmedia-derivative-desc-720_VBR.ogv' => 'Qualitativ hochwertige Ogg-Videodatei (720p)', |
— | — | @@ -700,7 +714,7 @@ |
701 | 715 | 'timedmedia-desc-link' => 'À propos de ce fichier', |
702 | 716 | 'timedmedia-oggThumb-version' => 'OggHandler nécessite oggThumb, version $1 ou supérieure.', |
703 | 717 | 'timedmedia-oggThumb-failed' => 'oggThumb n’a pas réussi à créer la miniature.', |
704 | | - 'timedmedia-derivative-desc-200_200kbs_ogv' => 'Vidéo Ogg bas débit (200 kbps)', |
| 718 | + 'timedmedia-derivative-desc-220_200kbs.ogv' => 'Vidéo Ogg bas débit (200 kbps)', |
705 | 719 | 'timedmedia-derivative-desc-360_400kbs.ogv' => 'Vidéo Ogg lisible en continu sur le Web (360p)', |
706 | 720 | 'timedmedia-derivative-desc-480_600kbs.ogv' => 'Vidéo Ogg lisible en continu sur le web (480p)', |
707 | 721 | 'timedmedia-derivative-desc-720_VBR.ogv' => 'Vidéo Ogg téléchargeable de grande qualité (720p)', |
— | — | @@ -958,7 +972,7 @@ |
959 | 973 | 'timedmedia-desc-link' => 'A proposito de iste file', |
960 | 974 | 'timedmedia-oggThumb-version' => 'OggHandler require oggThumb version $1 o plus recente.', |
961 | 975 | 'timedmedia-oggThumb-failed' => 'oggThumb ha fallite de crear le miniatura.', |
962 | | - 'timedmedia-derivative-desc-200_200kbs_ogv' => 'Video Ogg a basse largor de banda (200 kbs)', |
| 976 | + 'timedmedia-derivative-desc-220_200kbs.ogv' => 'Video Ogg a basse largor de banda (200 kbs)', |
963 | 977 | 'timedmedia-derivative-desc-360_400kbs.ogv' => 'Video Ogg fluibile per web (360P)', |
964 | 978 | 'timedmedia-derivative-desc-480_600kbs.ogv' => 'Video Ogg fluibile per web (480P)', |
965 | 979 | 'timedmedia-derivative-desc-720_VBR.ogv' => 'Video Ogg discargabile de alte qualitate (720P)', |
— | — | @@ -1237,7 +1251,7 @@ |
1238 | 1252 | 'timedmedia-desc-link' => 'Övver di Datei', |
1239 | 1253 | 'timedmedia-oggThumb-version' => 'Dä <code lang="en">OggHandler</code> bruch <code lang="en">oggThumb</code> in dä Version $1 udder hüüter.', |
1240 | 1254 | 'timedmedia-oggThumb-failed' => '<code lang="en">oggThumb</code> kunnt kei MiniBelldsche maache.', |
1241 | | - 'timedmedia-derivative-desc-200_200kbs_ogv' => 'En Viddejo-Dattei met winnesch Bandbreide (200 kbs) em <i lang="en">Ogg</i>-Fommaat', |
| 1255 | + 'timedmedia-derivative-desc-220_200kbs.ogv' => 'En Viddejo-Dattei met winnesch Bandbreide (200 kbs) em <i lang="en">Ogg</i>-Fommaat', |
1242 | 1256 | 'timedmedia-derivative-desc-360_400kbs.ogv' => 'En Viddejo-Dattei met huhe Qualiteit (met 720p) em <i lang="en">Ogg</i>-Fommaat zom eronger laade', |
1243 | 1257 | 'timedmedia-derivative-desc-480_600kbs.ogv' => 'En Viddejo-Dattei (met 480p) em <i lang="en">Ogg</i>-Fommaat för övver et Web ze striime', |
1244 | 1258 | 'timedmedia-derivative-desc-720_VBR.ogv' => 'En Viddejo-Dattei met huhe Qualiteit (met 720p) em <i lang="en">Ogg</i>-Fommaat zom eronger laade', |
— | — | @@ -1353,7 +1367,7 @@ |
1354 | 1368 | 'timedmedia-desc-link' => 'Информации за оваа податотека', |
1355 | 1369 | 'timedmedia-oggThumb-version' => 'OggHandler бара oggThumb верзија $1 или понова.', |
1356 | 1370 | 'timedmedia-oggThumb-failed' => 'oggThumb не успеа да ја создаде минијатурата.', |
1357 | | - 'timedmedia-derivative-desc-200_200kbs_ogv' => 'Нископропусно Ogg-видео (200 кб/с)', |
| 1371 | + 'timedmedia-derivative-desc-220_200kbs.ogv' => 'Нископропусно Ogg-видео (200 кб/с)', |
1358 | 1372 | 'timedmedia-derivative-360_400kbs.ogv' => 'Ogg 360п', |
1359 | 1373 | 'timedmedia-derivative-desc-360_400kbs.ogv' => 'Ogg-видео за емитување (360 пиксели)', |
1360 | 1374 | 'timedmedia-derivative-480_600kbs.ogv' => 'Ogg 480п', |
— | — | @@ -1500,7 +1514,7 @@ |
1501 | 1515 | 'timedmedia-desc-link' => 'Over dit bestand', |
1502 | 1516 | 'timedmedia-oggThumb-version' => 'OggHandler vereist oggThumb versie $1 of hoger.', |
1503 | 1517 | 'timedmedia-oggThumb-failed' => 'oggThumb kon geen miniatuur aanmaken.', |
1504 | | - 'timedmedia-derivative-desc-200_200kbs_ogv' => 'Lage bandbreedte Ogg video (200 kbps)', |
| 1518 | + 'timedmedia-derivative-desc-220_200kbs.ogv' => 'Lage bandbreedte Ogg video (200 kbps)', |
1505 | 1519 | 'timedmedia-derivative-desc-360_400kbs.ogv' => 'Te webstreamen Off video (360P)', |
1506 | 1520 | 'timedmedia-derivative-desc-480_600kbs.ogv' => 'Te webstreamen Ogg video (480P)', |
1507 | 1521 | 'timedmedia-derivative-desc-720_VBR.ogv' => 'Hoge kwaliteit downloadbare Ogg video (720P)', |
— | — | @@ -1683,7 +1697,7 @@ |
1684 | 1698 | 'timedmedia-desc-link' => 'Sobre este ficheiro', |
1685 | 1699 | 'timedmedia-oggThumb-version' => 'O oggHandler requer o oggThumb versão $1 ou posterior.', |
1686 | 1700 | 'timedmedia-oggThumb-failed' => 'O oggThumb não conseguiu criar a miniatura.', |
1687 | | - 'timedmedia-derivative-desc-200_200kbs_ogv' => 'Vídeo Ogg de baixa largura de banda (200 kbs)', |
| 1701 | + 'timedmedia-derivative-desc-220_200kbs.ogv' => 'Vídeo Ogg de baixa largura de banda (200 kbs)', |
1688 | 1702 | 'timedmedia-derivative-desc-360_400kbs.ogv' => 'Vídeo Ogg para web streaming (360P)', |
1689 | 1703 | 'timedmedia-derivative-desc-480_600kbs.ogv' => 'Vídeo Ogg para web streaming (480P)', |
1690 | 1704 | 'timedmedia-derivative-desc-720_VBR.ogv' => 'Vídeo Ogg de alta qualidade para download (720 P)', |
— | — | @@ -1886,7 +1900,7 @@ |
1887 | 1901 | 'timedmedia-desc-link' => 'O datoteki', |
1888 | 1902 | 'timedmedia-oggThumb-version' => 'OggHandler potrebuje oggThumb različice $1 ali višje.', |
1889 | 1903 | 'timedmedia-oggThumb-failed' => 'oggThumb ni uspel ustvariti predogledne sličice.', |
1890 | | - 'timedmedia-derivative-desc-200_200kbs_ogv' => 'Video Ogg za majhno pasovno širino (200 kb/s)', |
| 1904 | + 'timedmedia-derivative-desc-220_200kbs.ogv' => 'Video Ogg za majhno pasovno širino (200 kb/s)', |
1891 | 1905 | 'timedmedia-derivative-desc-360_400kbs.ogv' => 'Video Ogg za pretakanje preko spleta (360P)', |
1892 | 1906 | 'timedmedia-derivative-desc-480_600kbs.ogv' => 'Video Ogg za pretakanje preko spleta (480P)', |
1893 | 1907 | 'timedmedia-derivative-desc-720_VBR.ogv' => 'Visoko ločljivostni video Ogg za prenos (720P)', |
Index: trunk/extensions/TimedMediaHandler/TimedMediaHandler.php |
— | — | @@ -8,22 +8,14 @@ |
9 | 9 | // Set up the timed media handler dir: |
10 | 10 | $timedMediaDir = dirname(__FILE__); |
11 | 11 | |
12 | | -if ( !in_array( 'ogg', $wgFileExtensions ) ) { |
13 | | - $wgFileExtensions[] = 'ogg'; |
| 12 | +$wgTimedMediaHandlerFileExtensions = array( 'ogg', 'ogv', 'oga', 'webm'); |
| 13 | + |
| 14 | +foreach($wgTimedMediaHandlerFileExtensions as $ext ){ |
| 15 | + if ( !in_array( $ext, $wgFileExtensions ) ) { |
| 16 | + $wgFileExtensions[] = $ext; |
| 17 | + } |
14 | 18 | } |
15 | | -if ( !in_array( 'ogv', $wgFileExtensions ) ) { |
16 | | - $wgFileExtensions[] = 'ogv'; |
17 | | -} |
18 | | -if ( !in_array( 'oga', $wgFileExtensions ) ) { |
19 | | - $wgFileExtensions[] = 'oga'; |
20 | | -} |
21 | | -if ( !in_array( 'webm', $wgFileExtensions ) ) { |
22 | | - $wgFileExtensions[] = 'webm'; |
23 | | -} |
24 | 19 | |
25 | | - |
26 | | - |
27 | | - |
28 | 20 | // Timed Media Handler AutoLoad Classes: |
29 | 21 | $wgAutoloadClasses['TimedMediaHandler'] = "$timedMediaDir/TimedMediaHandler_body.php"; |
30 | 22 | $wgAutoloadClasses['TimedMediaHandlerHooks'] = "$timedMediaDir/TimedMediaHandler.hooks.php"; |
— | — | @@ -111,6 +103,7 @@ |
112 | 104 | * -Only derivatives with smaller width than the source asset size will be created |
113 | 105 | * -Derivative jobs are added to the mediaWiki JobQueue the first time the asset is displayed |
114 | 106 | * -Derivative keys encode settings are defined in WebVideoTranscode.php |
| 107 | + * -List Derivative from min to max |
115 | 108 | */ |
116 | 109 | $wgEnabledTranscodeSet = array( |
117 | 110 | // Cover accessibility for low bandwidth / low resources clients: |
Index: trunk/extensions/TimedMediaHandler/WebVideoTranscode/WebVideoTranscodeJob.php |
— | — | @@ -21,7 +21,7 @@ |
22 | 22 | parent::__construct( 'webVideoTranscode', $title, $params, $id ); |
23 | 23 | } |
24 | 24 | |
25 | | - // Local function to debug output ( jobs don't have access to the maintenance class ) |
| 25 | + // Local function to debug output ( jobs don't have access to the maintenance output class ) |
26 | 26 | private function output( $msg ){ |
27 | 27 | print $msg . "\n"; |
28 | 28 | } |
— | — | @@ -30,11 +30,21 @@ |
31 | 31 | public function run() { |
32 | 32 | // Get the file object |
33 | 33 | $file = wfLocalFile( $this->title ); |
| 34 | + |
| 35 | + $source = $file->getFullPath(); |
| 36 | + if( !is_file($source ) ){ |
| 37 | + $this->output( 'File not found: ' . $this->title ); |
| 38 | + return false; |
| 39 | + } |
34 | 40 | $transcodeKey = $this->params['transcodeKey']; |
35 | 41 | |
36 | 42 | // Build the destination target |
37 | 43 | $destinationFile = WebVideoTranscode::getTargetEncodePath( $file, $transcodeKey ); |
38 | | - |
| 44 | + |
| 45 | + if( ! isset( WebVideoTranscode::$derivativeSettings[ $transcodeKey ] )){ |
| 46 | + $this->output("Transcode key $transcodeKey not found, skipping"); |
| 47 | + return false; |
| 48 | + } |
39 | 49 | $options = WebVideoTranscode::$derivativeSettings[ $transcodeKey ]; |
40 | 50 | |
41 | 51 | $this->output( "Encoding to codec: " . $options['codec'] ); |
— | — | @@ -44,14 +54,17 @@ |
45 | 55 | } else if( $options['codec'] == 'vp8' ){ |
46 | 56 | // Check for twopass: |
47 | 57 | if( isset( $options['twopass'] ) ){ |
| 58 | + // ffmpeg requires manual two pass |
48 | 59 | $status = $this->ffmpegEncode( $file, $destinationFile, $options, 1 ); |
49 | 60 | if( $status ){ |
50 | 61 | $status = $this->ffmpegEncode( $file, $destinationFile, $options, 2 ); |
51 | | - } |
| 62 | + } |
| 63 | + // remove any log files |
| 64 | + $this->removeFffmpgeLogFiles( dirname( $destinationFile) ); |
| 65 | + |
52 | 66 | } else { |
53 | | - $this->ffmpegEncode( $file, $destinationFile, $options ); |
| 67 | + $status = $this->ffmpegEncode( $file, $destinationFile, $options ); |
54 | 68 | } |
55 | | - |
56 | 69 | } else { |
57 | 70 | wfDebug( 'Error unknown codec:' . $options['codec'] ); |
58 | 71 | $status = false; |
— | — | @@ -60,12 +73,27 @@ |
61 | 74 | // If status is oky move the file to its final destination. ( timedMediaHandler will look for it there ) |
62 | 75 | // XXX would be nice to clear the cache for the pages where the title in use |
63 | 76 | if( $status ){ |
64 | | - $status = @rename($destinationFile, WebVideoTranscode::getDerivativeFilePath( $file, $transcodeKey) ); |
| 77 | + wfSuppressWarnings(); |
| 78 | + $status = rename($destinationFile, WebVideoTranscode::getDerivativeFilePath( $file, $transcodeKey) ); |
| 79 | + wfRestoreWarnings(); |
65 | 80 | } |
66 | | - |
67 | 81 | return $status; |
68 | 82 | } |
69 | | - |
| 83 | + function removeFffmpgeLogFiles( $dir ){ |
| 84 | + if (is_dir($dir)) { |
| 85 | + if ($dh = opendir($dir)) { |
| 86 | + while (($file = readdir($dh)) !== false) { |
| 87 | + $ext = strtolower( pathinfo("$dir/$file", PATHINFO_EXTENSION) ); |
| 88 | + if( $ext == '.log' ){ |
| 89 | + wfSuppressWarnings(); |
| 90 | + unlink( "$dir/$file"); |
| 91 | + wfRestoreWarnings(); |
| 92 | + } |
| 93 | + } |
| 94 | + closedir($dh); |
| 95 | + } |
| 96 | + } |
| 97 | + } |
70 | 98 | /** Utility helper for ffmpeg and ffmpeg2theora mapping **/ |
71 | 99 | |
72 | 100 | function ffmpegEncode( $file, $target, $options, $pass=0 ){ |
— | — | @@ -75,7 +103,7 @@ |
76 | 104 | $this->output( "Encode:\n source:$source\n target:$target\n" ); |
77 | 105 | |
78 | 106 | // Set up the base command |
79 | | - $cmd = wfEscapeShellArg( $wgFFmpegLocation ) . ' ' . wfEscapeShellArg( $source ); |
| 107 | + $cmd = wfEscapeShellArg( $wgFFmpegLocation ) . ' -i ' . wfEscapeShellArg( $source ); |
80 | 108 | |
81 | 109 | if( isset($options['preset']) ){ |
82 | 110 | if ($options['preset'] == "360p") { |
— | — | @@ -86,14 +114,11 @@ |
87 | 115 | $cmd.= " -vpre libvpx-1080p"; |
88 | 116 | } |
89 | 117 | } |
90 | | - $this->output( "novideo::$cmd" ); |
91 | 118 | if ( isset( $options['novideo'] ) ) { |
92 | 119 | $cmd.= " -vn "; |
93 | 120 | } else { |
94 | 121 | $cmd.= $this->ffmpegAddVideoOptions( $file, $target, $options, $pass ); |
95 | | - |
96 | 122 | } |
97 | | - $this->output( "add starty optiosn$cmd" ); |
98 | 123 | |
99 | 124 | // Check for start time |
100 | 125 | if( isset( $options['starttime'] ) ){ |
— | — | @@ -105,15 +130,14 @@ |
106 | 131 | if( isset( $options['endtime'] ) ){ |
107 | 132 | $cmd.= ' -t ' . intval( $options['endtime'] ) - intval($options['starttime'] ) ; |
108 | 133 | } |
109 | | - $this->output( "add audio optiosn$cmd" ); |
110 | 134 | |
111 | | - if ( $pass == 1 || $options['noaudio'] ) { |
| 135 | + if ( $pass == 1 || isset( $options['noaudio'] ) ) { |
112 | 136 | $cmd.= ' -an'; |
113 | 137 | } else { |
114 | 138 | $cmd.= $this->ffmpegAddAudioOptions( $file, $target, $options, $pass ); |
115 | 139 | } |
116 | | - $this->output( "add webmn$cmd" ); |
117 | | - // Output WebM |
| 140 | + |
| 141 | + // Output WebM |
118 | 142 | $cmd.=" -f webm"; |
119 | 143 | |
120 | 144 | if ( $pass != 0 ) { |
— | — | @@ -124,11 +148,15 @@ |
125 | 149 | if ($pass==1) { |
126 | 150 | $cmd.= ' /dev/null'; |
127 | 151 | } else{ |
128 | | - $cmd.= $target; |
129 | | - } |
| 152 | + $cmd.= " $target"; |
| 153 | + } |
130 | 154 | |
| 155 | + // Don't display shell output |
| 156 | + $cmd .= ' 2>&1'; |
| 157 | + |
131 | 158 | $this->output( "Running cmd: \n\n" .$cmd . "\n" ); |
132 | 159 | |
| 160 | + // Right before we output remove the old file |
133 | 161 | wfProfileIn( 'ffmpeg_encode' ); |
134 | 162 | wfShellExec( $cmd, $retval ); |
135 | 163 | wfProfileOut( 'ffmpeg_encode' ); |
— | — | @@ -141,7 +169,7 @@ |
142 | 170 | function ffmpegAddVideoOptions( $file, $target, $options, $pass){ |
143 | 171 | $cmd =''; |
144 | 172 | // Add the boiler plate vp8 ffmpeg command: |
145 | | - $cmd.="-y -skip_threshold 0 -rc_buf_aggressivity 0 -bufsize 6000k -rc_init_occupancy 4000 -threads 4"; |
| 173 | + $cmd.=" -y -skip_threshold 0 -rc_buf_aggressivity 0 -bufsize 6000k -rc_init_occupancy 4000 -threads 4"; |
146 | 174 | |
147 | 175 | // Check for video quality: |
148 | 176 | if ( isset( $options['videoQuality'] ) && $options['videoQuality'] >= 0 ) { |
— | — | @@ -154,35 +182,35 @@ |
155 | 183 | // Check for video bitrate: |
156 | 184 | if ( isset( $options['videoBitrate'] ) ) { |
157 | 185 | $cmd.= " -qmin 1 -qmax 51"; |
158 | | - $cmd.= " -vp " . wfEscapeShellArg( $options['videoBitrate'] ); |
| 186 | + $cmd.= " -vb " . wfEscapeShellArg( $options['videoBitrate'] * 1000 ); |
159 | 187 | } |
160 | 188 | // Set the codec: |
161 | 189 | $cmd.= " -vcodec libvpx"; |
162 | 190 | |
163 | | - die( $file->getWidth() + ':' + $file->getHeight() ); |
164 | | - |
165 | 191 | // Check for aspect ratio |
166 | | - if ($options['aspect']) { |
| 192 | + if ( isset( $options['aspect'] ) ) { |
167 | 193 | $aspectRatio = $options['aspect']; |
168 | 194 | } else { |
169 | | - $aspectRatio = $file->getWidth() + ':' + $file->getHeight(); |
| 195 | + $aspectRatio = $file->getWidth() . ':' . $file->getHeight(); |
170 | 196 | } |
| 197 | + $dar = explode(':', $aspectRatio); |
| 198 | + $dar = intval( $dar[0] ) / intval( $dar[1] ); |
171 | 199 | |
172 | | - $dar = $aspectRatio.split(':'); |
173 | | - $dar = intval( $aspectRatio[0] ) / intval( $aspectRatio[1] ); |
174 | | - |
175 | 200 | // Check maxSize |
176 | 201 | if (isset( $options['maxSize'] ) && intval( $options['maxSize'] ) > 0) { |
177 | | - $sourceWidth = $file->getWidth(); |
178 | | - $sourceHeight =$file->getHeight(); |
179 | | - if ($sourceWidth > $options['maxSize'] ) { |
180 | | - $width = intval( $options['maxSize'] ); |
181 | | - $height = intval( $width / $dar); |
182 | | - } else { |
183 | | - $height = intval( $options['maxSize'] ); |
184 | | - $width = intval( $height * $dar); |
185 | | - } |
186 | | - $cmd.= ' -s ' . intval( $width ) . 'x' . intval( $height ); |
| 202 | + // Check if source is smaller than maxSize |
| 203 | + if( !WebVideoTranscode::isTargetLargerThanFile( $options['maxSize'], $file ) ){ |
| 204 | + $sourceWidth = $file->getWidth(); |
| 205 | + $sourceHeight = $file->getHeight(); |
| 206 | + if ($sourceWidth > $options['maxSize'] ) { |
| 207 | + $width = intval( $options['maxSize'] ); |
| 208 | + $height = intval( $width / $dar); |
| 209 | + } else { |
| 210 | + $height = intval( $options['maxSize'] ); |
| 211 | + $width = intval( $height * $dar); |
| 212 | + } |
| 213 | + $cmd.= ' -s ' . intval( $width ) . 'x' . intval( $height ); |
| 214 | + } |
187 | 215 | } else if ( |
188 | 216 | (isset( $options['width'] ) && $options['width'] > 0 ) |
189 | 217 | && |
— | — | @@ -253,18 +281,23 @@ |
254 | 282 | if( isset( self::$foggMap[$key] ) ){ |
255 | 283 | if( is_array( self::$foggMap[$key] ) ){ |
256 | 284 | $cmd.= ' '. implode(' ', WebVideoTranscode::$foggMap[$key] ); |
257 | | - }else if($val == 'true' || $val === true){ |
| 285 | + } else if ($val == 'true' || $val === true){ |
258 | 286 | $cmd.= ' '. self::$foggMap[$key]; |
259 | | - }else if( $val === false){ |
| 287 | + } else if ( $val === false){ |
260 | 288 | //ignore "false" flags |
261 | | - }else{ |
| 289 | + } else { |
262 | 290 | //normal get/set value |
263 | 291 | $cmd.= ' '. self::$foggMap[$key] . ' ' . wfEscapeShellArg( $val ); |
264 | 292 | } |
265 | 293 | } |
266 | 294 | } |
| 295 | + |
267 | 296 | // Add the output target: |
268 | 297 | $cmd.= ' -o ' . wfEscapeShellArg ( $target ); |
| 298 | + |
| 299 | + // Don't display shell output |
| 300 | + $cmd.=' 2>&1'; |
| 301 | + |
269 | 302 | $this->output( "Running cmd: \n\n" .$cmd . "\n" ); |
270 | 303 | |
271 | 304 | wfProfileIn( 'ffmpeg2theora_encode' ); |
— | — | @@ -276,6 +309,7 @@ |
277 | 310 | } |
278 | 311 | return true; |
279 | 312 | } |
| 313 | + |
280 | 314 | /** |
281 | 315 | * Mapping between firefogg api and ffmpeg2theora command line |
282 | 316 | * |
Index: trunk/extensions/TimedMediaHandler/WebVideoTranscode/WebVideoTranscode.php |
— | — | @@ -30,7 +30,7 @@ |
31 | 31 | */ |
32 | 32 | |
33 | 33 | // Ogg Profiles |
34 | | - const ENC_OGV_2MBS = '200_200kbs.ogv'; |
| 34 | + const ENC_OGV_2MBS = '220_200kbs.ogv'; |
35 | 35 | const ENC_OGV_4MBS = '360_400kbs.ogv'; |
36 | 36 | const ENC_OGV_6MBS = '480_600kbs.ogv'; |
37 | 37 | const ENC_OGV_HQ_VBR = '720_VBR.ogv'; |
— | — | @@ -50,11 +50,11 @@ |
51 | 51 | public static $derivativeSettings = array( |
52 | 52 | WebVideoTranscode::ENC_OGV_2MBS => |
53 | 53 | array( |
54 | | - 'maxSize' => '200', |
55 | | - 'videoBitrate' => '128', |
| 54 | + 'maxSize' => '220', |
| 55 | + 'videoBitrate' => '160', |
56 | 56 | 'audioBitrate' => '32', |
57 | 57 | 'samplerate' => '22050', |
58 | | - 'framerate' => '15', |
| 58 | + //'framerate' => '15', |
59 | 59 | 'channels' => '1', |
60 | 60 | 'noUpscaling' => 'true', |
61 | 61 | 'twopass' => 'true', |
— | — | @@ -105,19 +105,25 @@ |
106 | 106 | 'noUpscaling' => 'true', |
107 | 107 | 'codec' => 'vp8', |
108 | 108 | ) |
109 | | - ); |
110 | | - static public function getDerivativeFilePath($file, $transcodeKey){ |
| 109 | + ); |
| 110 | + |
| 111 | + static public function getDerivativeFilePath( &$file, $transcodeKey){ |
111 | 112 | return dirname( |
112 | | - $file->getThumbPath( |
113 | | - $file->thumbName( array() ) |
114 | | - ) |
115 | | - ) . '/' . |
116 | | - $file->getName() . '.' . |
117 | | - $transcodeKey ; |
| 113 | + $file->getThumbPath( |
| 114 | + $file->thumbName( array() ) |
| 115 | + ) |
| 116 | + ) . '/' . |
| 117 | + $file->getName() . '.' . |
| 118 | + $transcodeKey ; |
| 119 | +} |
| 120 | + |
| 121 | + static public function getTargetEncodePath( &$file, $transcodeKey ){ |
| 122 | + // TODO probably should use some other temporary non-web accessible location for |
| 123 | + // in-progress encodes. |
| 124 | + $filePath = self::getDerivativeFilePath( $file, $transcodeKey ); |
| 125 | + $ext = strtolower( pathinfo( "$filePath", PATHINFO_EXTENSION ) ); |
| 126 | + return "{$filePath}.queue.{$ext}"; |
118 | 127 | } |
119 | | - static public function getTargetEncodePath( $file, $transcodeKey ){ |
120 | | - return self::getDerivativeFilePath( $file, $transcodeKey ) . '.tmp'; |
121 | | - } |
122 | 128 | |
123 | 129 | /** |
124 | 130 | * Static function to get the set of video assets |
— | — | @@ -132,71 +138,109 @@ |
133 | 139 | * @param {Object} File object |
134 | 140 | * @returns an associative array of sources suitable for <source> tag output |
135 | 141 | */ |
136 | | - static public function getSources( $file ){ |
137 | | - global $wgEnabledTranscodeSet; |
| 142 | + static public function getSources( &$file ){ |
| 143 | + global $wgEnabledTranscodeSet, $wgLang; |
138 | 144 | $sources = array(); |
139 | 145 | |
| 146 | + // Add the original file: |
| 147 | + $sources[] = array( |
| 148 | + 'src' => $file->getUrl(), |
| 149 | + 'title' => wfMsg('timedmedia-source-file-desc', |
| 150 | + $file->getHandler()->getMetadataType(), |
| 151 | + $wgLang->formatNum( $file->getWidth() ), |
| 152 | + $wgLang->formatNum( $file->getHeight() ), |
| 153 | + $wgLang->formatBitrate( $file->getHandler()->getBitrate( $file ) ) |
| 154 | + ), |
| 155 | + 'data-shorttitle' => wfMsg('timedmedia-source-file') |
| 156 | + // TODO add some title and data about the file |
| 157 | + ); |
| 158 | + |
| 159 | + // Just directly return audio sources ( for now no transcoding for audio ) |
| 160 | + if( $file->getHandler()->isAudio( $file ) ){ |
| 161 | + return $sources; |
| 162 | + } |
| 163 | + |
140 | 164 | // Setup local variables |
141 | 165 | $fileName = $file->getName(); |
142 | 166 | |
143 | | - // Add the source file: |
144 | | - $sources[] = array( |
145 | | - 'src' => $file->getUrl() |
146 | | - ); |
| 167 | + $addOggFlag = false; |
| 168 | + $addWebMFlag = false; |
147 | 169 | |
148 | | - $thumbName = $file->thumbName( array() ); |
149 | | - $thumbUrl = $file->getThumbUrl( $thumbName ); |
150 | | - $thumbUrlDir = dirname( $thumbUrl ); |
151 | | - |
152 | | - $hasOggFlag = false; |
153 | | - $hasWebMFlag = false; |
| 170 | + $ext = pathinfo("$fileName", PATHINFO_EXTENSION); |
154 | 171 | // Check the source file for .webm extension |
155 | | - if( preg_match( "/$.webm/i", $fileName ) ) { |
156 | | - $hasWebMFlag = true; |
| 172 | + if( strtolower( $ext )== 'webm' ) { |
| 173 | + $addWebMFlag = true; |
157 | 174 | } else { |
158 | | - // we only support ogg and webm so assume oky if we have .webm |
159 | | - $hasOggFlag = true; |
| 175 | + // If not webm assume ogg as the source file |
| 176 | + $addOggFlag = true; |
160 | 177 | } |
161 | 178 | |
162 | | - foreach($wgEnabledTranscodeSet as $transcodeKey){ |
| 179 | + foreach( $wgEnabledTranscodeSet as $transcodeKey ){ |
163 | 180 | $derivativeFile = self::getDerivativeFilePath( $file, $transcodeKey); |
164 | 181 | $codec = self::$derivativeSettings[$transcodeKey]['codec']; |
165 | | - if( is_file( $derivativeFile ) ){ |
166 | | - $messageKey = str_replace('.','_',$transcodeKey ); |
167 | | - $sources[] = array( |
168 | | - 'src' => $thumbUrlDir . '/' .$fileName . '.' . $transcodeKey, |
169 | | - 'title' => wfMsg('timedmedia-derivative-desc-' . $messageKey ), |
170 | | - 'data-shorttitle' => wfMsg('timedmedia-derivative-' . $messageKey) |
171 | | - ); |
172 | | - } else { |
173 | | - // Check if we should derivative to job queue |
174 | | - // Skip if we have both ogg and one WebM and target is too small: |
175 | | - if( $hasOggFlag && $hasWebMFlag && |
176 | | - !self::isTranscodeSmallerThanSource( $file, $transcodeKey ) ){ |
177 | | - continue; |
| 182 | + // Check if we should add derivative to job queue |
| 183 | + // Skip if we have both an Ogg & WebM and if target encode larger than source |
| 184 | + if( self::isTargetLargerThanFile( self::$derivativeSettings[$transcodeKey]['maxSize'], $file) ){ |
| 185 | + continue; |
| 186 | + } |
| 187 | + // if we are checking for this derivative, update codec flags: |
| 188 | + if( $codec == 'theora' ){ |
| 189 | + $addOggFlag = true; |
| 190 | + } |
| 191 | + if( $codec == 'vp8' ){ |
| 192 | + $addWebMFlag = true; |
| 193 | + } |
| 194 | + // Try and add the source |
| 195 | + self::tryAddSource( $file, $sources,$transcodeKey ); |
| 196 | + } |
| 197 | + // Make sure we got at least one ogg and webm encode |
| 198 | + if( !$addOggFlag || !$addWebMFlag){ |
| 199 | + foreach( $wgEnabledTranscodeSet as $transcodeKey ){ |
| 200 | + if( !$addOggFlag && self::$derivativeSettings[$transcodeKey]['codec'] == 'theora' ){ |
| 201 | + self::tryAddSource( $file, $sources,$transcodeKey ); |
| 202 | + $addOggFlag = true; |
178 | 203 | } |
179 | | - // Update Flags: |
180 | | - if( $codec == 'theora' ){ |
181 | | - $hasOggFlag = true; |
| 204 | + if( !$addWebMFlag && self::$derivativeSettings[$transcodeKey]['codec'] == 'vp8' ){ |
| 205 | + self::tryAddSource( $file, $sources, $transcodeKey ); |
| 206 | + $addWebMFlag = true; |
182 | 207 | } |
183 | | - if( $codec == 'vp8' ){ |
184 | | - $hasWebMFlag = true; |
185 | | - } |
186 | | - self::updateJobQueue($file, $transcodeKey); |
187 | 208 | } |
188 | 209 | } |
189 | 210 | return $sources; |
190 | 211 | } |
| 212 | + |
191 | 213 | /** |
| 214 | + * Try to add a source to the sources param |
| 215 | + * if the source is not found update the job queue |
| 216 | + */ |
| 217 | + public static function tryAddSource( &$file, &$sources, $transcodeKey){ |
| 218 | + $derivativeFile = self::getDerivativeFilePath( $file, $transcodeKey); |
| 219 | + |
| 220 | + $thumbName = $file->thumbName( array() ); |
| 221 | + $thumbUrl = $file->getThumbUrl( $thumbName ); |
| 222 | + $thumbUrlDir = dirname( $thumbUrl ); |
| 223 | + |
| 224 | + if( is_file( $derivativeFile ) ){ |
| 225 | + $sources[] = array( |
| 226 | + 'src' => $thumbUrlDir . '/' .$file->getName() . '.' . $transcodeKey, |
| 227 | + 'title' => wfMsg('timedmedia-derivative-desc-' . $transcodeKey ), |
| 228 | + 'data-shorttitle' => wfMsg('timedmedia-derivative-' . $transcodeKey) |
| 229 | + ); |
| 230 | + } else { |
| 231 | + self::updateJobQueue($file, $transcodeKey); |
| 232 | + } |
| 233 | + } |
| 234 | + |
| 235 | + /** |
192 | 236 | * Update the job queue if the file is not already in the job queue: |
193 | 237 | */ |
194 | | - public static function updateJobQueue( $file, $transcodeKey ){ |
| 238 | + public static function updateJobQueue( &$file, $transcodeKey ){ |
195 | 239 | $target = self::getTargetEncodePath( $file, $transcodeKey ); |
196 | 240 | // TranscodeKey not found ( check if the file is in progress ) ( tmp transcode location ) |
197 | 241 | if( is_file( $target ) ) { |
198 | 242 | // file in progress / in queue |
199 | | - // XXX Note we could check date and flag as failure |
200 | | - } else { |
| 243 | + // TODO We could check date and flag as failure somewhere |
| 244 | + } else { |
201 | 245 | // no in-progress file add to job queue and touch the target |
202 | 246 | $job = new WebVideoTranscodeJob( $file->getTitle(), array( |
203 | 247 | 'transcodeMode' => 'derivative', |
— | — | @@ -204,23 +248,24 @@ |
205 | 249 | ) ); |
206 | 250 | $jobId = $job->insert(); |
207 | 251 | if( $jobId ){ |
208 | | - // Make the thumb target directory and touch the file ( so we don't add the job again ) |
209 | | - wfMkdirParents( dirname( $target ) ); |
210 | | - touch( $target ); |
| 252 | + // Make the thumb target directory |
| 253 | + if( ! is_dir( dirname( $target ) )){ |
| 254 | + wfMkdirParents( dirname( $target ) ); |
| 255 | + } |
| 256 | + // Touch the target file |
| 257 | + touch( $target ); |
211 | 258 | } |
212 | 259 | } |
213 | 260 | } |
214 | 261 | /** |
215 | | - * Test if a given transcode target is smaller than the source file |
| 262 | + * Test if a given transcode target is larger than the source file |
216 | 263 | * |
217 | 264 | * @param $transcodeKey The static transcode key |
218 | 265 | * @param $file {Object} File object |
219 | 266 | */ |
220 | | - public static function isTranscodeSmallerThanSource( $file, $transcodeKey){ |
221 | | - return ( self::$derivativeSettings[$transcodeKey]['maxSize'] < $file->getWidth() |
222 | | - && |
223 | | - self::$derivativeSettings[$transcodeKey]['maxSize'] < $file->getHeight() |
224 | | - ); |
| 267 | + public static function isTargetLargerThanFile( $targetMaxSize, &$file){ |
| 268 | + $largerSize = ( $file->getWidth() > $file->getHeight() )?$file->getWidth(): $file->getHeight(); |
| 269 | + return ( $targetMaxSize > $largerSize ); |
225 | 270 | } |
226 | 271 | } |
227 | 272 | |
Index: trunk/extensions/TimedMediaHandler/TimedMediaHandler.hooks.php |
— | — | @@ -10,7 +10,8 @@ |
11 | 11 | class TimedMediaHandlerHooks { |
12 | 12 | // Register TimedMediaHandler Hooks |
13 | 13 | static function register(){ |
14 | | - global $wgParserOutputHooks, $wgHooks, $wgJobClasses, $wgJobExplitRequestTypes, $wgMediaHandlers; |
| 14 | + global $wgParserOutputHooks, $wgHooks, $wgJobClasses, $wgJobExplitRequestTypes, |
| 15 | + $wgMediaHandlers, $wgExcludeFromThumbnailPurge, $wgTimedMediaHandlerFileExtensions; |
15 | 16 | |
16 | 17 | // Setup media Handlers: |
17 | 18 | $wgMediaHandlers['application/ogg'] = 'OggHandler'; |
— | — | @@ -27,7 +28,12 @@ |
28 | 29 | $wgJobExplitRequestTypes+= array( |
29 | 30 | 'webVideoTranscode' |
30 | 31 | ); |
31 | | - |
| 32 | + // Exclude transcoded assets from normal thumbnail purging |
| 33 | + // ( a mantaince script could handle transcode asset purging) |
| 34 | + $wgExcludeFromThumbnailPurge += $wgTimedMediaHandlerFileExtensions; |
| 35 | + // Also add the .log file ( used in two pass encoding ) |
| 36 | + // ( probably should move in-progress encodes out of web accessible directory ) |
| 37 | + $wgExcludeFromThumbnailPurge+= array( 'log'); |
32 | 38 | /** |
33 | 39 | * Add support for the "TimedText" NameSpace |
34 | 40 | */ |
Index: trunk/extensions/TimedMediaHandler/TimedMediaThumbnail.php |
— | — | @@ -7,16 +7,19 @@ |
8 | 8 | |
9 | 9 | // Set up lodal pointer to file |
10 | 10 | $file = $options['file']; |
11 | | - |
12 | | - wfMkdirParents( dirname( $options['dstPath'] ) ); |
| 11 | + if( !is_dir( dirname( $options['dstPath'] ) ) ){ |
| 12 | + wfMkdirParents( dirname( $options['dstPath'] ) ); |
| 13 | + } |
13 | 14 | |
14 | 15 | wfDebug( "Creating video thumbnail at" . $options['dstPath'] . "\n" ); |
15 | 16 | |
16 | | - // If ogg try OggThumb: |
17 | | - if( self::tryOggThumb( $options) ){ |
18 | | - return true; |
| 17 | + // If ogg try OggThumb: |
| 18 | + if( $options['file']->getHandler()->getMetadataType() == 'ogg' ){ |
| 19 | + if( self::tryOggThumb( $options) ){ |
| 20 | + return true; |
| 21 | + } |
19 | 22 | } |
20 | | - // Else try and return the ffmpeg thumbnail attempt: |
| 23 | + // Else try ffmpeg and return result: |
21 | 24 | return self::tryFfmpegThumb( $options ); |
22 | 25 | } |
23 | 26 | /** |
— | — | @@ -30,8 +33,7 @@ |
31 | 34 | global $wgOggThumbLocation; |
32 | 35 | |
33 | 36 | // Check for ogg format file and $wgOggThumbLocation |
34 | | - if( !$options['file']->getHandler()->getMetadataType() == 'ogg' |
35 | | - || !$wgOggThumbLocation |
| 37 | + if( !$wgOggThumbLocation |
36 | 38 | || !is_file( $wgOggThumbLocation ) |
37 | 39 | ){ |
38 | 40 | return false; |
— | — | @@ -57,8 +59,8 @@ |
58 | 60 | } |
59 | 61 | |
60 | 62 | $cmd = wfEscapeShellArg( $wgFFmpegLocation ) . |
61 | | - ' -ss ' . intval( $options['thumbtime'] ) . ' ' . |
62 | 63 | ' -i ' . wfEscapeShellArg( $options['file']->getPath() ) . |
| 64 | + ' -ss ' . intval( $options['thumbtime'] ) . |
63 | 65 | # MJPEG, that's the same as JPEG except it's supported by the windows build of ffmpeg |
64 | 66 | # No audio, one frame |
65 | 67 | ' -f mjpeg -an -vframes 1 ' . |
— | — | @@ -66,7 +68,6 @@ |
67 | 69 | |
68 | 70 | $retval = 0; |
69 | 71 | $returnText = wfShellExec( $cmd, $retval ); |
70 | | - |
71 | 72 | // Check if it was successful |
72 | 73 | if ( !$options['file']->getHandler()->removeBadFile( $options['dstPath'], $retval ) ) { |
73 | 74 | return true; |