diff --git a/ElevenLabs-DotNet-Tests/Test_Fixture_02_VoicesEndpoint.cs b/ElevenLabs-DotNet-Tests/Test_Fixture_02_VoicesEndpoint.cs index af1d3be..c577290 100644 --- a/ElevenLabs-DotNet-Tests/Test_Fixture_02_VoicesEndpoint.cs +++ b/ElevenLabs-DotNet-Tests/Test_Fixture_02_VoicesEndpoint.cs @@ -86,7 +86,43 @@ public async Task Test_05_AddVoice() } [Test] - public async Task Test_06_EditVoice() + public async Task Test_06_AddVoiceFromByteArray() + { + Assert.NotNull(ElevenLabsClient.VoicesEndpoint); + var testLabels = new Dictionary + { + { "accent", "american" } + }; + var clipPath = Path.GetFullPath("../../../Assets/test_sample_01.ogg"); + byte[] clipData = await File.ReadAllBytesAsync(clipPath); + var result = await ElevenLabsClient.VoicesEndpoint.AddVoiceAsync("Test Voice", new[] { clipData }, testLabels); + Assert.NotNull(result); + Console.WriteLine($"{result.Name}"); + Assert.IsNotEmpty(result.Samples); + } + + + [Test] + public async Task Test_07_AddVoiceFromStream() + { + Assert.NotNull(ElevenLabsClient.VoicesEndpoint); + var testLabels = new Dictionary + { + { "accent", "american" } + }; + var clipPath = Path.GetFullPath("../../../Assets/test_sample_01.ogg"); + + using (FileStream fs = File.OpenRead(clipPath)) + { + var result = await ElevenLabsClient.VoicesEndpoint.AddVoiceAsync("Test Voice", new[] { fs }, testLabels); + Assert.NotNull(result); + Console.WriteLine($"{result.Name}"); + Assert.IsNotEmpty(result.Samples); + } + } + + [Test] + public async Task Test_08_EditVoice() { Assert.NotNull(ElevenLabsClient.VoicesEndpoint); var results = await ElevenLabsClient.VoicesEndpoint.GetAllVoicesAsync(); @@ -106,7 +142,7 @@ public async Task Test_06_EditVoice() } [Test] - public async Task Test_07_GetVoiceSample() + public async Task Test_09_GetVoiceSample() { Assert.NotNull(ElevenLabsClient.VoicesEndpoint); var results = await ElevenLabsClient.VoicesEndpoint.GetAllVoicesAsync(); @@ -124,7 +160,7 @@ public async Task Test_07_GetVoiceSample() } [Test] - public async Task Test_08_DeleteVoiceSample() + public async Task Test_10_DeleteVoiceSample() { Assert.NotNull(ElevenLabsClient.VoicesEndpoint); var results = await ElevenLabsClient.VoicesEndpoint.GetAllVoicesAsync(); @@ -143,7 +179,7 @@ public async Task Test_08_DeleteVoiceSample() } [Test] - public async Task Test_09_DeleteVoice() + public async Task Test_11_DeleteVoice() { Assert.NotNull(ElevenLabsClient.VoicesEndpoint); var results = await ElevenLabsClient.VoicesEndpoint.GetAllVoicesAsync(); diff --git a/ElevenLabs-DotNet/Voices/VoicesEndpoint.cs b/ElevenLabs-DotNet/Voices/VoicesEndpoint.cs index cdbeaad..5b8628c 100644 --- a/ElevenLabs-DotNet/Voices/VoicesEndpoint.cs +++ b/ElevenLabs-DotNet/Voices/VoicesEndpoint.cs @@ -197,6 +197,100 @@ public async Task AddVoiceAsync(string name, IEnumerable samplePa form.Add(new StringContent(JsonSerializer.Serialize(labels)), "labels"); } + var response = await client.Client.PostAsync(GetUrl("/add"), form, cancellationToken).ConfigureAwait(false); + var responseAsString = await response.ReadAsStringAsync(EnableDebug, cancellationToken).ConfigureAwait(false); + var voiceResponse = JsonSerializer.Deserialize(responseAsString, ElevenLabsClient.JsonSerializationOptions); + return await GetVoiceAsync(voiceResponse.VoiceId, cancellationToken: cancellationToken).ConfigureAwait(false); + } + + /// + /// Add a new voice to your collection of voices in VoiceLab from a stream + /// + /// Name of the voice you want to add. + /// Collection of samples as an array of bytes to be used for the new voice + /// Optional, labels for the new voice. + /// Optional, . + public async Task AddVoiceAsync(string name, IEnumerable sampleDatums, IReadOnlyDictionary labels = null, CancellationToken cancellationToken = default) + { + var form = new MultipartFormDataContent(); + + if (string.IsNullOrWhiteSpace(name)) + { + throw new ArgumentNullException(nameof(name)); + } + + form.Add(new StringContent(name), "name"); + + if (sampleDatums != null) + { + int fileItr = 0; + foreach (byte[] datum in sampleDatums) + { + try + { + form.Add(new ByteArrayContent(datum), "files", $"file-{fileItr++}"); + } + catch (Exception e) + { + Console.WriteLine(e); + } + } + } + + if (labels != null) + { + form.Add(new StringContent(JsonSerializer.Serialize(labels)), "labels"); + } + + var response = await client.Client.PostAsync(GetUrl("/add"), form, cancellationToken).ConfigureAwait(false); + var responseAsString = await response.ReadAsStringAsync(EnableDebug, cancellationToken).ConfigureAwait(false); + var voiceResponse = JsonSerializer.Deserialize(responseAsString, ElevenLabsClient.JsonSerializationOptions); + return await GetVoiceAsync(voiceResponse.VoiceId, cancellationToken: cancellationToken).ConfigureAwait(false); + } + + /// + /// Add a new voice to your collection of voices in VoiceLab from a stream + /// + /// Name of the voice you want to add. + /// Collection of samples as a stream to be used for the new voice + /// Optional, labels for the new voice. + /// Optional, . + public async Task AddVoiceAsync(string name, IEnumerable sampleStreams, IReadOnlyDictionary labels = null, CancellationToken cancellationToken = default) + { + var form = new MultipartFormDataContent(); + + if (string.IsNullOrWhiteSpace(name)) + { + throw new ArgumentNullException(nameof(name)); + } + + form.Add(new StringContent(name), "name"); + + if (sampleStreams != null) + { + int fileItr = 0; + foreach (Stream voiceStream in sampleStreams) + { + try + { + using (MemoryStream ms = new MemoryStream()) + { + await voiceStream.CopyToAsync(ms, cancellationToken); + form.Add(new ByteArrayContent(ms.ToArray()),"files", $"file-{fileItr++}"); + } + } + catch (Exception e) + { + Console.WriteLine(e); + } + } + } + + if (labels != null) + { + form.Add(new StringContent(JsonSerializer.Serialize(labels)), "labels"); + } + var response = await client.Client.PostAsync(GetUrl("/add"), form, cancellationToken).ConfigureAwait(false); var responseAsString = await response.ReadAsStringAsync(EnableDebug, cancellationToken).ConfigureAwait(false); var voiceResponse = JsonSerializer.Deserialize(responseAsString, ElevenLabsClient.JsonSerializationOptions);