r61956 MediaWiki - Code Review archive

Repository:MediaWiki
Revision:r61955‎ | r61956 | r61957 >
Date:23:30, 3 February 2010
Author:dale
Status:deferred
Tags:
Comment:
* stubs and schema for ApiPlayTracking
* reorganized oggTranscode and ApiPlayTracking into respective folders
Modified paths:
  • /trunk/extensions/OggHandler/ApiPlayTracking (added) (history)
  • /trunk/extensions/OggHandler/ApiPlayTracking/ApiPlayTracking.php (added) (history)
  • /trunk/extensions/OggHandler/ApiPlayTracking/ApiPlayTracking.sql (added) (history)
  • /trunk/extensions/OggHandler/OggHandler.php (modified) (history)
  • /trunk/extensions/OggHandler/OggHandler_body.php (modified) (history)
  • /trunk/extensions/OggHandler/OggTranscode (added) (history)
  • /trunk/extensions/OggHandler/OggTranscode.php (deleted) (history)
  • /trunk/extensions/OggHandler/OggTranscode.sql (deleted) (history)
  • /trunk/extensions/OggHandler/OggTranscode/OggTranscode.php (added) (history)
  • /trunk/extensions/OggHandler/OggTranscode/OggTranscode.sql (added) (history)
  • /trunk/extensions/OggHandler/OggTranscode/OggTranscodeCron.php (added) (history)
  • /trunk/extensions/OggHandler/OggTranscode/patch-image-index.sql (added) (history)
  • /trunk/extensions/OggHandler/OggTranscodeCron.php (deleted) (history)
  • /trunk/extensions/OggHandler/patch-image-index.sql (deleted) (history)

Diff [purge]

Index: trunk/extensions/OggHandler/patch-image-index.sql
@@ -1,14 +0,0 @@
2 -CREATE INDEX /*i*/image_media_type ON /*_*/image ( img_media_type );
3 -
4 -CREATE INDEX /*i*/transcode_job_name ON /*_*/transcode_job ( tjob_name );
5 -
6 -CREATE INDEX /*i*/transcode_job_state ON /*_*/transcode_job ( tjob_state );
\ No newline at end of file
Index: trunk/extensions/OggHandler/OggTranscodeCron.php
@@ -1,318 +0,0 @@
2 -<?php
3 -
4 -/*
5 -* OggTranscodeCron.php
6 -*
7 -* Maintenance script overview:
8 -*
9 -* Designed to be run every 10 seconds or so. Will spawn threads
10 -* until max thread count reached
11 -*
12 -* 1) Check if number of instances is < $wgMaxTranscodeThreads
13 -* the script exits immediately.
14 -*
15 -* 2) Query the db for jobSets ( find a job that is not processed or > wgTranscodeJobTimeOut )
16 -*
17 -* 3) Does a incomplete transcode to temporary location
18 -* once done moves file into place.
19 -*
20 -*/
21 -require_once( dirname(__FILE__) . '/../../maintenance/Maintenance.php' );
22 -
23 -class OggTranscodeCron extends Maintenance {
24 -
25 - // The max number of threads ( can also be set when called via the command line )
26 - private $maxThreads = 2;
27 -
28 - public function __construct() {
29 - global $wgUseNormalUser;
30 - parent::__construct();
31 - $this->mDescription = "Transcode video files";
32 - $this->addOption( 'maxThreads', 'Maximum number of threads to run', false, true );
33 - $wgUseNormalUser = true;
34 - }
35 -
36 - /**
37 - * Main Execute method from Maintenance class
38 - */
39 - public function execute() {
40 - global $wgEnabledDerivatives;
41 - // Set command line options:
42 - if ( $this->hasOption( 'maxThreads' ) ) {
43 - $this->maxThreads = intval( $this->hasOption( 'maxThreads' ) );
44 - }
45 -
46 - // Check if number of instances is < $wgMaxTranscodeThreads
47 - if( $this->checkMaxThreads() ){
48 - exit( 0 );
49 - }
50 -
51 - // Check if we have $wgEnabledDerivatives to transcode to.
52 - if( !isset( $wgEnabledDerivatives ) || count( $wgEnabledDerivatives ) == 0 ){
53 - print "\$wgEnabledDerivatives is not set or empty \n";
54 - exit( 0 );
55 - }
56 -
57 - // Check if there are any jobs to be done
58 - $job = $this->getTranscodeJob();
59 - if( $job ){
60 - if( ! $this->processTranscodeJob( $job ) ){
61 - // Mark the job as failed if it did not complete
62 - $this->markJobState( $job, 'FAILED' );
63 - exit( 1 );
64 - }
65 - // Else job was oky mark state and exit:
66 - $this->markJobState( $job, 'OK' );
67 - exit( 0 );
68 - }
69 - // No jobs found.
70 -
71 - // Update Transcode Jobs table with images that are missing transcode jobs
72 - // ( the updated transcode job set will be accessed the next time the script is run)
73 - $this->updateTranscodeJobs();
74 - exit( 0 );
75 - }
76 -
77 - /**
78 - * Get a Transcode Job from the transcode_job table
79 - */
80 - function getTranscodeJob() {
81 - $dbr = & wfGetDB( DB_SLAVE );
82 -
83 - // Don't hit the slaves under high load:
84 - wfWaitForSlaves( 5 );
85 -
86 - // Grab transcode job
87 - $res = $dbr->select(
88 - 'transcode_job',
89 - '*',
90 - 'tjob_state IS NULL',
91 - __METHOD__,
92 - array(
93 - 'USE INDEX' => array(
94 - 'transcode_job' => 'transcode_job_state'
95 - ),
96 - 'LIMIT' => 20
97 - )
98 - );
99 - return $dbr->fetchObject( $res );
100 - }
101 -
102 - /**
103 - * Grab a batch of up-to 100 jobs and insert them into the jobs table.
104 - *
105 - * NOTE: this presently does not test for missing derivative keys /
106 - * keep derivative keys "in-sync" with transcode_job table.
107 - */
108 - function updateTranscodeJobs( ){
109 - global $wgEnabledDerivatives;
110 - // Find new jobs and insert them into the db
111 - $dbr = & wfGetDB( DB_SLAVE );
112 -
113 - // Don't hit the slaves under high load:
114 - wfWaitForSlaves( 5 );
115 -
116 - // Get image files that don't have a transcode job
117 - $res = $dbr->select(
118 - array( 'image', 'transcode_job'),
119 - array( 'img_name' ),
120 - array( 'tjob_name IS NULL',
121 - 'img_media_type' => 'VIDEO'),
122 - __METHOD__,
123 - array( 'LIMIT' => 100 ),
124 - array(
125 - 'transcode_job' => array(
126 - 'LEFT JOIN',
127 - array( 'img_name = tjob_name' )
128 - )
129 - )
130 - );
131 - $imageNames = array();
132 - while( $row = $dbr->fetchObject( $res ) ) {
133 - $imageNames[] = $row->img_name;
134 - }
135 - if( count( $imageNames ) == 0){
136 - return false;
137 - }
138 -
139 - // Add the derivative set[s] to the transcode table
140 - $dbw = & wfGetDB( DB_MASTER );
141 - $dbw->begin();
142 - foreach( $imageNames as $name){
143 - foreach( $wgEnabledDerivatives as $derivativeKey ){
144 -
145 - // Do not to add a derivative job that is > than the source asset
146 - $fileTitle = Title::newFromText( $name, NS_FILE);
147 -
148 - $file = wfFindFile( $fileTitle );
149 - if( !$file ){
150 - $this->output( "File not found: {$name} (not adding to jobQueue\n" );
151 - continue;
152 - }
153 - $targetSize = OggTranscode::$derivativeSettings[ $derivativeKey ]['maxSize'];
154 - $sourceSize = $file->getWidth();
155 - if( $targetSize > $sourceSize ){
156 - $this->output( "File:{$name} is too small for {$derivativeKey} ::\n" .
157 - "target: {$targetSize} > source: {$sourceSize} \n\n" );
158 - continue;
159 - }
160 - // Else $derivative size is < source size, do insert:
161 - $dbw->insert(
162 - 'transcode_job',
163 - array(
164 - 'tjob_name' => $name,
165 - 'tjob_derivative_key' => $derivativeKey,
166 - 'tjob_start_timestamp' => time()
167 - ),
168 - __METHOD__
169 - );
170 - }
171 - }
172 - $dbw->commit();
173 - }
174 -
175 - /**
176 - * Process a transcode job
177 - * @param {Object} $job Transcode job db row
178 - * @return {Bollean}
179 - * true if job was processed
180 - * false if there was an error in the job
181 - */
182 - function processTranscodeJob( $job ){
183 - $dbw = & wfGetDB( DB_MASTER );
184 -
185 - // Update job state to "ASSIGNED"
186 - $this->markJobState( $job, 'ASSIGNED');
187 -
188 - // Get the source title from tjob_name
189 - $fileTitle = Title::newFromText( $job->tjob_name, NS_FILE);
190 - if( ! $fileTitle->exists() ){
191 - $this->output( "Title not found: {$job->tjob_name}\n" );
192 - return false;
193 - }
194 -
195 - // Get the file source:
196 - $file = wfFindFile( $fileTitle );
197 - if( !$file ){
198 - $this->output( "File not found: {$job->tjob_name}\n" );
199 - return false;
200 - }
201 -
202 - // Setup a temporary target location for encode output
203 - $tempTarget = wfTempDir() .'/'. $fileTitle->getDbKey() . $job->tjob_derivative_key . '.ogv';
204 -
205 - // Get encoding settings from encode key
206 - if( !isset( OggTranscode::$derivativeSettings[ $job->tjob_derivative_key ] )){
207 - $this->output( "Derivative key not found: {$job->tjob_name}\n" );
208 - return false;
209 - }
210 - $encodeSettings = OggTranscode::$derivativeSettings[ $job->tjob_derivative_key ];
211 -
212 - // Shell out the transcode command.
213 - $this->output( "Starting transcode:\n" );
214 - $result = $this->doEncode( $file->getPath(), $tempTarget, $encodeSettings );
215 -
216 - // Check the result
217 - if( !$result ){
218 - $this->output( "Transcode failed: {$job->tjob_name}\n" );
219 - return false;
220 - }
221 -
222 - // If result is "ok"
223 - $this->output( "Transcode OK, moving thumb to public location\n" );
224 - $derivativeTarget = $file->getThumbPath( $job->tjob_derivative_key ) . '.ogv';
225 -
226 - if( !rename( $tempTarget, $derivativeTarget) ){
227 - $this->output( "Renamed failed: {$tempTarget} to {$derivativeTarget}\n" );
228 - return false;
229 - }
230 - // Return true to update the job state:
231 - return true;
232 - }
233 - /**
234 - * Mark a job as state
235 - * @param {Object} $job Job db row object.
236 - * @param {String} $state String to update state to can be:
237 - * 'OK','ASSIGNED','FAILED'
238 - */
239 - function markJobState( $job , $state){
240 - $dbw = & wfGetDB( DB_MASTER );
241 - $dbw->update(
242 - 'transcode_job',
243 - array(
244 - 'tjob_state' => $state
245 - ),
246 - array(
247 - 'tjob_name' => $job->tjob_name,
248 - 'tjob_derivative_key' => $job->tjob_derivative_key
249 - )
250 - );
251 - }
252 -
253 - /**
254 - * Check the number if the instances of this script that are running
255 - * are over the max allowed threads $this->maxThreads
256 - *
257 - * @return {Boolean}
258 - * true if max Threads count has been reached
259 - * false if less than max Threads
260 - */
261 - public function checkMaxThreads(){
262 -
263 - // Get the list of processes:
264 - $pslist = wfShellExec( "ps aux", $out);
265 -
266 - // Return the count of php OggTranscodeCron.php found
267 - $threadCount = preg_match_all( '/php\sOggTranscodeCron\.php/', $pslist, $matches);
268 - if( $threadCount === false ){
269 - print "Error in preg_match";
270 - exit( 1 );
271 - }
272 - return ( $threadCount > $this->maxThreads );
273 - }
274 -
275 - /**
276 - * Issues an encode command to ffmpeg2theora
277 - *
278 - * @param {String} $source Source file asset
279 - * @param {String} $target Target output encode
280 - * @param {Array} $encodeSettings Settings to encode the file with
281 - */
282 - function doEncode( $source, $target, $encodeSettings ){
283 - global $wgffmpeg2theoraPath;
284 -
285 - // Set up the base command
286 - $cmd = wfEscapeShellArg( $wgffmpeg2theoraPath ) . ' ' . wfEscapeShellArg( $source );
287 -
288 - // Add in the encode settings
289 - foreach( $encodeSettings as $key => $val){
290 - if( isset( OggTranscode::$foggMap[$key] ) ){
291 - if( is_array( OggTranscode::$foggMap[$key] ) ){
292 - $cmd.= ' '. implode(' ', OggTranscode::$foggMap[$key] );
293 - }else if($val == 'true' || $val === true){
294 - $cmd.= ' '. OggTranscode::$foggMap[$key];
295 - }else if( $val === false){
296 - //ignore "false" flags
297 - }else{
298 - //normal get/set value
299 - $cmd.= ' '. OggTranscode::$foggMap[$key] . ' ' . wfEscapeShellArg( $val );
300 - }
301 - }
302 - }
303 - // Add the output target:
304 - $cmd.= ' -o ' . wfEscapeShellArg ( $target );
305 - $this->output( "Running cmd: \n\n" .$cmd . "\n\n" );
306 - wfProfileIn( 'ffmpeg2theora_encode' );
307 - wfShellExec( $cmd, $retval );
308 - wfProfileOut( 'ffmpeg2theora_encode' );
309 -
310 - if( $retval ){
311 - return false;
312 - }
313 - return true;
314 - }
315 -}
316 -
317 -$maintClass = "OggTranscodeCron";
318 -require_once( DO_MAINTENANCE );
319 -?>
\ No newline at end of file
Index: trunk/extensions/OggHandler/OggTranscode.php
@@ -1,199 +0,0 @@
2 -<?php
3 -
4 -/*
5 - * OggTranscode provides keys and encode settings
6 - */
7 -
8 -
9 -/*
10 - * Main OggTranscode Class hold some constants and config values
11 - */
12 -class OggTranscode {
13 - /**
14 - * Key constants for the derivatives,
15 - * this key is appended to the derivative file name
16 - *
17 - * If you update the wgDerivativeSettings for one of these keys
18 - * and want to re-generate the video you should also update the
19 - * key constant.
20 - */
21 - const ENC_WEB_2MBS = '200_200kbs';
22 - const ENC_WEB_4MBS = '360_400kbs';
23 - const ENC_WEB_6MBS = '480_600kbs';
24 - const ENC_HQ_VBR = '720_VBR';
25 -
26 - /**
27 - * Encoding parameters are set via firefogg encode api
28 - *
29 - * For clarity and compatibility with passing down
30 - * client side encode settings at point of upload
31 - *
32 - * http://firefogg.org/dev/index.html
33 - */
34 -
35 - public static $derivativeSettings = array(
36 - OggTranscode::ENC_WEB_2MBS =>
37 - array(
38 - 'maxSize' => '200',
39 - 'videoBitrate' => '128',
40 - 'audioBitrate' => '32',
41 - 'samplerate' => '22050',
42 - 'framerate' => '15',
43 - 'channels' => '1',
44 - 'noUpscaling' => 'true',
45 - 'twopass' => 'true',
46 - 'keyframeInterval' => '64',
47 - 'bufDelay' => '128'
48 - ),
49 - OggTranscode::ENC_WEB_4MBS =>
50 - array(
51 - 'maxSize' => '360',
52 - 'videoBitrate' => '368',
53 - 'audioBitrate' => '48',
54 - 'noUpscaling' => 'true',
55 - 'twopass' => 'true',
56 - 'keyframeInterval' => '128',
57 - 'bufDelay' => '256'
58 - ),
59 - OggTranscode::ENC_WEB_6MBS =>
60 - array(
61 - 'maxSize' => '480',
62 - 'videoBitrate' => '512',
63 - 'audioBitrate' => '96',
64 - 'noUpscaling' => 'true',
65 - 'twopass' => 'true',
66 - 'keyframeInterval' => '128',
67 - 'bufDelay' => '256'
68 - ),
69 - OggTranscode::ENC_HQ_VBR =>
70 - array(
71 - 'maxSize' => '720',
72 - 'videoQuality' => 7,
73 - 'audioQuality' => 3,
74 - 'noUpscaling' => 'true'
75 - )
76 - );
77 - /**
78 - * Mapping between firefogg api and ffmpeg2theora command line
79 - *
80 - * This lets us share a common api between firefogg and oggTranscode
81 - * also see: http://firefogg.org/dev/index.html
82 - */
83 - public static $foggMap = array(
84 - //video
85 - 'width' => "--width",
86 - 'height' => "--height",
87 - 'maxSize' => "--max_size",
88 - 'noUpscaling' => "--no-upscaling",
89 - 'videoQuality'=> "-v",
90 - 'videoBitrate' => "-V",
91 - 'twopass' => "--two-pass",
92 - 'framerate' => "-F",
93 - 'aspect' => "--aspect",
94 - 'starttime' => "--starttime",
95 - 'endtime' => "--endtime",
96 - 'cropTop' => "--croptop",
97 - 'cropBottom' => "--cropbottom",
98 - 'cropLeft' => "--cropleft",
99 - 'cropRight' => "--cropright",
100 - 'keyframeInterval'=> "--key",
101 - 'denoise' => array("--pp", "de"),
102 - 'novideo' => array("--novideo", "--no-skeleton"),
103 - 'bufDelay' => "--buf-delay",
104 - //audio
105 - 'audioQuality' => "-a",
106 - 'audioBitrate' => "-A",
107 - 'samplerate' => "-H",
108 - 'channels' => "-c",
109 - 'noaudio' => "--noaudio",
110 - //metadata
111 - 'artist' => "--artist",
112 - 'title' => "--title",
113 - 'date' => "--date",
114 - 'location' => "--location",
115 - 'organization' => "--organization",
116 - 'copyright' => "--copyright",
117 - 'license' => "--license",
118 - 'contact' => "--contact"
119 - );
120 - /*
121 - * Setup the OggTranscode tables
122 - */
123 - public static function schema() {
124 - global $wgExtNewTables, $wgExtNewIndexes;
125 -
126 - $wgExtNewTables[] = array(
127 - 'transcode_job',
128 - dirname( __FILE__ ) . '/OggTranscode.sql'
129 - );
130 -
131 - $wgExtNewIndexes[] = array(
132 - 'image', 'image_media_type',
133 - dirname( __FILE__ ) . '/patch-image-index.sql'
134 - );
135 -
136 - return true;
137 - }
138 -
139 - /**
140 - * Get derivative url for given embed width
141 - *
142 - * @param {Object} $srcFile Source file object
143 - * @param {Number} $targetWidth Target output width
144 - * @return {String}
145 - * the url for a given embed width,
146 - * or the srcFile url if no derivative found
147 - */
148 - static function getWidthDerivativeURL( $srcFile, $targetWidth){
149 - global $wgEnabledDerivatives;
150 - $srcWidth = $srcFile->getWidth();
151 - $srcHeight = $srcFile->getHeight();
152 -
153 - // Return source file url if targetdWidth greater than our source file. )
154 - // should cover audio as well
155 -
156 - // NOTE removed: && get_class( $srcFile->handler) != 'NonFreeVideoHandler')
157 - if( $targetWidth >= $srcWidth ){
158 - $srcFile->getURL();
159 - }
160 -
161 - // Get the available derivatives by difference of 'maxSize' to 'targetWidth'
162 - $derivativeSet = array();
163 -
164 - // include the source asset in the $derivativeSet distance comparison
165 - $derivativeSet[ 'SOURCE' ] = abs( $targetWidth - $srcWidth );
166 -
167 - foreach( $wgEnabledDerivatives as $derivativeKey ){
168 - if( isset( self::$derivativeSettings[ $derivativeKey ] ) ){
169 - $derivativePath = $srcFile->getThumbPath( $derivativeKey );
170 - // Check for derivative file:
171 - if( is_file ( "{$derivativePath}.ogv" )){
172 - $maxSize = self::$derivativeSettings[ $derivativeKey ]['maxSize'];
173 - $derivativeSet[ $derivativeKey ] = abs( $targetWidth - $maxSize );
174 - }
175 - }
176 - }
177 -
178 - // No derivative found return the src url
179 - if( count( $derivativeSet ) == 0 ){
180 - return $srcFile->getURL();
181 - }
182 - // Sort the $derivativeSet
183 - asort( $derivativeSet );
184 -
185 - // Reset the pointer to start:
186 - reset( $derivativeSet );
187 -
188 - // Handle special case where source is closes to target:
189 - if( key( $derivativeSet ) == 'SOURCE' ){
190 - return $srcFile->getURL();
191 - }
192 -
193 - // Get the url for the closest derivative
194 - return $srcFile->getThumbUrl( key( $derivativeSet ) . '.ogv');
195 - }
196 -}
197 -
198 -
199 -
200 -?>
\ No newline at end of file
Index: trunk/extensions/OggHandler/OggTranscode.sql
@@ -1,29 +0,0 @@
2 -
3 -CREATE TABLE IF NOT EXISTS /*_*/transcode_job (
4 -
5 - --File name key ( called image to match table name )
6 - tjob_name varbinary(255) NOT NULL,
7 -
8 - --Derivative key of the transcode
9 - tjob_derivative_key varbinary(40) NOT NULL,
10 -
11 - -- Timestamp
12 - `tjob_start_timestamp` char(14) NOT NULL,
13 -
14 - -- Transcoding state
15 - tjob_state enum('OK','ASSIGNED','FAILED') default NULL
16 -
17 -) /*$wgDBTableOptions*/;
18 -
19 -CREATE INDEX /*i*/transcode_job_name ON /*_*/transcode_job ( tjob_name );
20 -
21 -CREATE INDEX /*i*/transcode_job_state ON /*_*/transcode_job ( tjob_state );
Index: trunk/extensions/OggHandler/OggTranscode/patch-image-index.sql
@@ -0,0 +1,14 @@
 2+--
 3+-- Add an index on img_media_type
 4+--
 5+CREATE INDEX /*i*/image_media_type ON /*_*/image ( img_media_type );
 6+
 7+--
 8+-- Index for transcode_job_name
 9+--
 10+CREATE INDEX /*i*/transcode_job_name ON /*_*/transcode_job ( tjob_name );
 11+
 12+--
 13+-- Index for tjob_state
 14+--
 15+CREATE INDEX /*i*/transcode_job_state ON /*_*/transcode_job ( tjob_state );
\ No newline at end of file
Property changes on: trunk/extensions/OggHandler/OggTranscode/patch-image-index.sql
___________________________________________________________________
Name: svn:mergeinfo
116 +
Index: trunk/extensions/OggHandler/OggTranscode/OggTranscode.php
@@ -0,0 +1,199 @@
 2+<?php
 3+
 4+/*
 5+ * OggTranscode provides keys and encode settings
 6+ */
 7+
 8+
 9+/*
 10+ * Main OggTranscode Class hold some constants and config values
 11+ */
 12+class OggTranscode {
 13+ /**
 14+ * Key constants for the derivatives,
 15+ * this key is appended to the derivative file name
 16+ *
 17+ * If you update the wgDerivativeSettings for one of these keys
 18+ * and want to re-generate the video you should also update the
 19+ * key constant.
 20+ */
 21+ const ENC_WEB_2MBS = '200_200kbs';
 22+ const ENC_WEB_4MBS = '360_400kbs';
 23+ const ENC_WEB_6MBS = '480_600kbs';
 24+ const ENC_HQ_VBR = '720_VBR';
 25+
 26+ /**
 27+ * Encoding parameters are set via firefogg encode api
 28+ *
 29+ * For clarity and compatibility with passing down
 30+ * client side encode settings at point of upload
 31+ *
 32+ * http://firefogg.org/dev/index.html
 33+ */
 34+ public static $derivativeSettings = array(
 35+ OggTranscode::ENC_WEB_2MBS =>
 36+ array(
 37+ 'maxSize' => '200',
 38+ 'videoBitrate' => '128',
 39+ 'audioBitrate' => '32',
 40+ 'samplerate' => '22050',
 41+ 'framerate' => '15',
 42+ 'channels' => '1',
 43+ 'noUpscaling' => 'true',
 44+ 'twopass' => 'true',
 45+ 'keyframeInterval' => '64',
 46+ 'bufDelay' => '128'
 47+ ),
 48+ OggTranscode::ENC_WEB_4MBS =>
 49+ array(
 50+ 'maxSize' => '360',
 51+ 'videoBitrate' => '368',
 52+ 'audioBitrate' => '48',
 53+ 'noUpscaling' => 'true',
 54+ 'twopass' => 'true',
 55+ 'keyframeInterval' => '128',
 56+ 'bufDelay' => '256'
 57+ ),
 58+ OggTranscode::ENC_WEB_6MBS =>
 59+ array(
 60+ 'maxSize' => '480',
 61+ 'videoBitrate' => '512',
 62+ 'audioBitrate' => '96',
 63+ 'noUpscaling' => 'true',
 64+ 'twopass' => 'true',
 65+ 'keyframeInterval' => '128',
 66+ 'bufDelay' => '256'
 67+ ),
 68+ OggTranscode::ENC_HQ_VBR =>
 69+ array(
 70+ 'maxSize' => '720',
 71+ 'videoQuality' => 7,
 72+ 'audioQuality' => 3,
 73+ 'noUpscaling' => 'true'
 74+ )
 75+ );
 76+ /**
 77+ * Mapping between firefogg api and ffmpeg2theora command line
 78+ *
 79+ * This lets us share a common api between firefogg and oggTranscode
 80+ * also see: http://firefogg.org/dev/index.html
 81+ */
 82+ public static $foggMap = array(
 83+ //video
 84+ 'width' => "--width",
 85+ 'height' => "--height",
 86+ 'maxSize' => "--max_size",
 87+ 'noUpscaling' => "--no-upscaling",
 88+ 'videoQuality'=> "-v",
 89+ 'videoBitrate' => "-V",
 90+ 'twopass' => "--two-pass",
 91+ 'framerate' => "-F",
 92+ 'aspect' => "--aspect",
 93+ 'starttime' => "--starttime",
 94+ 'endtime' => "--endtime",
 95+ 'cropTop' => "--croptop",
 96+ 'cropBottom' => "--cropbottom",
 97+ 'cropLeft' => "--cropleft",
 98+ 'cropRight' => "--cropright",
 99+ 'keyframeInterval'=> "--key",
 100+ 'denoise' => array("--pp", "de"),
 101+ 'novideo' => array("--novideo", "--no-skeleton"),
 102+ 'bufDelay' => "--buf-delay",
 103+ //audio
 104+ 'audioQuality' => "-a",
 105+ 'audioBitrate' => "-A",
 106+ 'samplerate' => "-H",
 107+ 'channels' => "-c",
 108+ 'noaudio' => "--noaudio",
 109+ //metadata
 110+ 'artist' => "--artist",
 111+ 'title' => "--title",
 112+ 'date' => "--date",
 113+ 'location' => "--location",
 114+ 'organization' => "--organization",
 115+ 'copyright' => "--copyright",
 116+ 'license' => "--license",
 117+ 'contact' => "--contact"
 118+ );
 119+
 120+ /**
 121+ * Setup the OggTranscode tables
 122+ */
 123+ public static function schema() {
 124+ global $wgExtNewTables, $wgExtNewIndexes;
 125+
 126+ $wgExtNewTables[] = array(
 127+ 'transcode_job',
 128+ dirname( __FILE__ ) . '/OggTranscode.sql'
 129+ );
 130+
 131+ $wgExtNewIndexes[] = array(
 132+ 'image', 'image_media_type',
 133+ dirname( __FILE__ ) . '/patch-image-index.sql'
 134+ );
 135+
 136+ return true;
 137+ }
 138+
 139+ /**
 140+ * Get derivative url for given embed width
 141+ *
 142+ * @param {Object} $srcFile Source file object
 143+ * @param {Number} $targetWidth Target output width
 144+ * @return {String}
 145+ * the url for a given embed width,
 146+ * or the srcFile url if no derivative found
 147+ */
 148+ static function getWidthDerivativeURL( $srcFile, $targetWidth){
 149+ global $wgEnabledDerivatives;
 150+ $srcWidth = $srcFile->getWidth();
 151+ $srcHeight = $srcFile->getHeight();
 152+
 153+ // Return source file url if targetdWidth greater than our source file. )
 154+ // should cover audio as well
 155+
 156+ // NOTE removed: && get_class( $srcFile->handler) != 'NonFreeVideoHandler')
 157+ if( $targetWidth >= $srcWidth ){
 158+ $srcFile->getURL();
 159+ }
 160+
 161+ // Get the available derivatives by difference of 'maxSize' to 'targetWidth'
 162+ $derivativeSet = array();
 163+
 164+ // include the source asset in the $derivativeSet distance comparison
 165+ $derivativeSet[ 'SOURCE' ] = abs( $targetWidth - $srcWidth );
 166+
 167+ foreach( $wgEnabledDerivatives as $derivativeKey ){
 168+ if( isset( self::$derivativeSettings[ $derivativeKey ] ) ){
 169+ $derivativePath = $srcFile->getThumbPath( $derivativeKey );
 170+ // Check for derivative file:
 171+ if( is_file ( "{$derivativePath}.ogv" )){
 172+ $maxSize = self::$derivativeSettings[ $derivativeKey ]['maxSize'];
 173+ $derivativeSet[ $derivativeKey ] = abs( $targetWidth - $maxSize );
 174+ }
 175+ }
 176+ }
 177+
 178+ // No derivative found return the src url
 179+ if( count( $derivativeSet ) == 0 ){
 180+ return $srcFile->getURL();
 181+ }
 182+ // Sort the $derivativeSet
 183+ asort( $derivativeSet );
 184+
 185+ // Reset the pointer to start:
 186+ reset( $derivativeSet );
 187+
 188+ // Handle special case where source is closes to target:
 189+ if( key( $derivativeSet ) == 'SOURCE' ){
 190+ return $srcFile->getURL();
 191+ }
 192+
 193+ // Get the url for the closest derivative
 194+ return $srcFile->getThumbUrl( key( $derivativeSet ) . '.ogv');
 195+ }
 196+}
 197+
 198+
 199+
 200+?>
\ No newline at end of file
Property changes on: trunk/extensions/OggHandler/OggTranscode/OggTranscode.php
___________________________________________________________________
Name: svn:mergeinfo
1201 +
Index: trunk/extensions/OggHandler/OggTranscode/OggTranscodeCron.php
@@ -0,0 +1,318 @@
 2+<?php
 3+
 4+/*
 5+* OggTranscodeCron.php
 6+*
 7+* Maintenance script overview:
 8+*
 9+* Designed to be run every 10 seconds or so. Will spawn threads
 10+* until max thread count reached
 11+*
 12+* 1) Check if number of instances is < $wgMaxTranscodeThreads
 13+* the script exits immediately.
 14+*
 15+* 2) Query the db for jobSets ( find a job that is not processed or > wgTranscodeJobTimeOut )
 16+*
 17+* 3) Does a incomplete transcode to temporary location
 18+* once done moves file into place.
 19+*
 20+*/
 21+require_once( dirname(__FILE__) . '/../../maintenance/Maintenance.php' );
 22+
 23+class OggTranscodeCron extends Maintenance {
 24+
 25+ // The max number of threads ( can also be set when called via the command line )
 26+ private $maxThreads = 2;
 27+
 28+ public function __construct() {
 29+ global $wgUseNormalUser;
 30+ parent::__construct();
 31+ $this->mDescription = "Transcode video files";
 32+ $this->addOption( 'maxThreads', 'Maximum number of threads to run', false, true );
 33+ $wgUseNormalUser = true;
 34+ }
 35+
 36+ /**
 37+ * Main Execute method from Maintenance class
 38+ */
 39+ public function execute() {
 40+ global $wgEnabledDerivatives;
 41+ // Set command line options:
 42+ if ( $this->hasOption( 'maxThreads' ) ) {
 43+ $this->maxThreads = intval( $this->hasOption( 'maxThreads' ) );
 44+ }
 45+
 46+ // Check if number of instances is < $wgMaxTranscodeThreads
 47+ if( $this->checkMaxThreads() ){
 48+ exit( 0 );
 49+ }
 50+
 51+ // Check if we have $wgEnabledDerivatives to transcode to.
 52+ if( !isset( $wgEnabledDerivatives ) || count( $wgEnabledDerivatives ) == 0 ){
 53+ print "\$wgEnabledDerivatives is not set or empty \n";
 54+ exit( 0 );
 55+ }
 56+
 57+ // Check if there are any jobs to be done
 58+ $job = $this->getTranscodeJob();
 59+ if( $job ){
 60+ if( ! $this->processTranscodeJob( $job ) ){
 61+ // Mark the job as failed if it did not complete
 62+ $this->markJobState( $job, 'FAILED' );
 63+ exit( 1 );
 64+ }
 65+ // Else job was oky mark state and exit:
 66+ $this->markJobState( $job, 'OK' );
 67+ exit( 0 );
 68+ }
 69+ // No jobs found.
 70+
 71+ // Update Transcode Jobs table with images that are missing transcode jobs
 72+ // ( the updated transcode job set will be accessed the next time the script is run)
 73+ $this->updateTranscodeJobs();
 74+ exit( 0 );
 75+ }
 76+
 77+ /**
 78+ * Get a Transcode Job from the transcode_job table
 79+ */
 80+ function getTranscodeJob() {
 81+ $dbr = & wfGetDB( DB_SLAVE );
 82+
 83+ // Don't hit the slaves under high load:
 84+ wfWaitForSlaves( 5 );
 85+
 86+ // Grab transcode job
 87+ $res = $dbr->select(
 88+ 'transcode_job',
 89+ '*',
 90+ 'tjob_state IS NULL',
 91+ __METHOD__,
 92+ array(
 93+ 'USE INDEX' => array(
 94+ 'transcode_job' => 'transcode_job_state'
 95+ ),
 96+ 'LIMIT' => 20
 97+ )
 98+ );
 99+ return $dbr->fetchObject( $res );
 100+ }
 101+
 102+ /**
 103+ * Grab a batch of up-to 100 jobs and insert them into the jobs table.
 104+ *
 105+ * NOTE: this presently does not test for missing derivative keys /
 106+ * keep derivative keys "in-sync" with transcode_job table.
 107+ */
 108+ function updateTranscodeJobs( ){
 109+ global $wgEnabledDerivatives;
 110+ // Find new jobs and insert them into the db
 111+ $dbr = & wfGetDB( DB_SLAVE );
 112+
 113+ // Don't hit the slaves under high load:
 114+ wfWaitForSlaves( 5 );
 115+
 116+ // Get image files that don't have a transcode job
 117+ $res = $dbr->select(
 118+ array( 'image', 'transcode_job'),
 119+ array( 'img_name' ),
 120+ array( 'tjob_name IS NULL',
 121+ 'img_media_type' => 'VIDEO'),
 122+ __METHOD__,
 123+ array( 'LIMIT' => 100 ),
 124+ array(
 125+ 'transcode_job' => array(
 126+ 'LEFT JOIN',
 127+ array( 'img_name = tjob_name' )
 128+ )
 129+ )
 130+ );
 131+ $imageNames = array();
 132+ while( $row = $dbr->fetchObject( $res ) ) {
 133+ $imageNames[] = $row->img_name;
 134+ }
 135+ if( count( $imageNames ) == 0){
 136+ return false;
 137+ }
 138+
 139+ // Add the derivative set[s] to the transcode table
 140+ $dbw = & wfGetDB( DB_MASTER );
 141+ $dbw->begin();
 142+ foreach( $imageNames as $name){
 143+ foreach( $wgEnabledDerivatives as $derivativeKey ){
 144+
 145+ // Do not to add a derivative job that is > than the source asset
 146+ $fileTitle = Title::newFromText( $name, NS_FILE);
 147+
 148+ $file = wfFindFile( $fileTitle );
 149+ if( !$file ){
 150+ $this->output( "File not found: {$name} (not adding to jobQueue\n" );
 151+ continue;
 152+ }
 153+ $targetSize = OggTranscode::$derivativeSettings[ $derivativeKey ]['maxSize'];
 154+ $sourceSize = $file->getWidth();
 155+ if( $targetSize > $sourceSize ){
 156+ $this->output( "File:{$name} is too small for {$derivativeKey} ::\n" .
 157+ "target: {$targetSize} > source: {$sourceSize} \n\n" );
 158+ continue;
 159+ }
 160+ // Else $derivative size is < source size, do insert:
 161+ $dbw->insert(
 162+ 'transcode_job',
 163+ array(
 164+ 'tjob_name' => $name,
 165+ 'tjob_derivative_key' => $derivativeKey,
 166+ 'tjob_start_timestamp' => time()
 167+ ),
 168+ __METHOD__
 169+ );
 170+ }
 171+ }
 172+ $dbw->commit();
 173+ }
 174+
 175+ /**
 176+ * Process a transcode job
 177+ * @param {Object} $job Transcode job db row
 178+ * @return {Bollean}
 179+ * true if job was processed
 180+ * false if there was an error in the job
 181+ */
 182+ function processTranscodeJob( $job ){
 183+ $dbw = & wfGetDB( DB_MASTER );
 184+
 185+ // Update job state to "ASSIGNED"
 186+ $this->markJobState( $job, 'ASSIGNED');
 187+
 188+ // Get the source title from tjob_name
 189+ $fileTitle = Title::newFromText( $job->tjob_name, NS_FILE);
 190+ if( ! $fileTitle->exists() ){
 191+ $this->output( "Title not found: {$job->tjob_name}\n" );
 192+ return false;
 193+ }
 194+
 195+ // Get the file source:
 196+ $file = wfFindFile( $fileTitle );
 197+ if( !$file ){
 198+ $this->output( "File not found: {$job->tjob_name}\n" );
 199+ return false;
 200+ }
 201+
 202+ // Setup a temporary target location for encode output
 203+ $tempTarget = wfTempDir() .'/'. $fileTitle->getDbKey() . $job->tjob_derivative_key . '.ogv';
 204+
 205+ // Get encoding settings from encode key
 206+ if( !isset( OggTranscode::$derivativeSettings[ $job->tjob_derivative_key ] )){
 207+ $this->output( "Derivative key not found: {$job->tjob_name}\n" );
 208+ return false;
 209+ }
 210+ $encodeSettings = OggTranscode::$derivativeSettings[ $job->tjob_derivative_key ];
 211+
 212+ // Shell out the transcode command.
 213+ $this->output( "Starting transcode:\n" );
 214+ $result = $this->doEncode( $file->getPath(), $tempTarget, $encodeSettings );
 215+
 216+ // Check the result
 217+ if( !$result ){
 218+ $this->output( "Transcode failed: {$job->tjob_name}\n" );
 219+ return false;
 220+ }
 221+
 222+ // If result is "ok"
 223+ $this->output( "Transcode OK, moving thumb to public location\n" );
 224+ $derivativeTarget = $file->getThumbPath( $job->tjob_derivative_key ) . '.ogv';
 225+
 226+ if( !rename( $tempTarget, $derivativeTarget) ){
 227+ $this->output( "Renamed failed: {$tempTarget} to {$derivativeTarget}\n" );
 228+ return false;
 229+ }
 230+ // Return true to update the job state:
 231+ return true;
 232+ }
 233+ /**
 234+ * Mark a job as state
 235+ * @param {Object} $job Job db row object.
 236+ * @param {String} $state String to update state to can be:
 237+ * 'OK','ASSIGNED','FAILED'
 238+ */
 239+ function markJobState( $job , $state){
 240+ $dbw = & wfGetDB( DB_MASTER );
 241+ $dbw->update(
 242+ 'transcode_job',
 243+ array(
 244+ 'tjob_state' => $state
 245+ ),
 246+ array(
 247+ 'tjob_name' => $job->tjob_name,
 248+ 'tjob_derivative_key' => $job->tjob_derivative_key
 249+ )
 250+ );
 251+ }
 252+
 253+ /**
 254+ * Check the number if the instances of this script that are running
 255+ * are over the max allowed threads $this->maxThreads
 256+ *
 257+ * @return {Boolean}
 258+ * true if max Threads count has been reached
 259+ * false if less than max Threads
 260+ */
 261+ public function checkMaxThreads(){
 262+
 263+ // Get the list of processes:
 264+ $pslist = wfShellExec( "ps aux", $out);
 265+
 266+ // Return the count of php OggTranscodeCron.php found
 267+ $threadCount = preg_match_all( '/php\sOggTranscodeCron\.php/', $pslist, $matches);
 268+ if( $threadCount === false ){
 269+ print "Error in preg_match";
 270+ exit( 1 );
 271+ }
 272+ return ( $threadCount > $this->maxThreads );
 273+ }
 274+
 275+ /**
 276+ * Issues an encode command to ffmpeg2theora
 277+ *
 278+ * @param {String} $source Source file asset
 279+ * @param {String} $target Target output encode
 280+ * @param {Array} $encodeSettings Settings to encode the file with
 281+ */
 282+ function doEncode( $source, $target, $encodeSettings ){
 283+ global $wgffmpeg2theoraPath;
 284+
 285+ // Set up the base command
 286+ $cmd = wfEscapeShellArg( $wgffmpeg2theoraPath ) . ' ' . wfEscapeShellArg( $source );
 287+
 288+ // Add in the encode settings
 289+ foreach( $encodeSettings as $key => $val){
 290+ if( isset( OggTranscode::$foggMap[$key] ) ){
 291+ if( is_array( OggTranscode::$foggMap[$key] ) ){
 292+ $cmd.= ' '. implode(' ', OggTranscode::$foggMap[$key] );
 293+ }else if($val == 'true' || $val === true){
 294+ $cmd.= ' '. OggTranscode::$foggMap[$key];
 295+ }else if( $val === false){
 296+ //ignore "false" flags
 297+ }else{
 298+ //normal get/set value
 299+ $cmd.= ' '. OggTranscode::$foggMap[$key] . ' ' . wfEscapeShellArg( $val );
 300+ }
 301+ }
 302+ }
 303+ // Add the output target:
 304+ $cmd.= ' -o ' . wfEscapeShellArg ( $target );
 305+ $this->output( "Running cmd: \n\n" .$cmd . "\n\n" );
 306+ wfProfileIn( 'ffmpeg2theora_encode' );
 307+ wfShellExec( $cmd, $retval );
 308+ wfProfileOut( 'ffmpeg2theora_encode' );
 309+
 310+ if( $retval ){
 311+ return false;
 312+ }
 313+ return true;
 314+ }
 315+}
 316+
 317+$maintClass = "OggTranscodeCron";
 318+require_once( DO_MAINTENANCE );
 319+?>
\ No newline at end of file
Property changes on: trunk/extensions/OggHandler/OggTranscode/OggTranscodeCron.php
___________________________________________________________________
Name: svn:mergeinfo
1320 +
Index: trunk/extensions/OggHandler/OggTranscode/OggTranscode.sql
@@ -0,0 +1,29 @@
 2+--
 3+-- Table structure for table `transcode_job`
 4+--
 5+
 6+CREATE TABLE IF NOT EXISTS /*_*/transcode_job (
 7+
 8+ --File name key ( called image to match table name )
 9+ tjob_name varbinary(255) NOT NULL,
 10+
 11+ --Derivative key of the transcode
 12+ tjob_derivative_key varbinary(40) NOT NULL,
 13+
 14+ -- Timestamp
 15+ `tjob_start_timestamp` char(14) NOT NULL,
 16+
 17+ -- Transcoding state
 18+ tjob_state enum('OK','ASSIGNED','FAILED') default NULL
 19+
 20+) /*$wgDBTableOptions*/;
 21+
 22+--
 23+-- Index for transcode_job_name
 24+--
 25+CREATE INDEX /*i*/transcode_job_name ON /*_*/transcode_job ( tjob_name );
 26+
 27+--
 28+-- Index for tjob_state
 29+--
 30+CREATE INDEX /*i*/transcode_job_state ON /*_*/transcode_job ( tjob_state );
Property changes on: trunk/extensions/OggHandler/OggTranscode/OggTranscode.sql
___________________________________________________________________
Name: svn:mergeinfo
131 +
Index: trunk/extensions/OggHandler/ApiPlayTracking/ApiPlayTracking.sql
@@ -0,0 +1,26 @@
 2+--
 3+-- Table structure for table `play_tracking`
 4+--
 5+
 6+CREATE TABLE IF NOT EXISTS /*_*/play_tracking (
 7+
 8+ -- Unique id of play tracking event
 9+ track_id int unsigned NOT NULL PRIMARY KEY AUTO_INCREMENT
 10+
 11+ -- Filename of resource played
 12+ track_filename varchar(255) binary NOT NULL,
 13+
 14+ -- Anonymous hash of client
 15+ track_client_hash varbinary(16) NOT NULL,
 16+
 17+ -- Browser and playback system dump.
 18+ track_clientplayer tinyblob NOT NULL,
 19+
 20+ -- Rate we are tracking ( ie 10 means 1 in 10 tracked )
 21+ track_rate integer
 22+
 23+) /*$wgDBTableOptions*/;
 24+
 25+
 26+
 27+
Index: trunk/extensions/OggHandler/ApiPlayTracking/ApiPlayTracking.php
@@ -0,0 +1,79 @@
 2+<?php
 3+/**
 4+ * Extend the API for play request tracking
 5+ *
 6+ * @file
 7+ * @ingroup API
 8+ */
 9+
 10+class ApiPlayTracking extends ApiBase {
 11+
 12+ /**
 13+ * Runs when the API is called with "playtracking", takes in "filename"
 14+ * and "client" serialized data for ogg support analysis
 15+ *
 16+ * @see includes/api/ApiBase#execute()
 17+ */
 18+ public function execute() {
 19+ global $wgEnablePlayTracking;
 20+ if( ! $wgEnablePlayTracking ){
 21+ $this->dieUsageMsg( array( 'unknownerror', 'Play tracking is not enabled' ) );
 22+ }
 23+ $params = $this->extractRequestParams();
 24+ $this->validateParams( $params );
 25+
 26+ // insert into the play_tracking table
 27+ }
 28+
 29+ /**
 30+ * Required parameter check
 31+ * @param $params params extracted from the POST
 32+ */
 33+ protected function validateParams( $params ) {
 34+ $required = array( 'filename', 'client' );
 35+ foreach ( $required as $arg ) {
 36+ if ( !isset( $params[$arg] ) ) {
 37+ $this->dieUsageMsg( array( 'missingparam', $arg ) );
 38+ }
 39+ }
 40+ }
 41+
 42+ /**
 43+ * Setup the ApiTracking tables
 44+ */
 45+ public static function schema() {
 46+ global $wgExtNewTables, $wgExtNewIndexes;
 47+
 48+ $wgExtNewTables[] = array(
 49+ 'play_tracking',
 50+ dirname( __FILE__ ) . '/ApiPlayTracking.sql'
 51+ );
 52+
 53+ return true;
 54+ }
 55+
 56+ public function getParamDescription() {
 57+ return array(
 58+ 'filename' => 'title of filename played',
 59+ 'client' => 'seralized data about client playback support',
 60+ );
 61+ }
 62+
 63+ public function getDescription() {
 64+ return array(
 65+ 'Track user audio and video play requests.'
 66+ );
 67+ }
 68+
 69+ public function getAllowedParams() {
 70+ return array(
 71+ 'filename' => null,
 72+ 'client' => null,
 73+ );
 74+ }
 75+ public function getVersion() {
 76+ return __CLASS__ . ': $Id: ApiPlayTracking.php 59374 2009-11-24 01:06:56Z dale $';
 77+ }
 78+}
 79+
 80+?>
\ No newline at end of file
Index: trunk/extensions/OggHandler/OggHandler.php
@@ -7,7 +7,6 @@
88
99 $oggDir = dirname(__FILE__);
1010 $wgAutoloadClasses['OggHandler'] = "$oggDir/OggHandler_body.php";
11 -$wgAutoloadClasses['OggTranscode'] = "$oggDir/OggTranscode.php";
1211
1312 $wgMediaHandlers['application/ogg'] = 'OggHandler';
1413 if ( !in_array( 'ogg', $wgFileExtensions ) ) {
@@ -36,7 +35,8 @@
3736 // Setup a hook for iframe=true (will strip the interface and only output the player)
3837 $wgHooks['ArticleFromTitle'][] = 'OggHandler::iframeOutputHook';
3938
40 -// Add the oggTranscode schema
 39+// OggTranscode setup
 40+$wgAutoloadClasses['OggTranscode'] = "$oggDir/OggTranscode/OggTranscode.php";
4141 $wgHooks['LoadExtensionSchemaUpdates'][] = 'OggTranscode::schema';
4242
4343 $wgExtensionCredits['media'][] = array(
@@ -54,9 +54,6 @@
5555 $wgOggVideoTypes = array( 'Theora' );
5656 $wgOggAudioTypes = array( 'Vorbis', 'Speex', 'FLAC' );
5757
58 -// if wgPlayerStats collection is enabled or not
59 -$wgPlayerStatsCollection = false;
60 -
6158 // Output Video tag for player ( video tag is then rewritten to compatible player via mwEmbed )
6259 $wgVideoTagOut = false;
6360
@@ -89,6 +86,7 @@
9087 $wgEnableTemporalOggUrls = false;
9188
9289 // Enabled derivatives array
 90+// If set to false no derivatives will be used
9391 //
9492 // Only derivatives with less width than the
9593 // source asset size will be created
@@ -106,6 +104,13 @@
107105 OggTranscode::ENC_HQ_VBR
108106 );
109107
 108+// If play requests should be tracked.
 109+$wgEnablePlayTracking = false;
 110+
 111+// One out of how many requests should be tracked:
 112+$wgPlayTrackingRate = 10;
 113+
 114+
110115 // Filename or URL path to the Cortado Java player applet.
111116 //
112117 // If no path is included, the path to this extension's
@@ -122,8 +127,24 @@
123128
124129 /******************* CONFIGURATION ENDS HERE **********************/
125130
126 -// NOTE: normally configuration based code would go into extension setup
127 -// so config could follow the oggHandler include but we need add the namespace early.
 131+// NOTE: normally configuration based code would go into extension setup function
 132+// This config setups hooks and autoloaders that should happen at
 133+// initial config time
 134+
 135+// Alternatively we could have top level php files that include the
 136+// following pieces of code, but that would distribute configuration
 137+
 138+// Enable play tracking
 139+if( $wgEnablePlayTracking ){
 140+ // Add the Api Play Tracking setup
 141+ $wgAutoloadClasses['ApiPlayTracking'] = "$oggDir/ApiPlayTracking/ApiPlayTracking.php";
 142+ $wgHooks['LoadExtensionSchemaUpdates'][] = 'ApiPlayTracking::schema';
 143+
 144+ //Add the api entry point:
 145+ $wgAPIModules['playtracking'] = 'ApiPlayTracking';
 146+}
 147+
 148+// Enable timed text
128149 if( $wgEnableTimedText ){
129150 /**
130151 * Handle Adding of "timedText" NameSpace
Index: trunk/extensions/OggHandler/OggHandler_body.php
@@ -452,21 +452,30 @@
453453
454454 function setHeaders( $out ) {
455455 global $wgOggScriptVersion, $wgCortadoJarFile, $wgServer, $wgUser, $wgScriptPath,
456 - $wgPlayerStatsCollection, $wgVideoTagOut;
 456+ $wgEnablePlayTracking, $wgPlayTrackingRate, $wgVideoTagOut;
457457
458458 if( $wgVideoTagOut ){
459 - // We could add "video" tag javascript here if want. specifically:
 459+ // We could add "video" tag javascript
 460+ // If we wanted to block on mwEmbed player js, instead of loading the js onDomReady
460461
461 - // <script type="text/javascript" src="js/mwEmbed/jsScriptLoader.php?class=window.jQuery,mwEmbed,$j.ui,mw.EmbedPlayer,nativeEmbed,ctrlBuilder,mvpcfConfig,kskinConfig,$j.fn.menu,$j.cookie,$j.ui.slider,mw.TimedText&debug=true"></script>
462 - //<link rel="stylesheet" href="js/mwEmbed/skins/styles.css" type="text/css" media="screen" />
 462+ // embedPlayer classes include: $j.ui,mw.EmbedPlayer,nativeEmbed,ctrlBuilder,mvpcfConfig,kskinConfig,$j.fn.menu,$j.cookie,$j.ui.slider,mw.TimedText
463463 //<link rel="stylesheet" href="js/mwEmbed/skins/kskin/playerSkin.css" type="text/css" media="screen" />
464464
465 - // The above is loaded on-dom-ready for faster dom readyness.
466 - // but that has the disadvantage of video player interfaces not being "instantly" ready
467 - // on page load. So its a trade off.
 465+ // Loading dynamically lets us avoid unnecessary code
 466+ // ie firefox does not need "JSON.js" and IE ~maybe~ needs cortado embed etc.
468467
469 - // Loading dynamically also lets us avoid unnecessary code
470 - // ie firefox does not need "JSON.js" and IE ~maybe~ needs cortado embed etc.
 468+ if( $wgEnablePlayTracking ) {
 469+ $encPlayTracking = Xml::encodeJsVar( $wgPlayTrackingRate );
 470+ // Should replace with a standard way to send configuration to mw core js
 471+ $out->addHeadItem( 'OggHandler', <<<EOT
 472+<script type="text/javascript">
 473+mw.setConfig('playTracking', 'true');
 474+mw.setConfig('playTrackingRate', $encPlayTracking );
 475+</script>
 476+EOT
 477+);
 478+ }
 479+
471480 }else{
472481 if ( $out->hasHeadItem( 'OggHandler' ) ) {
473482 return;
@@ -491,12 +500,26 @@
492501 $encCortadoUrl = Xml::encodeJsVar( $cortadoUrl );
493502 $encExtPathUrl = Xml::encodeJsVar( $scriptPath );
494503
 504+
 505+ $playTrackingJs = '';
 506+ //Check for play tracking and output vars
 507+ if( $wgEnablePlayTracking ) {
 508+ $encPlayTracking = Xml::encodeJsVar( $wgPlayTrackingRate );
 509+ $playTrackingJs = <<<EOT
 510+wgOggPlayer.playTracking = true;
 511+wgOggPlayer.playTrackingRate = $encPlayTracking
 512+EOT
 513+;
 514+ }
 515+
 516+
495517 $out->addHeadItem( 'OggHandler', <<<EOT
496518 <script type="text/javascript" src="$scriptPath/OggPlayer.js?$wgOggScriptVersion"></script>
497519 <script type="text/javascript">
498520 wgOggPlayer.msg = $jsMsgs;
499521 wgOggPlayer.cortadoUrl = $encCortadoUrl;
500522 wgOggPlayer.extPathUrl = $encExtPathUrl;
 523+$playTrackingJs;
501524 </script>
502525 <style type="text/css">
503526 .ogg-player-options {

Status & tagging log