File size: 11,920 Bytes
4741934 ed3717e 39152f8 4741934 39152f8 4741934 39152f8 4741934 ed3717e 4741934 ed3717e 4741934 ed3717e 39152f8 ed3717e 39152f8 ed3717e 39152f8 4741934 3a0ef3e ed3717e 4741934 ed3717e 4741934 ed3717e 39152f8 ed3717e 39152f8 4741934 ed3717e 39152f8 4741934 ed3717e 39152f8 4741934 39152f8 ed3717e 39152f8 4741934 ed3717e 39152f8 ed3717e 39152f8 4741934 ed3717e 39152f8 d811ffc 39152f8 ed3717e 4741934 39152f8 ed3717e 39152f8 4741934 ed3717e d811ffc ed3717e d811ffc ed3717e d811ffc ed3717e 39152f8 4741934 39152f8 ed3717e 39152f8 ed3717e 4741934 39152f8 4741934 | 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 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 | <!DOCTYPE html>
<html lang="fa" dir="rtl">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>شبیهساز اختصاصی صدا - OmniVoice Clone API</title>
<!-- استفاده از Tailwind CSS برای طراحی محیط کاربری ساده و مدرن -->
<script src="https://cdn.tailwindcss.com"></script>
<link href="https://fonts.googleapis.com/css2?family=Vazirmatn:wght@300;400;700;900&display=swap" rel="stylesheet">
<style>
body {
font-family: 'Vazirmatn', sans-serif;
}
</style>
</head>
<body class="bg-slate-900 text-slate-100 min-h-screen py-10 px-4">
<div class="max-w-2xl mx-auto bg-slate-800 rounded-2xl shadow-2xl border border-slate-700 overflow-hidden">
<!-- هدر -->
<div class="bg-gradient-to-r from-teal-600 to-emerald-600 p-6 text-white text-center">
<h1 class="text-2xl font-black">پنل شبیهسازی صدا (OmniVoice Clone)</h1>
<p class="text-xs opacity-90 mt-1">تولید گفتار با کپیبرداری دقیق از فایل صوتی مرجع شما</p>
</div>
<div class="p-6 space-y-6">
<!-- متن ورودی -->
<div>
<label class="block text-sm font-bold text-slate-300 mb-2">متن مورد نظر برای تبدیل به گفتار:</label>
<textarea id="inputText" rows="4" class="w-full bg-slate-900 border border-slate-700 rounded-lg p-3 text-white placeholder-slate-500 focus:outline-none focus:ring-2 focus:ring-teal-500" placeholder="متنی را که میخواهید با صدای شبیهسازیشده خوانده شود، بنویسید..."></textarea>
</div>
<!-- فایل صوتی مرجع -->
<div class="bg-slate-900/40 p-4 rounded-xl border border-slate-700 space-y-4">
<div>
<label class="block text-sm font-bold text-slate-300 mb-2">فایل صوتی مرجع (۳ تا ۱۰ ثانیه):</label>
<input type="file" id="refAudio" accept="audio/*" class="w-full text-sm text-slate-400 file:mr-4 file:py-2 file:px-4 file:rounded-full file:border-0 file:text-xs file:font-semibold file:bg-teal-600 file:text-white hover:file:bg-teal-500 cursor-pointer">
<p class="text-[10px] text-slate-500 mt-1">یک فایل صوتی کوتاه و باکیفیت از گوینده مورد نظر آپلود کنید (فرمت mp3، wav و غیره).</p>
</div>
<div>
<label class="block text-xs font-bold text-slate-400 mb-1">متن فایل صوتی مرجع (اختیاری):</label>
<input type="text" id="refText" class="w-full bg-slate-900 border border-slate-700 rounded-lg p-2 text-sm text-white focus:outline-none focus:ring-1 focus:ring-teal-500" placeholder="جملهای که گوینده در فایل مرجع بالا میگوید...">
</div>
</div>
<!-- انتخاب زبان -->
<div>
<label class="block text-sm font-bold text-slate-300 mb-2">زبان خروجی:</label>
<select id="language" class="w-full bg-slate-900 border border-slate-700 rounded-lg p-2.5 text-white text-sm focus:ring-teal-500 focus:border-teal-500">
<option value="Auto">تشخیص خودکار (Auto)</option>
<option value="English">انگلیسی (English)</option>
<option value="Persian">فارسی (Persian)</option>
<option value="Spanish">اسپانیایی (Spanish)</option>
<option value="French">فرانسوی (French)</option>
<option value="Chinese">چینی (Chinese)</option>
</select>
</div>
<!-- توکن هگینگ فیس -->
<div class="bg-slate-950/20 p-3 rounded-lg border border-slate-700/50">
<label class="block text-xs font-bold text-slate-400 mb-1">توکن Hugging Face (اختیاری):</label>
<input type="password" id="hfToken" class="w-full bg-slate-900 border border-slate-700 rounded-lg p-2 text-xs text-white focus:outline-none focus:ring-1 focus:ring-teal-500" placeholder="Bearer hf_...">
<p class="text-[10px] text-slate-500 mt-1">در صورت شلوغ بودن صف عمومی یا مسدود شدن درخواستها، از توکن شخصی خود استفاده کنید.</p>
</div>
<!-- دکمه پردازش -->
<button id="btnGenerate" onclick="generateClone()" class="w-full bg-gradient-to-r from-teal-500 to-emerald-500 hover:from-teal-600 hover:to-emerald-600 text-white font-bold py-3.5 px-6 rounded-xl transition duration-300 shadow-lg flex items-center justify-center">
<span id="btnText">تولید صدای شبیهسازیشده (Synthesize)</span>
</button>
<!-- وضعیت زنده -->
<div id="statusBox" class="hidden bg-slate-950/50 p-4 rounded-xl border border-slate-800 text-xs">
<div class="flex items-center space-x-3 space-x-reverse">
<!-- انیمیشن لودینگ سنتی -->
<div class="w-4 h-4 border-2 border-teal-500 border-t-transparent rounded-full animate-spin"></div>
<span id="statusMessage" class="text-slate-300">در حال بررسی ارتباط...</span>
</div>
</div>
<!-- خروجی نهایی -->
<div id="resultContainer" class="hidden bg-slate-900/90 p-5 rounded-xl border border-teal-500/40 space-y-4">
<h3 class="text-sm font-bold text-teal-400">فایل صوتی شبیهسازیشده با موفقیت آماده شد:</h3>
<audio id="audioPlayer" controls class="w-full"></audio>
<a id="btnDownload" download="cloned_speech.wav" class="block text-center bg-teal-600 hover:bg-teal-500 text-white text-xs font-bold py-2.5 px-4 rounded-lg transition shadow">
دانلود فایل صوتی خروجی (WAV)
</a>
</div>
</div>
</div>
<!-- بارگذاری کتابخانه رسمی جاوااسکریپت گرادیو -->
<script type="module">
import { Client, handle_file } from "https://cdn.jsdelivr.net/npm/@gradio/client/dist/index.min.js";
window.generateClone = async function() {
const btn = document.getElementById("btnGenerate");
const btnText = document.getElementById("btnText");
const statusBox = document.getElementById("statusBox");
const statusMessage = document.getElementById("statusMessage");
const resultContainer = document.getElementById("resultContainer");
const audioPlayer = document.getElementById("audioPlayer");
const btnDownload = document.getElementById("btnDownload");
const text = document.getElementById("inputText").value.trim();
const refAudioFile = document.getElementById("refAudio").files[0];
const refTextVal = document.getElementById("refText").value.trim() || null;
const language = document.getElementById("language").value;
const hfToken = document.getElementById("hfToken").value.trim();
// بررسی الزامات
if (!text) {
alert("لطفاً ابتدا متنی را برای خوانده شدن وارد کنید.");
return;
}
if (!refAudioFile) {
alert("لطفاً فایل صوتی مرجع را آپلود کنید تا صدا شبیهسازی شود.");
return;
}
// آمادهسازی ظاهر
btn.disabled = true;
btnText.innerText = "منتظر بمانید...";
statusBox.classList.remove("hidden");
resultContainer.classList.add("hidden");
statusMessage.innerText = "در حال ایجاد اتصال به موتور هوش مصنوعی OmniVoice...";
try {
// ۱. اتصال به کلاینت گرادیو
const app = await Client.connect("k2-fsa/OmniVoice", {
token: hfToken ? `Bearer ${hfToken}` : undefined
});
statusMessage.innerText = "اتصال برقرار شد. در حال آپلود فایل صوتی مرجع...";
// ۲. پیدا کردن خودکار اندپوینت شبیهسازی (دارای ۱۲ پارامتر ورودی)
const cloneDep = app.config.dependencies.find(dep => dep.inputs && dep.inputs.length === 12);
if (!cloneDep) {
throw new Error("تنظیمات مربوط به مدل شبیهسازی روی سرور یافت نشد.");
}
const endpoint = cloneDep.api_name ? `/${cloneDep.api_name}` : cloneDep.id;
// ۳. آپلود و ساختاردهی فایل صوتی با کلاینت رسمی
const refAudioPayload = handle_file(refAudioFile);
statusMessage.innerText = "درخواست شما با موفقیت در صف سرور قرار گرفت. پردازش روی کارت گرافیک (ZeroGPU) در حال انجام است. لطفاً پنجره را نبندید...";
// ۴. ارسال نهایی درخواست به کمک متد predict (که به طور خودکار صف و SSE را در پسزمینه مدیریت میکند)
const result = await app.predict(endpoint, [
text, // 1. Text to synthesize
language, // 2. Language
refAudioPayload, // 3. Reference Audio
refTextVal, // 4. Reference Text
"", // 5. Instruct (در حالت کلون خالی رها میشود)
32, // 6. Steps (تعداد مراحل تولید پیشفرض)
2.0, // 7. Guidance scale (مقیاس هدایت پیشفرض)
true, // 8. Denoise (کاهش نویز پیشفرض)
1.0, // 9. Speed (سرعت طبیعی)
0, // 10. Duration (مدت زمان خودکار)
true, // 11. Preprocess prompt (پیشپردازش پیشفرض)
true // 12. Postprocess output (پسپردازش خروجی)
]);
// ۵. نمایش نتایج
if (result && result.data && result.data[0]) {
const audioUrl = result.data[0].url;
audioPlayer.src = audioUrl;
btnDownload.href = audioUrl;
statusMessage.innerText = "پردازش نهایی شد و فایل صدا تولید گردید.";
resultContainer.classList.remove("hidden");
} else {
throw new Error("خروجی معتبری از هوش مصنوعی دریافت نشد.");
}
} catch (error) {
console.error(error);
statusMessage.innerText = `خطا در فرآیند: ${error.message || error}`;
} finally {
btn.disabled = false;
btnText.innerText = "تولید صدای شبیهسازیشده (Synthesize)";
}
}
</script>
</body>
</html> |