feat: support player
This commit is contained in:
@@ -10,6 +10,10 @@ export const postApi = {
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
play(id) {
|
||||
return client.get(`/api/posts/${id}/play`);
|
||||
},
|
||||
show(id) {
|
||||
return client.get(`/api/posts/${id}`);
|
||||
},
|
||||
|
||||
@@ -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>
|
||||
Reference in New Issue
Block a user