由于UI还没出样式,于是就先写写video自定义按钮事件,附在线mp4视频测试地址
版本:vue,没样式,只有video标签自定义控制按钮事件
版本:vue,没样式,只有video标签自定义控制按钮事件
版本:vue,没样式,只有video标签自定义控制按钮事件
在线mp4测试视频地址:GO

<template>
    <div class="player">
        <video ref="video" :controls="false" controlslist="nodownload">
            <!-- <source src="./../../assets/source/sintel.mp4" type="video/mp4"/> -->
            <source
                src="http://vfx.mtime.cn/Video/2019/03/21/mp4/190321153853126488.mp4"
                type="video/mp4"
            />
        </video>
        <div class="btns">
            <el-button ref="isPlay" class="stop">停止/播放</el-button>
            <el-button ref="enableMute">关闭声音</el-button>
            <el-button ref="disableMute">打开声音</el-button>
            <input type="range" ref="ran" :value="ranVal"/>
            <div ref="current"></div>
            <!-- 当前进度 -->
            <div ref="buffered"></div>
            <!-- 下载进度 秒 -->
            <div ref="duration"></div>
            <!-- 总时长 -->
            <el-button ref="fullScreen">全屏</el-button>
            <!-- 全屏按钮 -->
            <div ref="progress" style="height:10px;background:#f00;">
                <!-- 进度条 -->
                <div ref="bar" style="height:5px;background:#0f0;"></div>
                <!-- 播放进度 -->
                <div ref="buffer" style="height:5px;background:#00f;"></div>
                <!-- 缓存进度 -->
            </div>
        </div>
    </div>
</template>

<script>
import { hasClass } from "@/commons/func";
export default {
    data() {
        return {
            bufferTimer: null,
            timer: null,
            video: null,

            enableMute: null,
            disableMute: null,
            ran: null,
            ranVal:0,
            current: null,
            buffered: null,
            duration: null,
            fullScreen: null,
            progress: null,
            bar: null,
            buffer: null
        };
    },
    methods: {
        init() {
            this.video = this.$refs.video; //获取video对象
            this.isPlay = this.$refs.isPlay.$el; //获取播放/暂停按钮对象,element-ui库需要'.$el'获取
            this.enableMute = this.$refs.enableMute.$el; //获取关闭声音按钮对象
            this.disableMute = this.$refs.disableMute.$el; //获取开启声音按钮对象
            this.ran = this.$refs.ran; //获取滑块对象,方便调整音量大小
            this.ranVal = this.video.volume*100;
            this.ran.style.backgroundSize = this.ranVal+'% 100%';
            this.current = this.$refs.current; //获取显示当前播放时间进度的对象
            this.buffered = this.$refs.buffered; //获取显示下载进度的对象,下载使用,暂时无用
            this.duration = this.$refs.duration; //
            this.fullScreen = this.$refs.fullScreen.$el;
            this.progress = this.$refs.progress;
            this.bar = this.$refs.bar;
            this.buffer = this.$refs.buffer;
            this.addEvent(this.isPlay, "click", this.playPause);
            this.addEvent(this.video, "timeupdate", this.timeupdate);
            this.addEvent(this.progress, "click", this.changeProgress);
            this.addEvent(this.fullScreen, "click", this.launchFullScreen);
            this.addEvent(this.enableMute, "click", this.closeVolume);
            this.addEvent(this.disableMute, "click", this.openVolume);
            this.rangeSlider(this.ran,{min:0,max:100,step:5,callback:this.setVolume})
        },
        // 补零
        zeroFill(num) {
            if (num < 10) {
                num = "0" + num;
            }
            return num;
        },
        // 处理秒数为时分秒 h:m:s
        getTime(num) {
            let m = this.zeroFill(Math.floor(num / 60) % 60),
                s = this.zeroFill(Math.floor(num % 60)),
                h = this.zeroFill(Math.floor(Math.floor(num / 60) / 60)),
                time = "" + h + ":" + m + ":" + s + "";
            return time;
        },
        //全屏方法
        launchFullScreen() {
            if (this.video.requestFullscreen) {
                this.video.requestFullscreen();
            } else if (this.video.mozRequestFullScreen) {
                this.video.mozRequestFullScreen();
            } else if (this.video.webkitRequestFullscreen) {
                this.video.webkitRequestFullscreen();
            } else if (this.video.msRequestFullscreen) {
                this.video.msRequestFullscreen();
            }
        },
        //播放和暂停
        playPause() {
            let classStr = this.isPlay.className;
            if (hasClass(this.isPlay, "stop")) {
                this.video.play();
                this.bufferTimer = setInterval(() => {
                    this.buffer.style.width =
                        (this.video.buffered.end(0) / this.video.duration) *
                            100 +
                        "%";
                }, 1000 / 30);
                if (this.video.buffered.end(0) == this.video.duration) {
                    this.buffer.style.width = "100%";
                    clearInterval(this.bufferTimer);
                }
                this.timer = setInterval(() => {
                    this.bar.style.width =
                        (this.video.currentTime / this.video.duration) * 100 +
                        "%";
                }, 1000 / 30);
                this.isPlay.className = classStr.replace("stop", "play");
            } else if (hasClass(this.isPlay, "play")) {
                this.video.pause();
                clearInterval(this.timer);
                this.isPlay.className = classStr.replace("play", "stop");
            }
        },
        //视频播放进度改变触发
        timeupdate() {
            this.current.innerHTML = this.getTime(this.video.currentTime);
            this.duration.innerHTML = this.getTime(this.video.duration);
            this.buffered.innerHTML = this.video.buffered.end(0);
            if (this.video.currentTime == this.video.duration) {
                this.isPlay.className = this.isPlay.className.replace(
                    "play",
                    "stop"
                );
            }
        },
        //点击进度条改变播放进度
        changeProgress(e) {
            let barLength = e.pageX - this.progress.offsetLeft;
            this.video.currentTime =
                (barLength / this.progress.clientWidth) * this.video.duration;
            this.bar.style.width =
                (barLength / this.progress.clientWidth) * 100 + "%";
        },
        //关闭声音
        closeVolume() {
            this.video.muted = true;
        },
        //开启声音
        openVolume() {
            this.video.muted = false;
        },
        //设置音量
        setVolume() {
            this.video.volume = this.ran.value / 100;
            this.video.muted = false;
        },
        rangeSlider(rangeElem, { min, max, step, callback }) {
            min = !isNaN(parseFloat(min)) ? Number(min) : null;
            max = !isNaN(parseFloat(max)) ? Number(max) : null;
            step = !isNaN(parseFloat(step)) ? Number(step) : 1;
            callback = callback ? callback : null;

            rangeElem.setAttribute("min", min);
            rangeElem.setAttribute("max", max);
            rangeElem.setAttribute("step", step);

            rangeElem.addEventListener("input", function(e) {
                var that = e.target;
                that.style.backgroundSize = this.value + "% 100%";
                if (typeof callback == "function") {
                    callback(that);
                }
            });
        }
    },
    mounted() {
        this.init();
    }
};
</script>

<style lang="less" scoped>
input[type="range"] {
    -webkit-appearance: none;
    width: 200px;
    height: 5px;
    border-radius: 5px;
    background: -webkit-linear-gradient(#fa03e4, #a5f601) no-repeat;
    background-size: 0% 100%;
}
input[type="range"]::-webkit-slider-thumb {
    -webkit-appearance: none;
    height: 15px;
    width: 5px;
    margin-top: -5px; /*使滑块超出轨道部分的偏移量相等*/
    background: #f5f5f5;
    border-radius: 2px; /*外观设置为圆形*/
    border: solid 1px #a5a5a5; /*设置边框*/
    box-shadow: 0 0px 1px #666666; /*添加底部阴影*/
}
input[type="range"]::-webkit-slider-runnable-track {
    height: 5px;
    border-radius: 2px; /*将轨道设为圆角的*/
    box-shadow: 0 0px 1px #0f00ff, inset 0 0px 2px #00ffff; /* 轨道内置阴影效果 */
}
input[type="range"]:focus {
    outline: none;
}
</style>

有个通用函数是写在外面引入的,现写在这儿,防止用到的兄dei不知道怎么弄

hasClass(elem,classm){
    return elem.className.indexOf(classm) > -1;
}

有几个绑定事件的函数估计会找不到,this.addEvent 找不到的【看这里】,已经封装好了的,可以直接拿去用

附上另外一个网友的东西:【javascript中使用video实现视频的缓冲,加载与下载,获取视频的时长

Logo

前往低代码交流专区

更多推荐