diff --git a/css/editors.less b/css/editors.less index 8245a72a0..9b060ff3e 100644 --- a/css/editors.less +++ b/css/editors.less @@ -592,6 +592,20 @@ textarea { margin: 0; padding: 10px 20px; border-bottom: 1px solid @baseLightOutline; + &.media-properties { + font-size: 11px; + background: darken( @baseLight, 5% ); + .clearfix(); + } +} + +.source-container { + display: none; + margin-bottom: 5px; + &.loaded { + display: block; + } + .clearfix(); } .butter-form .switch { diff --git a/css/media-editor.less b/css/media-editor.less index e8907b98e..972348ff0 100644 --- a/css/media-editor.less +++ b/css/media-editor.less @@ -132,112 +132,6 @@ border-radius: 2px; } - .media-gallery-item { - position: relative; - padding: 10px 20px; - height: 60px; - border: 0 solid @baseLightOutline; - border-top-width: 1px; - background-color: @baseLight; - font-size: 11px; - .transition( background-color 0.2s linear ); - &:first-child { - margin-top: -1px; - } - &.new { - background: @green; - color: #FFF; - > .delete-btn { - display: none; - } - > .mg-meta-data { - > .mg-type { - color: #FFF; - } - } - } - } - - .mg-thumbnail { - position: relative; - overflow: hidden; - float: left; - margin-right: 10px; - border: 1px solid @baseLightOutline; - > img, video { - display: block; - width: 80px; - height: 60px; - } - &:hover { - border-color: @green; - } - &:hover:before { - content: ""; - display: block; - position: absolute; - top: 0; - left: 0; - height: 100%; - width: 100%; - background: fade( @green, 60% ); - } - &:hover:after { - content: ""; - height: 14px; - width: 14px; - position: absolute; - top: 50%; - margin-top: -7px; - margin-left: -7px; - left: 50%; - background: url( "../resources/icons/glyphiconshalflings-white.png" ) -408px -96px no-repeat; - } - } - .mg-html5 .mg-thumbnail { - > video { - height: auto; - } - background: url( "../resources/icons/media.png" ) center no-repeat; - } - - .mg-meta-data { - float: left; - width: 190px; - height: 60px; - line-height: 1.2em; - } - .mg-title { - overflow: hidden; - font-weight: 700; - max-height: 3.6em; // 3 lines - } - .mg-type { - &:after { - content: " clip"; - text-transform: lowercase; - } - color: #999; - text-transform: capitalize; - } - .mg-error { - color: #FF0000; - } - .mg-duration { - &:before { - content: "Duration: " - } - } - .mg-delete-btn { - position: absolute; - top: 10px; - right: 5px; - opacity: 0.5; - &:hover { - opacity: 1; - } - } - .add-media-input { height: 50px; } @@ -261,3 +155,112 @@ } } + +.media-gallery-item { + position: relative; + padding: 10px 20px; + height: 60px; + border: 0 solid @baseLightOutline; + border-top-width: 1px; + background-color: @baseLight; + font-size: 11px; + .transition( background-color 0.2s linear ); + &:first-child { + margin-top: -1px; + } + &.new { + background: @green; + color: #FFF; + > .delete-btn { + display: none; + } + > .mg-meta-data { + > .mg-type { + color: #FFF; + } + } + } +} + +.mg-thumbnail { + position: relative; + overflow: hidden; + float: left; + margin-right: 10px; + border: 1px solid @baseLightOutline; + width: 80px; + height: 60px; + > img, video { + display: block; + width: 80px; + height: 60px; + } + &:hover { + border-color: @green; + } + &:hover:before { + content: ""; + display: block; + position: absolute; + top: 0; + left: 0; + height: 100%; + width: 100%; + background: fade( @green, 60% ); + } + &:hover:after { + content: ""; + height: 14px; + width: 14px; + position: absolute; + top: 50%; + margin-top: -7px; + margin-left: -7px; + left: 50%; + background: url( "../resources/icons/glyphiconshalflings-white.png" ) -408px -96px no-repeat; + } +} +.mg-html5 .mg-thumbnail { + > video { + height: auto; + } + background: url( "../resources/icons/media.png" ) center no-repeat; +} + +.mg-meta-data { + float: left; + width: 190px; + height: 60px; + line-height: 1.2em; +} +.mg-title { + overflow: hidden; + font-weight: 700; + max-height: 3.6em; // 3 lines +} +.mg-type { + &:after { + content: " clip"; + text-transform: lowercase; + } + color: #999; + text-transform: capitalize; +} +.mg-error { + color: #FF0000; +} +.mg-duration { + &:before { + content: "Duration: " + } +} +.mg-delete-btn { + position: absolute; + top: 10px; + right: 5px; + opacity: 0.5; + &:hover { + opacity: 1; + } +} + diff --git a/src/editor/sequencer-editor.js b/src/editor/sequencer-editor.js index 80927c205..10d7ee257 100644 --- a/src/editor/sequencer-editor.js +++ b/src/editor/sequencer-editor.js @@ -19,371 +19,413 @@ define( [ "util/mediatypes", "editor/editor", "util/time", var _fields = {}; - // Creates an "off-on" toggler - function Toggler( el, property, isReverse, customUpdateUI ) { - var hiddenInput = el.querySelector( "input" ); - - function updateUI() { - var val = _popcornOptions[ property ]; - if ( val && !isReverse || !val && isReverse ) { - el.classList.add( "on" ); - } else { - el.classList.remove( "on" ); - } - hiddenInput.checked = val; - if ( customUpdateUI ) { - customUpdateUI( el ); - } + // Creates an "off-on" toggler + function Toggler( el, property, isReverse, customUpdateUI ) { + var hiddenInput = el.querySelector( "input" ); + + function updateUI() { + var val = _popcornOptions[ property ]; + if ( val && !isReverse || !val && isReverse ) { + el.classList.add( "on" ); + } else { + el.classList.remove( "on" ); } - - function updateTrackEvent( val ) { - var properties = {}; - properties[ property ] = val; - updateUI( val ); - _this.updateTrackEventSafe( _trackEvent, properties ); + hiddenInput.checked = val; + if ( customUpdateUI ) { + customUpdateUI( el ); } + } - el.addEventListener( "click", function() { - // Toggle the state - updateTrackEvent( !hiddenInput.checked ); - }, false ); - - updateUI( _popcornOptions[ property ] ); + function updateTrackEvent( val ) { + var properties = {}; + properties[ property ] = val; + updateUI( val ); + _this.updateTrackEventSafe( _trackEvent, properties ); + } - return { - el: el, - updateUI: updateUI, - }; + el.addEventListener( "click", function() { + // Toggle the state + updateTrackEvent( !hiddenInput.checked ); + }, false ); - } + updateUI( _popcornOptions[ property ] ); - // Creates a standard input - function Input( el, property, callback, customUpdate ) { - _this.attachInputChangeHandler( el, _trackEvent, property, callback ); + return { + el: el, + updateUI: updateUI, + }; - function updateUI() { - var val = _popcornOptions[ property ]; - el.value = val; - if ( customUpdate ) { - customUpdate( el ); - } - } + } - updateUI( _popcornOptions[ property ] ); + // Creates a standard input + function Input( el, property, callback, customUpdate ) { + _this.attachInputChangeHandler( el, _trackEvent, property, callback ); - return { - el: el, - updateUI: updateUI - }; + function updateUI() { + var val = _popcornOptions[ property ]; + el.value = val; + if ( customUpdate ) { + customUpdate( el ); + } } - function StartEnd( el ) { - var container = _this.createStartEndInputs( _trackEvent, _this.updateTrackEventSafe ), - startEl = container.querySelector( "[data-manifest-key=start]" ), - endEl = container.querySelector( "[data-manifest-key=end]" ); + updateUI( _popcornOptions[ property ] ); - el.appendChild( container ); + return { + el: el, + updateUI: updateUI + }; + } - function updateUI() { - startEl.value = Time.toTimecode( _popcornOptions.start ); - endEl.value = Time.toTimecode( _popcornOptions.end ); - } + function StartEnd( el ) { + var container = _this.createStartEndInputs( _trackEvent, _this.updateTrackEventSafe ), + startEl = container.querySelector( "[data-manifest-key=start]" ), + endEl = container.querySelector( "[data-manifest-key=end]" ); - updateUI(); + el.appendChild( container ); - return { - el: el, - updateUI: updateUI - }; + function updateUI() { + startEl.value = Time.toTimecode( _popcornOptions.start ); + endEl.value = Time.toTimecode( _popcornOptions.end ); } - function Slider( el, property ) { - var scrubber = el.querySelector( ".butter-slider-scrubber" ), - MAX_VAL = el.getAttribute( "data-max" ) || 100; + updateUI(); - function toReal( n ) { - var maxUI = el.offsetWidth; - return ( n / maxUI ) * MAX_VAL; - } + return { + el: el, + updateUI: updateUI + }; + } - function toUI( n ) { - var maxUI = el.offsetWidth; - return ( n / MAX_VAL ) * maxUI; - } + function Slider( el, property ) { + var scrubber = el.querySelector( ".butter-slider-scrubber" ), + MAX_VAL = el.getAttribute( "data-max" ) || 100; - function normalize( n ) { - if ( n < 0 ) { - n = 0; - } else if ( n > MAX_VAL ) { - n = MAX_VAL; - } - return n; - } + function toReal( n ) { + var maxUI = el.offsetWidth; + return ( n / maxUI ) * MAX_VAL; + } - function updateUI() { - scrubber.style.left = toUI( _popcornOptions[ property ] ) + "px"; - } + function toUI( n ) { + var maxUI = el.offsetWidth; + return ( n / MAX_VAL ) * maxUI; + } - function updateTrackEvent( options) { - _this.updateTrackEventSafe( _trackEvent, options ); - updateUI(); + function normalize( n ) { + if ( n < 0 ) { + n = 0; + } else if ( n > MAX_VAL ) { + n = MAX_VAL; } + return n; + } - var firstX, - startLeft; + function updateUI() { + scrubber.style.left = toUI( _popcornOptions[ property ] ) + "px"; + } - function onSlideStop() { - document.removeEventListener( "mousemove", onSliding, false ); - document.removeEventListener( "mouseup", onSlideStop, false ); - } + function updateTrackEvent( options) { + _this.updateTrackEventSafe( _trackEvent, options ); + updateUI(); + } - function onSliding( e ) { - var left = startLeft + e.clientX - firstX, - properties = {}; - properties[ property ] = normalize( toReal( left ) ); - updateTrackEvent( properties ); - } + var firstX, + startLeft; - function onSlideStart( e ) { - e.preventDefault(); - firstX = e.clientX; - startLeft = scrubber.offsetLeft; - document.addEventListener( "mousemove", onSliding, false ); - document.addEventListener( "mouseup", onSlideStop, false ); - } + function onSlideStop() { + document.removeEventListener( "mousemove", onSliding, false ); + document.removeEventListener( "mouseup", onSlideStop, false ); + } - scrubber.addEventListener( "mousedown", onSlideStart, false ); - updateUI(); + function onSliding( e ) { + var left = startLeft + e.clientX - firstX, + properties = {}; + properties[ property ] = normalize( toReal( left ) ); + updateTrackEvent( properties ); } - // Our custom trimmer thingy - function Trimmer( el ) { - - var MIN_VISUAL_WIDTH = 5; - - var rightHandle = el.querySelector( ".trimmer-resizable-e" ), - leftHandle = el.querySelector( ".trimmer-resizable-w" ), - outInput = _rootElement.querySelector( ".trimmer-input-right" ), - inInput = _rootElement.querySelector( ".trimmer-input-left" ), - clipSection = el.querySelector( ".clip-section" ), - clipEndLable = el.querySelector( ".clip-end" ); - - var firstX, - startLeft, - startWidth, - activeHandle, - updateOptions = {}; - - // Converting px <=> time, normalizing - function positionToTime( pos ) { - var max1 = _popcornOptions.duration, - max2 = el.offsetWidth; - return ( pos / max2 ) * max1; - } + function onSlideStart( e ) { + e.preventDefault(); + firstX = e.clientX; + startLeft = scrubber.offsetLeft; + document.addEventListener( "mousemove", onSliding, false ); + document.addEventListener( "mouseup", onSlideStop, false ); + } - function timeToPosition( time ) { - var max1 = _popcornOptions.duration, - max2 = el.offsetWidth; - return ( time / max1 ) * max2; - } + scrubber.addEventListener( "mousedown", onSlideStart, false ); + updateUI(); + } - // Updating functions - function updateUI( options ) { - options = options || _popcornOptions; + // Our custom trimmer thingy + function Trimmer( el ) { - var start = ( options.start || options.start === 0 ) && options.start || _popcornOptions.start, - end = options.end || ( options.end || options.end === 0 ) && options.end || _popcornOptions.end, - from = options.from || ( options.from || options.from === 0 ) && options.from || _popcornOptions.from; + var MIN_VISUAL_WIDTH = 5; - // Adjust UI to account for very small durations - if ( timeToPosition( end - start ) < MIN_VISUAL_WIDTH ) { - clipSection.classList.add( "small" ); - } else { - clipSection.classList.remove( "small" ); - } + var rightHandle = el.querySelector( ".trimmer-resizable-e" ), + leftHandle = el.querySelector( ".trimmer-resizable-w" ), + outInput = _rootElement.querySelector( ".trimmer-input-right" ), + inInput = _rootElement.querySelector( ".trimmer-input-left" ), + clipSection = el.querySelector( ".clip-section" ), + clipEndLable = el.querySelector( ".clip-end" ); - if ( options.from ) { - clipSection.style.left = timeToPosition( from ) + "px"; - inInput.value = Time.toTimecode( from ); - outInput.value = Time.toTimecode( from + end - start ); - } + var firstX, + startLeft, + startWidth, + activeHandle, + updateOptions = {}; - if ( options.end || options.start ) { - clipSection.style.width = timeToPosition( end - start ) + "px"; - outInput.value = Time.toTimecode( from + end - start ); - } + // Converting px <=> time, normalizing + function positionToTime( pos ) { + var max1 = _popcornOptions.duration, + max2 = el.offsetWidth; + return ( pos / max2 ) * max1; + } - if ( options.duration ) { - clipEndLable.innerHTML = Time.toTimecode( options.duration ); - } + function timeToPosition( time ) { + var max1 = _popcornOptions.duration, + max2 = el.offsetWidth; + return ( time / max1 ) * max2; + } + // Updating functions + function updateUI( options ) { + options = options || _popcornOptions; + + var start = ( options.start || options.start === 0 ) && options.start || _popcornOptions.start, + end = options.end || ( options.end || options.end === 0 ) && options.end || _popcornOptions.end, + from = options.from || ( options.from || options.from === 0 ) && options.from || _popcornOptions.from; + + // Adjust UI to account for very small durations + if ( timeToPosition( end - start ) < MIN_VISUAL_WIDTH ) { + clipSection.classList.add( "small" ); + } else { + clipSection.classList.remove( "small" ); } - function updateEndAfterExpand() { - var track = _trackEvent.track; - track.removeTrackEvent( _trackEvent ); - track.addTrackEvent( _trackEvent ); - _this.updateTrackEventSafe( _trackEvent, updateOptions ); - _butter.unlisten( "mediaready", updateEndAfterExpand ); + if ( options.from ) { + clipSection.style.left = timeToPosition( from ) + "px"; + inInput.value = Time.toTimecode( from ); + outInput.value = Time.toTimecode( from + end - start ); + } + + if ( options.end || options.start ) { + clipSection.style.width = timeToPosition( end - start ) + "px"; + outInput.value = Time.toTimecode( from + end - start ); + } + + if ( options.duration ) { + clipEndLable.innerHTML = Time.toTimecode( options.duration ); + } + + } + + function updateEndAfterExpand() { + var track = _trackEvent.track; + track.removeTrackEvent( _trackEvent ); + track.addTrackEvent( _trackEvent ); + _this.updateTrackEventSafe( _trackEvent, updateOptions ); + _butter.unlisten( "mediaready", updateEndAfterExpand ); + updateOptions = {}; + updateUI(); + } + + function updateTrackEvent( options ) { + // If the end time is greater than the duration of the video, expand it to fit. + // We have to set an event listener on "mediaready" to update the trackevent after the base duration has been changed + if ( options.end && options.end > _butter.duration ) { + _butter.currentMedia.url = "#t=," + options.end; + _butter.listen( "mediaready", updateEndAfterExpand ); + } else { + _this.updateTrackEventSafe( _trackEvent, options ); updateOptions = {}; updateUI(); } + } - function updateTrackEvent( options ) { - // If the end time is greater than the duration of the video, expand it to fit. - // We have to set an event listener on "mediaready" to update the trackevent after the base duration has been changed - if ( options.end && options.end > _butter.duration ) { - _butter.currentMedia.url = "#t=," + options.end; - _butter.listen( "mediaready", updateEndAfterExpand ); - } else { - _this.updateTrackEventSafe( _trackEvent, options ); - updateOptions = {}; - updateUI(); - } + function onResizeStop() { + var accuracy, + start = updateOptions.start || _popcornOptions.start, + end = updateOptions.end || _popcornOptions.end; + + el.classList.remove( "editing" ); + + if ( activeHandle === "left" ) { + accuracy = start * Math.pow( 10, Time.timeAccuracy - 1 ); + butter.currentTime = start === 0 ? start : Math.ceil( start * accuracy ) / accuracy; + } else if ( activeHandle === "right" ) { + accuracy = end * Math.pow( 10, Time.timeAccuracy - 1 ); + butter.currentTime = Math.floor( end * accuracy ) / accuracy; } - function onResizeStop() { - var accuracy, - start = updateOptions.start || _popcornOptions.start, - end = updateOptions.end || _popcornOptions.end; + updateTrackEvent( updateOptions ); + activeHandle = ""; - el.classList.remove( "editing" ); + document.removeEventListener( "mousemove", onResizingRight, false ); + document.removeEventListener( "mousemove", onResizingLeft, false ); + document.removeEventListener( "mouseup", onResizeStop, false ); + } - if ( activeHandle === "left" ) { - accuracy = start * Math.pow( 10, Time.timeAccuracy - 1 ); - butter.currentTime = start === 0 ? start : Math.ceil( start * accuracy ) / accuracy; - } else if ( activeHandle === "right" ) { - accuracy = end * Math.pow( 10, Time.timeAccuracy - 1 ); - butter.currentTime = Math.floor( end * accuracy ) / accuracy; - } - updateTrackEvent( updateOptions ); - activeHandle = ""; + function onResizingLeft( e ) { + e.preventDefault(); + var left = startLeft + e.clientX - firstX, + width = startWidth - ( e.clientX - firstX ); - document.removeEventListener( "mousemove", onResizingRight, false ); - document.removeEventListener( "mousemove", onResizingLeft, false ); - document.removeEventListener( "mouseup", onResizeStop, false ); + if ( left < 0 || width < 0 ) { + return; } + updateOptions.end = _popcornOptions.start + positionToTime( width ); + updateOptions.from = positionToTime( left ); - function onResizingLeft( e ) { - e.preventDefault(); - var left = startLeft + e.clientX - firstX, - width = startWidth - ( e.clientX - firstX ); - - if ( left < 0 || width < 0 ) { - return; - } + updateUI({ + from: updateOptions.from, + end: updateOptions.end + }); - updateOptions.end = _popcornOptions.start + positionToTime( width ); - updateOptions.from = positionToTime( left ); + } - updateUI({ - from: updateOptions.from, - end: updateOptions.end - }); + function onResizingRight( e ) { + e.preventDefault(); + var left = clipSection.offsetLeft, + width = startWidth + e.clientX - firstX; + if ( left + width > el.offsetWidth || width < 0 ) { + return; } - function onResizingRight( e ) { - e.preventDefault(); - var left = clipSection.offsetLeft, - width = startWidth + e.clientX - firstX; + updateOptions.end = _popcornOptions.start + positionToTime( width ); + updateUI({ + end: updateOptions.end + }); - if ( left + width > el.offsetWidth || width < 0 ) { - return; - } + } - updateOptions.end = _popcornOptions.start + positionToTime( width ); - updateUI({ - end: updateOptions.end - }); + function onResizeStart( e ) { + e.preventDefault(); // Prevent selection + el.classList.add( "editing" ); + firstX = e.clientX; + startLeft = clipSection.offsetLeft; + startWidth = clipSection.offsetWidth; + + if ( this === rightHandle ) { + document.addEventListener( "mousemove", onResizingRight, false ); + activeHandle = "right"; + } else if ( this === leftHandle ) { + activeHandle = "left"; + document.addEventListener( "mousemove", onResizingLeft, false ); } + document.addEventListener( "mouseup", onResizeStop, false ); + } - function onResizeStart( e ) { - e.preventDefault(); // Prevent selection - el.classList.add( "editing" ); - firstX = e.clientX; - startLeft = clipSection.offsetLeft; - startWidth = clipSection.offsetWidth; + function onDragStop() { + el.classList.remove( "editing" ); + updateTrackEvent( updateOptions ); + document.removeEventListener( "mouseup", onDragStop, false ); + document.removeEventListener( "mousemove", onDragging, false ); + } - if ( this === rightHandle ) { - document.addEventListener( "mousemove", onResizingRight, false ); - activeHandle = "right"; - } else if ( this === leftHandle ) { - activeHandle = "left"; - document.addEventListener( "mousemove", onResizingLeft, false ); - } - document.addEventListener( "mouseup", onResizeStop, false ); + function onDragging( e ) { + e.preventDefault(); // Prevent selection + var left = startLeft + e.clientX - firstX, + width = clipSection.offsetWidth; + + if ( left < 0 || ( left + width ) > el.offsetWidth ) { + return; } + updateOptions.from = positionToTime( left ); + updateUI({ + from: updateOptions.from + }); + } - function onDragStop() { - el.classList.remove( "editing" ); - updateTrackEvent( updateOptions ); - document.removeEventListener( "mouseup", onDragStop, false ); - document.removeEventListener( "mousemove", onDragging, false ); + function onDragStart( e ) { + e.preventDefault(); + if ( e.target !== clipSection ) { + // We are resizing, not dragging. + return; } - function onDragging( e ) { - e.preventDefault(); // Prevent selection - var left = startLeft + e.clientX - firstX, - width = clipSection.offsetWidth; + el.classList.add( "editing" ); - if ( left < 0 || ( left + width ) > el.offsetWidth ) { - return; - } + firstX = e.clientX; + startLeft = clipSection.offsetLeft; + startWidth = clipSection.offsetWidth; + document.addEventListener( "mousemove", onDragging, false ); + document.addEventListener( "mouseup", onDragStop, false ); + } - updateOptions.from = positionToTime( left ); - updateUI({ - from: updateOptions.from - }); - } + function onRightInputChange() { + var val = Time.toSeconds( this.value ); + updateOptions.end = _popcornOptions.start + val - _popcornOptions.from; + updateTrackEvent( updateOptions ); + } - function onDragStart( e ) { - e.preventDefault(); - if ( e.target !== clipSection ) { - // We are resizing, not dragging. - return; - } + function onLeftInputChange() { + var val = Time.toSeconds( this.value ); + updateOptions.from = val; + updateOptions.end = _popcornOptions.end + ( _popcornOptions.from - val ); + updateTrackEvent( updateOptions ); + } - el.classList.add( "editing" ); + // Setup + outInput.addEventListener( "change", onRightInputChange, false ); + inInput.addEventListener( "change", onLeftInputChange, false ); + rightHandle.addEventListener( "mousedown", onResizeStart, false ); + leftHandle.addEventListener( "mousedown", onResizeStart, false ); + clipSection.addEventListener( "mousedown", onDragStart, false ); + updateUI(); + + return { + el: el, + updateUI: updateUI + }; + } - firstX = e.clientX; - startLeft = clipSection.offsetLeft; - startWidth = clipSection.offsetWidth; - document.addEventListener( "mousemove", onDragging, false ); - document.addEventListener( "mouseup", onDragStop, false ); + function MetadataBox( el ) { + function updateUI() { + if ( !Array.isArray( _popcornOptions.source ) ) { + _popcornOptions.source = [ _popcornOptions.source ]; } - function onRightInputChange() { - var val = Time.toSeconds( this.value ); - updateOptions.end = _popcornOptions.start + val - _popcornOptions.from; - updateTrackEvent( updateOptions ); - } + MediaUtils.getMetaData( _popcornOptions.source[ 0 ], function( data ) { + var titleEl = el.querySelector( ".mg-title" ), + typeEl = el.querySelector( ".mg-type" ), + durationEl = el.querySelector( ".mg-duration" ), + thumbnailEl = el.querySelector( ".mg-thumbnail" ), + thumbnailImg; - function onLeftInputChange() { - var val = Time.toSeconds( this.value ); - updateOptions.from = val; - updateOptions.end = _popcornOptions.end + ( _popcornOptions.from - val ); - updateTrackEvent( updateOptions ); - } + el.classList.add( "loaded" ); + titleEl.innerHTML = data.title; + typeEl.innerHTML = data.type; + durationEl.innerHTML = Time.toTimecode( data.duration ) || "???"; - // Setup - outInput.addEventListener( "change", onRightInputChange, false ); - inInput.addEventListener( "change", onLeftInputChange, false ); - rightHandle.addEventListener( "mousedown", onResizeStart, false ); - leftHandle.addEventListener( "mousedown", onResizeStart, false ); - clipSection.addEventListener( "mousedown", onDragStart, false ); - updateUI(); + if ( data.type === "html5" ) { + thumbnailImg = data.thumbnail; + fallbackContainer.classList.add( "show" ); + } else { + thumbnailImg = document.createElement( "img" ); + thumbnailImg.src = data.thumbnail; + thumbnailEl.appendChild( thumbnailImg ); + fallbackContainer.classList.remove( "show" ); + } + + el.classList.add( "mg-" + data.type ); + el.querySelector( ".mg-thumbnail" ).addEventListener( "click", function( e ) { + _butter.editor.openEditor( "media-editor" ); + }, false ); - return { - el: el, - updateUI: updateUI - }; + }); } + updateUI(); + return { + el: el, + updateUI: updateUI + }; + } function setup( trackEvent ) { @@ -403,40 +445,7 @@ define( [ "util/mediatypes", "editor/editor", "util/time", sliderContainer = _rootElement.querySelector( ".volume-slider-container" ); // Custom callbacks and UI updating functions - var sourceCallback = function( trackEvent, updateOptions ) { - if ( !Array.isArray( updateOptions.source ) ) { - updateOptions.source = [ updateOptions.source ]; - } - if ( _mediaType && _mediaType !== "html5" ) { - updateOptions.fallback = [ "" ]; - } - updateOptions.source[ 0 ] = updateOptions.source[ 0 ] || _popcornOptions.source[ 0 ]; - - MediaUtils.getMetaData( updateOptions.source[ 0 ], function( data ) { - _mediaType = data.type; - updateOptions.duration = data.duration; - updateOptions.denied = data.denied; - if ( _mediaType === "html5" ) { - updateOptions.source[ 0 ] = URI.makeUnique( updateOptions.source[ 0 ] ).toString(); - } - trackEvent.update( updateOptions ); - }); - }, - sourceUpdateUI = function( el ) { - - if ( !Array.isArray( _popcornOptions.source ) ) { - _popcornOptions.source = [ _popcornOptions.source ]; - } - - if ( MediaUtils.checkUrl( _popcornOptions.source[ 0 ] ) === "html5" ) { - fallbackContainer.classList.add( "show" ); - } else { - fallbackContainer.classList.remove( "show" ); - } - console.log( _popcornOptions.source[ 0 ] ); - el.value = URI.stripUnique( _popcornOptions.source[ 0 ] ).toString(); - }, - fallbackUpdateUI = function( el ) { + var fallbackUpdateUI = function( el ) { if ( !Array.isArray( _popcornOptions.fallback ) ) { _popcornOptions.fallback = [ _popcornOptions.fallback ]; } @@ -451,16 +460,13 @@ define( [ "util/mediatypes", "editor/editor", "util/time", }; _fields.startEnd = new StartEnd( startEndContainer, "start", _this.updateTrackEventSafe ); - _fields.source = new Input( sourceEl, "source", sourceCallback, sourceUpdateUI ); _fields.fallback = new Input( fallbackEl, "fallback", _this.updateTrackEventSafe, fallbackUpdateUI ); _fields.title = new Input( titleEl, "title", _this.updateTrackEventSafe ); _fields.mute = new Toggler( muteEl, "mute", "reverse", muteUpdateUI ); _fields.volume = new Slider( sliderEl, "volume" ); _fields.hidden = new Toggler( hiddenEl, "hidden", "reverse" ); _fields.from = new Trimmer( clipTrimmerEl ); - - Textbox.applyTo( _fields.source.el, "textarea" ); - Textbox.applyTo( _fields.fallback.el, "textarea" ); + _fields.source = new MetadataBox( sourceEl ); } //setup @@ -478,6 +484,7 @@ define( [ "util/mediatypes", "editor/editor", "util/time", } } } + _this.setErrorState( false ); } diff --git a/src/layouts/sequencer-editor.html b/src/layouts/sequencer-editor.html index 04842a9a6..faf596de3 100644 --- a/src/layouts/sequencer-editor.html +++ b/src/layouts/sequencer-editor.html @@ -9,9 +9,15 @@