Bug 20489 Configure illegal file characters https://bugzilla.wikimedia.org/show_bug...
[mediawiki.git] / js2 / mwEmbed / libEmbedVideo / nativeEmbed.js
blobba0a5ddb65bd5edf78a2ac0f72860387887bb685
1 //native embed library:
2 var nativeEmbed = {
3         instanceOf:'nativeEmbed',
4         canPlayThrough:false,
5         grab_try_count:0,
6         onlyLoadFlag:false,     
7         urlAppend:'',
8         supports: {
9                 'play_head':true, 
10                 'pause':true,            
11                 'fullscreen':false, 
12                 'time_display':true, 
13                 'volume_control':true,
14                 
15                 'overlays':true,
16                 'playlist_swap_loader':true //if the object supports playlist functions         
17    },
18         getEmbedHTML : function (){                                     
19                 var embed_code =  this.getEmbedObj();
20                 js_log("embed code: " + embed_code)                             
21                 setTimeout('$j(\'#' + this.id + '\').get(0).postEmbedJS()', 150);
22                 return this.wrapEmebedContainer( embed_code);           
23         },
24         getEmbedObj:function(){
25                 //we want to let mv_embed handle the controls so notice the absence of control attribute
26                 // controls=false results in controls being displayed: 
27                 //http://lists.whatwg.org/pipermail/whatwg-whatwg.org/2008-August/016159.html           
28                 js_log("native play url:" + this.getSrc() + ' start_offset: '+ this.start_ntp + ' end: ' + this.end_ntp);
29                 var eb = '<video ' +
30                                         'id="' + this.pid + '" ' +
31                                         'style="width:' + this.width+'px;height:' + this.height + 'px;" ' +
32                                         'width="' + this.width + '" height="'+this.height+'" '+
33                                            'src="' + this.getSrc() + '" ';
34                                            
35                 /*if(!this.onlyLoadFlag)
36                         eb+='autoplay="true" ';*/
37                         
38                 //continue with the other attr:                                         
39                 eb+=            'oncanplaythrough="$j(\'#'+this.id+'\').get(0).oncanplaythrough();return false;" ' +
40                                            'onloadedmetadata="$j(\'#'+this.id+'\').get(0).onloadedmetadata();return false;" ' + 
41                                            'loadedmetadata="$j(\'#'+this.id+'\').get(0).onloadedmetadata();return false;" ' +
42                                            'onprogress="$j(\'#'+this.id+'\').get(0).onprogress( event );return false;" '+
43                                            'onended="$j(\'#'+this.id+'\').get(0).onended();return false;" >' +
44                         '</video>';
45                 return eb;
46         },
47         //@@todo : loading progress     
48         postEmbedJS:function(){
49                 var _this = this;               
50                 js_log("f:native:postEmbedJS:");                
51                 this.getVID();
52                 var doActualPlay= function(){
53                         js_log("doActualPlay ");
54                         _this.vid.play();
55                 }
56                 if(typeof this.vid != 'undefined'){                     
57                         //always load the media:
58                         if( this.onlyLoadFlag ){ 
59                                 this.vid.load();
60                         }else{  
61                                 this.vid.load();
62                                 setTimeout(doActualPlay, 500);                                                          
63                         }                                                       
64                         setTimeout('$j(\'#'+this.id+'\').get(0).monitor()',100);                
65                 }else{
66                         js_log('could not grab vid obj trying again:' + typeof this.vid);
67                         this.grab_try_count++;
68                         if(     this.grab_count == 10 ){
69                                 js_log(' could not get vid object after 10 tries re-run: getEmbedObj()' ) ;                                             
70                         }else{
71                                 setTimeout('$j(\'#'+this.id+'\').get(0).postEmbedJS()',100);
72                         }                       
73                 }
74         },      
75         doSeek:function(perc){                          
76                 //js_log('native:seek:p: ' + perc+ ' : '  + this.supportsURLTimeEncoding() + ' dur: ' + this.getDuration() + ' sts:' + this.seek_time_sec );            
77                 //@@todo check if the clip is loaded here (if so we can do a local seek)
78                 if( this.supportsURLTimeEncoding() || !this.vid){                       
79                         //make sure we could not do a local seek instead:
80                         if( perc < this.bufferedPercent && this.vid.duration && !this.didSeekJump ){
81                                 js_log("do local seek " + perc + ' is already buffered < ' + this.bufferedPercent);
82                                 this.doNativeSeek(perc);
83                         }else{
84                                 this.parent_doSeek(perc);
85                         }                       
86                 }else if(this.vid && this.vid.duration ){          
87                         //(could also check bufferedPercent > perc seek (and issue oggz_chop request or not) 
88                         this.doNativeSeek( perc );      
89                 }else{
90                         this.doPlayThenSeek( perc )
91                 }                                 
92         },      
93         doNativeSeek:function(perc){    
94                 this.seek_time_sec=0;                    
95                 this.vid.currentTime = perc * this.vid.duration;                
96                 this.parent_monitor();  
97         },
98         doPlayThenSeek:function(perc){
99                 js_log('native::doPlayThenSeek::');
100                 var _this = this;
101                 this.play();
102                 var rfsCount = 0;
103                 var readyForSeek = function(){
104                         _this.getVID();         
105                         //if we have duration then we are ready to do the seek
106                         if(this.vid && this.vid.duration){
107                                 _this.doSeek(perc);
108                         }else{                  
109                                 //try to get player for 10 seconds: 
110                                 if( rfsCount < 200 ){
111                                         setTimeout(readyForSeek, 50);
112                                         rfsCount++;
113                                 }else{
114                                         js_log('error:doPlayThenSeek failed');
115                                 }
116                         }
117                 }
118                 readyForSeek();
119         },
120         setCurrentTime: function(pos, callback){
121                 var _this = this;
122                 this.getVID();
123                 if(!this.vid) {                 
124                         this.load();
125                         var loaded = function(event) {
126                                 js_log('native:setCurrentTime (after load): ' + pos + ' :  dur: ' + this.getDuration());
127                                 _this.vid.currentTime = pos;
128                                 var once = function(event) { 
129                                         callback();
130                                         _this.vid.removeEventListener('seeked', once, false) 
131                                 };
132                                 _this.vid.addEventListener('seeked', once, false);
133                                 _this.removeEventListener('loadedmetadata', loaded, false);
134                         };
135                         _this.addEventListener('loadedmetadata', loaded, false);
136                 } else {
137                         //js_log('native:setCurrentTime: ' + pos + ' : '  + this.supportsURLTimeEncoding() + ' dur: ' + this.getDuration() + ' sts:' + this.seek_time_sec );
138                         _this.vid.currentTime = pos;
139                         var once = function(event) { 
140                                 callback(); 
141                                 _this.vid.removeEventListener('seeked', once, false) 
142                         };
143                         _this.vid.addEventListener('seeked', once, false);
144                 }
145         },
146         monitor : function(){
147                 this.getVID(); //make shure we have .vid obj
148                 if(!this.vid){
149                         js_log('could not find video embed: '+this.id + ' stop monitor');
150                         this.stopMonitor();                     
151                         return false;
152                 }               
153                 //don't update status if we are not the current clip (playlist leekage?) .. should move to playlist overwite of monitor? 
154                 if(this.pc){
155                         if(this.pc.pp.cur_clip.id != this.pc.id)
156                                 return true;
157                 }                                                               
158                                 
159                 //update currentTime                            
160                 this.currentTime = this.vid.currentTime;                
161                 this.addPresTimeOffset();
162                                 
163                 //js_log('currentTime:' + this.currentTime);
164                 //js_log('this.currentTime: ' + this.currentTime );
165                 //once currentTime is updated call parent_monitor
166                 this.parent_monitor();
167         },      
168         getSrc:function(){
169                 var src = this.parent_getSrc();
170                 if(  this.urlAppend != '')
171                         return src + ( (src.indexOf('?')==-1)?'?':'&') + this.urlAppend;
172                 return src;
173         },
174         /*
175          * native callbacks for the video tag: 
176          */
177         oncanplaythrough : function(){          
178                 //js_log('f:oncanplaythrough');
179                 this.getVID();
180                 if( ! this.paused )
181                         this.vid.play();
182         },
183         onloadedmetadata: function(){
184                 this.getVID();
185                 js_log('f:onloadedmetadata metadata ready (update duration)');  
186                 //update duration if not set (for now trust the getDuration more than this.vid.duration         
187                 if( this.getDuration()==0  &&  !isNaN( this.vid.duration )){
188                         js_log('updaed duration via native video duration: '+ this.vid.duration)
189                         this.duration = this.vid.duration;
190                 }
191         },
192         onprogress: function(e){                
193                 this.bufferedPercent =   e.loaded / e.total;
194                 //js_log("onprogress:" +e.loaded + ' / ' +  (e.total) + ' = ' + this.bufferedPercent);
195         },
196         onended:function(){       
197                 var _this = this         
198                 this.getVID();   
199                 js_log('native:onended:' + this.vid.currentTime + ' real dur:' +  this.getDuration() );
200                 //if we just started (under 1 second played) & duration is much longer.. don't run onClipDone just yet . (bug in firefox native sending onended event early) 
201                 if(this.vid.currentTime  < 1 && this.getDuration() > 1 && this.grab_try_count < 5){                     
202                         js_log('native on ended called with time:' + this.vid.currentTime + ' of total real dur: ' +  this.getDuration() + ' attempting to reload src...');
203                         var doRetry = function(){
204                                 _this.urlAppend = 'retry_src=' + _this.grab_try_count; 
205                                 _this.doEmbedHTML();
206                                 _this.grab_try_count++;
207                         }
208                         setTimeout(doRetry, 100);                       
209                 }else{
210                         this.onClipDone();
211                 }
212         },      
213         pause : function(){             
214                 this.getVID();
215                 this.parent_pause(); //update interface         
216                 if(this.vid){                   
217                         this.vid.pause();
218                 }
219                 //stop updates: 
220                 this.stopMonitor();
221         },
222         play:function(){
223                 this.getVID();
224                 this.parent_play(); //update interface
225                 if( this.vid ){
226                         this.vid.play();
227                         //re-start the monitor: 
228                         this.monitor();
229                 }
230         },
231         toggleMute:function(){
232                 this.parent_toggleMute();
233                 this.getVID();
234                 if(this.vid)
235                         this.vid.muted = this.muted;
236         },      
237         updateVolumen:function(perc){
238                 this.getVID();          
239                 if(this.vid)
240                         this.vid.volume = perc;                     
241         },              
242     getVolumen:function(){
243                 this.getVID();          
244                 if(this.vid)
245                         return this.vid.volume;                    
246         },      
247         getNativeDuration:function(){
248                 if(this.vid)
249                         return this.vid.duration;
250         },
251         load:function(){
252                 this.getVID();
253                 if( !this.vid ){
254                         //no vid loaded
255                         js_log('native::load() ... doEmbed');
256                         this.onlyLoadFlag = true;
257                         this.doEmbedHTML();
258                 }else{
259                         //won't happen offten
260                         this.vid.load();
261                 }
262         },
263         // get the embed vlc object 
264         getVID : function (){
265                 this.vid = $j('#'+this.pid).get(0);               
266         },  
267         /* 
268          * playlist driver        
269          * mannages native playlist calls                 
270          */