vue项目中自定义video视频控制条的实现代码


Posted in Javascript onApril 26, 2020

最近公司项目中,添加了视频模块,但是产品觉得Video自带的控制条有点LOW,于是自己设计了一个。于是开始了自定义Video控制的采坑之旅。。

首页效果图:

 

vue项目中自定义video视频控制条的实现代码

需求描述:

当鼠标放在图片上的时候,自动播放视频,并显示预览进度条,当鼠标移开,显示预览图片,再次hover图片,继续上次播放

视频详情页的效果图:

vue项目中自定义video视频控制条的实现代码

需求描述:

  • 能自定义的暂停和播放
  • 模仿进度条可实现拖拽播放速度
  • 显示当前时间
  • 能选择倍速
  • 能控制声音
  • 能全屏播放

接下来一步步的实现

首先康康首页的,上结构代码:

<div class="clickL video-box" @mouseover="play(item3.images_id)" @mouseout="pause(item3.images_id)">
   <img v-lazy="item3.picture" width="268" alt="" v-show="id != item3.images_id">
   <video class="video-hover" ref="videoAll" onMouseOver="this.play()" :src="item3.short_video" @timeupdate="commonVideoUpdata(index)" width="268px" height="176px" onMouseOut="this.pause()" muted loop="loop">
   </video>
  </div>
  <div class="process-slider common-progress" v-show="id == item3.images_id">
   <el-slider v-model="currentTimeProgress" :show-tooltip="false" input-size="small"></el-slider>
  </div>

这里思路是:

1,判断用户鼠标事件,切换图片和视频。

2.video需要通过video来获取他实例来进行dom操作,video的鼠标移入和滑出分类是控制视频的播放和停止,play和pause是video的内置方法。 更多方法见这里哦~

3.这里的进度条使用的是element的滑动条组件,默认max是100,显示视频的时候,这里用v-show判断显隐。

css部分代码:

.video-box {
  position: relative;
  height: 176px;

  &>img {
  width: 100%;
  height: 100%;
  position: absolute;
  left: 0;
  top: 0;
  z-index: 2;
  }

  &>video {
  object-fit: fill; //拉伸填充盒子,保证和图片一样大
  }

 }

css部分主要是要注意让video显示的时候和图片的宽高一致,不然就会出现图片大,视频小的情况,如图:

vue项目中自定义video视频控制条的实现代码

逻辑部分:

data() {
 return {
 id:0, //保存当前播放的视频id
 currentTimeVal:0 //进度条
 }
},
methods:{
 //开始播放
 play(val) {
 this.id = val
 },
 // 停止播放,显示图片清零进度条
 pause(val) {
 this.id = 0
 this.currentTimeVal = 0
 },
 // 公共video获取时间
 commonVideoUpdata(id) {
  let videoObj = this.$refs.videoAll
  console.log(videoObj);
  let currTime = videoObj[id].currentTime //当前时间
  let duration = videoObj[id].duration //总时间
  let pre = currTime / duration
  this.currentTimeProgress = pre * 100;
 },
}

这里使用video 的timeupdate内置方法获取当前播放时间,并获取当前的的dom元素,这里的videoObj打印出来是个数组:

vue项目中自定义video视频控制条的实现代码

我们通过当前元素在数组中循环出来的索引来获取对应视频的时间,最后一个简单的计算进度条的方法,(当前时间 / 总时间)* 100 = 进度条的值

注意坑点

:如果在数组中掺杂了其他的非视频文件,这里使用ref的方式,就不能根据索引来获取,就得定义唯一的ref,嘿嘿!

到此首页功能结束了,接着实现详情页的自定义控制条。

html部分:

<div class="detali_box_img video-media">
  <div class="video-example">
   <video :src="item.video_file" width="100%" height="100%" loop="loop" preload="auto" @timeupdate="videoTimeUpdate" @click="controlVideo" ref="videoCon">
   您的浏览器不支持 video 标签。
   </video>
  </div>
  //视频中的暂停按钮
  <div class="play-btn" @click="controlVideo" :style="[opcityVal]"></div>
  // 控制条的播放和暂停按钮
  <div class="control-play">
   <p class="control-play-btn" @click="controlVideo">
   <span class="el-icon-video-play" v-show="!vcIsPlay"></span>
   <span class="el-icon-video-pause" v-show="vcIsPlay"></span>
   </p>
   //播放进度条
   <div class="control-progress common-progress">
   <div>
   <el-slider v-model="vcProgress" :show-tooltip="false" :max="durationProgress" input-size="small" @change="getNewTime"></el-slider>
   </div>
   <!-- <p class="control-progress-item"></p> -->
   </div>
   //当前播放时间
   <div class="current-time">{{vcCurrentTime}}</div>
   //视频总时长
   <div class="duration">{{item.duration_time}}</div>
   //倍速控制
   <div class="video-speed-box" @click="getPlayBackRate">
   <el-dropdown placement="bottom" @command="handleCommand">
   <!-- <span class="el-dropdown-link"> -->
   <span class="video-speed-show">{{speedTime}}</span>
   <!-- </span> -->
   <el-dropdown-menu slot="dropdown">
   <el-dropdown-item command="1">0.5x</el-dropdown-item>
   <el-dropdown-item command="2">1x</el-dropdown-item>
   <el-dropdown-item command="3">1.5x</el-dropdown-item>
   <el-dropdown-item command="4">2x</el-dropdown-item>
   <el-dropdown-item command="5">3x</el-dropdown-item>

   </el-dropdown-menu>
   </el-dropdown>

   </div>
   //音量控制
   <div class="control-voice common-progress">
   <span class="voice-icon"></span>
   <div class="voice-slider">
   <el-slider v-model="voiceProgress" input-size="small" @change="getNewVoice"></el-slider>
   </div>
   </div>
   //全屏播放
   <p class="fullscreen" title="全屏" @click="getFullSceen">
   <span class="el-icon-full-screen"></span>
   </p>
  </div>
  </div>

css部分忽略了。。。

直接看功能:首先data部分:

vcIsPlay: false, //是否播放
 opcityVal: {
 opacity: '1'
 },
 currentTimeVal: 0, // 当前时间
 vcCurrentTime: '00:00:00', //当前时间格式化
 vcProgress: 0, //进度条的绑定时间
 durationProgress: 0, //当前视频的总时长
 speedTime: '1x', //倍速
 voiceProgress: 0 //声音

暂停和播放:

// 播放和暂停视频
 controlVideo() {
 let videoObj = this.$refs.videoCon
 this.durationProgress = videoObj[0].duration //总时间
 if (this.vcIsPlay) {
 videoObj[0].pause()
 } else {
 videoObj[0].play()
 }
 this.vcIsPlay = !this.vcIsPlay
 this.opcityVal.opacity = this.opcityVal.opacity == '1' ? '0' : '1'
 },

直接调用提供的两个方法即可,然后使用vue的style绑定控制暂停按钮的显隐即可,这里的进度条,我换了种玩法,同样是element的滑动条组件,只不过max值我换成了总时长,单位秒,原因请耐心看下文,嘿嘿!

vue项目中自定义video视频控制条的实现代码

进度条部分:

// 获取时间
 videoTimeUpdate() {
 let videoObj = this.$refs.videoCon
 let currTime = videoObj[0].currentTime //当前时间
 this.vcProgress = currTime //赋值给进度条
 this.vcCurrentTime = this.getFormatVideoTime(currTime)
 console.log(this.vcCurrentTime) //"00:00:27"
 },
 //格式化时间
 getFormatVideoTime(time) {
 let curtime = time
 let h = parseInt(curtime / 3600)
 let m = parseInt((curtime % 3600) / 60)
 let s = parseInt(curtime % 60)
 h = h < 10 ? '0' + h : h
 m = m < 10 ? '0' + m : m
 s = s < 10 ? '0' + s : s
 return h + ':' + m + ':' + s
 },

这里难点是,我如何进行拖动进度条,来进行控制呢?

别慌,看 代码:

@change="getNewTime" //element 的滑动组件有个chang事件
 getNewTime(val) {
 let videoObj = this.$refs.videoCon
 console.log(val)
 videoObj[0].currentTime = val
 },

通过change进度条,然后重新赋值给当前时间就搞定了,可以说是炒鸡舒服了

vue项目中自定义video视频控制条的实现代码

倍速部分:

// 获取当前播放的速度
 handleCommand(val) {
 let videoObj = this.$refs.videoCon
 switch (val) {
 case '1':
  videoObj[0].playbackRate = 0.5
  this.speedTime = '0.5x'
  break
 case '2':
  videoObj[0].playbackRate = 1
  this.speedTime = '1x'
  break
 case '3':
  videoObj[0].playbackRate = 1.5
  this.speedTime = '1.5x'
  break
 case '4':
  videoObj[0].playbackRate = 2
  this.speedTime = '2x'
  break
 case '5':
  videoObj[0].playbackRate = 3
  this.speedTime = '3x'
  break

 default:
  videoObj[0].playbackRate = 1
  this.speedTime = '1x'
  break
 }
 },

看图:

vue项目中自定义video视频控制条的实现代码

这里使用的是element的下拉组件,同样,Video的playbackRate可以直接赋值,控制播放速度

声音部分:

// 设置声音

 getNewVoice(val) {
 let videoObj = this.$refs.videoCon
 let newVc = val / 100 //h5规定,volume的值必须再0-1之间,比如0.5就是50%的音量,但是进度条的值为100,因此这里做个除法
 videoObj[0].volume = newVc //赋值
 },

我也是使用的滑组件,max值保持默认的100,然后滑动改变的时候,把默认值除100,比如当前滑块的新值是50,除100后得到的就是【0-1】范围里的合法值,Video提供的volume值如果不在 0-1之间,就会报错

最后是全屏部分:

// 全屏播放
 getFullSceen() {
 let videoObj = this.$refs.videoCon
 videoObj[0].webkitRequestFullScreen()
 },

但是我看到网上还有一种方法是模拟按下f11的全部,如果有兴趣也可以了解下!

总结

因为之前没有很仔细的搞过video,所以对它很多的内置属性和方法不了解,没经验就害怕,很慌很慌,这就跟谈恋爱似的,哈哈哈,再组长的支持和鼓励下,我大胆的尝试了,成功后,这次经验给了我很大信心,感觉以后写其他没做过的功能,都不会慌了,毕竟难的部分写elementUi的大佬们都给写好了,可以说是站在巨人的肩膀上,哈哈哈!膜拜大佬,以后还得多多努力了。

到此这篇关于vue项目中自定义video视频控制条的实现代码的文章就介绍到这了,更多相关vue 自定义video视频控制条内容请搜索三水点靠木以前的文章或继续浏览下面的相关文章希望大家以后多多支持三水点靠木!

Javascript 相关文章推荐
运用jquery实现table单双行不同显示并能单行选中
Jul 25 Javascript
Js从头学起(基本数据类型和引用类型的参数传递详细分析)
Feb 16 Javascript
十个迅速提升JQuery性能让你的JQuery跑得更快
Dec 10 Javascript
JavaScript拆分字符串时产生空字符的解决方案
Sep 26 Javascript
JS简单计算器实例
Jan 20 Javascript
js判断鼠标左、中、右键哪个被点击的方法
Jan 27 Javascript
详解Backbone.js框架中的模型Model与其集合collection
May 05 Javascript
vue实现动态按钮功能
May 13 Javascript
React精髓!一篇全概括小结(急速)
May 23 Javascript
vue实现中部导航栏布局功能
Jul 30 Javascript
jQuery高级编程之js对象、json与ajax用法实例分析
Nov 01 jQuery
深入理解Antd-Select组件的用法
Feb 25 Javascript
vue项目启动出现cannot GET /服务错误的解决方法
Apr 26 #Javascript
详解vuejs中执行npm run dev出现页面cannot GET/问题
Apr 26 #Javascript
jquery检测上传文件大小示例
Apr 26 #jQuery
element中的$confirm的使用
Apr 26 #Javascript
JavaScript监听一个DOM元素大小变化
Apr 26 #Javascript
分享一款超好用的JavaScript 打包压缩工具
Apr 26 #Javascript
微信小程序自定义navigationBar顶部导航栏适配所有机型(附完整案例)
Apr 26 #Javascript
You might like
PHP 和 MySQL 基础教程(一)
2006/10/09 PHP
定制404错误页面,并发信给管理员的程序
2006/10/09 PHP
Smarty最简单实现列表奇偶变色的方法
2015/07/01 PHP
jQuery控制输入框只能输入数值的小例子
2013/03/20 Javascript
Extjs4 Treegrid 使用心得分享(经验篇)
2013/07/01 Javascript
浏览器的JavaScript引擎的识别方法
2013/10/20 Javascript
javascript如何使用bind指定接收者
2014/05/04 Javascript
Javascript中的关键字和保留字整理
2014/10/16 Javascript
jQuery中innerWidth()方法用法实例
2015/01/19 Javascript
跟我学习javascript的定时器
2015/11/19 Javascript
js实现页面a向页面b传参的方法
2016/05/29 Javascript
checkbox批量选中,获取选中项的值的简单实例
2016/06/28 Javascript
vue 组件中添加样式不生效的解决方法
2018/07/06 Javascript
js中的深浅拷贝问题简析
2019/05/10 Javascript
webpack3.0升级4.0的方法步骤
2020/04/02 Javascript
封装Vue Element的table表格组件的示例详解
2020/08/19 Javascript
[01:21]辉夜杯战队访谈宣传片—CDEC
2015/12/25 DOTA
Python多进程通信Queue、Pipe、Value、Array实例
2014/11/21 Python
Python利用Beautiful Soup模块修改内容方法示例
2017/03/27 Python
浅谈flask截获所有访问及before/after_request修饰器
2018/01/18 Python
python装饰器深入学习
2018/04/06 Python
Python中利用LSTM模型进行时间序列预测分析的实现
2019/07/26 Python
详解如何在cmd命令窗口中搭建简单的python开发环境
2019/08/29 Python
python环境下安装opencv库的方法
2020/03/05 Python
Sublime Text3最新激活注册码分享适用2020最新版 亲测可用
2020/11/12 Python
pycharm激活码免费分享适用最新pycharm2020.2.3永久激活
2020/11/25 Python
PyTorch中clone()、detach()及相关扩展详解
2020/12/09 Python
Web页面中八种创建多列等高(等高列布局)的实现技术
2012/12/24 HTML / CSS
手工制作的意大利皮革运动鞋:KOIO
2020/01/05 全球购物
俄罗斯苹果优质经销商商店:iPort
2020/05/27 全球购物
求职简历自荐信
2013/10/20 职场文书
个人思想理论学习的自我鉴定
2013/11/30 职场文书
销售主管的自我评价分享
2014/01/03 职场文书
麦当劳辞职信范文
2014/01/18 职场文书
中层干部竞聘演讲稿
2014/05/15 职场文书
nginx部署多前端项目的几种方法
2021/05/25 Servers