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 }
        )
    }
}