feat: 增加设备丢失自恢复机制

增加音频设备丢失自恢复机制,完善视频设备丢失自恢复机制

降级部分日志级别,GOSTC key打印脱敏

代码格式化
This commit is contained in:
mofeng-git
2026-05-02 10:54:31 +08:00
parent 52754c862b
commit 12a3f1c947
16 changed files with 929 additions and 60 deletions

View File

@@ -16,6 +16,31 @@ export function useAudioPlayer() {
let decoder: any = null
let nextPlayTime = 0
let isConnecting = false // Prevent concurrent connection attempts
let reconnectTimer: number | null = null
let shouldReconnect = false
function clearReconnectTimer() {
if (reconnectTimer !== null) {
clearTimeout(reconnectTimer)
reconnectTimer = null
}
}
function scheduleReconnect() {
if (!shouldReconnect || volume.value <= 0 || reconnectTimer !== null) {
return
}
reconnectTimer = window.setTimeout(() => {
reconnectTimer = null
if (!shouldReconnect || volume.value <= 0) {
return
}
connect().catch(() => {
scheduleReconnect()
})
}, 1000)
}
async function initDecoder() {
const opusDecoder = new OpusDecoder({
@@ -34,6 +59,8 @@ export function useAudioPlayer() {
}
async function connect() {
shouldReconnect = true
// Prevent concurrent connection attempts (critical fix for multiple WS connections)
if (isConnecting) {
return
@@ -52,6 +79,7 @@ export function useAudioPlayer() {
}
isConnecting = true
clearReconnectTimer()
try {
if (!decoder) await initDecoder()
@@ -72,6 +100,7 @@ export function useAudioPlayer() {
connected.value = true
playing.value = true
error.value = null
clearReconnectTimer()
nextPlayTime = audioContext!.currentTime
}
@@ -83,8 +112,10 @@ export function useAudioPlayer() {
ws.onclose = () => {
isConnecting = false
ws = null
connected.value = false
playing.value = false
scheduleReconnect()
}
ws.onerror = () => {
@@ -94,10 +125,13 @@ export function useAudioPlayer() {
} catch (e) {
isConnecting = false
error.value = e instanceof Error ? e.message : 'Failed to initialize audio'
scheduleReconnect()
}
}
function disconnect() {
shouldReconnect = false
clearReconnectTimer()
if (ws) {
ws.close()
ws = null
@@ -172,6 +206,11 @@ export function useAudioPlayer() {
function setVolume(v: number) {
volume.value = Math.max(0, Math.min(1, v))
updateVolume()
if (volume.value <= 0) {
clearReconnectTimer()
} else if (shouldReconnect && !connected.value && !isConnecting) {
scheduleReconnect()
}
}
watch(volume, updateVolume)