Skip to content

Commit 3dd77e1

Browse files
com.rest.elevenlabs 3.4.3 (#114)
- Added flash models - Added stream input support to dubbing endpoint - Fixed http/https protocol in client settings --------- Co-authored-by: evya5 <76632693+evya5@users.noreply.github.com>
1 parent d41517c commit 3dd77e1

File tree

9 files changed

+142
-20
lines changed

9 files changed

+142
-20
lines changed

Documentation~/README.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -305,7 +305,7 @@ Gets a list of shared voices in the public voice library.
305305

306306
```csharp
307307
var api = new ElevenLabsClient();
308-
var results = await ElevenLabsClient.SharedVoicesEndpoint.GetSharedVoicesAsync();
308+
var results = await api.SharedVoicesEndpoint.GetSharedVoicesAsync();
309309
foreach (var voice in results.Voices)
310310
{
311311
Debug.Log($"{voice.OwnerId} | {voice.VoiceId} | {voice.Date} | {voice.Name}");
@@ -452,7 +452,7 @@ Returns downloaded dubbed file path.
452452
> Videos will be returned in MP4 format and audio only dubs will be returned in MP3.
453453
454454
```csharp
455-
var dubbedClipPath = await ElevenLabsClient.DubbingEndpoint.GetDubbedFileAsync(metadata.DubbingId, request.TargetLanguage);
455+
var dubbedClipPath = await api.DubbingEndpoint.GetDubbedFileAsync(metadata.DubbingId, request.TargetLanguage);
456456
var dubbedClip = await Rest.DownloadAudioClipAsync($"file://{dubbedClipPath}", AudioType.MPEG);
457457
audioSource.PlayOneShot(dubbedClip);
458458
```
@@ -464,7 +464,7 @@ Returns transcript for the dub in the desired format.
464464
```csharp
465465
var srcFile = new FileInfo(audioPath);
466466
var transcriptPath = new FileInfo($"{srcFile.FullName}.dubbed.{request.TargetLanguage}.srt");
467-
var transcriptFile = await ElevenLabsClient.DubbingEndpoint.GetTranscriptForDubAsync(metadata.DubbingId, request.TargetLanguage);
467+
var transcriptFile = await api.DubbingEndpoint.GetTranscriptForDubAsync(metadata.DubbingId, request.TargetLanguage);
468468
await File.WriteAllTextAsync(transcriptPath.FullName, transcriptFile);
469469
```
470470

Runtime/Authentication/ElevenLabsSettingsInfo.cs

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ namespace ElevenLabs
77
{
88
public sealed class ElevenLabsSettingsInfo : ISettingsInfo
99
{
10+
internal const string Http = "http://";
1011
internal const string Https = "https://";
1112
internal const string ElevenLabsDomain = "api.elevenlabs.io";
1213
internal const string DefaultApiVersion = "v1";
@@ -45,7 +46,20 @@ public ElevenLabsSettingsInfo(string domain, string apiVersion = DefaultApiVersi
4546
apiVersion = DefaultApiVersion;
4647
}
4748

48-
Domain = domain.Contains("http") ? domain : $"{Https}{domain}";
49+
var protocol = Https;
50+
51+
if (domain.StartsWith(Http))
52+
{
53+
protocol = Http;
54+
domain = domain.Replace(Http, string.Empty);
55+
}
56+
else if (domain.StartsWith(Https))
57+
{
58+
protocol = Https;
59+
domain = domain.Replace(Https, string.Empty);
60+
}
61+
62+
Domain = $"{protocol}{domain}";
4963
ApiVersion = apiVersion;
5064
BaseRequest = $"/{ApiVersion}/";
5165
BaseRequestUrlFormat = $"{Domain}{BaseRequest}{{0}}";

Runtime/Dubbing/DubbingEndpoint.cs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -43,11 +43,11 @@ public async Task<DubbingProjectMetadata> DubAsync(DubbingRequest request, int?
4343
{
4444
if (request.Files != null)
4545
{
46-
foreach (var (fileName, mediaType, stream) in request.Files)
46+
foreach (var dub in request.Files)
4747
{
4848
using var audioData = new MemoryStream();
49-
await stream.CopyToAsync(audioData, cancellationToken);
50-
payload.AddBinaryData("file", audioData.ToArray(), fileName, mediaType);
49+
await dub.Stream.CopyToAsync(audioData, cancellationToken);
50+
payload.AddBinaryData("file", audioData.ToArray(), dub.Name, dub.MediaType);
5151
}
5252
}
5353

Runtime/Dubbing/DubbingRequest.cs

Lines changed: 29 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ public DubbingRequest(
3939
bool? dropBackgroundAudio = null,
4040
bool? useProfanityFilter = null,
4141
string projectName = null)
42-
: this(targetLanguage, null, filePaths, sourceLanguage, numberOfSpeakers, watermark, startTime, endTime, highestResolution, dropBackgroundAudio, useProfanityFilter, projectName)
42+
: this(targetLanguage, null, null, filePaths, sourceLanguage, numberOfSpeakers, watermark, startTime, endTime, highestResolution, dropBackgroundAudio, useProfanityFilter, projectName)
4343
{
4444
}
4545

@@ -55,7 +55,7 @@ public DubbingRequest(
5555
bool? dropBackgroundAudio = null,
5656
bool? useProfanityFilter = null,
5757
string projectName = null)
58-
: this(targetLanguage, sourceUrl, null, sourceLanguage, numberOfSpeakers, watermark, startTime, endTime, highestResolution, dropBackgroundAudio, useProfanityFilter, projectName)
58+
: this(targetLanguage, sourceUrl, null, null, sourceLanguage, numberOfSpeakers, watermark, startTime, endTime, highestResolution, dropBackgroundAudio, useProfanityFilter, projectName)
5959
{
6060
}
6161

@@ -104,14 +104,34 @@ public DubbingRequest(
104104
DropBackgroundAudio = dropBackgroundAudio;
105105
UseProfanityFilter = useProfanityFilter;
106106
ProjectName = projectName;
107-
var files = new List<(string, string, Stream)>(clips.Count);
108-
files.AddRange((from audioClip in clips let stream = new MemoryStream(audioClip.EncodeToWav()) select (audioClip.name, "audio/wav", stream)).Select(value => ((string, string, Stream))value));
107+
var files = new List<DubbingStream>(clips.Count);
108+
var streams = from audioClip in clips
109+
let stream = new MemoryStream(audioClip.EncodeToWav())
110+
select (stream, audioClip.name, mediaType: "audio/wav");
111+
files.AddRange(streams.Select(dub => new DubbingStream(dub.stream, dub.name, dub.mediaType)));
109112
Files = files;
110113
}
111114

115+
public DubbingRequest(
116+
List<DubbingStream> files,
117+
string targetLanguage,
118+
string sourceLanguage = null,
119+
int? numberOfSpeakers = null,
120+
bool? watermark = null,
121+
int? startTime = null,
122+
int? endTime = null,
123+
bool? highestResolution = null,
124+
bool? dropBackgroundAudio = null,
125+
bool? useProfanityFilter = null,
126+
string projectName = null)
127+
: this(targetLanguage, null, files, null, sourceLanguage, numberOfSpeakers, watermark, startTime, endTime, highestResolution, dropBackgroundAudio, useProfanityFilter, projectName)
128+
{
129+
}
130+
112131
private DubbingRequest(
113132
string targetLanguage,
114133
Uri sourceUrl = null,
134+
List<DubbingStream> files = null,
115135
IEnumerable<string> filePaths = null,
116136
string sourceLanguage = null,
117137
int? numberOfSpeakers = null,
@@ -135,7 +155,7 @@ private DubbingRequest(
135155
throw new ArgumentException("Either sourceUrl or filePaths must be provided.");
136156
}
137157

138-
var files = new List<(string, string, Stream)>();
158+
files ??= new List<DubbingStream>();
139159

140160
if (filePaths != null)
141161
{
@@ -170,7 +190,7 @@ private DubbingRequest(
170190
".webm" => "video/webm",
171191
_ => "application/octet-stream"
172192
};
173-
files.Add((fileInfo.Name, mediaType, stream));
193+
files.Add(new(stream, fileInfo.Name, mediaType));
174194
}
175195
}
176196

@@ -192,7 +212,7 @@ private DubbingRequest(
192212
/// <summary>
193213
/// Files to dub.
194214
/// </summary>
195-
public IReadOnlyList<(string, string, Stream)> Files { get; }
215+
public IReadOnlyList<DubbingStream> Files { get; }
196216

197217
/// <summary>
198218
/// URL of the source video/audio file.
@@ -261,12 +281,11 @@ private void Dispose(bool disposing)
261281
if (disposing)
262282
{
263283
if (Files == null) { return; }
264-
foreach (var (_, _, stream) in Files)
284+
foreach (var dub in Files)
265285
{
266286
try
267287
{
268-
stream?.Close();
269-
stream?.Dispose();
288+
dub.Dispose();
270289
}
271290
catch (Exception e)
272291
{

Runtime/Dubbing/DubbingStream.cs

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
// Licensed under the MIT License. See LICENSE in the project root for license information.
2+
3+
using System;
4+
using System.IO;
5+
6+
namespace ElevenLabs.Dubbing
7+
{
8+
public sealed class DubbingStream : IDisposable
9+
{
10+
public DubbingStream(Stream stream, string name, string mediaType)
11+
{
12+
Stream = stream ?? throw new ArgumentNullException(nameof(stream));
13+
14+
if (Stream.Length == 0)
15+
{
16+
throw new ArgumentException("Stream cannot be empty.");
17+
}
18+
19+
if (!Stream.CanRead)
20+
{
21+
throw new ArgumentException("Stream must be readable.");
22+
}
23+
24+
Name = name ?? throw new ArgumentNullException(nameof(name));
25+
26+
if (string.IsNullOrWhiteSpace(Name))
27+
{
28+
throw new ArgumentException("Name cannot be empty.");
29+
}
30+
31+
MediaType = mediaType ?? throw new ArgumentNullException(nameof(mediaType));
32+
33+
if (string.IsNullOrWhiteSpace(MediaType))
34+
{
35+
throw new ArgumentException("Media type cannot be empty.");
36+
}
37+
38+
if (MediaType.Contains("/"))
39+
{
40+
var parts = MediaType.Split('/');
41+
42+
if (parts.Length != 2 || string.IsNullOrWhiteSpace(parts[0]) || string.IsNullOrWhiteSpace(parts[1]))
43+
{
44+
throw new ArgumentException("Invalid media type.");
45+
}
46+
}
47+
else
48+
{
49+
throw new ArgumentException("Invalid media type.");
50+
}
51+
}
52+
53+
public Stream Stream { get; }
54+
55+
public string Name { get; }
56+
57+
public string MediaType { get; }
58+
59+
public void Dispose()
60+
{
61+
Stream?.Dispose();
62+
}
63+
}
64+
}

Runtime/Dubbing/DubbingStream.cs.meta

Lines changed: 11 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Runtime/Models/Model.cs

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,20 @@ public Model(
7878

7979
#region Predefined Models
8080

81+
/// <summary>
82+
/// Our latest, ultra-low-latency model, generating speech in under 75ms. Best for developer use cases requiring speed and multiple languages.
83+
/// </summary>
84+
[Preserve]
85+
[JsonIgnore]
86+
public static Model FlashV2 { get; } = new("eleven_flash_v2");
87+
88+
/// <summary>
89+
/// Our latest, ultra-low-latency English only model, generating speech in under 75ms. Best for developer use cases requiring speed.
90+
/// </summary>
91+
[Preserve]
92+
[JsonIgnore]
93+
public static Model FlashV2_5 { get; } = new("eleven_flash_v2_5");
94+
8195
[Preserve]
8296
[JsonIgnore]
8397
[Obsolete("Use EnglishV1")]

Runtime/TextToSpeech/TextToSpeechRequest.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ public sealed class TextToSpeechRequest
2626
/// Optional, <see cref="VoiceSettings"/> that will override the default settings in <see cref="Voice.Settings"/>.
2727
/// </param>
2828
/// <param name="model">
29-
/// Optional, <see cref="Model"/> to use. Defaults to <see cref="Model.TurboV2_5"/>.
29+
/// Optional, <see cref="Model"/> to use. Defaults to <see cref="Model.FlashV2"/>.
3030
/// </param>
3131
/// <param name="outputFormat">
3232
/// Output format of the generated audio.<br/>
@@ -87,7 +87,7 @@ public TextToSpeechRequest(
8787
}
8888

8989
Text = text;
90-
Model = model ?? Models.Model.TurboV2_5;
90+
Model = model ?? Models.Model.FlashV2;
9191
Voice = string.IsNullOrWhiteSpace(voice) ? Voice.Adam : voice;
9292
VoiceSettings = voiceSettings ?? voice.Settings;
9393
OutputFormat = outputFormat;

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
"displayName": "ElevenLabs",
44
"description": "A non-official Eleven Labs voice synthesis RESTful client.",
55
"keywords": [],
6-
"version": "3.4.2",
6+
"version": "3.4.3",
77
"unity": "2021.3",
88
"documentationUrl": "https://github.com/RageAgainstThePixel/com.rest.elevenlabs#documentation",
99
"changelogUrl": "https://github.com/RageAgainstThePixel/com.rest.elevenlabs/releases",

0 commit comments

Comments
 (0)