最终效果图,弹框可根据屏幕大小上下自适应

在一个视频列表上面,点击某一个视频弹出弹框,播放控件自定义

<template><div><Modalv-model="showmodels"title="  "footer-hidewidth="1160"><div class="componentsVideo"><video:src="url.url":muted="url.noSource"></video><div class="controls"><div class="control-left"><span@click="startVideo"class="playsauto":class="!isPlay ? 'playins' : 'stopIns'"></span><!-- 时间 --><div class="timer"><span class="current">00:00:00</span> /<span class="total">00:00:00</span></div></div><div class="control-right"><!-- 音量 --><spanclass="control-voice"@click="setmuted(url)"><spanclass="voices-pross":class="{'noSource': !url.noSource}"></span></span><!-- 全屏 --><spanclass="control-screen"@click="gotoAll"></span><spanclass="control-more"@click="showMore = !showMore"><divclass="more-model"v-if="showMore"><span @click="download(url.url)">{{$terms('下载')}}</span><span @click="showSpeed = true">{{$terms('播放速度')}}</span><span @click="goPicture">{{$terms('画中画')}}</span></div><divclass="more-model more-speed"v-if="showSpeed"><span@click="setSpeed(0.5)":class="{'isChecked': isChecked === 0.5}">x0.5</span><span@click="setSpeed(1)":class="{'isChecked': isChecked === 1}">x1.0</span><span@click="setSpeed(1.5)":class="{'isChecked': isChecked === 1.5}">x1.5</span><span@click="setSpeed(2)":class="{'isChecked': isChecked === 2}">x2.0</span></div></span></div></div><divref="controlRef"class="progress"><div class="duration"></div><i @mousedown="handleSliderMouseDown"></i></div><divclass="start":class="!isPlay ? 'playin' : 'stopIn'"@click="startVideo"></div></div></Modal></div>
</template><script>
export default {props: {// 这里是从上个页面传进来的视频数据,直接在video标签里面绑定url即可url: {type: Object,default: () => {}}},data() {return {showmodels: false,videos: null,isPlay: false,muted: false,noSource: false,currentTime: '',totalTime: '',progressWidth: '', // 进度条宽度showMore: false, // 是否展示更多弹框showSpeed: false, // 是否展示倍速isChecked: 1 // 倍速选中}},mounted() {},watch: {showmodels(val) {if (val) {// 弹框展示获取videothis.videos = document.querySelector('.componentsVideo video')let bb = document.querySelector('.componentsVideo .total')this.videos.oncanplay = () => {bb.innerHTML = this.getFormatTime(this.videos.duration)this.total_time = this.getFormatTime(this.videos.duration)}setTimeout(() => {this.startVideo()}, 300)} else {// 弹窗关闭所有值清空let current = document.querySelector('.componentsVideo .current')let duration = document.querySelector('.duration')let durationIcon = document.querySelector('.progress i')current.innerHTML = '00:00:00'duration.style.width = '0px'durationIcon.style.left = '0px'this.videos.pause()this.isPlay = falsethis.showMore = falsethis.showSpeed = false}}},methods: {// 画中画goPicture() {this.videos.requestPictureInPicture()},// 播放倍速setSpeed(v) {this.videos.playbackRate = vthis.isChecked = vthis.showSpeed = false},// 下载视频download(url) {let urls = url + '?action=download'window.open(urls)},// 全屏退出全屏gotoAll() {let bb = document.querySelector('.componentsVideo')let isFullScreen = document.fullscreen || document.mozFullScreen || document.webkitIsFullScreenlet cc = isFullScreen === undefined ? false : isFullScreenif (cc) {document.webkitCancelFullScreen()} else {bb.webkitRequestFullScreen()}},// 更新当前时间、帧号updadteCurrentTime(progressWidth, width) {this.currentTime = this.getFormatTime((progressWidth / width) * this.videos.duration)this.totalTime = this.getFormatTime(this.videos.duration)this.videos.currentTime = (progressWidth / width) * this.videos.duration// 拖动进度条跟随移动let progress = document.querySelector('.progress')let duration = document.querySelector('.duration')let durationIcon = document.querySelector('.progress i')let cirW = durationIcon.offsetWidth / 2let new_width = (this.videos.currentTime / this.videos.duration) * progress.offsetWidthduration.style.width = new_width + 'px'durationIcon.style.left = new_width - cirW + 'px'},clearTimer() {if (this.timer) {clearInterval(this.timer)this.timer = null}},// 拖动滑块handleSliderMouseDown(event) {event.preventDefault()// 滑块点击坐标const offsetX = event.offsetXdocument.onmousemove = (e) => {e.preventDefault()// 滑动距离可视区域左侧的距离const X = e.clientX// 减去滑块偏移量const cl = X - offsetXconst { left, width } = this.$refs.controlRef.getBoundingClientRect()// 除去滑块按钮长度的进度条长度const ml = cl - leftlet progressWidthif (ml <= 0) {// 进度条长度最小和最大值的界定progressWidth = 0} else if (ml >= width) {progressWidth = width} else {progressWidth = ml}this.progressWidth = progressWidth + 'px'// 更新当前时间this.updadteCurrentTime(progressWidth, width)}// 抬起鼠标,结束移动事件document.onmouseup = () => {document.onmousemove = nulldocument.onmouseup = null}},setmuted(v) {v.noSource = !v.noSource},startVideo() {this.isPlay = !this.isPlayif (this.isPlay) {this.videos.play()let current = document.querySelector('.componentsVideo .current')let progress = document.querySelector('.progress')let duration = document.querySelector('.duration')let durationIcon = document.querySelector('.progress i')// 滑块一半的宽度let cirW = durationIcon.offsetWidth / 2let that = this// 显示当前播放时间this.videos.addEventListener('timeupdate', function() {this.current_time = this.currentTimecurrent.innerHTML = that.getFormatTime(this.currentTime)// 显示当前播放进度条let new_width = (this.current_time / that.videos.duration) * progress.offsetWidthduration.style.width = new_width + 'px'durationIcon.style.left = new_width - cirW + 'px'})this.videos.addEventListener('ended', function() {that.isPlay = false})} else {this.videos.pause()}},// 格式化时间getFormatTime(times) {let time = timeslet h = parseInt(time / 3600)let m = parseInt((time % 3600) / 60)let s = parseInt(time % 60)h = h < 10 ? '0' + h : hm = m < 10 ? '0' + m : ms = s < 10 ? '0' + s : sreturn h + ':' + m + ':' + s}}
}
</script><style lang='scss' scoped>
video::-webkit-media-controls {display: none !important;
}
::v-deep .ivu-modal {padding: 124px 140px;width: 100% !important;height: 100% !important;top: 0;.ivu-modal-content {width: 100%;height: 100%;min-width: 849px;min-height: 533px;}
}
::v-deep .ivu-modal-header {display: none;
}
::v-deep .ivu-modal-body {width: 100%;height: 100%;padding: 4px;background: #000000;border-radius: 4px;
}
::v-deep .ivu-modal-close {right: -38px;top: 0;background: #000000;border-radius: 2px;opacity: 0.65;width: 32px;height: 32px;.ivu-icon-ios-close {font-weight: 400;color: #fff;top: -10px;left: -9px;font-size: 52px;}
}
.componentsVideo {position: relative;background: #000;height: 648px;height: 100%;width: 100%;text-align: center;video {width: 100%; // 全屏下height: 100%;}.controls {position: absolute;bottom: 33px;color: #ffffff;padding: 0 12px 0 10px;width: 100%;display: flex;justify-content: space-between;.timer {opacity: 1;font-size: 14px;line-height: 22px;font-weight: 400;color: #fff;display: inline-block;position: relative;top: -4px;-moz-user-select: none;-webkit-user-select: none;user-select: none;}.playsauto {display: inline-block;width: 20px;height: 20px;margin-right: 12px;cursor: pointer;}.playins {background: url('./imgs/playto.png');background-size: 20px 20px;}.stopIns {background: url('./imgs/palystop.png');background-size: 20px 20px;}.control-right {span {display: inline-block;width: 20px;height: 20px;vertical-align: middle;}span:hover {cursor: pointer;}.control-voice {background: url('./imgs/source.png');background-size: 20px 20px;.voices-pross {height: 2px;background: #fff;transform: rotate(45deg);position: relative;top: -3px;}.noSource {opacity: 0;}}.control-screen {background: url('./imgs/screen.png');background-size: 20px 20px;margin-left: 16px;}.control-more {background: url('./imgs/more.png');background-size: 20px 20px;margin-left: 16px;position: relative;.more-model {position: absolute;left: -132px;bottom: 0;background: #fff;color: #262626;width: 120px;height: 136px;padding: 8px 0;border-radius: 4px;span {display: block;width: 100%;text-align: left;padding: 9px 12px;height: 40px;font-size: 14px;}span:hover {background: #f5f5f5;}}.more-speed {height: 176px;}.isChecked {color: #2061e6;}}}}.progress {width: 100%;height: 4px;position: absolute;bottom: 12px;background: rgba(0, 0, 0, 0.5);.duration {width: 0;height: 4px;background: #2061e6;}i {position: absolute;width: 12px;height: 12px;background: #fff;border-radius: 6px;top: -4px;left: 0;cursor: pointer;}}.start {width: 42px;height: 42px;position: absolute;top: 50%;left: 50%;transform: translate(-50%, -50%);cursor: pointer;}.playin {background: url('./imgs/playto.png');background-size: 42px 42px;}.stopIn {background: url('./imgs/palystop.png');background-size: 42px 42px;opacity: 0;}.stopIn:hover {opacity: 1;}
}
</style>

vue自定义一个视频播放器相关推荐

  1. 在Vue中自制视频播放器(上)

    在Vue中自制视频播放器(上) 前言 初始化组件 开始/暂停按钮 停止按钮 静音按钮 视频播放时间 全屏按钮 源代码 前言 平时大家在浏览视频网站时,会发现各大视频网站都有自己的视频控制组件,虽然浏览 ...

  2. vue引入video视频播放器(视频调用代码范例)

    vue引入video视频播放器(视频调用代码范例) VUE视频调用代码范例1: <template><div><div id="player"> ...

  3. 嵌入式Qt 开发一个视频播放器

    上篇文章:嵌入式 Qt开发一个音乐播放器,使用Qt制作了一个音乐播放器,并在OK3568开发板上进行了运行测试,实际测试效果还不错. 本篇继续来实现一个Qt视频播放器软件,可以实现视频列表的显示与选择 ...

  4. vue中DPlayer视频播放器使用方法

    vue中DPlayer视频播放器使用方法 1通过npm下载 npm install dplayer - s 2在需要使用的组件中导入 import Dplayer from 'Dplayer' 3页面 ...

  5. 用QT5做一个视频播放器

    作为一个菜鸟有空的时候都会做一些QT小项目拿来练练手,今天做的是一个视频播放器,暂时只实现了本地视频的播放,后续会继续完善实现网络播放功能. (1)因为图片都是自己网上随便找的,做的界面有点丑,后续有 ...

  6. 用Pyqt5写一个视频播放器

    用Pyqt5写一个视频播放器 编写方式: Qt Designer设计,pyuic5转化为.py文件. 播放器效果: 代码链接:https://github.com/GRF-Sunomikp31/Qt_ ...

  7. FFmpeg开发(四)——Qt实现一个视频播放器(参考了暴风影音、迅雷影音)

    FFmpeg开发(四)--Qt实现一个视频播放器(参考了暴风影音.迅雷影音) 本系列文章目录: FFmpeg开发(一)一Qt Creator配置FFmpeg FFmpeg开发(二)--(FFmpeg基 ...

  8. Video标签自定义简易视频播放器

    Video标签自定义简易视频播放器 提示:以下是本篇文章正文内容,下面案例可供参考 一.Dom结构 <template><el-dialog :title="winTitl ...

  9. 安卓使用MediaPlayer自定义音频视频播放器

    全栈工程师开发手册 (作者:栾鹏) 安卓教程全解 安卓使用MediaPlayer,一般还要配置一个播放画面SurfaceView,和一个进度条SeekBar. 视频的播放会更改进度条的进度,也可以手动 ...

  10. 自定义Android视频播放器 - 切换横竖屏

    前一篇自定义了SurfaceView,然后尝试横屏显示,虽然视频适配方面没有问题,但是没有占满整个屏幕. 我分析了一下一般的视频播放器,发现: 竖屏播放视频,播放器的宽度占满手机屏幕的宽度,播放器的高 ...

最新文章

  1. go build 编译报错 missing go.sum entry for module providing package
  2. 读样章、写评语,即有机会获赠《编程大师访谈录》!
  3. js最小化浏览器_Handtrack.js 开源:3行JS代码搞定手部动作跟踪
  4. 吴恩达 coursera ML 第六课总结+作业答案
  5. mxnet基础到提高(22)-C++-常量和变量
  6. 5加载stm32 keil_KEIL 那些编辑技巧与方法
  7. Java中的Google ClientLogin实用程序
  8. sql server 2000的数据库还原
  9. Defense hash algorithm collision 防御hash算法冲突导致拒绝服务器
  10. 【5分钟Paper】Fast强化学习和Slow强化学习
  11. 2020 年省份数据拉取
  12. Java实现支付功能(支付宝)
  13. 微信建群怎么建?2个方法,快速学会!
  14. intellij idea 类和文件夹(目录)左上角出现小叉号
  15. [MySQL]超市购物管理系统
  16. 解决OBS录屏模糊问题
  17. 启发式测试策略模型(Heuristic Test Strategy Model,简称HTSM)
  18. 什么是OPC UA?为什么它会继续使用?
  19. 今天才知道!华为手机摄像头可不止能拍照,它还能提高办公效率
  20. 什么是元数据(元数据)?

热门文章

  1. 【Note2】MPS/PXE/ADS/INA电流电压,i2c设备在位和读,samba/nfs,ntp/log/me/树莓派,pip/office,vr,i2ctool,大数据,pam
  2. python dlib opencv人脸识别准确度_Dlib+OpenCV深度学习人脸识别
  3. EtherCat主站开源的C语言库SOEM说明
  4. java8 32位脱机安装_java8离线安装包32位 官方最新版
  5. Windows server 2008 R2 SP1 IE8升级IE11(离线安装)
  6. 【CSDN软考VIP资料群】让软考通过更容易,软考资料大全支持你软考!
  7. pytorch——MINST数据集
  8. 挑战程序设计竞赛(第二章:2.1 搜索)
  9. (五)比赛中的CV算法(上2)目标检测初步:神经网络及优化方法
  10. 前端面试题及答案(持续更新)