fix: play Opus TTS audio directly instead of WAV-converting it
The backend sends Opus-encoded audio from OpenAI TTS (tts-1 with response_format=opus). The frontend was treating it as raw PCM16 and wrapping it in a WAV container, which corrupted the audio into static. Now plays the Opus data directly as audio/ogg.
This commit is contained in:
@@ -151,28 +151,14 @@ export function useConversation() {
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case 'audio': {
|
case 'audio': {
|
||||||
// Incoming PCM16 audio from Kira
|
// Incoming Opus audio from TTS (full response, not streamed)
|
||||||
if (msg.data && audioRef.current) {
|
if (msg.data && audioRef.current) {
|
||||||
// Accumulate audio chunks and create a blob
|
|
||||||
const binary = atob(msg.data);
|
const binary = atob(msg.data);
|
||||||
const bytes = new Uint8Array(binary.length);
|
const bytes = new Uint8Array(binary.length);
|
||||||
for (let i = 0; i < binary.length; i++) {
|
for (let i = 0; i < binary.length; i++) {
|
||||||
bytes[i] = binary.charCodeAt(i);
|
bytes[i] = binary.charCodeAt(i);
|
||||||
}
|
}
|
||||||
audioBufferRef.current.push(bytes);
|
const blob = new Blob([bytes], { type: 'audio/ogg' });
|
||||||
|
|
||||||
// Convert accumulated PCM16 to WAV blob for playback
|
|
||||||
const allChunks = audioBufferRef.current;
|
|
||||||
const totalLen = allChunks.reduce((s, c) => s + c.length, 0);
|
|
||||||
const combined = new Uint8Array(totalLen);
|
|
||||||
let offset = 0;
|
|
||||||
for (const chunk of allChunks) {
|
|
||||||
combined.set(chunk, offset);
|
|
||||||
offset += chunk.length;
|
|
||||||
}
|
|
||||||
|
|
||||||
const wav = pcm16ToWav(combined);
|
|
||||||
const blob = new Blob([wav], { type: 'audio/wav' });
|
|
||||||
const url = URL.createObjectURL(blob);
|
const url = URL.createObjectURL(blob);
|
||||||
audioRef.current.src = url;
|
audioRef.current.src = url;
|
||||||
audioRef.current.play().catch(() => {});
|
audioRef.current.play().catch(() => {});
|
||||||
|
|||||||
Reference in New Issue
Block a user