feat: support player

This commit is contained in:
yanghao05
2025-04-25 14:38:55 +08:00
parent 11bea6b8c9
commit 75865ae19a
7 changed files with 151 additions and 12 deletions

View File

@@ -10,6 +10,10 @@ export const postApi = {
}
});
},
play(id) {
return client.get(`/api/posts/${id}/play`);
},
show(id) {
return client.get(`/api/posts/${id}`);
},

View File

@@ -1,5 +1,7 @@
<script setup>
import { onMounted, ref } from 'vue'
import Plyr from 'plyr'
import 'plyr/dist/plyr.css'
import { onMounted, onUnmounted, ref } from 'vue'
import { useRoute, useRouter } from 'vue-router'
import { postApi } from '../api/postApi'
@@ -7,6 +9,49 @@ const route = useRoute()
const router = useRouter()
const article = ref(null)
const buying = ref(false)
const player = ref(null)
const videoElement = ref(null)
const mediaLoaded = ref(false)
const initializePlayer = () => {
if (videoElement.value) {
player.value = new Plyr(videoElement.value, {
controls: ['play', 'progress', 'current-time', 'duration', 'settings', 'fullscreen'],
settings: ['speed'],
speed: { selected: 1, options: [0.5, 0.75, 1] },
autoplay: false
})
player.value.on('play', async () => {
if (!mediaLoaded.value) {
await loadVideoSource()
}
})
player.value.on('ended', () => {
mediaLoaded.value = false
videoElement.value.src = ''
})
}
}
const loadVideoSource = async () => {
try {
const { data } = await postApi.play(route.params.id)
if (videoElement.value) {
mediaLoaded.value = true
videoElement.value.src = data.url
await player.value.restart()
await player.value.play()
}
} catch (error) {
console.error('Failed to load video:', error)
// alert('视频加载失败,请稍后重试')
}
}
const handleBuy = async () => {
if (buying.value) return
@@ -46,23 +91,24 @@ const fetchArticle = async () => {
}
}
const formatDate = (dateString) => {
return new Date(dateString).toLocaleDateString('zh-CN', {
year: 'numeric',
month: 'long',
day: 'numeric'
})
}
onMounted(async () => {
await fetchArticle()
initializePlayer()
})
onUnmounted(() => {
if (player.value) {
player.value.destroy()
}
})
</script>
<template>
<div class="min-h-screen bg-gray-50">
<div v-if="article">
<video controls :poster="article.head_images[0]" class="w-full aspect-video object-cover">
<video ref="videoElement" :poster="article.head_images[0]"
class="w-full aspect-video object-cover plyr-video" playsinline preload="none">
<source type="video/mp4" />
Your browser does not support the video tag.
</video>
<div class="p-4">
@@ -88,4 +134,12 @@ onMounted(async () => {
</div>
</div>
</div>
</template>
</template>
<style>
.plyr-video {
--plyr-color-main: #2563eb;
width: 100%;
max-height: 100vh;
}
</style>