293650869868eb40372cb48669d9e460a81ec714
[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 if(typeof this.vid != 'undefined'){
53 //always load the media:
54 if( this.onlyLoadFlag ){
55 this.vid.load();
56 }else{
57 //issue play request
58 this.vid.play();
59 }
60 setTimeout('$j(\'#'+this.id+'\').get(0).monitor()',100);
61 }else{
62 js_log('could not grab vid obj trying again:' + typeof this.vid);
63 this.grab_try_count++;
64 if( this.grab_count == 20 ){
65 js_log(' could not get vid object after 10 tries re-run: getEmbedObj()' ) ;
66 }else{
67 setTimeout('$j(\'#'+this.id+'\').get(0).postEmbedJS()', 200);
68 }
69 }
70 },
71 doSeek:function(perc){
72 //js_log('native:seek:p: ' + perc+ ' : ' + this.supportsURLTimeEncoding() + ' dur: ' + this.getDuration() + ' sts:' + this.seek_time_sec );
73 //@@todo check if the clip is loaded here (if so we can do a local seek)
74 if( this.supportsURLTimeEncoding() || !this.vid){
75 //make sure we could not do a local seek instead:
76 if( perc < this.bufferedPercent && this.vid.duration && !this.didSeekJump ){
77 js_log("do local seek " + perc + ' is already buffered < ' + this.bufferedPercent);
78 this.doNativeSeek(perc);
79 }else{
80 this.parent_doSeek(perc);
81 }
82 }else if(this.vid && this.vid.duration ){
83 //(could also check bufferedPercent > perc seek (and issue oggz_chop request or not)
84 this.doNativeSeek( perc );
85 }else{
86 this.doPlayThenSeek( perc )
87 }
88 },
89 doNativeSeek:function(perc){
90 this.seek_time_sec=0;
91 this.vid.currentTime = perc * this.vid.duration;
92 this.parent_monitor();
93 },
94 doPlayThenSeek:function(perc){
95 js_log('native::doPlayThenSeek::');
96 var _this = this;
97 this.play();
98 var rfsCount = 0;
99 var readyForSeek = function(){
100 _this.getVID();
101 //if we have duration then we are ready to do the seek
102 if(this.vid && this.vid.duration){
103 _this.doSeek(perc);
104 }else{
105 //try to get player for 10 seconds:
106 if( rfsCount < 200 ){
107 setTimeout(readyForSeek, 50);
108 rfsCount++;
109 }else{
110 js_log('error:doPlayThenSeek failed');
111 }
112 }
113 }
114 readyForSeek();
115 },
116 setCurrentTime: function(pos, callback){
117 var _this = this;
118 this.getVID();
119 if(!this.vid) {
120 this.load();
121 var loaded = function(event) {
122 js_log('native:setCurrentTime (after load): ' + pos + ' : dur: ' + this.getDuration());
123 _this.vid.currentTime = pos;
124 var once = function(event) {
125 callback();
126 _this.vid.removeEventListener('seeked', once, false)
127 };
128 _this.vid.addEventListener('seeked', once, false);
129 _this.removeEventListener('loadedmetadata', loaded, false);
130 };
131 _this.addEventListener('loadedmetadata', loaded, false);
132 } else {
133 //js_log('native:setCurrentTime: ' + pos + ' : ' + this.supportsURLTimeEncoding() + ' dur: ' + this.getDuration() + ' sts:' + this.seek_time_sec );
134 _this.vid.currentTime = pos;
135 var once = function(event) {
136 callback();
137 _this.vid.removeEventListener('seeked', once, false)
138 };
139 _this.vid.addEventListener('seeked', once, false);
140 }
141 },
142 monitor : function(){
143 this.getVID(); //make shure we have .vid obj
144 if(!this.vid){
145 js_log('could not find video embed: '+this.id + ' stop monitor');
146 this.stopMonitor();
147 return false;
148 }
149 //don't update status if we are not the current clip (playlist leekage?) .. should move to playlist overwite of monitor?
150 if(this.pc){
151 if(this.pc.pp.cur_clip.id != this.pc.id)
152 return true;
153 }
154
155 //update currentTime
156 this.currentTime = this.vid.currentTime;
157 this.addPresTimeOffset();
158
159 //js_log('currentTime:' + this.currentTime);
160 //js_log('this.currentTime: ' + this.currentTime );
161 //once currentTime is updated call parent_monitor
162 this.parent_monitor();
163 },
164 getSrc:function(){
165 var src = this.parent_getSrc();
166 if( this.urlAppend != '')
167 return src + ( (src.indexOf('?')==-1)?'?':'&') + this.urlAppend;
168 return src;
169 },
170 /*
171 * native callbacks for the video tag:
172 */
173 oncanplaythrough : function(){
174 //js_log('f:oncanplaythrough');
175 this.getVID();
176 if( ! this.paused )
177 this.vid.play();
178 },
179 onloadedmetadata: function(){
180 this.getVID();
181 js_log('f:onloadedmetadata metadata ready (update duration)');
182 //update duration if not set (for now trust the getDuration more than this.vid.duration
183 if( this.getDuration() == 0 && ! isNaN( this.vid.duration ) ){
184 js_log('updaed duration via native video duration: '+ this.vid.duration)
185 this.duration = this.vid.duration;
186 }
187 },
188 onprogress: function(e){
189 this.bufferedPercent = e.loaded / e.total;
190 //js_log("onprogress:" +e.loaded + ' / ' + (e.total) + ' = ' + this.bufferedPercent);
191 },
192 onended:function(){
193 var _this = this
194 this.getVID();
195 js_log('native:onended:' + this.vid.currentTime + ' real dur:' + this.getDuration() );
196 //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)
197 if(this.vid.currentTime < 1 && this.getDuration() > 1 && this.grab_try_count < 5){
198 js_log('native on ended called with time:' + this.vid.currentTime + ' of total real dur: ' + this.getDuration() + ' attempting to reload src...');
199 var doRetry = function(){
200 _this.urlAppend = 'retry_src=' + _this.grab_try_count;
201 _this.doEmbedHTML();
202 _this.grab_try_count++;
203 }
204 setTimeout(doRetry, 100);
205 }else{
206 js_log('native onClipDone done call');
207 this.onClipDone();
208 }
209 },
210 pause : function(){
211 this.getVID();
212 this.parent_pause(); //update interface
213 if(this.vid){
214 this.vid.pause();
215 }
216 //stop updates:
217 this.stopMonitor();
218 },
219 play:function(){
220 this.getVID();
221 this.parent_play(); //update interface
222 if( this.vid ){
223 this.vid.play();
224 //re-start the monitor:
225 this.monitor();
226 }
227 },
228 toggleMute:function(){
229 this.parent_toggleMute();
230 this.getVID();
231 if(this.vid)
232 this.vid.muted = this.muted;
233 },
234 updateVolumen:function(perc){
235 this.getVID();
236 if(this.vid)
237 this.vid.volume = perc;
238 },
239 getVolumen:function(){
240 this.getVID();
241 if(this.vid)
242 return this.vid.volume;
243 },
244 getNativeDuration:function(){
245 if(this.vid)
246 return this.vid.duration;
247 },
248 load:function(){
249 this.getVID();
250 if( !this.vid ){
251 //no vid loaded
252 js_log('native::load() ... doEmbed');
253 this.onlyLoadFlag = true;
254 this.doEmbedHTML();
255 }else{
256 //won't happen offten
257 this.vid.load();
258 }
259 },
260 // get the embed vlc object
261 getVID : function (){
262 this.vid = $j('#'+this.pid).get(0);
263 },
264 /*
265 * playlist driver
266 * mannages native playlist calls
267 */
268 };