mirror of
https://github.com/mofeng-git/One-KVM.git
synced 2026-04-29 17:36:35 +08:00
fix: 修复 MJPEG模式可用但状态显示离线的问题
This commit is contained in:
1
.gitignore
vendored
1
.gitignore
vendored
@@ -42,3 +42,4 @@ CLAUDE.md
|
||||
secrets.toml
|
||||
.env
|
||||
/docs/
|
||||
web/package-lock.json
|
||||
|
||||
@@ -259,6 +259,30 @@ export const useSystemStore = defineStore('system', () => {
|
||||
}
|
||||
}
|
||||
|
||||
async function fetchStreamState() {
|
||||
try {
|
||||
const [status, modeResp] = await Promise.all([
|
||||
streamApi.status(),
|
||||
streamApi.getMode().catch(() => ({ mode: 'mjpeg' }))
|
||||
])
|
||||
stream.value = {
|
||||
online: status.state === 'streaming',
|
||||
active: status.state !== 'uninitialized',
|
||||
device: status.device,
|
||||
format: status.format,
|
||||
resolution: status.resolution,
|
||||
targetFps: status.target_fps,
|
||||
clients: status.clients,
|
||||
streamMode: modeResp.mode || 'mjpeg',
|
||||
error: status.state === 'error' ? 'Stream error' : null,
|
||||
}
|
||||
return status
|
||||
} catch (e) {
|
||||
console.error('Failed to fetch stream state:', e)
|
||||
throw e
|
||||
}
|
||||
}
|
||||
|
||||
async function fetchAllStates() {
|
||||
loading.value = true
|
||||
error.value = null
|
||||
@@ -266,7 +290,8 @@ export const useSystemStore = defineStore('system', () => {
|
||||
try {
|
||||
await Promise.all([
|
||||
fetchSystemInfo(),
|
||||
// HID state is updated via WebSocket device_info event
|
||||
fetchStreamState().catch(() => null),
|
||||
fetchHidState().catch(() => null),
|
||||
fetchAtxState().catch(() => null),
|
||||
fetchMsdState().catch(() => null),
|
||||
])
|
||||
|
||||
@@ -96,6 +96,7 @@ const videoLoading = ref(true)
|
||||
const videoError = ref(false)
|
||||
const videoErrorMessage = ref('')
|
||||
const videoRestarting = ref(false) // Track if video is restarting due to config change
|
||||
const mjpegFrameReceived = ref(false) // Whether MJPEG stream has received at least one frame
|
||||
|
||||
// Video aspect ratio (dynamically updated from actual video dimensions)
|
||||
// Using string format "width/height" to let browser handle the ratio calculation
|
||||
@@ -188,6 +189,11 @@ const videoStatus = computed<'connected' | 'connecting' | 'disconnected' | 'erro
|
||||
if (webrtc.isConnecting.value) return 'connecting'
|
||||
if (webrtc.isConnected.value) return 'connected'
|
||||
}
|
||||
// MJPEG: check if frames have actually arrived (frontend-side detection)
|
||||
// This is more reliable than relying on stream.online from backend,
|
||||
// which can be stale due to the debounce delay in device_info broadcaster.
|
||||
// Also handles browsers that don't fire img.onload for multipart MJPEG streams.
|
||||
if (videoMode.value === 'mjpeg' && mjpegFrameReceived.value) return 'connected'
|
||||
if (systemStore.stream?.online) return 'connected'
|
||||
return 'disconnected'
|
||||
})
|
||||
@@ -680,6 +686,7 @@ function handleVideoLoad() {
|
||||
// MJPEG video frame loaded successfully - update stream online status
|
||||
// This fixes the timing issue where device_info event may arrive before stream is fully active
|
||||
if (videoMode.value === 'mjpeg') {
|
||||
mjpegFrameReceived.value = true
|
||||
systemStore.setStreamOnline(true)
|
||||
// Update aspect ratio from MJPEG image dimensions
|
||||
const img = videoRef.value
|
||||
@@ -758,6 +765,7 @@ function handleVideoError() {
|
||||
|
||||
// Show loading state immediately
|
||||
videoLoading.value = true
|
||||
mjpegFrameReceived.value = false
|
||||
|
||||
// Auto-retry with exponential backoff (infinite retry, capped delay)
|
||||
retryCount++
|
||||
@@ -1062,6 +1070,7 @@ function refreshVideo() {
|
||||
backendFps.value = 0
|
||||
videoError.value = false
|
||||
videoErrorMessage.value = ''
|
||||
mjpegFrameReceived.value = false
|
||||
|
||||
// Update timestamp to force MJPEG reconnection via reactive URL
|
||||
isRefreshingVideo = true
|
||||
@@ -2061,6 +2070,11 @@ async function activateConsoleView() {
|
||||
isConsoleActive.value = true
|
||||
registerInteractionListeners()
|
||||
|
||||
// Ensure HID WebSocket is connected when console becomes active
|
||||
if (!hidWs.connected.value) {
|
||||
hidWs.connect().catch(() => {})
|
||||
}
|
||||
|
||||
if (videoMode.value !== 'mjpeg' && webrtc.videoTrack.value) {
|
||||
await nextTick()
|
||||
await rebindWebRTCVideo()
|
||||
|
||||
Reference in New Issue
Block a user