vue2封装一个视频显示组件
时间: 2023-12-28 20:05:47 浏览: 92
以下是一个简单的Vue2视频显示组件的封装示例:
```vue
<template>
<div class="video-container">
<video ref="videoPlayer" :src="source" @play="onPlay" @pause="onPause" @ended="onEnded"></video>
<div class="controls" :class="{ active: showControls }">
<button @click="togglePlay"><i :class="playIcon"></i></button>
<div class="progress">
<div class="bar" :style="{ width: progress + '%' }"></div>
<div class="thumb" :style="{ left: progress + '%' }" @mousedown="onThumbMouseDown"></div>
</div>
<span class="current-time">{{ currentTime }}</span>
<span class="total-time">{{ totalTime }}</span>
<button @click="toggleMute"><i :class="muteIcon"></i></button>
<div class="volume">
<div class="bar" :style="{ width: volume + '%' }"></div>
<div class="thumb" :style="{ left: volume + '%' }" @mousedown="onThumbMouseDown"></div>
</div>
<button @click="toggleFullscreen"><i :class="fullscreenIcon"></i></button>
</div>
</div>
</template>
<script>
export default {
props: {
source: {
type: String,
required: true
},
autoplay: {
type: Boolean,
default: false
},
controls: {
type: Boolean,
default: true
},
loop: {
type: Boolean,
default: false
},
muted: {
type: Boolean,
default: false
},
poster: {
type: String,
default: ''
}
},
data() {
return {
showControls: false,
isPlaying: false,
isMuted: false,
isFullscreen: false,
duration: 0,
currentTime: 0,
volume: 100,
progress: 0
}
},
mounted() {
const videoPlayer = this.$refs.videoPlayer
videoPlayer.addEventListener('durationchange', this.onDurationChange)
videoPlayer.addEventListener('timeupdate', this.onTimeUpdate)
videoPlayer.addEventListener('volumechange', this.onVolumeChange)
if (this.autoplay) {
videoPlayer.play()
this.isPlaying = true
}
if (this.muted) {
videoPlayer.muted = true
this.isMuted = true
}
if (this.controls) {
this.showControls = true
}
if (this.poster) {
videoPlayer.poster = this.poster
}
},
beforeUnmount() {
const videoPlayer = this.$refs.videoPlayer
videoPlayer.removeEventListener('durationchange', this.onDurationChange)
videoPlayer.removeEventListener('timeupdate', this.onTimeUpdate)
videoPlayer.removeEventListener('volumechange', this.onVolumeChange)
},
computed: {
playIcon() {
return this.isPlaying ? 'fa fa-pause' : 'fa fa-play'
},
muteIcon() {
return this.isMuted ? 'fa fa-volume-off' : 'fa fa-volume-up'
},
fullscreenIcon() {
return this.isFullscreen ? 'fa fa-compress' : 'fa fa-expand'
},
totalTime() {
const totalSeconds = parseInt(this.duration)
const minutes = Math.floor(totalSeconds / 60)
const seconds = totalSeconds - minutes * 60
return `${minutes}:${seconds.toString().padStart(2, '0')}`
}
},
methods: {
onDurationChange() {
this.duration = this.$refs.videoPlayer.duration
},
onTimeUpdate() {
this.currentTime = this.$refs.videoPlayer.currentTime
this.progress = (this.currentTime / this.duration) * 100
},
onVolumeChange() {
this.volume = Math.round(this.$refs.videoPlayer.volume * 100)
},
onThumbMouseDown(event) {
const thumb = event.target
const bar = thumb.previousSibling
const startX = event.clientX
const onMouseMove = event => {
const delta = event.clientX - startX
const rect = bar.getBoundingClientRect()
const barWidth = rect.right - rect.left
const thumbWidth = thumb.offsetWidth
const left = Math.min(Math.max(rect.left, rect.left + delta), rect.right - thumbWidth)
const position = (left - rect.left) / barWidth
thumb.style.left = position * 100 + '%'
bar.style.width = position * 100 + '%'
if (bar === thumb.nextSibling) {
this.$refs.videoPlayer.volume = position
} else {
this.$refs.videoPlayer.currentTime = position * this.duration
}
}
const onMouseUp = () => {
document.removeEventListener('mousemove', onMouseMove)
document.removeEventListener('mouseup', onMouseUp)
}
document.addEventListener('mousemove', onMouseMove)
document.addEventListener('mouseup', onMouseUp)
},
onPlay() {
this.isPlaying = true
},
onPause() {
this.isPlaying = false
},
onEnded() {
if (this.loop) {
this.$refs.videoPlayer.currentTime = 0
this.$refs.videoPlayer.play()
} else {
this.isPlaying = false
}
},
togglePlay() {
const videoPlayer = this.$refs.videoPlayer
if (this.isPlaying) {
videoPlayer.pause()
} else {
videoPlayer.play()
}
this.isPlaying = !this.isPlaying
},
toggleMute() {
const videoPlayer = this.$refs.videoPlayer
if (this.isMuted) {
videoPlayer.muted = false
videoPlayer.volume = 0.5
} else {
videoPlayer.muted = true
}
this.isMuted = !this.isMuted
},
toggleFullscreen() {
const videoContainer = this.$el
if (this.isFullscreen) {
if (document.exitFullscreen) {
document.exitFullscreen()
} else if (document.webkitExitFullscreen) {
document.webkitExitFullscreen()
} else if (document.mozCancelFullScreen) {
document.mozCancelFullScreen()
} else if (document.msExitFullscreen) {
document.msExitFullscreen()
}
} else {
if (videoContainer.requestFullscreen) {
videoContainer.requestFullscreen()
} else if (videoContainer.webkitRequestFullscreen) {
videoContainer.webkitRequestFullscreen()
} else if (videoContainer.mozRequestFullScreen) {
videoContainer.mozRequestFullScreen()
} else if (videoContainer.msRequestFullscreen) {
videoContainer.msRequestFullscreen()
}
}
this.isFullscreen = !this.isFullscreen
}
}
}
</script>
<style>
.video-container {
position: relative;
width: 100%;
height: 0;
padding-bottom: 56.25%;
overflow: hidden;
}
.video-container video {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
object-fit: contain;
}
.controls {
position: absolute;
bottom: 0;
left: 0;
width: 100%;
padding: 10px;
background-color: rgba(0, 0, 0, 0.5);
color: #fff;
font-size: 14px;
text-align: center;
transition: opacity 0.3s;
opacity: 0;
pointer-events: none;
}
.controls.active {
opacity: 1;
pointer-events: auto;
}
.controls button {
background-color: transparent;
border: none;
outline: none;
cursor: pointer;
padding: 0;
margin-right: 10px;
}
.controls button i {
font-size: 24px;
}
.progress {
position: relative;
height: 5px;
width: 100%;
background-color: rgba(255, 255, 255, 0.5);
margin: 10px 0;
cursor: pointer;
}
.progress .bar {
position: absolute;
top: 0;
left: 0;
height: 100%;
background-color: #fff;
}
.progress .thumb {
position: absolute;
top: -7.5px;
left: 0;
width: 15px;
height: 15px;
border-radius: 50%;
background-color: #fff;
cursor: pointer;
transform: translateX(-50%);
}
.volume {
position: relative;
height: 5px;
width: 60px;
background-color: rgba(255, 255, 255, 0.5);
margin-right: 10px;
cursor: pointer;
}
.volume .bar {
position: absolute;
top: 0;
left: 0;
height: 100%;
background-color: #fff;
}
.volume .thumb {
position: absolute;
top: -7.5px;
left: 0;
width: 15px;
height: 15px;
border-radius: 50%;
background-color: #fff;
cursor: pointer;
transform: translateX(-50%);
}
</style>
```
使用示例:
```vue
<template>
<div>
<video-player source="https://www.w3schools.com/html/mov_bbb.mp4" poster="https://www.w3schools.com/html/pic_trulli.jpg"></video-player>
</div>
</template>
<script>
import VideoPlayer from './VideoPlayer.vue'
export default {
components: {
VideoPlayer
}
}
</script>
```
阅读全文