Index: branches/MwEmbedStandAlone/modules/SmilPlayer/mw.SmilBody.js |
— | — | @@ -378,8 +378,28 @@ |
379 | 379 | } |
380 | 380 | return $node.data('computedDuration'); |
381 | 381 | }, |
382 | | - |
383 | 382 | /** |
| 383 | + * Get the asset duration for a clip |
| 384 | + * @param {element} $node the smil clip that we want to get duration for |
| 385 | + * @param {function} callback Function to be called once asset duration is known. |
| 386 | + */ |
| 387 | + getClipAssetDuration: function( $node, callback ){ |
| 388 | + this.smil.getBuffer().loadElement( $node ); |
| 389 | + // xxx check if the type is "video or audio" else nothing to return |
| 390 | + |
| 391 | + var vid = $j( '#' + this.smil.getAssetId( $node ) ).get(0); |
| 392 | + if( vid.duration ){ |
| 393 | + callback( vid.duration ); |
| 394 | + } |
| 395 | + // Duration ready callback: |
| 396 | + var durationReady = function(){ |
| 397 | + callback( vid.duration ); |
| 398 | + } |
| 399 | + // else setup a load biding |
| 400 | + vid.removeEventListener( "loadedmetadata", durationReady, true ); |
| 401 | + vid.addEventListener( "loadedmetadata", durationReady, true ); |
| 402 | + }, |
| 403 | + /** |
384 | 404 | * Maps a few smil tags to smil types |
385 | 405 | * |
386 | 406 | * http://www.w3.org/TR/2008/REC-SMIL3-20081201/smil-structure.html#edef-body |
Index: branches/MwEmbedStandAlone/modules/SmilPlayer/mw.SmilLayout.js |
— | — | @@ -113,7 +113,9 @@ |
114 | 114 | } |
115 | 115 | }, |
116 | 116 | |
117 | | - drawElementThumb: function( $target, $node, relativeTime ){ |
| 117 | + drawElementThumb: function( $target, $node, relativeTime ){ |
| 118 | + // parse the time incase it came in as human input |
| 119 | + relativeTime = this.smil.parseTime( relativeTime ); |
118 | 120 | switch ( this.smil.getRefType( $node )){ |
119 | 121 | case 'video': |
120 | 122 | this.getVideoCanvasThumb($target, $node, relativeTime ) |
— | — | @@ -137,31 +139,46 @@ |
138 | 140 | // draw an audio icon in the target |
139 | 141 | break; |
140 | 142 | } |
141 | | - }, |
| 143 | + }, |
| 144 | + |
142 | 145 | getVideoCanvasThumb: function($target, $node, relativeTime ){ |
143 | 146 | |
144 | | - var naturaSize = {}; |
145 | | - var drawElement = $j( '#' + this.smil.getAssetId( $node ) ).get(0); |
| 147 | + var naturaSize = {}; |
| 148 | + var drawElement = $j( '#' + this.smil.getAssetId( $node ) ).get(0); |
146 | 149 | |
147 | | - naturaSize.height = drawElement.videoHeight; |
148 | | - naturaSize.width = drawElement.videoWidth; |
149 | | - |
150 | | - // Draw the thumb via canvas grab |
151 | | - // NOTE I attempted to scale down the image using canvas but failed |
152 | | - // xxx should revisit thumb size issue: |
153 | | - $target.html( $j('<canvas />') |
154 | | - .attr({ |
155 | | - height: naturaSize.height, |
156 | | - width : naturaSize.width |
157 | | - }).css( { |
158 | | - height:'100%', |
159 | | - widht:'100%' |
160 | | - }) |
161 | | - .addClass("ui-corner-all") |
162 | | - ).find( 'canvas') |
163 | | - .get(0) |
164 | | - .getContext('2d') |
165 | | - .drawImage( drawElement, 0, 0) |
| 150 | + var drawFrame = function(){ |
| 151 | + naturaSize.height = drawElement.videoHeight; |
| 152 | + naturaSize.width = drawElement.videoWidth; |
| 153 | + |
| 154 | + // Draw the thumb via canvas grab |
| 155 | + // NOTE I attempted to scale down the image using canvas but failed |
| 156 | + // xxx should revisit thumb size issue: |
| 157 | + $target.html( $j('<canvas />') |
| 158 | + .attr({ |
| 159 | + height: naturaSize.height, |
| 160 | + width : naturaSize.width |
| 161 | + }).css( { |
| 162 | + height:'100%', |
| 163 | + widht:'100%' |
| 164 | + }) |
| 165 | + .addClass("ui-corner-all") |
| 166 | + ).find( 'canvas') |
| 167 | + .get(0) |
| 168 | + .getContext('2d') |
| 169 | + .drawImage( drawElement, 0, 0) |
| 170 | + } |
| 171 | + |
| 172 | + // check if relativeTime transform matches current absolute time then render directly: |
| 173 | + var drawTime = ( relativeTime + this.smil.parseTime( $j( $node ).attr('clipBegin') ) ); |
| 174 | + if( drawElement.currentTime == drawTime ){ |
| 175 | + mw.log("getVideoCanvasThumb: Draw time:" + drawTime + " matches video time drawFrame:" +drawElement.currentTime ); |
| 176 | + drawFrame(); |
| 177 | + } else { |
| 178 | + // check if we need to spawn a video copy for the draw request |
| 179 | + |
| 180 | + // no match do seek |
| 181 | + mw.log( "getVideoCanvasThumb: Draw time:" + drawTime + ' != ' + drawElement.currentTime ); |
| 182 | + } |
166 | 183 | }, |
167 | 184 | |
168 | 185 | /** |
Index: branches/MwEmbedStandAlone/modules/SmilPlayer/mw.SmilAnimate.js |
— | — | @@ -216,7 +216,7 @@ |
217 | 217 | * @param {Element} smilElement Smil video element to be transformed |
218 | 218 | * @param {time} animateTime Relative time to be transformed |
219 | 219 | */ |
220 | | - transformVideoForTime: function( smilElement, animateTime ){ |
| 220 | + transformVideoForTime: function( smilElement, animateTime, callback ){ |
221 | 221 | // Get the video element |
222 | 222 | var assetId = this.smil.getAssetId( smilElement ); |
223 | 223 | var vid = $j ( '#' + assetId ).get( 0 ); |
— | — | @@ -224,7 +224,7 @@ |
225 | 225 | var videoSeekTime = animateTime; |
226 | 226 | //Add the clipBegin if set |
227 | 227 | if( $j( smilElement ).attr( 'clipBegin') && |
228 | | - this.smil.parseTime( $j( smilElement ).attr( 'clipBegin') ) ) |
| 228 | + this.smil.parseTime( $j( smilElement ).attr( 'clipBegin') ) ) |
229 | 229 | { |
230 | 230 | videoSeekTime += this.smil.parseTime( $j( smilElement ).attr( 'clipBegin') ); |
231 | 231 | } |
— | — | @@ -233,7 +233,9 @@ |
234 | 234 | |
235 | 235 | // Register a buffer ready callback |
236 | 236 | this.smil.getBuffer().videoBufferSeek( smilElement, videoSeekTime, function() { |
237 | | - //mw.log( "transformVideoForTime:: seek complete "); |
| 237 | + //mw.log( "transformVideoForTime:: seek complete ") |
| 238 | + if( callback ) |
| 239 | + callback(); |
238 | 240 | }); |
239 | 241 | }, |
240 | 242 | |
Index: branches/MwEmbedStandAlone/modules/SmilPlayer/mw.style.SmilLayout.css |
— | — | @@ -4,4 +4,5 @@ |
5 | 5 | height : 100%; |
6 | 6 | top : 0px; |
7 | 7 | left : 0px; |
8 | | -} |
\ No newline at end of file |
| 8 | +} |
| 9 | + |
Index: branches/MwEmbedStandAlone/modules/SmilPlayer/mw.EmbedPlayerSmil.js |
— | — | @@ -17,14 +17,14 @@ |
18 | 18 | // Store the actual play time |
19 | 19 | smilPlayTime: 0, |
20 | 20 | |
21 | | - // Flag to register the player being embedd |
| 21 | + // Flag to register the player being embedded |
22 | 22 | smilPlayerEmbedded: false, |
23 | 23 | |
24 | 24 | // Store the pause time |
25 | 25 | smilPauseTime: 0, |
26 | 26 | |
27 | 27 | // Store a playback duration |
28 | | - smilsmilPlayEndTime: null, |
| 28 | + smilplaySegmentEndTime: null, |
29 | 29 | |
30 | 30 | // flag to register when video is paused to fill a buffer. |
31 | 31 | pausedForBuffer: false, |
— | — | @@ -85,13 +85,13 @@ |
86 | 86 | } |
87 | 87 | // Start seek |
88 | 88 | this.controlBuilder.onSeek(); |
89 | | - this.smilPlayTime = time; |
| 89 | + this.smilPlayTime = time; |
| 90 | + this.smilPauseTime = this.smilPlayTime; |
90 | 91 | var _this = this; |
91 | 92 | this.getSmil( function( smil ){ |
92 | 93 | smil.renderTime( time, function(){ |
93 | 94 | //mw.log( "setCurrentTime:: renderTime callback" ); |
94 | | - $j('#loadingSpinner_' + _this.id ).remove(); |
95 | | - |
| 95 | + $j('#loadingSpinner_' + _this.id ).remove(); |
96 | 96 | _this.monitor(); |
97 | 97 | if( callback ){ |
98 | 98 | callback(); |
— | — | @@ -99,6 +99,24 @@ |
100 | 100 | } ); |
101 | 101 | }); |
102 | 102 | }, |
| 103 | + /** |
| 104 | + * Issue a seeking request. |
| 105 | + * |
| 106 | + * @param {Float} percentage |
| 107 | + */ |
| 108 | + doSeek: function( percentage ) { |
| 109 | + mw.log( 'EmbedPlayerSmil::doSeek p: ' + percentage ); |
| 110 | + this.seeking = true; |
| 111 | + var _this = this; |
| 112 | + // Run the seeking hook |
| 113 | + |
| 114 | + $j( this.embedPlayer ).trigger( 'onSeek' ); |
| 115 | + this.setCurrentTime( percentage * this.getDuration(), function(){ |
| 116 | + mw.log("EmbedPlayerSmil:: seek done"); |
| 117 | + _this.seeking = false; |
| 118 | + _this.monitor(); |
| 119 | + }) |
| 120 | + }, |
103 | 121 | |
104 | 122 | /** |
105 | 123 | * Return the render target for output of smil html |
— | — | @@ -123,34 +141,31 @@ |
124 | 142 | }, |
125 | 143 | /** |
126 | 144 | * Smil play function |
127 | | - * @param {float=} smilPlayEndTime Optional duration to be played before pausing playback |
| 145 | + * @param {float=} playSegmentEndTime Optional duration to be played before pausing playback |
128 | 146 | */ |
129 | | - play: function( smilPlayEndTime ){ |
| 147 | + play: function( playSegmentEndTime ){ |
130 | 148 | var _this = this; |
131 | | - mw.log(" EmbedPlayerSmil::play " + _this.smilPlayTime ); |
| 149 | + mw.log(" EmbedPlayerSmil::play " + _this.smilPlayTime + ' to ' + playSegmentEndTime + ' pause time: ' + this.smilPauseTime ); |
132 | 150 | // Update the interface |
133 | 151 | this.parent_play(); |
134 | 152 | |
135 | | - // Update the smilPlayEndTime flag |
136 | | - if( ! smilPlayEndTime ){ |
137 | | - this.smilPlayEndTime = null; |
| 153 | + // Update the playSegmentEndTime flag |
| 154 | + if( ! playSegmentEndTime ){ |
| 155 | + this.playSegmentEndTime = null; |
138 | 156 | } else { |
139 | | - this.smilPlayEndTime = smilPlayEndTime; |
| 157 | + this.playSegmentEndTime = playSegmentEndTime; |
140 | 158 | } |
141 | 159 | |
142 | 160 | // Make sure this.smil is ready : |
143 | 161 | this.getSmil( function( smil ){ |
144 | 162 | // Start buffering the movie |
145 | 163 | _this.smil.startBuffer(); |
146 | | - |
147 | | - // Set start clock time: |
148 | | - _this.clockStartTime = new Date().getTime(); |
149 | | - |
150 | | - // Update the pause time: |
151 | | - _this.smilPauseTime = 0; |
152 | 164 | |
153 | 165 | // Sync with current smilPlayTime |
154 | | - _this.clockStartTime = _this.clockStartTime -( _this.smilPlayTime * 1000 ); |
| 166 | + _this.clockStartTime = new Date().getTime() -( _this.smilPlayTime * 1000 ); |
| 167 | + |
| 168 | + // Zero out the pause time: |
| 169 | + _this.smilPauseTime = 0; |
155 | 170 | |
156 | 171 | // Start up monitor: |
157 | 172 | _this.monitor(); |
— | — | @@ -180,7 +195,7 @@ |
181 | 196 | * Preserves the pause time across for timed playback |
182 | 197 | */ |
183 | 198 | pause: function() { |
184 | | - mw.log( 'EmbedPlayerSmil::pause at time' + this.smilPlayTime ); |
| 199 | + mw.log( 'EmbedPlayerSmil::pause at time:' + this.smilPlayTime ); |
185 | 200 | this.smilPauseTime = this.smilPlayTime; |
186 | 201 | |
187 | 202 | // Issue pause to smil engine |
— | — | @@ -204,9 +219,10 @@ |
205 | 220 | monitor: function(){ |
206 | 221 | // Get a local variable of the new target time: |
207 | 222 | |
208 | | - // Check if we reached smilPlayEndTime and pause playback |
209 | | - if( this.smilPlayEndTime && this.smilPlayTime >= this.smilPlayEndTime ) { |
210 | | - this.smilPlayEndTime= null; |
| 223 | + // Check if we reached playSegmentEndTime and pause playback |
| 224 | + if( this.playSegmentEndTime && this.smilPlayTime >= this.playSegmentEndTime ) { |
| 225 | + mw.log("monitor:: Reached playSegmentEndTime pause playback: " + this.playSegmentEndTime ); |
| 226 | + this.playSegmentEndTime= null; |
211 | 227 | this.pause(); |
212 | 228 | this.parent_monitor(); |
213 | 229 | return ; |
— | — | @@ -238,14 +254,17 @@ |
239 | 255 | if( !this.pausedForBuffer ){ |
240 | 256 | // Update playtime if not pausedForBuffer |
241 | 257 | this.smilPlayTime = this.smilPauseTime + ( ( new Date().getTime() - this.clockStartTime ) / 1000 ); |
242 | | - /*mw.log(" update smilPlayTime: " + this.smilPauseTime + " getTime: " + new Date().getTime() + |
| 258 | + /* |
| 259 | + mw.log(" update smilPlayTime: " + this.smilPauseTime + " getTime: " + new Date().getTime() + |
243 | 260 | ' - clockStartTime: ' + this.clockStartTime + ' = ' + |
244 | 261 | ( ( new Date().getTime() - this.clockStartTime ) / 1000 ) + |
245 | | - " \n time:" + this.smilPlayTime );*/ |
| 262 | + " \n time:" + this.smilPlayTime ); |
| 263 | + */ |
246 | 264 | } |
247 | 265 | |
248 | | - // Done with sync delay: |
| 266 | + // Reset the pausedForBuffer flag: |
249 | 267 | this.pausedForBuffer = false; |
| 268 | + |
250 | 269 | //mw.log( "Call animateTime: " + this.smilPlayTime); |
251 | 270 | // Issue an animate time request with monitorDelta |
252 | 271 | this.smil.animateTime( this.smilPlayTime, this.monitorRate ); |
Index: branches/MwEmbedStandAlone/modules/SequenceEdit/mw.SequenceEditTimeline.js |
— | — | @@ -348,7 +348,9 @@ |
349 | 349 | // Draw a clip thumb into the timeline clip target |
350 | 350 | drawClipThumb: function ( $node , relativeTime ){ |
351 | 351 | var _this = this; |
352 | | - var smil = this.sequenceEdit.getSmil(); |
| 352 | + var smil = this.sequenceEdit.getSmil(); |
| 353 | + |
| 354 | + |
353 | 355 | // Buffer the asset then render it into the layout target: |
354 | 356 | smil.getBuffer().canGrabRelativeTime( $node, relativeTime, function(){ |
355 | 357 | var $timelineClip = $j( '#' + _this.getTimelineClipId( $node ) ); |
— | — | @@ -408,13 +410,22 @@ |
409 | 411 | ) |
410 | 412 | // remove loader |
411 | 413 | .find('.loadingSpinner').remove(); |
412 | | - // Add thumb |
413 | | - smil.getLayout().drawElementThumb( |
414 | | - $j( '#' + _this.getTimelineClipId( $node ) ).find('.thumbTraget'), |
415 | | - $node, |
416 | | - relativeTime |
417 | | - ) |
418 | | - }) |
| 414 | + |
| 415 | + var $thumbTarget = $j( '#' + _this.getTimelineClipId( $node ) ).find('.thumbTraget'); |
| 416 | + |
| 417 | + // Check for a "poster" image use that temporarily while we wait for the video to seek and draw |
| 418 | + if( $node.attr('poster') ){ |
| 419 | + $thumbTarget.append( |
| 420 | + $j('<img />') |
| 421 | + .attr( 'src', smil.getAssetUrl( $node.attr('poster') ) ) |
| 422 | + .css('height', $thumbTarget.height() ) |
| 423 | + ) |
| 424 | + } |
| 425 | + |
| 426 | + // Add the seek, add to canvas and draw thumb request |
| 427 | + smil.getLayout().drawElementThumb( $thumbTarget, $node, relativeTime ); |
| 428 | + |
| 429 | + }) |
419 | 430 | }, |
420 | 431 | /** |
421 | 432 | * Gets an sequence track control interface |
Index: branches/MwEmbedStandAlone/modules/SequenceEdit/css/mw.style.SequenceEdit.css |
— | — | @@ -64,4 +64,12 @@ |
65 | 65 | border: 2px solid #F22; |
66 | 66 | } |
67 | 67 | |
| 68 | +.mwe-sequence-edit .trimStartThumb, .trimEndThumb { |
| 69 | + float : left; |
| 70 | + display:block; |
| 71 | + width : 80px; |
| 72 | + height : 60px; |
| 73 | + overflow: hidden; |
| 74 | + border: 2px solid #555; |
| 75 | +} |
68 | 76 | |
Index: branches/MwEmbedStandAlone/modules/SequenceEdit/mw.SequenceEditPlayer.js |
— | — | @@ -68,6 +68,7 @@ |
69 | 69 | var clipEndTime = startOffset + |
70 | 70 | this.sequenceEdit.getSmil().getBody().getClipDuration( smilClip ); |
71 | 71 | this.getEmbedPlayer().setCurrentTime( startOffset, function(){ |
| 72 | + mw.log("SequenceEditPlayer::Preview clip: " + startOffset + ' to ' + clipEndTime); |
72 | 73 | _this.getEmbedPlayer().play( clipEndTime ); |
73 | 74 | }) |
74 | 75 | }, |
Index: branches/MwEmbedStandAlone/modules/SequenceEdit/mw.SequenceEdit.js |
— | — | @@ -97,8 +97,7 @@ |
98 | 98 | */ |
99 | 99 | drawUI: function( ){ |
100 | 100 | var _this = this; |
101 | | - mw.log("SequenceEdit:: drawUI to: " + this.interfaceContainer + |
102 | | - ' ' + this.getContainer().length); |
| 101 | + mw.log( "SequenceEdit:: drawUI to: " + this.interfaceContainer + ' ' + this.getContainer().length ); |
103 | 102 | |
104 | 103 | // Add the ui layout |
105 | 104 | this.getContainer().html( |
Index: branches/MwEmbedStandAlone/modules/SequenceEdit/mw.SequenceEditTools.js |
— | — | @@ -46,10 +46,11 @@ |
47 | 47 | $j( smilClip ).attr( attributeName, mw.seconds2npt( seconds ) ); |
48 | 48 | // Update the clip duration : |
49 | 49 | _this.sequenceEdit.getEmbedPlayer().getDuration( true ); |
| 50 | + |
50 | 51 | // Seek to "this clip" |
51 | 52 | _this.sequenceEdit.getEmbedPlayer().setCurrentTime( |
52 | 53 | $j( smilClip ).data('startOffset') |
53 | | - ); |
| 54 | + ); |
54 | 55 | }, |
55 | 56 | getSmilVal : function( _this, smilClip, attributeName ){ |
56 | 57 | var smil = _this.sequenceEdit.getSmil(); |
— | — | @@ -69,16 +70,6 @@ |
70 | 71 | _this.sequenceEdit.getPlayer().previewClip( smilClip ); |
71 | 72 | } |
72 | 73 | }, |
73 | | - /*'apply' :{ |
74 | | - 'icon' : 'check', |
75 | | - 'title' : gM('mwe-sequenceedit-apply-changes'), |
76 | | - 'action': function( _this, smilClip, toolId){ |
77 | | - mw.log( "editActions:: changes already applied" ); |
78 | | - _this.sequenceEdit.getEditToolTarget().html( |
79 | | - _this.defaultText |
80 | | - ) |
81 | | - } |
82 | | - },*/ |
83 | 74 | 'cancel':{ |
84 | 75 | 'icon': 'close', |
85 | 76 | 'title' : gM('mwe-cancel'), |
— | — | @@ -86,17 +77,137 @@ |
87 | 78 | var tool = _this.tools[toolId]; |
88 | 79 | for( var i=0; i < tool.editableAttributes.length ; i++ ){ |
89 | 80 | var attributeName = tool.editableAttributes[i]; |
90 | | - var $editToolInput = $j('#' + _this.getEditToolId( toolId, attributeName ) ); |
| 81 | + var $editToolInput = $j('#' + _this.getEditToolId( toolId, attributeName ) ); |
91 | 82 | // Restore all original attribute values |
92 | | - smilClip.attr( attributeName, $editToolInput.data('initialValue') ); |
93 | | - // close / empty the toolWindow |
| 83 | + smilClip.attr( attributeName, $editToolInput.data('initialValue') ); |
94 | 84 | } |
| 85 | + |
| 86 | + // Update the clip duration : |
| 87 | + _this.sequenceEdit.getEmbedPlayer().getDuration( true ); |
| 88 | + |
| 89 | + // Update the embed player |
| 90 | + _this.sequenceEdit.getEmbedPlayer().setCurrentTime( |
| 91 | + $j( smilClip ).data('startOffset') |
| 92 | + ); |
| 93 | + |
| 94 | + // Close / empty the toolWindow |
95 | 95 | _this.sequenceEdit.getEditToolTarget().html( |
96 | 96 | _this.defaultText |
97 | 97 | ) |
98 | 98 | } |
99 | 99 | } |
100 | 100 | }, |
| 101 | + editWidgets: { |
| 102 | + 'trimTimeline':{ |
| 103 | + 'update': function( _this, target, smilClip ){ |
| 104 | + var smil = _this.sequenceEdit.getSmil(); |
| 105 | + // Update the preview thumbs |
| 106 | + var clipBeginTime = $j('#editTool_trim_clipBegin').val(); |
| 107 | + if( !clipBeginTime ){ |
| 108 | + $j(target).find('.trimStartThumb').hide(); |
| 109 | + } else { |
| 110 | + // Render a thumbnail for relative start time = 0 |
| 111 | + smil.getLayout().drawElementThumb( |
| 112 | + $j(target).find('.trimStartThumb'), |
| 113 | + smilClip, |
| 114 | + 0 |
| 115 | + ) |
| 116 | + } |
| 117 | + // Check the duration: |
| 118 | + var clipDur = $j('editTool_trim_dur').val(); |
| 119 | + if( clipDur ){ |
| 120 | + // Render a thumbnail for relative start time = 0 |
| 121 | + smil.getLayout().drawElementThumb( |
| 122 | + $j(target).find('.trimEndThumb'), |
| 123 | + smilClip, |
| 124 | + clipDur |
| 125 | + ); |
| 126 | + } |
| 127 | + |
| 128 | + mw.log( "editWidgets::trimTimeline:update:: " + clipBeginTime + ' dur: ' + clipDur); |
| 129 | + }, |
| 130 | + // Return the trimTimeline edit widget |
| 131 | + 'draw': function( _this, target, smilClip ){ |
| 132 | + var smil = _this.sequenceEdit.getSmil(); |
| 133 | + // For now just have a thumbnail and a slider |
| 134 | + $j(target).append( |
| 135 | + $j('<div />') |
| 136 | + .addClass( 'trimStartThumb ui-corner-all' ), |
| 137 | + $j('<div />') |
| 138 | + .addClass( 'trimEndThumb ui-corner-all' ), |
| 139 | + $j('<div />').addClass('ui-helper-clearfix') |
| 140 | + ) |
| 141 | + |
| 142 | + // Add a trim binding: |
| 143 | + $j('#editTool_trim_clipBegin,#editTool_trim_dur').change(function(){ |
| 144 | + _this.editWidgets.trimTimeline.update( _this, target, smilClip); |
| 145 | + }) |
| 146 | + // Update the thumbnails: |
| 147 | + _this.editWidgets.trimTimeline.update( _this, target, smilClip); |
| 148 | + |
| 149 | + // get the clip full duration to build out the timeline selector |
| 150 | + smil.getBody().getClipAssetDuration( smilClip, function( fullClipDuration ) { |
| 151 | + |
| 152 | + var sliderToTime = function( sliderval ){ |
| 153 | + return parseInt( fullClipDuration * ( sliderval / 1000 ) ); |
| 154 | + } |
| 155 | + var timeToSlider = function( time ){ |
| 156 | + return parseInt( ( time / fullClipDuration ) * 1000 ); |
| 157 | + } |
| 158 | + var startSlider = timeToSlider( smil.parseTime( $j('#editTool_trim_clipBegin').val() ) ); |
| 159 | + var sliderValues = [ |
| 160 | + startSlider, |
| 161 | + startSlider + timeToSlider( smil.parseTime( $j('#editTool_trim_dur').val() ) ) |
| 162 | + ]; |
| 163 | + // Return a trim tool binded to smilClip id update value events. |
| 164 | + $j(target).append( |
| 165 | + $j('<div />') |
| 166 | + .attr( 'id', _this.sequenceEdit.id + '_trimTimeline' ) |
| 167 | + .css({ |
| 168 | + 'width': '100%', |
| 169 | + 'margin': '5px' |
| 170 | + }) |
| 171 | + .slider({ |
| 172 | + range: true, |
| 173 | + min: 0, |
| 174 | + max: 1000, |
| 175 | + values: sliderValues, |
| 176 | + slide: function(event, ui) { |
| 177 | + mw.log( 'slider1: ' + ui.values[0] + ' - sldier two' + ui.values[1] + ' t: ' + sliderToTime( ui.values[0] ) + ' t2: ' + sliderToTime( ui.values[1]) ); |
| 178 | + $j('#editTool_trim_clipBegin').val( |
| 179 | + mw.seconds2npt( sliderToTime( ui.values[0] ), true ) |
| 180 | + ); |
| 181 | + $j('#editTool_trim_dur').val( |
| 182 | + mw.seconds2npt( sliderToTime( ui.values[1] ), true ) |
| 183 | + ); |
| 184 | + }, |
| 185 | + change: function( event, ui ) { |
| 186 | + if( sliderValues[0] != ui.values[0] ){ |
| 187 | + var attributeChanged = 'clipBegin'; |
| 188 | + sliderIndex = 0; |
| 189 | + } else { |
| 190 | + var attributeChanged = 'dur'; |
| 191 | + sliderIndex = 1; |
| 192 | + } |
| 193 | + var attributeValue = sliderToTime( ui.values[ sliderIndex ] ) |
| 194 | + sliderValues[ sliderIndex ] = ui.values[ sliderIndex ]; |
| 195 | + |
| 196 | + // update start and end time: |
| 197 | + _this.editableTypes['time'].update( _this, smilClip, attributeChanged, attributeValue) |
| 198 | + |
| 199 | + // update the widget |
| 200 | + _this.editWidgets.trimTimeline.update( _this, target, smilClip); |
| 201 | + } |
| 202 | + }) |
| 203 | + ); |
| 204 | + }); |
| 205 | + // On resize event |
| 206 | + |
| 207 | + // Fill in timeline images |
| 208 | + |
| 209 | + } |
| 210 | + } |
| 211 | + }, |
101 | 212 | getEditToolId: function( toolId, attributeName){ |
102 | 213 | return 'editTool_' + toolId + '_' + attributeName; |
103 | 214 | }, |
— | — | @@ -107,10 +218,10 @@ |
108 | 219 | // get the toolId based on what "ref type" smilClip is: |
109 | 220 | switch( this.sequenceEdit.getSmil().getRefType( smilClip ) ){ |
110 | 221 | case 'video': |
111 | | - toolId = 'trim' |
| 222 | + toolId = 'trim'; |
112 | 223 | break; |
113 | 224 | default: |
114 | | - toolId = 'duration' |
| 225 | + toolId = 'duration'; |
115 | 226 | break; |
116 | 227 | } |
117 | 228 | |
— | — | @@ -121,19 +232,14 @@ |
122 | 233 | return ; |
123 | 234 | } |
124 | 235 | var tool = this.tools[ toolId ]; |
| 236 | + |
125 | 237 | // Append the title: |
126 | 238 | $target.empty().append( |
127 | 239 | $j('<h3 />' ).append( |
128 | 240 | tool.title |
129 | 241 | ) |
130 | 242 | ); |
131 | | - |
132 | | - // Build out widgets |
133 | | - //if( tool.editWidgets ){ |
134 | | - //for( var i =0 ; i < tool.editWidgets.length ; i ++ ){ |
135 | | - //} |
136 | | - //} |
137 | | - |
| 243 | + |
138 | 244 | // Build out the attribute list: |
139 | 245 | for( var i=0; i < tool.editableAttributes.length ; i++ ){ |
140 | 246 | attributeName = tool.editableAttributes[i]; |
— | — | @@ -141,9 +247,34 @@ |
142 | 248 | this.getEditableAttribute( smilClip, toolId, attributeName ) |
143 | 249 | ); |
144 | 250 | } |
| 251 | + |
145 | 252 | // output a float divider: |
146 | 253 | $target.append( $j('<div />').addClass('ui-helper-clearfix') ); |
147 | 254 | |
| 255 | + // Build out widgets |
| 256 | + if( tool.editWidgets ){ |
| 257 | + for( var i =0 ; i < tool.editWidgets.length ; i ++ ){ |
| 258 | + var editWidgetId = tool.editWidgets[i]; |
| 259 | + if( ! this.editWidgets[editWidgetId] ){ |
| 260 | + mw.log("Error: not recogonized widget: " + editWidgetId); |
| 261 | + continue; |
| 262 | + } |
| 263 | + // Append a target for the edit widget: |
| 264 | + $target.append( |
| 265 | + $j('<div />') |
| 266 | + .attr('id', 'editWidgets_' + editWidgetId) |
| 267 | + ); |
| 268 | + // Draw the binded widget: |
| 269 | + this.editWidgets[editWidgetId].draw( |
| 270 | + this, |
| 271 | + $j( '#editWidgets_' + editWidgetId ), |
| 272 | + smilClip |
| 273 | + ) |
| 274 | + // Output a float divider: |
| 275 | + $target.append( $j('<div />').addClass( 'ui-helper-clearfix' ) ); |
| 276 | + } |
| 277 | + } |
| 278 | + |
148 | 279 | // Build out edit Actions buttons |
149 | 280 | for( var i=0; i < tool.editActions.length ; i++){ |
150 | 281 | var editActionId = tool.editActions[i]; |
— | — | @@ -178,14 +309,14 @@ |
179 | 310 | mw.log("Error: editableAttributes : " + attributeName + ' not found'); |
180 | 311 | return; |
181 | 312 | } |
182 | | - var _this = this; |
| 313 | + var _this = this; |
183 | 314 | var editAttribute = this.editableAttributes[ attributeName ]; |
184 | 315 | var editType = editAttribute.type; |
185 | 316 | |
186 | 317 | var initialValue = _this.editableTypes[ editType ].getSmilVal( |
187 | | - _this, |
188 | | - smilClip, |
189 | | - attributeName |
| 318 | + _this, |
| 319 | + smilClip, |
| 320 | + attributeName |
190 | 321 | ); |
191 | 322 | return $j( '<div />' ) |
192 | 323 | .css({ |
— | — | @@ -196,15 +327,16 @@ |
197 | 328 | 'padding' : '2px', |
198 | 329 | 'margin' : '5px' |
199 | 330 | }) |
| 331 | + .addClass('ui-corner-all') |
200 | 332 | .append( |
201 | 333 | $j('<span />') |
202 | 334 | .css('margin', '5px') |
203 | 335 | .text( editAttribute.title ), |
204 | 336 | |
205 | | - $j('<input />') |
| 337 | + $j('<input />') |
206 | 338 | .attr( { |
207 | 339 | 'id' : _this.getEditToolId( toolId, attributeName), |
208 | | - 'size': 5 |
| 340 | + 'size': 6 |
209 | 341 | }) |
210 | 342 | .data('initialValue', initialValue ) |
211 | 343 | .sequenceEditInput( _this.sequenceEdit ) |
— | — | @@ -216,41 +348,11 @@ |
217 | 349 | smilClip, |
218 | 350 | attributeName, |
219 | 351 | $j( this ).val() |
220 | | - ); |
| 352 | + ); |
| 353 | + // widgets can bind directly to this change action. |
221 | 354 | }) |
222 | 355 | ); |
223 | | - }, |
224 | | - |
225 | | - /*drawTrimClipTool: function( clipNode ){ |
226 | | - $target = this.sequenceEdit.getToolTarget(); |
227 | | - $target.empty().append( |
228 | | - $j('<div />') |
229 | | - .addClass("toolTarget") |
230 | | - .append( |
231 | | - $j('<h3 />').text( |
232 | | - |
233 | | - ), |
234 | | - // Width of the container images thumbs set-in-out |
235 | | - |
236 | | - $j('<div />') |
237 | | - .addClass("ui-helper-clearfix"), |
238 | | - // Start time and end time text: |
239 | | - $j( '<div />' ) |
240 | | - .css({ |
241 | | - 'float': 'left', |
242 | | - 'width': '200px', |
243 | | - 'background-color': '#AAA' |
244 | | - }) |
245 | | - .append( |
246 | | - $j('<span />') |
247 | | - .text( gM('mwe-sequenceedit-start-time') ), |
248 | | - $j('<input />') |
249 | | - .attr('size', 5) |
250 | | - ) |
251 | | - ) |
252 | | - ) |
253 | | - ) |
254 | | - }*/ |
| 356 | + } |
255 | 357 | } |
256 | 358 | |
257 | 359 | } )( window.mw ); |
\ No newline at end of file |