fix: 完善 RK3588 HDMI RX 信号检测与自动恢复

- 统一使用 QUERY_DV_TIMINGS 判断 HDMI RX 输入状态
  - 增加 source-following 设备状态 API 与前端只读展示
  - 支持长时间无信号后的 MJPEG/WebRTC 自动恢复
  - 修复模式切换时采集设备尚未释放导致的 EBUSY
  - 取消陈旧 WebRTC 重连并统一采集恢复策略
  - 移除视频输入状态区域的冗余标题
This commit is contained in:
mofeng-git
2026-07-30 19:41:44 +08:00
parent 971c263bf8
commit 9fb23476ac
36 changed files with 1883 additions and 1492 deletions

View File

@@ -374,11 +374,12 @@ export const webrtcApi = {
createSession: () =>
request<{ session_id: string }>('/webrtc/session', { method: 'POST' }),
offer: (sdp: string) =>
offer: (sdp: string, signal?: AbortSignal) =>
request<{ sdp: string; session_id: string; ice_candidates: IceCandidate[] }>('/webrtc/offer', {
method: 'POST',
body: JSON.stringify({ sdp }),
}),
signal,
}, { toastOnError: false }),
addIceCandidate: (sessionId: string, candidate: IceCandidate) =>
request<{ success: boolean }>('/webrtc/ice', {
@@ -742,6 +743,56 @@ interface SerialDeviceOption {
name: string
}
export type VideoControlMode = 'configurable' | 'source_following'
export type VideoInputState = 'locked' | 'no_signal' | 'unavailable'
export interface VideoInputStatus {
state: VideoInputState
format: string | null
width: number | null
height: number | null
fps: number | null
}
export interface VideoResolution {
width: number
height: number
fps: number[]
}
export interface VideoFormat {
format: string
description: string
resolutions: VideoResolution[]
}
export interface VideoDevice {
path: string
name: string
driver: string
formats: VideoFormat[]
usb_bus: string | null
has_signal: boolean
control_mode: VideoControlMode
input_status: VideoInputStatus
}
export interface DeviceList {
video: VideoDevice[]
serial: Array<{ path: string; name: string }>
audio: Array<{
name: string
description: string
is_hdmi: boolean
usb_bus: string | null
}>
udc: Array<{ name: string }>
extensions: {
ttyd_available: boolean
rustdesk_available: boolean
}
}
function encodeDrivePath(path: string): string {
if (path === '' || path === '/') {
return '/'
@@ -774,42 +825,20 @@ function sortSerialDevices(serialDevices: SerialDeviceOption[]): SerialDeviceOpt
export const configApi = {
listDevices: async () => {
const result = await request<{
video: Array<{
path: string
name: string
driver: string
formats: Array<{
format: string
description: string
resolutions: Array<{
width: number
height: number
fps: number[]
}>
}>
usb_bus: string | null
has_signal: boolean
}>
serial: Array<{ path: string; name: string }>
audio: Array<{
name: string
description: string
is_hdmi: boolean
usb_bus: string | null
}>
udc: Array<{ name: string }>
extensions: {
ttyd_available: boolean
rustdesk_available: boolean
}
}>('/devices')
const result = await request<DeviceList>('/devices')
return {
...result,
serial: sortSerialDevices(result.serial),
}
},
getVideoInputStatus: (device: string) =>
request<VideoInputStatus>(
`/video/input-status?device=${encodeURIComponent(device)}`,
{},
{ toastOnError: false },
),
}
export {