mirror of https://github.com/jetkvm/kvm.git
100 lines
2.7 KiB
Go
100 lines
2.7 KiB
Go
package audio
|
|
|
|
import (
|
|
"context"
|
|
"os"
|
|
"os/signal"
|
|
"strings"
|
|
"syscall"
|
|
"time"
|
|
|
|
"github.com/jetkvm/kvm/internal/logging"
|
|
"github.com/rs/zerolog"
|
|
)
|
|
|
|
// getEnvInt reads an integer from environment variable with a default value
|
|
|
|
// RunAudioOutputServer runs the audio output server subprocess
|
|
// This should be called from main() when the subprocess is detected
|
|
func RunAudioOutputServer() error {
|
|
logger := logging.GetSubsystemLogger("audio").With().Str("component", "audio-output-server").Logger()
|
|
|
|
// Parse OPUS configuration from environment variables
|
|
bitrate, complexity, vbr, signalType, bandwidth, dtx := parseOpusConfig()
|
|
applyOpusConfig(bitrate, complexity, vbr, signalType, bandwidth, dtx, "audio-output-server", true)
|
|
|
|
// Initialize validation cache for optimal performance
|
|
InitValidationCache()
|
|
|
|
// Create audio server
|
|
server, err := NewAudioOutputServer()
|
|
if err != nil {
|
|
logger.Error().Err(err).Msg("failed to create audio server")
|
|
return err
|
|
}
|
|
defer server.Stop()
|
|
|
|
// Start accepting connections
|
|
if err := server.Start(); err != nil {
|
|
logger.Error().Err(err).Msg("failed to start audio server")
|
|
return err
|
|
}
|
|
|
|
// Initialize audio processing
|
|
err = StartNonBlockingAudioStreaming(func(frame []byte) {
|
|
if err := server.SendFrame(frame); err != nil {
|
|
logger.Warn().Err(err).Msg("failed to send audio frame")
|
|
RecordFrameDropped()
|
|
}
|
|
})
|
|
if err != nil {
|
|
logger.Error().Err(err).Msg("failed to start audio processing")
|
|
return err
|
|
}
|
|
|
|
logger.Info().Msg("audio output server started, waiting for connections")
|
|
|
|
// Update C trace logging based on current audio scope log level (after environment variables are processed)
|
|
loggerTraceEnabled := logger.GetLevel() <= zerolog.TraceLevel
|
|
|
|
// Manual check for audio scope in PION_LOG_TRACE (workaround for logging system bug)
|
|
manualTraceEnabled := false
|
|
pionTrace := os.Getenv("PION_LOG_TRACE")
|
|
if pionTrace != "" {
|
|
scopes := strings.Split(strings.ToLower(pionTrace), ",")
|
|
for _, scope := range scopes {
|
|
if strings.TrimSpace(scope) == "audio" {
|
|
manualTraceEnabled = true
|
|
break
|
|
}
|
|
}
|
|
}
|
|
|
|
// Use manual check as fallback if logging system fails
|
|
traceEnabled := loggerTraceEnabled || manualTraceEnabled
|
|
|
|
CGOSetTraceLogging(traceEnabled)
|
|
|
|
// Set up signal handling for graceful shutdown
|
|
ctx, cancel := context.WithCancel(context.Background())
|
|
defer cancel()
|
|
|
|
sigChan := make(chan os.Signal, 1)
|
|
signal.Notify(sigChan, syscall.SIGINT, syscall.SIGTERM)
|
|
|
|
// Wait for shutdown signal
|
|
select {
|
|
case sig := <-sigChan:
|
|
logger.Info().Str("signal", sig.String()).Msg("received shutdown signal")
|
|
case <-ctx.Done():
|
|
}
|
|
|
|
// Graceful shutdown
|
|
StopNonBlockingAudioStreaming()
|
|
|
|
// Give some time for cleanup
|
|
time.Sleep(Config.DefaultSleepDuration)
|
|
|
|
return nil
|
|
}
|