initial commit

This commit is contained in:
2026-03-22 02:25:16 +01:00
commit eb72820ce9
42 changed files with 2506 additions and 0 deletions
+12
View File
@@ -0,0 +1,12 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net10.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<PublishAot>true</PublishAot>
<InvariantGlobalization>true</InvariantGlobalization>
<SelfContained>true</SelfContained>
</PropertyGroup>
</Project>
+41
View File
@@ -0,0 +1,41 @@
using System.Diagnostics;
namespace Hush.Audio;
public class FfmpegAudioRecorder : IAudioRecorder
{
private Process? _process;
public bool IsRecording => _process != null && !_process.HasExited;
public Task StartRecording(string path)
{
if (IsRecording)
throw new InvalidOperationException("Recording is already in progress");
_process = new Process
{
StartInfo = new ProcessStartInfo
{
FileName = "ffmpeg",
Arguments = $"-f pulse -i default -ac 1 -ar 16000 -f wav \"{path}\" -y",
UseShellExecute = false,
CreateNoWindow = true
}
};
_process.Start();
return Task.CompletedTask;
}
public async Task StopRecording()
{
if (_process == null || _process.HasExited)
return;
_process.Kill();
await _process.WaitForExitAsync();
_process.Dispose();
_process = null;
}
}
+8
View File
@@ -0,0 +1,8 @@
namespace Hush.Audio;
public interface IAudioRecorder
{
Task StartRecording(string path);
Task StopRecording();
bool IsRecording { get; }
}
+49
View File
@@ -0,0 +1,49 @@
using System.Diagnostics;
namespace Hush.Audio;
public class PipewireAudioRecorder : IAudioRecorder
{
private Process? _process;
private string? _currentPath;
public bool IsRecording => _process != null && !_process.HasExited;
public Task StartRecording(string path)
{
if (IsRecording)
throw new InvalidOperationException("Recording is already in progress");
_currentPath = path;
_process = new Process
{
StartInfo = new ProcessStartInfo
{
FileName = "pw-record",
Arguments = $"\"{_currentPath}\" --rate=16000 --channels=1",
UseShellExecute = false,
RedirectStandardOutput = true,
RedirectStandardError = true,
CreateNoWindow = true
}
};
_process.Start();
return Task.CompletedTask;
}
public async Task StopRecording()
{
if (!IsRecording || _process == null)
return;
_process.Kill();
await _process.WaitForExitAsync();
_process.Dispose();
_process = null;
_currentPath = null;
}
}