Skip to content

Commit

Permalink
ElevenLabs-DotNet 1.0.2 (#5)
Browse files Browse the repository at this point in the history
- Added VoiceGenerationEndpoint
- Added unit tests for voice design and instant voice cloning
- Updated docs
  • Loading branch information
StephenHodgson authored Mar 12, 2023
1 parent e875f62 commit 4d4204f
Show file tree
Hide file tree
Showing 10 changed files with 149 additions and 39 deletions.
39 changes: 19 additions & 20 deletions ElevenLabs-DotNet-Tests/Test_Fixture_03_HistoryEndpoint.cs
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,25 @@ public async Task Test_02_GetHistoryAudio()
}

[Test]
public async Task Test_03_DeleteHistoryItem()
public async Task Test_03_DownloadAllHistoryItems()
{
var api = new ElevenLabsClient();
Assert.NotNull(api.HistoryEndpoint);
var historyItems = await api.HistoryEndpoint.GetHistoryAsync();
Assert.NotNull(historyItems);
Assert.IsNotEmpty(historyItems);
var singleItem = historyItems.FirstOrDefault();
var singleItemResult = await api.HistoryEndpoint.DownloadHistoryItemsAsync(new List<string> { singleItem });
Assert.NotNull(singleItemResult);
Assert.IsNotEmpty(singleItemResult);
var downloadItems = historyItems.Select(item => item.Id).ToList();
var results = await api.HistoryEndpoint.DownloadHistoryItemsAsync(downloadItems);
Assert.NotNull(results);
Assert.IsNotEmpty(results);
}

[Test]
public async Task Test_04_DeleteHistoryItem()
{
var api = new ElevenLabsClient();
Assert.NotNull(api.HistoryEndpoint);
Expand All @@ -56,7 +74,6 @@ public async Task Test_03_DeleteHistoryItem()
Assert.IsTrue(result);
var updatedItems = await api.HistoryEndpoint.GetHistoryAsync();
Assert.NotNull(updatedItems);
Assert.IsNotEmpty(updatedItems);
var isDeleted = updatedItems.All(item => item.Id != itemToDelete.Id);
Assert.IsTrue(isDeleted);

Expand All @@ -65,23 +82,5 @@ public async Task Test_03_DeleteHistoryItem()
Console.WriteLine($"{item.State} {item.Date} | {item.Id} | {item.Text}");
}
}

[Test]
public async Task Test_04_DownloadAllHistoryItems()
{
var api = new ElevenLabsClient();
Assert.NotNull(api.HistoryEndpoint);
var historyItems = await api.HistoryEndpoint.GetHistoryAsync();
Assert.NotNull(historyItems);
Assert.IsNotEmpty(historyItems);
var singleItem = historyItems.FirstOrDefault();
var singleItemResult = await api.HistoryEndpoint.DownloadHistoryItemsAsync(new List<string> { singleItem });
Assert.NotNull(singleItemResult);
Assert.IsNotEmpty(singleItemResult);
var downloadItems = historyItems.Select(item => item.Id).ToList();
var results = await api.HistoryEndpoint.DownloadHistoryItemsAsync(downloadItems);
Assert.NotNull(results);
Assert.IsNotEmpty(results);
}
}
}
46 changes: 46 additions & 0 deletions ElevenLabs-DotNet-Tests/Test_Fixture_05_VoiceGeneration.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
// Licensed under the MIT License. See LICENSE in the project root for license information.

using ElevenLabs.VoiceGeneration;
using NUnit.Framework;
using System;
using System.IO;
using System.Linq;
using System.Text.Json;
using System.Threading.Tasks;

namespace ElevenLabs.Voice.Tests
{
internal class Test_Fixture_05_VoiceGeneration
{
[Test]
public async Task Test_01_GetVoiceGenerationOptions()
{
var api = new ElevenLabsClient(ElevenLabsAuthentication.LoadFromEnv());
Assert.NotNull(api.VoiceGenerationEndpoint);
var options = await api.VoiceGenerationEndpoint.GetVoiceGenerationOptionsAsync();
Assert.NotNull(options);
Console.WriteLine(JsonSerializer.Serialize(options));
}

[Test]
public async Task Test_02_GenerateVoice()
{
var api = new ElevenLabsClient(ElevenLabsAuthentication.LoadFromEnv());
Assert.NotNull(api.VoiceGenerationEndpoint);
var options = await api.VoiceGenerationEndpoint.GetVoiceGenerationOptionsAsync();
var generateRequest = new GeneratedVoiceRequest("First we thought the PC was a calculator. Then we found out how to turn numbers into letters and we thought it was a typewriter.", options.Genders.FirstOrDefault(), options.Accents.FirstOrDefault(), options.Ages.FirstOrDefault());
var (generatedVoiceId, audioFilePath) = await api.VoiceGenerationEndpoint.GenerateVoiceAsync(generateRequest);
Console.WriteLine(generatedVoiceId);
Console.WriteLine(audioFilePath);
var createVoiceRequest = new CreateVoiceRequest("Test Voice Lab Create Voice", generatedVoiceId);
File.Delete(audioFilePath);
Assert.NotNull(createVoiceRequest);
var result = await api.VoiceGenerationEndpoint.CreateVoiceAsync(createVoiceRequest);
Assert.NotNull(result);
Console.WriteLine(result.Id);
var deleteResult = await api.VoicesEndpoint.DeleteVoiceAsync(result.Id);
Assert.NotNull(deleteResult);
Assert.IsTrue(deleteResult);
}
}
}
8 changes: 6 additions & 2 deletions ElevenLabs-DotNet/ElevenLabs-DotNet.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,14 @@
<Authors>Stephen Hodgson</Authors>
<Title>ElevenLabs-DotNet</Title>
<Company>RageAgainstThePixel</Company>
<Version>1.0.1</Version>
<Version>1.0.2</Version>
<Copyright>2023</Copyright>
<PackageTags>ElevenLabs, AI, ML, Voice, TTS</PackageTags>
<PackageReleaseNotes>Release 1.0.1
<PackageReleaseNotes>Release 1.0.2
- Added VoiceGenerationEndpoint
- Added unit tests for voice design and instant voice cloning
- Updated docs
Release 1.0.1
- Updated Docs
Release 1.0.0
- Initial Release!</PackageReleaseNotes>
Expand Down
4 changes: 4 additions & 0 deletions ElevenLabs-DotNet/ElevenLabsClient.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
using ElevenLabs.History;
using ElevenLabs.TextToSpeech;
using ElevenLabs.User;
using ElevenLabs.VoiceGeneration;
using ElevenLabs.Voices;
using System.Net.Http;
using System.Security.Authentication;
Expand Down Expand Up @@ -43,6 +44,7 @@ public ElevenLabsClient(ElevenLabsAuthentication elevenLabsAuthentication = null
VoicesEndpoint = new VoicesEndpoint(this);
HistoryEndpoint = new HistoryEndpoint(this);
TextToSpeechEndpoint = new TextToSpeechEndpoint(this);
VoiceGenerationEndpoint = new VoiceGenerationEndpoint(this);
}

/// <summary>
Expand Down Expand Up @@ -87,5 +89,7 @@ public int Version
public HistoryEndpoint HistoryEndpoint { get; }

public TextToSpeechEndpoint TextToSpeechEndpoint { get; }

public VoiceGenerationEndpoint VoiceGenerationEndpoint { get; }
}
}
2 changes: 1 addition & 1 deletion ElevenLabs-DotNet/History/HistoryEndpoint.cs
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,7 @@ public async Task<string> GetHistoryAudioAsync(HistoryItem historyItem, string s
public async Task<bool> DeleteHistoryItemAsync(string historyId, CancellationToken cancellationToken = default)
{
var response = await Api.Client.DeleteAsync($"{GetEndpoint()}/{historyId}", cancellationToken);
await response.ReadAsStringAsync(true);
await response.ReadAsStringAsync();
return response.IsSuccessStatusCode;
}

Expand Down
4 changes: 2 additions & 2 deletions ElevenLabs-DotNet/VoiceGeneration/Age.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,10 @@ public sealed class Age
{
[JsonInclude]
[JsonPropertyName("name")]
public string Name { get; }
public string Name { get; private set; }

[JsonInclude]
[JsonPropertyName("code")]
public string Code { get; }
public string Code { get; private set; }
}
}
10 changes: 8 additions & 2 deletions ElevenLabs-DotNet/VoiceGeneration/CreateVoiceRequest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,18 @@ namespace ElevenLabs.VoiceGeneration
{
public sealed class CreateVoiceRequest
{
public CreateVoiceRequest(string voiceName, string generatedVoiceId = null)
{
VoiceName = voiceName;
GeneratedVoiceId = generatedVoiceId;
}

[JsonInclude]
[JsonPropertyName("voice_name")]
public string VoiceName { get; private set; }
public string VoiceName { get; }

[JsonInclude]
[JsonPropertyName("generated_voice_id")]
public string GeneratedVoiceId { get; private set; }
public string GeneratedVoiceId { get; }
}
}
57 changes: 47 additions & 10 deletions ElevenLabs-DotNet/VoiceGeneration/GeneratedVoiceRequest.cs
Original file line number Diff line number Diff line change
@@ -1,29 +1,66 @@
// Licensed under the MIT License. See LICENSE in the project root for license information.

using System;
using System.Text.Json.Serialization;

namespace ElevenLabs.VoiceGeneration
{
public sealed class GeneratedVoiceRequest
{
[JsonInclude]
/// <summary>
/// Voice Generation Request.
/// Use <see cref="VoiceGenerationEndpoint.GetVoiceGenerationOptionsAsync"/> to get a full list of options.
/// </summary>
/// <param name="text">Sample text to return for voice generation. Must be between 100 and 1000 characters.</param>
/// <param name="gender">The gender of the voice to generate.</param>
/// <param name="accent">The accent of the voice to generate.</param>
/// <param name="age">The age of the voice to generate.</param>
/// <param name="accentStrength">Optional, accept strength, between 0.3 - 2.</param>
public GeneratedVoiceRequest(string text, Gender gender, Accent accent, Age age, double accentStrength = 1)
{
switch (text.Length)
{
case < 100:
throw new ArgumentOutOfRangeException(nameof(text), $"{nameof(text)} must be longer than 100 characters.");
case > 1000:
throw new ArgumentOutOfRangeException(nameof(text), $"{nameof(text)} cannot be longer than 1000 characters.");
default:
if (string.IsNullOrWhiteSpace(text))
{
throw new ArgumentNullException(nameof(text));
}

break;
}

Text = text;
Gender = gender.Code;
Accent = accent.Code;
Age = age.Code;

accentStrength = accentStrength switch
{
< 0.3f => 0.3f,
> 2f => 2f,
_ => accentStrength
};

AccentStrength = accentStrength;
}

[JsonPropertyName("text")]
public string Text { get; private set; }
public string Text { get; }

[JsonInclude]
[JsonPropertyName("gender")]
public string Gender { get; private set; }
public string Gender { get; }

[JsonInclude]
[JsonPropertyName("accent")]
public string Accent { get; private set; }
public string Accent { get; }

[JsonInclude]
[JsonPropertyName("age")]
public string Age { get; private set; }
public string Age { get; }

[JsonInclude]
[JsonPropertyName("accent_strength")]
public int AccentStrength { get; private set; }
public double AccentStrength { get; }
}
}
2 changes: 1 addition & 1 deletion ElevenLabs-DotNet/Voices/VoicesEndpoint.cs
Original file line number Diff line number Diff line change
Expand Up @@ -163,7 +163,7 @@ public async Task<Voice> AddVoiceAsync(string name, IEnumerable<string> samplePa
}

var response = await Api.Client.PostAsync($"{GetEndpoint()}/add", form, cancellationToken);
var responseAsString = await response.ReadAsStringAsync(true);
var responseAsString = await response.ReadAsStringAsync();
var voiceResponse = JsonSerializer.Deserialize<VoiceResponse>(responseAsString, Api.JsonSerializationOptions);
var voice = await GetVoiceAsync(voiceResponse.VoiceId, cancellationToken: cancellationToken);
return voice;
Expand Down
16 changes: 15 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,26 @@
[![NuGet version (ElevenLabs-DotNet)](https://img.shields.io/nuget/v/ElevenLabs-DotNet.svg)](https://www.nuget.org/packages/ElevenLabs-DotNet/)
[![Nuget Publish](https://github.com/RageAgainstThePixel/ElevenLabs-DotNet/actions/workflows/Publish-Nuget.yml/badge.svg)](https://github.com/RageAgainstThePixel/ElevenLabs-DotNet/actions/workflows/Publish-Nuget.yml)

A non-official Eleven Labs voice synthesis RESTful client.
A non-official [Eleven Labs](https://elevenlabs.io/) voice synthesis RESTful client.

I am not affiliated with Eleven Labs and an account with api access is required.

***All copyrights, trademarks, logos, and assets are the property of their respective owners.***

## Getting started

### Install from NuGet

Install package [`ElevenLabs` from Nuget](https://www.nuget.org/packages/ElevenLabs-DotNet/). Here's how via command line:

```powershell
Install-Package ElevenLabs-DotNet
```

> Looking to [use ElevenLabs in the Unity Game Engine](https://github.com/RageAgainstThePixel/com.rest.elevenlabs)? Check out our unity package on OpenUPM:
>
>[![openupm](https://img.shields.io/npm/v/com.rest.elevenlabs?label=openupm&registry_uri=https://package.openupm.com)](https://openupm.com/packages/com.rest.elevenlabs/)
---

## Documentation
Expand Down

0 comments on commit 4d4204f

Please sign in to comment.