here it is ... the upload-api, script-server, js2 (javascript phase2) branch merge...
[lhc/web/wiklou.git] / js2 / mwEmbed / libEmbedVideo / nativeEmbed.js
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 js_log('native:setCurrentTime: load video');
125 this.load();
126 var loaded = function(event) {
127 js_log('native:setCurrentTime (after load): ' + pos + ' : dur: ' + this.getDuration());
128 _this.vid.currentTime = pos;
129 var once = function(event) { callback(); _this.vid.removeEventListener('seeked', once, false) };
130 _this.vid.addEventListener('seeked', once, false);
131 _this.removeEventListener('loadedmetadata', loaded, false);
132 };
133 _this.addEventListener('loadedmetadata', loaded, false);
134 } else {
135 js_log('native:setCurrentTime: ' + pos + ' : ' + this.supportsURLTimeEncoding() + ' dur: ' + this.getDuration() + ' sts:' + this.seek_time_sec );
136 _this.vid.currentTime = pos;
137 var once = function(event) { callback(); _this.vid.removeEventListener('seeked', once, false) };
138 _this.vid.addEventListener('seeked', once, false);
139 }
140 },
141 monitor : function(){
142 this.getVID(); //make shure we have .vid obj
143 if(!this.vid){
144 js_log('could not find video embed: '+this.id + ' stop monitor');
145 this.stopMonitor();
146 return false;
147 }
148 //don't update status if we are not the current clip (playlist leekage?) .. should move to playlist overwite of monitor?
149 if(this.pc){
150 if(this.pc.pp.cur_clip.id != this.pc.id)
151 return true;
152 }
153
154 //update currentTime
155 this.currentTime = this.vid.currentTime;
156 this.addPresTimeOffset();
157 //js_log('currentTime:' + this.currentTime);
158 //js_log('this.currentTime: ' + this.currentTime );
159 //once currentTime is updated call parent_monitor
160 this.parent_monitor();
161 },
162 getSrc:function(){
163 var src = this.parent_getSrc();
164 if( this.urlAppend != '')
165 return src + ( (src.indexOf('?')==-1)?'?':'&') + this.urlAppend;
166 return src;
167 },
168 /*
169 * native callbacks for the video tag:
170 */
171 oncanplaythrough : function(){
172 js_log('f:oncanplaythrough');
173 this.getVID();
174 if( ! this.paused )
175 this.vid.play();
176 },
177 onloadedmetadata: function(){
178 this.getVID();
179 js_log('f:onloadedmetadata metadata ready (update duration)');
180 //update duration if not set (for now trust the getDuration more than this.vid.duration
181 if( this.getDuration()==0 && !isNaN( this.vid.duration )){
182 js_log('updaed duration via native video duration: '+ this.vid.duration)
183 this.duration = this.vid.duration;
184 }
185 },
186 onprogress: function(e){
187 this.bufferedPercent = e.loaded / e.total;
188 //js_log("onprogress:" +e.loaded + ' / ' + (e.total) + ' = ' + this.bufferedPercent);
189 },
190 onended:function(){
191 var _this = this
192 this.getVID();
193 js_log('native:onended:' + this.vid.currentTime + ' real dur:' + this.getDuration() );
194 //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)
195 if(this.vid.currentTime < 1 && this.getDuration() > 1 && this.grab_try_count < 5){
196 js_log('native on ended called with time:' + this.vid.currentTime + ' of total real dur: ' + this.getDuration() + ' attempting to reload src...');
197 var doRetry = function(){
198 _this.urlAppend = 'retry_src=' + _this.grab_try_count;
199 _this.doEmbedHTML();
200 _this.grab_try_count++;
201 }
202 setTimeout(doRetry, 100);
203 }else{
204 this.onClipDone();
205 }
206 },
207 pause : function(){
208 this.getVID();
209 this.parent_pause(); //update interface
210 if(this.vid){
211 this.vid.pause();
212 }
213 //stop updates:
214 this.stopMonitor();
215 },
216 play:function(){
217 this.getVID();
218 this.parent_play(); //update interface
219 if( this.vid ){
220 this.vid.play();
221 //re-start the monitor:
222 this.monitor();
223 }
224 },
225 toggleMute:function(){
226 this.parent_toggleMute();
227 this.getVID();
228 if(this.vid)
229 this.vid.muted = this.muted;
230 },
231 updateVolumen:function(perc){
232 this.getVID();
233 if(this.vid)
234 this.vid.volume = perc;
235 },
236 getVolumen:function(){
237 this.getVID();
238 if(this.vid)
239 return this.vid.volume;
240 },
241 load:function(){
242 this.getVID();
243 if( !this.vid ){
244 //no vid loaded
245 js_log('native::load() ... doEmbed');
246 this.onlyLoadFlag = true;
247 this.doEmbedHTML();
248 }else{
249 //won't happen offten
250 this.vid.load();
251 }
252 },
253 // get the embed vlc object
254 getVID : function (){
255 this.vid = $j('#'+this.pid).get(0);
256 },
257 /*
258 * playlist driver
259 * mannages native playlist calls
260 */
261 };