integration/js/mashupcore.js
changeset 41 3ec2343f2b85
child 43 5a5024bc74e6
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/integration/js/mashupcore.js	Thu Nov 08 18:24:47 2012 +0100
@@ -0,0 +1,632 @@
+IriSP.mashupcore = function(project, mashup) {
+    
+    var currentMedia,
+        intervaltemplate = _.template('<span class="frise-indication" style="left:<%= left %>%;"><%= time.toString() %></span>'),
+        viztemplate = _.template('<div class="frise-segment annotation" data-segment-id="<%= segmentid %>" style="background-color:<%= color %>; left:<%= left %>%; width:<%= width %>%;"></div>');
+
+    function updateMashupUI() {
+        var vizhtml = '', t = 0, k = mashup.duration ? (100 / mashup.duration) : 0;
+        mashup.segments.forEach(function(_s) {
+            var vizdata = {
+                left: k * t,
+                width: k * _s.duration,
+                color: _s.color,
+                segmentid: _s.annotation.id
+            }
+            vizhtml += viztemplate(vizdata);
+            t += _s.duration.milliseconds;
+        });
+        
+        var intervals = [ 1000, 2000, 5000, 10000, 30000, 60000, 120000, 300000, 600000, 900000, 1800000, 3600000, 7200000 ];
+        
+        function createIntervals(maxn) {
+            for (var i = 0; i < intervals.length; i++) {
+                if (mashup.duration / intervals[i] <= maxn) {
+                    var html = '';
+                    for (var j = intervals[i]; j < mashup.duration; j += intervals[i]) {
+                        html += intervaltemplate({ left: k * j, time: new IriSP.Model.Time(j) });
+                    }
+                    return html;
+                }
+            }
+            return "";
+        }
+        
+        $(".mashup-total-duration").text(mashup.duration.toString());
+        $(".mashup-frise .frise-segments").html(vizhtml);
+        $(".mashup-frise .frise-indications").html(createIntervals(6));
+        
+        if (currentMedia === mashup) {
+            $(".Ldt-Ctrl-Time-Total").text(currentMedia.duration.toString());
+            if (mashupTimecode > mashup.duration) {
+                mashup.setCurrentTime(mashup.duration);
+            }
+            changeCurrentAnnotation();
+            mashup.trigger("enter-annotation",mashupCurrentAnnotation);
+        }
+        
+    }
+    
+    /* Slider */
+    
+    var timeSlider = $(".Ldt-Slider"),
+        timeSliderContainer = $(".Ldt-Slider-Container"),
+        slidersRange = 920;
+    timeSlider.slider({
+        range: "min",
+        value: 0,
+        min: 0,
+        max: slidersRange,
+        slide: function(event, ui) {
+            if (currentMedia) {
+                var t = currentMedia.duration * ui.value / slidersRange;
+                currentMedia.setCurrentTime(t);
+            }
+        }
+    });
+    
+    var timeSliderHandle = timeSlider.find('.ui-slider-handle'),
+        timeSliderMaximized = false,
+        timeSliderTimeoutId = false,
+        timeSliderMinimizedHeight = 4,
+        timeSliderMaximizedHeight = 10,
+        timeSliderTimeoutDuration = 1500,
+        timeTooltip = $(".Ldt-Slider-Time");
+    
+    timeSliderContainer.css(calculateSliderCss(timeSliderMinimizedHeight));
+    timeSliderHandle.css(calculateHandleCss(timeSliderMinimizedHeight));
+    
+    function timeSliderMouseOver() {
+        if (timeSliderTimeoutId) {
+            window.clearTimeout(timeSliderTimeoutId);
+            timeSliderTimeoutId = false;
+        }
+        if (!timeSliderMaximized) {
+           timeSliderAnimateToHeight(timeSliderMaximizedHeight);
+           timeSliderMaximized = true;
+        }
+    }
+    
+    function timeSliderMouseOut() {
+        timeTooltip.hide();
+        if (timeSliderTimeoutId) {
+            clearTimeout(timeSliderTimeoutId);
+            timeSliderTimeoutId = false;
+        }
+        timeSliderTimeoutId = setTimeout(function() {
+            if (timeSliderMaximized) {
+                timeSliderAnimateToHeight(timeSliderMinimizedHeight);
+                timeSliderMaximized = false;
+            }
+            timeSliderTimeoutId = false;
+        }, timeSliderTimeoutDuration);
+    }
+    
+    timeSliderContainer
+        .mouseover(function() {
+            timeTooltip.show();
+            timeSliderMouseOver();
+        })
+        .mouseout(timeSliderMouseOut);
+    timeSlider.mousemove(function(_e) {
+            var _x = _e.pageX - timeSlider.offset().left,
+                _t = new IriSP.Model.Time(
+                );
+            timeTooltip.text(_t.toString()).css("left",_x);
+        });
+    
+    $(".Ldt-Ctrl").mouseover(timeSliderMouseOver).mouseout(timeSliderMouseOut);
+    
+    function timeSliderAnimateToHeight(_height) {
+        timeSliderContainer.stop().animate(
+            calculateSliderCss(_height),
+            500,
+            function() {
+                IriSP.jQuery(this).css("overflow","visible");
+            });
+        timeSliderHandle.stop().animate(
+            calculateHandleCss(_height),
+            500,
+            function() {
+                IriSP.jQuery(this).css("overflow","visible");
+            });
+    }
+
+    function calculateSliderCss(_size) {
+        return {
+            height: _size + "px",
+            "margin-top": (timeSliderMinimizedHeight - _size) + "px"
+        };
+    }
+
+    function calculateHandleCss(_size) {
+        return {
+            height: (2 + _size) + "px",
+            width: (2 + _size) + "px",
+            "margin-left": -Math.ceil(2 + _size / 2) + "px" 
+        }
+    }
+    
+    /* Controller Widget */
+   
+    var volBlock = $(".Ldt-Ctrl-Volume-Control");
+    
+    $('.Ldt-Ctrl-Sound')
+        .click(function() {
+            if (currentMedia) {
+                currentMedia.setMuted(!currentMedia.getMuted());
+            }
+        })
+        .mouseover(function() {
+            volBlock.show();
+        })
+        .mouseout(function() {
+            volBlock.hide();
+        });
+    volBlock.mouseover(function() {
+        volBlock.show();
+    }).mouseout(function() {
+        volBlock.hide();
+    });
+    
+    var volBar = $(".Ldt-Ctrl-Volume-Bar");
+    
+    function ctrlVolumeUpdater() {
+        if (currentMedia) {
+            var _muted = currentMedia.getMuted(),
+                _vol = currentMedia.getVolume();
+            if (_vol === false) {
+                _vol = .5;
+            }
+            var _soundCtl = $(".Ldt-Ctrl-Sound");
+            _soundCtl.removeClass("Ldt-Ctrl-Sound-Mute Ldt-Ctrl-Sound-Half Ldt-Ctrl-Sound-Full");
+            if (_muted) {        
+                _soundCtl.attr("title", "Activer le son")
+                    .addClass("Ldt-Ctrl-Sound-Mute");    
+            } else {
+                _soundCtl.attr("title", "Couper le son")
+                    .addClass(_vol < .5 ? "Ldt-Ctrl-Sound-Half" : "Ldt-Ctrl-Sound-Full" )
+            }
+            volBar.slider("value", _muted ? 0 : 100 * _vol);
+            volBar.attr("title",'Volume : ' + Math.floor(100 * _vol) + '%');
+        }
+    }
+    
+    volBar.slider({
+        slide: function(event, ui) {
+            if (currentMedia) {
+                currentMedia.setVolume(ui.value / 100);
+            }
+        }
+    });
+    
+    $(".Ldt-Ctrl-Play").click(function() {
+        if (currentMedia) {
+            if (currentMedia.getPaused()) {        
+                currentMedia.play();
+            } else {
+                currentMedia.pause();
+            }
+        }
+    });
+    
+    $(".Ldt-Ctrl-SetIn").click(function() {
+        if (currentMedia && currentSegment) {
+            currentSegment.setBegin(currentMedia.getCurrentTime());
+        }
+    });
+    $(".Ldt-Ctrl-SetOut").click(function() {
+        if (currentMedia && currentSegment) {
+            currentSegment.setEnd(currentMedia.getCurrentTime());
+        }
+    });
+    
+    /* 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);
+    }
+    
+    /* Mashup Player */
+   
+    mashup.currentMedia = null;
+   
+    var mashupCurrentAnnotation = null,
+        mashupSegmentBegin,
+        mashupSegmentEnd,
+        mashupTimecode = 0,
+        mashupSeeking = false,
+        seekdiv = $(".video-wait"),
+        mashupTimedelta;
+    
+    function showSeek() {
+        if (mashupSeeking) {
+            seekdiv.show();
+        }
+    }
+    
+    function changeCurrentAnnotation() {
+        if (mashupTimecode >= mashup.duration) {
+            if (!mashup.paused) {
+                mashup.paused = true;
+                mashup.trigger("pause");
+            }
+            mashupTimecode = 0;
+        }
+        var _annotation = mashup.getAnnotationAtTime( mashupTimecode );
+        if (typeof _annotation === "undefined") {
+            if (mashup.currentMedia) {
+                mashup.currentMedia.pause();
+                if (!mashup.paused) {
+                    mashup.paused = true;
+                    mashup.trigger("pause");
+                }
+            }
+            return;
+        }
+        mashupCurrentAnnotation = _annotation;
+        mashupSegmentBegin = mashupCurrentAnnotation.annotation.begin.milliseconds;
+        mashupSegmentEnd = mashupCurrentAnnotation.annotation.end.milliseconds;
+        mashupTimedelta = mashupSegmentBegin - mashupCurrentAnnotation.begin.milliseconds;
+        mashup.currentMedia = mashupCurrentAnnotation.getMedia();
+        
+        project.getMedias().forEach(function(_media) {
+            if (_media !== mashup.currentMedia) {
+                _media.hide();
+                _media.pause();
+            } else {
+                _media.show();
+            }
+        });
+        
+        mashup.currentMedia.setCurrentTime( mashupTimecode + mashupTimedelta);
+        mashup.currentMedia.seeking = true;
+        
+        if (!mashup.paused) {
+            mashup.currentMedia.play();
+            mashupSeeking = true;
+            setTimeout(showSeek,200);
+        }
+        mashup.trigger("timeupdate", new IriSP.Model.Time(mashupTimecode));
+
+    }
+    
+    function addMedia(media) {
+        if (media.has_player) {
+            return;
+        }
+        media.has_player = true;
+        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);
+        
+        media.show = function() {
+            videoEl.show();
+        }
+        media.hide = function() {
+            videoEl.hide();
+        }
+        
+        var popcorn = Popcorn("#" + videoid);
+        
+        // Binding functions to Popcorn
+        
+        media.on("setcurrenttime", function(_milliseconds) {
+            if (media.loaded) {
+                popcorn.currentTime(_milliseconds / 1000);
+            }
+        });
+        
+        media.on("setvolume", function(_vol) {
+            media.volume = _vol;
+            if (media.loaded) {
+                popcorn.volume(_vol);
+            }
+        });
+        
+        media.on("setmuted", function(_muted) {
+            media.muted = _muted;
+            if (media.loaded) {
+                popcorn.muted(_muted);
+            }
+        });
+        
+        media.on("setplay", function() {
+            if (media.loaded) {
+                popcorn.play();
+            }
+        });
+        
+        media.on("setpause", function() {
+            if (media.loaded) {
+                popcorn.pause();
+            }
+        });
+        
+        // Binding Popcorn events to media
+        
+        function getVolume() {
+            media.muted = popcorn.muted();
+            media.volume = popcorn.volume();
+        }
+        
+        popcorn.on("loadedmetadata", function() {
+            getVolume();
+            media.loaded = true;
+            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 and Mashup Playing to Media
+        
+        media.on("loadedmetadata", function() {
+            if (media === currentMedia) {
+                seekdiv.hide();
+            }
+            mashup.checkLoaded();
+        });
+        
+        media.on("play", function() {
+            if (media === currentMedia) {
+                onCurrentMediaPlay();
+            }
+            if (mashup === currentMedia && media === mashup.currentMedia) {
+                mashup.trigger("play");
+            }
+        });
+        
+        media.on("pause", function() {
+            if (media === currentMedia) {
+                onCurrentMediaPause();
+            }
+            if (mashup === currentMedia && media === mashup.currentMedia) {
+                mashup.trigger("pause");
+            }
+        });
+        
+        media.on("timeupdate", function(_time) {
+            if (media === currentMedia) {
+                onCurrentMediaTimeupdate(_time);
+            }
+            if (mashup === currentMedia && !mashup.paused && media === mashup.currentMedia && !media.seeking) {
+                if ( _time < mashupSegmentEnd ) {
+                    if ( _time >= mashupSegmentBegin ) {
+                        mashupTimecode = _time - mashupTimedelta;
+                    } else {
+                        mashupTimecode = mashupSegmentBegin - mashupTimedelta;
+                        media.setCurrentTime(mashupSegmentBegin);
+                    }
+                } else {
+                    mashupTimecode = mashupSegmentEnd - mashupTimedelta;
+                    media.pause();
+                    changeCurrentAnnotation();
+                }
+                mashup.trigger("timeupdate", new IriSP.Model.Time(mashupTimecode));
+            }
+        });
+        
+        media.on("seeked", function() {
+            media.seeking = false;
+            if (mashup === currentMedia && media === mashup.currentMedia && mashupSeeking) {
+                mashupSeeking = false;
+                seekdiv.hide();
+            }
+        });
+        
+        media.on("volumechange", function() {
+            if (media === currentMedia) {
+                ctrlVolumeUpdater();
+            }
+            mashup.muted = media.muted;
+            mashup.volume = media.volume;
+            mashup.trigger("volumechange");
+        });
+        
+        project.on("set-current", function(_m) {
+            if (_m !== media) {
+                media.hide();
+            }
+        });
+        
+    }
+
+    // Mashup Events
+    
+    mashup.on("setcurrenttime", function(_milliseconds) {
+        mashupTimecode = _milliseconds;
+        changeCurrentAnnotation();
+    });
+    
+    mashup.on("setvolume", function(_vol) {
+        mashup.getMedias().forEach(function(_media) {
+            _media.setVolume(_vol);
+        });
+        mashup.volume = _vol;
+    });
+    
+    mashup.on("setmuted", function(_muted) {
+        mashup.getMedias().forEach(function(_media) {
+            _media.setMuted(_muted);
+        });
+        mashup.muted = _muted;
+    });
+    
+    mashup.on("setplay", function() {
+        mashup.paused = false;
+        changeCurrentAnnotation();
+    });
+    
+    mashup.on("setpause", function() {
+        mashup.paused = true;
+        if (mashup.currentMedia) {
+            mashup.currentMedia.pause();
+        }
+    });
+    
+    mashup.on("loadedmetadata", function() {
+        if (mashup === currentMedia) {
+            changeCurrentAnnotation();
+        }
+    });
+    
+    /* Mashup Events to UI */
+   
+    mashup.on("play", function() {
+        if (mashup === currentMedia) {
+            onCurrentMediaPlay();
+        }
+    });
+    
+    mashup.on("pause", function() {
+        if (mashup === currentMedia) {
+            onCurrentMediaPause();
+        }
+    });
+    
+    mashup.on("timeupdate", function(_time) {
+        if (mashup === currentMedia) {
+            $(".frise-position").css("left",(100*_time/mashup.duration)+"%");
+            onCurrentMediaTimeupdate(_time);
+        }
+    });
+    
+    mashup.on("add", function() {
+        mashup.getMedias().forEach(addMedia);
+    })
+    
+    mashup.on("change",updateMashupUI);
+    
+    mashup.on("enter-annotation", function(segment) {
+        var a = segment.annotation;
+        $(".annotation-title").text(a.title);
+        $(".annotation-begin").text(a.begin.toString());
+        $(".annotation-end").text(a.end.toString());
+        $(".annotation-tags").text(a.keywords.join(", "));
+        $(".annotation-media-title").text(a.getMedia().title);
+        $(".annotation-description").text(a.description);
+        var p = (segment.begin + segment.end) / (2 * mashup.duration);
+        $(".mashup-description .pointer").css("left", (100 * p) + "%");
+        project.trigger("mouseout-annotation");
+    });
+    
+    project.on("mouseover-annotation", function(annotation) {
+        $(".annotation").removeClass("active");
+        if (!annotation) {
+            return;
+        }
+        $(".annotation[data-segment-id='" + annotation.id + "']").addClass("active");
+    });
+    
+    project.on("mouseout-annotation", function() {
+        if (currentMedia === mashup && mashupCurrentAnnotation) {
+            $(".annotation").removeClass("active");
+            $(".item-video.annotation[data-segment-id='" + mashupCurrentAnnotation.annotation.id + "']").addClass("active");
+        }
+    });
+    
+    project.on("click-annotation", function(annotation) {
+        if (!annotation) {
+            return;
+        }
+        var segment = mashup.getAnnotation(annotation);
+        project.trigger("set-current", mashup);
+        if (segment) {
+            mashup.setCurrentTime(segment.begin);
+        }
+    })
+    
+    project.on("set-current", function(media) {
+        currentMedia = media;
+        if (currentMedia.elementType === "media") {
+            if (!media.has_player) {
+                addMedia(media);
+            }
+            media.show();
+            if (!currentMedia.loaded) {
+                seekdiv.show();
+            }
+        }
+        if (currentMedia.elementType === "mashup") {
+            mashup.checkLoaded();
+        }
+        $(".Ldt-Ctrl-Time-Total").text(currentMedia.duration.toString());
+        currentMedia.trigger("timeupdate",currentMedia.getCurrentTime());
+        currentMedia.trigger("pause");
+    });
+    
+    $(".frise")
+    .on("mouseover", ".frise-segment", function() {
+        project.trigger("mouseover-annotation", project.getElement($(this).attr("data-segment-id")));
+    })
+    .on("mouseout", ".frise-segment", function() {
+        project.trigger("mouseout-annotation");
+    })
+    .on("click", ".frise-segment", function() {
+        project.trigger("click-annotation", project.getElement($(this).attr("data-segment-id")));
+    });
+    
+    mashup.trigger("add");
+    
+}