Index: trunk/extensions/MetavidWiki/skins/mv_embed/embedLibs/mv_nativeEmbed.js |
— | — | @@ -21,7 +21,10 @@ |
22 | 22 | return this.wrapEmebedContainer( embed_code); |
23 | 23 | }, |
24 | 24 | getEmbedObj:function(){ |
25 | | - return '<video " ' + |
| 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 | + return '<video ' + |
26 | 29 | 'id="'+this.pid + '" ' + |
27 | 30 | 'style="width:'+this.width+'px;height:'+this.height+'px;" ' + |
28 | 31 | 'width="'+this.width+'" height="'+this.height+'" '+ |
— | — | @@ -45,6 +48,7 @@ |
46 | 49 | } |
47 | 50 | }, |
48 | 51 | monitor : function(){ |
| 52 | + //js_log('native:monitor'); |
49 | 53 | this.getVID(); //make shure we have .vid obj |
50 | 54 | //js_log('time loaded: ' + this.vid.TimeRanges ); |
51 | 55 | //js_log('current time: '+ this.vid.currentTime + ' dur: ' + this.duration); |
— | — | @@ -59,15 +63,11 @@ |
60 | 64 | if(!this.start_offset) |
61 | 65 | this.start_offset=this.media_element.selected_source.start_offset; |
62 | 66 | |
63 | | - //does smili based actions |
64 | | - this.doSmilActions(); |
65 | | - //if in playlist mode make sure we are the "current_clip" |
66 | | - if(this.pc){ |
67 | | - if(this.pc.pp.cur_clip.embed.id!=this.id){ |
68 | | - js_log("no status updates for "+this.id + ' not current clip'); |
69 | | - return ; |
70 | | - } |
71 | | - } |
| 67 | + //don't update status if we are not the current clip |
| 68 | + if(this.pc.pp.cur_clip.id != this.pc.id) |
| 69 | + return true; |
| 70 | + |
| 71 | + //only update the interface if controls have been included: |
72 | 72 | if( this.currentTime > 0 ){ |
73 | 73 | if(!this.userSlide){ |
74 | 74 | if(this.currentTime > this.duration){//we are likely viewing a annodex stream add in offset |
— | — | @@ -93,7 +93,7 @@ |
94 | 94 | */ |
95 | 95 | oncanplaythrough : function(){ |
96 | 96 | js_log("f:oncanplaythrough start playback"); |
97 | | - this.play(); |
| 97 | + //this.play(); |
98 | 98 | }, |
99 | 99 | onloadedmetadata: function(){ |
100 | 100 | js_log('f:onloadedmetadata get duration: ' +this.vid.duration); |
— | — | @@ -139,114 +139,7 @@ |
140 | 140 | // get the embed vlc object |
141 | 141 | getVID : function (){ |
142 | 142 | this.vid = $j('#'+this.pid).get(0); |
143 | | - }, |
144 | | - //handles the rendering of overlays loaind of future clips (if nessesary) |
145 | | - //@@todo could be lazy loaded if nessesary |
146 | | - doSmilActions: function(){ |
147 | | - if(this.pc){ //make sure we haev a parent clip: |
148 | | - var offSetTime = 0; //offset time should let us start a transition later on if we have to. |
149 | | - _pClip = this.pc; |
150 | | - |
151 | | - //@@todo move some of this out of this loop |
152 | | - if(!_pClip.dur) |
153 | | - _pClip.dur = this.duration; |
154 | | - |
155 | | - //check for duration actions / clip freze mode |
156 | | - if(_pClip.dur <= this.currentTime && _pClip.order != _pClip.pp.getClipCount()-1 ){ |
157 | | - //force next clip |
158 | | - js_log('order:' +_pClip.order + ' != count:' + (_pClip.pp.getClipCount()-1) + |
159 | | - ' smil dur: '+_pClip.dur + ' <= curTime: ' + this.currentTime + ' go to next clip..'); |
160 | | - _pClip.pp.next(); |
161 | | - } |
162 | | - |
163 | | - if(_pClip.dur >= this.currentTime ){ |
164 | | - //@@todo freeze on onClipStop |
165 | | - } |
166 | | - |
167 | | - if(_pClip.begin){ |
168 | | - //@@todo do freeze until begin time |
169 | | - } |
170 | | - |
171 | | - //check future clip for transitions (assume we are the current clip) |
172 | | - /*var next_pClip = _pClip.pp.getClip(1); |
173 | | - if(next_pClip.id!=_pClip.id){ //make sure we are not transitioning to the current clip |
174 | | - if(next_pClip.transIn){ |
175 | | - if(next_pClip.transIn.subtype=='crossfade'){ |
176 | | - //apply the effect to the end of "this" |
177 | | - if(this.currentTime > (this.duration - next_pClip.transIn.dur) ){ |
178 | | - js_log("do clip: cross fade now: "+(this.duration - next_pClip.transIn.dur) ); |
179 | | - if(!_pClip['trans_corssfadeOut']){ |
180 | | - //make new trans_corssfadeOut (special for cross fade) |
181 | | - _pClip['trans_corssfadeOut']=_pClip.pp.transitions[next_pClip.transIn.id].clone(); |
182 | | - _pClip.trans_corssfadeOut.cfout=true; |
183 | | - } |
184 | | - var overlay_selector_id = 'clipDesc_'+_pClip.id; |
185 | | - mvTransLib.doTransition(_pClip.trans_corssfadeOut, overlay_selector_id, offSetTime ) |
186 | | - } |
187 | | - |
188 | | - } |
189 | | - } |
190 | | - }*/ |
191 | | - //js_log("check for transOut: ct:"+this.currentTime + ' not > dur:'+_pClip.dur+'-'+'cdur:'+ _pClip.transOut.dur +' = '+ (_pClip.dur - _pClip.transOut.dur)); |
192 | | - if(_pClip.transOut){ |
193 | | - if(this.currentTime > (_pClip.dur - _pClip.transOut.dur) ){ |
194 | | - if(_pClip.transOut.animation_state==0){ |
195 | | - js_log("RUN transOut: ct:"+this.currentTime + ' > ' + (_pClip.dur - _pClip.transOut.dur)); |
196 | | - _pClip.transOut.animation_state=1;//running transition |
197 | | - if(_pClip.transOut.subtype=='crossfade'){ |
198 | | - //make sure the "next" clip is visiable |
199 | | - var next_pClip = _pClip.pp.getClip(1); |
200 | | - //start playing the clip |
201 | | - next_pClip.embed.play(); |
202 | | - //alert('opacity: '+$j('#clipDesc_'+next_pClip.id).css('opacity')); |
203 | | - var overlay_selector_id = 'clipDesc_'+next_pClip.id; |
204 | | - js_log("do transOUT for: "+overlay_selector_id); |
205 | | - mvTransLib.doTransition(_pClip.transOut, overlay_selector_id, offSetTime ); |
206 | | - } |
207 | | - }else if(_pClip.transOut.animation_state==2){ |
208 | | - this.stop(); |
209 | | - } |
210 | | - } |
211 | | - } |
212 | | - if(_pClip.transIn){ |
213 | | - if(this.currentTime < _pClip.transIn.dur){ |
214 | | - if(_pClip.transIn.animation_state==0){ |
215 | | - _pClip.transIn.animation_state=1;//running transition |
216 | | - js_log("RUN transIn "); |
217 | | - //@@todo process special case when overlay is subsequent clip |
218 | | - if(_pClip.transIn.subtype=='crossfade'){ |
219 | | - //check if prev clip pid exist: |
220 | | - var prev_clip = _pClip.pp.getClip(-1); |
221 | | - var overlay_selector_id = 'clipDesc_'+prev_clip.id; |
222 | | - }else{ |
223 | | - var overlay_selector_id =this.getOverlaySelector(_pClip, 'transIn_'); |
224 | | - } |
225 | | - js_log('selector element: '+$j('#'+overlay_selector_id).length); |
226 | | - //start transition for remaining time |
227 | | - |
228 | | - //var tran_function = getTransitionFunction(_pClip.transIn,overlay_selector_id, offSetTime) |
229 | | - mvTransLib.doTransition(_pClip.transIn, overlay_selector_id, offSetTime ) |
230 | | - } |
231 | | - //special case of cross fading clips: |
232 | | - //js_log('tran function: '+tran_function); |
233 | | - //debugger; |
234 | | - } |
235 | | - } |
236 | | - } |
237 | | - }, |
238 | | - getOverlaySelector:function(_pClip, pre_var){ |
239 | | - var overlay_selector_id= pre_var+_pClip.id; |
240 | | - if( ! $j('#'+overlay_selector_id).get(0) ){ |
241 | | - $j('#mv_ebct_'+_pClip.pp.id).prepend(''+ |
242 | | - '<div id="'+overlay_selector_id+'" ' + |
243 | | - 'style="position:absolute;top:0px;left:0px;' + |
244 | | - 'height:'+this.height+'px;'+ |
245 | | - 'width:'+this.width+'px;' + |
246 | | - 'z-index:2">' + |
247 | | - '</div>'); |
248 | | - } |
249 | | - return overlay_selector_id; |
250 | | - }, |
| 143 | + }, |
251 | 144 | /* |
252 | 145 | * playlist driver |
253 | 146 | * mannages native playlist calls |
— | — | @@ -257,95 +150,4 @@ |
258 | 151 | |
259 | 152 | } |
260 | 153 | } |
261 | | -} |
262 | | -/* |
263 | | - * mvTransLib libary of transitions |
264 | | - * a single object called to initiate transition effects can easily be extended in separate js file |
265 | | - * (that way a limited feature set "sequence" need not include a _lot_ of js unless necessary ) |
266 | | - * |
267 | | - * Smil Transition Effects see: |
268 | | - * http://www.w3.org/TR/SMIL3/smil-transitions.html#TransitionEffects-TransitionAttribute |
269 | | - */ |
270 | | -var mvTransLib = { |
271 | | - /* |
272 | | - * function doTransition lookups up the transition in the mvTransLib obj |
273 | | - * and intiates the transition if its avaliable |
274 | | - * @param tObj transition attribute object |
275 | | - * @param offSetTime default value 0 if we need to start rendering from a given time |
276 | | - */ |
277 | | - doTransition:function(tObj, overlay_selector_id, offSetTime){ |
278 | | - if(!tObj.type) |
279 | | - return js_log('transition is missing type attribute'); |
280 | | - |
281 | | - if(!tObj.subtype) |
282 | | - return js_log('transition is missing subtype attribute'); |
283 | | - |
284 | | - if(!this['type'][tObj.type]) |
285 | | - return js_log('mvTransLib does not support type: '+tObj.type); |
286 | | - |
287 | | - if(!this['type'][tObj.type][tObj.subtype]) |
288 | | - return js_log('mvTransLib does not support subType: '+tObj.subtype); |
289 | | - |
290 | | - //has type and subype call function with params: |
291 | | - this['type'][tObj.type][tObj.subtype](tObj,overlay_selector_id, offSetTime); |
292 | | - }, |
293 | | - type:{ |
294 | | - //types: |
295 | | - fade:{ |
296 | | - fadeFromColor:function(tObj, overlay_selector_id, offSetTime){ |
297 | | - js_log('f:fadeFromColor: '+overlay_selector_id +' to color: '+ tObj.fadeColor); |
298 | | - if(!tObj.fadeColor) |
299 | | - return js_log('missing fadeColor'); |
300 | | - if($j('#'+overlay_selector_id).get(0).length==0){ |
301 | | - js_log("ERROR cant find: "+ overlay_selector_id); |
302 | | - } |
303 | | - //set the initial state |
304 | | - $j('#'+overlay_selector_id).css({ |
305 | | - 'background-color':tObj.fadeColor, |
306 | | - 'opacity':"1", |
307 | | - }); |
308 | | - /*js_log('do transition annimation for: '+ (tObj.dur - offSetTime) |
309 | | - + ' seconds for: '+$j('#'+overlay_selector_id).get(0) + |
310 | | - ' current opacity: '+$j('#'+overlay_selector_id).css('opacity') );*/ |
311 | | - |
312 | | - //annimate the trasiion |
313 | | - $j('#'+overlay_selector_id).animate( |
314 | | - { |
315 | | - "opacity" : "0" |
316 | | - }, |
317 | | - (( tObj.dur - offSetTime )*1000), //duration value should be stored in ms earlier on. |
318 | | - 'linear', |
319 | | - function(){ //callback |
320 | | - js_log('fade done'); |
321 | | - tObj.animation_state=2; |
322 | | - } |
323 | | - ); |
324 | | - }, |
325 | | - //corssFade |
326 | | - crossfade:function(tObj, overlay_selector_id, offSetTime){ |
327 | | - js_log('f:crossfade: '+overlay_selector_id); |
328 | | - if($j('#'+overlay_selector_id).length==0) |
329 | | - js_log("ERROR overlay selector not found: "+overlay_selector_id); |
330 | | - |
331 | | - //set the initial state show the zero opacity animiation |
332 | | - $j('#'+overlay_selector_id).css({'opacity':0}).show(); |
333 | | - |
334 | | - /*js_log("should have set "+overlay_selector_id +"to zero is: "+ |
335 | | - $j('#'+overlay_selector_id).css('opacity') + ' should annimate for'+ |
336 | | - (( tObj.dur - offSetTime )*1000) );*/ |
337 | | - |
338 | | - $j('#'+overlay_selector_id).animate( |
339 | | - { |
340 | | - "opacity" : "1" |
341 | | - }, |
342 | | - (( tObj.dur - offSetTime )*1000), |
343 | | - 'linear', |
344 | | - function(){ //callback |
345 | | - js_log("animated opacity done"); |
346 | | - tObj.animation_state=2; |
347 | | - } |
348 | | - ); |
349 | | - } |
350 | | - } |
351 | | - } |
352 | 154 | } |
\ No newline at end of file |
Index: trunk/extensions/MetavidWiki/skins/mv_embed/mv_embed.js |
— | — | @@ -2347,7 +2347,7 @@ |
2348 | 2348 | $j.each(this.media_element.getPlayableSources(), function(index, source) |
2349 | 2349 | { |
2350 | 2350 | var default_player = embedTypes.players.defaultPlayer(source.getMIMEType()); |
2351 | | - var source_select_code = '$j(\'#'+this_id+'\').closeDisplayedHTML(); $j(\''+_this.id+'\').media_element.selectSource(\''+index+'\');'; |
| 2351 | + var source_select_code = '$j(\'#'+this_id+'\').get(0).closeDisplayedHTML(); $j(\''+_this.id+'\').media_element.selectSource(\''+index+'\');'; |
2352 | 2352 | var player_code = _this.getPlayerSelectList(source.getMIMEType(), index, source_select_code); |
2353 | 2353 | var is_not_selected = (source != _this.media_element.selected_source); |
2354 | 2354 | var image_src = mv_embed_path+'/images/stream/'; |
Index: trunk/extensions/MetavidWiki/skins/mv_embed/mv_playlist.js |
— | — | @@ -58,6 +58,7 @@ |
59 | 59 | start_clip:null, |
60 | 60 | start_clip_src:null, |
61 | 61 | disp_play_head:null, |
| 62 | + userSlide:false, |
62 | 63 | loading:true, |
63 | 64 | loading_external_data:true, //load external data by default |
64 | 65 | tracks:{}, |
— | — | @@ -216,16 +217,18 @@ |
217 | 218 | //js_log("GET PL DURRATION for : "+ this.tracks[this.default_track_id].clips.length + 'clips'); |
218 | 219 | if(!regen && this.pl_duration) |
219 | 220 | return this.pl_duration; |
220 | | - durSum=0; |
| 221 | + |
| 222 | + durSum=0; |
221 | 223 | $j.each(this.default_track.clips, function(i,clip){ |
222 | 224 | if(clip.embed){ |
223 | | - //js_log('add : '+ clip.getDuration()); |
| 225 | + js_log('plDUR:add : '+ clip.getDuration()); |
| 226 | + clip.dur_offset=durSum; |
224 | 227 | durSum+=clip.getDuration(); |
225 | 228 | }else{ |
226 | 229 | js_log("ERROR: clip " +clip.id + " not ready"); |
227 | 230 | } |
228 | 231 | }); |
229 | | - this.pl_duration=durSum; |
| 232 | + this.pl_duration=durSum; |
230 | 233 | //js_log("return dur: " + this.pl_duration); |
231 | 234 | return this.pl_duration; |
232 | 235 | }, |
— | — | @@ -389,7 +392,6 @@ |
390 | 393 | js_log('cound not find: clipDesc_'+clip.id); |
391 | 394 | } |
392 | 395 | }); |
393 | | - |
394 | 396 | if(this.cur_clip) |
395 | 397 | $j('#clipDesc_'+this.cur_clip.id).css({display:'inline'}); |
396 | 398 | |
— | — | @@ -402,7 +404,9 @@ |
403 | 405 | $j('#ptitle_'+this.id).html(''+ |
404 | 406 | '<b>' + this.title + '</b> '+ |
405 | 407 | this.getClipCount()+' clips, <i>'+ |
406 | | - this.getPlDurationNTP() + '</i>' ); |
| 408 | + this.getPlDurationNTP() + '</i>' ); |
| 409 | + //update status: |
| 410 | + this.cur_clip.embed.setStatus('0:0:00/'+this.getPlDurationNTP()); |
407 | 411 | }, |
408 | 412 | /*gets adds hidden desc to the #dc container*/ |
409 | 413 | getAllClipDesc : function(){ |
— | — | @@ -527,26 +531,33 @@ |
528 | 532 | this.cur_clip.embed.pe_postEmbedJS(); |
529 | 533 | }, |
530 | 534 | //playlist play |
531 | | - play : function(){ |
| 535 | + play: function(){ |
532 | 536 | var plObj=this; |
533 | 537 | js_log('pl play'); |
534 | 538 | //hide the playlist play button: |
535 | | - $j('#big_play_link_'+this.id).hide(); |
536 | | - //update cur clip based if sequence playhead set: |
537 | | - var d = new Date(); |
538 | | - this.clockStartTime = d.getTime(); |
| 539 | + $j('#big_play_link_'+this.id).hide(); |
539 | 540 | |
540 | | - js_log('pl_true_start_time:'+ this.pl_true_start_time); |
541 | | - |
542 | 541 | this.start_clip = this.cur_clip; |
543 | 542 | this.start_clip_src= this.cur_clip.src; |
544 | | - //load up the ebmed object with the playlist (if it supports it) |
545 | | - if(this.cur_clip.embed.supports['playlist_driver'] ){ |
546 | | - //load the playlist into the embed object: |
547 | | - js_log('clip obj supports playlist driver'); |
548 | | - //start up playlist driver: |
| 543 | + |
| 544 | + if(this.cur_clip.embed.supports['playlist_swap_loader'] ){ |
| 545 | + //navtive support: |
| 546 | + // * pre-loads clips |
| 547 | + // * mv_playlist smil extension, mannages transitions animations overlays etc. |
| 548 | + js_log('clip obj supports playlist swap_loader (ie playlist controlled playback)'); |
| 549 | + //update cur clip based if sequence playhead set: |
| 550 | + var d = new Date(); |
| 551 | + this.clockStartTime = d.getTime(); |
| 552 | + this.monitor(); |
| 553 | + |
| 554 | + //@@todo pre-load each clip: |
| 555 | + this.cur_clip.embed.play(); |
| 556 | + }else if(this.cur_clip.embed.supports['playlist_driver']){ |
| 557 | + js_log('playlist_driver'); |
| 558 | + //embedObject is feed the playlist info directly and mannages next/prev |
549 | 559 | this.cur_clip.embed.playMovieAt(this.cur_clip.order); |
550 | 560 | }else{ |
| 561 | + //not much playlist support just play the first clip: |
551 | 562 | js_log('basic play'); |
552 | 563 | //play cur_clip |
553 | 564 | this.cur_clip.embed.play(); |
— | — | @@ -1179,9 +1190,15 @@ |
1180 | 1191 | }, |
1181 | 1192 | setStatus:function(value){ |
1182 | 1193 | var plObj = this.pc.pp; |
1183 | | - //js_log('set status:'+ value); |
1184 | | - var pl_value='On clip ' + (plObj.cur_clip.order+1) + ' of ' + plObj.getClipCount() + '<br>'; |
1185 | | - this.pe_setStatus(value); |
| 1194 | + //only update status if playlist driver otherwise ignore and let master playlist update |
| 1195 | + if(this.supports['playlist_driver']){ |
| 1196 | + //js_log('set status:'+ value); |
| 1197 | + var pl_value='On clip ' + (plObj.cur_clip.order+1) + ' of ' + plObj.getClipCount() + '<br>'; |
| 1198 | + this.pe_setStatus(value); |
| 1199 | + }else{ |
| 1200 | + //js_log("set time via base offset:"+base_dur + ' curTime:'+plObj.cur_clip.embed.currentTime) |
| 1201 | + this.pe_setStatus(seconds2ntp(plObj.cur_clip.dur_offset + plObj.cur_clip.embed.currentTime) + '/'+ plObj.getPlDurationNTP()); |
| 1202 | + } |
1186 | 1203 | }, |
1187 | 1204 | setSliderValue:function(value){ |
1188 | 1205 | var sliderVal = this.pc.pp.getPlayHeadPos(value); |
— | — | @@ -1435,14 +1452,244 @@ |
1436 | 1453 | } |
1437 | 1454 | } |
1438 | 1455 | /***************************** |
1439 | | - * SMIL CODE (should be put into another js file / lazy_loaded) |
| 1456 | + * SMIL CODE (could be put into another js file / lazy_loaded for improved basic playlist performace / modularity) |
1440 | 1457 | *****************************/ |
1441 | 1458 | /*playlist driver extensions to the playlist object*/ |
1442 | | -mvPlayList.prototype.monitor = function(){ |
| 1459 | +mvPlayList.prototype.monitor = function(){ |
| 1460 | + //js_log('pl:monitor'); |
| 1461 | + var ct = new Date(); |
| 1462 | + //js_log('mvPlayList:monitor trueTime: '+ ( (ct.getTime() - this.clockStartTime )/1000)); |
| 1463 | + |
| 1464 | + //status updates are hanndled by children clips ... playlist just mannages smil actions |
| 1465 | + this.doSmilActions(); |
1443 | 1466 | |
| 1467 | + if( ! this.smil_monitorTimerId ){ |
| 1468 | + if(document.getElementById(this.id)){ |
| 1469 | + this.smil_monitorTimerId = setInterval('$j(\'#'+this.id+'\').get(0).monitor()', 250); |
| 1470 | + } |
| 1471 | + } |
1444 | 1472 | } |
| 1473 | +/* |
| 1474 | + * getOverlaySelectorHTML |
| 1475 | + * appends a div to curent clip if not already there |
| 1476 | + * @returns string 'overlay_selector_id' |
| 1477 | + */ |
| 1478 | +mvPlayList.prototype.getOverlaySelector = function(_pClip, pre_var){ |
| 1479 | + var overlay_selector_id= pre_var+_pClip.id; |
| 1480 | + js_log('f:getOverlaySelector: '+overlay_selector_id); |
| 1481 | + if( ! $j('#'+overlay_selector_id).get(0) ){ |
| 1482 | + $j('#videoPlayer_'+_pClip.embed.id).prepend(''+ |
| 1483 | + '<div id="'+overlay_selector_id+'" ' + |
| 1484 | + 'style="position:absolute;top:0px;left:0px;' + |
| 1485 | + 'height:'+this.height+'px;'+ |
| 1486 | + 'width:'+this.width+'px;' + |
| 1487 | + 'z-index:2">' + |
| 1488 | + '</div>'); |
| 1489 | + } |
| 1490 | + return overlay_selector_id; |
| 1491 | +} |
| 1492 | +//handles the rendering of overlays loaind of future clips (if nessesary) |
| 1493 | +//@@todo could be lazy loaded if nessesary |
| 1494 | +mvPlayList.prototype.doSmilActions = function(){ |
| 1495 | + //js_log('f:doSmilActions'); |
| 1496 | + var offSetTime = 0; //offset time should let us start a transition later on if we have to. |
| 1497 | + _pClip = this.cur_clip; |
| 1498 | + |
| 1499 | + //@@todo move some of this out of this loop |
| 1500 | + if(!_pClip.dur) |
| 1501 | + _pClip.dur = this.duration; |
| 1502 | + |
| 1503 | + //check for duration actions / clip freze mode |
| 1504 | + if(_pClip.dur <= _pClip.embed.currentTime && _pClip.order != _pClip.pp.getClipCount()-1 ){ |
| 1505 | + //force next clip |
| 1506 | + js_log('order:' +_pClip.order + ' != count:' + (_pClip.pp.getClipCount()-1) + |
| 1507 | + ' smil dur: '+_pClip.dur + ' <= curTime: ' + _pClip.embed.currentTime + ' go to next clip..'); |
| 1508 | + _pClip.pp.next(); |
| 1509 | + } |
| 1510 | + |
| 1511 | + if(_pClip.dur >= _pClip.embed.currentTime ){ |
| 1512 | + //@@todo freeze on onClipStop |
| 1513 | + } |
| 1514 | + |
| 1515 | + if(_pClip.begin){ |
| 1516 | + //@@todo do freeze until begin time |
| 1517 | + } |
| 1518 | + //@@todo could maybe generalize transIn with trasOut into one "flow" with a few scattered if statements |
| 1519 | + //update/setup all transitions (will render current transition state) |
| 1520 | + if(_pClip.transIn){ |
| 1521 | + //make sure we are in range: |
| 1522 | + if(_pClip.embed.currentTime < _pClip.transIn.dur){ |
| 1523 | + //make sure we have not already started the clip |
| 1524 | + if(_pClip.transIn.animation_state==0){ |
| 1525 | + _pClip.transIn.start_time =0;//start time is zero since we are transIn effect |
| 1526 | + |
| 1527 | + //setup overlay_selector_id |
| 1528 | + if(_pClip.transIn.subtype=='crossfade'){ |
| 1529 | + var prev_pClip = _pClip.pp.getClip(-1); |
| 1530 | + if(prev_pClip.id == this.cur_clip.id) |
| 1531 | + js_log('Error: transIn crossfade without previus media asset'); |
| 1532 | + |
| 1533 | + _pClip.transIn.overlay_selector_id = 'clipDesc_'+prev_pClip.id; |
| 1534 | + }else{ |
| 1535 | + _pClip.transIn.overlay_selector_id =this.getOverlaySelector(_pClip, 'transIn_'); |
| 1536 | + } |
| 1537 | + |
| 1538 | + js_log('selector element: '+$j('#'+_pClip.transIn.overlay_selector_id).length); |
| 1539 | + |
| 1540 | + |
| 1541 | + //start running the transition animation (will stop once pClip time > transition duration |
| 1542 | + js_log("ABOUT TO RUN transIn"); |
| 1543 | + js_log("cid: "+_pClip.transIn.pClip.id); |
| 1544 | + _pClip.transIn.run_animation(); |
| 1545 | + } |
| 1546 | + } |
| 1547 | + } |
| 1548 | + if(_pClip.transOut){ |
| 1549 | + //make sure we are in range: |
| 1550 | + if(_pClip.embed.currentTime >= (_pClip.dur - _pClip.transOut.dur) ){ |
| 1551 | + //make sure we have not already started the clip |
| 1552 | + if(_pClip.transOut.animation_state==0){ |
| 1553 | + _pClip.transOut.start_time =(_pClip.getDuration()-_pClip.transOut.dur) ;//start time is clip.dur - transOut.dr |
| 1554 | + |
| 1555 | + //setup overlay_selector_id |
| 1556 | + if(_pClip.transOut.subtype=='crossfade'){ |
| 1557 | + //@@ check that next clip is not current |
| 1558 | + var next_pClip = _pClip.pp.getClip(1); |
| 1559 | + if(next_pClip.id == this.cur_clip.id) |
| 1560 | + js_log('Error: transOut crossfade without subquent asset'); |
| 1561 | + |
| 1562 | + //start playing the next clip |
| 1563 | + next_pClip.embed.play(); |
| 1564 | + _pClip.transOut.overlay_selector_id = 'clipDesc_'+next_pClip.id; |
| 1565 | + //mvTransLib.doTransition(_pClip.transOut, overlay_selector_id, pClip); |
| 1566 | + |
| 1567 | + //start running the transition animation (will stop once pClip stops |
| 1568 | + js_log("ABOUT TO RUN transOut ANI: "+_pClip.transIn.pClip.id); |
| 1569 | + _pClip.transOut.run_animation(); |
| 1570 | + } |
| 1571 | + } |
| 1572 | + } |
| 1573 | + } |
| 1574 | + |
1445 | 1575 | |
| 1576 | + //check future clip for transitions (assume we are the current clip) |
| 1577 | + /*var next_pClip = _pClip.pp.getClip(1); |
| 1578 | + if(next_pClip.id!=_pClip.id){ //make sure we are not transitioning to the current clip |
| 1579 | + if(next_pClip.transIn){ |
| 1580 | + if(next_pClip.transIn.subtype=='crossfade'){ |
| 1581 | + //apply the effect to the end of "this" |
| 1582 | + if(this.currentTime > (this.duration - next_pClip.transIn.dur) ){ |
| 1583 | + js_log("do clip: cross fade now: "+(this.duration - next_pClip.transIn.dur) ); |
| 1584 | + if(!_pClip['trans_corssfadeOut']){ |
| 1585 | + //make new trans_corssfadeOut (special for cross fade) |
| 1586 | + _pClip['trans_corssfadeOut']=_pClip.pp.transitions[next_pClip.transIn.id].clone(); |
| 1587 | + _pClip.trans_corssfadeOut.cfout=true; |
| 1588 | + } |
| 1589 | + var overlay_selector_id = 'clipDesc_'+_pClip.id; |
| 1590 | + mvTransLib.doTransition(_pClip.trans_corssfadeOut, overlay_selector_id, offSetTime ) |
| 1591 | + } |
| 1592 | + |
| 1593 | + } |
| 1594 | + } |
| 1595 | + }*/ |
| 1596 | + //js_log("check for transOut: ct:"+this.currentTime + ' not > dur:'+_pClip.dur+'-'+'cdur:'+ _pClip.transOut.dur +' = '+ (_pClip.dur - _pClip.transOut.dur)); |
| 1597 | + /* |
| 1598 | + |
| 1599 | + }*/ |
| 1600 | +} |
1446 | 1601 | |
| 1602 | +/* |
| 1603 | + * mvTransLib libary of transitions |
| 1604 | + * a single object called to initiate transition effects can easily be extended in separate js file |
| 1605 | + * (that way a limited feature set "sequence" need not include a _lot_ of js unless necessary ) |
| 1606 | + * |
| 1607 | + * Smil Transition Effects see: |
| 1608 | + * http://www.w3.org/TR/SMIL3/smil-transitions.html#TransitionEffects-TransitionAttribute |
| 1609 | + */ |
| 1610 | +var mvTransLib = { |
| 1611 | + /* |
| 1612 | + * function doTransition lookups up the transition in the mvTransLib obj |
| 1613 | + * and intiates the transition if its avaliable |
| 1614 | + * @param tObj transition attribute object |
| 1615 | + * @param offSetTime default value 0 if we need to start rendering from a given time |
| 1616 | + */ |
| 1617 | + doInitTransition:function(tObj){ |
| 1618 | + if(!tObj.type) |
| 1619 | + return js_log('transition is missing type attribute'); |
| 1620 | + |
| 1621 | + if(!tObj.subtype) |
| 1622 | + return js_log('transition is missing subtype attribute'); |
| 1623 | + |
| 1624 | + if(!this['type'][tObj.type]) |
| 1625 | + return js_log('mvTransLib does not support type: '+tObj.type); |
| 1626 | + |
| 1627 | + if(!this['type'][tObj.type][tObj.subtype]) |
| 1628 | + return js_log('mvTransLib does not support subType: '+tObj.subtype); |
| 1629 | + |
| 1630 | + //has type and subype call function with params: |
| 1631 | + this['type'][tObj.type][tObj.subtype].init(tObj); |
| 1632 | + }, |
| 1633 | + doUpdate:function(tObj, percent){ |
| 1634 | + this['type'][tObj.type][tObj.subtype].u(tObj,percent); |
| 1635 | + }, |
| 1636 | + type:{ |
| 1637 | + //types: |
| 1638 | + fade:{ |
| 1639 | + fadeFromColor:{ |
| 1640 | + "init":function(tObj){ |
| 1641 | + js_log('f:fadeFromColor: '+tObj.overlay_selector_id +' to color: '+ tObj.fadeColor); |
| 1642 | + if(!tObj.fadeColor) |
| 1643 | + return js_log('missing fadeColor'); |
| 1644 | + if($j('#'+tObj.overlay_selector_id).get(0).length==0){ |
| 1645 | + js_log("ERROR cant find: "+ tObj.overlay_selector_id); |
| 1646 | + } |
| 1647 | + //set the initial state |
| 1648 | + $j('#'+tObj.overlay_selector_id).css({ |
| 1649 | + 'background-color':tObj.fadeColor, |
| 1650 | + 'opacity':"1", |
| 1651 | + }); |
| 1652 | + }, |
| 1653 | + 'u':function(tObj, percent){ |
| 1654 | + //fade from color invert the percent |
| 1655 | + var percent = 1- percent; |
| 1656 | + $j('#'+tObj.overlay_selector_id).css({ |
| 1657 | + "opacity" : percent |
| 1658 | + }); |
| 1659 | + } |
| 1660 | + }, |
| 1661 | + //corssFade |
| 1662 | + crossfade:{ |
| 1663 | + "init":function(tObj, overlay_selector_id, offSetTime){ |
| 1664 | + js_log('f:crossfade: '+overlay_selector_id); |
| 1665 | + if($j('#'+overlay_selector_id).length==0) |
| 1666 | + js_log("ERROR overlay selector not found: "+overlay_selector_id); |
| 1667 | + |
| 1668 | + //set the initial state show the zero opacity animiation |
| 1669 | + $j('#'+overlay_selector_id).css({'opacity':0}).show(); |
| 1670 | + |
| 1671 | + /*js_log("should have set "+overlay_selector_id +"to zero is: "+ |
| 1672 | + $j('#'+overlay_selector_id).css('opacity') + ' should annimate for'+ |
| 1673 | + (( tObj.dur - offSetTime )*1000) );*/ |
| 1674 | + |
| 1675 | + $j('#'+overlay_selector_id).animate( |
| 1676 | + { |
| 1677 | + "opacity" : "1" |
| 1678 | + }, |
| 1679 | + (( tObj.dur - offSetTime )*1000), |
| 1680 | + 'linear', |
| 1681 | + function(){ //callback |
| 1682 | + js_log("animated opacity done"); |
| 1683 | + tObj.animation_state=2; |
| 1684 | + } |
| 1685 | + ); |
| 1686 | + }, |
| 1687 | + 'u':function(tObj, percentage){ |
| 1688 | + |
| 1689 | + } |
| 1690 | + } |
| 1691 | + } |
| 1692 | + } |
| 1693 | +} |
1447 | 1694 | //smile based extension of <video> tag: |
1448 | 1695 | //region="video_region" transIn="fromGreen" begin="2s" |
1449 | 1696 | //http://www.w3.org/TR/2007/WD-SMIL3-20070713/smil-extended-media-object.html#edef-ref |
— | — | @@ -1547,19 +1794,38 @@ |
1548 | 1795 | |
1549 | 1796 | //lookup and assing copies of transitions |
1550 | 1797 | // (since transition needs to hold some per-instance state info) |
1551 | | - if(this.transIn && this.pp.transitions[this.transIn]) |
1552 | | - this.transIn =this.pp.transitions[this.transIn].clone(); |
| 1798 | + if(this.transIn && this.pp.transitions[this.transIn]){ |
| 1799 | + this.transIn =this.pp.transitions[this.transIn].clone(); |
| 1800 | + this.transIn.pClip = _this; |
| 1801 | + js_log("PCLIP:"+ this.transIn.pClip.id); |
| 1802 | + this.transIn.transAttrType='transIn'; |
| 1803 | + } |
1553 | 1804 | |
1554 | | - if(this.transOut && this.pp.transitions[this.transOut]) |
| 1805 | + if(this.transOut && this.pp.transitions[this.transOut]){ |
1555 | 1806 | this.transOut =this.pp.transitions[this.transOut].clone(); |
1556 | | - |
| 1807 | + this.transOut.pClip = _this; |
| 1808 | + js_log("PCLIP:"+ this.transIn.pClip.id); |
| 1809 | + this.transOut.transAttrType='transOut'; |
| 1810 | + } |
1557 | 1811 | //parse duration / begin times: |
1558 | 1812 | if(this.dur) |
1559 | | - this.dur = smilParseTime(this.dur); |
| 1813 | + this.dur = smilParseTime(this.dur); |
1560 | 1814 | |
1561 | 1815 | //check if the transition is a valid id: |
1562 | 1816 | return this; |
1563 | 1817 | }, |
| 1818 | + /* |
| 1819 | + * getDuration |
| 1820 | + * @returns duration in int |
| 1821 | + */ |
| 1822 | + getDuration:function(){ |
| 1823 | + //check for smil dur: |
| 1824 | + if(this.dur) |
| 1825 | + return this.dur; |
| 1826 | + //else get the duration from the embed clip: |
| 1827 | + if(this.embed.getDuration()) |
| 1828 | + return this.embed.getDuration(); |
| 1829 | + }, |
1564 | 1830 | setUpEmbedObj:function(){ |
1565 | 1831 | js_log('set up embed for smil based clip'); |
1566 | 1832 | if(this.tagName=='video') |
— | — | @@ -1586,10 +1852,16 @@ |
1587 | 1853 | 'fadeColor', |
1588 | 1854 | 'dur' |
1589 | 1855 | ); |
| 1856 | + |
| 1857 | +var MV_ANIMATION_CB_RATE = 34; |
1590 | 1858 | var transitionObj = function(element) { |
1591 | 1859 | this.init(element); |
1592 | 1860 | }; |
1593 | 1861 | transitionObj.prototype = { |
| 1862 | + transAttrType:null, //transIn or transOut |
| 1863 | + overlay_selector_id:null, |
| 1864 | + pClip:null, |
| 1865 | + timerId:null, |
1594 | 1866 | animation_state:0, //can be 0=unset, 1=running, 2=done |
1595 | 1867 | dur:2, //default duration of 2 |
1596 | 1868 | init:function(element){ |
— | — | @@ -1604,6 +1876,53 @@ |
1605 | 1877 | if(_this.dur) |
1606 | 1878 | _this.dur = smilParseTime(_this.dur); |
1607 | 1879 | }, |
| 1880 | + /* |
| 1881 | + * the main animation loop called every MV_ANIMATION_CB_RATE or 34ms ~around 30frames per second~ |
| 1882 | + */ |
| 1883 | + run_animation:function(){ |
| 1884 | + //js_log('f:run_animation'); |
| 1885 | + |
| 1886 | + if(this.prev_curtime!=this.pClip.embed.currentTime){ |
| 1887 | + this.prev_curtime = this.pClip.embed.currentTime; |
| 1888 | + this.interValCount=0; |
| 1889 | + } |
| 1890 | + |
| 1891 | + //start_time =assinged by doSmilActions |
| 1892 | + //base_cur_time = pClip.embed.currentTime; |
| 1893 | + //dur = assinged by attribute |
| 1894 | + |
| 1895 | + if(this.animation_state==0){ |
| 1896 | + mvTransLib.doInitTransition(this); |
| 1897 | + this.animation_state=1; |
| 1898 | + } |
| 1899 | + var percentage = (this.pClip.embed.currentTime + ((this.interValCount*MV_ANIMATION_CB_RATE)/1000) - this.start_time) / this.dur; |
| 1900 | + |
| 1901 | + /*js_log('percentage = ct:'+this.pClip.embed.currentTime + ' + ic:'+this.interValCount +' * cb'+MV_ANIMATION_CB_RATE + |
| 1902 | + ' - st'+this.start_time + ' / ' + this.dur + ' = ' + percentage ); |
| 1903 | + */ |
| 1904 | + |
| 1905 | + if(percentage >= 1){ |
| 1906 | + this.animation_state=2; |
| 1907 | + js_log("transition done"); |
| 1908 | + return true; |
| 1909 | + } |
| 1910 | + //js_log('cur percentage: '+percentage); |
| 1911 | + //update state based on curent time + cur_time_offset (for now just use pClip.embed.currentTime) |
| 1912 | + mvTransLib.doUpdate(this, percentage); |
| 1913 | + |
| 1914 | + |
| 1915 | + this.interValCount++; |
| 1916 | + //setInterval in we are still in running state |
| 1917 | + if(this.animation_state==1){ |
| 1918 | + if(!this.timerId){ |
| 1919 | + this.timerId = setInterval('document.getElementById(\''+this.pClip.pp.id+'\').cur_clip.'+this.transAttrType+'.run_animation()', |
| 1920 | + MV_ANIMATION_CB_RATE); |
| 1921 | + } |
| 1922 | + }else{ |
| 1923 | + clearInterval(this.timerId); |
| 1924 | + } |
| 1925 | + return true; |
| 1926 | + }, |
1608 | 1927 | clone:function(){ |
1609 | 1928 | var cObj = new this.constructor(); |
1610 | 1929 | for(var i in this) |