Public Access
Add meeting assistant speech and summary automation
This commit is contained in:
@@ -26,10 +26,11 @@ public sealed class FunAsrStreamingTranscriptionProvider : IStreamingTranscripti
|
||||
|
||||
public async IAsyncEnumerable<TranscriptionSegment> TranscribeAsync(
|
||||
IAsyncEnumerable<AudioChunk> audio,
|
||||
SpeechRecognitionPipelineOptions options,
|
||||
[System.Runtime.CompilerServices.EnumeratorCancellation] CancellationToken cancellationToken)
|
||||
{
|
||||
var segments = Channel.CreateUnbounded<TranscriptionSegment>();
|
||||
var session = Task.Run(() => RunSessionAsync(audio, segments.Writer, cancellationToken), CancellationToken.None);
|
||||
var session = Task.Run(() => RunSessionAsync(audio, options, segments.Writer, cancellationToken), CancellationToken.None);
|
||||
|
||||
await foreach (var segment in segments.Reader.ReadAllAsync(cancellationToken))
|
||||
{
|
||||
@@ -41,6 +42,7 @@ public sealed class FunAsrStreamingTranscriptionProvider : IStreamingTranscripti
|
||||
|
||||
private async Task RunSessionAsync(
|
||||
IAsyncEnumerable<AudioChunk> audio,
|
||||
SpeechRecognitionPipelineOptions pipelineOptions,
|
||||
ChannelWriter<TranscriptionSegment> segments,
|
||||
CancellationToken cancellationToken)
|
||||
{
|
||||
@@ -61,7 +63,7 @@ public sealed class FunAsrStreamingTranscriptionProvider : IStreamingTranscripti
|
||||
var finalReceived = new TaskCompletionSource(TaskCreationOptions.RunContinuationsAsynchronously);
|
||||
var receiveTask = ReceiveAsync(connection, parser, segments, finalReceived, cancellationToken);
|
||||
|
||||
await SendStartAsync(connection, firstChunk, cancellationToken);
|
||||
await SendStartAsync(connection, firstChunk, pipelineOptions.DictationWords, cancellationToken);
|
||||
await connection.SendBinaryAsync(firstChunk.Pcm, cancellationToken);
|
||||
|
||||
while (await enumerator.MoveNextAsync())
|
||||
@@ -139,6 +141,7 @@ public sealed class FunAsrStreamingTranscriptionProvider : IStreamingTranscripti
|
||||
private async Task SendStartAsync(
|
||||
IFunAsrWebSocketConnection connection,
|
||||
AudioChunk firstChunk,
|
||||
IReadOnlyList<string>? dictationWords,
|
||||
CancellationToken cancellationToken)
|
||||
{
|
||||
var message = new Dictionary<string, object?>
|
||||
@@ -152,24 +155,17 @@ public sealed class FunAsrStreamingTranscriptionProvider : IStreamingTranscripti
|
||||
["wav_name"] = options.FunAsr.WavName,
|
||||
["wav_format"] = "pcm",
|
||||
["is_speaking"] = true,
|
||||
["hotwords"] = await LoadHotwordsAsync(cancellationToken),
|
||||
["hotwords"] = BuildHotwords(dictationWords),
|
||||
["itn"] = options.FunAsr.Itn
|
||||
};
|
||||
|
||||
await connection.SendTextAsync(JsonSerializer.Serialize(message), cancellationToken);
|
||||
}
|
||||
|
||||
private async Task<string> LoadHotwordsAsync(CancellationToken cancellationToken)
|
||||
internal static string BuildHotwords(IReadOnlyList<string>? dictationWords)
|
||||
{
|
||||
var path = VaultPath.Resolve(options.Vault.DictationWordsPath);
|
||||
if (!File.Exists(path))
|
||||
{
|
||||
return "";
|
||||
}
|
||||
|
||||
var words = await File.ReadAllLinesAsync(path, cancellationToken);
|
||||
var hotwords = words
|
||||
.Select(line => line.Trim().TrimStart('-', '*').Trim())
|
||||
var hotwords = (dictationWords ?? [])
|
||||
.Select(word => word.Trim())
|
||||
.Where(line => !string.IsNullOrWhiteSpace(line))
|
||||
.Distinct(StringComparer.OrdinalIgnoreCase)
|
||||
.ToDictionary(word => word, _ => 20);
|
||||
|
||||
Reference in New Issue
Block a user