Su189 commited on
Commit
c7abdc4
·
verified ·
1 Parent(s): 059501b

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +19 -2
app.py CHANGED
@@ -221,8 +221,25 @@ HEADER_HTML = """
221
  # =====================================================
222
  # MAIN APP
223
  # =====================================================
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
224
  with gr.Blocks(css=GLOBAL_CSS) as demo:
225
  gr.HTML(HEADER_HTML)
 
226
  with gr.Tabs():
227
  # ========== CLONE TAB ==========
228
  with gr.Tab("Clone Voice"):
@@ -239,7 +256,7 @@ with gr.Blocks(css=GLOBAL_CSS) as demo:
239
 
240
  # === CỘT PHẢI: KẾT QUẢ CLONE ===
241
  with gr.Column():
242
- gr.HTML('''<div class="audio-box" style="display:flex;flex-direction:column;gap:8px;"><div style="display:flex;align-items:center;gap:8px;width:100%;"><span style="flex-shrink:0;font-weight:600;">Kết quả Clone</span><audio controls style="flex-grow:1;height:28px;margin-left:8px;"><source src="result.mp3" type="audio/mpeg"></audio></div><div class="clone-control" style="display:flex;align-items:center;justify-content:space-between;width:100%;margin-top:8px;"><button style="width:120px;background:#555;color:#fff;border:none;border-radius:20px;padding:6px 0;font-size:14px;cursor:pointer;" onclick="(function(){let a=document.querySelector('audio');let src=a?(a.currentSrc||a.src):null;if(!src){alert('Không có file để tải');return;}let link=document.createElement('a');link.href=src;link.download='clone_result.mp3';document.body.appendChild(link);link.click();document.body.removeChild(link);})()">⬇ Tải xuống</button><div id="clone-status" style="text-align:center;white-space:nowrap;font-weight:500;flex-grow:1;">Chưa bắt đầu</div><button style="width:110px;background:#555;color:#fff;border:none;border-radius:20px;padding:6px 0;font-size:14px;cursor:pointer;" onclick="(function(){let s=document.getElementById('clone-status');s.innerHTML='<div class=\\'loading-spinner\\'></div>';setTimeout(()=>{s.innerText='✅ Đã hoàn thành';},4000);})()">🚀 Bắt đầu Clone</button></div></div>''')
243
 
244
 
245
  # ========== TTS TAB ==========
@@ -250,7 +267,7 @@ with gr.Blocks(css=GLOBAL_CSS) as demo:
250
  gr.HTML("<div>⏳ Hạn sử dụng: 0/30 ngày</div>")
251
  with gr.Row(elem_id="tts_cols"):
252
  with gr.Column():# <-- đây là CỘT TRÁI (Voice + Tốc độ)
253
- gr.HTML('''<div class="audio-box" style="position:relative;"><div style="display:flex;align-items:center;justify-content:space-between;"><span style="font-weight:600;">Chọn giọng</span><div id="voice-select" style="border:1px solid #ccc;border-radius:8px;padding:6px 12px;width:60%;display:flex;align-items:center;justify-content:space-between;cursor:pointer;"><span id="selected-voice">Giọng A</span><span style="color:#555;">▸</span></div></div><div id="voice-dropdown" style="display:none;position:absolute;bottom:100%;left:0;width:100%;background:#fff;border:1px solid #ccc;border-radius:8px;box-shadow:0 2px 6px rgba(0,0,0,0.15);margin-bottom:6px;z-index:1000;overflow-y:auto;max-height:220px;padding:4px 0;">''' + ''.join([f"<div class='voice-item' style='display:flex;align-items:center;justify-content:space-between;padding:6px 12px;border-bottom:1px solid #eee;'><span>{v}</span><div style='display:flex;align-items:center;gap:10px;'><button class='voice-play' data-voice='{v}' style='background:#000;color:#fff;border:none;width:26px;height:26px;border-radius:4px;font-weight:bold;cursor:pointer;'>▶</button><div class='voice-radio' data-voice='{v}' style='width:16px;height:16px;border:2px solid #000;border-radius:50%;cursor:pointer;'></div></div></div>" for v in ["Giọng A","Giọng B","Giọng C","Giọng D","Giọng E","Giọng F","Giọng G","Giọng H","Giọng I","Giọng J"]]) + '''</div><div id="file-name" style="font-size:13px;color:#444;margin-top:6px;text-align:left;">Tên file mp3: <i>chưa tải</i></div><div style="display:flex;align-items:center;justify-content:space-between;margin-top:10px;"><span style="flex-shrink:0;">Tốc độ giọng đọc</span><input id="speed-slider" type="range" min="0.5" max="2" step="0.1" value="1" style="width:60%;height:4px;border-radius:4px;background:#555;appearance:none;cursor:pointer;"><span id="speed-value">1.0x</span></div><script>const sel=document.getElementById("voice-select");const drop=document.getElementById("voice-dropdown");const selName=document.getElementById("selected-voice");sel.onclick=()=>{drop.style.display=drop.style.display==="block"?"none":"block";};document.querySelectorAll(".voice-radio").forEach(r=>r.onclick=()=>{document.querySelectorAll(".voice-radio").forEach(x=>x.style.background='transparent');r.style.background='#0078ff';selName.textContent=r.dataset.voice;drop.style.display='none';});document.querySelectorAll(".voice-play").forEach(p=>p.onclick=()=>{const v=p.dataset.voice;if(p.textContent==='▶'){p.textContent='⏸';const a=new Audio('assets/sample_audio.mp3');a.play();a.onended=()=>{p.textContent='▶';};}else{p.textContent='▶';}});const s=document.getElementById('speed-slider');const val=document.getElementById('speed-value');s.oninput=()=>{val.textContent=parseFloat(s.value).toFixed(1)+'x';};</script><style>input[type="range"]::-webkit-slider-thumb{appearance:none;width:9px;height:9px;border-radius:50%;background:#000;cursor:pointer;}input[type="range"]::-moz-range-thumb{width:9px;height:9px;border-radius:50%;background:#000;cursor:pointer;}</style></div>''')
254
  with gr.Column():# <-- đây là CỘT PHẢI (Kết quả TTS)
255
  gr.HTML('''<div class="audio-box" style="display:flex;flex-direction:column;gap:8px;"><div style="display:flex;align-items:center;gap:8px;width:100%;"><span style="flex-shrink:0;font-weight:600;">Kết quả TTS</span><audio controls style="flex-grow:1;height:28px;margin-left:8px;"><source src="result.mp3" type="audio/mpeg"></audio></div><div class="clone-control" style="display:flex;align-items:center;justify-content:space-between;width:100%;margin-top:8px;"><button style="width:110px;background:#555;color:#fff;border:none;border-radius:20px;padding:6px 0;font-size:14px;cursor:pointer;" onclick="(function(){let a=document.querySelector('audio');let src=a?(a.currentSrc||a.src):null;if(!src){alert('Không có file');return;}let link=document.createElement('a');link.href=src;link.download='tts_result.mp3';document.body.appendChild(link);link.click();document.body.removeChild(link);})()">⬇ Tải xuống</button><div id="tts-status" style="text-align:center;white-space:nowrap;font-weight:500;flex-grow:1;">Chưa bắt đầu</div><button style="width:120px;background:#555;color:#fff;border:none;border-radius:20px;padding:6px 0;font-size:14px;cursor:pointer;" onclick="(function(){let s=document.getElementById('tts-status');s.innerHTML='<div class=\\'loading-spinner\\'></div>';setTimeout(()=>{s.innerText='✅ Đã hoàn thành';},4000);})()">🚀 Bắt đầu TTS</button></div><style>.clone-control input[type=range]{height:4px;background:#000;}</style></div>''')
256
 
 
221
  # =====================================================
222
  # MAIN APP
223
  # =====================================================
224
+ GLOBAL_CSS = """
225
+ /* Style cho thanh tốc độ đọc */
226
+ input[type="range"] {
227
+ accent-color: #555 !important;
228
+ height: 4px !important;
229
+ width: 100% !important;
230
+ border-radius: 2px !important;
231
+ }
232
+
233
+ /* Căn giữa thanh slider */
234
+ div.svelte-1ipelgc {
235
+ margin-top: 4px !important;
236
+ margin-bottom: 8px !important;
237
+ width: 100% !important;
238
+ }
239
+ """
240
  with gr.Blocks(css=GLOBAL_CSS) as demo:
241
  gr.HTML(HEADER_HTML)
242
+ gr.HTML("<style>#char_usage_row{position:relative;margin:0!important;padding:0!important;height:auto!important;} #char_usage_row>div{display:flex;justify-content:space-between;align-items:center;width:100%;margin:0;padding:0;} #char_usage_row>div>div:first-child{margin:0;padding:0;} #char_usage_row>div>div:nth-child(2){position:absolute;left:50%;transform:translateX(-50%);margin:0;padding:0;} #clone_cols,#tts_cols{margin-top:0!important;padding-top:0!important;} .gradio-tabs .tab-content{padding-top:0!important;margin-top:0!important;} </style>")
243
  with gr.Tabs():
244
  # ========== CLONE TAB ==========
245
  with gr.Tab("Clone Voice"):
 
256
 
257
  # === CỘT PHẢI: KẾT QUẢ CLONE ===
258
  with gr.Column():
259
+ gr.HTML('''<div class="audio-box" style="display:flex;flex-direction:column;gap:8px;"><div style="display:flex;align-items:center;gap:8px;width:100%;"><span style="flex-shrink:0;font-weight:600;">Kết quả Clone</span><audio controls style="flex-grow:1;height:28px;margin-left:8px;"><source src="result.mp3" type="audio/mpeg"></audio></div><div class="clone-control" style="display:flex;align-items:center;justify-content:space-between;width:100%;margin-top:8px;"><button style="width:130px;background:#555;color:#fff;border:none;border-radius:20px;padding:6px 0;font-size:14px;cursor:pointer;" onclick="(function(){let a=document.querySelector('audio');let src=a?(a.currentSrc||a.src):null;if(!src){alert('Không có file để tải');return;}let link=document.createElement('a');link.href=src;link.download='clone_result.mp3';document.body.appendChild(link);link.click();document.body.removeChild(link);})()">⬇ Tải xuống</button><div id="clone-status" style="text-align:center;white-space:nowrap;font-weight:500;flex-grow:1;">Chưa bắt đầu</div><button style="width:110px;background:#555;color:#fff;border:none;border-radius:20px;padding:6px 0;font-size:14px;cursor:pointer;" onclick="(function(){let s=document.getElementById('clone-status');s.innerHTML='<div class=\\'loading-spinner\\'></div>';setTimeout(()=>{s.innerText='✅ Đã hoàn thành';},4000);})()">🚀 Bắt đầu Clone</button></div></div>''')
260
 
261
 
262
  # ========== TTS TAB ==========
 
267
  gr.HTML("<div>⏳ Hạn sử dụng: 0/30 ngày</div>")
268
  with gr.Row(elem_id="tts_cols"):
269
  with gr.Column():# <-- đây là CỘT TRÁI (Voice + Tốc độ)
270
+ gr.HTML('''<div class="audio-box" style="position:relative;"><div style="display:flex;align-items:center;justify-content:space-between;"><span style="font-weight:600;">Chọn giọng để Text to Speech</span><div id="voice-select" style="border:1px solid #ccc;border-radius:8px;padding:6px 12px;width:60%;display:flex;align-items:center;justify-content:space-between;cursor:pointer;"><span id="selected-voice">Giọng A</span><span style="color:#555;">▸</span></div></div><div id="voice-dropdown" style="display:none;position:absolute;bottom:100%;left:0;width:100%;background:#fff;border:1px solid #ccc;border-radius:8px;box-shadow:0 2px 6px rgba(0,0,0,0.15);margin-bottom:6px;z-index:1000;overflow-y:auto;max-height:220px;padding:4px 0;">''' + ''.join([f"<div class='voice-item' style='display:flex;align-items:center;justify-content:space-between;padding:6px 12px;border-bottom:1px solid #eee;'><span>{v}</span><div style='display:flex;align-items:center;gap:10px;'><button class='voice-play' data-voice='{v}' style='background:#000;color:#fff;border:none;width:26px;height:26px;border-radius:4px;font-weight:bold;cursor:pointer;'>▶</button><div class='voice-radio' data-voice='{v}' style='width:16px;height:16px;border:2px solid #000;border-radius:50%;cursor:pointer;'></div></div></div>" for v in ["Giọng A","Giọng B","Giọng C","Giọng D","Giọng E","Giọng F","Giọng G","Giọng H","Giọng I","Giọng J"]]) + '''</div><div id="file-name" style="font-size:13px;color:#444;margin-top:6px;text-align:left;">Tên file mp3: <i>chưa tải</i></div><div style="display:flex;align-items:center;justify-content:space-between;margin-top:10px;"><span style="flex-shrink:0;">Tốc độ giọng đọc</span><input id="speed-slider" type="range" min="0.5" max="2" step="0.1" value="1" style="width:60%;height:4px;border-radius:4px;background:#555;appearance:none;cursor:pointer;"><span id="speed-value">1.0x</span></div><script>const sel=document.getElementById("voice-select");const drop=document.getElementById("voice-dropdown");const selName=document.getElementById("selected-voice");sel.onclick=()=>{drop.style.display=drop.style.display==="block"?"none":"block";};document.querySelectorAll(".voice-radio").forEach(r=>r.onclick=()=>{document.querySelectorAll(".voice-radio").forEach(x=>x.style.background='transparent');r.style.background='#0078ff';selName.textContent=r.dataset.voice;drop.style.display='none';});document.querySelectorAll(".voice-play").forEach(p=>p.onclick=()=>{const v=p.dataset.voice;if(p.textContent==='▶'){p.textContent='⏸';const a=new Audio('assets/sample_audio.mp3');a.play();a.onended=()=>{p.textContent='▶';};}else{p.textContent='▶';}});const s=document.getElementById('speed-slider');const val=document.getElementById('speed-value');s.oninput=()=>{val.textContent=parseFloat(s.value).toFixed(1)+'x';};</script><style>input[type="range"]::-webkit-slider-thumb{appearance:none;width:9px;height:9px;border-radius:50%;background:#000;cursor:pointer;}input[type="range"]::-moz-range-thumb{width:9px;height:9px;border-radius:50%;background:#000;cursor:pointer;}</style></div>''')
271
  with gr.Column():# <-- đây là CỘT PHẢI (Kết quả TTS)
272
  gr.HTML('''<div class="audio-box" style="display:flex;flex-direction:column;gap:8px;"><div style="display:flex;align-items:center;gap:8px;width:100%;"><span style="flex-shrink:0;font-weight:600;">Kết quả TTS</span><audio controls style="flex-grow:1;height:28px;margin-left:8px;"><source src="result.mp3" type="audio/mpeg"></audio></div><div class="clone-control" style="display:flex;align-items:center;justify-content:space-between;width:100%;margin-top:8px;"><button style="width:110px;background:#555;color:#fff;border:none;border-radius:20px;padding:6px 0;font-size:14px;cursor:pointer;" onclick="(function(){let a=document.querySelector('audio');let src=a?(a.currentSrc||a.src):null;if(!src){alert('Không có file');return;}let link=document.createElement('a');link.href=src;link.download='tts_result.mp3';document.body.appendChild(link);link.click();document.body.removeChild(link);})()">⬇ Tải xuống</button><div id="tts-status" style="text-align:center;white-space:nowrap;font-weight:500;flex-grow:1;">Chưa bắt đầu</div><button style="width:120px;background:#555;color:#fff;border:none;border-radius:20px;padding:6px 0;font-size:14px;cursor:pointer;" onclick="(function(){let s=document.getElementById('tts-status');s.innerHTML='<div class=\\'loading-spinner\\'></div>';setTimeout(()=>{s.innerText='✅ Đã hoàn thành';},4000);})()">🚀 Bắt đầu TTS</button></div><style>.clone-control input[type=range]{height:4px;background:#000;}</style></div>''')
273