mr-don88 commited on
Commit
ce75e96
·
verified ·
1 Parent(s): 967c2e0

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +45 -127
app.py CHANGED
@@ -1,41 +1,28 @@
1
- # -*- coding: utf-8 -*-
2
- import os, re, time, random, zipfile, requests, natsort
3
- import gradio as gr
4
- from pydub import AudioSegment
5
 
6
- # ================= API CHECK =================
7
  def check_api_key(api_key):
8
  try:
9
- r = requests.get(
10
  "https://api.elevenlabs.io/v1/user",
11
  headers={"xi-api-key": api_key},
12
  timeout=10
13
  )
14
- if r.status_code != 200:
15
- return None
16
- sub = r.json().get("subscription", {})
17
- return sub.get("character_limit", 0) - sub.get("character_count", 0)
18
- except:
19
- return None
20
-
21
-
22
- # ================= TEXT =================
23
- def split_text(text, max_len=200):
24
- out, cur = [], ""
25
- for s in re.split(r'(?<=[.!?])\s+', text):
26
- if len(cur) + len(s) <= max_len:
27
- cur += " " + s
28
  else:
29
- out.append(cur.strip())
30
- cur = s
31
- if cur:
32
- out.append(cur.strip())
33
- return out
34
 
35
-
36
- # ================= TTS (FIX QUAN TRỌNG) =================
37
  def tts(text, api_key, voice_id, model):
38
- time.sleep(random.uniform(0.8, 1.5))
39
 
40
  r = requests.post(
41
  f"https://api.elevenlabs.io/v1/text-to-speech/{voice_id}",
@@ -59,107 +46,38 @@ def tts(text, api_key, voice_id, model):
59
  )
60
 
61
  if r.status_code == 200:
62
- return r.content
 
 
 
 
 
 
63
 
64
  return None
65
 
 
 
 
66
 
67
-
68
- # ================= AUDIO + SRT =================
69
- def merge_audio(folder, fmt):
70
- files = natsort.natsorted(f for f in os.listdir(folder) if f.endswith(fmt))
71
- audio = AudioSegment.from_file(os.path.join(folder, files[0]))
72
- for f in files[1:]:
73
- audio += AudioSegment.silent(500)
74
- audio += AudioSegment.from_file(os.path.join(folder, f))
75
- out = f"output_full.{fmt}"
76
- audio.export(out, format=fmt)
77
- return out
78
-
79
-
80
- def create_srt(folder, texts):
81
- t, lines = 0, []
82
- files = natsort.natsorted(f for f in os.listdir(folder) if f.startswith("voice_"))
83
- for i, (f, txt) in enumerate(zip(files, texts), 1):
84
- a = AudioSegment.from_file(os.path.join(folder, f))
85
- lines += [
86
- str(i),
87
- f"00:00:{t//1000:02},{t%1000:03} --> 00:00:{(t+len(a))//1000:02},{(t+len(a))%1000:03}",
88
- txt, ""
89
- ]
90
- t += len(a) + 500
91
- with open(os.path.join(folder, "output_full.srt"), "w", encoding="utf-8") as f:
92
- f.write("\n".join(lines))
93
-
94
-
95
- # ================= RUN =================
96
- def run(api_text, api_file, voice_id, text, model, fmt):
97
- keys = api_file.decode().splitlines() if api_file else api_text.splitlines()
98
- keys = [k.strip() for k in keys if k.strip()]
99
-
100
- table = "| API KEY | CREDIT |\n|---|---|\n"
101
- valid = []
102
-
103
- for k in keys:
104
- rem = check_api_key(k)
105
- show = f"{k[:6]}...{k[-4:]}"
106
- if rem and rem > 600:
107
- valid.append(k)
108
- table += f"| {show} | {rem} |\n"
109
  else:
110
- table += f"| {show} | |\n"
111
-
112
- if not valid:
113
- return "❌ Không có API key >600", None, None, table
114
-
115
- texts = split_text(text)
116
- os.makedirs("voices", exist_ok=True)
117
- for f in os.listdir("voices"):
118
- os.remove(os.path.join("voices", f))
119
-
120
- for i, t in enumerate(texts):
121
- success = False
122
- for key in valid:
123
- audio = tts(t, key, voice_id, model)
124
- if audio:
125
- with open(f"voices/voice_{i+1:03d}.{fmt}", "wb") as f:
126
- f.write(audio)
127
- success = True
128
- break
129
- if not success:
130
- return "❌ Không API key nào tạo được audio", None, None, table
131
-
132
- merged = merge_audio("voices", fmt)
133
- create_srt("voices", texts)
134
-
135
- zipf = "output.zip"
136
- with zipfile.ZipFile(zipf, "w") as z:
137
- for f in os.listdir("voices"):
138
- z.write(os.path.join("voices", f), f)
139
- z.write(merged)
140
-
141
- return "✅ HOÀN TẤT", merged, zipf, table
142
-
143
-
144
- # ================= UI =================
145
- with gr.Blocks() as app:
146
- gr.Markdown("## 🔊 ElevenLabs TTS – FIX CHUẨN HF")
147
-
148
- api_text = gr.Textbox(lines=4, label="API key")
149
- api_file = gr.File(type="binary", label="Upload API file")
150
- voice_id = gr.Textbox(label="Voice ID")
151
- text = gr.Textbox(lines=6, label="Text")
152
-
153
- model = gr.Dropdown(["eleven_multilingual_v2"], value="eleven_multilingual_v2")
154
- fmt = gr.Dropdown(["mp3", "wav"], value="mp3")
155
-
156
- btn = gr.Button("🎧 TẠO GIỌNG")
157
- status = gr.Textbox()
158
- audio = gr.Audio(type="filepath")
159
- zipf = gr.File()
160
- table = gr.Markdown()
161
-
162
- btn.click(run, [api_text, api_file, voice_id, text, model, fmt],
163
- [status, audio, zipf, table])
164
-
165
- app.launch()
 
1
+ import requests
2
+ import random
3
+ import time
 
4
 
 
5
  def check_api_key(api_key):
6
  try:
7
+ res = requests.get(
8
  "https://api.elevenlabs.io/v1/user",
9
  headers={"xi-api-key": api_key},
10
  timeout=10
11
  )
12
+ if res.status_code == 200:
13
+ sub = res.json().get("subscription", {})
14
+ remaining = sub.get("character_limit", 0) - sub.get("character_count", 0)
15
+ if remaining > 600:
16
+ return {"valid": True, "remaining": remaining}
17
+ else:
18
+ return {"valid": False, "error": "API key hết credit."}
 
 
 
 
 
 
 
19
  else:
20
+ return {"valid": False, "error": f"Lỗi kết nối: {res.status_code}"}
21
+ except Exception as e:
22
+ return {"valid": False, "error": str(e)}
 
 
23
 
 
 
24
  def tts(text, api_key, voice_id, model):
25
+ time.sleep(random.uniform(0.8, 1.5)) # Delay random để tránh lỗi rate-limit
26
 
27
  r = requests.post(
28
  f"https://api.elevenlabs.io/v1/text-to-speech/{voice_id}",
 
46
  )
47
 
48
  if r.status_code == 200:
49
+ if r.headers.get("content-type", "").startswith("audio"):
50
+ return r.content
51
+ else:
52
+ print("❌ Không có audio trong phản hồi")
53
+ else:
54
+ print(f"❌ Lỗi API: {r.status_code}")
55
+ print(f"Chi tiết lỗi: {r.text}")
56
 
57
  return None
58
 
59
+ def run_tool(api_keys_content, text, voice_id, model_id):
60
+ api_keys = [line.strip() for line in api_keys_content.decode().splitlines() if line.strip()]
61
+ valid_keys = []
62
 
63
+ for key in api_keys:
64
+ key_info = check_api_key(key)
65
+ if key_info["valid"]:
66
+ valid_keys.append(key)
67
+ print(f"✅ Key {key[:6]}... hợp lệ, còn {key_info['remaining']} tín dụng.")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
68
  else:
69
+ print(f" Key {key[:6]}... không hợp lệ: {key_info.get('error', 'Không rõ lý do')}")
70
+
71
+ if not valid_keys:
72
+ print("❌ Không có API key hợp lệ.")
73
+ return
74
+
75
+ for key in valid_keys:
76
+ audio = tts(text, key, voice_id, model_id)
77
+ if audio:
78
+ print("🎧 Tạo giọng nói thành công.")
79
+ return audio
80
+ else:
81
+ print(f"❌ Không thể tạo giọng nói với key {key[:6]}...")
82
+
83
+ print("❌ Không API key nào tạo được audio")