r83048 MediaWiki - Code Review archive

Repository:MediaWiki
Revision:r83047‎ | r83048 | r83049 >
Date:21:29, 1 March 2011
Author:dale
Status:deferred
Tags:
Comment:
added basic api module support for query stream sources
Modified paths:
  • /trunk/extensions/TimedMediaHandler/ApiQueryVideoInfo.php (added) (history)
  • /trunk/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/resources/mw.EmbedPlayer.js (modified) (history)
  • /trunk/extensions/TimedMediaHandler/TimedMediaHandler.hooks.php (modified) (history)
  • /trunk/extensions/TimedMediaHandler/TimedMediaHandler.php (modified) (history)
  • /trunk/extensions/TimedMediaHandler/WebVideoTranscode/WebVideoTranscode.php (modified) (history)

Diff [purge]

Index: trunk/extensions/TimedMediaHandler/TimedMediaHandler.php
@@ -40,6 +40,7 @@
4141 // Transcode support
4242 $wgAutoloadClasses['WebVideoTranscode'] = "$timedMediaDir/WebVideoTranscode/WebVideoTranscode.php";
4343 $wgAutoloadClasses['WebVideoTranscodeJob'] = "$timedMediaDir/WebVideoTranscode/WebVideoTranscodeJob.php";
 44+$wgAutoloadClasses['ApiQueryVideoInfo'] = "$timedMediaDir/ApiQueryVideoInfo.php";
4445
4546 // Register the Timed Media Handler javascript resources ( MwEmbed modules )
4647 MwEmbedResourceManager::register( 'extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer' );
Index: trunk/extensions/TimedMediaHandler/WebVideoTranscode/WebVideoTranscode.php
@@ -157,12 +157,17 @@
158158 * If no transcode is in progress or ready add the job to the jobQueue
159159 *
160160 * @param {Object} File object
 161+ * @param {Object} Options, a set of options:
 162+ * 'nodata' Strips the data- attribute, useful when your output is not html
161163 * @returns an associative array of sources suitable for <source> tag output
162164 */
163 - static public function getSources( &$file ){
 165+ static public function getSources( &$file , $options=array() ){
164166 global $wgEnabledTranscodeSet, $wgLang;
165167 $sources = array();
166168
 169+ // Setup options
 170+ $dataPrefix = in_array( 'nodata', $options )? '': 'data-';
 171+
167172 // Add the original file:
168173 $source = array(
169174 'src' => $file->getUrl(),
@@ -172,23 +177,23 @@
173178 $wgLang->formatNum( $file->getHeight() ),
174179 $wgLang->formatBitrate( $file->getHandler()->getBitrate( $file ) )
175180 ),
176 - 'data-shorttitle' => wfMsg('timedmedia-source-file', wfMsg( 'timedmedia-' . $file->getHandler()->getMetadataType() ) ),
 181+ "{$dataPrefix}shorttitle" => wfMsg('timedmedia-source-file', wfMsg( 'timedmedia-' . $file->getHandler()->getMetadataType() ) ),
177182
178 - 'data-width' => $file->getWidth(),
179 - 'data-height' => $file->getHeight(),
 183+ "{$dataPrefix}width" => $file->getWidth(),
 184+ "{$dataPrefix}height" => $file->getHeight(),
180185 // TODO add some title and data about the file
181186 );
182187
183 - // Just directly return audio sources ( for now no transcoding for audio )
 188+ // Just directly return audio sources ( No transcoding for audio )
184189 if( $file->getHandler()->isAudio( $file ) ){
185190 return $sources;
186191 }
187192 // For video include bitrate and framerate:
188193 $bitrate = $file->getHandler()->getBitrate( $file );
189 - if( $bitrate ) $source['data-bandwidth'] = $bitrate;
 194+ if( $bitrate ) $source["{$dataPrefix}bandwidth"] = round ( $bitrate );
190195
191196 $framerate = $file->getHandler()->getFramerate( $file );
192 - if( $framerate ) $source['data-framerate'] = $framerate;
 197+ if( $framerate ) $source["{$dataPrefix}framerate"] = $framerate;
193198
194199 // Add the source to the sources array
195200 $sources[] = $source;
@@ -223,29 +228,28 @@
224229 $addWebMFlag = true;
225230 }
226231 // Try and add the source
227 - self::tryAddSource( $file, $sources,$transcodeKey );
 232+ self::tryAddSource( $file, $sources, $transcodeKey, $dataPrefix );
228233 }
229234 // Make sure we got at least one ogg and webm encode
230235 if( !$addOggFlag || !$addWebMFlag){
231236 foreach( $wgEnabledTranscodeSet as $transcodeKey ){
232237 if( !$addOggFlag && self::$derivativeSettings[$transcodeKey]['codec'] == 'theora' ){
233 - self::tryAddSource( $file, $sources,$transcodeKey );
 238+ self::tryAddSource( $file, $sources, $transcodeKey, $dataPrefix );
234239 $addOggFlag = true;
235240 }
236241 if( !$addWebMFlag && self::$derivativeSettings[$transcodeKey]['codec'] == 'vp8' ){
237 - self::tryAddSource( $file, $sources, $transcodeKey );
 242+ self::tryAddSource( $file, $sources, $transcodeKey, $dataPrefix );
238243 $addWebMFlag = true;
239244 }
240245 }
241246 }
242247 return $sources;
243248 }
244 -
245249 /**
246250 * Try to add a source to the sources param
247 - * if the source is not found update the job queue
 251+ * if the source is not found update the job queue
248252 */
249 - public static function tryAddSource( &$file, &$sources, $transcodeKey){
 253+ public static function tryAddSource( &$file, &$sources, $transcodeKey, $dataPrefix=''){
250254 global $wgLang;
251255 $derivativeFile = self::getDerivativeFilePath( $file, $transcodeKey);
252256
@@ -256,7 +260,7 @@
257261 // if the source size is < $transcodeKey assume source size:
258262 if( is_file( $derivativeFile ) ){
259263 // Estimate bandwidth:
260 - $bandwidth = intval( filesize( $derivativeFile ) / $file->getLength() ) * 8;
 264+ $bandwidth = round( intval( filesize( $derivativeFile ) / $file->getLength() ) * 8 );
261265
262266 list( $width, $height ) = WebVideoTranscode::getMaxSizeTransform(
263267 $file,
@@ -269,14 +273,14 @@
270274 $sources[] = array(
271275 'src' => $thumbUrlDir . '/' .$file->getName() . '.' . $transcodeKey,
272276 'title' => wfMsg('timedmedia-derivative-desc-' . $transcodeKey ),
273 - 'data-shorttitle' => wfMsg('timedmedia-derivative-' . $transcodeKey),
 277+ "{$dataPrefix}shorttitle" => wfMsg('timedmedia-derivative-' . $transcodeKey),
274278
275279 // Add data attributes per emerging DASH / webTV adaptive streaming attributes
276280 // eventually we will define a manifest xml entry point.
277 - 'data-width' => $width,
278 - 'data-height' => $height,
279 - 'data-bandwidth' => $bandwidth,
280 - 'data-framerate' => $framerate,
 281+ "{$dataPrefix}width" => $width,
 282+ "{$dataPrefix}height" => $height,
 283+ "{$dataPrefix}bandwidth" => $bandwidth,
 284+ "{$dataPrefix}framerate" => $framerate,
281285 );
282286 } else {
283287 self::updateJobQueue($file, $transcodeKey);
Index: trunk/extensions/TimedMediaHandler/ApiQueryVideoInfo.php
@@ -0,0 +1,226 @@
 2+<?php
 3+/**
 4+ * Extends imageinfo with support for videoinfo sources property.
 5+ *
 6+ * Alternativly core ApiQueryImageInfo could support being extended in obvious ways.
 7+ */
 8+class ApiQueryVideoInfo extends ApiQueryImageInfo {
 9+
 10+ public function __construct( $query, $moduleName, $prefix = 'vi' ) {
 11+ // We allow a subclass to override the prefix, to create a related API module.
 12+ // Some other parts of MediaWiki construct this with a null $prefix, which used to be ignored when this only took two arguments
 13+ if ( is_null( $prefix ) ) {
 14+ $prefix = 'vi';
 15+ }
 16+ ApiQueryBase::__construct( $query, $moduleName, $prefix );
 17+ }
 18+
 19+ public function getDescription() {
 20+ return 'Extends imageinfo to include video source information';
 21+ }
 22+
 23+ static function getInfo( $file, $prop, $result, $thumbParams = null ) {
 24+ $vals = parent::getInfo( $file, $prop, $result, $thumbParams = null );
 25+ if( isset( $prop['derivatives'] ) ){
 26+ $vals['derivatives'] = WebVideoTranscode::getSources( $file, array( 'nodata', 'fullurl') );
 27+ }
 28+ return $vals;
 29+ }
 30+
 31+ public static function getPropertyNames() {
 32+ $prop = parent::getPropertyNames();
 33+ $prop[] = 'derivatives';
 34+ return $prop;
 35+ }
 36+ public static function getPropertyDescriptions() {
 37+ $s = parent::getPropertyDescriptions();
 38+ $s[] = ' derivatives -Adds an array of video source derivatives';
 39+ return $s;
 40+ }
 41+
 42+ protected function getExamples() {
 43+ return array(
 44+ 'api.php?action=query&titles=File:Folgers.ogv&prop=videoinfo',
 45+ );
 46+ }
 47+
 48+
 49+ /**
 50+ * execute and getAllowedprops have to be verbatim copied because of static self:: references
 51+ *
 52+ * With late static binding this would be avoidable:
 53+ * http://php.net/manual/en/language.oop5.late-static-bindings.php
 54+ */
 55+ public function execute() {
 56+ $params = $this->extractRequestParams();
 57+
 58+ $prop = array_flip( $params['prop'] );
 59+
 60+ $scale = $this->getScale( $params );
 61+
 62+ $pageIds = $this->getPageSet()->getAllTitlesByNamespace();
 63+ if ( !empty( $pageIds[NS_FILE] ) ) {
 64+ $titles = array_keys( $pageIds[NS_FILE] );
 65+ asort( $titles ); // Ensure the order is always the same
 66+
 67+ $skip = false;
 68+ if ( !is_null( $params['continue'] ) ) {
 69+ $skip = true;
 70+ $cont = explode( '|', $params['continue'] );
 71+ if ( count( $cont ) != 2 ) {
 72+ $this->dieUsage( 'Invalid continue param. You should pass the original ' .
 73+ 'value returned by the previous query', '_badcontinue' );
 74+ }
 75+ $fromTitle = strval( $cont[0] );
 76+ $fromTimestamp = $cont[1];
 77+ // Filter out any titles before $fromTitle
 78+ foreach ( $titles as $key => $title ) {
 79+ if ( $title < $fromTitle ) {
 80+ unset( $titles[$key] );
 81+ } else {
 82+ break;
 83+ }
 84+ }
 85+ }
 86+
 87+ $result = $this->getResult();
 88+ $images = RepoGroup::singleton()->findFiles( $titles );
 89+ foreach ( $images as $img ) {
 90+ // Skip redirects
 91+ if ( $img->getOriginalTitle()->isRedirect() ) {
 92+ continue;
 93+ }
 94+
 95+ $start = $skip ? $fromTimestamp : $params['start'];
 96+ $pageId = $pageIds[NS_IMAGE][ $img->getOriginalTitle()->getDBkey() ];
 97+
 98+ $fit = $result->addValue(
 99+ array( 'query', 'pages', intval( $pageId ) ),
 100+ 'imagerepository', $img->getRepoName()
 101+ );
 102+ if ( !$fit ) {
 103+ if ( count( $pageIds[NS_IMAGE] ) == 1 ) {
 104+ // The user is screwed. imageinfo can't be solely
 105+ // responsible for exceeding the limit in this case,
 106+ // so set a query-continue that just returns the same
 107+ // thing again. When the violating queries have been
 108+ // out-continued, the result will get through
 109+ $this->setContinueEnumParameter( 'start',
 110+ wfTimestamp( TS_ISO_8601, $img->getTimestamp() ) );
 111+ } else {
 112+ $this->setContinueEnumParameter( 'continue',
 113+ $this->getContinueStr( $img ) );
 114+ }
 115+ break;
 116+ }
 117+
 118+ // Check if we can make the requested thumbnail, and get transform parameters.
 119+ $finalThumbParams = $this->mergeThumbParams( $img, $scale, $params['urlparam'] );
 120+
 121+ // Get information about the current version first
 122+ // Check that the current version is within the start-end boundaries
 123+ $gotOne = false;
 124+ if (
 125+ ( is_null( $start ) || $img->getTimestamp() <= $start ) &&
 126+ ( is_null( $params['end'] ) || $img->getTimestamp() >= $params['end'] )
 127+ ) {
 128+ $gotOne = true;
 129+
 130+ $fit = $this->addPageSubItem( $pageId,
 131+ self::getInfo( $img, $prop, $result, $finalThumbParams ) );
 132+ if ( !$fit ) {
 133+ if ( count( $pageIds[NS_IMAGE] ) == 1 ) {
 134+ // See the 'the user is screwed' comment above
 135+ $this->setContinueEnumParameter( 'start',
 136+ wfTimestamp( TS_ISO_8601, $img->getTimestamp() ) );
 137+ } else {
 138+ $this->setContinueEnumParameter( 'continue',
 139+ $this->getContinueStr( $img ) );
 140+ }
 141+ break;
 142+ }
 143+ }
 144+
 145+ // Now get the old revisions
 146+ // Get one more to facilitate query-continue functionality
 147+ $count = ( $gotOne ? 1 : 0 );
 148+ $oldies = $img->getHistory( $params['limit'] - $count + 1, $start, $params['end'] );
 149+ foreach ( $oldies as $oldie ) {
 150+ if ( ++$count > $params['limit'] ) {
 151+ // We've reached the extra one which shows that there are additional pages to be had. Stop here...
 152+ // Only set a query-continue if there was only one title
 153+ if ( count( $pageIds[NS_FILE] ) == 1 ) {
 154+ $this->setContinueEnumParameter( 'start',
 155+ wfTimestamp( TS_ISO_8601, $oldie->getTimestamp() ) );
 156+ }
 157+ break;
 158+ }
 159+ $fit = $this->addPageSubItem( $pageId,
 160+ self::getInfo( $oldie, $prop, $result, $finalThumbParams ) );
 161+ if ( !$fit ) {
 162+ if ( count( $pageIds[NS_IMAGE] ) == 1 ) {
 163+ $this->setContinueEnumParameter( 'start',
 164+ wfTimestamp( TS_ISO_8601, $oldie->getTimestamp() ) );
 165+ } else {
 166+ $this->setContinueEnumParameter( 'continue',
 167+ $this->getContinueStr( $oldie ) );
 168+ }
 169+ break;
 170+ }
 171+ }
 172+ if ( !$fit ) {
 173+ break;
 174+ }
 175+ $skip = false;
 176+ }
 177+
 178+ $data = $this->getResultData();
 179+ foreach ( $data['query']['pages'] as $pageid => $arr ) {
 180+ if ( !isset( $arr['imagerepository'] ) ) {
 181+ $result->addValue(
 182+ array( 'query', 'pages', $pageid ),
 183+ 'imagerepository', ''
 184+ );
 185+ }
 186+ // The above can't fail because it doesn't increase the result size
 187+ }
 188+ }
 189+ }
 190+
 191+ public function getAllowedParams() {
 192+ return array(
 193+ 'prop' => array(
 194+ ApiBase::PARAM_ISMULTI => true,
 195+ ApiBase::PARAM_DFLT => 'timestamp|user',
 196+ ApiBase::PARAM_TYPE => self::getPropertyNames()
 197+ ),
 198+ 'limit' => array(
 199+ ApiBase::PARAM_TYPE => 'limit',
 200+ ApiBase::PARAM_DFLT => 1,
 201+ ApiBase::PARAM_MIN => 1,
 202+ ApiBase::PARAM_MAX => ApiBase::LIMIT_BIG1,
 203+ ApiBase::PARAM_MAX2 => ApiBase::LIMIT_BIG2
 204+ ),
 205+ 'start' => array(
 206+ ApiBase::PARAM_TYPE => 'timestamp'
 207+ ),
 208+ 'end' => array(
 209+ ApiBase::PARAM_TYPE => 'timestamp'
 210+ ),
 211+ 'urlwidth' => array(
 212+ ApiBase::PARAM_TYPE => 'integer',
 213+ ApiBase::PARAM_DFLT => -1
 214+ ),
 215+ 'urlheight' => array(
 216+ ApiBase::PARAM_TYPE => 'integer',
 217+ ApiBase::PARAM_DFLT => -1
 218+ ),
 219+ 'urlparam' => array(
 220+ ApiBase::PARAM_DFLT => '',
 221+ ApiBase::PARAM_TYPE => 'string',
 222+ ),
 223+ 'continue' => null,
 224+ );
 225+ }
 226+
 227+}
\ No newline at end of file
Index: trunk/extensions/TimedMediaHandler/TimedMediaHandler.hooks.php
@@ -12,7 +12,7 @@
1313 static function register(){
1414 global $wgParserOutputHooks, $wgHooks, $wgJobClasses, $wgJobExplitRequestTypes,
1515 $wgMediaHandlers, $wgResourceModules, $wgExcludeFromThumbnailPurge,
16 - $wgTimedMediaHandlerFileExtensions, $wgParserOutputHooks, $wgOut;
 16+ $wgTimedMediaHandlerFileExtensions, $wgParserOutputHooks, $wgOut, $wgAPIPropModules;
1717
1818 // Setup media Handlers:
1919 $wgMediaHandlers['application/ogg'] = 'OggHandler';
@@ -47,10 +47,10 @@
4848 ),
4949 'embedPlayerIframeStyle'=> $baseExtensionResource + array(
5050 'styles' => 'resources/embedPlayerIframe.css',
51 - )
 51+ )
5252 );
53 - // We should probably move this to a parser function but not working right
54 - // on special upload, when there is an "existing file" warning.
 53+ // We should probably move this to a parser function but not working correctly in
 54+ // dynamic contexts ( for example in special upload, when there is an "existing file" warning. )
5555 $wgHooks['BeforePageDisplay'][] = 'TimedMediaHandlerHooks::pageOutputHook';
5656
5757
@@ -60,6 +60,11 @@
6161 // Also add the .log file ( used in two pass encoding )
6262 // ( probably should move in-progress encodes out of web accessible directory )
6363 $wgExcludeFromThumbnailPurge+= array( 'log');
 64+
 65+ // Api hooks for derivatives and query video derivatives
 66+ $wgAPIPropModules += array(
 67+ 'videoinfo' => 'ApiQueryVideoInfo'
 68+ );
6469
6570 /**
6671 * Add support for the "TimedText" NameSpace
Index: trunk/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/resources/mw.EmbedPlayer.js
@@ -814,7 +814,6 @@
815815 */
816816 setupSourcePlayer: function() {
817817 mw.log("EmbedPlayer::setupSourcePlayer: " + this.id + ' sources: ' + this.mediaElement.sources.length );
818 -
819818 // Autoseletct the media source
820819 this.mediaElement.autoSelectSource();
821820

Status & tagging log