import React, { useState } from 'react' import { Alert, AlertDescription } from '@/components/ui/alert' import { AlertCircle, Upload, Music, Loader2 } from 'lucide-react' interface Voice { id: string name: string createdAt: string } interface SongGenerationProps { voices: Voice[] language: 'english' | 'hindi' onLanguageChange: (lang: 'english' | 'hindi') => void } export const SongGeneration: React.FC = ({ voices, language, onLanguageChange, }) => { const [songFile, setSongFile] = useState(null) const [selectedVoice, setSelectedVoice] = useState(voices[0]?.id || '') const [addEffects, setAddEffects] = useState(true) const [isConverting, setIsConverting] = useState(false) const [progress, setProgress] = useState(0) const [outputAudio, setOutputAudio] = useState(null) const [error, setError] = useState(null) const [successMessage, setSuccessMessage] = useState(null) const handleSongSelect = (e: React.ChangeEvent) => { const file = e.target.files?.[0] if (file) { if (!['audio/mpeg', 'audio/wav', 'audio/mp4', 'audio/flac'].includes(file.type)) { setError('Please select a valid audio file (MP3, WAV, M4A, FLAC)') setSongFile(null) return } setSongFile(file) setError(null) } } const handleConvertSong = async () => { if (!songFile) { setError('Please select a song file') return } if (!selectedVoice) { setError('Please select an enrolled voice') return } setIsConverting(true) setProgress(0) setError(null) setSuccessMessage(null) try { const API_BASE_URL = import.meta.env.VITE_API_URL || 'http://localhost:5000' // Simulate progress const progressInterval = setInterval(() => { setProgress((prev) => Math.min(prev + 10, 90)) }, 2000) const formData = new FormData() formData.append('song', songFile) formData.append('voice_id', selectedVoice) formData.append('language', language) formData.append('add_effects', addEffects ? 'true' : 'false') console.log('Converting song with:', { voice: selectedVoice, language, addEffects, }) const response = await fetch(`${API_BASE_URL}/api/convert_song`, { method: 'POST', body: formData, }) clearInterval(progressInterval) setProgress(100) if (!response.ok) { const errorData = await response.json() throw new Error(errorData.error || `Server error: ${response.status}`) } const result = await response.json() if (result.success) { const audioUrl = `${API_BASE_URL}${result.audio_url}` setOutputAudio(audioUrl) setSuccessMessage('โœ… Song converted successfully! Your voice is now in the song.') setSongFile(null) setProgress(0) } else { throw new Error(result.error || 'Conversion failed') } } catch (err) { console.error('Song conversion error:', err) setError(err instanceof Error ? err.message : 'Failed to convert song') setProgress(0) } finally { setIsConverting(false) } } return (
{/* Language Selector */}
{/* Info Alert */} How it works: Upload a song โ†’ Select your enrolled voice โ†’ Your voice will replace the original singer! (Quality: 6-7/10, Processing time: 6-10 min) {/* Song Upload */}
{songFile && (

โœ“ Song selected: {songFile.name} ({(songFile.size / 1024 / 1024).toFixed(1)}MB)

)}
{/* Voice Selection */}
{voices.length === 0 ? (

No voices enrolled. Please enroll a voice first.

) : ( )}
{/* Effects Toggle */}
setAddEffects(e.target.checked)} disabled={isConverting} className="w-4 h-4 cursor-pointer" />
{/* Error Alert */} {error && ( {error} )} {/* Success Alert */} {successMessage && ( {successMessage} )} {/* Progress Bar */} {isConverting && progress > 0 && (
Converting... {progress}%
)} {/* Convert Button */} {/* Output Audio */} {outputAudio && (

๐ŸŽ‰ Your Song is Ready!

)} {/* Quality Info */}
โš ๏ธ Quality Note: Output is AI-processed (6-7/10 quality). Works best with pop/rock songs. Enable effects for better sound!
) }