tori29umai commited on
Commit
cc74d7f
·
verified ·
1 Parent(s): 69bd82a

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +236 -93
app.py CHANGED
@@ -1032,10 +1032,6 @@ if IN_HF_SPACE and 'spaces' in globals():
1032
 
1033
  process = process_with_gpu
1034
  else:
1035
-
1036
-
1037
-
1038
-
1039
  def process(input_image, prompt, n_prompt, seed, total_second_length, use_teacache):
1040
  global stream
1041
  assert input_image is not None, '入力画像がありません!'
@@ -1047,8 +1043,6 @@ else:
1047
  rs = 0.0
1048
  gpu_memory_preservation = 6
1049
 
1050
-
1051
-
1052
  # UI状態の初期化
1053
  yield None, None, '', '', gr.update(interactive=False), gr.update(interactive=True)
1054
 
@@ -1169,19 +1163,16 @@ def make_custom_css():
1169
  margin: 0 auto;
1170
  }
1171
 
1172
- /* 言語切り替えボタンのスタイル */
1173
- #language-toggle {
1174
- position: fixed;
1175
- top: 10px;
1176
- right: 10px;
1177
- z-index: 1000;
1178
- background-color: rgba(0, 0, 0, 0.7);
1179
- color: white;
1180
- border: none;
1181
- border-radius: 4px;
1182
- padding: 5px 10px;
1183
- cursor: pointer;
1184
- font-size: 14px;
1185
  }
1186
 
1187
  /* ページタイトルのスタイル */
@@ -1328,22 +1319,36 @@ with block:
1328
  # 言語切り替え機能を追加
1329
  gr.HTML("""
1330
  <div id="app-container">
1331
- <button id="language-toggle" onclick="toggleLanguage()">日本語/English</button>
1332
- </div>
1333
- <script>
1334
- // グローバル変数、現在の言語を保存
1335
- window.currentLang = "ja";
1336
-
1337
- // 言語切り替え関数
1338
- function toggleLanguage() {
1339
- window.currentLang = window.currentLang === "en" ? "ja" : "en";
1340
-
1341
- // data-i18n属性を持つすべての要素を取得
1342
- const elements = document.querySelectorAll('[data-i18n]');
1343
-
1344
- // 言語に基づいて切り替え
1345
- elements.forEach(el => {
1346
- const key = el.getAttribute('data-i18n');
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1347
  const translations = {
1348
  "en": {
1349
  "title": "FramePack_rotate_landscape - Rotating Landscape Video Generator",
@@ -1356,8 +1361,10 @@ with block:
1356
  "teacache_info": "Faster speed, but may result in slightly worse finger and hand generation.",
1357
  "negative_prompt": "Negative Prompt",
1358
  "seed": "Seed",
 
1359
  "next_latents": "Next Latents",
1360
  "generated_video": "Generated Video",
 
1361
  "sampling_note": "Note: Due to reversed sampling, ending actions will be generated before starting actions. If the starting action is not in the video, please wait, it will be generated later.",
1362
  "error_message": "Error",
1363
  "processing_error": "Processing error",
@@ -1378,9 +1385,10 @@ with block:
1378
  "teacache_info": "処理速度が速くなりますが、指や手の生成品質が若干低下する可能性があります。",
1379
  "negative_prompt": "ネガティブプロンプト",
1380
  "seed": "シード値",
1381
- "video_length": "動画の長さ(最大5秒)",
1382
  "next_latents": "次の潜在変数",
1383
  "generated_video": "生成された動画",
 
1384
  "sampling_note": "注意:逆順サンプリングのため、終了動作が開始動作より先に生成されます。開始動作が動画に表示されていない場合は、しばらくお待ちください。後で生成されます。",
1385
  "error_message": "エラーメッセージ",
1386
  "processing_error": "処理中にエラーが発生しました",
@@ -1392,67 +1400,202 @@ with block:
1392
  }
1393
  };
1394
 
1395
- if (translations[window.currentLang] && translations[window.currentLang][key]) {
1396
- // 要素の種類に基づいてテキストを設定
1397
- if (el.tagName === 'BUTTON') {
1398
- el.textContent = translations[window.currentLang][key];
1399
- } else if (el.tagName === 'LABEL') {
1400
- el.textContent = translations[window.currentLang][key];
1401
- } else {
1402
- el.innerHTML = translations[window.currentLang][key];
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1403
  }
 
 
 
 
 
 
 
 
 
 
 
1404
  }
1405
- });
1406
-
1407
- // ページ上の他の要素を更新
1408
- document.querySelectorAll('.bilingual-label').forEach(el => {
1409
- const enText = el.getAttribute('data-en');
1410
- const jaText = el.getAttribute('data-ja');
1411
- el.textContent = window.currentLang === 'en' ? enText : jaText;
1412
- });
1413
-
1414
- // エラーメッセージコンテナの処理
1415
- document.querySelectorAll('[data-lang]').forEach(el => {
1416
- el.style.display = el.getAttribute('data-lang') === window.currentLang ? 'block' : 'none';
1417
- });
1418
- }
1419
-
1420
- // ページロード後の初期化
1421
- document.addEventListener('DOMContentLoaded', function() {
1422
- // 国際化が必要な要素にdata-i18n属性を追加
1423
- setTimeout(() => {
1424
- // すべてのラベルにi18n属性を追加
1425
- const labelMap = {
1426
- "Upload Image": "upload_image",
1427
- "画像をアップロード": "upload_image",
1428
- "Prompt": "prompt",
1429
- "プロンプト": "prompt",
1430
- "Quick Prompts": "quick_prompts",
1431
- "クイックプロンプト一覧": "quick_prompts",
1432
- "Generate": "start_generation",
1433
- "生成開始": "start_generation",
1434
- "Stop": "stop_generation",
1435
- "停止": "stop_generation",
1436
- // 他のラベルマッピングを追加...
1437
- };
1438
 
1439
- // ラベルの処理
1440
- document.querySelectorAll('label, span, button').forEach(el => {
1441
- const text = el.textContent.trim();
1442
- if (labelMap[text]) {
1443
- el.setAttribute('data-i18n', labelMap[text]);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1444
  }
1445
  });
1446
 
1447
- // 特定の要素にi18n属性を追加
1448
- const titleEl = document.querySelector('h1');
1449
- if (titleEl) titleEl.setAttribute('data-i18n', 'title');
1450
-
1451
- // ラベル言語の初期化
1452
- toggleLanguage();
1453
- }, 1000);
1454
- });
1455
- </script>
1456
  """)
1457
 
1458
  # タイトルにはJavaScriptで切り替えられるようにdata-i18n属性を使用
@@ -1561,7 +1704,7 @@ with block:
1561
  error_message = gr.HTML('', elem_id='error-message', visible=True)
1562
 
1563
  # 処理関数
1564
- ips = [input_image, prompt, n_prompt, seed, total_second_length,use_teacache]
1565
 
1566
  # 開始と終了ボタンのイベント
1567
  start_button.click(fn=process, inputs=ips, outputs=[result_video, preview_image, progress_desc, progress_bar, start_button, end_button])
@@ -1633,4 +1776,4 @@ def create_error_html(error_msg, is_timeout=False):
1633
  }})();
1634
  </script>
1635
  """
1636
-
 
1032
 
1033
  process = process_with_gpu
1034
  else:
 
 
 
 
1035
  def process(input_image, prompt, n_prompt, seed, total_second_length, use_teacache):
1036
  global stream
1037
  assert input_image is not None, '入力画像がありません!'
 
1043
  rs = 0.0
1044
  gpu_memory_preservation = 6
1045
 
 
 
1046
  # UI状態の初期化
1047
  yield None, None, '', '', gr.update(interactive=False), gr.update(interactive=True)
1048
 
 
1163
  margin: 0 auto;
1164
  }
1165
 
1166
+ /* 言語切り替えボタンのスタイル - CSSは自動生成されるので不要です */
1167
+
1168
+ /* 言語切り替え用のクラス */
1169
+ body.lang-ja .lang-en,
1170
+ body.lang-en .lang-ja {
1171
+ display: none !important;
1172
+ }
1173
+
1174
+ body.lang-initialized .dual-lang-text {
1175
+ display: none !important;
 
 
 
1176
  }
1177
 
1178
  /* ページタイトルのスタイル */
 
1319
  # 言語切り替え機能を追加
1320
  gr.HTML("""
1321
  <div id="app-container">
1322
+ <script>
1323
+ // 言語切り替え機能のJavaScriptコード
1324
+ document.addEventListener('DOMContentLoaded', function() {
1325
+ console.log('DOM読み込み完了、言語切り替え初期化処理を開始します');
1326
+
1327
+ // グローバル変数、現在の言語を保存(デフォルトは日本語)
1328
+ window.currentLang = "ja";
1329
+
1330
+ // CSSを動的に追加
1331
+ const styleElement = document.createElement('style');
1332
+ styleElement.textContent = `
1333
+ /* 言語切り替え用のスタイル */
1334
+ body.lang-ja .lang-en,
1335
+ body.lang-en .lang-ja {
1336
+ display: none !important;
1337
+ }
1338
+
1339
+ /* スラッシュ付きのデュアル言語表示を非表示 */
1340
+ body.lang-initialized .dual-lang-text {
1341
+ display: none !important;
1342
+ }
1343
+
1344
+ /* 言語固有表示用クラス */
1345
+ .lang-ja, .lang-en {
1346
+ display: block;
1347
+ }
1348
+ `;
1349
+ document.head.appendChild(styleElement);
1350
+
1351
+ // 翻訳データ
1352
  const translations = {
1353
  "en": {
1354
  "title": "FramePack_rotate_landscape - Rotating Landscape Video Generator",
 
1361
  "teacache_info": "Faster speed, but may result in slightly worse finger and hand generation.",
1362
  "negative_prompt": "Negative Prompt",
1363
  "seed": "Seed",
1364
+ "video_length": "Video Length (max 1 seconds)",
1365
  "next_latents": "Next Latents",
1366
  "generated_video": "Generated Video",
1367
+ "preview": "Preview",
1368
  "sampling_note": "Note: Due to reversed sampling, ending actions will be generated before starting actions. If the starting action is not in the video, please wait, it will be generated later.",
1369
  "error_message": "Error",
1370
  "processing_error": "Processing error",
 
1385
  "teacache_info": "処理速度が速くなりますが、指や手の生成品質が若干低下する可能性があります。",
1386
  "negative_prompt": "ネガティブプロンプト",
1387
  "seed": "シード値",
1388
+ "video_length": "動画の長さ(最大1秒)",
1389
  "next_latents": "次の潜在変数",
1390
  "generated_video": "生成された動画",
1391
+ "preview": "プレビュー",
1392
  "sampling_note": "注意:逆順サンプリングのため、終了動作が開始動作より先に生成されます。開始動作が動画に表示されていない場合は、しばらくお待ちください。後で生成されます。",
1393
  "error_message": "エラーメッセージ",
1394
  "processing_error": "処理中にエラーが発生しました",
 
1400
  }
1401
  };
1402
 
1403
+ // 言語切り替えボタンを作成
1404
+ const langToggleBtn = document.createElement('button');
1405
+ langToggleBtn.id = 'language-toggle';
1406
+ langToggleBtn.textContent = 'English / 英語';
1407
+ langToggleBtn.onclick = toggleLanguage;
1408
+ langToggleBtn.style.position = 'fixed';
1409
+ langToggleBtn.style.top = '10px';
1410
+ langToggleBtn.style.right = '10px';
1411
+ langToggleBtn.style.zIndex = '1000';
1412
+ langToggleBtn.style.backgroundColor = 'rgba(0, 0, 0, 0.7)';
1413
+ langToggleBtn.style.color = 'white';
1414
+ langToggleBtn.style.border = 'none';
1415
+ langToggleBtn.style.borderRadius = '4px';
1416
+ langToggleBtn.style.padding = '5px 10px';
1417
+ langToggleBtn.style.cursor = 'pointer';
1418
+ langToggleBtn.style.fontSize = '14px';
1419
+ document.body.appendChild(langToggleBtn);
1420
+
1421
+ // 言語切り替え関数
1422
+ window.toggleLanguage = function() {
1423
+ const newLang = window.currentLang === "en" ? "ja" : "en";
1424
+ window.currentLang = newLang;
1425
+
1426
+ // body要素に言語クラスを設定
1427
+ document.body.classList.remove('lang-ja', 'lang-en');
1428
+ document.body.classList.add(`lang-${newLang}`);
1429
+
1430
+ // ボタンのテキストを更新
1431
+ langToggleBtn.textContent = newLang === "en" ? '日本語 / Japanese' : 'English / 英語';
1432
+
1433
+ applyTranslations();
1434
+ console.log(`言語を ${newLang} に切り替えました`);
1435
+ }
1436
+
1437
+ // 翻訳を適用する関数
1438
+ function applyTranslations() {
1439
+ // 通常のラベル要素の処理
1440
+ const allLabels = document.querySelectorAll('label, span.label-wrap span, div.wrap span, h1, .gradio-button, .note');
1441
+
1442
+ allLabels.forEach(label => {
1443
+ const text = label.textContent.trim();
1444
+
1445
+ // スラッシュ付きのテキストなら分割して処理
1446
+ if (text.includes('/')) {
1447
+ // 初回のみ言語ごとの要素を作成する
1448
+ if (!label.classList.contains('processed-dual-lang')) {
1449
+ processSlashSeparatedText(label, text);
1450
+ label.classList.add('processed-dual-lang');
1451
+ label.classList.add('dual-lang-text');
1452
+ }
1453
+ } else {
1454
+ // 単一言語のテキストの場合、キーを検索して翻訳
1455
+ const key = getKeyFromText(text);
1456
+ if (key && translations[window.currentLang][key]) {
1457
+ label.textContent = translations[window.currentLang][key];
1458
+ }
1459
+ }
1460
+ });
1461
+
1462
+ // ボタン要素の特別処理
1463
+ const startBtn = document.querySelector('#start-button');
1464
+ if (startBtn) {
1465
+ startBtn.textContent = translations[window.currentLang].start_generation;
1466
+ }
1467
+
1468
+ const stopBtn = document.querySelector('#stop-button');
1469
+ if (stopBtn) {
1470
+ stopBtn.textContent = translations[window.currentLang].stop_generation;
1471
+ }
1472
+
1473
+ // チェックボックスの情報テキスト
1474
+ const infoTexts = document.querySelectorAll('.wrap p, .checkbox-container .wrap p');
1475
+ infoTexts.forEach(info => {
1476
+ const text = info.textContent.trim();
1477
+ if (text.includes('/')) {
1478
+ if (!info.classList.contains('processed-dual-lang')) {
1479
+ processSlashSeparatedText(info, text);
1480
+ info.classList.add('processed-dual-lang');
1481
+ info.classList.add('dual-lang-text');
1482
+ }
1483
+ } else {
1484
+ // TeaCacheのinfo文字列を特別に検出
1485
+ if (text.includes('指や手の生成品質') || text.includes('finger and hand generation')) {
1486
+ info.textContent = translations[window.currentLang].teacache_info;
1487
+ }
1488
+ }
1489
+ });
1490
+
1491
+ // エラーメッセージ処理
1492
+ document.querySelectorAll('[data-lang]').forEach(el => {
1493
+ el.style.display = el.getAttribute('data-lang') === window.currentLang ? 'block' : 'none';
1494
+ });
1495
+ }
1496
+
1497
+ // スラッシュ区切りテキストを処理して、言語ごとの要素を作成
1498
+ function processSlashSeparatedText(element, text) {
1499
+ // テキストをスラッシュで分割
1500
+ const parts = text.split('/');
1501
+ let jaText = parts[0].trim();
1502
+ let enText = parts.length > 1 ? parts[1].trim() : '';
1503
+
1504
+ // 親要素を取得
1505
+ const parent = element.parentNode;
1506
+
1507
+ // 言語ごとの要素を作成
1508
+ const jaElement = document.createElement('span');
1509
+ jaElement.textContent = jaText;
1510
+ jaElement.classList.add('lang-ja');
1511
+
1512
+ const enElement = document.createElement('span');
1513
+ enElement.textContent = enText;
1514
+ enElement.classList.add('lang-en');
1515
+
1516
+ // オリジナル要素の直後に挿入
1517
+ insertAfter(jaElement, element);
1518
+ insertAfter(enElement, jaElement);
1519
+ }
1520
+
1521
+ // 要素の後に新しい要素を挿入するヘルパー関数
1522
+ function insertAfter(newElement, referenceElement) {
1523
+ referenceElement.parentNode.insertBefore(newElement, referenceElement.nextSibling);
1524
+ }
1525
+
1526
+ // テキストからキーを取得する関数
1527
+ function getKeyFromText(text) {
1528
+ if (!text) return null;
1529
+
1530
+ // 複合テキスト(「日本語 / English」形式)を処理
1531
+ if (text.includes('/')) {
1532
+ const parts = text.split('/');
1533
+ const jaText = parts[0].trim();
1534
+ const enText = parts.length > 1 ? parts[1].trim() : '';
1535
+
1536
+ // 日本語テキストからキーを検索
1537
+ for (const [key, value] of Object.entries(translations.ja)) {
1538
+ if (value === jaText) return key;
1539
+ }
1540
+
1541
+ // 英語テキストからキーを検索
1542
+ for (const [key, value] of Object.entries(translations.en)) {
1543
+ if (value === enText) return key;
1544
+ }
1545
  }
1546
+
1547
+ // 単一言語テキストからキーを検索
1548
+ for (const [key, value] of Object.entries(translations.ja)) {
1549
+ if (value === text) return key;
1550
+ }
1551
+
1552
+ for (const [key, value] of Object.entries(translations.en)) {
1553
+ if (value === text) return key;
1554
+ }
1555
+
1556
+ return null;
1557
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1558
 
1559
+ // Gradioの要素が完全に読み込まれるまで少し待ってから実行
1560
+ function initializeLanguage() {
1561
+ console.log('言語初期化処理を実行します');
1562
+
1563
+ // デフォルト言語を設定
1564
+ document.body.classList.add(`lang-${window.currentLang}`);
1565
+ document.body.classList.add('lang-initialized');
1566
+
1567
+ // 翻訳を適用
1568
+ applyTranslations();
1569
+ }
1570
+
1571
+ // 初期化を3回試行(Gradioの読み込みタイミングに合わせるため)
1572
+ setTimeout(initializeLanguage, 1000);
1573
+ setTimeout(initializeLanguage, 2000);
1574
+ setTimeout(initializeLanguage, 3000);
1575
+
1576
+ // MutationObserverでDOM変更を監視し、新しい要素にも翻訳を適用
1577
+ const observer = new MutationObserver(function(mutations) {
1578
+ let shouldUpdate = false;
1579
+
1580
+ mutations.forEach(function(mutation) {
1581
+ if (mutation.addedNodes.length) {
1582
+ shouldUpdate = true;
1583
+ }
1584
+ });
1585
+
1586
+ if (shouldUpdate) {
1587
+ setTimeout(applyTranslations, 100);
1588
  }
1589
  });
1590
 
1591
+ // 監視設定
1592
+ observer.observe(document.body, {
1593
+ childList: true,
1594
+ subtree: true
1595
+ });
1596
+ });
1597
+ </script>
1598
+ </div>
 
1599
  """)
1600
 
1601
  # タイトルにはJavaScriptで切り替えられるようにdata-i18n属性を使用
 
1704
  error_message = gr.HTML('', elem_id='error-message', visible=True)
1705
 
1706
  # 処理関数
1707
+ ips = [input_image, prompt, n_prompt, seed, total_second_length, use_teacache]
1708
 
1709
  # 開始と終了ボタンのイベント
1710
  start_button.click(fn=process, inputs=ips, outputs=[result_video, preview_image, progress_desc, progress_bar, start_button, end_button])
 
1776
  }})();
1777
  </script>
1778
  """
1779
+