暂时无法自动播放
This commit is contained in:
@@ -9,7 +9,7 @@ export default defineAppConfig({
|
||||
defaultVolume: 50,
|
||||
autoFullscreen: true,
|
||||
showControls: false,
|
||||
webSocketPort: 8080,
|
||||
webSocketPort: 6666,
|
||||
reconnectInterval: 5000
|
||||
},
|
||||
ui: {
|
||||
|
@@ -15,9 +15,12 @@
|
||||
v-if="currentVideo"
|
||||
ref="videoElement"
|
||||
class="w-full h-full object-contain"
|
||||
:src="currentVideo.path"
|
||||
:src="videoSrc"
|
||||
:volume="volume / 100"
|
||||
:loop="isLooping"
|
||||
playsinline
|
||||
:muted="isMuted"
|
||||
preload="auto"
|
||||
autoplay
|
||||
@loadedmetadata="onVideoLoaded"
|
||||
@timeupdate="onTimeUpdate"
|
||||
@@ -75,6 +78,7 @@
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
// remove direct import that breaks vite in dev; we will fallback to file:// URLs
|
||||
const appConfig = useAppConfig()
|
||||
const isDev = process.env.NODE_ENV === 'development'
|
||||
|
||||
@@ -93,10 +97,46 @@ const volume = ref(appConfig.player.defaultVolume)
|
||||
const isLooping = ref(false)
|
||||
const isFullscreen = ref(false)
|
||||
const showControls = ref(false)
|
||||
const isMuted = ref(true)
|
||||
|
||||
// Video element ref
|
||||
const videoElement = ref(null)
|
||||
|
||||
// Video source URL - reactive ref that gets updated when currentVideo changes
|
||||
const videoSrc = ref('')
|
||||
|
||||
// Convert file path to Tauri-compatible URL
|
||||
async function updateVideoSrc() {
|
||||
const raw = currentVideo.value?.path || ''
|
||||
if (!raw) {
|
||||
console.log('🎥 No video path available')
|
||||
videoSrc.value = ''
|
||||
return
|
||||
}
|
||||
|
||||
const filePath = raw.startsWith('file://') ? raw.slice(7) : raw
|
||||
console.log('🎥 Converting video path:', { raw, filePath })
|
||||
|
||||
// Use file:// protocol for local files in Tauri
|
||||
const absolutePath = filePath.startsWith('/') ? filePath : `/${filePath}`
|
||||
const fileUrl = `file://${absolutePath}`
|
||||
videoSrc.value = fileUrl
|
||||
console.log('🎥 Using file:// URL:')
|
||||
console.log(' - Original path:', raw)
|
||||
console.log(' - File path:', filePath)
|
||||
console.log(' - File URL:', fileUrl)
|
||||
}
|
||||
|
||||
// Watch for changes in currentVideo and update videoSrc
|
||||
watch(currentVideo, updateVideoSrc, { immediate: true })
|
||||
|
||||
// Watch for changes in videoSrc to debug
|
||||
watch(videoSrc, (newSrc, oldSrc) => {
|
||||
console.log('🎥 videoSrc changed:')
|
||||
console.log(' - Old:', oldSrc)
|
||||
console.log(' - New:', newSrc)
|
||||
})
|
||||
|
||||
// Computed properties
|
||||
const connectionStatusClass = computed(() => {
|
||||
switch (connectionStatus.value) {
|
||||
@@ -167,9 +207,57 @@ function setVolume(newVolume) {
|
||||
|
||||
// Video event handlers
|
||||
function onVideoLoaded() {
|
||||
console.log('🎬 Video loaded event triggered')
|
||||
if (videoElement.value) {
|
||||
duration.value = videoElement.value.duration
|
||||
videoElement.value.volume = volume.value / 100
|
||||
console.log('🎬 Video metadata:', {
|
||||
duration: duration.value,
|
||||
volume: volume.value,
|
||||
currentSrc: videoElement.value.currentSrc,
|
||||
readyState: videoElement.value.readyState
|
||||
})
|
||||
// 尝试主动播放;若被策略阻止则静音后重试
|
||||
console.log('🎬 Attempting to play video...')
|
||||
|
||||
// Always start muted to comply with autoplay policies, then unmute
|
||||
isMuted.value = true
|
||||
|
||||
// Small delay to ensure video is ready
|
||||
setTimeout(() => {
|
||||
if (videoElement.value) {
|
||||
const playPromise = videoElement.value.play()
|
||||
if (playPromise && typeof playPromise.then === 'function') {
|
||||
playPromise.then(() => {
|
||||
console.log('✅ Video started playing successfully (muted)')
|
||||
isPlaying.value = true
|
||||
|
||||
// Try to unmute after successful playback
|
||||
setTimeout(() => {
|
||||
if (videoElement.value) {
|
||||
videoElement.value.muted = false
|
||||
isMuted.value = false
|
||||
console.log('🔊 Video unmuted')
|
||||
}
|
||||
}, 1000)
|
||||
}).catch((err) => {
|
||||
console.error('❌ Autoplay failed:', err)
|
||||
// Show user a play button if autoplay fails
|
||||
showControls.value = true
|
||||
})
|
||||
} else {
|
||||
// Fallback for browsers without promise-based play
|
||||
try {
|
||||
videoElement.value.play()
|
||||
console.log('✅ Video started playing (fallback)')
|
||||
isPlaying.value = true
|
||||
} catch (err) {
|
||||
console.error('❌ Autoplay failed (fallback):', err)
|
||||
showControls.value = true
|
||||
}
|
||||
}
|
||||
}
|
||||
}, 500)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -186,14 +274,22 @@ function onVideoEnded() {
|
||||
}
|
||||
|
||||
function onVideoError(event) {
|
||||
console.error('Video playback error:', event)
|
||||
console.error('❌ Video playback error:', event)
|
||||
console.error('❌ Video error details:', {
|
||||
error: event.target?.error,
|
||||
networkState: event.target?.networkState,
|
||||
readyState: event.target?.readyState,
|
||||
currentSrc: event.target?.currentSrc
|
||||
})
|
||||
currentVideo.value = null
|
||||
isPlaying.value = false
|
||||
}
|
||||
|
||||
// Initialize fullscreen if configured
|
||||
onMounted(async () => {
|
||||
console.log('🔧 Component mounted, initializing...')
|
||||
if (appConfig.player.autoFullscreen) {
|
||||
console.log('🔧 Auto fullscreen enabled')
|
||||
// Request fullscreen
|
||||
nextTick(() => {
|
||||
document.documentElement.requestFullscreen?.() ||
|
||||
@@ -202,10 +298,14 @@ onMounted(async () => {
|
||||
}
|
||||
|
||||
// Setup Tauri event listeners
|
||||
console.log('🔧 Setting up Tauri listeners...')
|
||||
await setupTauriListeners()
|
||||
|
||||
// Get initial player state
|
||||
console.log('🔧 Getting initial player state...')
|
||||
await updatePlayerState()
|
||||
|
||||
console.log('✅ Component initialization complete')
|
||||
})
|
||||
|
||||
// Setup Tauri event listeners
|
||||
@@ -227,6 +327,7 @@ async function setupTauriListeners() {
|
||||
|
||||
// Listen for player commands from backend
|
||||
await listen('player-command', async (event) => {
|
||||
console.log('📡 Backend player command received:', event.payload)
|
||||
const command = event.payload
|
||||
await handlePlayerCommand(command)
|
||||
})
|
||||
@@ -267,6 +368,7 @@ async function updatePlayerState() {
|
||||
|
||||
// Handle player commands from WebSocket
|
||||
async function handlePlayerCommand(command) {
|
||||
console.log('🎮 Received player command:', command)
|
||||
switch (command.type) {
|
||||
case 'play':
|
||||
if (videoElement.value) {
|
||||
@@ -313,25 +415,27 @@ async function handlePlayerCommand(command) {
|
||||
|
||||
// Load video from file path
|
||||
async function loadVideoFromPath(path) {
|
||||
console.log('📥 loadVideoFromPath called with:', path)
|
||||
try {
|
||||
// Convert file path to URL for video element
|
||||
const videoUrl = `file://${path}`
|
||||
const rawPath = path.startsWith('file://') ? path.slice(7) : path
|
||||
console.log('📥 Processing video path:', { originalPath: path, rawPath })
|
||||
|
||||
// Create video info
|
||||
const title = path.split('/').pop() || path
|
||||
const title = rawPath.split('/').pop() || rawPath
|
||||
currentVideo.value = {
|
||||
path: videoUrl,
|
||||
path: rawPath,
|
||||
title,
|
||||
duration: null,
|
||||
size: null,
|
||||
format: null
|
||||
}
|
||||
console.log('📹 currentVideo.value set to:', currentVideo.value)
|
||||
|
||||
// The videoSrc will be updated automatically via the watcher
|
||||
|
||||
// Update backend state if invoke is available
|
||||
if (invoke) {
|
||||
await invoke('load_video', { path })
|
||||
await invoke('load_video', { path: rawPath })
|
||||
}
|
||||
console.log('📹 Video loaded:', title)
|
||||
console.log('📹 Video loaded successfully:', title)
|
||||
} catch (error) {
|
||||
console.error('❌ Failed to load video:', error)
|
||||
}
|
||||
|
Reference in New Issue
Block a user