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 相关文章推荐
理解Javascript_13_执行模型详解
Oct 20 Javascript
js日历功能对象
Jan 12 Javascript
JQuery一种取同级值的方式(比如你在GridView中)
Mar 15 Javascript
浅谈react.js 之 批量添加与删除功能
Apr 17 Javascript
微信小程序网络请求wx.request详解及实例
May 18 Javascript
vue2 前端搜索实现示例
Feb 26 Javascript
Vue中this.$router.push参数获取方法
Feb 27 Javascript
利用vue重构有赞商城的思路以及总结整理
Feb 21 Javascript
JavaScript碎片—函数闭包(模拟面向对象)
Mar 13 Javascript
express框架下使用session的方法
Jul 31 Javascript
解决vuex数据异步造成初始化的时候没值报错问题
Nov 13 Javascript
vue实现员工信息录入功能
Jun 11 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
ThinkPHP分页类使用详解
2014/03/05 PHP
Laravel框架中实现使用阿里云ACE缓存服务
2015/02/10 PHP
php微信公众平台开发(一) 配置接口
2016/12/06 PHP
php处理抢购类功能的高并发请求
2018/02/08 PHP
PHP实现基于PDO扩展连接PostgreSQL对象关系数据库示例
2018/03/31 PHP
js字符编码函数区别分析
2008/06/05 Javascript
jquery的Theme和Theme Switcher使用小结
2010/09/08 Javascript
Moment.js 不容错过的超棒Javascript日期处理类库
2012/04/15 Javascript
javascript操作JSON的要领总结
2012/12/09 Javascript
扩展jQuery对象时如何扩展成员变量具体怎么实现
2014/04/25 Javascript
Nodejs 发送Post请求功能(发短信验证码例子)
2017/02/09 NodeJs
Vue2.x中的父组件传递数据至子组件的方法
2017/05/01 Javascript
angularjs路由传值$routeParams详解
2020/09/05 Javascript
vue弹窗组件使用方法
2018/04/28 Javascript
详解基于vue的服务端渲染框架NUXT
2018/06/20 Javascript
微信小程序 Animation实现图片旋转动画示例
2018/08/22 Javascript
解决vue-cli单页面手机应用input点击手机端虚拟键盘弹出盖住input问题
2018/08/25 Javascript
egg.js的基本使用和调用数据库的方法示例
2019/05/18 Javascript
Vue.js组件使用props传递数据的方法
2019/10/19 Javascript
深入讲解Python函数中参数的使用及默认参数的陷阱
2016/03/13 Python
Python实现图片转字符画的示例代码
2017/08/21 Python
Python快速排序算法实例分析
2017/11/29 Python
pandas 转换成行列表进行读取与Nan处理的方法
2018/10/30 Python
利用Python将文本中的中英文分离方法
2018/10/31 Python
对python函数签名的方法详解
2019/01/22 Python
台湾饭店和机票预订网站:Expedia台湾
2016/08/05 全球购物
萨克斯第五大道的折扣店:Saks Fifth Avenue OFF 5TH
2016/08/25 全球购物
Notino意大利:购买香水和化妆品
2018/11/14 全球购物
BudgetAir印度:预订航班、酒店和汽车租赁
2019/07/07 全球购物
门卫工作岗位职责
2013/12/17 职场文书
员工拾金不昧表扬信
2014/01/09 职场文书
户籍证明的格式
2014/01/13 职场文书
煤矿安全生产责任书
2014/04/15 职场文书
施工单位工程部经理岗位职责
2015/04/09 职场文书
幼儿园教学工作总结2015
2015/05/12 职场文书
Python自动化测试PO模型封装过程详解
2021/06/22 Python