Implemented timerange for mdplayer and use of it in widget Segment: if enable (option is use_timerange) when clicking a segment user can only read the video on current segment + adapted other widgets that need to detect segment to be able to use this option if it is enable so that segment detection is smoother + adjusted API testing form on iframetesting to use the correct api (form is still hidden by default)
authordurandn
Mon, 03 Aug 2015 14:17:03 +0200
changeset 69 be6fde8f0ef9
parent 68 5002976e742d
child 70 7b65807314f5
Implemented timerange for mdplayer and use of it in widget Segment: if enable (option is use_timerange) when clicking a segment user can only read the video on current segment + adapted other widgets that need to detect segment to be able to use this option if it is enable so that segment detection is smoother + adjusted API testing form on iframetesting to use the correct api (form is still hidden by default)
server/src/remie/static/remie/metadataplayer/AnnotationsController.js
server/src/remie/static/remie/metadataplayer/AnnotationsList.js
server/src/remie/static/remie/metadataplayer/CurrentSegmentInfobox.js
server/src/remie/static/remie/metadataplayer/LatestAnnotation.js
server/src/remie/static/remie/metadataplayer/LdtPlayer-core.js
server/src/remie/static/remie/metadataplayer/Segments.js
server/src/remie/templates/remie/iframe.html
server/src/remie/templates/remie/iframe_tester.html
--- a/server/src/remie/static/remie/metadataplayer/AnnotationsController.js	Fri Jul 31 18:36:24 2015 +0200
+++ b/server/src/remie/static/remie/metadataplayer/AnnotationsController.js	Mon Aug 03 14:17:03 2015 +0200
@@ -57,7 +57,17 @@
             _this.player.trigger("CreateAnnotation.hide");
         }
     })
-    this.onMediaEvent("timeupdate", "onTimeUpdate")
+    
+    if(this.hide_without_segment){
+        this.onMediaEvent("timeupdate", function(){
+            _this.refresh();
+        })
+        this.onMediaEvent("settimerange", function(_timeRange){
+            _this.refresh(_timeRange);
+        })
+        this.segments = this.source.getAnnotationsByTypeTitle(this.segments_annotation_type)
+        this.currentSegment = false
+    }
     
     if (this.starts_hidden) {
         this.visible = true
@@ -70,14 +80,36 @@
     
 };
 
-IriSP.Widgets.AnnotationsController.prototype.onTimeUpdate = function(){
+IriSP.Widgets.AnnotationsController.prototype.refresh = function(_timeRange){
+    _timeRange = typeof _timeRange !== 'undefined' ? _timeRange : false ;
+    
     if (this.hide_without_segment){
-        _currentTime = this.media.getCurrentTime() 
-        _segmentsAnnotations = this.source.getAnnotationsByTypeTitle(this.segments_annotation_type)
-        _currentSegments = _segmentsAnnotations.filter(function(_segment){
-            return (_currentTime >= _segment.begin && _currentTime <= _segment.end)
-        });
-        if (_currentSegments.length == 0){
+        if (!_timeRange){
+            _currentTime = this.media.getCurrentTime() 
+            _currentSegments = this.segments.filter(function(_segment){
+                return (_currentTime >= _segment.begin && _currentTime <= _segment.end)
+            });
+            if(_currentSegments.length > 0){
+                currentSegment = true;
+            }
+            else {
+                currentSegment = false;
+            }
+        }
+        else {
+            var _timeRangeBegin = _timeRange[0],
+                _timeRangeEnd = _timeRange[1];
+            _currentSegments = this.segments.filter(function(_segment){
+                return (_timeRangeBegin == _segment.begin && _timeRangeEnd == _segment.end)
+            });
+            if(_currentSegments.length > 0){
+                currentSegment = true;
+            }
+            else {
+                currentSegment = false;
+            }
+        }
+        if (!currentSegment && _currentSegments.length == 0){
             if (this.visible){
                 this.hide();
                 this.player.trigger("CreateAnnotation.hide");
--- a/server/src/remie/static/remie/metadataplayer/AnnotationsList.js	Fri Jul 31 18:36:24 2015 +0200
+++ b/server/src/remie/static/remie/metadataplayer/AnnotationsList.js	Mon Aug 03 14:17:03 2015 +0200
@@ -190,9 +190,16 @@
          *  Note this is meant to be used for "markings" annotations (not segments)
          */
         _segmentsAnnotation = this.currentSource.getAnnotationsByTypeTitle(this.segments_annotation_type)
-        _currentSegments = _segmentsAnnotation.filter(function(_segment){
-            return (_currentTime >= _segment.begin && _currentTime <= _segment.end)
-        });
+        if (this.media.getTimeRange()){
+            _currentSegments = _segmentsAnnotation.filter(function(_segment){
+                return (_this.media.getTimeRange()[0] == _segment.begin && _this.media.getTimeRange()[1] == _segment.end)
+            });
+        }
+        else {
+            _currentSegments = _segmentsAnnotation.filter(function(_segment){
+                return (_currentTime >= _segment.begin && _currentTime <= _segment.end)
+            });
+        }
         if (_currentSegments.length == 0) {
             _list = _list.filter(function(_annotation){
                 return false;
@@ -554,11 +561,12 @@
     this.onMdpEvent("AnnotationsList.hide", "hide");
     this.onMdpEvent("AnnotationsList.show", "show");
     
-    this.onMdpEvent("createAnnotationWidget.addedAnnotation", "refresh");
+    this.onMdpEvent("createAnnotationWidget.addedAnnotation", this.throttledRefresh);
     var _events = [
         "timeupdate",
         "seeked",
-        "loadedmetadata"
+        "loadedmetadata",
+        "settimerange"
     ];
     for (var _i = 0; _i < _events.length; _i++) {
         this.onMediaEvent(_events[_i], this.throttledRefresh);
--- a/server/src/remie/static/remie/metadataplayer/CurrentSegmentInfobox.js	Fri Jul 31 18:36:24 2015 +0200
+++ b/server/src/remie/static/remie/metadataplayer/CurrentSegmentInfobox.js	Mon Aug 03 14:17:03 2015 +0200
@@ -9,7 +9,10 @@
 IriSP.Widgets.CurrentSegmentInfobox.prototype.defaults = {
     annotation_type: "chap",
     readonly: true,
-    empty_message: false
+    empty_message: false,
+    pause_on_segment_end: false,
+    // How long in milliseconds after segment's end can the player pause (less than 500 is unreliable)
+    pause_latency: 500 
 };
 
 IriSP.Widgets.CurrentSegmentInfobox.prototype.template = 
@@ -45,32 +48,60 @@
     this.segments = this.getWidgetAnnotations();
     
     this.renderTemplate();
+    this.currentSegment = false;
+    this.nextPauseOn = -1;
+    this.clearBox();
     this.refresh();
-    
     this.onMediaEvent("timeupdate", "refresh");
+    this.onMediaEvent("settimerange", function(_timeRange){
+        var _segmentBegin = _timeRange[0],
+            _segmentEnd = _timeRange[1],
+            _list = _this.segments.filter(function(_segment){
+            return _segment.begin == _segmentBegin && _segment.end == _segmentEnd
+        });
+        if (_list.length >0){
+            if (_this.currentSegment.id != _list[0].id){
+                _this.currentSegment = _list[0];
+                _data = {
+                    title: _this.currentSegment.title,
+                    description : _this.currentSegment.description,
+                    tags : _this.currentSegment.getTagTexts()
+                }
+                _this.$.html(Mustache.to_html(_this.template, _data))
+            }
+        }
+    });
 }
 
 IriSP.Widgets.CurrentSegmentInfobox.prototype.refresh = function() {
-    var _list = this.segments;
-    
-    _currentTime = this.media.getCurrentTime();
-    _list = _list.filter(function(_segment){
-        return (_segment.begin <= _currentTime && _segment.end >= _currentTime);
-    })
-    if (_list.length > 0){
-        _currentSegment = _list[0];
-        _data = {
-            title: _currentSegment.title,
-            description : _currentSegment.description,
-            tags : _currentSegment.getTagTexts()
+    if(!this.media.getTimeRange()){
+        var _currentTime = this.media.getCurrentTime();
+        var _list = this.segments.filter(function(_segment){
+            return (_segment.begin <= _currentTime && _segment.end >= _currentTime);
+        })
+        
+        if (_list.length > 0){
+            if (this.currentSegment.id != _list[0].id){
+                this.currentSegment = _list[0];
+                _data = {
+                    title: this.currentSegment.title,
+                    description : this.currentSegment.description,
+                    tags : this.currentSegment.getTagTexts()
+                }
+                this.$.html(Mustache.to_html(this.template, _data))
+            }
         }
-        this.$.html(Mustache.to_html(this.template, _data))
+        else {
+            this.currentSegment = false;
+            this.clearBox();
+        }
     }
-    else {
-        var _empty_message = this.l10n.empty
-        if (this.empty_message) {
-            _empty_message = this.empty_message
-        }
-        this.$.find(".Ldt-CurrentSegmentInfobox").html("<div class='Ldt-CurrentSegmentInfobox-Element Ldt-CurrentSegmentInfobox-NoSegment'>"+_empty_message+"</div>");
+}
+
+IriSP.Widgets.CurrentSegmentInfobox.prototype.clearBox = function(){
+    var _empty_message = this.l10n.empty
+    if (this.empty_message) {
+        _empty_message = this.empty_message
     }
+    this.$.find(".Ldt-CurrentSegmentInfobox").html("<div class='Ldt-CurrentSegmentInfobox-Element Ldt-CurrentSegmentInfobox-NoSegment'>"+_empty_message+"</div>");
 }
\ No newline at end of file
--- a/server/src/remie/static/remie/metadataplayer/LatestAnnotation.js	Fri Jul 31 18:36:24 2015 +0200
+++ b/server/src/remie/static/remie/metadataplayer/LatestAnnotation.js	Mon Aug 03 14:17:03 2015 +0200
@@ -63,8 +63,6 @@
     
     this.annotationContainer_$ = this.$.find('.Ldt-LatestAnnotation');
     
-    this.onMediaEvent("timeupdate", "refresh");
-    
     if (this.selectable_annotations){
         this.onMdpEvent("AnnotationsList.refresh", function(){
             _this.getWidgetAnnotations().forEach(function(_annotation){
@@ -84,13 +82,22 @@
             }); 
         });
         
-        var _segmentsAnnotations = _this.source.getAnnotationsByTypeTitle(this.segments_annotation_type)
-        _segmentsAnnotations.forEach(function(_segment){
+        this.segments = _this.source.getAnnotationsByTypeTitle(this.segments_annotation_type)
+        this.segments.forEach(function(_segment){
             _segment.on("click", function(){
                 _this.selectedAnnotation = false;
             })
         })
+        this.currentSegment = false;
     }
+    
+    this.onMediaEvent("timeupdate", function(){
+        _this.refresh();
+    });
+    this.onMediaEvent("settimerange", function(_timeRange){
+        _this.refresh(_timeRange);
+    })
+    
     if (this.starts_hidden){
         this.visible = true;
         this.hide();
@@ -101,31 +108,49 @@
     }
     
     this.selectedAnnotation = false; // This flag tells the widget if it must display last annotation (false) or clicked annotation (true)
-    this.player.trigger("AnnotationsList.refresh")
+    this.player.trigger("AnnotationsList.refresh");
     this.refresh();
 }
 
 
-IriSP.Widgets.LatestAnnotation.prototype.refresh = function(){ 
-    var _currentTime = this.media.getCurrentTime() 
-    var _segmentsAnnotations = this.source.getAnnotationsByTypeTitle(this.segments_annotation_type)
-    var _currentSegments = _segmentsAnnotations.filter(function(_segment){
-        return (_currentTime >= _segment.begin && _currentTime <= _segment.end)
-    });
-    
-    if (_currentSegments.length == 0){
-        this.selectedAnnotation = false;
-    }
-    
+IriSP.Widgets.LatestAnnotation.prototype.refresh = function(_timeRange){
+    _timeRange = typeof _timeRange !== 'undefined' ? _timeRange : false ;
+    var _this = this;
     if (this.hide_without_segment){
-        if (_currentSegments.length == 0){
+        if (!_timeRange && !this.media.getTimeRange()){
+            var _currentTime = this.media.getCurrentTime();
+            var _currentSegments = this.segments.filter(function(_segment){
+                return (_currentTime >= _segment.begin && _currentTime <= _segment.end)
+            });
+            if (_currentSegments.length == 0){
+                this.currentSegment = false;
+                this.selectedAnnotation = false;
+            }
+            else {
+                this.currentSegment = _currentSegments[0]
+            }
+        }
+        else {
+            var _segmentBegin = _timeRange? _timeRange[0] : this.media.getTimeRange()[0],
+                _segmentEnd = _timeRange? _timeRange[1] : this.media.getTimeRange()[1];
+            if ((!this.currentSegment)||(this.currentSegment.begin != _segmentBegin || this.currentSegment.end != _segmentEnd)) {
+                var _currentSegments = this.segments.filter(function(_segment){
+                    return _segment.begin == _segmentBegin && _segment.end == _segmentEnd
+                });
+                if (_currentSegments.length > 0){
+                    this.selectedAnnotation = false;
+                    this.currentSegment = _currentSegments[0];
+                }
+            }
+        }
+        if (!this.currentSegment){
             if (this.visible){
-                this.hide()
+                this.hide();
             }
         }
         else {
             if (!this.visible){
-                this.show()
+                this.show();
             }
         }
     }
@@ -134,7 +159,7 @@
         var _list = this.getWidgetAnnotations();
         
         if(this.filter_by_segment){
-            if (_currentSegments.length == 0) {
+            if (!this.currentSegment) {
                 _list = _list.filter(function(_annotation){
                     return false;
                 });
@@ -142,11 +167,10 @@
             else {
                 _list = _list.filter(function(_annotation){
                     _annotationTime = (_annotation.begin+_annotation.end)/2;
-                    return (_currentSegments[0].begin <= _annotationTime && _currentSegments[0].end >= _annotationTime);
+                    return (_this.currentSegment.begin <= _annotationTime && _this.currentSegment.end >= _annotationTime);
                 });
             }
         }
-        
         _list = _list.sortBy(function(_annotation){
             return _annotation.created;
         });
@@ -173,12 +197,11 @@
         }
         this.annotationContainer_$.html(_html);    
     }
-    
+
     if(this.copy_and_edit_button){
         this.copyAndEditButton_$ = this.$.find('.Ldt-LatestAnnotation-CopyEditButton');
         this.copyAndEditButton_$.click(this.functionWrapper("copy_and_edit"));
     }
-    
 }
 
 IriSP.Widgets.LatestAnnotation.prototype.copy_and_edit = function(){
--- a/server/src/remie/static/remie/metadataplayer/LdtPlayer-core.js	Fri Jul 31 18:36:24 2015 +0200
+++ b/server/src/remie/static/remie/metadataplayer/LdtPlayer-core.js	Mon Aug 03 14:17:03 2015 +0200
@@ -758,6 +758,7 @@
     this.volume = .5;
     this.paused = true;
     this.muted = false;
+    this.timeRange = false;
     this.loadedMetadata = false;
     var _this = this;
     this.on("play", function() {
@@ -782,6 +783,18 @@
             _a.trigger("enter");
             _this.trigger("enter-annotation",_a);
         });
+        
+        if (_this.getTimeRange()){
+            if (_this.getTimeRange()[0] > _time) {
+                _this.pause();
+                _this.setCurrentTime(_this.getTimeRange()[0]);
+            }
+            if (_this.getTimeRange()[1] < _time){
+                _this.pause();
+                _this.setCurrentTime(_this.getTimeRange()[1]);
+            }
+        }
+        
     });
     this.on("loadedmetadata", function() {
         _this.loadedMetadata = true;
@@ -806,6 +819,10 @@
     return this.muted;
 };
 
+Playable.prototype.getTimeRange = function() {
+    return this.timeRange;
+}
+
 Playable.prototype.setCurrentTime = function(_time) {
     this.trigger("setcurrenttime",_time);
 };
@@ -818,6 +835,16 @@
     this.trigger("setmuted",_muted);
 };
 
+Playable.prototype.setTimeRange = function(_timeBegin, _timeEnd) {
+    if ((_timeBegin < _timeEnd)&&(_timeBegin > 0)&&(_timeEnd>0)){
+        return this.trigger("settimerange", [_timeBegin, _timeEnd]);
+    }
+}
+
+Playable.prototype.resetTimeRange = function() {
+    return this.trigger("resettimerange");
+}
+
 Playable.prototype.play = function() {
     this.trigger("setplay");
 };
@@ -1465,6 +1492,20 @@
         }
     });
     
+    media.on("settimerange", function(_timeRange){
+        media.timeRange = _timeRange;
+        try {
+            if (media.getCurrentTime() > _timeRange[0] || media.getCurrentTime() < _timeRange){
+                mediaEl.currentTime = (_timeRange[0] / 1000);
+            }
+        } catch (err) {
+        }
+    })
+    
+    media.on("resettimerange", function(){
+        media.timeRange = false;
+    })
+    
     media.on("setplay", function() {
         try {
             mediaEl.play();
@@ -1517,8 +1558,6 @@
     videoEl.on("seeked", function() {
         media.trigger("seeked");
     });
-    
-    
 };
 /* START contentapi-serializer.js */
 
--- a/server/src/remie/static/remie/metadataplayer/Segments.js	Fri Jul 31 18:36:24 2015 +0200
+++ b/server/src/remie/static/remie/metadataplayer/Segments.js	Mon Aug 03 14:17:03 2015 +0200
@@ -14,7 +14,10 @@
     overlap: .25,
     found_color: "#FF00FC",
     faded_found_color: "#ff80fc",
-    no_tooltip: false
+    selected_color: "#74d600",
+    faded_selected_color: "#baf9b5",
+    no_tooltip: false,
+    use_timerange: false,
 };
 
 IriSP.Widgets.Segments.prototype.template =
@@ -97,6 +100,32 @@
                 _annotation.trigger("unselect");
             })
             .click(function() {
+                if(_this.use_timerange){
+                    if(!_this.media.getTimeRange()){
+                        _this.media.setTimeRange(_annotation.begin, _annotation.end)              
+                        _this.$segments.each(function(){
+                            var _segment = IriSP.jQuery(this);
+                            _segment.css("background", lowcolor).removeClass("selected");
+                        })
+                        _el.css("background", _this.selected_color).addClass("selected");
+                    }
+                    else if (_this.media.getTimeRange()[0]==_annotation.begin || _this.media.getTimeRange()[1]==_annotation.end){
+                        _this.media.resetTimeRange();
+                        _this.$segments.each(function(){
+                            var _segment = IriSP.jQuery(this);
+                            _segment.css("background", lowcolor).removeClass("selected");
+                            _annotation.trigger("select");
+                        })
+                    }
+                    else {
+                        _this.media.setTimeRange(_annotation.begin, _annotation.end);
+                        _this.$segments.each(function(){
+                            var _segment = IriSP.jQuery(this);
+                            _segment.css("background", lowcolor).removeClass("selected");
+                        })
+                        _el.css("background", _this.selected_color).addClass("selected");
+                    }
+                }
                 _annotation.trigger("click");
             })
             .appendTo(list_$);
@@ -114,9 +143,13 @@
                 _segment.css({
                     background: _segment.hasClass("found") ? _this.faded_found_color : _segment.attr("data-low-color")
                 });
+                _segment.css({
+                    background: _segment.hasClass("selected") ? _this.faded_selected_color : _segment.attr("data-low-color")
+                })
             });
             _el.css({
                 background: _el.hasClass("found") ? _this.found_color: color,
+                background: _el.hasClass("selected") ? _this.selected_color: color,
                 "z-index": ++zindex
             });
             if (_this.tooltip) {
@@ -130,6 +163,7 @@
             _this.$segments.each(function() {
                 var _segment = IriSP.jQuery(this);
                 _segment.css("background", _segment.hasClass("found") ? _this.found_color : _segment.attr(searching ? "data-low-color" : "data-medium-color"));
+                _segment.css("background", _segment.hasClass("selected") ? _this.selected_color : _segment.attr(searching ? "data-low-color" : "data-medium-color"));
             });
         });
         _annotation.on("found", function() {
--- a/server/src/remie/templates/remie/iframe.html	Fri Jul 31 18:36:24 2015 +0200
+++ b/server/src/remie/templates/remie/iframe.html	Mon Aug 03 14:17:03 2015 +0200
@@ -77,7 +77,9 @@
             annotation_type: "découpage",
             line_height: 24,
             overlap: 1,
-            no_tooltip: true
+            no_tooltip: true,
+            use_timerange: true,
+            
         },{
             type: "AnnotationsController",
             container: "AnnotationsController_container",
--- a/server/src/remie/templates/remie/iframe_tester.html	Fri Jul 31 18:36:24 2015 +0200
+++ b/server/src/remie/templates/remie/iframe_tester.html	Mon Aug 03 14:17:03 2015 +0200
@@ -32,9 +32,8 @@
 	    }
 	    
 	    $("#copy_button").click(function(){
-	        var project_id = $("#project_id_copy").val();
-	        var copy_title = $("#title_copy").val();
-			console.log(project_id)
+	        var _project_id = $("#project_id_copy").val();
+	        var _copy_title = $("#title_copy").val();
 		    var csrftoken = getCookie('csrftoken');
 		    
 	        function csrfSafeMethod(method) {
@@ -50,11 +49,29 @@
 	                $("#success_copy").html("Copie en cours ... ");
 	            }
 	        });
+	        var _data = 
+	        '{'
+            + '"meta": {'
+            + '"dc:creator": "admin",'
+            + '"dc:contributor": "admin",'
+            + '"dc:title": "'+_copy_title+'",'
+            + '"dc:created": "",'
+            + '"dc:modified": "",'
+            + '"dc:description": "",'
+            + '"iricle:status": 2'
+            + '},'
+            + '"views": [],'
+            + '"lists": [],'
+            + '"annotation-types": [],'
+            + '"medias": [],'
+            + '"tags": [],'
+            + '"annotations": []'
+            + '}';
 	        $.ajax({
 	        	method: "POST",
-        	    url: '{% url "api_dispatch_list" resource_name="projects" api_name="1.0" %}?format=json&publish=true&source='+project_id,
-                contentType: 'application/json',
-        	    data: '{"source": "'+project_id+'", "title": "'+copy_title+'", "publish": "true"}',
+        	    url: '{% url "api_dispatch_list" resource_name="projects" api_name="1.0" %}?source='+_project_id,
+                contentType: 'application/cinelab',
+        	    data: _data,
 	        	success: function(_data, _status, _request) {
 	                $("#success_copy").css("color", "green");
 	                $("#success_copy").html("Copie réussie: la ressource est atteignable en "+_request.getResponseHeader('Location'));
@@ -75,7 +92,7 @@
   <br><input id="iframe_update_button" type="button" value="Générer"></input>
 </div>
 <div hidden="true">
-  <label>Id projet (copie via l'API): </label><input id="project_id_copy" type="text"></input>
+  <label>Id projet (copie via l'API): </label><input id="projecÒt_id_copy" type="text"></input>
   <br><label>Titre de la copie: </label><input id="title_copy" type="text"></input>
   <br><input id="copy_button" type="button" value="Copier"></input>
   <div id="success_copy"></div>