Untitled
unknown
csharp
a year ago
6.3 kB
11
Indexable
using System.Net.WebSockets;
using System.Text.Json;
using Apex.BFF.Application.Common.Interfaces;
using Apex.BFF.Infrastructure.Services.AzureAiTranslation;
using Microsoft.CognitiveServices.Speech;
using Microsoft.CognitiveServices.Speech.Audio;
using Microsoft.CognitiveServices.Speech.Translation;
using Microsoft.Extensions.Options;
namespace Apex.BFF.Infrastructure.Services.AITranslationService
{
public class TranslationService(IOptions<TranslationServiceSettings> settings) : ITranslationService
{
private readonly TranslationServiceSettings _serviceSettings = settings.Value;
public async Task HandleWebSocketAsync(WebSocket webSocket)
{
try
{
var v2EndpointInString =
$"wss://{_serviceSettings.Region}.stt.speech.microsoft.com/speech/universal/v2";
var v2EndpointUrl = new Uri(v2EndpointInString);
var config = SpeechTranslationConfig.FromEndpoint(v2EndpointUrl, _serviceSettings.ApiKey);
var autoDetectSourceLanguageConfig = AutoDetectSourceLanguageConfig.FromLanguages(["en-US", "es-ES"]);
config.AddTargetLanguage("es");
config.AddTargetLanguage("en");
using var pushStream = AudioInputStream.CreatePushStream();
using var audioInput = AudioConfig.FromStreamInput(pushStream);
using var recognizer = new TranslationRecognizer(config, autoDetectSourceLanguageConfig, audioInput);
recognizer.SessionStarted += (s, e) => Console.WriteLine("Session started");
recognizer.Recognizing += (s, e) => Console.WriteLine("Recognizing started");
recognizer.Recognized += async (s, e) =>
{
Console.WriteLine($"Recognized result: Reason={e.Result.Reason}");
var lidResult =
e.Result.Properties.GetProperty(PropertyId
.SpeechServiceConnection_AutoDetectSourceLanguageResult);
if (e.Result.Reason == ResultReason.TranslatedSpeech)
{
await HandleTranslationsAsync(lidResult.Substring(0, 2), e.Result.Translations,
e.Result.Text, webSocket);
}
else
{
Console.WriteLine("No translation was produced.");
}
};
recognizer.Canceled += (s, e) =>
{
Console.WriteLine($"Recognition canceled: {e.Reason}");
if (e.Reason == CancellationReason.Error)
{
Console.WriteLine($"Error details: {e.ErrorDetails}");
}
};
recognizer.SessionStopped += (s, e) => Console.WriteLine("Session stopped");
await recognizer.StartContinuousRecognitionAsync().ConfigureAwait(false);
var buffer = new byte[1024 * 4];
WebSocketReceiveResult result;
while (webSocket.State == WebSocketState.Open)
{
result = await webSocket.ReceiveAsync(new ArraySegment<byte>(buffer), CancellationToken.None)
.ConfigureAwait(false);
if (result.MessageType == WebSocketMessageType.Close)
{
break;
}
if (result.Count > 0)
{
pushStream.Write(buffer, result.Count);
}
}
// Signal that no more audio will be sent
pushStream.Close();
await recognizer.StopContinuousRecognitionAsync().ConfigureAwait(false);
if (webSocket.State == WebSocketState.Open)
{
await webSocket
.CloseAsync(WebSocketCloseStatus.NormalClosure, string.Empty, CancellationToken.None)
.ConfigureAwait(false);
}
}
catch (Exception ex)
{
Console.WriteLine($"WebSocket receive error: {ex.Message}");
throw;
}
}
private async Task<byte[]> SynthesizeAudioAsync(string text)
{
var config = SpeechConfig.FromSubscription(_serviceSettings.ApiKey, _serviceSettings.Region);
using (var pullAudioStream = new PullAudioOutputStream())
using (var audioConfig = AudioConfig.FromStreamOutput(pullAudioStream))
using (var synthesizer = new SpeechSynthesizer(config, audioConfig))
{
var result = await synthesizer.SpeakTextAsync(text);
if (result.Reason == ResultReason.SynthesizingAudioCompleted)
{
return result.AudioData;
}
else
{
throw new Exception($"Speech synthesis failed: {result.Reason}");
}
}
}
private async Task HandleTranslationsAsync(string? sourceLanguage,
IReadOnlyDictionary<string, string> translations, string originalText, WebSocket webSocket)
{
var tasks = translations.Select(async element =>
{
if (element.Key != sourceLanguage)
{
var translatedAudio = await SynthesizeAudioAsync(element.Value);
var message = new
{
TranslateLanguage = element.Key,
TranslatedText = element.Value,
TranslatedAudio = translatedAudio,
Originaltext = originalText
};
var messageBytes = JsonSerializer.SerializeToUtf8Bytes(message);
await webSocket.SendAsync(new ArraySegment<byte>(messageBytes), WebSocketMessageType.Text, true,
CancellationToken.None);
}
});
await Task.WhenAll(tasks);
}
}
}Editor is loading...
Leave a Comment