vue 中 自定义视频video
自定义视频进度条、音量、选集、全屏功能
利用HTML5 Audio/Video 事件给出的事件
<video :src= videoingurl ref="myvideo" @canplay="getTotal" @timeupdate="timeupdate"></video>
timeupdate:监控视频当前播放的时间控制进度条
timeupdate() {
if(this.myvideo.currentTime == this.myvideo.duration){
this.isPaused = !this.isPaused
this.myvideo.pause()
}
this.currentTime = this.timeFormat(this.myvideo.currentTime)
this.currentTimeVal = this.myvideo.currentTime
},
canplay:获取视频的总时长、进度条最大值
getTotal() {
this.totalTime = this.timeFormat(this.myvideo.duration)
this.durationProgress = this.myvideo.duration
},
成品如下:


完整代码如下:
<div class="video-box" class="video-info-height">
<video :src= videoingurl ref="myvideo" @canplay="getTotal" @timeupdate="timeupdate"></video>
<div class="progress">
<el-slider v-model="currentTimeVal" :max="durationProgress" :show-tooltip="false" @change="getNewTime"> </el-slider>
</div>
<div class="control">
<i class="iconfonts" :class="isPaused ? 'iconzanting1' : 'iconicon_play'" @click="play()"></i>
<span class="time">{{currentTime}} / {{totalTime}}</span>
<i class="iconfonts iconyinliang-gao"></i>
<el-slider v-model="volume" @change="getNewVoice"></el-slider>
<span class="anthology">选集</span>
<el-select v-model="videoingurl" placeholder="请选择" @change="changevideo">
<el-option
v-for="item in videoinglist"
:key="item.url"
:label="item.channelDesc"
:value="item.url"
></el-option>
</el-select>
<i class="iconfont iconquanping" @click="toggleFullScreen"></i>
</div>
<--以下内容是项目中需要播放其他类型内容,可自行绕过-->
<div class="operating-room-video">
<div class="lunb">
<div class="sing" v-for="(i,index) in videochannalList" @click="clickvideosing(i,index)">
<img v-show="currentIndex !== index" src="../../assets/images/videoimg.png" alt />
<img v-show="currentIndex == index" src="../../assets/images/login_outer_bgi.png" alt />
<p class="name">{{videochannalList[index][0].channelDesc}}</p>
</div>
</div>
</div>
</div>
data() {
return {
volume: 30, // 音量
videochannalList: [], // 全部视频
// 选集列表
videoinglist: [
{
url: 'https://www.yy.com/ftpurl/medical-record/video/2020/07/01/1593596146146382.mp4',
channelDesc: '导播'
},
{
url: 'http://clips.vorwaerts-gmbh.de/big_buck_bunny.mp4',
channelDesc: '导播'
}
],
videoingurl: '', // 正在播放视频地址
myvideo: '',
isPaused: false, //标记当前的播放状态
currentTime: '00:00', //当前播放时间
totalTime: '00:00', //总时长
currentTimeVal: 0, // 进度条当前播放时间,必须是number类型
durationProgress: 0, // 进度条的最大值,必须是number类型
currentIndex: '', // 选中视频类型索引
};
},
mounted() {
//获取播放器元素
this.myvideo = this.$refs.myvideo
},
methods: {
// 选集
changevideo(val) {
console.log(val)
if(this.videoingurl == val) {
this.isPaused = false
this.myvideo.pause()
}
},
play() {
//修改当前的播放状态
this.isPaused = !this.isPaused
if(this.isPaused) {
this.myvideo.play()
}else {
this.myvideo.pause()
}
},
// 进度条拖动时间
getNewTime(val) {
console.log(val)
this.myvideo.currentTime = val
},
// 音量控制
getNewVoice(val) {
this.volume = val
let newVc = val / 100 //h5规定,volume的值必须再0-1之间,比如0.5就是50%的音量,但是进度条的值为100,因此这里做个除法
this.myvideo.volume = newVc //赋值
},
//时间格式化处理
timeFormat(time) {
let minute = Math.floor((time % 3600) / 60)
let second = Math.floor(time % 60)
minute = minute < 10 ? "0" + minute : minute
second = second < 10 ? "0" + second : second
return `${minute}:${second}`
},
//获取总时长
getTotal() {
this.totalTime = this.timeFormat(this.myvideo.duration)
this.durationProgress = this.myvideo.duration
},
//获取当前视频播放到的时间
timeupdate() {
if(this.myvideo.currentTime == this.myvideo.duration){
this.isPaused = !this.isPaused
this.myvideo.pause()
}
this.currentTime = this.timeFormat(this.myvideo.currentTime)
this.currentTimeVal = this.myvideo.currentTime
},
//全屏切换
toggleFullScreen(event) {
const myvideo = this.$refs.myvideo
//如果当前是全屏状态,就退出全屏,否则进入全屏状态
//获取当前的全屏状态
let isFullscreen = document.webkitIsFullScreen || document.fullscreen
if(!isFullscreen) {
const inFun = myvideo.requestFullscreen || myvideo.webkitRequestFullScreen
//让当前播放器进入全屏状态
inFun.call(myvideo)
}else {
const exitFun = document.exitFullscreen || document.webkitExitFullScreen
//退出全屏状态要使用document
exitFun.call(document)
}
},
}
.video-box,
.info-box {
float: left;
background: #fff;
height: 5.1rem;
box-sizing: border-box;
}
.video-box {
width: 8.7rem;
margin-right: 0.16rem;
padding: 0.2rem;
box-sizing: border-box;
position: relative;
video {
width: 100%;
height: 4.7rem;
object-fit: cover;
cursor: pointer;
}
.control {
width: 8.3rem;
height: 0.55rem;
padding: 0.2rem;
position: absolute;
top: 4.35rem;
left: 0.2rem;
background-color: rgba(0, 0, 0, 0.2);
display: flex;
align-items: center;
color: #fff;
.iconicon_play{
cursor:pointer;
}
/deep/.el-select .el-input .el-select__caret {
color: #FFF;
}
/deep/.el-input__inner {
color: #FFF;
&::placeholder {
color: #FFF;
}
&::-webkit-input-placeholder {
/* WebKit browsers 适配谷歌 */
color:#FFF;
}
&:-moz-placeholder {
/* Mozilla Firefox 4 to 18 适配火狐 */
color: #FFF;
}
&::-moz-placeholder {
/* Mozilla Firefox 19+ 适配火狐 */
color: #FFF;
}
&:-ms-input-placeholder {
/* Internet Explorer 10+ 适配ie*/
color: #FFF;
}
}
.time {
margin-left: 0.22rem;
color: #f5f5fa;
}
.iconyinliang-gao {
margin-left: 2.68rem;
}
/deep/.el-input,
div.el-select {
width: 1.1rem !important;
background-color: transparent;
.el-input__inner {
background-color: transparent;
}
}
.anthology {
margin: 0 0.2rem 0 0.24rem;
}
.iconquanping-video,.iconquanping {
margin-left: 0.44rem;
cursor:pointer;
}
}
/deep/ .el-slider {
width: 0.88rem;
margin-left: 0.1rem;
.el-slider__runway,
.el-slider__bar {
height: 0.04rem;
}
.el-slider__button {
width: 0.13rem;
height: 0.13rem;
}
.el-slider__button-wrapper {
top: -16px;
}
}
.progress {
width: 8.3rem;
position: absolute;
top: 4.14rem;
left: 0.2rem;
overflow: hidden;
.el-slider{
width:100%;
margin-left:0;
}
}
.operating-room-video::-webkit-scrollbar {
// height: 4px;
// background:#bababa;
}
.operating-room-video {
width: 100%;
height: 1.3rem;
white-space:nowrap;
overflow-x:auto;
overflow-y: hidden;
> div.lunb{
width: max-content;
height: 1.2rem;
> div.sing {
width: 2.07rem;
display: block;
height: 1.2rem;
float: left;
position: relative;
cursor: pointer;
> img {
width: 2.08rem;
height: 1.2rem;
}
.name {
width: 100%;
position: absolute;
bottom: 0;
left: 0;
background-color: rgba(0, 0, 0, 0.1);
text-align: center;
color: #fff;
}
}
}
}
}
.video-info-height {
height: 6.3rem;
}
.info-box {
width: 3.92rem;
/deep/ .el-tabs__nav-scroll {
display: flex;
justify-content: space-around;
.el-tabs__item {
font-size: 0.18rem;
padding: 0 0.5rem;
color: #999;
}
.el-tabs__active-bar {
width: 0.75rem !important;
background-color: @color;
}
.is-active {
color: #333;
}
}
.video-info {
padding: 0.1rem 0.4rem;
> div {
line-height: 0.34rem;
display: flex;
> div:first-child {
color: @color;
margin-right: 0.1rem;
min-width: 0.7rem;
}
> div {
display: inline-block;
}
}
}
.patient-info {
> div {
> div:first-child {
min-width: 0.9rem;
}
}
}
}