import React, { useState, useRef, useEffect } from 'react'; interface CustomVoiceProps { onStart: (src: File, ref: File) => void; isLoading: boolean; } const CustomVoice: React.FC = ({ onStart, isLoading }) => { const [srcFile, setSrcFile] = useState(null); const [refFile, setRefFile] = useState(null); // Audio Playback State const [playingType, setPlayingType] = useState<'src' | 'ref' | null>(null); const audioRef = useRef(null); const srcInputRef = useRef(null); const refInputRef = useRef(null); // Cleanup audio on unmount useEffect(() => { return () => { if (audioRef.current) { audioRef.current.pause(); audioRef.current = null; } }; }, []); const handleFileChange = (e: React.ChangeEvent, type: 'src' | 'ref') => { if (e.target.files && e.target.files[0]) { // Stop playing if currently playing the file being changed if (playingType === type && audioRef.current) { audioRef.current.pause(); setPlayingType(null); } if (type === 'src') setSrcFile(e.target.files[0]); else setRefFile(e.target.files[0]); } }; const togglePreview = (e: React.MouseEvent, type: 'src' | 'ref') => { e.stopPropagation(); // Prevent opening file dialog const file = type === 'src' ? srcFile : refFile; if (!file) return; // If clicking the currently playing type, stop it if (playingType === type) { if (audioRef.current) { audioRef.current.pause(); audioRef.current = null; } setPlayingType(null); return; } // Stop any other audio if (audioRef.current) { audioRef.current.pause(); } // Create new audio const url = URL.createObjectURL(file); const audio = new Audio(url); audioRef.current = audio; audio.onended = () => { setPlayingType(null); URL.revokeObjectURL(url); }; audio.onerror = () => { alert("خطا در پخش فایل"); setPlayingType(null); }; audio.play(); setPlayingType(type); }; const handleSubmit = (e: React.FormEvent) => { e.preventDefault(); if (srcFile && refFile) { if (audioRef.current) { audioRef.current.pause(); setPlayingType(null); } onStart(srcFile, refFile); } }; return (

استودیو ساخت صدای اختصاصی

با داشتن یک نمونه صدا هر صدایی رو به همون صدا تبدیل کنید

برای شبیه‌سازی دقیق، صدای خود و صدای هدف را با کیفیت بالا بارگذاری کنید.

{/* Source File */}
srcInputRef.current?.click()} className={`relative overflow-hidden rounded-3xl border-2 border-dashed p-6 transition-all duration-300 active:scale-95 cursor-pointer ${srcFile ? 'border-primary bg-blue-50/50' : 'border-gray-200 bg-white hover:bg-gray-50'}`} > handleFileChange(e, 'src')} />
صدای ورودی (ویس شما)

{srcFile ? srcFile.name : 'برای انتخاب ضربه بزنید'}

{srcFile && }
{/* Reference File */}
refInputRef.current?.click()} className={`relative overflow-hidden rounded-3xl border-2 border-dashed p-6 transition-all duration-300 active:scale-95 cursor-pointer ${refFile ? 'border-secondary bg-purple-50/50' : 'border-gray-200 bg-white hover:bg-gray-50'}`} > handleFileChange(e, 'ref')} />
صدای الگو (رفرنس)

{refFile ? refFile.name : 'برای انتخاب ضربه بزنید'}

{refFile && }
{/* Enhanced Tips Section - Amber Style (Right Aligned per Screenshot) */}
{/* Animated Background Layers */}
{/* Tip 1: Main Instructions (As per screenshot) */}
{/* Animated Icon Container 1 (Lightbulb) */}
راهنمای هوشمند

در قسمت صدای ورودی صدای خودتان و در قسمت صدای الگو صدای هدف را بارگذاری کنید؛ هوش مصنوعی صدای شما را دقیقاً به صدای الگو تبدیل می‌کند.

{/* Tip 2: Time Recommendation (Updated Text per user request) */}
{/* Animated Icon Container 2 (Stopwatch - Same Size) */}

نکته: بهترین حالت این است که صدای مدل بین ۳ تا ۹ ثانیه بدون نویز باشه. کیفیت صدای خروجی به کیفیت صدای مدل که اضافه میکنید بستگی داره.

); }; export default CustomVoice;