integration/js/editor.js
author veltr
Mon, 29 Oct 2012 18:11:09 +0100
changeset 26 7c394ea40f28
parent 25 eea45f9b124b
parent 24 1fbf7d835dc2
child 27 b2d068afdbd8
permissions -rw-r--r--
Merge with 1fbf7d835dc2bbe1caed72774d4aaa247d944090

IriSP.Hashcut = function() {
    
    /* Load Media List */
    
    var directory = new IriSP.Model.Directory(),
        project = directory.remoteSource({
            url: "data/bpidata.json",
            serializer: IriSP.serializers.medialist
        }),
        mashup = new IriSP.Model.Mashup(false, project),
        mediatemplate = '<li class="item-video" data-media-id="{{id}}"><img src="{{thumbnail}}" alt="{{title}}" />'
            + '<span class="video-info"><span class="title-video">{{title}}</span><span class="author">{{description}}</span>'
            + '<span class="time-length">Durée : <span>{{duration}}</span></span></span></li>',
        segmenttemplate = '<li class="item-video" data-segment-id="{{id}}"><img src="{{annotation.thumbnail}}" alt="{{media_title}}" />'
            + '<span class="video-info"><span class="title-video">{{media_title}}</span>'
            + '<span class="subtitle">{{title}}</span><span class="duration">{{begin}} - {{end}} ({{duration}})</span>'
            + '<ul class="tools"><li><a class="edit" href="#"></a></li><li><a class="bottom" href="#"></a></li>'
            + '<li><a class="top" href="#"></a></li><li><a class="delete" href="#"></a></li></ul></span></li>';

    /* Fill left column with Media List */

    project.onLoad(function() {
        var html = '';
        project.getMedias().forEach(function(_m) {
            html += Mustache.to_html(mediatemplate, _m);
        });
        $(".col-left .list-video").html(html);
    });
    
    /* Search Media with left column form */
    
    $(".col-left input").on("keyup change input paste", function() {
        var val = $(this).val();
        if (val) {
            var find = IriSP.Model.regexpFromTextOrArray(val, true),
                replace = IriSP.Model.regexpFromTextOrArray(val, false);
        }
        $(".col-left .item-video").each(function() {
            var li = $(this),
                title = $(this).find(".title-video"),
                titletext = title.text();
            if (val && find.test(titletext)) {
                title.html(titletext.replace(replace, '<span style="background: yellow;">$1</span>'));
                li.show();
            } else {
                title.text(titletext);
                if (val) {
                    li.hide();
                } else {
                    li.show();
                }
            }
        })
    });
    
    /* Fill right column when mashup is updated */
   
    function fillRightColumn() {
        var html = '';
        mashup.segments.forEach(function(_s) {
            html += Mustache.to_html(segmenttemplate, _s);
        });
        $(".col-right .list-video").html(html);
    }
    
    mashup.on("add-segments",fillRightColumn);
    
    /* Slider */
   
    var timeSlider = $(".Ldt-Slider"),
        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");
    
    timeSlider.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);
    }
    
    timeSlider
        .mouseover(function() {
            timeTooltip.show();
            timeSliderMouseOver();
        })
        .mouseout(timeSliderMouseOut)
        .mousemove(function(_e) {
            var _x = _e.pageX - timeSlider.offset().left,
                _t = new IriSP.Model.Time(
                    currentMedia ? currentMedia.duration * _x / timeSlider.width() : 0
                );
            timeTooltip.text(_t.toString()).css("left",_x);
        });
    
    $(".Ldt-Ctrl").mouseover(timeSliderMouseOver).mouseout(timeSliderMouseOut);
    
    function timeSliderAnimateToHeight(_height) {
        timeSlider.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 && currentMedia.currentSegment) {
            currentMedia.currentSegment.setBegin(currentMedia.getCurrentTime());
        }
    });
    $(".Ldt-Ctrl-SetOut").click(function() {
        if (currentMedia && currentMedia.currentSegment) {
            currentMedia.currentSegment.setEnd(currentMedia.getCurrentTime());
        }
    });
    
    /* Slice Widget */
   
    var sliceSlider = $(".Ldt-Slice"),
        sliceStartTime;
    
    sliceSlider.slider({
        range: true,
        values: [0, slidersRange],
        min: 0,
        max: slidersRange,
        start: function() {
            if (currentMedia) {
                if (!currentMedia.getPaused()) {
                    currentMedia.pause();
                }
            }
        },
        slide: function(event, ui) {
            if (currentMedia && currentMedia.currentSegment) {
                var t = currentMedia.duration * ui.value / slidersRange;
                if (ui.value === ui.values[0]) {
                    currentMedia.currentSegment.setBegin(t);
                } else {
                    currentMedia.currentSegment.setEnd(t);
                }
            }
        }
    });
    
    sliceSlider.find(".ui-slider-handle:first")
        .addClass("Ldt-Slice-left-handle")
        .click(function() {
            if (currentMedia && currentMedia.currentSegment) {
                currentMedia.setCurrentTime(currentMedia.currentSegment.begin);
            }
        });
    sliceSlider.find(".ui-slider-handle:last")
        .addClass("Ldt-Slice-right-handle")
        .click(function() {
            if (currentMedia && currentMedia.currentSegment) {
                currentMedia.setCurrentTime(currentMedia.currentSegment.end);
            }
        });
    
    /* 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 updateSliderAndTangles() {
        if (currentMedia && currentMedia.currentSegment) {
            var start = currentMedia.currentSegment.begin,
                end = currentMedia.currentSegment.end,
                dur = currentMedia.currentSegment.getDuration(),
                f = slidersRange / currentMedia.duration;
            sliceSlider.slider( "values", [ f * start, f * end ] );
            $(".tangle-start").text(start.toString()).attr("data-milliseconds",start.milliseconds);
            $(".tangle-end").text(end.toString()).attr("data-milliseconds",end.milliseconds);
            $(".tangle-duration").text(dur.toString()).attr("data-milliseconds",dur.milliseconds);
            $(".segment-info .pointer").css("left",(parseFloat($(".Ldt-Slice-left-handle").css("left")) + parseFloat($(".Ldt-Slice-right-handle").css("left")))/2)
        }
    }
    
    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") {
            $(".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);
            if (!currentMedia.currentSegment) {
                currentMedia.currentSegment = new IriSP.Model.Annotation(false, project);
                currentMedia.currentSegment.setMedia(currentMedia.id);
                currentMedia.currentSegment.setBegin(0);
                currentMedia.currentSegment.setEnd(currentMedia.duration);
                currentMedia.currentSegment.thumbnail = currentMedia.thumbnail;
                currentMedia.currentSegment.title = "Segment sans titre";
                currentMedia.currentSegment.description = "Extrait de « " + currentMedia.title + " »";
                currentMedia.currentSegment.on("change-begin", function() {
                    if (currentMedia && currentMedia.currentSegment === this) {
                        currentMedia.setCurrentTime(this.begin);
                        updateSliderAndTangles();
                    }
                });
                currentMedia.currentSegment.on("change-end", function() {
                    if (currentMedia && currentMedia.currentSegment === this) {
                        currentMedia.setCurrentTime(this.end);
                        updateSliderAndTangles();
                    }
                });
            }
            updateSliderAndTangles();
        }
        currentvideo.show();
        $(".Ldt-Ctrl-Time-Total").text(currentMedia.duration.toString());
        $("#segment-title").val(currentMedia.currentSegment.title);
        $("#segment-description").text(currentMedia.currentSegment.description);
        // TODO: Do something with the tags !
        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);
            }
        });
        
        media.on("volumechange", function() {
            if (media === currentMedia) {
                ctrlVolumeUpdater();
            }
        })
        
    }
    
    /* Segment Form interaction */
   
    $("#segment-title").on("keyup change input paste", function() {
        if (currentMedia && currentMedia.currentSegment) {
            currentMedia.currentSegment.title = $(this).val();
        }
    });
    $("#segment-description").on("keyup change input paste", function() {
        if (currentMedia && currentMedia.currentSegment) {
            currentMedia.currentSegment.title = $(this).val();
        }
    });
    $("#segment-form").submit(function() {
        mashup.addSegment(currentMedia.currentSegment);
        currentMedia.currentSegment = undefined;
    })
    
    /* Click on media items */
   
    $(".col-left").on("click", ".item-video", function() {
        setMedia($(this).attr("data-media-id"));
    });
    
    /* Click on Tabs */
    
    function showSegmentation() {
        $(".col-middle").removeClass("empty-mode pvw-mode").addClass("segment-mode");
        return false;
    }
    function showPreview() {
        $(".col-middle").removeClass("empty-mode segment-mode").addClass("pvw-mode");
        return false;
    }
    
    $(".tab-pvw").click(showPreview);
    
    function disableMoveItemVideo() {
        $(".organize-segments .top, .organize-segments .bottom").removeClass("disable");
        $(".organize-segments .item-video:last-child .bottom, .organize-segments .item-video:first-child .top").addClass("disable");
    }
    disableMoveItemVideo();
    
    $(".organize-segments").sortable({
        stop : function(){
            disableMoveItemVideo();
        }
    });
    
    $(".organize-segments .top").click(function(e){
        var currentItem = $(this).parents(".item-video");
        currentItem.insertBefore(currentItem.prev());
        disableMoveItemVideo();
    });
    
    $(".organize-segments .bottom").click(function(e){
        var currentItem = $(this).parents(".item-video");
        currentItem.insertAfter(currentItem.next());
        disableMoveItemVideo();
    });
    
    /* Tangles */
    var tangleMsPerPixel = 100,
        activeTangle,
        tangleStartX,
        tangleStartVal,
        tangleHasMoved;
    
    $(".time-tangle").mousedown(function(evt) {
        activeTangle = $(this);
        activeTangle.addClass("active");
        tangleStartVal = +activeTangle.attr("data-milliseconds");
        tangleStartX = evt.pageX;
        tangleHasMoved = false;
        $(this).siblings(".time-tangle").addClass("deactivate");
        return false;
    });
    $(document)
        .mousemove(function(evt) {
            if (activeTangle) {
                tangleHasMoved = true;
                var newval = new IriSP.Model.Time(tangleMsPerPixel * (evt.pageX - tangleStartX) + tangleStartVal);
                activeTangle.trigger("valuechange", newval);
                return false;
            }
        })
        .mouseup(function() {
            if (activeTangle) {
                $(".time-tangle").removeClass("active deactivate");
                activeTangle = undefined;
            }
        });
        
    $(".tangle-start")
        .mouseup(function(evt) {
            if (!tangleHasMoved && currentMedia && currentMedia.currentSegment) {
                currentMedia.setCurrentTime(currentMedia.currentSegment.begin);
            }
        })
        .on("valuechange", function(evt, val) {
            if (currentMedia && currentMedia.currentSegment) {
                currentMedia.currentSegment.setBegin(val);
            }
        });
    $(".tangle-end")
        .mouseup(function(evt) {
            if (!tangleHasMoved && currentMedia && currentMedia.currentSegment) {
                currentMedia.setCurrentTime(currentMedia.currentSegment.end);
            }
        })
        .on("valuechange", function(evt, val) {
            if (currentMedia && currentMedia.currentSegment) {
                currentMedia.currentSegment.setEnd(val);
            }
        });
    $(".tangle-duration").on("valuechange", function(evt, val) {
        if (currentMedia && currentMedia.currentSegment) {
            currentMedia.currentSegment.setDuration(val);
        }
    });
}

$(function() {
    var hashcut = new IriSP.Hashcut();
});