Changes in video handling, displayed metadata and search results
authorveltr
Thu, 06 Dec 2012 12:38:34 +0100
changeset 123 679809037606
parent 121 839efd6eddf1
child 124 41c09a24bc92
Changes in video handling, displayed metadata and search results
integration/css/common.css
integration/css/edition.css
integration/edition.html
integration/js/editor.js
integration/js/mashupcore.js
integration/js/mediaplayer.js
integration/js/model.js
integration/js/segmentapi-serializer.js
src/hashcut/static/hashcut/bpi/css/common.css
src/hashcut/static/hashcut/bpi/css/edition.css
src/hashcut/static/hashcut/iri/css/common.css
src/hashcut/static/hashcut/iri/css/edition.css
src/hashcut/static/hashcut/js/hashcut.js
--- a/integration/css/common.css	Wed Dec 05 15:39:12 2012 +0100
+++ b/integration/css/common.css	Thu Dec 06 12:38:34 2012 +0100
@@ -477,11 +477,16 @@
 .item-video .video-info{
     margin-left: 88px;
 }
-.item-video .title-video{
+.item-video h3 {
 	font-size: 13px;
 	font-weight: 600;
+	margin-bottom: 1px;
+}
+.item-video .title-video{
 	color: #30036d;
-	margin-bottom: 1px;
+}
+.segment-title {
+    color: #de2500;
 }
 .item-video .description{
 	font-size: 11px;
@@ -515,14 +520,12 @@
   	border: 1px solid #C81000;
   	text-shadow: 1px 1px 1px #330000;
 }
-.item-video .subtitle{
+.item-video p {
 	margin-bottom: 2px;
-	color: #de2500;
-	font-size: 11px;
+	font-size: 12px;
 }
 .item-video .duration{
 	color: #7628df;
-	font-size: 12px;
 	font-weight: 600;
 }
 /* frise */
@@ -980,7 +983,7 @@
     -webkit-box-shadow: inset 1px 1px 1px #808080;
     box-shadow: inset 1px 1px 1px #808080;
 }
-.active .media-segment-section,
+.media-segment.active .media-segment-section,
 .media-segment:hover .media-segment-section,
 .list-video .frise-segment.active {
     -moz-box-shadow: inset 0 0 2px 2px #fc00ff, 0 0 2px #fc00ff;
@@ -989,13 +992,16 @@
 }
 .media-segment-popin h3, .media-found-popin h3{
     padding: 0;
-    color: #de2500;
     margin-bottom: 4px;
     font-weight: 600;
 }
 
-.media-segment-popin p{
-    font-size: 12px;
+.media-segment-popin p, .media-found-popin p {
+    font-size: 12px; margin: 4px 0; line-height: 13px;
+}
+
+.media-segment-popin strong, .media-found-popin strong{
+    font-weight: 600;
 }
 
 .media-segment-popin span{
--- a/integration/css/edition.css	Wed Dec 05 15:39:12 2012 +0100
+++ b/integration/css/edition.css	Thu Dec 06 12:38:34 2012 +0100
@@ -187,11 +187,6 @@
     display: none;
 }
 
-.media-segment-popin p{
-    margin-right: 155px;
-    font-size: 12px;
-}
-
 .media-found-segments {
     clear: both; padding-top: 5px;
 }
--- a/integration/edition.html	Wed Dec 05 15:39:12 2012 +0100
+++ b/integration/edition.html	Thu Dec 06 12:38:34 2012 +0100
@@ -353,12 +353,21 @@
         
     IriSP.endpoints = {
         content: "/pf/ldtplatform/api/ldt/1.0/contents/",
+        //content: "data/bpidata2.json",
         project: "/pf/ldtplatform/api/ldt/1.0/projects/",
         segment: "/pf/ldtplatform/api/ldt/1.0/segments/",
         ldt: "http://capsicum//pf/ldtplatform/ldt/cljson/id/__PROJECT_ID__",
         hashcut_page: "hashcut.html?project=__PROJECT_ID__"
     };
     
+    IriSP.video_url_transform = function(oldurl) {
+        var newurl = oldurl.replace(/mp4:/i,'');
+        newurl = newurl.replace(/ddc_player\//i,'');
+        newurl = newurl.replace(/rtmp/i,'http');
+        newurl = newurl.replace('media.iri.centrepompidou.fr','ftv.iri-research.org')
+        return newurl;
+    };
+    
     $(function() {
         var hashcut = IriSP.editor({
             csrf_token: "{{csrf_token}}",
--- a/integration/js/editor.js	Wed Dec 05 15:39:12 2012 +0100
+++ b/integration/js/editor.js	Thu Dec 06 12:38:34 2012 +0100
@@ -19,8 +19,8 @@
         segmenttemplate = _.template(
             '<li class="item-video annotation" data-segment-id="<%= annotation.id %>" data-media-id="<%= annotation.getMedia().id %>">'
             + '<img class="thumbnail" src="<%= annotation.thumbnail %>" alt="<%= annotation.getMedia().title %>" />'
-            + '<div class="validate <%= annotation.status %>"><div class="validate-tooltip"><ul><li><%= annotation.status_messages.join("</li><li>") %></li></ul></div></div><div class="video-info"><h3 class="title-video"><%= annotation.getMedia().title %></h3>'
-            + '<p class="subtitle"><%= annotation.title %></p><p class="duration"><%= annotation.begin.toString() %> - <%= annotation.end.toString() %> (<%= annotation.getDuration().toString() %>)</p>'
+            + '<div class="validate <%= annotation.status %>"><div class="validate-tooltip"><ul><li><%= annotation.status_messages.join("</li><li>") %></li></ul></div></div><div class="video-info"><h3 class="segment-title"><%= annotation.title %></h3>'
+            + '<p class="title-video"><%= annotation.getMedia().title %></p><p class="duration"><%= annotation.begin.toString() %> - <%= annotation.end.toString() %> (<%= annotation.getDuration().toString() %>)</p>'
             + '<ul class="tools"><li><a class="edit" href="#" title="<%= gettext("Edit segment") %>"></a></li><li><a class="bottom" href="#" title="<%= gettext("Move segment down") %>"></a></li>'
             + '<li><a class="top" href="#" title="<%= gettext("Move segment up") %>"></a></li><li><a class="delete" href="#" title="<%= gettext("Delete segment") %>"></a></li></ul></div></li>'
         ),
@@ -28,7 +28,9 @@
             '<div class="media-segment">'
             + '<div class="media-segment-section" style="left:<%= left %>px; width:<%= width %>px; background:<%= color %>; top: <%= top %>px;" data-segment-id="<%= annotation.id %>"></div>'
             + '<div class="popin media-segment-popin" style="left:<%= popleft %>px; top: <%= 5+top %>px;"><div style="left:<%= pointerpos %>px;" class="pointer"></div><div class="popin-content">'
-            + '<h3><%= annotation.title %></h3><a href="#" class="button reprendre-segment" data-segment-id="<%= annotation.id %>"><%= gettext("Clone segment") %></a>'
+            + '<h3 class="segment-title"><%= annotation.title %></h3>'
+            + '<p><%= annotation.description %></p><% if (annotation.keywords.length) { console.log(annotation.keywords); print("<p><strong>" + gettext("Tags:") + "</strong> " + annotation.keywords.join(", ") + "</p>"); } %>'
+            + '<a href="#" class="button reprendre-segment" data-segment-id="<%= annotation.id %>"><%= gettext("Clone segment") %></a>'
             + '<p><%= gettext("From:") %> <span><%= annotation.begin.toString() %></span> <%= gettext("to:") %> <span><%= annotation.end.toString() %></span> (<%= gettext("duration:") %> <span><%= annotation.getDuration().toString() %></span>)</p>'
             + '</div></div></div>'
         ),
@@ -38,7 +40,9 @@
         mediafoundtemplate = _.template(
             '<div class="media-segment"><div class="media-segment-section" style="left:<%= left %>px; width:<%= width %>px; background:<%= color %>; top: <%= top %>px;"></div>'
             + '<div class="popin media-found-popin" style="left:<%= popleft %>px; top: <%= 5+top %>px;"><div style="left:<%= pointerpos %>px;" class="pointer"></div><div class="popin-content">'
-            + '<h3><%= title %></h3><a href="#" class="button clone-segment" data-segment-id="<%= annotation.id %>"><%= gettext("Clone segment") %></a>'
+            + '<h3 class="segment-title"><%= title %></h3>'
+            + '<p><%= description %></p><% if (tags) { print("<p><strong>" + gettext("Tags:") + "</strong> " + tags + "</p>"); } %>'
+            + '<a href="#" class="button clone-segment" data-segment-id="<%= annotation.id %>"><%= gettext("Clone segment") %></a>'
             + '</div></div></div>'
         ),
         mediafoundlisttemplate = _.template(
@@ -150,6 +154,9 @@
     
     $(".col-left input").on("keyup change input paste", function() {
         var val = $(this).val();
+        if (val.length < 2) {
+            val = false;
+        }
         if (val) {
             var find = IriSP.Model.regexpFromTextOrArray(val, true),
                 replace = IriSP.Model.regexpFromTextOrArray(val, false);
@@ -169,7 +176,7 @@
                     var annotations = apimedia.getAnnotations().searchByTextFields(val);
                 } else {
                     var annotations = [];
-                }   
+                }
                 var found = find.test(media.title) || find.test(media.description) || annotations.length;
                 if (found) {
                     li.find(".title-video").html(media.title.replace(replace, '<span style="background: #fc00ff; color: #ffffff;">$1</span>'));
@@ -197,6 +204,8 @@
                             top: 8 * line.index,
                             color: IriSP.vizcolors[i % IriSP.vizcolors.length],
                             title: _a.title.replace(replace, '<span style="background: #fc00ff; color: #ffffff;">$1</span>'),
+                            description: _a.description.replace(replace, '<span style="background: #fc00ff; color: #ffffff;">$1</span>'),
+                            tags: _a.keywords.join(", ").replace(replace, '<span style="background: #fc00ff; color: #ffffff;">$1</span>'),
                             popleft : corrpos,
                             pointerpos : (pos - corrpos),
                         }
@@ -226,7 +235,7 @@
             }
         });
         if (critical) {
-            messages.push("One or more segments are invalid");
+            messages.push(gettext("One or more segments are invalid"));
         }
         
         _(mashupcritical).each(function(sc) {
@@ -243,7 +252,7 @@
         });
         mashup.status = critical ? "critical" : (warning ? "warning" : "valid");
         if (!messages.length) {
-            messages.push("Your hashcut is valid!");
+            messages.push(gettext("Your hashcut is valid!"));
         }
         mashupstatus = ' - ' + _(messages).join('\n - ');
         
@@ -348,7 +357,7 @@
             });
             currentSegment.status = critical ? "critical" : (warning ? "warning" : "valid");
             if (!messages.length) {
-                messages.push("This segment is valid!")
+                messages.push(gettext("This segment is valid!"))
             }
             currentSegment.status_messages = _(messages);
             
--- a/integration/js/mashupcore.js	Wed Dec 05 15:39:12 2012 +0100
+++ b/integration/js/mashupcore.js	Thu Dec 06 12:38:34 2012 +0100
@@ -310,18 +310,26 @@
             videoEl = $('<video>'),
             width = $(".video").width(),
             height = $(".video").height(),
+/*
             mp4_file = videourl.replace(/\.webm$/i,'.mp4'),
             webm_file = videourl.replace(/\.mp4$/i,'.webm'),
+*/
             mp4_src = $('<source>'),
-            webm_src = $('<source>');
+/*
+            webm_src = $('<source>'),
+*/
+            lastseektime,
+            currentseektime;
         mp4_src.attr({
-            src: mp4_file,
+            src: videourl, //mp4_file,
             type: "video/mp4"
         });
+/*
         webm_src.attr({
             src: webm_file,
             type: "video/webm"
         });
+*/
         videoEl.attr({
             id : videoid,
             width : width,
@@ -333,7 +341,7 @@
             width : width,
             height : height
         });
-        videoEl.append(mp4_src).append(webm_src);
+        videoEl.append(mp4_src); //.append(webm_src);
         $(".video").append(videoEl);
         
         media.show = function() {
@@ -349,9 +357,14 @@
         
         media.on("setcurrenttime", function(_milliseconds) {
             if (media.loaded) {
-                popcorn.currentTime(_milliseconds / 1000);
-                media.seeking = true;
-                setTimeout(showSeek,200);
+                if (!media.seeking) {
+                    lastseektime = currentseektime = _milliseconds.valueOf();
+                    popcorn.currentTime(currentseektime / 1000);
+                    media.seeking = true;
+                    setTimeout(showSeek,200);
+                } else {
+                    lastseektime = _milliseconds.valueOf();
+                }
             }
         });
         
@@ -413,7 +426,13 @@
         });
         
         popcorn.on("seeked", function() {
-            media.trigger("seeked");
+            if (currentseektime !== lastseektime) {
+                currentseektime = lastseektime;
+                popcorn.currentTime(currentseektime / 1000);
+                media.seeking = true;
+            } else {
+                media.trigger("seeked");
+            }
         });
         
         // Binding UI Events and Mashup Playing to Media
--- a/integration/js/mediaplayer.js	Wed Dec 05 15:39:12 2012 +0100
+++ b/integration/js/mediaplayer.js	Thu Dec 06 12:38:34 2012 +0100
@@ -10,7 +10,8 @@
             '<div class="media-segment" data-mashup-id="<%= annotation.project_id %>">'
             + '<div class="media-segment-section" style="left:<%= left %>px; width:<%= width %>px; background:<%= color %>; top: <%= top %>px;" data-segment-id="<%= annotation.id %>"></div>'
             + '<div class="popin media-segment-popin" style="left:<%= popleft %>px; top: <%= 5+top %>px;"><div style="left:<%= pointerpos %>px;" class="pointer"></div><div class="popin-content">'
-            + '<h3><%= annotation.title %></h3>'
+            + '<h3 class="segment-title"><%= annotation.title %></h3>'
+            + '<p><%= annotation.description %></p><% if (annotation.keywords.length) { print("<p><strong>" + gettext("Tags:") + "</strong> " + annotation.keywords.join(", ") + "</p>"); } %>'
             + '<p><%= gettext("From:") %> <span><%= annotation.begin.toString() %></span> <%= gettext("to:") %> <span><%= annotation.end.toString() %></span> (<%= gettext("duration:") %> <span><%= annotation.getDuration().toString() %></span>)</p>'
             + '<p class="mashup-link"><%= gettext("From hashcut:") %> <a href="<%= IriSP.endpoints.hashcut_page.replace("__PROJECT_ID__", annotation.project_id) %>"></a></p>'
             + '</div></div></div>'
--- a/integration/js/model.js	Wed Dec 05 15:39:12 2012 +0100
+++ b/integration/js/model.js	Thu Dec 06 12:38:34 2012 +0100
@@ -194,7 +194,8 @@
     var _iexact = _iexact || false,
         _rgxp =  Model.regexpFromTextOrArray(_text, true);
     return this.filter(function(_element) {
-        return _rgxp.test(_element.description) || _rgxp.test(_element.title);
+        var keywords = (_element.keywords || _element.getTagTexts() || []).join(", ");
+        return _rgxp.test(_element.description) || _rgxp.test(_element.title) || _rgxp.test(keywords);
     });
 }
 
--- a/integration/js/segmentapi-serializer.js	Wed Dec 05 15:39:12 2012 +0100
+++ b/integration/js/segmentapi-serializer.js	Thu Dec 06 12:38:34 2012 +0100
@@ -16,7 +16,7 @@
             _ann.description = _s.abstract;
             _ann.begin = new IriSP.Model.Time(_s.start_ts);
             _ann.end = new IriSP.Model.Time(_s.start_ts + _s.duration);
-            _ann.keywords = _s.tags.split(",");
+            _ann.keywords = (_s.tags ? _s.tags.split(",") : []);
             _ann.project_id = _s.project_id;
             _annotationlist.push(_ann);
         }
--- a/src/hashcut/static/hashcut/bpi/css/common.css	Wed Dec 05 15:39:12 2012 +0100
+++ b/src/hashcut/static/hashcut/bpi/css/common.css	Thu Dec 06 12:38:34 2012 +0100
@@ -477,11 +477,16 @@
 .item-video .video-info{
     margin-left: 88px;
 }
-.item-video .title-video{
+.item-video h3 {
 	font-size: 13px;
 	font-weight: 600;
+	margin-bottom: 1px;
+}
+.item-video .title-video{
 	color: #30036d;
-	margin-bottom: 1px;
+}
+.segment-title {
+    color: #de2500;
 }
 .item-video .description{
 	font-size: 11px;
@@ -515,14 +520,12 @@
   	border: 1px solid #C81000;
   	text-shadow: 1px 1px 1px #330000;
 }
-.item-video .subtitle{
+.item-video p {
 	margin-bottom: 2px;
-	color: #de2500;
-	font-size: 11px;
+	font-size: 12px;
 }
 .item-video .duration{
 	color: #7628df;
-	font-size: 12px;
 	font-weight: 600;
 }
 /* frise */
@@ -980,7 +983,7 @@
     -webkit-box-shadow: inset 1px 1px 1px #808080;
     box-shadow: inset 1px 1px 1px #808080;
 }
-.active .media-segment-section,
+.media-segment.active .media-segment-section,
 .media-segment:hover .media-segment-section,
 .list-video .frise-segment.active {
     -moz-box-shadow: inset 0 0 2px 2px #fc00ff, 0 0 2px #fc00ff;
@@ -989,13 +992,16 @@
 }
 .media-segment-popin h3, .media-found-popin h3{
     padding: 0;
-    color: #de2500;
     margin-bottom: 4px;
     font-weight: 600;
 }
 
-.media-segment-popin p{
-    font-size: 12px;
+.media-segment-popin p, .media-found-popin p {
+    font-size: 12px; margin: 4px 0; line-height: 13px;
+}
+
+.media-segment-popin strong, .media-found-popin strong{
+    font-weight: 600;
 }
 
 .media-segment-popin span{
--- a/src/hashcut/static/hashcut/bpi/css/edition.css	Wed Dec 05 15:39:12 2012 +0100
+++ b/src/hashcut/static/hashcut/bpi/css/edition.css	Thu Dec 06 12:38:34 2012 +0100
@@ -187,11 +187,6 @@
     display: none;
 }
 
-.media-segment-popin p{
-    margin-right: 155px;
-    font-size: 12px;
-}
-
 .media-found-segments {
     clear: both; padding-top: 5px;
 }
--- a/src/hashcut/static/hashcut/iri/css/common.css	Wed Dec 05 15:39:12 2012 +0100
+++ b/src/hashcut/static/hashcut/iri/css/common.css	Thu Dec 06 12:38:34 2012 +0100
@@ -477,11 +477,16 @@
 .item-video .video-info{
     margin-left: 88px;
 }
-.item-video .title-video{
+.item-video h3 {
 	font-size: 13px;
 	font-weight: 600;
+	margin-bottom: 1px;
+}
+.item-video .title-video{
 	color: #30036d;
-	margin-bottom: 1px;
+}
+.segment-title {
+    color: #de2500;
 }
 .item-video .description{
 	font-size: 11px;
@@ -515,14 +520,12 @@
   	border: 1px solid #C81000;
   	text-shadow: 1px 1px 1px #330000;
 }
-.item-video .subtitle{
+.item-video p {
 	margin-bottom: 2px;
-	color: #de2500;
-	font-size: 11px;
+	font-size: 12px;
 }
 .item-video .duration{
 	color: #7628df;
-	font-size: 12px;
 	font-weight: 600;
 }
 /* frise */
@@ -980,7 +983,7 @@
     -webkit-box-shadow: inset 1px 1px 1px #808080;
     box-shadow: inset 1px 1px 1px #808080;
 }
-.active .media-segment-section,
+.media-segment.active .media-segment-section,
 .media-segment:hover .media-segment-section,
 .list-video .frise-segment.active {
     -moz-box-shadow: inset 0 0 2px 2px #fc00ff, 0 0 2px #fc00ff;
@@ -989,13 +992,16 @@
 }
 .media-segment-popin h3, .media-found-popin h3{
     padding: 0;
-    color: #de2500;
     margin-bottom: 4px;
     font-weight: 600;
 }
 
-.media-segment-popin p{
-    font-size: 12px;
+.media-segment-popin p, .media-found-popin p {
+    font-size: 12px; margin: 4px 0; line-height: 13px;
+}
+
+.media-segment-popin strong, .media-found-popin strong{
+    font-weight: 600;
 }
 
 .media-segment-popin span{
--- a/src/hashcut/static/hashcut/iri/css/edition.css	Wed Dec 05 15:39:12 2012 +0100
+++ b/src/hashcut/static/hashcut/iri/css/edition.css	Thu Dec 06 12:38:34 2012 +0100
@@ -187,11 +187,6 @@
     display: none;
 }
 
-.media-segment-popin p{
-    margin-right: 155px;
-    font-size: 12px;
-}
-
 .media-found-segments {
     clear: both; padding-top: 5px;
 }
--- a/src/hashcut/static/hashcut/js/hashcut.js	Wed Dec 05 15:39:12 2012 +0100
+++ b/src/hashcut/static/hashcut/js/hashcut.js	Thu Dec 06 12:38:34 2012 +0100
@@ -235,7 +235,8 @@
     var _iexact = _iexact || false,
         _rgxp =  Model.regexpFromTextOrArray(_text, true);
     return this.filter(function(_element) {
-        return _rgxp.test(_element.description) || _rgxp.test(_element.title);
+        var keywords = (_element.keywords || _element.getTagTexts() || []).join(", ");
+        return _rgxp.test(_element.description) || _rgxp.test(_element.title) || _rgxp.test(keywords);
     });
 }
 
@@ -1472,7 +1473,7 @@
             _ann.description = _s.abstract;
             _ann.begin = new IriSP.Model.Time(_s.start_ts);
             _ann.end = new IriSP.Model.Time(_s.start_ts + _s.duration);
-            _ann.keywords = _s.tags.split(",");
+            _ann.keywords = (_s.tags ? _s.tags.split(",") : []);
             _ann.project_id = _s.project_id;
             _annotationlist.push(_ann);
         }
@@ -1826,18 +1827,26 @@
             videoEl = $('<video>'),
             width = $(".video").width(),
             height = $(".video").height(),
+/*
             mp4_file = videourl.replace(/\.webm$/i,'.mp4'),
             webm_file = videourl.replace(/\.mp4$/i,'.webm'),
+*/
             mp4_src = $('<source>'),
-            webm_src = $('<source>');
+/*
+            webm_src = $('<source>'),
+*/
+            lastseektime,
+            currentseektime;
         mp4_src.attr({
-            src: mp4_file,
+            src: videourl, //mp4_file,
             type: "video/mp4"
         });
+/*
         webm_src.attr({
             src: webm_file,
             type: "video/webm"
         });
+*/
         videoEl.attr({
             id : videoid,
             width : width,
@@ -1849,7 +1858,7 @@
             width : width,
             height : height
         });
-        videoEl.append(mp4_src).append(webm_src);
+        videoEl.append(mp4_src); //.append(webm_src);
         $(".video").append(videoEl);
         
         media.show = function() {
@@ -1865,9 +1874,14 @@
         
         media.on("setcurrenttime", function(_milliseconds) {
             if (media.loaded) {
-                popcorn.currentTime(_milliseconds / 1000);
-                media.seeking = true;
-                setTimeout(showSeek,200);
+                if (!media.seeking) {
+                    lastseektime = currentseektime = _milliseconds.valueOf();
+                    popcorn.currentTime(currentseektime / 1000);
+                    media.seeking = true;
+                    setTimeout(showSeek,200);
+                } else {
+                    lastseektime = _milliseconds.valueOf();
+                }
             }
         });
         
@@ -1929,7 +1943,13 @@
         });
         
         popcorn.on("seeked", function() {
-            media.trigger("seeked");
+            if (currentseektime !== lastseektime) {
+                currentseektime = lastseektime;
+                popcorn.currentTime(currentseektime / 1000);
+                media.seeking = true;
+            } else {
+                media.trigger("seeked");
+            }
         });
         
         // Binding UI Events and Mashup Playing to Media
@@ -2192,8 +2212,8 @@
         segmenttemplate = _.template(
             '<li class="item-video annotation" data-segment-id="<%= annotation.id %>" data-media-id="<%= annotation.getMedia().id %>">'
             + '<img class="thumbnail" src="<%= annotation.thumbnail %>" alt="<%= annotation.getMedia().title %>" />'
-            + '<div class="validate <%= annotation.status %>"><div class="validate-tooltip"><ul><li><%= annotation.status_messages.join("</li><li>") %></li></ul></div></div><div class="video-info"><h3 class="title-video"><%= annotation.getMedia().title %></h3>'
-            + '<p class="subtitle"><%= annotation.title %></p><p class="duration"><%= annotation.begin.toString() %> - <%= annotation.end.toString() %> (<%= annotation.getDuration().toString() %>)</p>'
+            + '<div class="validate <%= annotation.status %>"><div class="validate-tooltip"><ul><li><%= annotation.status_messages.join("</li><li>") %></li></ul></div></div><div class="video-info"><h3 class="segment-title"><%= annotation.title %></h3>'
+            + '<p class="title-video"><%= annotation.getMedia().title %></p><p class="duration"><%= annotation.begin.toString() %> - <%= annotation.end.toString() %> (<%= annotation.getDuration().toString() %>)</p>'
             + '<ul class="tools"><li><a class="edit" href="#" title="<%= gettext("Edit segment") %>"></a></li><li><a class="bottom" href="#" title="<%= gettext("Move segment down") %>"></a></li>'
             + '<li><a class="top" href="#" title="<%= gettext("Move segment up") %>"></a></li><li><a class="delete" href="#" title="<%= gettext("Delete segment") %>"></a></li></ul></div></li>'
         ),
@@ -2201,7 +2221,9 @@
             '<div class="media-segment">'
             + '<div class="media-segment-section" style="left:<%= left %>px; width:<%= width %>px; background:<%= color %>; top: <%= top %>px;" data-segment-id="<%= annotation.id %>"></div>'
             + '<div class="popin media-segment-popin" style="left:<%= popleft %>px; top: <%= 5+top %>px;"><div style="left:<%= pointerpos %>px;" class="pointer"></div><div class="popin-content">'
-            + '<h3><%= annotation.title %></h3><a href="#" class="button reprendre-segment" data-segment-id="<%= annotation.id %>"><%= gettext("Clone segment") %></a>'
+            + '<h3 class="segment-title"><%= annotation.title %></h3>'
+            + '<p><%= annotation.description %></p><% if (annotation.keywords.length) { console.log(annotation.keywords); print("<p><strong>" + gettext("Tags:") + "</strong> " + annotation.keywords.join(", ") + "</p>"); } %>'
+            + '<a href="#" class="button reprendre-segment" data-segment-id="<%= annotation.id %>"><%= gettext("Clone segment") %></a>'
             + '<p><%= gettext("From:") %> <span><%= annotation.begin.toString() %></span> <%= gettext("to:") %> <span><%= annotation.end.toString() %></span> (<%= gettext("duration:") %> <span><%= annotation.getDuration().toString() %></span>)</p>'
             + '</div></div></div>'
         ),
@@ -2211,7 +2233,9 @@
         mediafoundtemplate = _.template(
             '<div class="media-segment"><div class="media-segment-section" style="left:<%= left %>px; width:<%= width %>px; background:<%= color %>; top: <%= top %>px;"></div>'
             + '<div class="popin media-found-popin" style="left:<%= popleft %>px; top: <%= 5+top %>px;"><div style="left:<%= pointerpos %>px;" class="pointer"></div><div class="popin-content">'
-            + '<h3><%= title %></h3><a href="#" class="button clone-segment" data-segment-id="<%= annotation.id %>"><%= gettext("Clone segment") %></a>'
+            + '<h3 class="segment-title"><%= title %></h3>'
+            + '<p><%= description %></p><% if (tags) { print("<p><strong>" + gettext("Tags:") + "</strong> " + tags + "</p>"); } %>'
+            + '<a href="#" class="button clone-segment" data-segment-id="<%= annotation.id %>"><%= gettext("Clone segment") %></a>'
             + '</div></div></div>'
         ),
         mediafoundlisttemplate = _.template(
@@ -2323,6 +2347,9 @@
     
     $(".col-left input").on("keyup change input paste", function() {
         var val = $(this).val();
+        if (val.length < 2) {
+            val = false;
+        }
         if (val) {
             var find = IriSP.Model.regexpFromTextOrArray(val, true),
                 replace = IriSP.Model.regexpFromTextOrArray(val, false);
@@ -2342,7 +2369,7 @@
                     var annotations = apimedia.getAnnotations().searchByTextFields(val);
                 } else {
                     var annotations = [];
-                }   
+                }
                 var found = find.test(media.title) || find.test(media.description) || annotations.length;
                 if (found) {
                     li.find(".title-video").html(media.title.replace(replace, '<span style="background: #fc00ff; color: #ffffff;">$1</span>'));
@@ -2370,6 +2397,8 @@
                             top: 8 * line.index,
                             color: IriSP.vizcolors[i % IriSP.vizcolors.length],
                             title: _a.title.replace(replace, '<span style="background: #fc00ff; color: #ffffff;">$1</span>'),
+                            description: _a.description.replace(replace, '<span style="background: #fc00ff; color: #ffffff;">$1</span>'),
+                            tags: _a.keywords.join(", ").replace(replace, '<span style="background: #fc00ff; color: #ffffff;">$1</span>'),
                             popleft : corrpos,
                             pointerpos : (pos - corrpos),
                         }
@@ -2399,7 +2428,7 @@
             }
         });
         if (critical) {
-            messages.push("One or more segments are invalid");
+            messages.push(gettext("One or more segments are invalid"));
         }
         
         _(mashupcritical).each(function(sc) {
@@ -2416,7 +2445,7 @@
         });
         mashup.status = critical ? "critical" : (warning ? "warning" : "valid");
         if (!messages.length) {
-            messages.push("Your hashcut is valid!");
+            messages.push(gettext("Your hashcut is valid!"));
         }
         mashupstatus = ' - ' + _(messages).join('\n - ');
         
@@ -2521,7 +2550,7 @@
             });
             currentSegment.status = critical ? "critical" : (warning ? "warning" : "valid");
             if (!messages.length) {
-                messages.push("This segment is valid!")
+                messages.push(gettext("This segment is valid!"))
             }
             currentSegment.status_messages = _(messages);
             
@@ -3191,7 +3220,8 @@
             '<div class="media-segment" data-mashup-id="<%= annotation.project_id %>">'
             + '<div class="media-segment-section" style="left:<%= left %>px; width:<%= width %>px; background:<%= color %>; top: <%= top %>px;" data-segment-id="<%= annotation.id %>"></div>'
             + '<div class="popin media-segment-popin" style="left:<%= popleft %>px; top: <%= 5+top %>px;"><div style="left:<%= pointerpos %>px;" class="pointer"></div><div class="popin-content">'
-            + '<h3><%= annotation.title %></h3>'
+            + '<h3 class="segment-title"><%= annotation.title %></h3>'
+            + '<p><%= annotation.description %></p><% if (annotation.keywords.length) { print("<p><strong>" + gettext("Tags:") + "</strong> " + annotation.keywords.join(", ") + "</p>"); } %>'
             + '<p><%= gettext("From:") %> <span><%= annotation.begin.toString() %></span> <%= gettext("to:") %> <span><%= annotation.end.toString() %></span> (<%= gettext("duration:") %> <span><%= annotation.getDuration().toString() %></span>)</p>'
             + '<p class="mashup-link"><%= gettext("From hashcut:") %> <a href="<%= IriSP.endpoints.hashcut_page.replace("__PROJECT_ID__", annotation.project_id) %>"></a></p>'
             + '</div></div></div>'