Page History
...
| Code Block | ||
|---|---|---|
| ||
public async Task<string> GetChatCompletion(string message, List<string> assist)
{
var completionResult = await _client.CompleteChatAsync(new ChatMessage[]
{
ChatMessage.CreateUserMessage(message),
ChatMessage.CreateAssistantMessage(string.Join("\n", assist))
});
string aiResponse = completionResult.Value.Content.FirstOrDefault()?.Text ?? string.Empty;
return aiResponse;
}
/// <summary>
/// voice alloy, ash, ballad, coral, echo, fable, onyx, nova, sage, , shimme
/// </summary>
/// <param name="text"></param>
/// <param name="voice"></param>
/// <returns></returns>
/// <exception cref="InvalidOperationException"></exception>
public async Task<float[]> ConvertTextToVoiceAsync(string text, string voice = "alloy")
{
var requestBody = new
{
model = "gpt-4o-mini-tts", // TTS 모델 이름
input = text, // 변환할 텍스트
voice // 음성 스타일
};
var ttsTask = _httpClient.PostAsJsonAsync("audio/speech", requestBody);
await Task.WhenAll(ttsTask); // 두 작업이 완료될작업을 동시실행하고 , 동시완료될 때까지 기다림
var response = await ttsTask;
if (!response.IsSuccessStatusCode)
{
throw new InvalidOperationException($"TTS API 호출 실패: {response.ReasonPhrase}");
}
// MP3 데이터를 byte 배열로 변환하여 반환
var audioBytes = await response.Content.ReadAsByteArrayAsync();
// MP3 데이터를 PCM 데이터로 변환
return ConvertMp3ToFloatArray(audioBytes);
} |
...
- OpenAPI의 TTS는 mp3로 반환하며~ 순수웹에서 스트리밍 재생하려면 PCM형태의 스트림 데이터 변환이 필요합니다필요하며 서버에서 변환합니다.
웹에서의 재생
| Code Block | ||
|---|---|---|
| ||
async function playAudioBytes(audioBytes, playbackRate, type, dotNetRef) {
try {
if (!audioContext || audioContext.state === 'closed') {
audioContext = new AudioContext();
}
// Float32Array로 변환된 PCM 데이터 사용
const float32Array = new Float32Array(audioBytes);
// AudioBuffer 생성
const audioBuffer = audioContext.createBuffer(1, float32Array.length, audioContext.sampleRate);
audioBuffer.copyToChannel(float32Array, 0);
// 재생
const bufferSource = audioContext.createBufferSource();
bufferSource.buffer = audioBuffer;
bufferSource.playbackRate.value = playbackRate; // 재생 속도 설정
bufferSource.connect(audioContext.destination);
// 재생 완료 이벤트 핸들러 추가
bufferSource.onended = () => {
// 타입에 따라 추가 작업 수행
console.log(`오디오 재생 완료 재생 타입: ${type}`);
if (type === 1) {
console.log("Type 1: 휴먼요청 재생완료~ LLM응답재생 요청");
if (dotNetRef && typeof dotNetRef.invokeMethodAsync === "function") {
dotNetRef.invokeMethodAsync("OnAudioPlaybackCompleted", 1)
.catch(err => console.error("Blazor 메서드 호출 OnAudioPlaybackCompleted 중 오류 발생:", err));
}
} else if (type === 2) {
console.log("Type 2: AI재생완료");
} else if (type === 3) {
console.log("Type 3: 사용자 정의 작업");
}
};
bufferSource.start();
} catch (err) {
console.error("오디오 재생 중 오류 발생:", err);
}
} |
...