Work on video loading - Commit before weekend
authorveltr
Fri, 26 Oct 2012 18:54:20 +0200
changeset 23 c9dc489913af
parent 22 bd904d592881
child 24 1fbf7d835dc2
child 25 eea45f9b124b
Work on video loading - Commit before weekend
integration/css/edition.css
integration/edition.html
integration/img/pinstripe-purple.png
integration/img/slice-handles.png
integration/js/editor.js
integration/js/model.js
integration/profil.html
--- a/integration/css/edition.css	Thu Oct 25 18:52:44 2012 +0200
+++ b/integration/css/edition.css	Fri Oct 26 18:54:20 2012 +0200
@@ -118,6 +118,10 @@
     font-style: italic; font-weight: normal;
 }
 
+.empty-mode .tab-media-title, .pvw-mode .tab-media-title {
+    display: none;
+}
+
 .frise{
 	width: 458px;
 	position: relative;
@@ -209,9 +213,19 @@
 	color:#de2500;
 	margin-bottom: 10px;
 }
-.segmentation h2 span{
-	color: #7628df;
+
+.time-tangle {
+	color: #7628df; cursor: w-resize; position: relative;
+}
+.time-tangle:hover, .time-tangle.active {
+    color: #FF00FC; border-bottom: 1px dashed #7628df;
 }
+.time-tangle:hover:after, .time-tangle.active:after {
+    color: #7628DF; position: absolute; top: 18px; left: 50%; width: 160px;
+    margin-left: -80px; font-size: 12px; text-align: center;
+    content: "glisser pour modifier"
+}
+
 .segmentation form{
 	overflow: hidden;
 }
@@ -478,10 +492,8 @@
 }
 .item-video {
 	margin-bottom: 1px;
-}
-.item-video{
+	cursor: pointer;
 	padding: 5px 10px 5px 10px;
-	position: relative;
 	clear: both;
 	width: auto;
 	min-height: 62px;
@@ -552,7 +564,6 @@
     width: 460px;
     height: 300px;
     position: relative;
-    margin-bottom: 8px;
     background: #333333;
 }
 a.publier-button{
@@ -586,7 +597,7 @@
 }
 
 .Ldt-Slider .ui-slider-handle {
-    border-radius: 8px; top: -2px; background: #fc00ff; border: 1px solid #ffffff;
+    border-radius: 8px; top: -2px; background: #ff00fc; border: 1px solid #ffffff;
 }
 
 .Ldt-Slider .ui-slider-range {
@@ -739,4 +750,27 @@
 
 .Ldt-Ctrl-Volume-Control:hover .ui-slider-handle {
      background: #F7268E;
-}
\ No newline at end of file
+}
+
+/* Slice Widget */
+
+.Ldt-Slice {
+    border-radius: 0; border: none; padding: 0; margin: 12px 0 12px; background: #B6B8B8; height: 8px;
+}
+
+.Ldt-Slice .ui-slider-handle {
+    width: 7px; height: 20px; top: 0; border: none; margin: 0; padding: 0;
+    background: url(../img/slice-handles.png); border-radius: 0; cursor: pointer;
+}
+
+.ui-slider-handle.Ldt-Slice-left-handle {
+    margin-left: -7px;
+}
+
+.ui-slider-handle.Ldt-Slice-right-handle {
+    margin-left: 0; background-position: -7px 0;
+}
+
+.Ldt-Slice .ui-slider-range {
+    background: url(../img/pinstripe-purple.png);
+}
--- a/integration/edition.html	Thu Oct 25 18:52:44 2012 +0200
+++ b/integration/edition.html	Fri Oct 26 18:54:20 2012 +0200
@@ -136,7 +136,7 @@
                 <div class="col-middle empty-mode">
                     
                     <div class="col-middle-header">
-                        <a href="#" class="tab tab-segment">Segmenter <span class="tab-media-title">La cuisine du Popcorn</span></a>
+                        <a href="#" class="tab tab-segment">Segmenter <span class="tab-media-title"></span></a>
                         <a href="#" class="tab tab-pvw">Prévisualiser</a>
                     </div>
                     
@@ -154,6 +154,7 @@
                     </div>
 
                     <div class="widget">
+                        
                         <div class="Ldt-Slider"></div>
                         <div class="Ldt-Slider-Time">00:00</div>
     
@@ -176,16 +177,23 @@
                                <div class="Ldt-Ctrl-Volume-Bar"></div>
                             </div>
                         </div>
+                        
                     </div>
 
                     <div class="bloc-segmentation">
-                        <div class="segment">
-                            <img src="img/visuel-segment.png" alt="">
-                        </div>
+                        <div class="Ldt-Slice"></div>
                         <div class="segment-info segmentation">
                             <img class="pointer" src="img/popin-triangle.png" alt="" />
                             <div class="popin-content">
-                                <h2>Créer un nouveau segment de <span>02:27</span> à <span>02:27</span> (durée: <span>02:27</span>)</h2>
+                                <h2>
+                                    <span class="create-or-edit">Créer un nouveau segment</span>
+                                    de
+                                    <span class="time-tangle tangle-start"></span>
+                                    à
+                                    <span class="time-tangle tangle-end"></span>
+                                    (durée:
+                                    <span class="time-tangle tangle-duration"></span>)
+                                </h2>
                                 <form action="#">
                                     <div class="form-segment-left">
                                         <p>
Binary file integration/img/pinstripe-purple.png has changed
Binary file integration/img/slice-handles.png has changed
--- a/integration/js/editor.js	Thu Oct 25 18:52:44 2012 +0200
+++ b/integration/js/editor.js	Fri Oct 26 18:54:20 2012 +0200
@@ -49,15 +49,18 @@
     
     /* Slider */
    
-    var timeSlider = $(".Ldt-Slider");
+    var timeSlider = $(".Ldt-Slider"),
+        slidersRange = 920;
     timeSlider.slider({
         range: "min",
         value: 0,
         min: 0,
-        max: 920,
+        max: slidersRange,
         slide: function(event, ui) {
-            console.log(ui.value);
-            //TODO: Slide to correct Timecode
+            if (currentMedia) {
+                var t = currentMedia.duration * ui.value / slidersRange;
+                currentMedia.setCurrentTime(t);
+            }
         }
     });
     
@@ -106,7 +109,9 @@
         .mouseout(timeSliderMouseOut)
         .mousemove(function(_e) {
             var _x = _e.pageX - timeSlider.offset().left,
-                _t = new IriSP.Model.Time(); // _this.media.duration * _x / _this.width
+                _t = new IriSP.Model.Time(
+                    currentMedia ? currentMedia.duration * _x / timeSlider.width() : 0
+                );
             timeTooltip.text(_t.toString()).css("left",_x);
         });
     
@@ -146,7 +151,7 @@
    
     var volBlock = $(".Ldt-Ctrl-Volume-Control");
     $('.Ldt-Ctrl-Sound')
-        .click(function(){}) //TODO: Add Mute Handler
+        .click(function(){}) //TODO: Add Mute and Volume Handlers
         .mouseover(function() {
             volBlock.show();
         })
@@ -170,19 +175,224 @@
         }
     });
     
+    $(".Ldt-Ctrl-Play").click(function() {
+        if (currentMedia) {
+            if (currentMedia.getPaused()) {        
+                currentMedia.play();
+            } else {
+                currentMedia.pause();
+            }
+        }
+    });
+    
+    /* Slice Widget */
+    var sliceSlider = $(".Ldt-Slice"),
+        sliceStartTime;
+        
+    function setTangles(sliderValues) {
+        //TODO: Move to Annotation.on("changebounds")
+        if (currentMedia) {
+            startTime = new IriSP.Model.Time(currentMedia.duration * sliderValues[0] / slidersRange),
+            endTime = new IriSP.Model.Time(currentMedia.duration * sliderValues[1] / slidersRange),
+            duration = new IriSP.Model.Time(endTime - startTime);
+            $(".tangle-start").text(startTime.toString()).attr("data-milliseconds",startTime.milliseconds);
+            $(".tangle-end").text(endTime.toString()).attr("data-milliseconds",endTime.milliseconds);
+            $(".tangle-duration").text(duration.toString()).attr("data-milliseconds",duration.milliseconds);
+        }
+    }
+    
+    sliceSlider.slider({
+        range: true,
+        values: [0, slidersRange],
+        min: 0,
+        max: slidersRange,
+        change: function(event, ui) {
+            setTangles(ui.values); // Not the right place to put it
+        },
+        start: function() {
+            if (currentMedia) {
+                if (!currentMedia.getPaused()) {
+                    currentMedia.pause();
+                }
+//                sliceStartTime = currentMedia.getCurrentTime(); 
+            }
+        },
+        slide: function(event, ui) {
+            if (currentMedia) {
+                var t = currentMedia.duration * ui.value / slidersRange;
+                currentMedia.setCurrentTime(t);
+            }
+            setTangles(ui.values);
+        },
+        stop: function() {
+            if (currentMedia && sliceStartTime) {
+//                currentMedia.setCurrentTime(sliceStartTime);
+            }
+        }
+    });
+    
+    sliceSlider.find(".ui-slider-handle:first").addClass("Ldt-Slice-left-handle");
+    sliceSlider.find(".ui-slider-handle:last").addClass("Ldt-Slice-right-handle");
+    
+    /* UI Events */
+
+    function onCurrentMediaPlay() {
+        $(".Ldt-Ctrl-Play")
+            .attr("title", "Pause")
+            .removeClass("Ldt-Ctrl-Play-PlayState")
+            .addClass("Ldt-Ctrl-Play-PauseState")
+    }
+    
+    function onCurrentMediaPause() {
+        $(".Ldt-Ctrl-Play")
+            .attr("title", "Lecture")
+            .removeClass("Ldt-Ctrl-Play-PauseState")
+            .addClass("Ldt-Ctrl-Play-PlayState")
+    }
+    
+    function onCurrentMediaTimeupdate(_time) {
+        $(".Ldt-Ctrl-Time-Elapsed").text(_time.toString());
+        timeSlider.slider("value",slidersRange * _time / currentMedia.duration);
+    }
+    
     /* Set current Media */
     var currentMedia;
     
     function setMedia(mediaid) {
+        $(".col-left .item-video").removeClass("active");
+        $(".tutorial").hide();
+        $("video").hide();
+        if (currentMedia) {
+            currentMedia.pause();
+        }
         currentMedia = project.getElement(mediaid);
         if (currentMedia.elementType == "media") {
-            $("video").hide();
-            var currentvideo = $('video[data-media-id="' + mediaid + '"]');
-            console.log(currentvideo);
+            $(".col-left .item-video[data-media-id='" + mediaid + "']").addClass("active");
+            showSegmentation();
+            var currentvideo = $('#video_' + mediaid);
+            if (!currentvideo.length) {
+                addMediaPlayer(currentMedia);
+                currentvideo = $('#video_' + mediaid);
+            }
+            $(".tab-media-title").text(currentMedia.title);
+            sliceSlider.slider("values",[0, slidersRange]);
         }
+        currentvideo.show();
+        $(".Ldt-Ctrl-Time-Total").text(currentMedia.duration.toString());
+        onCurrentMediaTimeupdate(currentMedia.getCurrentTime());
+        onCurrentMediaPause();
     }
     
     function addMediaPlayer(media) {
+        var videoid = "video_" + media.id,
+            videoEl = $('<video>'),
+            width = $(".video").width(),
+            height = $(".video").height(),
+            mp4_file = media.video.replace(/\.webm$/i,'.mp4'),
+            webm_file = media.video.replace(/\.mp4$/i,'.webm'),
+            mp4_src = $('<source>'),
+            webm_src = $('<source>');
+        mp4_src.attr({
+            src: mp4_file,
+            type: "video/mp4"
+        });
+        webm_src.attr({
+            src: webm_file,
+            type: "video/webm"
+        });
+        videoEl.attr({
+            id : videoid,
+            width : width,
+            height : height
+        }).css({
+            position : "absolute",
+            left: 0,
+            top: 0,
+            width : width,
+            height : height
+        });
+        videoEl.append(mp4_src).append(webm_src);
+        $(".video").append(videoEl);
+
+        var popcorn = Popcorn("#" + videoid);
+        
+        // Binding functions to Popcorn
+        
+        media.on("setcurrenttime", function(_milliseconds) {
+            popcorn.currentTime(_milliseconds / 1000);
+        });
+        
+        media.on("setvolume", function(_vol) {
+            popcorn.volume(_vol);
+            media.volume = _vol;
+        });
+        
+        media.on("setmuted", function(_muted) {
+            popcorn.muted(_muted);
+            media.muted = _muted;
+        });
+        
+        media.on("setplay", function() {
+            popcorn.play();
+        });
+        
+        media.on("setpause", function() {
+            popcorn.pause();
+        });
+        
+        // Binding Popcorn events to media
+        
+        function getVolume() {
+            media.muted = popcorn.muted();
+            media.volume = popcorn.volume();
+        }
+        
+        popcorn.on("loadedmetadata", function() {
+            getVolume();
+            media.trigger("loadedmetadata");
+            media.trigger("volumechange");
+        })
+        
+        popcorn.on("timeupdate", function() {
+            media.trigger("timeupdate", new IriSP.Model.Time(1000*popcorn.currentTime()));
+        });
+        
+        popcorn.on("volumechange", function() {
+            getVolume();
+            media.trigger("volumechange");
+        })
+        
+        popcorn.on("play", function() {
+            media.trigger("play");
+        });
+        
+        popcorn.on("pause", function() {
+            media.trigger("pause");
+        });
+        
+        popcorn.on("seeked", function() {
+            media.trigger("seeked");
+        });
+        
+        // Binding UI Events to Media
+        
+        media.on("play", function() {
+            if (media === currentMedia) {
+                onCurrentMediaPlay();
+            }
+        });
+        
+        media.on("pause", function() {
+            if (media === currentMedia) {
+                onCurrentMediaPause();
+            }
+        });
+        
+        media.on("timeupdate", function(_time) {
+            if (media === currentMedia) {
+                onCurrentMediaTimeupdate(_time);
+            }
+        })
         
     }
     /* Click on media items */
@@ -202,7 +412,6 @@
         return false;
     }
     
-    $(".tab-segment").click(showSegmentation);
     $(".tab-pvw").click(showPreview);
     
     function disableMoveItemVideo() {
@@ -228,6 +437,34 @@
         disableMoveItemVideo();
     });
     
+    /* Tangle */
+    var activeTangle,
+        tangleStartX,
+        tangleStartVal;
+    $(".time-tangle").mousedown(function(evt) {
+        activeTangle = $(this);
+        activeTangle.addClass("active");
+        tangleStartVal = +activeTangle.attr("data-milliseconds");
+        tangleStartX = evt.pageX;
+        return false;
+    });
+    $(document)
+        .mousemove(function(evt) {
+            if (activeTangle) {
+                var newval = new IriSP.Model.Time(100 * (evt.pageX - tangleStartX) + tangleStartVal);
+                activeTangle.text(newval.toString());
+                activeTangle.attr("data-milliseconds",newval.milliseconds);
+                activeTangle.trigger("valuechange", newval);
+                return false;
+            }
+        })
+        .mouseup(function() {
+            if (activeTangle) {
+                activeTangle.removeClass("active");
+                activeTangle = undefined;
+            }
+        })
+    
 }
 
 $(function() {
--- a/integration/js/model.js	Thu Oct 25 18:52:44 2012 +0200
+++ b/integration/js/model.js	Fri Oct 26 18:54:20 2012 +0200
@@ -1,8 +1,7 @@
 /* TODO: Separate Project-specific data from Source */
 
 /* model.js is where data is stored in a standard form, whatever the serializer */
-
-(function (ns) {
+IriSP.Model = (function (ns) {
 
 var Model = {
     _SOURCE_STATUS_EMPTY : 0,
@@ -30,20 +29,25 @@
         }
         return "autoid-" + this._ID_BASE + '-' + _n;
     },
-    regexpFromTextOrArray : function(_textOrArray, _testOnly) {
-        var _testOnly = _testOnly || false;
+    regexpFromTextOrArray : function(_textOrArray, _testOnly, _iexact) {
+        var _testOnly = _testOnly || false,
+            _iexact = _iexact || false;
         function escapeText(_text) {
             return _text.replace(/([\\\*\+\?\|\{\[\}\]\(\)\^\$\.\#\/])/gm, '\\$1');
         }
         var _source = 
             typeof _textOrArray === "string"
             ? escapeText(_textOrArray)
-            : ns._(_textOrArray).map(escapeText).join("|");
-        if (_testOnly) {
-            return new RegExp( _source, 'im');
-        } else {
-            return new RegExp( '(' + _source + ')', 'gim');
+            : ns._(_textOrArray).map(escapeText).join("|"),
+            _flags = 'im';
+        if (!_testOnly) {
+            _source = '(' + _source + ')';
+            _flags += 'g';
         }
+        if (_iexact) {
+            _source = '^' + _source + '$';
+        }
+        return new RegExp( _source, _flags);
     },
     isoToDate : function(_str) {
         // http://delete.me.uk/2005/03/iso8601.html
@@ -167,22 +171,25 @@
 /* Title and Description are basic information for (almost) all element types,
  * here we can search by these criteria
  */
-Model.List.prototype.searchByTitle = function(_text) {
-    var _rgxp = Model.regexpFromTextOrArray(_text, true);
+Model.List.prototype.searchByTitle = function(_text, _iexact) {
+    var _iexact = _iexact || false,
+        _rgxp = Model.regexpFromTextOrArray(_text, true);
     return this.filter(function(_element) {
         return _rgxp.test(_element.title);
     });
 }
 
-Model.List.prototype.searchByDescription = function(_text) {
-    var _rgxp = Model.regexpFromTextOrArray(_text, true);
+Model.List.prototype.searchByDescription = function(_text, _iexact) {
+    var _iexact = _iexact || false,
+        _rgxp = Model.regexpFromTextOrArray(_text, true);
     return this.filter(function(_element) {
         return _rgxp.test(_element.description);
     });
 }
 
-Model.List.prototype.searchByTextFields = function(_text) {
-    var _rgxp =  Model.regexpFromTextOrArray(_text, true);
+Model.List.prototype.searchByTextFields = function(_text, _iexact) {
+    var _iexact = _iexact || false,
+        _rgxp =  Model.regexpFromTextOrArray(_text, true);
     return this.filter(function(_element) {
         return _rgxp.test(_element.description) || _rgxp.test(_element.title);
     });
@@ -982,6 +989,6 @@
     return _res;
 }
 
-ns.Model = Model;
+return Model;
 
 })(IriSP);
--- a/integration/profil.html	Thu Oct 25 18:52:44 2012 +0200
+++ b/integration/profil.html	Fri Oct 26 18:54:20 2012 +0200
@@ -1,21 +1,19 @@
 <!DOCTYPE html>
-<!--[if lt IE 7]>      <html class="no-js lt-ie9 lt-ie8 lt-ie7"> <![endif]-->
-<!--[if IE 7]>         <html class="no-js lt-ie9 lt-ie8"> <![endif]-->
-<!--[if IE 8]>         <html class="no-js lt-ie9"> <![endif]-->
-<!--[if gt IE 8]><!--> <html class="no-js"> <!--<![endif]-->
+<html>
     <head>
         <meta charset="utf-8">
         <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
-        <title>Profil</title>
+        <meta name="copyright" content="Institut de Recherche et d'Innovation (IRI), 2012" />
+        <meta name="author" content="Anthony Ly, Raphaël Velt" />
+        <title>Hashcut &gt; Page profil</title>
+        <link rel="stylesheet" href="lib/jquery-ui.css" />
         <link rel="stylesheet" href="css/reset.css" />
-        <link rel="stylesheet" href="css/style.css" />
-        <link rel="stylesheet" href="css/ui-lightness/jquery-ui-1.8.24.custom.css">
-        <script src="js/vendor/modernizr-2.6.1.min.js"></script>
+        <link rel="stylesheet" href="css/common.css" />
     </head>
     <body>
         <div class="wrap">
             <div class="wrap-header">
-                <a title="Bibliothèque centre Pompidou" href="#"><img src="img/pompidou-logo.png" alt="Bibliothèque centre Pompidou" /></a>
+                <a title="Bibliothèque Publique d'Information" href="#"><img src="img/pompidou-logo.png" alt="Bibliothèque centre Pompidou" /></a>
             </div>
             <div class="header">
                 <!-- popin header -->
@@ -25,7 +23,9 @@
                         <h2>Mashup75</h2>
                         <h3>mash@cinecast.fr</h3>
                         <a href="#" class="nb-hashcut">12 Hashcuts</a>
-                        <a href="#" class="change-account">Changer de compte</a>
+                        <p>
+                            <a href="#" class="change-account button">Changer de compte</a>
+                        </p>
                     </div>
                 </div><!-- popin user info-->
 
@@ -33,7 +33,7 @@
                     <img class="pointer" src="img/popin-triangle.png" alt="" />
                     <div class="popin-content">
                         <h2>Créer un compte :</h2>
-                        <form action="#">
+                        <form action="#" class="signup-form">
                             <p>
                                 <label for="signup-pseudo">Pseudonyme : </label>
                                 <input type="text" id="signup-pseudo" name="" />
@@ -51,7 +51,7 @@
                                 <input type="password" id="signup-password" name="" />
                             </p>
                             <p>
-                                <input type="submit" value="Créer le compte">
+                                <input class="button" type="submit" value="Créer le compte">
                             </p>
                         </form>
    
@@ -62,7 +62,7 @@
                     <img class="pointer" src="img/popin-triangle.png" alt="" />
                     <div class="popin-content">
                         <h2>Connexion :</h2>
-                        <form action="#">
+                        <form action="#" class="login-form">
                             <p>
                                 <label for="signup-pseudo">E-mail : </label>
                                 <input type="text" id="signup-pseudo" name="" />
@@ -72,10 +72,10 @@
                                 <input type="password" id="signup-email" name="" />
                             </p>
                             <p>
-                                <input type="submit" value="Se connecter">
+                                <input class="button" type="submit" value="Se connecter">
                             </p>
                             <p>
-                                <a class="signup-button" href="#">Créer un compte</a>
+                                <a class="button signup-button" href="#">Créer un compte</a>
                             </p>
                         </form>
    
@@ -112,9 +112,8 @@
             </div><!-- footer -->
         </div><!-- wrap -->
         <!-- JavaScript -->
-        <script src="js/vendor/jquery-1.8.0.min.js"></script>
-        <script src="js/vendor/jquery-ui-1.8.24.custom.min.js"></script>
-        <script src="js/plugins.js"></script>
-        <script src="js/main.js"></script>
+        <script type="text/javascript" src="lib/jquery.min.js"></script>
+        <script type="text/javascript" src="lib/jquery-ui.min.js"></script>
+        <script type="text/javascript" src="js/common.js"></script>
     </body>
 </html>