오디오 생성
TanStack AI의 generateAudio() 활동은 텍스트 프롬프트에서 음악, 사운드스케이프 또는 음향 효과와 같은 오디오 콘텐츠를 생성합니다. 음성 합성에 최적화된 Text-to-Speech와는 다릅니다.
개요
오디오 생성은 TanStack AI의 다른 어댑터와 동일한 트리 셰이킹 가능한 아키텍처를 따르는 오디오 어댑터가 처리합니다.
현재 지원되는 항목은 다음과 같습니다.
- Google Gemini: Lyria 3 Pro 및 Lyria 3 Clip 음악 생성
- fal.ai: MiniMax Music, DiffRhythm, Google Lyria 2, Stable Audio 2.5, MMAudio, ElevenLabs 음향 효과, Thinksound 등
기본 사용법
Google Lyria (음악)
Google의 Lyria 모델은 보컬과 악기 연주가 포함된 전체 길이의 곡을 생성합니다. lyria-3-pro-preview는 여러 절로 구성된 작곡을 처리하고, lyria-3-clip-preview는 30초 클립을 생성합니다.
import { generateAudio } from '@tanstack/ai'
import { geminiAudio } from '@tanstack/ai-gemini'
const result = await generateAudio({
adapter: geminiAudio('lyria-3-pro-preview'),
prompt: 'Uplifting indie pop with layered vocals and jangly guitars',
})
console.log(result.audio.b64Json) // Base64-encoded audio bytes (Gemini)
console.log(result.audio.contentType) // e.g. "audio/mpeg"
fal.ai
fal.ai는 하나의 falAudio 어댑터를 통해 다양한 음악, SFX 및 일반 오디오 모델에 액세스할 수 있게 합니다.
음악 생성 (MiniMax Music 2.6)
MiniMax의 최신 음악 모델은 하나의 프롬프트에서 보컬, 반주 음악 및 편곡을 포함한 전체 작곡을 생성합니다.
import { generateAudio } from '@tanstack/ai'
import { falAudio } from '@tanstack/ai-fal'
const result = await generateAudio({
adapter: falAudio('fal-ai/minimax-music/v2.6'),
prompt: 'City Pop, 80s retro, groovy synth bass, warm female vocal, 104 BPM',
})
console.log(result.audio.url) // URL to the generated audio file
console.log(result.audio.contentType) // e.g. "audio/wav"
명시적 가사가 포함된 음악 (DiffRhythm)
import { generateAudio } from '@tanstack/ai'
import { falAudio } from '@tanstack/ai-fal'
const result = await generateAudio({
adapter: falAudio('fal-ai/diffrhythm'),
prompt: 'An upbeat electronic track with synths',
modelOptions: {
lyrics: '[verse]\nHello world\n[chorus]\nLa la la',
},
})
음향 효과
import { generateAudio } from '@tanstack/ai'
import { falAudio } from '@tanstack/ai-fal'
const result = await generateAudio({
adapter: falAudio('fal-ai/elevenlabs/sound-effects/v2'),
prompt: 'Thunderclap followed by heavy rain',
duration: 5,
})
MiniMax Music v2 (lyrics_prompt)
이전 MiniMax 변형은 가사 안내에 lyrics_prompt 필드를 사용합니다.
import { generateAudio } from '@tanstack/ai'
import { falAudio } from '@tanstack/ai-fal'
const result = await generateAudio({
adapter: falAudio('fal-ai/minimax-music/v2'),
prompt: 'A dreamy pop ballad in the style of the 80s',
modelOptions: {
lyrics_prompt: '[instrumental]',
},
})
요청이 예상한 오디오를 반환하지 않는 경우(모델이 조용히 잘라 내거나, 공급자가 프롬프트를 거부하거나, 응답 형태가 이상해 보이는 경우) debug: true를 전달하면 공급자 SDK가 내보내는 모든 청크를 확인할 수 있습니다. Debug Logging을 참조하세요.
옵션
| 옵션 | 타입 | 설명 |
|---|---|---|
adapter | AudioAdapter | falAudio()를 통해 생성된 어댑터(필수) |
prompt | string | 생성할 오디오의 텍스트 설명(필수) |
duration | number | 원하는 지속 시간(초, 모델에 따라 다름) |
modelOptions | object | 공급자별 옵션(모델 ID를 문자열 리터럴로 전달하면 완전히 타입 지정됨) |
debug | DebugOption | 카테고리별 디버그 로깅 활성화(true, false 또는 DebugConfig — Debug Logging 참조) |
클라이언트 훅 (useGenerateAudio)
클라이언트 측 사용을 위해 프레임워크 통합은 동일한 생성 흐름을 래핑하는 useGenerateAudio 훅(Svelte에서는 createGenerateAudio)을 제공합니다. useGenerateSpeech, useGenerateImage 및 다른 미디어 훅의 API를 따릅니다. 전체 형태는 Generation Hooks를 참조하세요.
참고: 긴 트랙의 경우 Generation Persistence를 사용하면 다시 로드하거나 연결이 끊긴 후에도 실행 상태와 결과를 유지하고, 공급자의 URL이 만료된 후에도 오디오를 유지할 수 있습니다.
서버 (스트리밍 SSE 경로)
// routes/api/generate/audio.ts
import { generateAudio, toServerSentEventsResponse } from '@tanstack/ai'
import { falAudio } from '@tanstack/ai-fal'
export async function POST(req: Request) {
const { prompt, duration } = await req.json()
return toServerSentEventsResponse(
generateAudio({
adapter: falAudio('fal-ai/diffrhythm'),
prompt,
duration,
stream: true,
}),
)
}
클라이언트 (React)
import { useGenerateAudio } from '@tanstack/ai-react'
import { fetchServerSentEvents } from '@tanstack/ai-client'
function AudioGenerator() {
const { generate, result, isLoading, error, reset } = useGenerateAudio({
connection: fetchServerSentEvents('/api/generate/audio'),
})
return (
<div>
<button
onClick={() =>
generate({ prompt: 'An upbeat electronic track', duration: 10 })
}
disabled={isLoading}
>
{isLoading ? 'Generating...' : 'Generate'}
</button>
{error && <p>Error: {error.message}</p>}
{result?.audio.url && <audio src={result.audio.url} controls />}
{result && <button onClick={reset}>Clear</button>}
</div>
)
}
TanStack Start 서버 함수를 직접 호출할 때는 connection 대신 fetcher 옵션을 사용합니다.
고급
이 기능을 작동시키는 데 필요하지 않은 참고용 세부 정보입니다.
결과 형태
import type { TokenUsage } from '@tanstack/ai'
interface AudioGenerationResult {
id: string
model: string
audio: {
url?: string
b64Json?: string
contentType?: string
duration?: number
}
// Canonical TokenUsage (same shape as chat), present when the provider
// reports it (e.g. Gemini Lyria via generateContent). Usage-billed providers
// (fal) instead surface `usage.billed` ({ quantity, unit: 'units' }) — the
// real billed quantity read from fal's `x-fal-billable-units` result header.
// Multiply the quantity by the endpoint's unit price (fal pricing API) for
// the exact cost.
usage?: TokenUsage
}
Gemini는 result.audio.b64Json에 Base64로 인코딩된 바이트를 반환합니다. fal 어댑터는 result.audio.url에 URL을 반환합니다. 원시 바이트가 필요하면 다음과 같이 URL을 직접 fetch()하세요.
import { generateAudio } from '@tanstack/ai'
import { falAudio } from '@tanstack/ai-fal'
const result = await generateAudio({
adapter: falAudio('fal-ai/diffrhythm'),
prompt: 'An upbeat electronic track',
})
const bytes = new Uint8Array(
await (await fetch(result.audio.url!)).arrayBuffer()
)
Text-to-Speech와의 차이
generateAudio() | generateSpeech() | |
|---|---|---|
| 목적 | 음악, 사운드스케이프, SFX | 음성 TTS |
| 결과 | result.audio.url 또는 result.audio.b64Json | result.audio의 Base64 |
| 주요 입력 | prompt | text |
| 음성/속도 제어 | 아니요 | 예 (voice, speed) |
말하는 음성을 원하면 generateSpeech()를 사용하고, 음성이 아닌 오디오를 원하면 generateAudio()를 사용합니다.
환경 변수
각 공급자는 기본적으로 환경 변수에서 자체 API 키를 읽습니다.
GOOGLE_API_KEY=your-google-api-key
FAL_KEY=your-fal-api-key
또는 어댑터에 명시적으로 전달할 수 있습니다.
import { createGeminiAudio } from '@tanstack/ai-gemini'
import { falAudio } from '@tanstack/ai-fal'
createGeminiAudio('lyria-3-pro-preview', 'your-key')
falAudio('fal-ai/diffrhythm', { apiKey: 'your-key' })