177 lines
3.3 KiB
Vue
Raw Normal View History

2025-06-06 03:08:19 +08:00
<template>
<view class="video_box">
<video
class="video_file"
:id="`video_${src}`"
:ref="`video_${src}`"
:src="src"
loop
:show-play-btn="false"
:show-center-play-btn="false"
:controls="false"
:enable-progress-gesture="false"
object-fit="contain"
:autoplay="play"
@timeupdate="onScheduleChange"
@waiting="onWaiting"
></video>
<!-- 播放按钮 -->
<view class="play_btn" @click="onPlay"><image class="icon_play" v-if="playState == 1000" src="../../static/demo/ic_play.png" mode="aspectFit"></image></view>
<view class="play_schedule">
<view class="schedule" :style="{ width: schedule + '%' }"><view v-if="progressDrag" class="progress_drag_dot"></view></view>
</view>
</view>
</template>
<script>
export default {
props: {
src: {
type: String,
default: ''
},
play: {
type: Boolean,
default: false
},
poster: {
//视频封面的图片
type: String,
default: ''
},
progress: {
type: Number,
default: 0
},
progressValue: {
type: Number,
default: 0
}
},
data() {
return {
schedule: 0,
// 1000 待播放
// 2000 播放中
// 3000 播放缓冲中
playState: 1000,
// 是否拖动进度
progressDrag: false,
// 视频总长度
duration: 0
};
},
watch: {
play(val) {
if (val) {
setTimeout(() => {
this.videoCtx.play();
this.playState = 2000;
}, 200);
} else {
setTimeout(() => {
this.videoCtx.pause();
this.videoCtx.seek(0);
this.playState = 1000;
this.schedule = 0;
},100);
}
},
progress(val) {
if (this.play) {
if (val == 0) {
this.progressDrag = true;
} else {
this.schedule = val;
}
}
},
progressValue(val) {
if (this.play) {
this.schedule = val;
this.progressDrag = false;
this.videoCtx.seek(this.duration * (val / 100));
}
}
},
mounted() {
this.videoCtx = uni.createVideoContext(`video_${this.src}`, this);
if(this.play){
this.playState = 2000;
}
},
methods: {
onScheduleChange(e) {
this.duration = e.detail.duration;
if (!this.progressDrag) {
this.schedule = (e.detail.currentTime / e.detail.duration) * 100;
}
},
onPlay() {
if (this.playState == 2000) {
this.videoCtx.pause();
this.playState = 1000;
} else if (this.playState == 1000) {
this.videoCtx.play();
this.playState = 2000;
} else if (this.playState == 3000) {
this.videoCtx.play();
this.playState = 2000;
}
},
// 视频进入缓冲中
onWaiting() {
this.playState = 3000;
}
}
};
</script>
<style lang="scss" scoped>
@import '@/style/mixin.scss';
.video_box {
position: relative;
}
.video_file {
width: 750rpx;
height: calc(100vh - var(--window-bottom));
}
.play_schedule {
position: absolute;
bottom: 6rpx;
left: 0;
height: 2rpx;
width: 100%;
background-color: rgba(255, 255, 255, 0.2);
z-index: 3;
}
.schedule {
background-color: #fff;
height: 2rpx;
width: 0%;
position: relative;
}
.progress_drag_dot {
position: absolute;
right: -8rpx;
top: -6rpx;
width: 16rpx;
height: 16rpx;
border-radius: 50%;
background-color: #fff;
}
.play_btn {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
justify-content: center;
align-items: center;
}
.icon_play {
width: 90rpx;
height: 90rpx;
}
</style>