Spaces:
Running
Running
File size: 3,545 Bytes
163eb99 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 |
import { NextResponse } from 'next/server'
export const dynamic = 'force-dynamic'
export const runtime = 'nodejs'
interface StoryRequest {
title: string
content: string
passkey: string
}
export async function POST(request: Request) {
try {
const body: StoryRequest = await request.json()
const { title, content, passkey } = body
// Verify passkey
if (!passkey) {
return NextResponse.json(
{ error: 'Passkey is required' },
{ status: 401 }
)
}
// Get ElevenLabs API key from environment
const elevenLabsApiKey = process.env.ELEVENLABS_API_KEY
if (!elevenLabsApiKey) {
return NextResponse.json(
{ error: 'ElevenLabs API key not configured. Set ELEVENLABS_API_KEY environment variable.' },
{ status: 500 }
)
}
// Use a default voice ID (you can customize this)
// Popular voices: Rachel (21m00Tcm4TlvDq8ikWAM), Bella (EXAVITQu4vr4xnSDxMaL)
const voiceId = 'EXAVITQu4vr4xnSDxMaL' // Bella voice
console.log('Generating story audio with ElevenLabs:', { title, contentLength: content.length })
// Limit content length for reasonable audio duration
const limitedContent = content.substring(0, 2000)
// Call ElevenLabs Text-to-Speech API
const response = await fetch(`https://api.elevenlabs.io/v1/text-to-speech/${voiceId}`, {
method: 'POST',
headers: {
'xi-api-key': elevenLabsApiKey,
'Content-Type': 'application/json',
},
body: JSON.stringify({
text: limitedContent,
model_id: 'eleven_multilingual_v2',
voice_settings: {
stability: 0.5,
similarity_boost: 0.75,
style: 0.5,
use_speaker_boost: true,
},
}),
})
if (!response.ok) {
const errorText = await response.text()
console.error('ElevenLabs API error:', {
status: response.status,
statusText: response.statusText,
error: errorText
})
return NextResponse.json(
{ error: `ElevenLabs API error: ${response.status} ${response.statusText}` },
{ status: response.status }
)
}
// Get the audio data as buffer
const audioBuffer = await response.arrayBuffer()
// Convert to base64 for data URL
const audioBase64 = Buffer.from(audioBuffer).toString('base64')
const audioDataUrl = `data:audio/mpeg;base64,${audioBase64}`
// Create voice content entry
const voiceContent = {
id: `story-${Date.now()}`,
type: 'story',
title,
storyContent: content,
audioUrl: audioDataUrl,
timestamp: Date.now(),
isProcessing: false,
}
return NextResponse.json({
success: true,
content: voiceContent,
message: 'Story audio generated successfully! Open Voice Studio app to listen.',
})
} catch (error) {
console.error('Error generating story audio:', error)
return NextResponse.json(
{ error: error instanceof Error ? error.message : 'Failed to generate story audio' },
{ status: 500 }
)
}
}
|