openai/openai-dotnet

Public

mirrored from https://github.com/openai/openai-dotnetAvailable

CodeCommitsIssuesPull requestsActionsInsightsSecurity
copilot/sub-pr-1011

Branches

Tags

  • No tags available.
0Branches0Tags
Go to file
Add file
Code

Clone

HTTPS

Download ZIP

src/Custom/Audio/AudioClient.cs

475lines · modecode

1using Microsoft.TypeSpec.Generator.Customizations;
2using System;
3using System.ClientModel;
4using System.ClientModel.Primitives;
5using System.Diagnostics.CodeAnalysis;
6using System.IO;
7using System.Threading;
8using System.Threading.Tasks;
9
10namespace OpenAI.Audio;
11
12// CUSTOM:
13// - Renamed.
14// - Suppressed constructor that takes endpoint parameter; endpoint is now a property in the options class.
15// - Suppressed methods that only take the options parameter.
16/// <summary> The service client for OpenAI audio operations. </summary>
17[CodeGenType("Audio")]
18[CodeGenSuppress("AudioClient", typeof(ClientPipeline), typeof(Uri))]
19[CodeGenSuppress("GenerateSpeechAsync", typeof(SpeechGenerationOptions), typeof(CancellationToken))]
20[CodeGenSuppress("GenerateSpeech", typeof(SpeechGenerationOptions), typeof(CancellationToken))]
21public partial class AudioClient
22{
23 private readonly string _model;
24
25 // CUSTOM: Added as a convenience.
26 /// <summary> Initializes a new instance of <see cref="AudioClient"/>. </summary>
27 /// <param name="model"> The name of the model to use in requests sent to the service. To learn more about the available models, see <see href="https://platform.openai.com/docs/models"/>. </param>
28 /// <param name="apiKey"> The API key to authenticate with the service. </param>
29 /// <exception cref="ArgumentNullException"> <paramref name="model"/> or <paramref name="apiKey"/> is null. </exception>
30 /// <exception cref="ArgumentException"> <paramref name="model"/> is an empty string, and was expected to be non-empty. </exception>
31 public AudioClient(string model, string apiKey) : this(model, new ApiKeyCredential(apiKey), new OpenAIClientOptions())
32 {
33 }
34
35 // CUSTOM:
36 // - Added `model` parameter.
37 // - Used a custom pipeline.
38 // - Demoted the endpoint parameter to be a property in the options class.
39 /// <summary> Initializes a new instance of <see cref="AudioClient"/>. </summary>
40 /// <param name="model"> The name of the model to use in requests sent to the service. To learn more about the available models, see <see href="https://platform.openai.com/docs/models"/>. </param>
41 /// <param name="credential"> The <see cref="ApiKeyCredential"/> to authenticate with the service. </param>
42 /// <exception cref="ArgumentNullException"> <paramref name="model"/> or <paramref name="credential"/> is null. </exception>
43 /// <exception cref="ArgumentException"> <paramref name="model"/> is an empty string, and was expected to be non-empty. </exception>
44 public AudioClient(string model, ApiKeyCredential credential) : this(model, credential, new OpenAIClientOptions())
45 {
46 }
47
48 // CUSTOM:
49 // - Added `model` parameter.
50 // - Used a custom pipeline.
51 // - Demoted the endpoint parameter to be a property in the options class.
52 /// <summary> Initializes a new instance of <see cref="AudioClient"/>. </summary>
53 /// <param name="model"> The name of the model to use in requests sent to the service. To learn more about the available models, see <see href="https://platform.openai.com/docs/models"/>. </param>
54 /// <param name="credential"> The <see cref="ApiKeyCredential"/> to authenticate with the service. </param>
55 /// <param name="options"> The options to configure the client. </param>
56 /// <exception cref="ArgumentNullException"> <paramref name="model"/> or <paramref name="credential"/> is null. </exception>
57 /// <exception cref="ArgumentException"> <paramref name="model"/> is an empty string, and was expected to be non-empty. </exception>
58 public AudioClient(string model, ApiKeyCredential credential, OpenAIClientOptions options) : this(model, OpenAIClient.CreateApiKeyAuthenticationPolicy(credential), options)
59 {
60 }
61
62 // CUSTOM: Added as a convenience.
63 /// <summary> Initializes a new instance of <see cref="AudioClient"/>. </summary>
64 /// <param name="model"> The name of the model to use in requests sent to the service. To learn more about the available models, see <see href="https://platform.openai.com/docs/models"/>. </param>
65 /// <param name="authenticationPolicy"> The authentication policy used to authenticate with the service. </param>
66 /// <exception cref="ArgumentNullException"> <paramref name="model"/> or <paramref name="authenticationPolicy"/> is null. </exception>
67 /// <exception cref="ArgumentException"> <paramref name="model"/> is an empty string, and was expected to be non-empty. </exception>
68 [Experimental("OPENAI001")]
69 public AudioClient(string model, AuthenticationPolicy authenticationPolicy) : this(model, authenticationPolicy, new OpenAIClientOptions())
70 {
71 }
72
73 // CUSTOM: Added as a convenience.
74 /// <summary> Initializes a new instance of <see cref="AudioClient"/>. </summary>
75 /// <param name="model"> The name of the model to use in requests sent to the service. To learn more about the available models, see <see href="https://platform.openai.com/docs/models"/>. </param>
76 /// <param name="authenticationPolicy"> The authentication policy used to authenticate with the service. </param>
77 /// <param name="options"> The options to configure the client. </param>
78 /// <exception cref="ArgumentNullException"> <paramref name="model"/> or <paramref name="authenticationPolicy"/> is null. </exception>
79 /// <exception cref="ArgumentException"> <paramref name="model"/> is an empty string, and was expected to be non-empty. </exception>
80 [Experimental("OPENAI001")]
81 public AudioClient(string model, AuthenticationPolicy authenticationPolicy, OpenAIClientOptions options)
82 {
83 Argument.AssertNotNullOrEmpty(model, nameof(model));
84 Argument.AssertNotNull(authenticationPolicy, nameof(authenticationPolicy));
85 options ??= new OpenAIClientOptions();
86
87 _model = model;
88 Pipeline = OpenAIClient.CreatePipeline(authenticationPolicy, options);
89 _endpoint = OpenAIClient.GetEndpoint(options);
90 }
91
92 // CUSTOM:
93 // - Added `model` parameter.
94 // - Used a custom pipeline.
95 // - Demoted the endpoint parameter to be a property in the options class.
96 // - Made protected.
97 /// <summary> Initializes a new instance of <see cref="AudioClient"/>. </summary>
98 /// <param name="pipeline"> The HTTP pipeline to send and receive REST requests and responses. </param>
99 /// <param name="model"> The name of the model to use in requests sent to the service. To learn more about the available models, see <see href="https://platform.openai.com/docs/models"/>. </param>
100 /// <param name="options"> The options to configure the client. </param>
101 /// <exception cref="ArgumentNullException"> <paramref name="pipeline"/> or <paramref name="model"/> is null. </exception>
102 /// <exception cref="ArgumentException"> <paramref name="model"/> is an empty string, and was expected to be non-empty. </exception>
103 protected internal AudioClient(ClientPipeline pipeline, string model, OpenAIClientOptions options)
104 {
105 Argument.AssertNotNull(pipeline, nameof(pipeline));
106 Argument.AssertNotNullOrEmpty(model, nameof(model));
107 options ??= new OpenAIClientOptions();
108
109 _model = model;
110 Pipeline = pipeline;
111 _endpoint = OpenAIClient.GetEndpoint(options);
112 }
113
114 [Experimental("SCME0002")]
115 public AudioClient(AudioClientSettings settings)
116 : this(settings?.Model, AuthenticationPolicy.Create(settings), settings?.Options)
117 {
118 }
119
120 /// <summary>
121 /// Gets the name of the model used in requests sent to the service.
122 /// </summary>
123 [Experimental("OPENAI001")]
124 public string Model => _model;
125
126 /// <summary>
127 /// Gets the endpoint URI for the service.
128 /// </summary>
129 [Experimental("OPENAI001")]
130 public Uri Endpoint => _endpoint;
131
132 #region GenerateSpeech
133
134 /// <summary> Generates a life-like, spoken audio recording of the input text. </summary>
135 /// <remarks>
136 /// The default format of the generated audio is <see cref="GeneratedSpeechFormat.Mp3"/> unless otherwise specified
137 /// via <see cref="SpeechGenerationOptions.ResponseFormat"/>.
138 /// </remarks>
139 /// <param name="text"> The text to generate audio for. </param>
140 /// <param name="voice"> The voice to use in the generated audio. </param>
141 /// <param name="options"> The options to configure the audio generation. </param>
142 /// <param name="cancellationToken"> A token that can be used to cancel this method call. </param>
143 /// <exception cref="ArgumentNullException"> <paramref name="text"/> is null. </exception>
144 /// <returns> The generated audio in the specified output format. </returns>
145 public virtual async Task<ClientResult<BinaryData>> GenerateSpeechAsync(string text, GeneratedSpeechVoice voice, SpeechGenerationOptions options = null, CancellationToken cancellationToken = default)
146 {
147 Argument.AssertNotNull(text, nameof(text));
148
149 options ??= new();
150 CreateSpeechGenerationOptions(text, voice, ref options);
151
152 using BinaryContent content = options.ToBinaryContent();
153 ClientResult result = await GenerateSpeechAsync(content, cancellationToken.ToRequestOptions()).ConfigureAwait(false);
154 return ClientResult.FromValue(result.GetRawResponse().Content, result.GetRawResponse());
155 }
156
157 /// <summary> Generates a life-like, spoken audio recording of the input text. </summary>
158 /// <remarks>
159 /// The default format of the generated audio is <see cref="GeneratedSpeechFormat.Mp3"/> unless otherwise specified
160 /// via <see cref="SpeechGenerationOptions.ResponseFormat"/>.
161 /// </remarks>
162 /// <param name="text"> The text to generate audio for. </param>
163 /// <param name="voice"> The voice to use in the generated audio. </param>
164 /// <param name="options"> The options to configure the audio generation. </param>
165 /// <param name="cancellationToken"> A token that can be used to cancel this method call. </param>
166 /// <exception cref="ArgumentNullException"> <paramref name="text"/> is null. </exception>
167 /// <returns> The generated audio in the specified output format. </returns>
168 public virtual ClientResult<BinaryData> GenerateSpeech(string text, GeneratedSpeechVoice voice, SpeechGenerationOptions options = null, CancellationToken cancellationToken = default)
169 {
170 Argument.AssertNotNull(text, nameof(text));
171
172 options ??= new();
173 CreateSpeechGenerationOptions(text, voice, ref options);
174
175 using BinaryContent content = options.ToBinaryContent();
176 ClientResult result = GenerateSpeech(content, cancellationToken.ToRequestOptions()); ;
177 return ClientResult.FromValue(result.GetRawResponse().Content, result.GetRawResponse());
178 }
179
180 #endregion
181
182 #region TranscribeAudio
183
184 /// <summary> Transcribes the input audio. </summary>
185 /// <param name="audio"> The audio stream to transcribe. </param>
186 /// <param name="audioFilename">
187 /// The filename associated with the audio stream. The filename's extension (for example: .mp3) will be used to
188 /// validate the format of the input audio. The request may fail if the filename's extension and the actual
189 /// format of the input audio do not match.
190 /// </param>
191 /// <param name="options"> The options to configure the audio transcription. </param>
192 /// <param name="cancellationToken"> A token that can be used to cancel this method call. </param>
193 /// <exception cref="ArgumentNullException"> <paramref name="audio"/> or <paramref name="audioFilename"/> is null. </exception>
194 /// <exception cref="ArgumentException"> <paramref name="audioFilename"/> is an empty string, and was expected to be non-empty. </exception>
195 public virtual async Task<ClientResult<AudioTranscription>> TranscribeAudioAsync(Stream audio, string audioFilename, AudioTranscriptionOptions options = null, CancellationToken cancellationToken = default)
196 {
197 Argument.AssertNotNull(audio, nameof(audio));
198 Argument.AssertNotNullOrEmpty(audioFilename, nameof(audioFilename));
199
200 using MultiPartFormDataBinaryContent content
201 = CreatePerCallTranscriptionOptions(options)
202 .ToMultipartContent(audio, audioFilename);
203
204 ClientResult result = await TranscribeAudioAsync(content, content.ContentType, cancellationToken.ToRequestOptions()).ConfigureAwait(false);
205 return ClientResult.FromValue(AudioTranscription.FromResponse(result.GetRawResponse()), result.GetRawResponse());
206 }
207
208 /// <summary> Transcribes the input audio. </summary>
209 /// <param name="audio"> The audio stream to transcribe. </param>
210 /// <param name="audioFilename">
211 /// The filename associated with the audio stream. The filename's extension (for example: .mp3) will be used to
212 /// validate the format of the input audio. The request may fail if the filename's extension and the actual
213 /// format of the input audio do not match.
214 /// </param>
215 /// <param name="options"> The options to configure the audio transcription. </param>
216 /// <param name="cancellationToken"> A token that can be used to cancel this method call. </param>
217 /// <exception cref="ArgumentNullException"> <paramref name="audio"/> or <paramref name="audioFilename"/> is null. </exception>
218 /// <exception cref="ArgumentException"> <paramref name="audioFilename"/> is an empty string, and was expected to be non-empty. </exception>
219 public virtual ClientResult<AudioTranscription> TranscribeAudio(Stream audio, string audioFilename, AudioTranscriptionOptions options = null, CancellationToken cancellationToken = default)
220 {
221 Argument.AssertNotNull(audio, nameof(audio));
222 Argument.AssertNotNullOrEmpty(audioFilename, nameof(audioFilename));
223
224 using MultiPartFormDataBinaryContent content
225 = CreatePerCallTranscriptionOptions(options)
226 .ToMultipartContent(audio, audioFilename);
227
228 ClientResult result = TranscribeAudio(content, content.ContentType, cancellationToken.ToRequestOptions());
229 return ClientResult.FromValue(AudioTranscription.FromResponse(result.GetRawResponse()), result.GetRawResponse());
230 }
231
232 /// <summary> Transcribes the input audio. </summary>
233 /// <param name="audioFilePath">
234 /// The path of the audio file to transcribe. The provided file path's extension (for example: .mp3) will be
235 /// used to validate the format of the input audio. The request may fail if the file path's extension and the
236 /// actual format of the input audio do not match.
237 /// </param>
238 /// <param name="options"> The options to configure the audio transcription. </param>
239 /// <exception cref="ArgumentNullException"> <paramref name="audioFilePath"/> is null. </exception>
240 /// <exception cref="ArgumentException"> <paramref name="audioFilePath"/> is an empty string, and was expected to be non-empty. </exception>
241 public virtual async Task<ClientResult<AudioTranscription>> TranscribeAudioAsync(string audioFilePath, AudioTranscriptionOptions options = null)
242 {
243 Argument.AssertNotNullOrEmpty(audioFilePath, nameof(audioFilePath));
244
245 using FileStream audioStream = File.OpenRead(audioFilePath);
246 return await TranscribeAudioAsync(audioStream, audioFilePath, options).ConfigureAwait(false);
247 }
248
249 /// <summary> Transcribes the input audio. </summary>
250 /// <param name="audioFilePath">
251 /// The path of the audio file to transcribe. The provided file path's extension (for example: .mp3) will be
252 /// used to validate the format of the input audio. The request may fail if the file path's extension and the
253 /// actual format of the input audio do not match.
254 /// </param>
255 /// <param name="options"> The options to configure the audio transcription. </param>
256 /// <exception cref="ArgumentNullException"> <paramref name="audioFilePath"/> is null. </exception>
257 /// <exception cref="ArgumentException"> <paramref name="audioFilePath"/> is an empty string, and was expected to be non-empty. </exception>
258 public virtual ClientResult<AudioTranscription> TranscribeAudio(string audioFilePath, AudioTranscriptionOptions options = null)
259 {
260 Argument.AssertNotNullOrEmpty(audioFilePath, nameof(audioFilePath));
261
262 using FileStream audioStream = File.OpenRead(audioFilePath);
263 return TranscribeAudio(audioStream, audioFilePath, options);
264 }
265
266 // CUSTOM: Added Experimental attribute.
267 [Experimental("OPENAI001")]
268 public virtual AsyncCollectionResult<StreamingAudioTranscriptionUpdate> TranscribeAudioStreamingAsync(Stream audio, string audioFilename, AudioTranscriptionOptions options = null, CancellationToken cancellationToken = default)
269 {
270 Argument.AssertNotNull(audio, nameof(audio));
271 Argument.AssertNotNullOrEmpty(audioFilename, nameof(audioFilename));
272
273 EnsureModelSupportsStreaming();
274
275 MultiPartFormDataBinaryContent content
276 = CreatePerCallTranscriptionOptions(options, stream: true)
277 .ToMultipartContent(audio, audioFilename);
278
279 return new AsyncSseUpdateCollection<StreamingAudioTranscriptionUpdate>(
280 async () => await TranscribeAudioAsync(content, content.ContentType, cancellationToken.ToRequestOptions(streaming: true)).ConfigureAwait(false),
281 StreamingAudioTranscriptionUpdate.DeserializeStreamingAudioTranscriptionUpdate,
282 cancellationToken);
283 }
284
285 // CUSTOM: Added Experimental attribute.
286 [Experimental("OPENAI001")]
287 public virtual AsyncCollectionResult<StreamingAudioTranscriptionUpdate> TranscribeAudioStreamingAsync(string audioFilePath, AudioTranscriptionOptions options = null, CancellationToken cancellationToken = default)
288 {
289 Argument.AssertNotNullOrEmpty(audioFilePath, nameof(audioFilePath));
290
291 EnsureModelSupportsStreaming();
292
293 FileStream inputStream = File.OpenRead(audioFilePath);
294
295 MultiPartFormDataBinaryContent content
296 = CreatePerCallTranscriptionOptions(options, stream: true)
297 .ToMultipartContent(inputStream, audioFilePath);
298
299 AsyncSseUpdateCollection<StreamingAudioTranscriptionUpdate> result = new(
300 async () => await TranscribeAudioAsync(content, content.ContentType, cancellationToken.ToRequestOptions(streaming: true)).ConfigureAwait(false),
301 StreamingAudioTranscriptionUpdate.DeserializeStreamingAudioTranscriptionUpdate,
302 cancellationToken);
303 result.AdditionalDisposalActions.Add(() => inputStream?.Dispose());
304 return result;
305 }
306
307 // CUSTOM: Added Experimental attribute.
308 [Experimental("OPENAI001")]
309 public virtual CollectionResult<StreamingAudioTranscriptionUpdate> TranscribeAudioStreaming(Stream audio, string audioFilename, AudioTranscriptionOptions options = null, CancellationToken cancellationToken = default)
310 {
311 Argument.AssertNotNull(audio, nameof(audio));
312 Argument.AssertNotNullOrEmpty(audioFilename, nameof(audioFilename));
313
314 EnsureModelSupportsStreaming();
315
316 MultiPartFormDataBinaryContent content
317 = CreatePerCallTranscriptionOptions(options, stream: true)
318 .ToMultipartContent(audio, audioFilename);
319
320 return new SseUpdateCollection<StreamingAudioTranscriptionUpdate>(
321 () => TranscribeAudio(content, content.ContentType, cancellationToken.ToRequestOptions(streaming: true)),
322 StreamingAudioTranscriptionUpdate.DeserializeStreamingAudioTranscriptionUpdate,
323 cancellationToken);
324 }
325
326 // CUSTOM: Added Experimental attribute.
327 [Experimental("OPENAI001")]
328 public virtual CollectionResult<StreamingAudioTranscriptionUpdate> TranscribeAudioStreaming(string audioFilePath, AudioTranscriptionOptions options = null, CancellationToken cancellationToken = default)
329 {
330 Argument.AssertNotNullOrEmpty(audioFilePath, nameof(audioFilePath));
331
332 EnsureModelSupportsStreaming();
333
334 FileStream inputStream = File.OpenRead(audioFilePath);
335
336 MultiPartFormDataBinaryContent content
337 = CreatePerCallTranscriptionOptions(options, stream: true)
338 .ToMultipartContent(inputStream, audioFilePath);
339
340 SseUpdateCollection<StreamingAudioTranscriptionUpdate> result = new(
341 () => TranscribeAudio(content, content.ContentType, cancellationToken.ToRequestOptions(streaming: true)),
342 StreamingAudioTranscriptionUpdate.DeserializeStreamingAudioTranscriptionUpdate,
343 cancellationToken);
344 result.AdditionalDisposalActions.Add(() => inputStream?.Dispose());
345 return result;
346 }
347
348 private void EnsureModelSupportsStreaming()
349 {
350 if (string.Equals(_model, "whisper-1", StringComparison.OrdinalIgnoreCase))
351 {
352 string isEnabled = Environment.GetEnvironmentVariable("OPENAI_ENABLE_WHISPER_1_STREAMING");
353 if (!string.Equals(isEnabled, "true", StringComparison.OrdinalIgnoreCase))
354 {
355 throw new NotSupportedException(
356 "The selected model 'whisper-1' does not support streaming transcription. " +
357 "Please use a compatible model or set the environment variable 'OPENAI_ENABLE_WHISPER_1_STREAMING=true' to bypass this check.");
358 }
359 }
360 }
361
362 #endregion
363
364 #region TranslateAudio
365
366 /// <summary> Translates the input audio into English. </summary>
367 /// <param name="audio"> The audio stream to translate. </param>
368 /// <param name="audioFilename">
369 /// The filename associated with the audio stream. The filename's extension (for example: .mp3) will be used to
370 /// validate the format of the input audio. The request may fail if the filename's extension and the actual
371 /// format of the input audio do not match.
372 /// </param>
373 /// <param name="options"> The options to configure the audio translation. </param>
374 /// <param name="cancellationToken"> A token that can be used to cancel this method call. </param>
375 /// <exception cref="ArgumentNullException"> <paramref name="audio"/> or <paramref name="audioFilename"/> is null. </exception>
376 /// <exception cref="ArgumentException"> <paramref name="audioFilename"/> is an empty string, and was expected to be non-empty. </exception>
377 public virtual async Task<ClientResult<AudioTranslation>> TranslateAudioAsync(Stream audio, string audioFilename, AudioTranslationOptions options = null, CancellationToken cancellationToken = default)
378 {
379 Argument.AssertNotNull(audio, nameof(audio));
380 Argument.AssertNotNullOrEmpty(audioFilename, nameof(audioFilename));
381
382 options ??= new();
383 CreateAudioTranslationOptions(audio, audioFilename, ref options);
384
385 using MultiPartFormDataBinaryContent content = options.ToMultipartContent(audio, audioFilename);
386 ClientResult result = await TranslateAudioAsync(content, content.ContentType, cancellationToken.ToRequestOptions()).ConfigureAwait(false);
387 return ClientResult.FromValue(AudioTranslation.FromResponse(result.GetRawResponse()), result.GetRawResponse());
388 }
389
390 /// <summary> Translates the input audio into English. </summary>
391 /// <param name="audio"> The audio stream to translate. </param>
392 /// <param name="audioFilename">
393 /// The filename associated with the audio stream. The filename's extension (for example: .mp3) will be used to
394 /// validate the format of the input audio. The request may fail if the filename's extension and the actual
395 /// format of the input audio do not match.
396 /// </param>
397 /// <param name="options"> The options to configure the audio translation. </param>
398 /// <param name="cancellationToken"> A token that can be used to cancel this method call. </param>
399 /// <exception cref="ArgumentNullException"> <paramref name="audio"/> or <paramref name="audioFilename"/> is null. </exception>
400 /// <exception cref="ArgumentException"> <paramref name="audioFilename"/> is an empty string, and was expected to be non-empty. </exception>
401 public virtual ClientResult<AudioTranslation> TranslateAudio(Stream audio, string audioFilename, AudioTranslationOptions options = null, CancellationToken cancellationToken = default)
402 {
403 Argument.AssertNotNull(audio, nameof(audio));
404 Argument.AssertNotNullOrEmpty(audioFilename, nameof(audioFilename));
405
406 options ??= new();
407 CreateAudioTranslationOptions(audio, audioFilename, ref options);
408
409 using MultiPartFormDataBinaryContent content = options.ToMultipartContent(audio, audioFilename);
410 ClientResult result = TranslateAudio(content, content.ContentType, cancellationToken.ToRequestOptions());
411 return ClientResult.FromValue(AudioTranslation.FromResponse(result.GetRawResponse()), result.GetRawResponse());
412 }
413
414 /// <summary> Translates the input audio into English. </summary>
415 /// <param name="audioFilePath">
416 /// The path of the audio file to translate. The provided file path's extension (for example: .mp3) will be
417 /// used to validate the format of the input audio. The request may fail if the file path's extension and the
418 /// actual format of the input audio do not match.
419 /// </param>
420 /// <param name="options"> The options to configure the audio translation. </param>
421 /// <exception cref="ArgumentNullException"> <paramref name="audioFilePath"/> was null. </exception>
422 /// <exception cref="ArgumentException"> <paramref name="audioFilePath"/> is an empty string, and was expected to be non-empty. </exception>
423 public virtual ClientResult<AudioTranslation> TranslateAudio(string audioFilePath, AudioTranslationOptions options = null)
424 {
425 Argument.AssertNotNullOrEmpty(audioFilePath, nameof(audioFilePath));
426
427 using FileStream audioStream = File.OpenRead(audioFilePath);
428 return TranslateAudio(audioStream, audioFilePath, options);
429 }
430
431 /// <summary> Translates the input audio into English. </summary>
432 /// <param name="audioFilePath">
433 /// The path of the audio file to translate. The provided file path's extension (for example: .mp3) will be
434 /// used to validate the format of the input audio. The request may fail if the file path's extension and the
435 /// actual format of the input audio do not match.
436 /// </param>
437 /// <param name="options"> The options to configure the audio translation. </param>
438 /// <exception cref="ArgumentNullException"> <paramref name="audioFilePath"/> was null. </exception>
439 /// <exception cref="ArgumentException"> <paramref name="audioFilePath"/> is an empty string, and was expected to be non-empty. </exception>
440 public virtual async Task<ClientResult<AudioTranslation>> TranslateAudioAsync(string audioFilePath, AudioTranslationOptions options = null)
441 {
442 Argument.AssertNotNull(audioFilePath, nameof(audioFilePath));
443
444 using FileStream audioStream = File.OpenRead(audioFilePath);
445 return await TranslateAudioAsync(audioStream, audioFilePath, options);
446 }
447
448 #endregion
449
450 private void CreateSpeechGenerationOptions(string text, GeneratedSpeechVoice voice, ref SpeechGenerationOptions options)
451 {
452 options.Input = text;
453 options.Voice = voice;
454 options.Model = _model;
455 }
456
457 internal virtual AudioTranscriptionOptions CreatePerCallTranscriptionOptions(AudioTranscriptionOptions userOptions, bool stream = false)
458 {
459 AudioTranscriptionOptions copiedOptions = userOptions is null ? new() : userOptions.GetClone();
460
461 copiedOptions.Model = _model;
462
463 if (stream)
464 {
465 copiedOptions.Stream = true;
466 }
467
468 return copiedOptions;
469 }
470
471 private void CreateAudioTranslationOptions(Stream audio, string audioFilename, ref AudioTranslationOptions options)
472 {
473 options.Model = _model;
474 }
475}
476