Spaces:
Sleeping
Sleeping
Update app.py
Browse files
app.py
CHANGED
|
@@ -13,6 +13,7 @@ import gradio as gr
|
|
| 13 |
from datetime import datetime
|
| 14 |
import threading
|
| 15 |
import subprocess
|
|
|
|
| 16 |
|
| 17 |
warnings.filterwarnings("ignore")
|
| 18 |
urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)
|
|
@@ -409,7 +410,7 @@ class ElevenLabsTTSApp:
|
|
| 409 |
self.output_dir = "voices"
|
| 410 |
os.makedirs(self.output_dir, exist_ok=True)
|
| 411 |
self.current_process = None
|
| 412 |
-
self.logs = []
|
| 413 |
|
| 414 |
def log_message(self, message, msg_type="info"):
|
| 415 |
timestamp = datetime.now().strftime("%H:%M:%S")
|
|
@@ -425,8 +426,8 @@ class ElevenLabsTTSApp:
|
|
| 425 |
return self.log_message("❌ Vui lòng nhập API key!", "error")
|
| 426 |
|
| 427 |
results = []
|
|
|
|
| 428 |
for i, key in enumerate(api_keys, 1):
|
| 429 |
-
self.log_message(f"🔍 Đang kiểm tra API key {i}...")
|
| 430 |
info = check_api_key(key, self.proxy_manager, self.use_proxy)
|
| 431 |
if info.get("valid"):
|
| 432 |
remaining = info.get("remaining", 0)
|
|
@@ -468,7 +469,7 @@ class ElevenLabsTTSApp:
|
|
| 468 |
return result
|
| 469 |
|
| 470 |
def generate_voices(self, api_keys_text, voice_id, text, model, fmt,
|
| 471 |
-
stability, similarity, style, speed, speaker_boost):
|
| 472 |
"""Tạo giọng nói"""
|
| 473 |
try:
|
| 474 |
# Parse inputs
|
|
@@ -505,6 +506,7 @@ class ElevenLabsTTSApp:
|
|
| 505 |
# Check API keys
|
| 506 |
valid_keys = []
|
| 507 |
for i, key in enumerate(api_keys, 1):
|
|
|
|
| 508 |
info = check_api_key(key, self.proxy_manager, self.use_proxy)
|
| 509 |
if info.get("valid"):
|
| 510 |
remaining = info.get("remaining", 0)
|
|
@@ -521,6 +523,7 @@ class ElevenLabsTTSApp:
|
|
| 521 |
generated_files = []
|
| 522 |
|
| 523 |
for i, text_block in enumerate(texts, 1):
|
|
|
|
| 524 |
self.log_message(f"🎤 Đang tạo file {i}/{len(texts)}...")
|
| 525 |
|
| 526 |
success = False
|
|
@@ -572,16 +575,19 @@ class ElevenLabsTTSApp:
|
|
| 572 |
# Merge files
|
| 573 |
if generated_files:
|
| 574 |
self.log_message("🔗 Đang merge file audio...")
|
|
|
|
| 575 |
merged_file = merge_audio_files(output_dir, fmt, os.path.join(output_dir, "output_full"))
|
| 576 |
|
| 577 |
if merged_file and os.path.exists(merged_file):
|
| 578 |
self.log_message("📝 Đang tạo file phụ đề...")
|
|
|
|
| 579 |
srt_file = create_srt(output_dir, texts)
|
| 580 |
|
| 581 |
if srt_file:
|
| 582 |
self.log_message(f"✅ Đã tạo file phụ đề: {os.path.basename(srt_file)}")
|
| 583 |
|
| 584 |
self.log_message(f"🎉 Hoàn thành! File: {os.path.basename(merged_file)}")
|
|
|
|
| 585 |
return merged_file, self.log_message("✅ Quá trình hoàn tất!")
|
| 586 |
else:
|
| 587 |
return None, self.log_message("❌ Không thể merge file audio", "error")
|
|
@@ -601,8 +607,12 @@ class ElevenLabsTTSApp:
|
|
| 601 |
|
| 602 |
def clear_logs(self):
|
| 603 |
"""Xóa logs"""
|
| 604 |
-
self.logs = []
|
| 605 |
return "Logs đã được xóa."
|
|
|
|
|
|
|
|
|
|
|
|
|
| 606 |
|
| 607 |
# ==================== GRADIO UI ====================
|
| 608 |
def create_gradio_interface():
|
|
@@ -659,7 +669,7 @@ def create_gradio_interface():
|
|
| 659 |
text_input = gr.Textbox(
|
| 660 |
label="Văn bản cần chuyển đổi",
|
| 661 |
placeholder="Nhập văn bản cần chuyển đổi tại đây...",
|
| 662 |
-
lines=
|
| 663 |
)
|
| 664 |
|
| 665 |
generate_btn = gr.Button("🚀 Bắt đầu tạo giọng nói", variant="primary")
|
|
@@ -669,7 +679,9 @@ def create_gradio_interface():
|
|
| 669 |
|
| 670 |
gr.Markdown("### 📊 Logs")
|
| 671 |
log_output = gr.Textbox(label="Logs", lines=10, interactive=False)
|
| 672 |
-
|
|
|
|
|
|
|
| 673 |
|
| 674 |
with gr.TabItem("🌐 Proxy Management"):
|
| 675 |
gr.Markdown("### Proxy Settings")
|
|
@@ -734,6 +746,7 @@ def create_gradio_interface():
|
|
| 734 |
- Giữ logs để debug nếu có lỗi
|
| 735 |
- Kiểm tra API keys và proxy trước khi sử dụng
|
| 736 |
- File âm thanh sẽ tự động download khi hoàn thành
|
|
|
|
| 737 |
""")
|
| 738 |
|
| 739 |
# Event handlers
|
|
@@ -753,6 +766,10 @@ def create_gradio_interface():
|
|
| 753 |
fn=app.toggle_proxy,
|
| 754 |
inputs=[use_proxy],
|
| 755 |
outputs=[log_output]
|
|
|
|
|
|
|
|
|
|
|
|
|
| 756 |
)
|
| 757 |
|
| 758 |
generate_btn.click(
|
|
@@ -770,33 +787,26 @@ def create_gradio_interface():
|
|
| 770 |
outputs=[log_output]
|
| 771 |
)
|
| 772 |
|
| 773 |
-
|
| 774 |
-
|
| 775 |
-
return "\n".join(app.logs[-20:])
|
| 776 |
-
|
| 777 |
-
demo.load(
|
| 778 |
-
fn=update_logs,
|
| 779 |
inputs=[],
|
| 780 |
-
outputs=[log_output]
|
| 781 |
-
every=1
|
| 782 |
)
|
| 783 |
|
| 784 |
-
#
|
| 785 |
-
|
| 786 |
-
|
| 787 |
-
|
| 788 |
-
|
| 789 |
-
fn=update_proxy_status,
|
| 790 |
-
inputs=[use_proxy],
|
| 791 |
-
outputs=[proxy_status]
|
| 792 |
)
|
| 793 |
|
| 794 |
return demo
|
| 795 |
|
| 796 |
# ==================== MAIN ====================
|
| 797 |
if __name__ == "__main__":
|
| 798 |
-
|
| 799 |
-
print("🔄 Đang khởi động ElevenLabs TTS Pro
|
|
|
|
| 800 |
|
| 801 |
# Tạo thư mục voices nếu chưa tồn tại
|
| 802 |
os.makedirs("voices", exist_ok=True)
|
|
@@ -807,6 +817,9 @@ if __name__ == "__main__":
|
|
| 807 |
# Lấy port từ environment variable (cần cho Hugging Face Spaces)
|
| 808 |
port = int(os.environ.get("PORT", 7860))
|
| 809 |
|
|
|
|
|
|
|
|
|
|
| 810 |
# Chạy ứng dụng
|
| 811 |
demo.launch(
|
| 812 |
server_name="0.0.0.0",
|
|
|
|
| 13 |
from datetime import datetime
|
| 14 |
import threading
|
| 15 |
import subprocess
|
| 16 |
+
import sys
|
| 17 |
|
| 18 |
warnings.filterwarnings("ignore")
|
| 19 |
urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)
|
|
|
|
| 410 |
self.output_dir = "voices"
|
| 411 |
os.makedirs(self.output_dir, exist_ok=True)
|
| 412 |
self.current_process = None
|
| 413 |
+
self.logs = ["===== ElevenLabs TTS Pro - Khởi động ứng dụng ====="]
|
| 414 |
|
| 415 |
def log_message(self, message, msg_type="info"):
|
| 416 |
timestamp = datetime.now().strftime("%H:%M:%S")
|
|
|
|
| 426 |
return self.log_message("❌ Vui lòng nhập API key!", "error")
|
| 427 |
|
| 428 |
results = []
|
| 429 |
+
self.log_message("🔍 Đang kiểm tra API keys...")
|
| 430 |
for i, key in enumerate(api_keys, 1):
|
|
|
|
| 431 |
info = check_api_key(key, self.proxy_manager, self.use_proxy)
|
| 432 |
if info.get("valid"):
|
| 433 |
remaining = info.get("remaining", 0)
|
|
|
|
| 469 |
return result
|
| 470 |
|
| 471 |
def generate_voices(self, api_keys_text, voice_id, text, model, fmt,
|
| 472 |
+
stability, similarity, style, speed, speaker_boost, progress=gr.Progress()):
|
| 473 |
"""Tạo giọng nói"""
|
| 474 |
try:
|
| 475 |
# Parse inputs
|
|
|
|
| 506 |
# Check API keys
|
| 507 |
valid_keys = []
|
| 508 |
for i, key in enumerate(api_keys, 1):
|
| 509 |
+
progress((i-1)/len(api_keys), f"Kiểm tra API key {i}/{len(api_keys)}")
|
| 510 |
info = check_api_key(key, self.proxy_manager, self.use_proxy)
|
| 511 |
if info.get("valid"):
|
| 512 |
remaining = info.get("remaining", 0)
|
|
|
|
| 523 |
generated_files = []
|
| 524 |
|
| 525 |
for i, text_block in enumerate(texts, 1):
|
| 526 |
+
progress((i-1)/len(texts), f"Đang tạo file {i}/{len(texts)}")
|
| 527 |
self.log_message(f"🎤 Đang tạo file {i}/{len(texts)}...")
|
| 528 |
|
| 529 |
success = False
|
|
|
|
| 575 |
# Merge files
|
| 576 |
if generated_files:
|
| 577 |
self.log_message("🔗 Đang merge file audio...")
|
| 578 |
+
progress(0.9, "Đang merge file audio...")
|
| 579 |
merged_file = merge_audio_files(output_dir, fmt, os.path.join(output_dir, "output_full"))
|
| 580 |
|
| 581 |
if merged_file and os.path.exists(merged_file):
|
| 582 |
self.log_message("📝 Đang tạo file phụ đề...")
|
| 583 |
+
progress(0.95, "Đang tạo file phụ đề...")
|
| 584 |
srt_file = create_srt(output_dir, texts)
|
| 585 |
|
| 586 |
if srt_file:
|
| 587 |
self.log_message(f"✅ Đã tạo file phụ đề: {os.path.basename(srt_file)}")
|
| 588 |
|
| 589 |
self.log_message(f"🎉 Hoàn thành! File: {os.path.basename(merged_file)}")
|
| 590 |
+
progress(1.0, "Hoàn thành!")
|
| 591 |
return merged_file, self.log_message("✅ Quá trình hoàn tất!")
|
| 592 |
else:
|
| 593 |
return None, self.log_message("❌ Không thể merge file audio", "error")
|
|
|
|
| 607 |
|
| 608 |
def clear_logs(self):
|
| 609 |
"""Xóa logs"""
|
| 610 |
+
self.logs = ["===== Logs đã được xóa ====="]
|
| 611 |
return "Logs đã được xóa."
|
| 612 |
+
|
| 613 |
+
def get_logs(self):
|
| 614 |
+
"""Lấy logs hiện tại"""
|
| 615 |
+
return "\n".join(self.logs[-20:])
|
| 616 |
|
| 617 |
# ==================== GRADIO UI ====================
|
| 618 |
def create_gradio_interface():
|
|
|
|
| 669 |
text_input = gr.Textbox(
|
| 670 |
label="Văn bản cần chuyển đổi",
|
| 671 |
placeholder="Nhập văn bản cần chuyển đổi tại đây...",
|
| 672 |
+
lines=15
|
| 673 |
)
|
| 674 |
|
| 675 |
generate_btn = gr.Button("🚀 Bắt đầu tạo giọng nói", variant="primary")
|
|
|
|
| 679 |
|
| 680 |
gr.Markdown("### 📊 Logs")
|
| 681 |
log_output = gr.Textbox(label="Logs", lines=10, interactive=False)
|
| 682 |
+
with gr.Row():
|
| 683 |
+
clear_log_btn = gr.Button("🗑️ Xóa logs")
|
| 684 |
+
refresh_log_btn = gr.Button("🔄 Làm mới logs")
|
| 685 |
|
| 686 |
with gr.TabItem("🌐 Proxy Management"):
|
| 687 |
gr.Markdown("### Proxy Settings")
|
|
|
|
| 746 |
- Giữ logs để debug nếu có lỗi
|
| 747 |
- Kiểm tra API keys và proxy trước khi sử dụng
|
| 748 |
- File âm thanh sẽ tự động download khi hoàn thành
|
| 749 |
+
- Cần có API key hợp lệ từ ElevenLabs để sử dụng
|
| 750 |
""")
|
| 751 |
|
| 752 |
# Event handlers
|
|
|
|
| 766 |
fn=app.toggle_proxy,
|
| 767 |
inputs=[use_proxy],
|
| 768 |
outputs=[log_output]
|
| 769 |
+
).then(
|
| 770 |
+
fn=lambda x: "BẬT" if x else "TẮT",
|
| 771 |
+
inputs=[use_proxy],
|
| 772 |
+
outputs=[proxy_status]
|
| 773 |
)
|
| 774 |
|
| 775 |
generate_btn.click(
|
|
|
|
| 787 |
outputs=[log_output]
|
| 788 |
)
|
| 789 |
|
| 790 |
+
refresh_log_btn.click(
|
| 791 |
+
fn=app.get_logs,
|
|
|
|
|
|
|
|
|
|
|
|
|
| 792 |
inputs=[],
|
| 793 |
+
outputs=[log_output]
|
|
|
|
| 794 |
)
|
| 795 |
|
| 796 |
+
# Initial load of logs
|
| 797 |
+
demo.load(
|
| 798 |
+
fn=app.get_logs,
|
| 799 |
+
inputs=[],
|
| 800 |
+
outputs=[log_output]
|
|
|
|
|
|
|
|
|
|
| 801 |
)
|
| 802 |
|
| 803 |
return demo
|
| 804 |
|
| 805 |
# ==================== MAIN ====================
|
| 806 |
if __name__ == "__main__":
|
| 807 |
+
print("=" * 60)
|
| 808 |
+
print("🔄 Đang khởi động ElevenLabs TTS Pro - Hugging Face Edition")
|
| 809 |
+
print("=" * 60)
|
| 810 |
|
| 811 |
# Tạo thư mục voices nếu chưa tồn tại
|
| 812 |
os.makedirs("voices", exist_ok=True)
|
|
|
|
| 817 |
# Lấy port từ environment variable (cần cho Hugging Face Spaces)
|
| 818 |
port = int(os.environ.get("PORT", 7860))
|
| 819 |
|
| 820 |
+
print(f"🌐 Ứng dụng đang chạy tại: http://0.0.0.0:{port}")
|
| 821 |
+
print("✅ Sẵn sàng sử dụng!")
|
| 822 |
+
|
| 823 |
# Chạy ứng dụng
|
| 824 |
demo.launch(
|
| 825 |
server_name="0.0.0.0",
|