|
|
@@ -0,0 +1,147 @@
|
|
|
+<template>
|
|
|
+ <div class="video-player">
|
|
|
+ <video
|
|
|
+ ref="videoRef"
|
|
|
+ muted
|
|
|
+ playsinline="true"
|
|
|
+ webkit-playsinline="true"
|
|
|
+ class="video"
|
|
|
+ :src="playUrl"
|
|
|
+ :poster="poster"
|
|
|
+ ></video>
|
|
|
+ <div class="video-box" :class="{ pause: !isPlaying }" @click="changePlay">
|
|
|
+ <van-icon class="play-img" v-if="!isPlaying" size="80" color="#fff" name="play-circle" />
|
|
|
+ <van-slider v-model="currentVal" @change="onChange" />
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+</template>
|
|
|
+
|
|
|
+<script setup>
|
|
|
+import { ref, onMounted, nextTick, computed, onUnmounted } from 'vue'
|
|
|
+import { accDiv } from '../plugins/calc'
|
|
|
+const props = defineProps({
|
|
|
+ playUrl: {
|
|
|
+ type: String,
|
|
|
+ default: ''
|
|
|
+ },
|
|
|
+ poster: {
|
|
|
+ type: String,
|
|
|
+ default: ''
|
|
|
+ },
|
|
|
+ curEpInfo: {
|
|
|
+ type: Object,
|
|
|
+ default: () => {
|
|
|
+ return {}
|
|
|
+ }
|
|
|
+ }
|
|
|
+})
|
|
|
+
|
|
|
+const emit = defineEmits(['videoEnded'])
|
|
|
+
|
|
|
+const videoRef = ref(null)
|
|
|
+const currentVal = ref(0)
|
|
|
+const canChange = ref(true)
|
|
|
+onMounted(() => {
|
|
|
+ nextTick(() => {
|
|
|
+ videoRef.value.addEventListener('ended', () => {
|
|
|
+ emit('videoEnded')
|
|
|
+ console.log('播放结束')
|
|
|
+ })
|
|
|
+ videoRef.value.addEventListener('timeupdate', e => {
|
|
|
+ if (videoRef.value && videoRef.value.duration && canChange.value) {
|
|
|
+ currentVal.value = Number(
|
|
|
+ (accDiv(videoRef.value.currentTime, videoRef.value.duration) * 100).toFixed(2)
|
|
|
+ )
|
|
|
+ }
|
|
|
+ })
|
|
|
+ videoRef.value.addEventListener('play', () => {
|
|
|
+ isPlaying.value = true
|
|
|
+ })
|
|
|
+ videoRef.value.addEventListener('pause', () => {
|
|
|
+ isPlaying.value = false
|
|
|
+ })
|
|
|
+ })
|
|
|
+})
|
|
|
+
|
|
|
+function getCurrent() {
|
|
|
+ return videoRef.value.currentTime
|
|
|
+}
|
|
|
+
|
|
|
+function play() {
|
|
|
+ videoRef.value.play()
|
|
|
+}
|
|
|
+
|
|
|
+function pause() {
|
|
|
+ videoRef.value.pause()
|
|
|
+}
|
|
|
+
|
|
|
+function setCurrent(currentTime) {
|
|
|
+ videoRef.value.currentTime = currentTime
|
|
|
+ nextTick(() => {
|
|
|
+ canChange.value = true
|
|
|
+ })
|
|
|
+}
|
|
|
+
|
|
|
+function changeMuted() {
|
|
|
+ videoRef.value.muted = false
|
|
|
+}
|
|
|
+
|
|
|
+function onChange(value) {
|
|
|
+ canChange.value = false
|
|
|
+ setCurrent((videoRef.value.duration * value) / 100)
|
|
|
+ play()
|
|
|
+}
|
|
|
+
|
|
|
+const isPlaying = ref(false)
|
|
|
+function changePlay() {
|
|
|
+ if (isPlaying.value) {
|
|
|
+ pause()
|
|
|
+ } else {
|
|
|
+ play()
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+defineExpose({ getCurrent, play, pause, setCurrent, changeMuted })
|
|
|
+
|
|
|
+
|
|
|
+</script>
|
|
|
+
|
|
|
+<style lang="less" scoped>
|
|
|
+.video {
|
|
|
+ width: 100%;
|
|
|
+ height: calc(100vh - 95px - env(safe-area-inset-bottom) - env(safe-area-inset-top));
|
|
|
+}
|
|
|
+
|
|
|
+.video-player {
|
|
|
+ position: relative;
|
|
|
+
|
|
|
+ .video-box {
|
|
|
+ position: absolute;
|
|
|
+ top: 0;
|
|
|
+ left: 0;
|
|
|
+ right: 0;
|
|
|
+ bottom: 0;
|
|
|
+ z-index: 20;
|
|
|
+ transition: all ease-in-out 0.3s;
|
|
|
+ &.pause {
|
|
|
+ background-color: rgba(0, 0, 0, 0.6);
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+.van-slider {
|
|
|
+ position: absolute;
|
|
|
+ left: 0;
|
|
|
+ right: 0;
|
|
|
+ bottom: 0px;
|
|
|
+ --van-slider-button-width: 18px;
|
|
|
+ --van-slider-button-height: 18px;
|
|
|
+}
|
|
|
+
|
|
|
+.play-img {
|
|
|
+ position: absolute;
|
|
|
+ top: 50%;
|
|
|
+ left: 50%;
|
|
|
+ transform: translate(-50%, -50%);
|
|
|
+}
|
|
|
+</style>
|