From f24443e0720481f8c056cf8bc25cde660cf97d93 Mon Sep 17 00:00:00 2001 From: Alex P Date: Mon, 25 Aug 2025 11:05:42 +0000 Subject: [PATCH] Improvement: automatically resume audio when the audio usb gadget is re-enabled from settings --- internal/audio/relay.go | 12 ++++++++++-- main.go | 15 ++++++++++++--- 2 files changed, 22 insertions(+), 5 deletions(-) diff --git a/internal/audio/relay.go b/internal/audio/relay.go index c87f94b..b161413 100644 --- a/internal/audio/relay.go +++ b/internal/audio/relay.go @@ -3,6 +3,7 @@ package audio import ( "context" "fmt" + "reflect" "sync" "time" @@ -168,15 +169,22 @@ func (r *AudioRelay) relayLoop() { // forwardToWebRTC forwards a frame to the WebRTC audio track func (r *AudioRelay) forwardToWebRTC(frame []byte) error { r.mutex.RLock() + defer r.mutex.RUnlock() + audioTrack := r.audioTrack config := r.config muted := r.muted - r.mutex.RUnlock() + // Comprehensive nil check for audioTrack to prevent panic if audioTrack == nil { return nil // No audio track available } + // Check if interface contains nil pointer using reflection + if reflect.ValueOf(audioTrack).IsNil() { + return nil // Audio track interface contains nil pointer + } + // Prepare sample data var sampleData []byte if muted { @@ -186,7 +194,7 @@ func (r *AudioRelay) forwardToWebRTC(frame []byte) error { sampleData = frame } - // Write sample to WebRTC track + // Write sample to WebRTC track while holding the read lock return audioTrack.WriteSample(media.Sample{ Data: sampleData, Duration: config.FrameSize, diff --git a/main.go b/main.go index 56f6917..961f2aa 100644 --- a/main.go +++ b/main.go @@ -11,6 +11,7 @@ import ( "github.com/gwatts/rootcerts" "github.com/jetkvm/kvm/internal/audio" + "github.com/pion/webrtc/v4" ) var ( @@ -46,9 +47,17 @@ func startAudioSubprocess() error { func(pid int) { logger.Info().Int("pid", pid).Msg("audio server process started") - // Start audio relay system for main process without a track initially - // The track will be updated when a WebRTC session is created - if err := audio.StartAudioRelay(nil); err != nil { + // Start audio relay system for main process + // If there's an active WebRTC session, use its audio track + var audioTrack *webrtc.TrackLocalStaticSample + if currentSession != nil && currentSession.AudioTrack != nil { + audioTrack = currentSession.AudioTrack + logger.Info().Msg("restarting audio relay with existing WebRTC audio track") + } else { + logger.Info().Msg("starting audio relay without WebRTC track (will be updated when session is created)") + } + + if err := audio.StartAudioRelay(audioTrack); err != nil { logger.Error().Err(err).Msg("failed to start audio relay") } },