From 8637b6182927372551c1658eb97dc19514ba6279 Mon Sep 17 00:00:00 2001 From: Ed Sparkes <1023491+ed-sparkes@users.noreply.github.com> Date: Wed, 15 Nov 2023 22:04:59 +0000 Subject: [PATCH] ElevenLabs-DotNet 2.0.3 (#30) - Fixed text to speech streaming --------- Co-authored-by: Stephen Hodgson Co-authored-by: Stephen Hodgson --- .../Test_Fixture_03_TextToSpeechEndpoint.cs | 30 +++++++++++++++++-- ElevenLabs-DotNet/ElevenLabs-DotNet.csproj | 6 ++-- .../TextToSpeech/TextToSpeechEndpoint.cs | 8 ++++- 3 files changed, 38 insertions(+), 6 deletions(-) diff --git a/ElevenLabs-DotNet-Tests/Test_Fixture_03_TextToSpeechEndpoint.cs b/ElevenLabs-DotNet-Tests/Test_Fixture_03_TextToSpeechEndpoint.cs index a134ee0..83d8ca4 100644 --- a/ElevenLabs-DotNet-Tests/Test_Fixture_03_TextToSpeechEndpoint.cs +++ b/ElevenLabs-DotNet-Tests/Test_Fixture_03_TextToSpeechEndpoint.cs @@ -2,6 +2,7 @@ using NUnit.Framework; using System; +using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; @@ -16,9 +17,32 @@ public async Task Test_01_TextToSpeech() var voice = (await ElevenLabsClient.VoicesEndpoint.GetAllVoicesAsync()).FirstOrDefault(); Assert.NotNull(voice); var defaultVoiceSettings = await ElevenLabsClient.VoicesEndpoint.GetDefaultVoiceSettingsAsync(); - var clipPath = await ElevenLabsClient.TextToSpeechEndpoint.TextToSpeechAsync("The quick brown fox jumps over the lazy dog.", voice, defaultVoiceSettings); - Assert.NotNull(clipPath); - Console.WriteLine(clipPath); + var voiceClip = await ElevenLabsClient.TextToSpeechEndpoint.TextToSpeechAsync("The quick brown fox jumps over the lazy dog.", voice, defaultVoiceSettings); + Assert.NotNull(voiceClip); + Console.WriteLine(voiceClip.Id); + } + + [Test] + public async Task Test_02_StreamTextToSpeech() + { + Assert.NotNull(ElevenLabsClient.TextToSpeechEndpoint); + var voice = (await ElevenLabsClient.VoicesEndpoint.GetAllVoicesAsync()).FirstOrDefault(); + Assert.NotNull(voice); + var partialClips = new Queue(); + var defaultVoiceSettings = await ElevenLabsClient.VoicesEndpoint.GetDefaultVoiceSettingsAsync(); + var voiceClip = await ElevenLabsClient.TextToSpeechEndpoint.TextToSpeechAsync("The quick brown fox jumps over the lazy dog.", voice, defaultVoiceSettings, + + partialClipCallback: async partialClip => + { + Assert.IsNotNull(partialClip); + partialClips.Enqueue(partialClip); + await Task.CompletedTask; + }); + + Assert.NotNull(partialClips); + Assert.IsNotEmpty(partialClips); + Assert.NotNull(voiceClip); + Console.WriteLine(voiceClip.Id); } } } \ No newline at end of file diff --git a/ElevenLabs-DotNet/ElevenLabs-DotNet.csproj b/ElevenLabs-DotNet/ElevenLabs-DotNet.csproj index d6f8bd4..bcb1106 100644 --- a/ElevenLabs-DotNet/ElevenLabs-DotNet.csproj +++ b/ElevenLabs-DotNet/ElevenLabs-DotNet.csproj @@ -14,8 +14,10 @@ RageAgainstThePixel 2023 ElevenLabs, AI, ML, Voice, TTS - 2.0.2 - Version 2.0.2 + 2.0.3 + Version 2.0.3 +- Fixed text to speech streaming +Version 2.0.2 - Added the u-law format Version 2.0.1 - Pass some cancellation tokens to internals diff --git a/ElevenLabs-DotNet/TextToSpeech/TextToSpeechEndpoint.cs b/ElevenLabs-DotNet/TextToSpeech/TextToSpeechEndpoint.cs index 5f248cf..df9845e 100644 --- a/ElevenLabs-DotNet/TextToSpeech/TextToSpeechEndpoint.cs +++ b/ElevenLabs-DotNet/TextToSpeech/TextToSpeechEndpoint.cs @@ -7,6 +7,7 @@ using System.Collections.Generic; using System.IO; using System.Linq; +using System.Net.Http; using System.Text.Json; using System.Threading; using System.Threading.Tasks; @@ -87,7 +88,12 @@ public async Task TextToSpeechAsync(string text, Voice voice, VoiceSe parameters.Add(OptimizeStreamingLatencyParameter, optimizeStreamingLatency.ToString()); } - var response = await Api.Client.PostAsync(GetUrl($"/{voice.Id}{(partialClipCallback == null ? string.Empty : "/stream")}", parameters), payload, cancellationToken).ConfigureAwait(false); + using var postRequest = new HttpRequestMessage(HttpMethod.Post, GetUrl($"/{voice.Id}{(partialClipCallback == null ? string.Empty : "/stream")}", parameters)); + postRequest.Content = payload; + var requestOption = partialClipCallback == null + ? HttpCompletionOption.ResponseContentRead + : HttpCompletionOption.ResponseHeadersRead; + var response = await Api.Client.SendAsync(postRequest, requestOption, cancellationToken); await response.CheckResponseAsync(cancellationToken).ConfigureAwait(false); var clipId = response.Headers.GetValues(HistoryItemId).FirstOrDefault();