Make meeting lifecycle stateful

This commit is contained in:
2026-05-27 12:55:17 +02:00
parent d607b957bb
commit e85274829a
91 changed files with 4076 additions and 479 deletions
@@ -12,20 +12,18 @@ public sealed class AsrDiagnosticService
this.pipelineFactory = pipelineFactory;
}
public async Task<AsrDiagnosticResult> TranscribeWavAsync(string path, CancellationToken cancellationToken)
public Task<AsrDiagnosticResult> TranscribeWavAsync(string path, CancellationToken cancellationToken)
{
if (string.IsNullOrWhiteSpace(path))
{
throw new ArgumentException("A WAV file path is required.", nameof(path));
}
return TranscribeWavAsync(path, launchProfileName: null, cancellationToken);
}
var fullPath = Path.GetFullPath(Environment.ExpandEnvironmentVariables(path));
if (!File.Exists(fullPath))
{
throw new FileNotFoundException($"WAV file was not found at '{fullPath}'.", fullPath);
}
await using var pipeline = pipelineFactory.Create();
public async Task<AsrDiagnosticResult> TranscribeWavAsync(
string path,
string? launchProfileName,
CancellationToken cancellationToken)
{
var fullPath = ResolveExistingWavPath(path);
await using var pipeline = pipelineFactory.Create(launchProfileName);
await pipeline.InitializeAsync(cancellationToken);
var liveTranscriptTask = CollectLiveTranscriptAsync(pipeline, cancellationToken);
await WriteWavToPipelineAsync(fullPath, pipeline, paceAudio: true, cancellationToken);
@@ -39,7 +37,17 @@ public sealed class AsrDiagnosticService
CancellationToken cancellationToken)
{
var fullPath = ResolveExistingWavPath(path);
await using var pipeline = pipelineFactory.Create();
return await DiarizeWavAsync(fullPath, options, launchProfileName: null, cancellationToken);
}
public async Task<AsrDiagnosticResult> DiarizeWavAsync(
string path,
SpeechRecognitionPipelineOptions options,
string? launchProfileName,
CancellationToken cancellationToken)
{
var fullPath = ResolveExistingWavPath(path);
await using var pipeline = pipelineFactory.Create(launchProfileName);
await pipeline.InitializeAsync(cancellationToken);
var liveTranscriptTask = CollectLiveTranscriptAsync(pipeline, cancellationToken);
await WriteWavToPipelineAsync(fullPath, pipeline, paceAudio: true, cancellationToken);
@@ -99,7 +107,9 @@ public sealed class AsrDiagnosticService
string path,
[System.Runtime.CompilerServices.EnumeratorCancellation] CancellationToken cancellationToken = default)
{
using var reader = new WaveFileReader(path);
var reader = new WaveFileReader(path);
try
{
var format = reader.WaveFormat;
if (format.Encoding != WaveFormatEncoding.Pcm || format.BitsPerSample != 16)
{
@@ -113,6 +123,18 @@ public sealed class AsrDiagnosticService
{
yield return new AudioChunk(buffer[..read], format.SampleRate, format.Channels);
}
}
finally
{
try
{
reader.Dispose();
}
catch (NotSupportedException)
{
// NAudio can throw while disposing reader streams from async iterators; diagnostics should not fail after reading all chunks.
}
}
}
}