From b69acb5e3e34de812c6e9063e23308e72d21ad87 Mon Sep 17 00:00:00 2001 From: shrimbly Date: Wed, 18 Feb 2026 14:09:04 +1300 Subject: [PATCH] fix: extract audio URL from Fal TTS response Fal returns audio in result.audio.url for TTS models, but the media URL extraction chain didn't check for this field. Add audio URL extraction, isAudioModel detection, and audio-specific output handling that returns base64-encoded audio with type "audio". Co-Authored-By: Claude Opus 4.6 --- src/app/api/generate/providers/fal.ts | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/src/app/api/generate/providers/fal.ts b/src/app/api/generate/providers/fal.ts index 112e6c9e..6cb398a9 100644 --- a/src/app/api/generate/providers/fal.ts +++ b/src/app/api/generate/providers/fal.ts @@ -473,6 +473,8 @@ export async function generateWithFalQueue( mediaUrl = result.glb.url; } else if (result.video && result.video.url) { mediaUrl = result.video.url; + } else if (result.audio && result.audio.url) { + mediaUrl = result.audio.url; } else if (result.images && Array.isArray(result.images) && result.images.length > 0) { mediaUrl = result.images[0].url; } else if (result.image && result.image.url) { @@ -508,6 +510,7 @@ export async function generateWithFalQueue( const is3DModel = input.model.capabilities.some(c => c.includes("3d")); const isVideoModel = input.model.capabilities.some(c => c.includes("video")); + const isAudioModel = input.model.capabilities.some(c => c.includes("audio")); // For 3D models, return URL directly (GLB files are binary — don't base64 encode) if (is3DModel) { @@ -524,6 +527,22 @@ export async function generateWithFalQueue( }; } + // For audio models, always base64 encode (audio files are small) + if (isAudioModel) { + const audioContentType = mediaResponse.headers.get("content-type") || "audio/mpeg"; + const audioBuffer = await mediaResponse.arrayBuffer(); + const audioBase64 = Buffer.from(audioBuffer).toString("base64"); + console.log(`[API:${requestId}] SUCCESS - Returning audio`); + return { + success: true, + outputs: [{ + type: "audio", + data: `data:${audioContentType};base64,${audioBase64}`, + url: mediaUrl, + }], + }; + } + const contentType = mediaResponse.headers.get("content-type") || (isVideoModel ? "video/mp4" : "image/png"); const isVideo = contentType.startsWith("video/");