using System.Diagnostics; using Toak.Core; using Toak.IO; namespace Toak.Audio; public static class AudioRecorder { private static readonly string WavPath = Path.Combine(Path.GetTempPath(), "toak_recording.wav"); public static string GetWavPath() => WavPath; public static void StartRecording() { if (File.Exists(WavPath)) { File.Delete(WavPath); } var pInfo = new ProcessStartInfo { FileName = "ffmpeg", Arguments = $"-f alsa -i default -y {WavPath}", UseShellExecute = false, CreateNoWindow = true, RedirectStandardOutput = true, RedirectStandardError = true }; var process = Process.Start(pInfo); if (process != null) { StateTracker.SetRecording(process.Id); Notifications.Notify("Recording Started"); } } public static void StopRecording() { var pid = StateTracker.GetRecordingPid(); if (pid.HasValue) { try { var process = Process.GetProcessById(pid.Value); if (!process.HasExited) { // Send gracefully? Process.Kill on linux sends SIGKILL by default. // But ffmpeg can sometimes handle SIGINT or SIGTERM if we use alternative tools or Process.Kill. // Standard .NET Process.Kill(true) kills the tree. Let's start with basic Kill. process.Kill(); process.WaitForExit(); } } catch (Exception ex) { // Process might already be dead Console.WriteLine($"[AudioRecorder] Error stopping ffmpeg: {ex.Message}"); } finally { StateTracker.ClearRecording(); } } } }