ui设计的界面总是极具个性化的,要去修改插件中的视频控件的样式和布局太困难了,那就自己参照video原生事件,重写一个吧。
(效果图预览)
一、video标签的属性(props)
标签 | 菜鸟教程”>html
您的浏览器不支持video
参数说明:(更多属性参照上述菜鸟教程中的video标签)
- controls:默认为true,即向用户展示视频控件(如播放、暂停按钮等)
- autoplay:如果出现该属性,则视频在就绪后马上播放。
- muted:是否静音,默认为true
- width:设置视频播放器的宽度
二、video视频控件的触发事件
video标签支持的多媒体事件(Media Events) | 菜鸟教程
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的进度条写音量大小调节条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)父组件调用
<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;">/</span><span id="durationTime" ref="durationTimer">{{ videoTotalTime }}</span></p>import ProgressLine from './ProgressLine.vue';export default {name: 'videoPage',components: {ProgressLine},data(){return{presentT: 0,// 进度条的当前值,必须为numbertotalT: 0,// 进度条的最大值,必须为numberpersentLoad: 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 : mvar s = parseInt(t % 60)s = s < 10 ? '0' + s : sreturn m + ':' + s},}}
(2)进度条组件(播放进度条 和 加载进度条)
// ProgressLine.vue 进度条组件<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><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 = truee.preventDefault()const { left, width } = this.$refs.progressRound.getBoundingClientRect()// 进度条到屏幕距离及进度条的宽度this.progressWidth = e.clientX - leftif (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.offsetXthis.dragClick = truethis.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 = nulldocument.onmouseup = nullthis.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]范围