using MeetingAssistant.Transcription; using NAudio.Wave; namespace MeetingAssistant.Speakers; public sealed class WavSpeakerSnippetExtractor : ISpeakerSnippetExtractor { public Task ExtractSnippetAsync( string audioPath, IReadOnlyList speakerSegments, CancellationToken cancellationToken) { if (speakerSegments.Count == 0 || !File.Exists(audioPath)) { return Task.FromResult([]); } var start = speakerSegments.Min(segment => segment.Start); var end = speakerSegments.Max(segment => segment.End); if (end <= start) { return Task.FromResult([]); } using var reader = new WaveFileReader(audioPath); using var output = new MemoryStream(); using (var writer = new WaveFileWriter(output, reader.WaveFormat)) { reader.CurrentTime = start; var bytesRemaining = reader.WaveFormat.AverageBytesPerSecond * (end - start).TotalSeconds; var buffer = new byte[reader.WaveFormat.AverageBytesPerSecond]; while (bytesRemaining > 0) { cancellationToken.ThrowIfCancellationRequested(); var bytesToRead = (int)Math.Min(buffer.Length, bytesRemaining); var bytesRead = reader.Read(buffer, 0, bytesToRead); if (bytesRead == 0) { break; } writer.Write(buffer, 0, bytesRead); bytesRemaining -= bytesRead; } } return Task.FromResult(output.ToArray()); } }