Untitled
unknown
csharp
a month ago
6.3 kB
3
Indexable
Never
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); } } }
Leave a Comment