mrr.sj.front/components/video-player/video-player.vue

200 lines
4.2 KiB
Vue
Raw Normal View History

2026-03-24 11:45:13 +08:00
<template>
<view class="video-player-container">
<video
:id="videoId"
:src="'https://app.mrrweb.com.cn'+src"
class="video-cont"
:autoplay="autoplay"
:controls="controls"
:muted="isMuted"
:show-fullscreen-btn="showFullscreenBtn"
:show-play-btn="showPlayBtn"
:show-progress="showProgress"
:loop="loop"
:object-fit="objectFit"
@play="onPlay"
@pause="onPause"
@ended="onEnded"
@error="onError"
@timeupdate="onTimeUpdate"
@fullscreenchange="onFullscreenChange">
</video>
<view class="video-controls">
<!-- <view class="control-btn" @click="togglePlay">
<image :src="isPlaying ? '/static/images/pause.png' : '/static/images/play.png'" class="control-icon"></image>
</view> -->
<view class="control-btn" @click="toggleMute">
<image :src="isMuted ? '/static/images/mute.png' : '/static/images/unmute.png'" class="control-icon"></image>
</view>
</view>
</view>
</template>
<script>
export default {
name: 'VideoPlayer',
props: {
// 视频源
src: {
type: String,
required: true
},
videoStyle: {
type: String,
default: 'width: 200rpx;height: 200rpx;'
},
// 视频封面
poster: {
type: String,
default: ''
},
// 是否显示控制栏
controls: {
type: Boolean,
default: false
},
// 是否自动播放
autoplay: {
type: Boolean,
default: true
},
// 是否循环播放
loop: {
type: Boolean,
default: false
},
// 是否静音
muted: {
type: Boolean,
default: true
},
// 是否显示全屏按钮
showFullscreenBtn: {
type: Boolean,
default: true
},
// 是否显示播放按钮
showPlayBtn: {
type: Boolean,
default: true
},
// 是否显示进度条
showProgress: {
type: Boolean,
default: true
},
// 视频填充模式
objectFit: {
type: String,
default: 'cover',
validator: value => ['contain', 'fill', 'cover'].includes(value)
}
},
data() {
return {
videoId: `video-${Date.now()}`,
currentTime: 0,
duration: 0,
isPlaying: false,
isFullscreen: false
}
},
methods: {
// 播放事件
onPlay(e) {
this.isPlaying = true
this.$emit('play', e)
},
// 暂停事件
onPause(e) {
this.isPlaying = false
this.$emit('pause', e)
},
// 播放结束事件
onEnded(e) {
this.isPlaying = false
this.$emit('ended', e)
},
// 错误事件
onError(e) {
this.$emit('error', e)
},
// 播放进度更新事件
onTimeUpdate(e) {
this.currentTime = e.detail.currentTime
this.duration = e.detail.duration
this.$emit('timeupdate', e)
},
// 全屏状态改变事件
onFullscreenChange(e) {
this.isFullscreen = e.detail.fullScreen
this.$emit('fullscreenchange', e)
},
// 播放方法
play() {
const videoContext = uni.createVideoContext(this.videoId)
videoContext.play()
},
// 暂停方法
pause() {
const videoContext = uni.createVideoContext(this.videoId)
videoContext.pause()
},
// 跳转到指定时间
seek(time) {
const videoContext = uni.createVideoContext(this.videoId)
videoContext.seek(time)
},
// 进入全屏
requestFullScreen() {
const videoContext = uni.createVideoContext(this.videoId)
videoContext.requestFullScreen()
},
// 退出全屏
exitFullScreen() {
const videoContext = uni.createVideoContext(this.videoId)
videoContext.exitFullScreen()
}
}
}
</script>
<style lang="scss" scoped>
video-player-container {
width: 750rpx;
height: 750rpx;
position: relative;
}
.video-cont {
width: 750rpx;
height: 750rpx;
}
.video-controls {
position: absolute;
left: 0;
right: 0;
bottom: 0;
height: 100rpx;
display: flex;
align-items: flex-start;
justify-content: center;
z-index: 3;
}
.control-btn {
width: 60rpx;
height: 60rpx;
display: flex;
align-items: center;
justify-content: center;
background-color: rgba(0, 0, 0, 0.5);
border-radius: 30rpx;
margin: 0 20rpx;
}
.control-icon {
width: 40rpx;
height: 40rpx;
}
</style>