更改rangelider的起点videojs

时间:2017-02-05 13:24:30

标签: javascript reactjs video.js rangeslider

我在我的反应应用程序中使用videojs。我已经添加了rangelider。我的视频播放器附近有一个按钮,可以触发测距播放器显示在视频播放器上。一切都运行正常,但是rangelider的起始箭头不在我点击按钮的点(时间)。开始按钮始终为0:0。我想要的是:说视频在当前时间30:00播放,然后我点击了显示按钮,然后测距应该只在30秒显示它的起始箭头而不是在o秒。我可以获取videojs播放器的当前时间并将其传递给rangeslider.js插件,但我不知道将它传递到何处。

这是我的rangelider.js(我知道它是一个很长的代码,但我不知道它的哪一部分用来实现结果)

//----------------Load Plugin----------------//
(function () {
    var videojsAddClass = function (element, className) {
        element.classList.add(className);
    };
    var videojsRemoveClass = function (element, className) {
        element.classList.remove(className);
    };
    var videojsFindPosition = function (element) {
        return element.getBoundingClientRect();
    };

    var videojsRound = function (n, precision) {
        return parseFloat(n.toFixed(precision));
    };
    var videojsFormatTime = function (totalSeconds) {
        var minutes = Math.floor(totalSeconds / 60).toFixed(0);
        var seconds = (totalSeconds % 60).toFixed(0);

        if (seconds.length === 1) {
            seconds = "0" + seconds;
        }

        return minutes + ':' + seconds;
    };
    var videojsBlockTextSelection = function () {
        // TODO
    };

//-- Load RangeSlider plugin in videojs
    function RangeSlider_(options) {
        var player = this;

        player.rangeslider = new RangeSlider(player, options);

        //When the DOM and the video media is loaded
        function initialVideoFinished(event) {
            var plugin = player.rangeslider;
            //All components will be initialize after they have been loaded by videojs
            for (var index in plugin.components) {
                plugin.components[index].init_();
            }

            if (plugin.options.hidden)
                plugin.hide(); //Hide the Range Slider

            if (plugin.options.locked)
                plugin.lock(); //Lock the Range Slider

            if (plugin.options.panel == false)
                plugin.hidePanel(); //Hide the second Panel

            if (plugin.options.controlTime == false)
                plugin.hidecontrolTime(); //Hide the control time panel

            plugin._reset();
            player.trigger('loadedRangeSlider'); //Let know if the Range Slider DOM is ready
        }
        if (player.techName == 'Youtube') {
            //Detect youtube problems
            player.one('error', function (e) {
                switch (player.error) {
                    case 2:
                        alert("The request contains an invalid parameter value. For example, this error occurs if you specify a video ID that does not have 11 characters, or if the video ID contains invalid characters, such as exclamation points or asterisks.");
                    case 5:
                        alert("The requested content cannot be played in an HTML5 player or another error related to the HTML5 player has occurred.");
                    case 100:
                        alert("The video requested was not found. This error occurs when a video has been removed (for any reason) or has been marked as private.");
                        break;
                    case 101:
                        alert("The owner of the requested video does not allow it to be played in embedded players.");
                        break;
                    case 150:
                        alert("The owner of the requested video does not allow it to be played in embedded players.");
                        break;
                    default:
                        alert("Unknown Error");
                        break;
                }
            });
            player.on('firstplay', initialVideoFinished);
        } else {
            player.one('playing', initialVideoFinished);
        }

    }
    videojs.plugin('rangeslider', RangeSlider_);



//-- Plugin
    function RangeSlider(player, options) {
        var player = player || this;

        this.player = player;

        this.components = {}; // holds any custom components we add to the player

        options = options || {}; // plugin options

        if (!options.hasOwnProperty('locked'))
            options.locked = false; // lock slider handles

        if (!options.hasOwnProperty('hidden'))
            options.hidden = true; // hide slider handles

        if (!options.hasOwnProperty('panel'))
            options.panel = true; // Show Second Panel

        if (!options.hasOwnProperty('controlTime'))
            options.controlTime = true; // Show Control Time to set the arrows in the edition

        this.options = options;

        this.init();
    }

//-- Methods
    RangeSlider.prototype = {
        /*Constructor*/
        init: function () {
            var player = this.player || {};

            this.updatePrecision = 3;

            //position in second of the arrows
            this.start = 0;
            this.end = 0;

            //components of the plugin
            var controlBar = player.controlBar;
            var seekBar = controlBar.progressControl.seekBar;
            this.components.RSTimeBar = seekBar.RSTimeBar;
            this.components.ControlTimePanel = controlBar.ControlTimePanel;

            //Save local component
            this.rstb = this.components.RSTimeBar;
            this.box = this.components.SeekRSBar = this.rstb.SeekRSBar;
            this.bar = this.components.SelectionBar = this.box.SelectionBar;
            this.left = this.components.SelectionBarLeft = this.box.SelectionBarLeft;
            this.right = this.components.SelectionBarRight = this.box.SelectionBarRight;
            this.tp = this.components.TimePanel = this.box.TimePanel;
            this.tpl = this.components.TimePanelLeft = this.tp.TimePanelLeft;
            this.tpr = this.components.TimePanelRight = this.tp.TimePanelRight;
            this.ctp = this.components.ControlTimePanel;
            this.ctpl = this.components.ControlTimePanelLeft = this.ctp.ControlTimePanelLeft;
            this.ctpr = this.components.ControlTimePanelRight = this.ctp.ControlTimePanelRight;

        },

        show: function () {
            this.options.hidden = false;
            if (typeof this.rstb != 'undefined') {
                this.rstb.show();
                if (this.options.controlTime)
                    this.showcontrolTime();
            }
        },
        hide: function () {
            this.options.hidden = true;
            if (typeof this.rstb != 'undefined') {
                this.rstb.hide();
                this.ctp.hide();
            }
        },
        showPanel: function () {
            this.options.panel = true;
            if (typeof this.tp != 'undefined')
                videojsRemoveClass(this.tp.el_, 'disable');
        },

        showcontrolTime: function () {
            this.options.controlTime = true;
            if (typeof this.ctp != 'undefined')
                this.ctp.show();
        },
        hidecontrolTime: function () {
            this.options.controlTime = false;
            if (typeof this.ctp != 'undefined')
                this.ctp.hide();
        },
        setValue: function (index, seconds, writeControlTime) {
            //index = 0 for the left Arrow and 1 for the right Arrow. Value in seconds
            var writeControlTime = typeof writeControlTime != 'undefined' ? writeControlTime : true;

            var percent = this._percent(seconds);
            var isValidIndex = (index === 0 || index === 1);
            var isChangeable = !this.locked;
            if (isChangeable && isValidIndex)
                this.box.setPosition(index, percent, writeControlTime);
        },
        setValues: function (start, end, writeControlTime) {
            //index = 0 for the left Arrow and 1 for the right Arrow. Value in seconds
            var writeControlTime = typeof writeControlTime != 'undefined' ? writeControlTime : true;

            this._reset();

            this._setValuesLocked(start, end, writeControlTime);
        },
        getValues: function () { //get values in seconds
            var values = {}, start, end;
            start = this.start || this._getArrowValue(0);
            end = this.end || this._getArrowValue(1);
            return {start: start, end: end};
        },


        _getArrowValue: function (index) {
            var index = index || 0;
            var duration = this.player.duration();

            duration = typeof duration == 'undefined' ? 0 : duration;

            var percentage = this[index === 0 ? "left" : "right"].el_.style.left.replace("%", "");
            if (percentage == "")
                percentage = index === 0 ? 0 : 100;

            return videojsRound(this._seconds(percentage / 100), this.updatePrecision - 1);
        },
        _percent: function (seconds) {
            var duration = this.player.duration();
            if (isNaN(duration)) {
                return 0;
            }
            return Math.min(1, Math.max(0, seconds / duration));
        },
        _seconds: function (percent) {
            var duration = this.player.duration();
            if (isNaN(duration)) {
                return 0;
            }
            return Math.min(duration, Math.max(0, percent * duration));
        },
        _reset: function () {
            var duration = this.player.duration();
            this.tpl.el_.style.left = '0%';
            this.tpr.el_.style.left = '100%';
            this._setValuesLocked(0, duration);
        },
        _setValuesLocked: function (start, end, writeControlTime) {
            var triggerSliderChange = typeof writeControlTime != 'undefined';
            var writeControlTime = typeof writeControlTime != 'undefined' ? writeControlTime : true;
            if (this.options.locked) {
                this.unlock();//It is unlocked to change the bar position. In the end it will return the value.
                this.setValue(0, start, writeControlTime);
                this.setValue(1, end, writeControlTime);
                this.lock();
            } else {
                this.setValue(0, start, writeControlTime);
                this.setValue(1, end, writeControlTime);
            }

            // Trigger slider change
            if (triggerSliderChange) {
                this._triggerSliderChange();
            }
        },
        _checkControlTime: function (index, TextInput, timeOld) {
            var h = TextInput[0],
                m = TextInput[1],
                s = TextInput[2],
                newHour = h.value,
                newMin = m.value,
                newSec = s.value,
                obj, objNew, objOld;
            index = index || 0;

            if (newHour != timeOld[0]) {
                obj = h;
                objNew = newHour;
                objOld = timeOld[0];
            } else if (newMin != timeOld[1]) {
                obj = m;
                objNew = newMin;
                objOld = timeOld[1];
            } else if (newSec != timeOld[2]) {
                obj = s;
                objNew = newSec;
                objOld = timeOld[2];
            } else {
                return false;
            }

            var duration = this.player.duration() || 0,
                durationSel;

            var intRegex = /^\d+$/;//check if the objNew is an integer
            if (!intRegex.test(objNew) || objNew > 60) {
                objNew = objNew == "" ? "" : objOld;
            }

            newHour = newHour == "" ? 0 : newHour;
            newMin = newMin == "" ? 0 : newMin;
            newSec = newSec == "" ? 0 : newSec;

            durationSel = videojs.TextTrack.prototype.parseCueTime(newHour + ":" + newMin + ":" + newSec);
            if (durationSel > duration) {
                obj.value = objOld;
                obj.style.border = "1px solid red";
            } else {
                obj.value = objNew;
                h.style.border = m.style.border = s.style.border = "1px solid transparent";
                this.setValue(index, durationSel, false);

                // Trigger slider change
                this._triggerSliderChange();
            }
            if (index === 1) {
                var oldTimeLeft = this.ctpl.el_.children,
                    durationSelLeft = videojs.TextTrack.prototype.parseCueTime(oldTimeLeft[0].value + ":" + oldTimeLeft[1].value + ":" + oldTimeLeft[2].value);
                if (durationSel < durationSelLeft) {
                    obj.style.border = "1px solid red";
                }
            } else {

                var oldTimeRight = this.ctpr.el_.children,
                    durationSelRight = videojs.TextTrack.prototype.parseCueTime(oldTimeRight[0].value + ":" + oldTimeRight[1].value + ":" + oldTimeRight[2].value);
                if (durationSel > durationSelRight) {
                    obj.style.border = "1px solid red";
                }
            }
        },
        _triggerSliderChange: function () {
            this.player.trigger("sliderchange");
        }
    };


//----------------Public Functions----------------//

//-- Public Functions added to video-js

    var videojsPlayer = videojs.getComponent('Player');

//Lock the Slider bar and it will not be possible to change the arrow positions
    videojsPlayer.prototype.lockSlider = function () {
        return this.rangeslider.lock();
    };

//Unlock the Slider bar and it will be possible to change the arrow positions
    videojsPlayer.prototype.unlockSlider = function () {
        return this.rangeslider.unlock();
    };

//Show the Slider Bar Component
    videojsPlayer.prototype.showSlider = function () {
        return this.rangeslider.show();
    };

//Hide the Slider Bar Component
    videojsPlayer.prototype.hideSlider = function () {
        return this.rangeslider.hide();
    };

//Show the Panel with the seconds of the selection
    videojsPlayer.prototype.showSliderPanel = function () {
        return this.rangeslider.showPanel();
    };

//Hide the Panel with the seconds of the selection
    videojsPlayer.prototype.hideSliderPanel = function () {
        return this.rangeslider.hidePanel();
    };


//Show the control Time to edit the position of the arrows
    videojsPlayer.prototype.showControlTime = function () {
        return this.rangeslider.showcontrolTime();
    };

//Hide the control Time to edit the position of the arrows
    videojsPlayer.prototype.hideControlTime = function () {
        return this.rangeslider.hidecontrolTime();
    };

//Set a Value in second for both arrows
    videojsPlayer.prototype.setValueSlider = function (start, end) {
        return this.rangeslider.setValues(start, end);
    };

//The video will be played in a selected section
    videojsPlayer.prototype.playBetween = function (start, end) {
        return this.rangeslider.playBetween(start, end);
    };

//The video will loop between to values
    videojsPlayer.prototype.loopBetween = function (start, end) {
        return this.rangeslider.loop(start, end);
    };

//Set a Value in second for the arrows
    videojsPlayer.prototype.getValueSlider = function () {
        return this.rangeslider.getValues();
    };



//----------------Create new Components----------------//

//--Charge the new Component into videojs
    var videojsSeekBar = videojs.getComponent('SeekBar');
    videojsSeekBar.prototype.options_.children.push('RSTimeBar'); //Range Slider Time Bar

    var videojsControlBar = videojs.getComponent('ControlBar');
    videojsControlBar.prototype.options_.children.push('ControlTimePanel'); //Panel with the time of the range slider



//-- Design the new components

    var videojsComponent = videojs.getComponent('Component');

    /**
     * Range Slider Time Bar
     * @param {videojs.Player|Object} player
     * @param {Object=} options
     * @constructor
     */
    var videojsRSTimeBar = videojs.extend(videojsComponent, {
        /** @constructor */
        constructor: function (player, options) {
            videojsComponent.call(this, player, options);
        }
    });

    videojsRSTimeBar.prototype.init_ = function () {
        this.rs = this.player_.rangeslider;
    };

    videojsRSTimeBar.prototype.options_ = {
        children: {
            'SeekRSBar': {}
        }
    };

    videojsRSTimeBar.prototype.createEl = function () {
        return videojsComponent.prototype.createEl.call(this, 'div', {
            className: 'vjs-timebar-RS',
            innerHTML: ''
        });
    };

    videojs.registerComponent('RSTimeBar', videojsRSTimeBar);

    /**
     * Seek Range Slider Bar and holder for the selection bars
     * @param {videojs.Player|Object} player
     * @param {Object=} options
     * @constructor
     */
    var videojsSeekRSBar = videojs.extend(videojsSeekBar, {
        /** @constructor */
        constructor: function (player, options) {
            videojsComponent.call(this, player, options);
            this.on('mousedown', this.onMouseDown);
            this.on('touchstart', this.onMouseDown);
        }
    });

    videojsSeekRSBar.prototype.init_ = function () {
        this.rs = this.player_.rangeslider;
    };

    videojsSeekRSBar.prototype.options_ = {
        children: {
            'SelectionBar': {},
            'SelectionBarLeft': {},
            'SelectionBarRight': {},
            'TimePanel': {},
        }
    };

    videojsSeekRSBar.prototype.createEl = function () {
        return videojsComponent.prototype.createEl.call(this, 'div', {
            className: 'vjs-rangeslider-holder'
        });
    };


    videojsSeekRSBar.prototype.onMouseDown = function (event) {
        event.preventDefault();
        videojsBlockTextSelection();

        if (!this.rs.options.locked) {
            this.on(document, "mousemove", videojs.bind(this, this.onMouseMove));
            this.on(document, "mouseup", videojs.bind(this, this.onMouseUp));
            this.on(document, "touchmove", videojs.bind(this, this.onMouseMove));
            this.on(document, "touchend", videojs.bind(this, this.onMouseUp));

        }
    };

    videojsSeekRSBar.prototype.onMouseUp = function (event) {
        this.off(document, "mousemove", videojs.bind(this, this.onMouseMove), false);
        this.off(document, "mouseup", videojs.bind(this, this.onMouseUp), false);
        this.off(document, "touchmove", videojs.bind(this, this.onMouseMove), false);
        this.off(document, "touchend", videojs.bind(this, this.onMouseUp), false);

    };

    videojsSeekRSBar.prototype.onMouseMove = function (event) {
        var left = this.calculateDistance(event);

        if (this.rs.left.pressed)
            this.setPosition(0, left);
        else if (this.rs.right.pressed)
            this.setPosition(1, left);

        //Fix a problem with the presition in the display time
        var ctd = this.player_.controlBar.currentTimeDisplay;
        ctd.contentEl_.innerHTML = '<span class="vjs-control-text">' + ctd.localize('Current Time') + '</span>' + videojsFormatTime(this.rs._seconds(left), this.player_.duration());

        // Trigger slider change
        if (this.rs.left.pressed || this.rs.right.pressed) {
            this.rs._triggerSliderChange();
        }
    };

    videojsSeekRSBar.prototype.setPosition = function (index, left, writeControlTime) {
        var writeControlTime = typeof writeControlTime != 'undefined' ? writeControlTime : true;
        //index = 0 for left side, index = 1 for right side
        var index = index || 0;

        // Position shouldn't change when handle is locked
        if (this.rs.options.locked)
            return false;

        // Check for invalid position
        if (isNaN(left))
            return false;

        // Check index between 0 and 1
        if (!(index === 0 || index === 1))
            return false;

        // Alias
        var ObjLeft = this.rs.left.el_,
            ObjRight = this.rs.right.el_,
            Obj = this.rs[index === 0 ? 'left' : 'right'].el_,
            tpr = this.rs.tpr.el_,
            tpl = this.rs.tpl.el_,
            bar = this.rs.bar,
            ctp = this.rs[index === 0 ? 'ctpl' : 'ctpr'].el_;

        //Check if left arrow is passing the right arrow
        if ((index === 0 ? bar.updateLeft(left) : bar.updateRight(left))) {
            Obj.style.left = (left * 100) + '%';
            index === 0 ? bar.updateLeft(left) : bar.updateRight(left);

            this.rs[index === 0 ? 'start' : 'end'] = this.rs._seconds(left);

            //Fix the problem  when you press the button and the two arrow are underhand
            //left.zIndex = 10 and right.zIndex=20. This is always less in this case:
            if (index === 0) {
                if ((left) >= 0.9)
                    ObjLeft.style.zIndex = 25;
                else
                    ObjLeft.style.zIndex = 10;
            }

            //-- Panel
            var TimeText = videojsFormatTime(this.rs._seconds(left)),
                tplTextLegth = tpl.children[0].innerHTML.length;
            var MaxP, MinP, MaxDisP;
            if (tplTextLegth <= 4) //0:00
                MaxDisP = this.player_.isFullScreen ? 3.25 : 6.5;
            else if (tplTextLegth <= 5)//00:00
                MaxDisP = this.player_.isFullScreen ? 4 : 8;
            else//0:00:00
                MaxDisP = this.player_.isFullScreen ? 5 : 10;
            if (TimeText.length <= 4) { //0:00
                MaxP = this.player_.isFullScreen ? 97 : 93;
                MinP = this.player_.isFullScreen ? 0.1 : 0.5;
            } else if (TimeText.length <= 5) {//00:00
                MaxP = this.player_.isFullScreen ? 96 : 92;
                MinP = this.player_.isFullScreen ? 0.1 : 0.5;
            } else {//0:00:00
                MaxP = this.player_.isFullScreen ? 95 : 91;
                MinP = this.player_.isFullScreen ? 0.1 : 0.5;
            }

            if (index === 0) {
                tpl.style.left = Math.max(MinP, Math.min(MaxP, (left * 100 - MaxDisP / 2))) + '%';

                if ((tpr.style.left.replace("%", "") - tpl.style.left.replace("%", "")) <= MaxDisP)
                    tpl.style.left = Math.max(MinP, Math.min(MaxP, tpr.style.left.replace("%", "") - MaxDisP)) + '%';
                tpl.children[0].innerHTML = TimeText;
            } else {
                tpr.style.left = Math.max(MinP, Math.min(MaxP, (left * 100 - MaxDisP / 2))) + '%';

                if (((tpr.style.left.replace("%", "") || 100) - tpl.style.left.replace("%", "")) <= MaxDisP)
                    tpr.style.left = Math.max(MinP, Math.min(MaxP, tpl.style.left.replace("%", "") - 0 + MaxDisP)) + '%';
                tpr.children[0].innerHTML = TimeText;
            }
            //-- Control Time
            if (writeControlTime) {
                var time = TimeText.split(":"),
                    h, m, s;
                if (time.length == 2) {
                    h = 0;
                    m = time[0];
                    s = time[1];
                } else {
                    h = time[0];
                    m = time[1];
                    s = time[2];
                }
                ctp.children[0].value = h;
                ctp.children[1].value = m;
                ctp.children[2].value = s;
            }
        }
        return true;
    };

    videojs.registerComponent('SeekRSBar', videojsSeekRSBar);


    /**
     * This is the bar with the selection of the RangeSlider
     * @param {videojs.Player|Object} player
     * @param {Object=} options
     * @constructor
     */
    var videojsSelectionBar = videojs.extend(videojsComponent, {
        /** @constructor */
        constructor: function (player, options) {
            videojsComponent.call(this, player, options);
            this.on('mouseup', this.onMouseUp);
            this.on('touchend', this.onMouseUp);
            this.fired = false;
        }
    });

    videojsSelectionBar.prototype.init_ = function () {
        this.rs = this.player_.rangeslider;
    };

    videojsSelectionBar.prototype.createEl = function () {
        return videojsComponent.prototype.createEl.call(this, 'div', {
            className: 'vjs-selectionbar-RS'
        });
    };



    videojsControlTimePanelRight.prototype.init_ = function () {
        this.rs = this.player_.rangeslider;
        this.timeOld = {};
    };

    videojsControlTimePanelRight.prototype.createEl = function () {
        return videojsComponent.prototype.createEl.call(this, 'div', {
            className: 'vjs-controltimepanel-right-RS',
            innerHTML: 'End: <input type="text" id="controltimepanel" maxlength="2" value="00"/>:<input type="text" id="controltimepanel" maxlength="2" value="00"/>:<input type="text" id="controltimepanel" maxlength="2" value="00"/>'
        });
    };

    videojsControlTimePanelRight.prototype.onKeyDown = function (event) {
        this.timeOld[0] = this.el_.children[0].value;
        this.timeOld[1] = this.el_.children[1].value;
        this.timeOld[2] = this.el_.children[2].value;
    };

    videojsControlTimePanelRight.prototype.onKeyUp = function (event) {
        this.rs._checkControlTime(1, this.el_.children, this.timeOld);
    };

    videojs.registerComponent('ControlTimePanelRight', videojsControlTimePanelRight);
})();

这就是rangelider每次出现时的样子

enter image description here

1 个答案:

答案 0 :(得分:0)

我用

video.currentTime

但看起来像rangelider正在使用

e.currentPoint
相关问题