Compare commits

..

1 Commits

Author SHA1 Message Date
Alex b165137f79
Merge 336a75812f into 36f06a064a 2025-11-06 21:55:06 +01:00
2 changed files with 26 additions and 76 deletions

View File

@ -601,20 +601,10 @@ export default function KvmIdRoute() {
} }
}, [peerConnectionState, cleanupAndStopReconnecting]); }, [peerConnectionState, cleanupAndStopReconnecting]);
const microphoneRequestInProgress = useRef(false);
useEffect(() => { useEffect(() => {
if (!audioTransceiver || !peerConnection) return; if (!audioTransceiver || !peerConnection) return;
if (microphoneEnabled) { if (microphoneEnabled) {
if (microphoneRequestInProgress.current) return;
const currentTrack = audioTransceiver.sender.track;
if (currentTrack) {
currentTrack.stop();
}
const requestMicrophone = () => {
microphoneRequestInProgress.current = true;
navigator.mediaDevices?.getUserMedia({ navigator.mediaDevices?.getUserMedia({
audio: { audio: {
echoCancellation: true, echoCancellation: true,
@ -623,36 +613,27 @@ export default function KvmIdRoute() {
channelCount: 2, channelCount: 2,
} }
}).then((stream) => { }).then((stream) => {
microphoneRequestInProgress.current = false;
const audioTrack = stream.getAudioTracks()[0]; const audioTrack = stream.getAudioTracks()[0];
if (audioTrack && audioTransceiver.sender) { if (audioTrack && audioTransceiver.sender) {
const handleTrackEnded = () => {
console.warn('Microphone track ended unexpectedly, attempting to restart...');
if (audioTransceiver.sender.track === audioTrack) {
audioTransceiver.sender.replaceTrack(null);
setTimeout(requestMicrophone, 500);
}
};
audioTrack.addEventListener('ended', handleTrackEnded, { once: true });
audioTransceiver.sender.replaceTrack(audioTrack); audioTransceiver.sender.replaceTrack(audioTrack);
} }
}).catch((err) => { }).catch(() => {
microphoneRequestInProgress.current = false;
console.error('Failed to get microphone:', err);
setMicrophoneEnabled(false); setMicrophoneEnabled(false);
}); });
};
requestMicrophone();
} else { } else {
microphoneRequestInProgress.current = false;
if (audioTransceiver.sender.track) { if (audioTransceiver.sender.track) {
audioTransceiver.sender.track.stop(); audioTransceiver.sender.track.stop();
audioTransceiver.sender.replaceTrack(null); audioTransceiver.sender.replaceTrack(null);
} }
} }
}, [microphoneEnabled, audioTransceiver, peerConnection, setMicrophoneEnabled]); }, [microphoneEnabled, audioTransceiver, peerConnection]);
useEffect(() => {
if (!audioTransceiver || !peerConnection || !audioInputAutoEnable || microphoneEnabled) return;
if (isSecureContext()) {
setMicrophoneEnabled(true);
}
}, [audioInputAutoEnable, audioTransceiver, peerConnection, microphoneEnabled]);
// Cleanup effect // Cleanup effect
const { clearInboundRtpStats, clearCandidatePairStats } = useRTCStore(); const { clearInboundRtpStats, clearCandidatePairStats } = useRTCStore();
@ -825,46 +806,15 @@ export default function KvmIdRoute() {
}); });
}, [rpcDataChannel?.readyState, send, setHdmiState]); }, [rpcDataChannel?.readyState, send, setHdmiState]);
const [audioInputAutoEnableLoaded, setAudioInputAutoEnableLoaded] = useState(false); // Load audio input auto-enable preference from backend
useEffect(() => { useEffect(() => {
if (rpcDataChannel?.readyState !== "open") return; if (rpcDataChannel?.readyState !== "open") return;
send("getAudioInputAutoEnable", {}, (resp: JsonRpcResponse) => { send("getAudioInputAutoEnable", {}, (resp: JsonRpcResponse) => {
if ("error" in resp) return; if ("error" in resp) return;
setAudioInputAutoEnable(resp.result as boolean); setAudioInputAutoEnable(resp.result as boolean);
setAudioInputAutoEnableLoaded(true);
}); });
}, [rpcDataChannel?.readyState, send, setAudioInputAutoEnable]); }, [rpcDataChannel?.readyState, send, setAudioInputAutoEnable]);
const autoEnableAppliedRef = useRef(false);
const audioInputAutoEnableValueRef = useRef(audioInputAutoEnable);
useEffect(() => {
audioInputAutoEnableValueRef.current = audioInputAutoEnable;
}, [audioInputAutoEnable]);
useEffect(() => {
if (!audioTransceiver || !peerConnection || microphoneEnabled) return;
if (!audioInputAutoEnableLoaded || autoEnableAppliedRef.current) return;
if (audioInputAutoEnableValueRef.current && isSecureContext()) {
autoEnableAppliedRef.current = true;
send("setAudioInputEnabled", { enabled: true }, (resp: JsonRpcResponse) => {
if ("error" in resp) {
console.error("Failed to auto-enable audio input:", resp.error);
} else {
setMicrophoneEnabled(true);
}
});
}
}, [audioTransceiver, peerConnection, audioInputAutoEnableLoaded, microphoneEnabled, setMicrophoneEnabled, send]);
useEffect(() => {
if (!peerConnection) {
autoEnableAppliedRef.current = false;
setAudioInputAutoEnableLoaded(false);
}
}, [peerConnection]);
const [needLedState, setNeedLedState] = useState(true); const [needLedState, setNeedLedState] = useState(true);
// request keyboard led state from the device // request keyboard led state from the device

4
web.go
View File

@ -814,7 +814,7 @@ func handleSendWOLMagicPacket(c *gin.Context) {
inputMacAddr := c.Param("mac-addr") inputMacAddr := c.Param("mac-addr")
macAddr, err := net.ParseMAC(inputMacAddr) macAddr, err := net.ParseMAC(inputMacAddr)
if err != nil { if err != nil {
logger.Warn().Err(err).Str("inputMacAddr", inputMacAddr).Msg("Invalid MAC address provided") logger.Warn().Err(err).Str("sendWol", inputMacAddr).Msg("Invalid mac address provided")
c.String(http.StatusBadRequest, "Invalid mac address provided") c.String(http.StatusBadRequest, "Invalid mac address provided")
return return
} }
@ -822,7 +822,7 @@ func handleSendWOLMagicPacket(c *gin.Context) {
macAddrString := macAddr.String() macAddrString := macAddr.String()
err = rpcSendWOLMagicPacket(macAddrString) err = rpcSendWOLMagicPacket(macAddrString)
if err != nil { if err != nil {
logger.Warn().Err(err).Str("macAddrString", macAddrString).Msg("Failed to send WOL magic packet") logger.Warn().Err(err).Str("sendWOL", macAddrString).Msg("Failed to send WOL magic packet")
c.String(http.StatusInternalServerError, "Failed to send WOL to %s: %v", macAddrString, err) c.String(http.StatusInternalServerError, "Failed to send WOL to %s: %v", macAddrString, err)
return return
} }