mirror of https://github.com/jetkvm/kvm.git
refactor(audio): remove unused context from audio input manager
Simplify AudioInputIPCManager by removing unused context and cancellation logic. The context was not providing any meaningful functionality. fix(ui): handle audio device changes with proper sync Add delayed microphone state synchronization when audio devices change to prevent race conditions during USB audio reconfiguration.
This commit is contained in:
parent
6f02870c90
commit
c89d678963
|
@ -1,7 +1,6 @@
|
||||||
package audio
|
package audio
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
|
||||||
"sync/atomic"
|
"sync/atomic"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
@ -16,18 +15,13 @@ type AudioInputIPCManager struct {
|
||||||
supervisor *AudioInputSupervisor
|
supervisor *AudioInputSupervisor
|
||||||
logger zerolog.Logger
|
logger zerolog.Logger
|
||||||
running int32
|
running int32
|
||||||
ctx context.Context
|
|
||||||
cancel context.CancelFunc
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewAudioInputIPCManager creates a new IPC-based audio input manager
|
// NewAudioInputIPCManager creates a new IPC-based audio input manager
|
||||||
func NewAudioInputIPCManager() *AudioInputIPCManager {
|
func NewAudioInputIPCManager() *AudioInputIPCManager {
|
||||||
ctx, cancel := context.WithCancel(context.Background())
|
|
||||||
return &AudioInputIPCManager{
|
return &AudioInputIPCManager{
|
||||||
supervisor: NewAudioInputSupervisor(),
|
supervisor: NewAudioInputSupervisor(),
|
||||||
logger: logging.GetDefaultLogger().With().Str("component", "audio-input-ipc").Logger(),
|
logger: logging.GetDefaultLogger().With().Str("component", "audio-input-ipc").Logger(),
|
||||||
ctx: ctx,
|
|
||||||
cancel: cancel,
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -52,14 +46,8 @@ func (aim *AudioInputIPCManager) Start() error {
|
||||||
FrameSize: 960,
|
FrameSize: 960,
|
||||||
}
|
}
|
||||||
|
|
||||||
// Wait with timeout for subprocess readiness
|
// Wait for subprocess readiness
|
||||||
select {
|
time.Sleep(200 * time.Millisecond)
|
||||||
case <-time.After(200 * time.Millisecond):
|
|
||||||
case <-aim.ctx.Done():
|
|
||||||
aim.supervisor.Stop()
|
|
||||||
atomic.StoreInt32(&aim.running, 0)
|
|
||||||
return aim.ctx.Err()
|
|
||||||
}
|
|
||||||
|
|
||||||
err = aim.supervisor.SendConfig(config)
|
err = aim.supervisor.SendConfig(config)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -77,7 +65,6 @@ func (aim *AudioInputIPCManager) Stop() {
|
||||||
}
|
}
|
||||||
|
|
||||||
aim.logger.Info().Msg("Stopping IPC-based audio input system")
|
aim.logger.Info().Msg("Stopping IPC-based audio input system")
|
||||||
aim.cancel()
|
|
||||||
aim.supervisor.Stop()
|
aim.supervisor.Stop()
|
||||||
aim.logger.Info().Msg("IPC-based audio input system stopped")
|
aim.logger.Info().Msg("IPC-based audio input system stopped")
|
||||||
}
|
}
|
||||||
|
|
|
@ -146,6 +146,8 @@ export default function KvmIdRoute() {
|
||||||
|
|
||||||
// Microphone hook - moved here to prevent unmounting when popover closes
|
// Microphone hook - moved here to prevent unmounting when popover closes
|
||||||
const microphoneHook = useMicrophone();
|
const microphoneHook = useMicrophone();
|
||||||
|
// Extract syncMicrophoneState to avoid dependency issues
|
||||||
|
const { syncMicrophoneState } = microphoneHook;
|
||||||
|
|
||||||
const isLegacySignalingEnabled = useRef(false);
|
const isLegacySignalingEnabled = useRef(false);
|
||||||
|
|
||||||
|
@ -656,8 +658,20 @@ export default function KvmIdRoute() {
|
||||||
const rpcDataChannel = useRTCStore(state => state.rpcDataChannel);
|
const rpcDataChannel = useRTCStore(state => state.rpcDataChannel);
|
||||||
const { send } = useJsonRpc(onJsonRpcRequest);
|
const { send } = useJsonRpc(onJsonRpcRequest);
|
||||||
|
|
||||||
// Use audio events hook without device change handler to avoid subscription loops
|
// Handle audio device changes to sync microphone state
|
||||||
useAudioEvents();
|
const handleAudioDeviceChanged = useCallback((data: { enabled: boolean; reason: string }) => {
|
||||||
|
console.log('[AudioDeviceChanged] Audio device changed:', data);
|
||||||
|
// Sync microphone state when audio device configuration changes
|
||||||
|
// This ensures the microphone state is properly synchronized after USB audio reconfiguration
|
||||||
|
if (syncMicrophoneState) {
|
||||||
|
setTimeout(() => {
|
||||||
|
syncMicrophoneState();
|
||||||
|
}, 500); // Small delay to ensure backend state is settled
|
||||||
|
}
|
||||||
|
}, [syncMicrophoneState]);
|
||||||
|
|
||||||
|
// Use audio events hook with device change handler
|
||||||
|
useAudioEvents(handleAudioDeviceChanged);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (rpcDataChannel?.readyState !== "open") return;
|
if (rpcDataChannel?.readyState !== "open") return;
|
||||||
|
|
Loading…
Reference in New Issue