57 lines
947 B
Vue
57 lines
947 B
Vue
<template>
|
|
<div class="video-player">
|
|
<video
|
|
ref="playerRef"
|
|
class="native-player"
|
|
:src="src"
|
|
:poster="poster"
|
|
controls
|
|
playsinline
|
|
preload="metadata"
|
|
@timeupdate="handleTimeUpdate"
|
|
@ended="emit('ended')"
|
|
/>
|
|
</div>
|
|
</template>
|
|
|
|
<script setup lang="ts">
|
|
import { ref, watch } from 'vue'
|
|
|
|
const props = defineProps<{
|
|
src: string
|
|
poster?: string
|
|
}>()
|
|
|
|
const emit = defineEmits<{
|
|
timeupdate: [time: number]
|
|
ended: []
|
|
}>()
|
|
|
|
const playerRef = ref<HTMLVideoElement>()
|
|
|
|
const handleTimeUpdate = () => {
|
|
emit('timeupdate', playerRef.value?.currentTime || 0)
|
|
}
|
|
|
|
watch(() => props.src, () => {
|
|
if (!playerRef.value) return
|
|
playerRef.value.load()
|
|
})
|
|
</script>
|
|
|
|
<style scoped lang="scss">
|
|
.video-player {
|
|
width: 100%;
|
|
height: 100%;
|
|
background: #000;
|
|
}
|
|
|
|
.native-player {
|
|
width: 100%;
|
|
height: 100%;
|
|
aspect-ratio: 16 / 9;
|
|
display: block;
|
|
background: #000;
|
|
}
|
|
</style>
|