Public Access
97 lines
3.0 KiB
C#
97 lines
3.0 KiB
C#
using NAudio.CoreAudioApi;
|
|
using NAudio.Wave;
|
|
|
|
namespace MeetingAssistant.Recording;
|
|
|
|
public sealed class WindowsMicrophoneDeviceProvider : IMicrophoneDeviceProvider, IMicrophoneCaptureSourceFactory
|
|
{
|
|
private readonly MicrophoneDeviceSelection selection;
|
|
private readonly ILogger<WindowsMicrophoneDeviceProvider> logger;
|
|
|
|
public WindowsMicrophoneDeviceProvider(
|
|
MicrophoneDeviceSelection selection,
|
|
ILogger<WindowsMicrophoneDeviceProvider> logger)
|
|
{
|
|
this.selection = selection;
|
|
this.logger = logger;
|
|
}
|
|
|
|
public IReadOnlyList<MicrophoneDevice> GetAvailableMicrophones()
|
|
{
|
|
try
|
|
{
|
|
using var enumerator = new MMDeviceEnumerator();
|
|
return enumerator
|
|
.EnumerateAudioEndPoints(DataFlow.Capture, DeviceState.Active)
|
|
.Select(ToMicrophoneDevice)
|
|
.OrderBy(device => device.Name, StringComparer.CurrentCultureIgnoreCase)
|
|
.ToArray();
|
|
}
|
|
catch (Exception exception)
|
|
{
|
|
logger.LogWarning(exception, "Could not enumerate microphone capture endpoints");
|
|
return [];
|
|
}
|
|
}
|
|
|
|
public MicrophoneDeviceSnapshot GetMicrophoneSnapshot(MeetingAssistantOptions options)
|
|
{
|
|
var devices = GetAvailableMicrophones();
|
|
return new MicrophoneDeviceSnapshot(
|
|
devices,
|
|
selection.Resolve(options.Recording.MicrophoneDeviceId, GetDefaultMicrophone(), devices));
|
|
}
|
|
|
|
public IMeetingAudioSource CreateCapture(MeetingAssistantOptions options)
|
|
{
|
|
var current = GetMicrophoneSnapshot(options).Current;
|
|
IWaveIn capture;
|
|
if (current is null)
|
|
{
|
|
logger.LogInformation("Starting microphone capture from Windows default capture endpoint");
|
|
capture = new WasapiCapture();
|
|
}
|
|
else
|
|
{
|
|
logger.LogInformation(
|
|
"Starting microphone capture from {MicrophoneName} ({MicrophoneDeviceId})",
|
|
current.Name,
|
|
current.Id);
|
|
using var enumerator = new MMDeviceEnumerator();
|
|
capture = new WasapiCapture(enumerator.GetDevice(current.Id));
|
|
}
|
|
|
|
try
|
|
{
|
|
capture.WaveFormat = new WaveFormat(
|
|
options.Recording.SampleRate,
|
|
16,
|
|
options.Recording.Channels);
|
|
return new NaudioCaptureAudioSource(capture, "microphone", logger);
|
|
}
|
|
catch
|
|
{
|
|
capture.Dispose();
|
|
throw;
|
|
}
|
|
}
|
|
|
|
private static MicrophoneDevice? GetDefaultMicrophone()
|
|
{
|
|
try
|
|
{
|
|
using var enumerator = new MMDeviceEnumerator();
|
|
return ToMicrophoneDevice(enumerator.GetDefaultAudioEndpoint(DataFlow.Capture, Role.Console));
|
|
}
|
|
catch
|
|
{
|
|
return null;
|
|
}
|
|
}
|
|
|
|
private static MicrophoneDevice ToMicrophoneDevice(MMDevice device)
|
|
{
|
|
return new MicrophoneDevice(device.ID, device.FriendlyName);
|
|
}
|
|
}
|