elmarcito commited on
Commit
7f0ceac
Β·
verified Β·
1 Parent(s): 6a0a7fe

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +76 -31
app.py CHANGED
@@ -43,7 +43,7 @@ THREAD_POOL = ThreadPoolExecutor(max_workers=16)
43
  @asynccontextmanager
44
  async def lifespan(app: FastAPI):
45
  task = asyncio.create_task(periodic_cleanup())
46
- log.info("DubFlow v2.5.2 started")
47
  yield
48
  task.cancel()
49
  THREAD_POOL.shutdown(wait=False)
@@ -51,7 +51,7 @@ async def lifespan(app: FastAPI):
51
 
52
  app = FastAPI(
53
  title="DubFlow API",
54
- version="2.5.2",
55
  description="Video dubbing pipeline β€” MP4 β†’ SRT β†’ Translate β†’ TTS β†’ Dubbed MP4",
56
  lifespan=lifespan,
57
  )
@@ -1697,7 +1697,7 @@ async def voices():
1697
 
1698
  @app.get("/health", tags=["Meta"])
1699
  async def health():
1700
- return {"status":"ok", "version": "2.5.2",
1701
  "jobs_active": sum(1 for j in JOBS.values() if not j["done"]),
1702
  "jobs_total": len(JOBS),
1703
  "max_upload_mb": MAX_UPLOAD_MB}
@@ -1750,9 +1750,10 @@ body{background:radial-gradient(900px 600px at 10% -10%,rgba(139,92,246,.18),tra
1750
  .label{letter-spacing:.12em;text-transform:uppercase;font-size:11px;color:#94a3b8;}
1751
  input,select{background:rgba(255,255,255,.05);border:1px solid rgba(255,255,255,.1);}
1752
  input:focus,select:focus{border-color:#a78bfa;box-shadow:0 0 0 3px rgba(167,139,250,.15);outline:none;}
1753
- .step-row{display:flex;align-items:center;gap:10px;padding:10px;border-radius:10px;background:rgba(255,255,255,.02);border:1px solid rgba(255,255,255,.05);transition:.3s;}
 
1754
  .step-row.active{background:rgba(139,92,246,.08);border-color:rgba(139,92,246,.3);}
1755
- .step-num{width:28px;height:28px;border-radius:999px;display:flex;align-items:center;justify-content:center;font-weight:600;font-size:12px;background:rgba(255,255,255,.05);border:1px solid rgba(255,255,255,.1);color:#94a3b8;flex-shrink:0;transition:.3s;}
1756
  .step-num.active{background:linear-gradient(90deg,#8b5cf6,#3b82f6);border-color:transparent;color:white;animation:pulse 2s infinite;}
1757
  .step-num.done{background:#10b981;border-color:transparent;color:white;}
1758
  @keyframes pulse{0%,100%{box-shadow:0 0 0 0 rgba(139,92,246,.5)}50%{box-shadow:0 0 0 8px rgba(139,92,246,0)}}
@@ -1760,6 +1761,9 @@ input:focus,select:focus{border-color:#a78bfa;box-shadow:0 0 0 3px rgba(167,139,
1760
  .toast.err{background:rgba(239,68,68,.95);} .toast.ok{background:rgba(16,185,129,.95);} .toast.info{background:rgba(59,130,246,.95);}
1761
  @keyframes slideIn{from{transform:translateX(100%);opacity:0}to{transform:translateX(0);opacity:1}}
1762
  .hint{font-size:11px;color:#64748b;margin-top:4px;}
 
 
 
1763
  .speed{font-size:10px;color:#10b981;font-family:'JetBrains Mono',monospace;}
1764
  .heartbeat{display:inline-block;width:6px;height:6px;border-radius:50%;background:#10b981;margin-left:6px;animation:beat 1s infinite;}
1765
  @keyframes beat{0%,100%{opacity:.3}50%{opacity:1;box-shadow:0 0 8px #10b981}}
@@ -1767,7 +1771,7 @@ input:focus,select:focus{border-color:#a78bfa;box-shadow:0 0 0 3px rgba(167,139,
1767
 
1768
  <div class="max-w-5xl mx-auto pt-10 px-6 pb-20">
1769
  <header class="mb-8">
1770
- <p class="label mb-2">Engine v2.5.2 β€” Real-time + REST API</p>
1771
  <h1 class="text-4xl md:text-5xl font-semibold tracking-tight">DubFlow <span class="text-slate-400 font-light">Web</span></h1>
1772
  <p class="text-slate-400 mt-2 text-sm">Pipeline: upload Β· estrazione Β· traduzione Β· TTS Β· dub</p>
1773
  </header>
@@ -1845,38 +1849,46 @@ input:focus,select:focus{border-color:#a78bfa;box-shadow:0 0 0 3px rgba(167,139,
1845
  <div class="step-row" id="row0">
1846
  <div class="step-num" id="num0">↑</div>
1847
  <div class="flex-1 min-w-0">
1848
- <div class="flex justify-between"><p class="text-sm font-medium">Upload</p><span id="upSpeed" class="speed"></span></div>
1849
  <div class="bar-track mt-1.5"><div id="s0bar" class="bar-fill upload"></div></div>
 
1850
  </div>
1851
- <span id="s0pct" class="code text-slate-500">β€”</span>
1852
  </div>
1853
 
1854
  <div class="step-row" id="row1">
1855
  <div class="step-num" id="num1">1</div>
1856
- <div class="flex-1 min-w-0"><p class="text-sm font-medium">Extract SRT</p>
1857
- <div class="bar-track mt-1.5"><div id="s1bar" class="bar-fill step"></div></div></div>
1858
- <span id="s1pct" class="code text-slate-500">β€”</span>
 
 
1859
  </div>
1860
 
1861
  <div class="step-row" id="row2">
1862
  <div class="step-num" id="num2">2</div>
1863
- <div class="flex-1 min-w-0"><p class="text-sm font-medium">Translate</p>
1864
- <div class="bar-track mt-1.5"><div id="s2bar" class="bar-fill step"></div></div></div>
1865
- <span id="s2pct" class="code text-slate-500">β€”</span>
 
 
1866
  </div>
1867
 
1868
  <div class="step-row" id="row3">
1869
  <div class="step-num" id="num3">3</div>
1870
- <div class="flex-1 min-w-0"><p class="text-sm font-medium">Synced TTS</p>
1871
- <div class="bar-track mt-1.5"><div id="s3bar" class="bar-fill step"></div></div></div>
1872
- <span id="s3pct" class="code text-slate-500">β€”</span>
 
 
1873
  </div>
1874
 
1875
  <div class="step-row" id="row4">
1876
  <div class="step-num" id="num4">4</div>
1877
- <div class="flex-1 min-w-0"><p class="text-sm font-medium">Dub Video</p>
1878
- <div class="bar-track mt-1.5"><div id="s4bar" class="bar-fill step"></div></div></div>
1879
- <span id="s4pct" class="code text-slate-500">β€”</span>
 
 
1880
  </div>
1881
  </div>
1882
 
@@ -1996,8 +2008,14 @@ function resetUI(){
1996
  setStep(i,'idle');
1997
  targetBars['s'+i]=0;
1998
  currentBars['s'+i]=0;
1999
- $('s'+i+'bar').style.width='0%';
2000
- $('s'+i+'pct').textContent='β€”';
 
 
 
 
 
 
2001
  }
2002
  targetBars['global']=0;
2003
  currentBars['global']=0;
@@ -2006,7 +2024,6 @@ function resetUI(){
2006
  $('globalStage').textContent='Avvio';
2007
  $('result').classList.add('hidden');
2008
  $('msg').textContent='';
2009
- $('upSpeed').textContent='';
2010
  $('hb').style.display='none';
2011
  }
2012
 
@@ -2032,24 +2049,43 @@ function track(jid){
2032
  $('msg').textContent=d.message||'';
2033
  const curStep = d.step !== undefined ? d.step : 0;
2034
  const curStepProg = d.step_progress || 0;
 
 
2035
  for(let i=0;i<=4;i++){
 
 
 
2036
  if(curStep > i){
2037
  // Step giΓ  superato β†’ DONE al 100%
2038
  setStep(i, 'done');
2039
  targetBars['s'+i] = 100;
2040
- // Snap immediato per evitare lag visivo
2041
  currentBars['s'+i] = 100;
 
 
 
 
 
2042
  }
2043
  else if(curStep === i){
2044
- // Step corrente β†’ ACTIVE con la sua %
2045
  setStep(i, 'active');
2046
  targetBars['s'+i] = curStepProg;
 
 
 
 
 
2047
  }
2048
  else {
2049
  // Step futuro β†’ IDLE
2050
  setStep(i, 'idle');
2051
  targetBars['s'+i] = 0;
2052
  currentBars['s'+i] = 0;
 
 
 
 
 
2053
  }
2054
  }
2055
  if(d.done && d.result){
@@ -2057,8 +2093,14 @@ function track(jid){
2057
  setStep(i,'done');
2058
  targetBars['s'+i]=100;
2059
  currentBars['s'+i]=100;
2060
- $('s'+i+'bar').style.width='100%';
2061
- $('s'+i+'pct').textContent='100.00%';
 
 
 
 
 
 
2062
  }
2063
  targetBars['global']=100;
2064
  currentBars['global']=100;
@@ -2116,12 +2158,15 @@ function uploadFile(jid, file){
2116
  const eta=e.loaded>0 ? (e.total-e.loaded)/(e.loaded/elapsed) : 0;
2117
  const mb=(e.loaded/1048576).toFixed(2);
2118
  const tot=(e.total/1048576).toFixed(2);
2119
- $('upSpeed').textContent=`${mb}/${tot} MB Β· ${speed.toFixed(2)} MB/s Β· ETA ${eta.toFixed(1)}s`;
 
 
 
 
2120
  };
2121
  xhr.upload.onload=()=>{
2122
- $('upSpeed').textContent='upload completato, attesa server…';
2123
- // Non forzare step 0 a done qui β€” aspetta che il server confermi via SSE
2124
- // perchΓ© il server deve ancora ricevere/validare il file
2125
  };
2126
  xhr.onload=()=>{
2127
  currentXHR=null;
 
43
  @asynccontextmanager
44
  async def lifespan(app: FastAPI):
45
  task = asyncio.create_task(periodic_cleanup())
46
+ log.info("DubFlow v2.5.3 started")
47
  yield
48
  task.cancel()
49
  THREAD_POOL.shutdown(wait=False)
 
51
 
52
  app = FastAPI(
53
  title="DubFlow API",
54
+ version="2.5.3",
55
  description="Video dubbing pipeline β€” MP4 β†’ SRT β†’ Translate β†’ TTS β†’ Dubbed MP4",
56
  lifespan=lifespan,
57
  )
 
1697
 
1698
  @app.get("/health", tags=["Meta"])
1699
  async def health():
1700
+ return {"status":"ok", "version": "2.5.3",
1701
  "jobs_active": sum(1 for j in JOBS.values() if not j["done"]),
1702
  "jobs_total": len(JOBS),
1703
  "max_upload_mb": MAX_UPLOAD_MB}
 
1750
  .label{letter-spacing:.12em;text-transform:uppercase;font-size:11px;color:#94a3b8;}
1751
  input,select{background:rgba(255,255,255,.05);border:1px solid rgba(255,255,255,.1);}
1752
  input:focus,select:focus{border-color:#a78bfa;box-shadow:0 0 0 3px rgba(167,139,250,.15);outline:none;}
1753
+ .step-row{display:flex;align-items:flex-start;gap:10px;padding:12px;border-radius:10px;background:rgba(255,255,255,.02);border:1px solid rgba(255,255,255,.05);transition:background .3s, border-color .3s;}
1754
+ .step-row.done-row{background:rgba(16,185,129,.04);border-color:rgba(16,185,129,.15);}
1755
  .step-row.active{background:rgba(139,92,246,.08);border-color:rgba(139,92,246,.3);}
1756
+ .step-num{width:28px;height:28px;border-radius:999px;display:flex;align-items:center;justify-content:center;font-weight:600;font-size:12px;background:rgba(255,255,255,.05);border:1px solid rgba(255,255,255,.1);color:#94a3b8;flex-shrink:0;transition:.3s;margin-top:1px;}
1757
  .step-num.active{background:linear-gradient(90deg,#8b5cf6,#3b82f6);border-color:transparent;color:white;animation:pulse 2s infinite;}
1758
  .step-num.done{background:#10b981;border-color:transparent;color:white;}
1759
  @keyframes pulse{0%,100%{box-shadow:0 0 0 0 rgba(139,92,246,.5)}50%{box-shadow:0 0 0 8px rgba(139,92,246,0)}}
 
1761
  .toast.err{background:rgba(239,68,68,.95);} .toast.ok{background:rgba(16,185,129,.95);} .toast.info{background:rgba(59,130,246,.95);}
1762
  @keyframes slideIn{from{transform:translateX(100%);opacity:0}to{transform:translateX(0);opacity:1}}
1763
  .hint{font-size:11px;color:#64748b;margin-top:4px;}
1764
+ .step-msg{font-size:10.5px;color:#94a3b8;margin-top:6px;font-family:'JetBrains Mono',monospace;line-height:1.3;min-height:13px;letter-spacing:.01em;}
1765
+ .step-row.active .step-msg{color:#c4b5fd;}
1766
+ .step-row.done-row .step-msg{color:#6ee7b7;}
1767
  .speed{font-size:10px;color:#10b981;font-family:'JetBrains Mono',monospace;}
1768
  .heartbeat{display:inline-block;width:6px;height:6px;border-radius:50%;background:#10b981;margin-left:6px;animation:beat 1s infinite;}
1769
  @keyframes beat{0%,100%{opacity:.3}50%{opacity:1;box-shadow:0 0 8px #10b981}}
 
1771
 
1772
  <div class="max-w-5xl mx-auto pt-10 px-6 pb-20">
1773
  <header class="mb-8">
1774
+ <p class="label mb-2">Engine v2.5.3 β€” Real-time + REST API</p>
1775
  <h1 class="text-4xl md:text-5xl font-semibold tracking-tight">DubFlow <span class="text-slate-400 font-light">Web</span></h1>
1776
  <p class="text-slate-400 mt-2 text-sm">Pipeline: upload Β· estrazione Β· traduzione Β· TTS Β· dub</p>
1777
  </header>
 
1849
  <div class="step-row" id="row0">
1850
  <div class="step-num" id="num0">↑</div>
1851
  <div class="flex-1 min-w-0">
1852
+ <div class="flex justify-between items-center"><p class="text-sm font-medium">Upload</p><span id="s0pct" class="code text-violet-300">β€”</span></div>
1853
  <div class="bar-track mt-1.5"><div id="s0bar" class="bar-fill upload"></div></div>
1854
+ <p id="s0msg" class="step-msg">β€”</p>
1855
  </div>
 
1856
  </div>
1857
 
1858
  <div class="step-row" id="row1">
1859
  <div class="step-num" id="num1">1</div>
1860
+ <div class="flex-1 min-w-0">
1861
+ <div class="flex justify-between items-center"><p class="text-sm font-medium">Extract SRT</p><span id="s1pct" class="code text-violet-300">β€”</span></div>
1862
+ <div class="bar-track mt-1.5"><div id="s1bar" class="bar-fill step"></div></div>
1863
+ <p id="s1msg" class="step-msg">β€”</p>
1864
+ </div>
1865
  </div>
1866
 
1867
  <div class="step-row" id="row2">
1868
  <div class="step-num" id="num2">2</div>
1869
+ <div class="flex-1 min-w-0">
1870
+ <div class="flex justify-between items-center"><p class="text-sm font-medium">Translate</p><span id="s2pct" class="code text-violet-300">β€”</span></div>
1871
+ <div class="bar-track mt-1.5"><div id="s2bar" class="bar-fill step"></div></div>
1872
+ <p id="s2msg" class="step-msg">β€”</p>
1873
+ </div>
1874
  </div>
1875
 
1876
  <div class="step-row" id="row3">
1877
  <div class="step-num" id="num3">3</div>
1878
+ <div class="flex-1 min-w-0">
1879
+ <div class="flex justify-between items-center"><p class="text-sm font-medium">Synced TTS</p><span id="s3pct" class="code text-violet-300">β€”</span></div>
1880
+ <div class="bar-track mt-1.5"><div id="s3bar" class="bar-fill step"></div></div>
1881
+ <p id="s3msg" class="step-msg">β€”</p>
1882
+ </div>
1883
  </div>
1884
 
1885
  <div class="step-row" id="row4">
1886
  <div class="step-num" id="num4">4</div>
1887
+ <div class="flex-1 min-w-0">
1888
+ <div class="flex justify-between items-center"><p class="text-sm font-medium">Dub Video</p><span id="s4pct" class="code text-violet-300">β€”</span></div>
1889
+ <div class="bar-track mt-1.5"><div id="s4bar" class="bar-fill step"></div></div>
1890
+ <p id="s4msg" class="step-msg">β€”</p>
1891
+ </div>
1892
  </div>
1893
  </div>
1894
 
 
2008
  setStep(i,'idle');
2009
  targetBars['s'+i]=0;
2010
  currentBars['s'+i]=0;
2011
+ const bar=document.getElementById('s'+i+'bar');
2012
+ const pct=document.getElementById('s'+i+'pct');
2013
+ const msg=document.getElementById('s'+i+'msg');
2014
+ const row=document.getElementById('row'+i);
2015
+ if(bar) bar.style.width='0%';
2016
+ if(pct) pct.textContent='β€”';
2017
+ if(msg){msg.textContent='β€”'; delete msg.dataset.locked;}
2018
+ if(row) row.classList.remove('active', 'done-row');
2019
  }
2020
  targetBars['global']=0;
2021
  currentBars['global']=0;
 
2024
  $('globalStage').textContent='Avvio';
2025
  $('result').classList.add('hidden');
2026
  $('msg').textContent='';
 
2027
  $('hb').style.display='none';
2028
  }
2029
 
 
2049
  $('msg').textContent=d.message||'';
2050
  const curStep = d.step !== undefined ? d.step : 0;
2051
  const curStepProg = d.step_progress || 0;
2052
+ const curMsg = d.message || '';
2053
+
2054
  for(let i=0;i<=4;i++){
2055
+ const msgEl = document.getElementById('s'+i+'msg');
2056
+ const rowEl = document.getElementById('row'+i);
2057
+
2058
  if(curStep > i){
2059
  // Step giΓ  superato β†’ DONE al 100%
2060
  setStep(i, 'done');
2061
  targetBars['s'+i] = 100;
 
2062
  currentBars['s'+i] = 100;
2063
+ if(rowEl){rowEl.classList.add('done-row'); rowEl.classList.remove('active');}
2064
+ if(msgEl && !msgEl.dataset.locked){
2065
+ msgEl.textContent = 'βœ“ completato';
2066
+ msgEl.dataset.locked = '1';
2067
+ }
2068
  }
2069
  else if(curStep === i){
2070
+ // Step corrente β†’ ACTIVE con messaggio LIVE
2071
  setStep(i, 'active');
2072
  targetBars['s'+i] = curStepProg;
2073
+ if(rowEl){rowEl.classList.add('active'); rowEl.classList.remove('done-row');}
2074
+ if(msgEl){
2075
+ msgEl.textContent = curMsg || '...';
2076
+ delete msgEl.dataset.locked;
2077
+ }
2078
  }
2079
  else {
2080
  // Step futuro β†’ IDLE
2081
  setStep(i, 'idle');
2082
  targetBars['s'+i] = 0;
2083
  currentBars['s'+i] = 0;
2084
+ if(rowEl){rowEl.classList.remove('active', 'done-row');}
2085
+ if(msgEl){
2086
+ msgEl.textContent = 'β€”';
2087
+ delete msgEl.dataset.locked;
2088
+ }
2089
  }
2090
  }
2091
  if(d.done && d.result){
 
2093
  setStep(i,'done');
2094
  targetBars['s'+i]=100;
2095
  currentBars['s'+i]=100;
2096
+ const bar=document.getElementById('s'+i+'bar');
2097
+ const pct=document.getElementById('s'+i+'pct');
2098
+ const msg=document.getElementById('s'+i+'msg');
2099
+ const row=document.getElementById('row'+i);
2100
+ if(bar) bar.style.width='100%';
2101
+ if(pct) pct.textContent='100.00%';
2102
+ if(msg) msg.textContent='βœ“ completato';
2103
+ if(row){row.classList.add('done-row'); row.classList.remove('active');}
2104
  }
2105
  targetBars['global']=100;
2106
  currentBars['global']=100;
 
2158
  const eta=e.loaded>0 ? (e.total-e.loaded)/(e.loaded/elapsed) : 0;
2159
  const mb=(e.loaded/1048576).toFixed(2);
2160
  const tot=(e.total/1048576).toFixed(2);
2161
+ const msg = `${mb}/${tot} MB Β· ${speed.toFixed(2)} MB/s Β· ETA ${eta.toFixed(1)}s`;
2162
+ const s0msg = document.getElementById('s0msg');
2163
+ if(s0msg){s0msg.textContent = msg; delete s0msg.dataset.locked;}
2164
+ const rowEl = document.getElementById('row0');
2165
+ if(rowEl) rowEl.classList.add('active');
2166
  };
2167
  xhr.upload.onload=()=>{
2168
+ const s0msg = document.getElementById('s0msg');
2169
+ if(s0msg) s0msg.textContent = 'upload completato, attesa server…';
 
2170
  };
2171
  xhr.onload=()=>{
2172
  currentXHR=null;