r53666 MediaWiki - Code Review archive

Repository:MediaWiki
Revision:r53665‎ | r53666 | r53667 >
Date:02:09, 23 July 2009
Author:dale
Status:deferred
Tags:
Comment:
* Sequencer render updates
** created class/file mvFirefoggRender.js
Modified paths:
  • /trunk/phase3/js2/mwEmbed/example_usage/SequencerPlayer_Render.html (added) (history)
  • /trunk/phase3/js2/mwEmbed/example_usage/SequencerPlayer_Seeking.html (deleted) (history)
  • /trunk/phase3/js2/mwEmbed/libAddMedia/mvFirefogg.js (modified) (history)
  • /trunk/phase3/js2/mwEmbed/libEmbedVideo/embedVideo.js (modified) (history)
  • /trunk/phase3/js2/mwEmbed/libEmbedVideo/nativeEmbed.js (modified) (history)
  • /trunk/phase3/js2/mwEmbed/libSequencer/mvFirefoggRender.js (added) (history)
  • /trunk/phase3/js2/mwEmbed/libSequencer/mvPlayList.js (modified) (history)
  • /trunk/phase3/js2/mwEmbed/mv_embed.js (modified) (history)
  • /trunk/phase3/js2/mwEmbed/php/jsAutoloadLocalClasses.php (modified) (history)

Diff [purge]

Index: trunk/phase3/js2/mwEmbed/example_usage/SequencerPlayer_Seeking.html
@@ -1,78 +0,0 @@
2 -<!doctype html>
3 -<html>
4 -<head>
5 - <title>mv_embed Seeking Example</title>
6 - <script type="text/javascript" src="../mv_embed.js?debug=true"></script>
7 - <style>
8 - #render_box {
9 - position:absolute;
10 - width:400px;
11 - height:300px;
12 - }
13 - #frame_overlay {
14 - position:absolute;
15 - width:400px;
16 - height:300px;
17 - top: 28px;
18 - left: 9px;
19 - }
20 -
21 - </style>
22 - <script>
23 -var pos = 0;
24 -var duration = 2;
25 -var step = 0.04;
26 -var render = false;
27 -
28 -function renderNext() {
29 - $j('#pos').val(pos);
30 - document.getElementById('render_box').setCurrentTime(pos, function(currentTime) {
31 - return function() {
32 - //ogg.addFrame('frame_overlay');
33 - pos += step;
34 - if(render && pos <= duration)
35 - renderNext();
36 - };
37 - }(pos));
38 -}
39 -
40 -function startRender() {
41 - //ogg = new Firefogg();
42 - //ogg.initRender('{"videoQuality": 10, "framerate": 25, "width": 400, "height": 300}', 'sample_smil.ogv');
43 - $j("#buttonStart").attr("disabled", true);
44 - if(!render) {
45 - //document.getElementById('render_box').play();
46 - //document.getElementById('render_box').pause();
47 - setTimeout(function() {
48 - //duration = document.getElementById('render_box').getDuration();
49 - render = true;
50 - pos = 0;
51 - renderNext();
52 - }, 1000);
53 - }
54 -}
55 -function stopRender() {
56 - render = false;
57 - $j("#buttonStart").attr("disabled", false);
58 - $j("#buttonSop").attr("disabled", true);
59 -}
60 -function seek() {
61 - var seekTo = $j('#pos').val();
62 - document.getElementById('render_box').setCurrentTime(seekTo, function() { js_log('seeked'); });
63 -}
64 - </script>
65 -</head>
66 -<body>
67 -<playlist id="render_box" src="media/sample_smil.xml" controls="false"></playlist>
68 -<div id="frame_overlay"></div>
69 -
70 -<div id="info" style="position: absolute; top:360px">
71 - <button onclick="startRender()" id="buttonStart">Start</button>
72 - <button onclick="stopRender()" id="buttonStart">Stop</button>
73 - position: <input type="text" id="pos" value="6.6" />
74 - <button onclick="seek()">seek</button>
75 - <span id="status"></span><br>
76 -</div>
77 -</body>
78 -</html>
79 -
Index: trunk/phase3/js2/mwEmbed/example_usage/SequencerPlayer_Render.html
@@ -0,0 +1,64 @@
 2+<!doctype html>
 3+<html>
 4+<head>
 5+ <title>mv_embed Seeking Example</title>
 6+ <script type="text/javascript" src="../mv_embed.js?debug=true"></script>
 7+ <style>
 8+ #render_box {
 9+ position:absolute;
 10+ width:400px;
 11+ height:300px;
 12+ }
 13+
 14+ </style>
 15+ <script>
 16+mwAddOnloadHook(function(){
 17+
 18+ $j('#render_player').firefoggRender({
 19+ 'render_options':{
 20+ "framerate" : 30
 21+ },
 22+ 'target_startRender':'#buttonStart',
 23+ 'target_stopRender': '#buttonStop',
 24+ 'target_timeStatus': '#time_status'
 25+
 26+ },function( foggRender ){
 27+ $j('#loading_text').hide();
 28+ if( foggRender.enabled ){
 29+ $j('#info_control').show();
 30+ }else{
 31+ $j('#info_control').html(
 32+ foggRender.myFogg.getTargetHtml('target_please_install')
 33+ );
 34+ if(!($j.browser.mozilla && $j.browser.version >= '1.9.1')) {
 35+ $j('#info_control').html(
 36+ foggRender.myFogg.getTargetHtml('target_use_latest_fox')
 37+ );
 38+ }
 39+ }
 40+ });
 41+
 42+});
 43+ </script>
 44+</head>
 45+<body>
 46+ <!--
 47+<playlist id="render_player" src="media/sample_smil.xml" controls="false" width="400" height="300"></playlist>
 48+-->
 49+ <video id="render_player" src="media/sample_fish.ogg" style="width:400px;height:300px" controls="false"
 50+ poster="media/sample_fish.jpg"></video>
 51+
 52+
 53+<span id="loading_text" style="position:absolute; top:320px;">
 54+loading render system <blink>...</blink>
 55+</span>
 56+<div id="info_control" style="display:none;">
 57+ <button id="buttonStart">Do Render</button>
 58+ <button id="buttonStop">Stop</button>
 59+ Current Time: <input type="text" id="time_status" value="0.0" />
 60+ <span id="status"></span><br>
 61+</div>
 62+
 63+</body>
 64+</html>
 65+
Property changes on: trunk/phase3/js2/mwEmbed/example_usage/SequencerPlayer_Render.html
___________________________________________________________________
Name: svn:mergeinfo
166 + /branches/REL1_15/phase3/js2/mwEmbed/example_usage/SequencerPlayer_Seeking.html:51646
Index: trunk/phase3/js2/mwEmbed/libAddMedia/mvFirefogg.js
@@ -23,12 +23,20 @@
2424 };
2525
2626 var default_firefogg_options = {
 27+ //what to do when finished uploading
2728 'upload_done_action':'redirect',
 29+ //if firefoog is enabled
2830 'fogg_enabled':false,
 31+ //the api url to upload to
2932 'api_url':null,
 33+ //the passthrough flag (enables un-modified uploads)
3034 'passthrough': false,
 35+ //if we will be showing the encoder interface
3136 'encoder_interface': false,
 37+ //if we want to limit the library functionality to "only firefoog" (no upload or progress bars)
 38+ 'only_fogg': false,
3239
 40+
3341 //callbacks:
3442 'new_source_cb': false, //called on source name update passes along source name
3543
@@ -63,7 +71,7 @@
6472 }
6573 mvFirefogg.prototype = { //extends mvBaseUploadInterface
6674
67 - min_firefogg_version : '0.9.8',
 75+ min_firefogg_version : '0.9.9',
6876 fogg_enabled : false, //if firefogg is enabled or not.
6977 encoder_settings:{ //@@todo allow server to set this
7078 'maxSize': 400,
@@ -92,21 +100,23 @@
93101 this[i] = default_firefogg_options[i];
94102 }
95103 }
96 -
97 - var myBUI = new mvBaseUploadInterface( iObj );
98 - //standard extends code:
99 - for(var i in myBUI){
100 - if(this[i]){
101 - this['pe_'+ i] = myBUI[i];
102 - }else{
103 - this[i] = myBUI[i];
 104+ //check if we want to limit the usage:
 105+ if(!this.only_fogg){
 106+ var myBUI = new mvBaseUploadInterface( iObj );
 107+
 108+ //standard extends code:
 109+ for(var i in myBUI){
 110+ if(this[i]){
 111+ this['pe_'+ i] = myBUI[i];
 112+ }else{
 113+ this[i] = myBUI[i];
 114+ }
104115 }
105116 }
 117+
106118 if(!this.selector){
107 - js_log('Error: firefogg: missing selector ');
108 - }
109 - //if detect
110 -
 119+ js_log('firefogg: missing selector ');
 120+ }
111121 },
112122 doRewrite:function( callback ){
113123 var _this = this;
@@ -222,10 +232,10 @@
223233 });
224234 },
225235 firefoggCheck:function(){
226 - if(typeof(Firefogg) != 'undefined' && Firefogg().version >= '0.9.9'){
227 - this.fogg = new Firefogg();
228 - this.fogg_enabled = true;
229 - return true;
 236+ if(typeof(Firefogg) != 'undefined' && Firefogg().version >= this.min_firefogg_version){
 237+ this.fogg = new Firefogg();
 238+ this.fogg_enabled = true;
 239+ return true;
230240 }else{
231241 return false;
232242 }
Index: trunk/phase3/js2/mwEmbed/libSequencer/mvPlayList.js
@@ -519,10 +519,12 @@
520520 $j('#mv_time_'+this.id).html( value );
521521 },
522522 setSliderValue:function(value){
523 - if(this.cur_clip.embed){
524 - //js_log('calling original embed slider with val: '+value);
525 - this.cur_clip.embed.pe_setSliderValue( value );
526 - //call seq playline update here
 523+ if( this.controls ){
 524+ if(this.cur_clip.embed){
 525+ //js_log('calling original embed slider with val: '+value);
 526+ this.cur_clip.embed.pe_setSliderValue( value );
 527+ //call seq playline update here
 528+ }
527529 }
528530 },
529531 getPlayHeadPos: function(prec_done){
@@ -718,7 +720,13 @@
719721 }
720722 //start up the playlist monitor
721723 this.monitor();
722 - },
 724+ },
 725+ /*
 726+ * the load function loads all the clips in order
 727+ */
 728+ load:function(){
 729+ //do nothing right now)
 730+ },
723731 toggleMute:function(){
724732 this.cur_clip.embed.toggleMute();
725733 },
@@ -828,10 +836,12 @@
829837 if (_this.cur_clip.id != clip.id) {
830838 _this.updateCurrentClip( clip );
831839 }
832 - _this.cur_clip.embed.setCurrentTime(clipTime, callback);
 840+ _this.cur_clip.embed.setCurrentTime(clipTime, function(){
 841+ if(callback)
 842+ callback();
 843+ });
833844 _this.currentTime = pos;
834 - _this.doSmilActions();
835 - return '';
 845+ _this.doSmilActions();
836846 }
837847 currentOffset += nextTime;
838848 }
Index: trunk/phase3/js2/mwEmbed/libSequencer/mvFirefoggRender.js
@@ -0,0 +1,146 @@
 2+/*
 3+ * hanndles driving the firefogg render system
 4+*/
 5+
 6+var mvFirefoggRender = function( iObj ) {
 7+ return this.init( iObj );
 8+};
 9+var default_render_options = {
 10+ "videoQuality" : 10,
 11+ "framerate" : 30,
 12+ "width" : 400,
 13+ "height" : 300
 14+}
 15+var default_FirefoggRender_options = {
 16+ start_time:0,
 17+ //if we should save to disk (if false setup upload stuff below)
 18+ save_to_disk:true
 19+}
 20+//set up the mvPlaylist object
 21+mvFirefoggRender.prototype = {
 22+ //default empty render options:
 23+ renderOptions: {},
 24+ continue_rendering:false,
 25+ init:function( iObj ){
 26+ var _this = this;
 27+
 28+ //grab the mvFirefogg object to do basic tests
 29+ this.myFogg = new mvFirefogg({
 30+ 'only_fogg':true
 31+ });
 32+
 33+ //check for firefogg:
 34+ if( this.myFogg.firefoggCheck() ){
 35+ this.enabled = true;
 36+ }else{
 37+ this.enabled = false;
 38+ return this;
 39+ }
 40+
 41+ //set up local fogg pointer:
 42+ this.fogg = this.myFogg.fogg;
 43+
 44+ //setup player instance
 45+ this.player = $j(iObj.player_target).get(0);
 46+ this.player_target = iObj.player_target;
 47+
 48+ //setup the render options (with defaults)
 49+ for(var i in default_render_options){
 50+ if( iObj['render_options'][i] ){
 51+ this.renderOptions[ i ] = iObj['render_options'][i];
 52+ }else{
 53+ this.renderOptions[ i ] = default_render_options[i];
 54+ }
 55+ }
 56+ //setup the application options (with defaults)
 57+ for(var i in default_FirefoggRender_options ){
 58+ if( iObj[ i ] ){
 59+ this[ i ] = iObj[ i ];
 60+ }else{
 61+ this[ i ] = default_FirefoggRender_options[i];
 62+ }
 63+ }
 64+ //set up targets and local vars
 65+
 66+ if( iObj.target_startRender ){
 67+ $j(iObj.target_startRender).click(function(){
 68+ js_log("Start render");
 69+ _this.startRender();
 70+ })
 71+ this.target_startRender = iObj.target_startRender;
 72+ }
 73+ if( iObj.target_stopRender ){
 74+ $j(iObj.target_stopRender).click(function(){
 75+ _this.stopRender();
 76+ })
 77+ this.target_stopRender = iObj.target_stopRender;
 78+ }
 79+ if( iObj.target_timeStatus ){
 80+ this.target_timeStatus = iObj.target_timeStatus;
 81+ }
 82+ },
 83+ startRender:function(){
 84+ var _this = this;
 85+ var t = this.start_time;
 86+ //get the interval from renderOptions framerate
 87+ var interval = 1 / this.renderOptions.framerate
 88+
 89+ //issue a load request on the player:
 90+ this.player.load();
 91+
 92+ //init the Render
 93+ this.fogg.initRender( JSON.stringify( _this.renderOptions ), 'foggRender' );
 94+
 95+ //add audio if we had any:
 96+
 97+ //request a target (should support rendering to temp location too)
 98+ this.fogg.saveVideoAs();
 99+
 100+ //set the continue rendering flag to true:
 101+ this.continue_rendering = true;
 102+
 103+ //internal function to hanndle updates:
 104+ var doNextFrame = function(){
 105+ $j(_this.target_timeStatus).val( " on " + (Math.round(t*10)/10) + " of "+
 106+ (Math.round( _this.player.getDuration() * 10) / 10 ) );
 107+ _this.player.setCurrentTime(t, function(){
 108+ _this.fogg.addFrame( $j(_this.player_target).attr('id') );
 109+ t += interval;
 110+ if(t >= _this.player.getDuration() ){
 111+ _this.doFinalRender();
 112+ }else{
 113+ if(_this.continue_rendering){
 114+ doNextFrame();
 115+ }else{
 116+ //else quit:
 117+ _this.doFinalRender();
 118+ }
 119+ }
 120+ });
 121+ }
 122+ doNextFrame();
 123+ },
 124+ stopRender:function(){
 125+ this.continue_rendering=false;
 126+ },
 127+ doFinalRender:function(){
 128+ $j(this.target_timeStatus).val("doing final render");
 129+ this.fogg.render();
 130+ this.updateStatus();
 131+ },
 132+ updateStatus:function(){
 133+ var _this = this;
 134+ var doUpdateStatus = function(){
 135+ var rstatus = _this.fogg.renderstatus()
 136+ $j(_this.target_timeStatus).val(rstatus);
 137+ if(rstatus != 'done' && rstatus != 'rendering failed') {
 138+ setTimeout(doUpdateStatus, 100);
 139+ } else {
 140+ $j(_this.target_startRender).attr("disabled", false);
 141+ }
 142+ }
 143+ doUpdateStatus();
 144+ }
 145+
 146+
 147+}
\ No newline at end of file
Index: trunk/phase3/js2/mwEmbed/php/jsAutoloadLocalClasses.php
@@ -84,6 +84,7 @@
8585 $wgJSAutoloadLocalClasses['mvPlayList'] = $wgMwEmbedDirectory . 'libSequencer/mvPlayList.js';
8686 $wgJSAutoloadLocalClasses['mvSequencer'] = $wgMwEmbedDirectory . 'libSequencer/mvSequencer.js';
8787 $wgJSAutoloadLocalClasses['mvSequencer'] = $wgMwEmbedDirectory . 'libSequencer/mvSequencer.js';
 88+$wgJSAutoloadLocalClasses['mvFirefoggRender'] = $wgMwEmbedDirectory . 'libSequencer/mvFirefoggRender.js';
8889
8990 // libTimedText:
9091 $wgJSAutoloadLocalClasses['mvTimedEffectsEdit'] = $wgMwEmbedDirectory . 'libTimedText/mvTimedEffectsEdit.js';
\ No newline at end of file
Index: trunk/phase3/js2/mwEmbed/mv_embed.js
@@ -225,6 +225,7 @@
226226 lcPaths( 'libSequencer/', [
227227 'mvPlayList',
228228 'mvSequencer',
 229+ 'mvFirefoggRender',
229230 'mvTimedEffectsEdit'
230231 ])
231232 //libTimedText:
@@ -894,6 +895,29 @@
895896 }
896897 });
897898 }
 899+ //takes a input player as the selector and exposes basic rendering controls
 900+ $.fn.firefoggRender = function( iObj, callback ){
 901+ //check if we already have render loaded then just pass on updates/actions
 902+ var sElm = $j(this.selector).get(0);
 903+ if(sElm['fogg_render']){
 904+ if(sElm['fogg_render']=='loading'){
 905+ js_log("Error: called firefoggRender while loading");
 906+ return false;
 907+ }
 908+ //call or update the property:
 909+ }
 910+ sElm['fogg_render']='loading';
 911+ //add the selector:
 912+ iObj['player_target'] = this.selector;
 913+ mvJsLoader.doLoad([
 914+ 'mvFirefogg',
 915+ 'mvFirefoggRender'
 916+ ],function(){
 917+ sElm['fogg_render']= new mvFirefoggRender( iObj );
 918+ if( callback && typeof callback == 'function' )
 919+ callback( sElm['fogg_render'] );
 920+ });
 921+ }
898922
899923 $.fn.baseUploadInterface = function(iObj){
900924 mvJsLoader.doLoad([
@@ -969,7 +993,7 @@
970994 */
971995 function seconds2npt(sec, show_ms){
972996 if( isNaN( sec ) ){
973 - js_log("warning: trying to get npt time on NaN:" + sec);
 997+ //js_log("warning: trying to get npt time on NaN:" + sec);
974998 return '0:0:0';
975999 }
9761000 var hours = Math.floor(sec/ 3600);
Index: trunk/phase3/js2/mwEmbed/libEmbedVideo/embedVideo.js
@@ -454,7 +454,7 @@
455455 function(){
456456 $j('#vol_container_' + embedObj.id).addClass('vol_container_top');
457457 //set to "below" if playing and embedType != native
458 - if(embedObj.isPlaying() && !embedObj.supports['overlays']){
 458+ if(embedObj && embedObj.isPlaying() && !embedObj.supports['overlays']){
459459 $j('#vol_container_' + embedObj.id).removeClass('vol_container_top').addClass('vol_container_below');
460460 }
461461
@@ -1364,7 +1364,14 @@
13651365 }
13661366 //do play in 100ms (give things time to clear)
13671367 setTimeout('$j(\'#' + this.id + '\').get(0).play()',100);
1368 - },
 1368+ },
 1369+ /*
 1370+ * seeks to the requested time and issues a callback when ready
 1371+ * (should be overwitten by client that supports frame serving)
 1372+ */
 1373+ setCurrentTime:function( time, callback){
 1374+ js_log('error: base embed setCurrentTime can not frame serve (overide via plugin)');
 1375+ },
13691376 addPresTimeOffset:function(){
13701377 //add in the offset:
13711378 if(this.seek_time_sec && this.seek_time_sec!=0){
@@ -1808,7 +1815,7 @@
18091816 '<img width="'+this.playerPixelWidth()+'" height="'+this.playerPixelHeight()+'" style="position:relative;width:'+this.playerPixelWidth()+';height:'+this.playerPixelHeight()+'"' +
18101817 ' id="img_thumb_'+this.id+'" src="' + this.thumbnail + '">';
18111818
1812 - if(this.play_button==true)
 1819+ if(this.play_button == true && this.controls == true)
18131820 thumb_html+=this.getPlayButton();
18141821
18151822 thumb_html+='</div>';
@@ -2370,11 +2377,12 @@
23712378 //do head request if on the same domain
23722379 return this.media_element.selected_source.URLTimeEncoding;
23732380 },
2374 - setSliderValue: function(perc, hide_progress){
2375 - var this_id = (this.pc)?this.pc.pp.id:this.id;
2376 - var val = parseInt( perc*1000 );
2377 - $j('#mv_play_head_'+this_id).slider('value', val);
2378 -
 2381+ setSliderValue: function(perc, hide_progress){
 2382+ if(this.controls){
 2383+ var this_id = (this.pc)?this.pc.pp.id:this.id;
 2384+ var val = parseInt( perc*1000 );
 2385+ $j('#mv_play_head_'+this_id).slider('value', val);
 2386+ }
23792387 //js_log('set#mv_seeker_slider_'+this_id + ' perc in: ' + perc + ' * ' + $j('#mv_seeker_'+this_id).width() + ' = set to: '+ val + ' - '+ Math.round(this.mv_seeker_width*perc) );
23802388 //js_log('op:' + offset_perc + ' *('+perc+' * ' + $j('#slider_'+id).width() + ')');
23812389 },
@@ -2746,7 +2754,7 @@
27472755 if (dummyvid.canPlayType && dummyvid.canPlayType("video/ogg;codecs=\"theora,vorbis\"") == "probably")
27482756 {
27492757 this.players.addPlayer( videoElementPlayer );
2750 - } else if(this.supportedMimeType('video/ogg')) {
 2758+ } else if(this.supportedMimeType( 'video/ogg' )) {
27512759 /* older versions of safari do not support canPlayType,
27522760 but xiph qt registers mimetype via quicktime plugin */
27532761 this.players.addPlayer( videoElementPlayer );
Index: trunk/phase3/js2/mwEmbed/libEmbedVideo/nativeEmbed.js
@@ -120,21 +120,26 @@
121121 setCurrentTime: function(pos, callback){
122122 var _this = this;
123123 this.getVID();
124 - if(!this.vid) {
125 - js_log('native:setCurrentTime: load video');
 124+ if(!this.vid) {
126125 this.load();
127126 var loaded = function(event) {
128127 js_log('native:setCurrentTime (after load): ' + pos + ' : dur: ' + this.getDuration());
129128 _this.vid.currentTime = pos;
130 - var once = function(event) { callback(); _this.vid.removeEventListener('seeked', once, false) };
 129+ var once = function(event) {
 130+ callback();
 131+ _this.vid.removeEventListener('seeked', once, false)
 132+ };
131133 _this.vid.addEventListener('seeked', once, false);
132134 _this.removeEventListener('loadedmetadata', loaded, false);
133135 };
134136 _this.addEventListener('loadedmetadata', loaded, false);
135137 } else {
136 - js_log('native:setCurrentTime: ' + pos + ' : ' + this.supportsURLTimeEncoding() + ' dur: ' + this.getDuration() + ' sts:' + this.seek_time_sec );
 138+ //js_log('native:setCurrentTime: ' + pos + ' : ' + this.supportsURLTimeEncoding() + ' dur: ' + this.getDuration() + ' sts:' + this.seek_time_sec );
137139 _this.vid.currentTime = pos;
138 - var once = function(event) { callback(); _this.vid.removeEventListener('seeked', once, false) };
 140+ var once = function(event) {
 141+ callback();
 142+ _this.vid.removeEventListener('seeked', once, false)
 143+ };
139144 _this.vid.addEventListener('seeked', once, false);
140145 }
141146 },
@@ -169,7 +174,7 @@
170175 * native callbacks for the video tag:
171176 */
172177 oncanplaythrough : function(){
173 - js_log('f:oncanplaythrough');
 178+ //js_log('f:oncanplaythrough');
174179 this.getVID();
175180 if( ! this.paused )
176181 this.vid.play();
@@ -238,6 +243,10 @@
239244 if(this.vid)
240245 return this.vid.volume;
241246 },
 247+ getNativeDuration:function(){
 248+ if(this.vid)
 249+ return this.vid.duration;
 250+ },
242251 load:function(){
243252 this.getVID();
244253 if( !this.vid ){

Status & tagging log