diff --git a/ElevenLabs-DotNet-Tests/Test_Fixture_07_DubbingEndpoint.cs b/ElevenLabs-DotNet-Tests/Test_Fixture_07_DubbingEndpoint.cs index 5026b1c..5e36c7a 100644 --- a/ElevenLabs-DotNet-Tests/Test_Fixture_07_DubbingEndpoint.cs +++ b/ElevenLabs-DotNet-Tests/Test_Fixture_07_DubbingEndpoint.cs @@ -24,18 +24,18 @@ public async Task Test_01_Dubbing_File() Watermark = false, }; - (string dubbingId, float expectedDurationSecs) = await ElevenLabsClient.DubbingEndpoint.StartDubbingAsync(request); - Assert.IsFalse(string.IsNullOrEmpty(dubbingId)); - Assert.IsTrue(expectedDurationSecs > 0); - Console.WriteLine($"Expected Duration: {expectedDurationSecs:0.00} seconds"); + DubbingResponse response = await ElevenLabsClient.DubbingEndpoint.StartDubbingAsync(request); + Assert.IsFalse(string.IsNullOrEmpty(response.DubbingId)); + Assert.IsTrue(response.ExpectedDurationSeconds > 0); + Console.WriteLine($"Expected Duration: {response.ExpectedDurationSeconds:0.00} seconds"); - Assert.IsTrue(await ElevenLabsClient.DubbingEndpoint.WaitForDubbingCompletionAsync(dubbingId, progress: new Progress(msg => Console.WriteLine(msg)))); + Assert.IsTrue(await ElevenLabsClient.DubbingEndpoint.WaitForDubbingCompletionAsync(response.DubbingId, progress: new Progress(msg => Console.WriteLine(msg)))); FileInfo srcFile = new(audio.FilePath); FileInfo dubbedPath = new($"{srcFile.FullName}.dubbed.{request.TargetLanguage}{srcFile.Extension}"); { await using FileStream fs = File.Open(dubbedPath.FullName, FileMode.Create); - await foreach (byte[] chunk in ElevenLabsClient.DubbingEndpoint.GetDubbedFileAsync(dubbingId, request.TargetLanguage)) + await foreach (byte[] chunk in ElevenLabsClient.DubbingEndpoint.GetDubbedFileAsync(response.DubbingId, request.TargetLanguage)) { await fs.WriteAsync(chunk); } @@ -45,7 +45,7 @@ public async Task Test_01_Dubbing_File() FileInfo transcriptPath = new($"{srcFile.FullName}.dubbed.{request.TargetLanguage}.srt"); { - string transcriptFile = await ElevenLabsClient.DubbingEndpoint.GetTranscriptForDubAsync(dubbingId, request.TargetLanguage, "srt"); + string transcriptFile = await ElevenLabsClient.DubbingEndpoint.GetTranscriptForDubAsync(response.DubbingId, request.TargetLanguage, "srt"); await File.WriteAllTextAsync(transcriptPath.FullName, transcriptFile); } Assert.IsTrue(transcriptPath.Exists); @@ -67,18 +67,18 @@ public async Task Test_02_Dubbing_Url() Watermark = true, }; - (string dubbingId, float expectedDurationSecs) = await ElevenLabsClient.DubbingEndpoint.StartDubbingAsync(request); - Assert.IsFalse(string.IsNullOrEmpty(dubbingId)); - Assert.IsTrue(expectedDurationSecs > 0); - Console.WriteLine($"Expected Duration: {expectedDurationSecs:0.00} seconds"); + DubbingResponse response = await ElevenLabsClient.DubbingEndpoint.StartDubbingAsync(request); + Assert.IsFalse(string.IsNullOrEmpty(response.DubbingId)); + Assert.IsTrue(response.ExpectedDurationSeconds > 0); + Console.WriteLine($"Expected Duration: {response.ExpectedDurationSeconds:0.00} seconds"); - Assert.IsTrue(await ElevenLabsClient.DubbingEndpoint.WaitForDubbingCompletionAsync(dubbingId, progress: new Progress(msg => Console.WriteLine(msg)))); + Assert.IsTrue(await ElevenLabsClient.DubbingEndpoint.WaitForDubbingCompletionAsync(response.DubbingId, progress: new Progress(msg => Console.WriteLine(msg)))); string assetsDir = Path.GetFullPath("../../../Assets"); FileInfo dubbedPath = new(Path.Combine(assetsDir, $"online.dubbed.{request.TargetLanguage}.mp4")); { await using FileStream fs = File.Open(dubbedPath.FullName, FileMode.Create); - await foreach (byte[] chunk in ElevenLabsClient.DubbingEndpoint.GetDubbedFileAsync(dubbingId, request.TargetLanguage)) + await foreach (byte[] chunk in ElevenLabsClient.DubbingEndpoint.GetDubbedFileAsync(response.DubbingId, request.TargetLanguage)) { await fs.WriteAsync(chunk); } @@ -88,7 +88,7 @@ public async Task Test_02_Dubbing_Url() FileInfo transcriptPath = new(Path.Combine(assetsDir, $"online.dubbed.{request.TargetLanguage}.srt")); { - string transcriptFile = await ElevenLabsClient.DubbingEndpoint.GetTranscriptForDubAsync(dubbingId, request.TargetLanguage, "srt"); + string transcriptFile = await ElevenLabsClient.DubbingEndpoint.GetTranscriptForDubAsync(response.DubbingId, request.TargetLanguage, "srt"); await File.WriteAllTextAsync(transcriptPath.FullName, transcriptFile); } Assert.IsTrue(transcriptPath.Exists); diff --git a/ElevenLabs-DotNet/Dubbing/DubbingEndpoint.cs b/ElevenLabs-DotNet/Dubbing/DubbingEndpoint.cs index 3c0f48f..b7b8a32 100644 --- a/ElevenLabs-DotNet/Dubbing/DubbingEndpoint.cs +++ b/ElevenLabs-DotNet/Dubbing/DubbingEndpoint.cs @@ -42,11 +42,11 @@ public sealed class DubbingEndpoint(ElevenLabsClient client) : ElevenLabsBaseEnd /// in seconds if the operation succeeds. /// /// Thrown when is . - public async Task<(string DubbingId, float ExpectedDurationSecs)> StartDubbingAsync(DubbingRequest request, CancellationToken cancellationToken = default) + public async Task StartDubbingAsync(DubbingRequest request, CancellationToken cancellationToken = default) { ArgumentNullException.ThrowIfNull(request); - using MultipartFormDataContent content = new(); + using MultipartFormDataContent content = []; if (!string.IsNullOrEmpty(request.Mode)) { @@ -126,10 +126,8 @@ public sealed class DubbingEndpoint(ElevenLabsClient client) : ElevenLabsBaseEnd using HttpResponseMessage response = await client.Client.PostAsync(GetUrl(), content, cancellationToken).ConfigureAwait(false); await response.CheckResponseAsync(cancellationToken).ConfigureAwait(false); - using var responseDoc = JsonDocument.Parse(await response.Content.ReadAsStringAsync(cancellationToken).ConfigureAwait(false)); - string dubbingId = responseDoc.RootElement.GetProperty(DubbingId).GetString(); - float expectedDurationSeconds = responseDoc.RootElement.GetProperty(ExpectedDurationSecs).GetSingle(); - return (dubbingId, expectedDurationSeconds); + using Stream responseStream = await response.Content.ReadAsStreamAsync(cancellationToken).ConfigureAwait(false); + return await JsonSerializer.DeserializeAsync(responseStream, cancellationToken: cancellationToken).ConfigureAwait(false); } private static void AppendFileToForm(MultipartFormDataContent content, string name, FileInfo fileInfo, MediaTypeHeaderValue mediaType) @@ -172,7 +170,7 @@ public async Task WaitForDubbingCompletionAsync(string dubbingId, int? max timeoutInterval ??= DefaultTimeoutInterval; for (int i = 0; i < maxRetries; i++) { - DubbingMetadataResponse metadata = await GetDubbingProjectMetadataAsync(dubbingId, cancellationToken).ConfigureAwait(false); + DubbingProjectMetadata metadata = await GetDubbingProjectMetadataAsync(dubbingId, cancellationToken).ConfigureAwait(false); if (metadata.Status.Equals("dubbed", StringComparison.Ordinal)) { return true; @@ -192,14 +190,14 @@ public async Task WaitForDubbingCompletionAsync(string dubbingId, int? max return false; } - private async Task GetDubbingProjectMetadataAsync(string dubbingId, CancellationToken cancellationToken = default) + private async Task GetDubbingProjectMetadataAsync(string dubbingId, CancellationToken cancellationToken = default) { string url = $"{GetUrl()}/{dubbingId}"; HttpResponseMessage response = await client.Client.GetAsync(url, cancellationToken).ConfigureAwait(false); await response.CheckResponseAsync(cancellationToken).ConfigureAwait(false); string responseBody = await response.Content.ReadAsStringAsync(cancellationToken).ConfigureAwait(false); - return JsonSerializer.Deserialize(responseBody) - ?? throw new JsonException("Could not deserialize the response!"); + return JsonSerializer.Deserialize(responseBody) + ?? throw new JsonException("Could not deserialize the dubbing project metadata!"); } /// diff --git a/ElevenLabs-DotNet/Dubbing/DubbingMetadataResponse.cs b/ElevenLabs-DotNet/Dubbing/DubbingProjectMetadata.cs similarity index 91% rename from ElevenLabs-DotNet/Dubbing/DubbingMetadataResponse.cs rename to ElevenLabs-DotNet/Dubbing/DubbingProjectMetadata.cs index 27640f4..ba70bba 100644 --- a/ElevenLabs-DotNet/Dubbing/DubbingMetadataResponse.cs +++ b/ElevenLabs-DotNet/Dubbing/DubbingProjectMetadata.cs @@ -3,7 +3,7 @@ using System.Collections.Generic; using System.Text.Json.Serialization; -public sealed class DubbingMetadataResponse +public sealed class DubbingProjectMetadata { [JsonPropertyName("dubbing_id")] public string DubbingId { get; set; } diff --git a/ElevenLabs-DotNet/Dubbing/DubbingResponse.cs b/ElevenLabs-DotNet/Dubbing/DubbingResponse.cs new file mode 100644 index 0000000..b392460 --- /dev/null +++ b/ElevenLabs-DotNet/Dubbing/DubbingResponse.cs @@ -0,0 +1,12 @@ +namespace ElevenLabs.Dubbing; + +using System.Text.Json.Serialization; + +public sealed class DubbingResponse +{ + [JsonPropertyName("dubbing_id")] + public string DubbingId { get; set; } + + [JsonPropertyName("expected_duration_sec")] + public float ExpectedDurationSeconds { get; set; } +} \ No newline at end of file