Update index.html
Browse files- index.html +44 -41
index.html
CHANGED
|
@@ -19,7 +19,7 @@
|
|
| 19 |
|
| 20 |
<div class="container-fluid">
|
| 21 |
<h2 class="text-center mb-4 text-primary">LTX 2.3 10Eros - تبدیل تصویر به ویدیو</h2>
|
| 22 |
-
<p class="text-center text-muted">اتصال مستقیم
|
| 23 |
|
| 24 |
<div class="row">
|
| 25 |
<!-- ستون تنظیمات -->
|
|
@@ -141,6 +141,7 @@
|
|
| 141 |
{ group: "مصرف منابع و Seed", id: "seed", type: "number", val: -1 },
|
| 142 |
{ group: "مصرف منابع و Seed", id: "randomize_seed", type: "checkbox", val: true },
|
| 143 |
{ group: "مصرف منابع و Seed", id: "gen_budget", type: "number", val: 0 },
|
|
|
|
| 144 |
{ group: "مصرف منابع و Seed", id: "profile_name", type: "text", val: "" },
|
| 145 |
|
| 146 |
{ group: "حالت چند مرجعی (MSR)", id: "input_mode", type: "select", options: ["single image (i2v)", "multi-reference (MSR)", "multi-reference (original)"], val: "single image (i2v)" },
|
|
@@ -234,6 +235,7 @@
|
|
| 234 |
index++;
|
| 235 |
}
|
| 236 |
|
|
|
|
| 237 |
document.getElementById("enhanceBtn").addEventListener("click", async () => {
|
| 238 |
const hfToken = document.getElementById("hf_token").value.trim();
|
| 239 |
const imgInput = document.getElementById("image_path");
|
|
@@ -253,7 +255,7 @@
|
|
| 253 |
const enhanceParams = {
|
| 254 |
image_path: imgInput.files[0],
|
| 255 |
prompt: promptInput.value,
|
| 256 |
-
enhance_budget:
|
| 257 |
msr_ref2_path: getFile("msr_ref2"),
|
| 258 |
msr_ref3_path: getFile("msr_ref3"),
|
| 259 |
msr_ref4_path: getFile("msr_ref4"),
|
|
@@ -261,6 +263,7 @@
|
|
| 261 |
};
|
| 262 |
|
| 263 |
const result = await client.predict("/enhance_prompt", enhanceParams);
|
|
|
|
| 264 |
if (result.data && result.data[0]) {
|
| 265 |
promptInput.value = result.data[0];
|
| 266 |
alert("پرامپت با موفقیت بهینهسازی شد!");
|
|
@@ -295,7 +298,7 @@
|
|
| 295 |
videoRes.style.display = "none";
|
| 296 |
errorBox.style.display = "none";
|
| 297 |
statusText.style.display = "block";
|
| 298 |
-
statusText.innerText = "در حال
|
| 299 |
|
| 300 |
try {
|
| 301 |
const params = {
|
|
@@ -323,45 +326,46 @@
|
|
| 323 |
}
|
| 324 |
});
|
| 325 |
|
| 326 |
-
|
|
|
|
| 327 |
const client = await Client.connect("Fighterdan/LTX-2.3-10Eros_I2V", { hf_token: hfToken });
|
| 328 |
|
| 329 |
-
|
| 330 |
-
const
|
| 331 |
-
|
| 332 |
-
|
| 333 |
-
|
| 334 |
-
|
| 335 |
-
|
| 336 |
-
|
| 337 |
-
|
| 338 |
-
|
| 339 |
-
|
| 340 |
-
|
| 341 |
-
|
| 342 |
-
} else if (
|
| 343 |
-
|
| 344 |
-
|
| 345 |
-
|
| 346 |
-
|
| 347 |
-
|
| 348 |
-
|
| 349 |
-
videoUrl = URL.createObjectURL(fileData);
|
| 350 |
-
} else if (typeof fileData === "string") {
|
| 351 |
-
videoUrl = fileData;
|
| 352 |
-
} else if (typeof fileData === "object") {
|
| 353 |
-
videoUrl = fileData.url || (fileData.path ? `https://fighterdan-ltx-2-3-10eros-i2v.hf.space/file=${fileData.path}` : "");
|
| 354 |
-
}
|
| 355 |
-
}
|
| 356 |
|
| 357 |
-
|
| 358 |
-
|
| 359 |
-
|
| 360 |
-
|
| 361 |
-
|
| 362 |
-
|
| 363 |
-
|
| 364 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 365 |
}
|
| 366 |
}
|
| 367 |
|
|
@@ -369,8 +373,7 @@
|
|
| 369 |
console.error(error);
|
| 370 |
statusText.style.display = "none";
|
| 371 |
errorBox.style.display = "block";
|
| 372 |
-
|
| 373 |
-
errorBox.innerHTML = `<strong>خطا در پردازش:</strong><br><br>${error.message.replace(/\n/g, '<br>')}<br><br><span style="color:#666;">نکته: اگر خطای "Quota Exceeded" یا "Capacity" دریافت کردید، یعنی محدودیت حساب شما در Hugging Face تمام شده است و باید Token دیگری استفاده کنید.</span>`;
|
| 374 |
} finally {
|
| 375 |
btn.disabled = false;
|
| 376 |
loader.style.display = "none";
|
|
|
|
| 19 |
|
| 20 |
<div class="container-fluid">
|
| 21 |
<h2 class="text-center mb-4 text-primary">LTX 2.3 10Eros - تبدیل تصویر به ویدیو</h2>
|
| 22 |
+
<p class="text-center text-muted">اتصال مستقیم و پایدار (نسخه نهایی با پشتیبانی از ساختار ویدیوی Gradio)</p>
|
| 23 |
|
| 24 |
<div class="row">
|
| 25 |
<!-- ستون تنظیمات -->
|
|
|
|
| 141 |
{ group: "مصرف منابع و Seed", id: "seed", type: "number", val: -1 },
|
| 142 |
{ group: "مصرف منابع و Seed", id: "randomize_seed", type: "checkbox", val: true },
|
| 143 |
{ group: "مصرف منابع و Seed", id: "gen_budget", type: "number", val: 0 },
|
| 144 |
+
{ group: "مصرف منابع و Seed", id: "enhance_budget", type: "number", val: 80 },
|
| 145 |
{ group: "مصرف منابع و Seed", id: "profile_name", type: "text", val: "" },
|
| 146 |
|
| 147 |
{ group: "حالت چند مرجعی (MSR)", id: "input_mode", type: "select", options: ["single image (i2v)", "multi-reference (MSR)", "multi-reference (original)"], val: "single image (i2v)" },
|
|
|
|
| 235 |
index++;
|
| 236 |
}
|
| 237 |
|
| 238 |
+
|
| 239 |
document.getElementById("enhanceBtn").addEventListener("click", async () => {
|
| 240 |
const hfToken = document.getElementById("hf_token").value.trim();
|
| 241 |
const imgInput = document.getElementById("image_path");
|
|
|
|
| 255 |
const enhanceParams = {
|
| 256 |
image_path: imgInput.files[0],
|
| 257 |
prompt: promptInput.value,
|
| 258 |
+
enhance_budget: Number(document.getElementById("enhance_budget")?.value || 80),
|
| 259 |
msr_ref2_path: getFile("msr_ref2"),
|
| 260 |
msr_ref3_path: getFile("msr_ref3"),
|
| 261 |
msr_ref4_path: getFile("msr_ref4"),
|
|
|
|
| 263 |
};
|
| 264 |
|
| 265 |
const result = await client.predict("/enhance_prompt", enhanceParams);
|
| 266 |
+
|
| 267 |
if (result.data && result.data[0]) {
|
| 268 |
promptInput.value = result.data[0];
|
| 269 |
alert("پرامپت با موفقیت بهینهسازی شد!");
|
|
|
|
| 298 |
videoRes.style.display = "none";
|
| 299 |
errorBox.style.display = "none";
|
| 300 |
statusText.style.display = "block";
|
| 301 |
+
statusText.innerText = "در حال تولید ویدیو (بسته به شلوغی سرور ممکن است چند دقیقه طول بکشد)...";
|
| 302 |
|
| 303 |
try {
|
| 304 |
const params = {
|
|
|
|
| 326 |
}
|
| 327 |
});
|
| 328 |
|
| 329 |
+
delete params.enhance_budget;
|
| 330 |
+
|
| 331 |
const client = await Client.connect("Fighterdan/LTX-2.3-10Eros_I2V", { hf_token: hfToken });
|
| 332 |
|
| 333 |
+
const result = await client.predict("/generate", params);
|
| 334 |
+
const data = result.data;
|
| 335 |
+
|
| 336 |
+
// ========================================================
|
| 337 |
+
// بخش هوشمند استخراج آدرس ویدیو بر اساس ساختار تو در تو
|
| 338 |
+
// ========================================================
|
| 339 |
+
let videoUrl = "";
|
| 340 |
+
if (data && data[0]) {
|
| 341 |
+
// در نسخههای جدید Gradio داده ویدیو در key به نام "video" قرار دارد
|
| 342 |
+
let fileData = data[0].video ? data[0].video : data[0];
|
| 343 |
+
|
| 344 |
+
if (fileData instanceof Blob) {
|
| 345 |
+
videoUrl = URL.createObjectURL(fileData);
|
| 346 |
+
} else if (typeof fileData === "string") {
|
| 347 |
+
videoUrl = fileData;
|
| 348 |
+
} else if (typeof fileData === "object") {
|
| 349 |
+
// استخراج URL یا ساخته شدن مسیر پایه
|
| 350 |
+
videoUrl = fileData.url || (fileData.path ? `https://fighterdan-ltx-2-3-10eros-i2v.hf.space/file=${fileData.path}` : "");
|
| 351 |
+
}
|
| 352 |
+
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 353 |
|
| 354 |
+
if (videoUrl) {
|
| 355 |
+
// موفقیت کامل
|
| 356 |
+
videoRes.src = videoUrl;
|
| 357 |
+
videoRes.style.display = "block";
|
| 358 |
+
statusText.innerText = "تولید با موفقیت به پایان رسید!";
|
| 359 |
+
// data[1] همان گزارش موفقیت (مثل 1024x1152, 25 frames) است
|
| 360 |
+
seedRes.innerText = "گزارش خروجی: " + (data[1] || "") + " | Seed: " + (data[2] || "");
|
| 361 |
+
} else {
|
| 362 |
+
// اگر ویدیویی یافت نشد، یعنی واقعا در پایتون اکسپشن رخ داده
|
| 363 |
+
statusText.style.display = "none";
|
| 364 |
+
errorBox.style.display = "block";
|
| 365 |
+
if (data && data[1]) {
|
| 366 |
+
errorBox.innerHTML = `<strong>خطای سرور:</strong><br><br>${data[1].replace(/\n/g, '<br>')}`;
|
| 367 |
+
} else {
|
| 368 |
+
errorBox.innerText = "خطا: ارتباط موفق بود اما ویدیویی برگشت داده نشد.";
|
| 369 |
}
|
| 370 |
}
|
| 371 |
|
|
|
|
| 373 |
console.error(error);
|
| 374 |
statusText.style.display = "none";
|
| 375 |
errorBox.style.display = "block";
|
| 376 |
+
errorBox.innerText = "خطای کلاینت/شبکه: " + error.message;
|
|
|
|
| 377 |
} finally {
|
| 378 |
btn.disabled = false;
|
| 379 |
loader.style.display = "none";
|