Index: trunk/extensions/MetavidWiki/skins/mv_embed/example_usage/sample_smil.smil.xml |
— | — | @@ -17,27 +17,27 @@ |
18 | 18 | <transition id="xFade" |
19 | 19 | type="fade" |
20 | 20 | subtype="crossfade" |
21 | | - dur="2s"/> |
| 21 | + dur="4s"/> |
22 | 22 | |
23 | 23 | </head> |
24 | 24 | <body> |
25 | 25 | <seq> |
26 | | - <video src="sample_fish.ogg?t=0:0:0/0:0:26" |
| 26 | + <video src="sample_fish.ogg?t=0:0:0/0:0:25" |
27 | 27 | region="video_region" |
28 | | - transIn="fromGreen" |
29 | | - fill="remove" |
30 | | - type="video/ogg" |
| 28 | + transIn="fromGreen" |
| 29 | + transOut="xFade" |
| 30 | + type="video/ogg" |
| 31 | + fill="transition" |
| 32 | + dur="10s" |
31 | 33 | poster="sample_fish.jpg"/> |
32 | 34 | |
33 | 35 | <video src="sample_magnolia.ogg?t=0:0:0/0:0:05" |
34 | 36 | region="video_region" |
35 | 37 | transIn="xFade" |
36 | | - transOut="toGreen" |
37 | | - begin="2s" |
| 38 | + transOut="toGreen" |
38 | 39 | fill="transition" |
39 | 40 | type="video/ogg" |
40 | | - poster="sample_magnolia.jpg"/> |
41 | | - |
| 41 | + poster="sample_magnolia.jpg"/> |
42 | 42 | </seq> |
43 | 43 | </body> |
44 | 44 | </smil> |
Index: trunk/extensions/MetavidWiki/skins/mv_embed/embedLibs/mv_nativeEmbed.js |
— | — | @@ -10,8 +10,8 @@ |
11 | 11 | 'volume_control':true, |
12 | 12 | |
13 | 13 | 'overlays':true, |
14 | | - 'playlist_driver':true //if the object supports playlist functions |
15 | | - }, |
| 14 | + 'playlist_swap_loader':true //if the object supports playlist functions |
| 15 | + }, |
16 | 16 | getEmbedHTML : function (){ |
17 | 17 | setTimeout('$j(\'#'+this.id+'\').get(0).postEmbedJS()', 150); |
18 | 18 | //set a default duration of 30 seconds: cortao should detect duration. |
— | — | @@ -48,15 +48,15 @@ |
49 | 49 | this.getVID(); //make shure we have .vid obj |
50 | 50 | //js_log('time loaded: ' + this.vid.TimeRanges ); |
51 | 51 | //js_log('current time: '+ this.vid.currentTime + ' dur: ' + this.duration); |
52 | | - |
53 | | - //update duration if not set |
| 52 | + |
| 53 | + //update duration if not set |
54 | 54 | this.duration =(this.vid.duration==0)?this.getDuration():this.vid.duration; |
55 | 55 | |
56 | 56 | //update currentTime |
57 | 57 | this.currentTime = this.vid.currentTime; |
58 | 58 | |
59 | | - //check for overlays to run or stop |
60 | | - this.doSmilTransitionOverlays(); |
| 59 | + //does smili based actions |
| 60 | + this.doSmilActions(); |
61 | 61 | |
62 | 62 | if( this.currentTime > 0 ){ |
63 | 63 | if(!this.userSlide){ |
— | — | @@ -117,58 +117,124 @@ |
118 | 118 | }, |
119 | 119 | //handles the rendering of overlays loaind of future clips (if nessesary) |
120 | 120 | //@@todo could be lazy loaded if nessesary |
121 | | - doSmilTransitionOverlays: function(){ |
122 | | - if(this.pc){ |
123 | | - _pClip = this.pc; |
| 121 | + doSmilActions: function(){ |
| 122 | + if(this.pc){ //make sure we haev a parent clip: |
| 123 | + var offSetTime = 0; //offset time should let us start a transition later on if we have to. |
| 124 | + _pClip = this.pc; |
| 125 | + |
| 126 | + //@@todo move some of this out of this loop |
| 127 | + if(!_pClip.dur) |
| 128 | + _pClip.dur = this.duration; |
| 129 | + |
| 130 | + //check for duration actions / clip freze mode |
| 131 | + if(_pClip.dur <= this.currentTime ){ |
| 132 | + //force next clip |
| 133 | + js_log('smil dur: '+_pClip.dur + ' <= curTime: ' + this.currentTime + ' go to next clip'); |
| 134 | + _pClip.pp.next(); |
| 135 | + } |
| 136 | + |
| 137 | + if(_pClip.dur >= this.currentTime ){ |
| 138 | + //@@todo freeze on onClipStop |
| 139 | + } |
| 140 | + |
| 141 | + if(_pClip.begin){ |
| 142 | + //@@todo do freeze until begin time |
| 143 | + } |
| 144 | + |
| 145 | + //check future clip for transitions (assume we are the current clip) |
| 146 | + /*var next_pClip = _pClip.pp.getClip(1); |
| 147 | + if(next_pClip.id!=_pClip.id){ //make sure we are not transitioning to the current clip |
| 148 | + if(next_pClip.transIn){ |
| 149 | + if(next_pClip.transIn.subtype=='crossfade'){ |
| 150 | + //apply the effect to the end of "this" |
| 151 | + if(this.currentTime > (this.duration - next_pClip.transIn.dur) ){ |
| 152 | + js_log("do clip: cross fade now: "+(this.duration - next_pClip.transIn.dur) ); |
| 153 | + if(!_pClip['trans_corssfadeOut']){ |
| 154 | + //make new trans_corssfadeOut (special for cross fade) |
| 155 | + _pClip['trans_corssfadeOut']=_pClip.pp.transitions[next_pClip.transIn.id].clone(); |
| 156 | + _pClip.trans_corssfadeOut.cfout=true; |
| 157 | + } |
| 158 | + var overlay_selector_id = 'clipDesc_'+_pClip.id; |
| 159 | + mvTransLib.doTransition(_pClip.trans_corssfadeOut, overlay_selector_id, offSetTime ) |
| 160 | + } |
| 161 | + |
| 162 | + } |
| 163 | + } |
| 164 | + }*/ |
| 165 | + js_log("check for transOut: ct:"+this.currentTime + ' not > dur:'+_pClip.dur+'-'+'cdur:'+ _pClip.transOut.dur +' = '+ (_pClip.dur - _pClip.transOut.dur)); |
| 166 | + if(_pClip.transOut){ |
| 167 | + if(this.currentTime > (_pClip.dur - _pClip.transOut.dur) ){ |
| 168 | + if(_pClip.transOut.animation_state==0){ |
| 169 | + js_log("RUN transOut: ct:"+this.currentTime + ' > ' + (_pClip.dur - _pClip.transOut.dur)); |
| 170 | + _pClip.transOut.animation_state=1;//running transition |
| 171 | + if(_pClip.transOut.subtype=='crossfade'){ |
| 172 | + //make sure the "next" clip is visiable |
| 173 | + var next_pClip = _pClip.pp.getClip(1); |
| 174 | + $j('#clipDesc_'+next_pClip.id).show(); |
| 175 | + var overlay_selector_id = 'clipDesc_'+_pClip.id; |
| 176 | + mvTransLib.doTransition(_pClip.transOut, overlay_selector_id, offSetTime ); |
| 177 | + } |
| 178 | + } |
| 179 | + } |
| 180 | + } |
124 | 181 | if(_pClip.transIn){ |
125 | | - //js_log('transIn exist see if we are in time range'); |
126 | | - if(_pClip.transIn.dur){ |
127 | | - //only run if the animation_done is not done yet: |
128 | | - if(!_pClip.transIn.animation_done){ //make sure the animation is not done |
129 | | - if(this.currentTime < _pClip.transIn.dur){ |
130 | | - if(_pClip.transIn.animation_state==0){ |
131 | | - _pClip.transIn.animation_state=1;//running transition |
132 | | - js_log("RUN TRANSITION: "); |
133 | | - //@@todo process special case when overlay is subsequent clip |
134 | | - var overlay_selector_id= 'transIn_'+_pClip.id; |
135 | | - if( ! $j('#'+overlay_selector_id).get(0) ){ |
136 | | - js_log('adding in element: to #mv_ebct_'+_pClip.pp.id + ' oid:' +overlay_selector_id); |
137 | | - $j('#mv_ebct_'+_pClip.pp.id).prepend(''+ |
138 | | - '<div id="'+overlay_selector_id+'" ' + |
139 | | - 'style="position:absolute;top:0px;left:0px;' + |
140 | | - 'height:'+this.height+'px;'+ |
141 | | - 'width:'+this.width+'px;' + |
142 | | - 'opacity:1;'+ |
143 | | - 'z-index:2">' + |
144 | | - '</div>'); |
145 | | - } |
146 | | - js_log('selector element: '+$j('#'+overlay_selector_id).length); |
147 | | - //start transition for remaining time |
148 | | - var offSetTime = 0; //future think about what time info we need to send |
149 | | - //var tran_function = getTransitionFunction(_pClip.transIn,overlay_selector_id, offSetTime) |
150 | | - mvTransLib.doTransition(_pClip.transIn, overlay_selector_id, offSetTime ) |
151 | | - } |
152 | | - //special case of cross fading clips: |
153 | | - //js_log('tran function: '+tran_function); |
154 | | - //debugger; |
155 | | - } |
156 | | - } |
157 | | - } |
| 182 | + if(this.currentTime < _pClip.transIn.dur){ |
| 183 | + if(_pClip.transIn.animation_state==0){ |
| 184 | + _pClip.transIn.animation_state=1;//running transition |
| 185 | + js_log("RUN transIn "); |
| 186 | + //@@todo process special case when overlay is subsequent clip |
| 187 | + if(_pClip.transIn.subtype=='crossfade'){ |
| 188 | + //check if prev clip pid exist: |
| 189 | + var prev_clip = _pClip.pp.getClip(-1); |
| 190 | + var overlay_selector_id = 'clipDesc_'+prev_clip.id; |
| 191 | + }else{ |
| 192 | + var overlay_selector_id =this.getOverlaySelector(_pClip, 'transIn_'); |
| 193 | + } |
| 194 | + js_log('selector element: '+$j('#'+overlay_selector_id).length); |
| 195 | + //start transition for remaining time |
| 196 | + |
| 197 | + //var tran_function = getTransitionFunction(_pClip.transIn,overlay_selector_id, offSetTime) |
| 198 | + mvTransLib.doTransition(_pClip.transIn, overlay_selector_id, offSetTime ) |
| 199 | + } |
| 200 | + //special case of cross fading clips: |
| 201 | + //js_log('tran function: '+tran_function); |
| 202 | + //debugger; |
| 203 | + } |
158 | 204 | } |
159 | 205 | } |
| 206 | + }, |
| 207 | + getOverlaySelector:function(_pClip, pre_var){ |
| 208 | + var overlay_selector_id= pre_var+_pClip.id; |
| 209 | + if( ! $j('#'+overlay_selector_id).get(0) ){ |
| 210 | + $j('#mv_ebct_'+_pClip.pp.id).prepend(''+ |
| 211 | + '<div id="'+overlay_selector_id+'" ' + |
| 212 | + 'style="position:absolute;top:0px;left:0px;' + |
| 213 | + 'height:'+this.height+'px;'+ |
| 214 | + 'width:'+this.width+'px;' + |
| 215 | + 'z-index:2">' + |
| 216 | + '</div>'); |
| 217 | + } |
| 218 | + return overlay_selector_id; |
| 219 | + }, |
| 220 | + /* |
| 221 | + * playlist driver |
| 222 | + * mannages native playlist calls |
| 223 | + */ |
| 224 | + playlistNext:function(){ |
| 225 | + if(!this.pc){//make sure we are a clip |
| 226 | + // |
| 227 | + |
| 228 | + } |
160 | 229 | } |
161 | 230 | } |
162 | 231 | /* |
163 | 232 | * mvTransLib libary of transitions |
164 | 233 | * a single object called to initiate transition effects can easily be extended in separate js file |
165 | 234 | * (that way a limited feature set "sequence" need not include a _lot_ of js unless necessary ) |
166 | | - */ |
167 | | - /* |
| 235 | + * |
168 | 236 | * Smil Transition Effects see: |
169 | 237 | * http://www.w3.org/TR/SMIL3/smil-transitions.html#TransitionEffects-TransitionAttribute |
170 | | - */ |
171 | | - |
172 | | - |
| 238 | + */ |
173 | 239 | mvTransLib = { |
174 | 240 | /* |
175 | 241 | * function doTransition lookups up the transition in the mvTransLib obj |
— | — | @@ -180,18 +246,14 @@ |
181 | 247 | if(!tObj.type) |
182 | 248 | return js_log('transition is missing type attribute'); |
183 | 249 | |
184 | | - if(!tObj.type) |
| 250 | + if(!tObj.subtype) |
185 | 251 | return js_log('transition is missing subtype attribute'); |
186 | 252 | |
187 | 253 | if(!this['type'][tObj.type]) |
188 | | - return js_log('mvTransLib is missing type: '+tObj.type); |
| 254 | + return js_log('mvTransLib does not support type: '+tObj.type); |
189 | 255 | |
190 | 256 | if(!this['type'][tObj.type][tObj.subtype]) |
191 | | - return js_log('mvTransLib is missing subType: '+tObj.subtype); |
192 | | - |
193 | | - //maybe have a default for this? |
194 | | - if(!tObj.dur) |
195 | | - return js_log('missing transition duration'); |
| 257 | + return js_log('mvTransLib does not support subType: '+tObj.subtype); |
196 | 258 | |
197 | 259 | //has type and subype call function with params: |
198 | 260 | this['type'][tObj.type][tObj.subtype](tObj,overlay_selector_id, offSetTime); |
— | — | @@ -229,7 +291,7 @@ |
230 | 292 | } |
231 | 293 | ); |
232 | 294 | }, |
233 | | - //depends if transition_in or transition_out |
| 295 | + //corssFade |
234 | 296 | crossfade:function(tObj, overlay_selector_id, offSetTime){ |
235 | 297 | js_log('f:crossfade: '+overlay_selector_id); |
236 | 298 | //set the initial state |
Index: trunk/extensions/MetavidWiki/skins/mv_embed/mv_embed.js |
— | — | @@ -1917,8 +1917,8 @@ |
1918 | 1918 | } |
1919 | 1919 | // time display |
1920 | 1920 | if(this.supports['time_display'] && (available_width > 80)) |
1921 | | - { |
1922 | | - html_code += '<div id="mv_time_'+id+'" class="time">'+this.getTimeReq()+'</div>'; |
| 1921 | + { |
| 1922 | + html_code += '<div id="mv_time_'+id+'" class="time">'+this.getDurationNTP()+'</div>'; |
1923 | 1923 | available_width -= 80; |
1924 | 1924 | } |
1925 | 1925 | |
— | — | @@ -2070,8 +2070,7 @@ |
2071 | 2071 | ' overflow:hidden; top:0px; left:0px; width:'+this.playerPixelWidth()+'px; height:'+this.playerPixelHeight()+'px; z-index:0;">'+ |
2072 | 2072 | '<img width="'+this.playerPixelWidth()+'" height="'+this.playerPixelHeight()+'" style="position:relative;width:'+this.playerPixelWidth()+';height:'+this.playerPixelHeight()+'"' + |
2073 | 2073 | ' id="img_thumb_'+this.id+'" src="' + thumbnail + '">'; |
2074 | | - |
2075 | | - js_log("PLAY BUTTON: " + this.play_button); |
| 2074 | + |
2076 | 2075 | if(this.play_button==true) |
2077 | 2076 | thumb_html+=this.getPlayButton(); |
2078 | 2077 | thumb_html+='</div>'; |
Index: trunk/extensions/MetavidWiki/skins/mv_embed/mv_playlist.js |
— | — | @@ -335,6 +335,8 @@ |
336 | 336 | //update the embed html: |
337 | 337 | clip.embed.height=plObj.height; |
338 | 338 | clip.embed.width=plObj.width; |
| 339 | + if(clip.id != plObj.cur_clip.id) |
| 340 | + clip.embed.play_button=false; |
339 | 341 | |
340 | 342 | clip.embed.getHTML();//get the thubnails for everything |
341 | 343 | $j(clip.embed).css({ 'position':"absolute",'top':"0px", 'left':"0px"}); |
— | — | @@ -342,11 +344,10 @@ |
343 | 345 | $j('#clipDesc_'+clip.id).get(0).appendChild(clip.embed); |
344 | 346 | }else{ |
345 | 347 | js_log('cound not find: clipDesc_'+clip.id); |
346 | | - } |
347 | | - |
| 348 | + } |
348 | 349 | //add the controls if we are on the current clip: |
349 | 350 | if(clip.id == plObj.cur_clip.id){ |
350 | | - js_log("add controls: "+ clip.embed.getControlsHTML() +"\nto:videoPlayer_"+ clip.embed.id); |
| 351 | + //js_log("add controls: "+ clip.embed.getControlsHTML() +"\nto:videoPlayer_"+ clip.embed.id); |
351 | 352 | $j('#videoPlayer_'+clip.embed.id).append( |
352 | 353 | '<div id="mv_embedded_controls_'+plObj.id+'" ' + |
353 | 354 | 'style="postion:relative;top:'+(plObj.height+title_bar_height)+'px" ' + |
— | — | @@ -354,7 +355,7 @@ |
355 | 356 | clip.embed.getControlsHTML() + |
356 | 357 | '</div>' |
357 | 358 | ); |
358 | | - } |
| 359 | + } |
359 | 360 | }); |
360 | 361 | |
361 | 362 | if(this.cur_clip) |
— | — | @@ -507,10 +508,19 @@ |
508 | 509 | next: function(){ |
509 | 510 | //advance the playhead to the next clip |
510 | 511 | var next_clip = this.getClip(1); |
511 | | - if(this.cur_clip.embed.supports['playlist_driver']){ |
| 512 | + if(this.cur_clip.embed.supports['playlist_driver']){ //where the plugin is just feed a playlist |
512 | 513 | //do next clip action on start_clip embed cuz its the one being displayed: |
513 | 514 | this.start_clip.embed.playlistNext(); |
514 | 515 | this.cur_clip=next_clip; |
| 516 | + }else if(this.cur_clip.embed.supports['playlist_swap_loader']){ |
| 517 | + //where the plugin supports pre_loading future clips and manage that in javascript |
| 518 | + //pause current clip |
| 519 | + this.cur_clip.embed.pause; |
| 520 | + //do swap: |
| 521 | + $j('#clipDesc_'+this.cur_clip.id).hide(); |
| 522 | + this.cur_clip=next_clip; |
| 523 | + $j('#clipDesc_'+this.cur_clip.id).show(); |
| 524 | + this.cur_clip.embed.play(); |
515 | 525 | }else{ |
516 | 526 | js_log('do next'); |
517 | 527 | this.switchPlayingClip(next_clip); |
— | — | @@ -522,8 +532,17 @@ |
523 | 533 | if(this.cur_clip.embed.supports['playlist_driver']){ |
524 | 534 | this.start_clip.embed.playlistPrev(); |
525 | 535 | this.cur_clip=prev_clip; |
| 536 | + }else if(this.cur_clip.embed.supports['playlist_swap_loader']){ |
| 537 | + //where the plugin supports pre_loading future clips and manage that in javascript |
| 538 | + //pause current clip |
| 539 | + this.cur_clip.embed.pause; |
| 540 | + //do swap: |
| 541 | + $j('#clipDesc_'+this.cur_clip.id).hide(); |
| 542 | + this.cur_clip=prev_clip; |
| 543 | + $j('#clipDesc_'+this.cur_clip.id).show(); |
| 544 | + this.cur_clip.embed.play(); |
526 | 545 | }else{ |
527 | | - js_log('do prev'); |
| 546 | + js_log('do prev hard embed swap'); |
528 | 547 | this.switchPlayingClip(prev_clip); |
529 | 548 | } |
530 | 549 | }, |
— | — | @@ -640,11 +659,13 @@ |
641 | 660 | }, |
642 | 661 | //returns a clip. If offset is out of bound returns first or last clip |
643 | 662 | getClip: function(clip_offset){ |
644 | | - if(!clip_offset)clip_offset=0; |
645 | | - //idorate through clips for this.cur_clipID (more complicated to allow for id of clips |
| 663 | + if(!clip_offset)clip_offset=0; |
| 664 | + |
646 | 665 | var cov = this.cur_clip.order + clip_offset; |
647 | 666 | var cmax = this.getClipCount()-1; |
648 | 667 | //js_log('cov:'+cov +' cmax:'+ cmax); |
| 668 | + |
| 669 | + //force first or last clip if offset is outOfBounds |
649 | 670 | if( cov >= 0 && cov <= cmax ){ |
650 | 671 | return this.default_track.clips[cov] |
651 | 672 | }else{ |
— | — | @@ -1554,7 +1575,8 @@ |
1555 | 1576 | 'transIn', |
1556 | 1577 | 'transOut', |
1557 | 1578 | 'begin', |
1558 | | - 'fill' |
| 1579 | + 'fill', |
| 1580 | + 'dur' |
1559 | 1581 | ); |
1560 | 1582 | //all the overwritten and new methods for playlist extension of mv_embed |
1561 | 1583 | mvSMILClip.prototype = { |
— | — | @@ -1590,7 +1612,9 @@ |
1591 | 1613 | if(this.transOut && this.pp.transitions[this.transOut]) |
1592 | 1614 | this.transOut =this.pp.transitions[this.transOut].clone(); |
1593 | 1615 | |
1594 | | - |
| 1616 | + //parse duration: |
| 1617 | + if(this.dur) |
| 1618 | + this.dur = smilParseTime(this.dur); |
1595 | 1619 | //check if the transition is a valid id: |
1596 | 1620 | return this; |
1597 | 1621 | }, |
— | — | @@ -1625,6 +1649,7 @@ |
1626 | 1650 | }; |
1627 | 1651 | transitionObj.prototype = { |
1628 | 1652 | animation_state:0, //can be 0=unset, 1=running, 2=done |
| 1653 | + dur:2, //default duration of 2 |
1629 | 1654 | init:function(element){ |
1630 | 1655 | //load supported attributes: |
1631 | 1656 | var _this = this; |
— | — | @@ -1635,7 +1660,7 @@ |
1636 | 1661 | //@@todo proccess duration (for now just srip s) per: |
1637 | 1662 | //http://www.w3.org/TR/SMIL3/smil-timing.html#Timing-ClockValueSyntax |
1638 | 1663 | if(_this.dur) |
1639 | | - _this.dur = parseInt(_this.dur.replace('s', '')); |
| 1664 | + _this.dur = smilParseTime(_this.dur); |
1640 | 1665 | }, |
1641 | 1666 | clone:function(){ |
1642 | 1667 | var cObj = new this.constructor(); |
— | — | @@ -1644,6 +1669,18 @@ |
1645 | 1670 | return cObj; |
1646 | 1671 | } |
1647 | 1672 | } |
| 1673 | +/* |
| 1674 | + * takes an input |
| 1675 | + * @time_str input time string |
| 1676 | + * returns time in seconds |
| 1677 | + * |
| 1678 | + * @@todo proccess duration (for now just srip s) per: |
| 1679 | + * http://www.w3.org/TR/SMIL3/smil-timing.html#Timing-ClockValueSyntax |
| 1680 | + * (probably have to use a Time object to fully support the smil spec |
| 1681 | + */ |
| 1682 | +function smilParseTime(time_str){ |
| 1683 | + return parseInt(time_str.replace('s', '')); |
| 1684 | +} |
1648 | 1685 | /*************************** |
1649 | 1686 | * end SMIL specific code |
1650 | 1687 | ***************************/ |