当前位置:首页 » 《随便一记》 » 正文

video 自定义视频播放控件

10 人参与  2023年05月02日 19:13  分类 : 《随便一记》  评论

点击全文阅读


ui设计的界面总是极具个性化的,要去修改插件中的视频控件的样式和布局太困难了,那就自己参照video原生事件,重写一个吧。

(效果图预览)


一、video标签的属性(props)

 html <video>标签 | 菜鸟教程

<video      ref="videoPlayer"      id="videoElement"      controls      autoplay     :muted="isMute"      width="800px"      height="600px" >     您的浏览器不支持video</video>

参数说明:(更多属性参照上述菜鸟教程中的video标签)

controls:默认为true,即向用户展示视频控件(如播放、暂停按钮等)autoplay:如果出现该属性,则视频在就绪后马上播放。muted:是否静音,默认为truewidth:设置视频播放器的宽度

二、video视频控件的触发事件 

video标签支持的多媒体事件(Media Events) | 菜鸟教程

<video     ref="videoPlayer"     id="videoElement"     controls     autoplay    :muted="isMute"     width="100%"     height="100%"     @loadeddata="setVideoPoster($event)"    @progress="videoProgress($event)"    @pause="videoPause($event)"    @play="videoPlay($event)"    @timeupdate="videoTimeUpdate()"    @ended="videoEnded()"    @contextmenu="contextmenu">    您的浏览器不支持video</video><button @click="handlePlay">播放</button><button @click="handlePause">暂停</button><button @click="handleMute">切换静音</button><button @click="fullScreen">全屏</button>data(){    return{        isMute: true // 默认静音     }}

1、播放(onplay事件)

this.$refs.videoPlayer.play();

methods:{    // 视频要开始播放时    videoPlay(e){        // ...触发该函数后视频会开始播放,我们可以做一些想做的事情,比如改变自定义播放按钮的样式等    },    // 自定义播放按钮中,触发视频的播放事件    handelPlay(){        this.$refs.videoPlayer.play();   // 会触发videoPlay()函数    }}

2、暂停(onpause事件)

this.$refs.videoPlayer.pause();

methods:{    // 视频要暂停播放时    videoPause(e){        // ...触发该函数后视频会暂停播放    },    // 自定义播放按钮中,触发视频的播放事件    handelPause(){        this.$refs.videoPlayer.pause();   // 会触发videoPause()函数    }}

3、静音(muted属性)

(1)切换静音

 // 手动切换静音(点击(非拖拽)静音时,用户选择的音量不变)

handleMute() {

      this.isMute = !this.isMute;

},

(2)改变音量(volume属性

this.$refs.videoPlayer.volume = a; (a为从 0~1的数字)

// 这里用element的进度条写音量大小调节条<el-slider v-model="curVolume" :show-tooltip="false" @input="changeVolume"></el-slider>data(){    return{        curVolume: 0, // 默认音量为0    }},methods:{    changeVolume(val){        this.curVolume = val;        // 由于h5规定volum的值在0-1之间,所以这里要对获取到的val做一个处理(滑块的val是从0-100)        this.$refs.videoPlayer.volume = val / 100;                // 音量为0的时候,video控件为静音        if ( val == 0 ) {           this.isMute = true;        } else {           this.isMute = false;        }    }}

4、全屏

fullScreen() {    this.$refs.videoPlayer.webkitRequestFullScreen();},

5、播放进度条

获取视频总时长(duration)

var videoObj = this.$refs.videoPlayer;

videoObj.addEventListener('canplay', () => {

        this.totalT = videoObj.duration;

})

获取视频加载进度

HTML5视频 - 加载百分比?

HTML5视频 - 加载百分比?

// 获取视频加载进度videoProgress(e){       var bf = this.$refs.videoPlayer.buffered;         var time = this.$refs.videoPlayer.currentTime;       if ( bf.length != 0 ){           var range = 0;           while( !( bf.start(range) <= time && time <= bf.end(range) ) ) {               range += 1;           }           var loadEndPercentage = ( bf.end(range) / this.playerVideo.duration ) * 100;  // 结束加载的百分比           this.persentLoad = loadEndPercentage;       }},

(1)父组件调用

<template>    <video       ref="videoPlayer"       @progress="videoProgress($event)"      @timeupdate="videoTimeUpdate()"    >      您的浏览器不支持video    </video>    // 视频播放、加载进度条    <ProgressLine       :presentT="presentT"       :totalT="totalT"       :persentLoad="persentLoad"       @changeCurrentTime="changeCurrentTime($event)"      @changeCurrentWord="changeCurrentWord($event)"    >    </ProgressLine>    // 播放时长、视频总时长    <p>      <span id="currentTime" ref="progressTimer">{{ videoCurrentTime }}</span>      <span style="color: #ffffff;opacity: 0.3;">&nbsp;/&nbsp;</span>      <span id="durationTime" ref="durationTimer">{{ videoTotalTime }}</span>    </p></template>import ProgressLine from './ProgressLine.vue';export default {    name: 'videoPage',    components: {        ProgressLine    },    data(){        return{            presentT: 0,  // 进度条的当前值,必须为number            totalT: 0,    // 进度条的最大值,必须为number            persentLoad: 0, // 视频加载进度             videoCurrentTime: '00:00', // 当前视频已播放时长            videoTotalTime: '00:00',  // 视频总时长        }    },    methods:{        // 子组件传入的时间修改        changeCurrentTime(data) {            this.$refs.videoPlayer.currentTime = data;  // 点击进度条设置视频当前播放点        },        changeCurrentWord(data) {            this.videoCurrentTime = this.formatTime(data);  // 当前播放时间显示文字        },        // 获取视频加载进度        videoProgress(e){            var bf = this.playerVideo.buffered;              var time = this.playerVideo.currentTime;            if ( bf.length != 0 ){                var range = 0;                while( !( bf.start(range) <= time && time <= bf.end(range) ) ) {                    range += 1;                 }                                var loadEndPercentage = ( bf.end(range) / this.playerVideo.duration ) * 100;    // 结束加载的百分比                this.persentLoad = loadEndPercentage;            }        },        // 视频自动播放时        videoTimeUpdate(){            this.presentT = this.playerVideo.currentTime;   // 获取当前播放时长            this.videoCurrentTime = this.formatTime(this.presentT);  // 时间格式化        },        // 时间格式化        formatTime(t) {            var m = parseInt(t % 3600 / 60)            m = m < 10 ? '0' + m : m            var s = parseInt(t % 60)            s = s < 10 ? '0' + s : s            return m + ':' + s        },    }}

(2)进度条组件(播放进度条 和 加载进度条)

// ProgressLine.vue 进度条组件<template>    <div>        <div class="line-background">            <div class="time-line" @click="adjustProgress($event)">                <div class="progress-round" ref="progressRound">                    <div class="loading" ref="persentLoad" style="width: 0;"></div>   <!-- 加载进度条 -->                    <div class="progress" ref="progress" @click="adjustProgress"></div>                    <div class="round" ref="round" @mousedown="roundDrag"></div>                </div>            </div>        </div>    </div></template><script>export default {    name: 'ProgressLine',    props: {        presentT: {},        totalT: {},        persentLoad: { default : 0 }    },    data() {        return {            // 进度条拖拽            dragClick: false,            // 鼠标/手指按下            clickDown: false,        }    },    created() {    },    watch: {        // 侦听当前播放时长设置进度条        presentT: {            handler(newValue, oldValue) {                // 未点击进度条                if (this.dragClick == false && this.clickDown == false) {                    this.$refs.progress.style.width = newValue / this.totalT * 100 + '%'                    if ((newValue / this.totalT * 100 - 1.23) < 0) {                        this.$refs.round.style.left = 0 + '%'                    } else {                        this.$refs.round.style.left = (newValue / this.totalT * 100) - 1.23 + '%'                    }                } else if (this.dragClick == true) {                    this.dealWidth()                    this.dragClick = false                }            }        },        persentLoad: {            handler(newValue, oldValue) {                this.$refs.persentLoad.style.width = ( newValue / 100 ) * 1300 + 'px';             }        }    },    methods: {        progressData(data) {            this.$emit('changeCurrentTime', data)            this.$emit('changeCurrentWord', data)        },        // 进度条位置和圆点定位处理        dealWidth() {            this.$refs.progress.style.width = this.progressWidth / this.$refs.progressRound.offsetWidth * 100 + '%'            if ((this.progressWidth / this.$refs.progressRound.offsetWidth * 100) - 1.23 < 0) {  // 圆点定位                this.$refs.round.style.left = 0 + '%'            } else {                this.$refs.round.style.left = (this.progressWidth / this.$refs.progressRound.offsetWidth * 100) - 1.23 + '%'            }        },        // 进度条点击        adjustProgress(e) {            this.dragClick = true            e.preventDefault()            const { left, width } = this.$refs.progressRound.getBoundingClientRect()  // 进度条到屏幕距离及进度条的宽度            this.progressWidth = e.clientX - left            if (this.progressWidth < 0) {//进度条边界值计算情况                this.progressWidth = 0            } else if (this.progressWidth >= width) {                this.progressWidth = width            } else {                this.progressWidth = e.clientX - left // e.clientX:鼠标点击的位置到屏幕最左侧的距离            }            this.dealWidth()            this.progressData((this.progressWidth / width) * this.totalT)        },        // 进度条圆点拖拽        roundDrag(event) {            event.preventDefault()            const offsetX = event.offsetX            this.dragClick = true            this.clickDown = true  // 解决圆点拖拽进度条长度抖动            document.onmousemove = (e) => {  // 给圆点添加移动事件                e.preventDefault()// 阻止进度条拖拽时屏幕原有的滑动功能                const X = e.clientX  // 获取圆点离屏幕的距离                const { left, width } = this.$refs.progressRound.getBoundingClientRect()                const ml = X - left  // 进度条长度:圆点离屏幕的距离减去进度条最左边离屏幕的距离                if (ml <= 0) {  // 进度条长度最小和最大值的界定                    this.progressWidth = 0                } else if (ml >= width) {                    this.progressWidth = width                } else {                    this.progressWidth = ml                }                this.progressData((this.progressWidth / width) * this.totalT)  //视频播放时间                this.dealWidth()            }            // 抬起鼠标,结束移动事件            document.onmouseup = () => {                document.onmousemove = null                document.onmouseup = null                this.clickDown = false            }        },    }}</script><style lang="less" scoped>.line-background {    width: 100%;    height: 10px;    background-color: rgba(255, 255, 255, 0.3);    .time-line {        width: 100%;        height: 10px;        background-color: #565651;        .progress-round {            cursor: pointer;            width: 100%;            position: relative;            display: flex;            .loading {                height: 10px;                background-color: rgba(255, 255, 255, 0.3);            }            .progress {                position: absolute;                top: 0;                left: 0;                width: 00%;                height: 10px;                background-color: #3d7eff;            }            .round {                position: absolute;                top: 50%;                left: 0;                transform: translateY(-50%);                width: 16px;                height: 16px;                border-radius: 16px;                background: #ffffff;                box-shadow: -2px 0px 2px 2px rgba(3, 0, 0, 0.30);            }        }    }}</style>

6、视频中禁用右键(可以禁止用户下载视频)

// 在视频中禁用右键(禁止用户下载)contextmenu(e){    e.returnValue = false;},

7、设置倍速播放

 this.$refs.videoPlayer.playbackRate = rate;   // rate 一般在[2.0,1.75,1.5,1.0,0.75,0.5]范围


点击全文阅读


本文链接:http://zhangshiyu.com/post/60305.html

<< 上一篇 下一篇 >>

  • 评论(0)
  • 赞助本站

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。

关于我们 | 我要投稿 | 免责申明

Copyright © 2020-2022 ZhangShiYu.com Rights Reserved.豫ICP备2022013469号-1