Retranscribe feature: ponovi STT z drugim providerjem v Edit modalu

PROBLEM: STT (Soniox/Scribe) včasih popolnoma narobe slišije besedilo —
npr. 'BILA JE LJUBEZEN PRVA' postane 'BILAL JO ME ZANPRLA' (TRIO ŠUBIC).
Edit modal je do zdaj zahteval popoln recut z novim clip range.

NEW: '🔁 Ponovi transkript' gumb v Edit modalu z dropdown za provider:
  - Scribe (ElevenLabs) — default, najboljši za nemščino + slovenščino
  - Soniox — slovenski default v auto routing
  - Whisper local (faster-whisper)

Backend:
  POST /api/jobs/{id}/retranscribe { provider, auto_upload?, lang? }
  - Briše stari MP4 + analysis.json + .srt + .ass (lokal + S3)
  - Re-queue job z whisper_provider override
  - Ohrani isti clip range — analyze.py si naredi svežo analizo
  - retranscribe_count števec za sledenje poskusov

UX: confirm dialog → 1.5s status → auto-close modal → watchJob za live progress.
Brez auto_upload v Nextcloud — preveri rezultat preden re-uploadaš.
This commit is contained in:
Claude
2026-05-03 14:38:35 +00:00
parent 2abd9daae1
commit 79f611ba73
2 changed files with 134 additions and 1 deletions
+80
View File
@@ -2435,6 +2435,86 @@ async def recut_job(job_id: str, payload: RecutRequest, user: str = Depends(chec
}
# ────────────────────────────────────────────────────────────────
# Retranscribe — ponovi STT z drugim providerjem (npr. Soniox→Scribe)
# Ohrani isti clip range, samo regenerira transkript + podnapise + render.
# ────────────────────────────────────────────────────────────────
class RetranscribeRequest(BaseModel):
provider: str = "elevenlabs" # 'elevenlabs' (Scribe) | 'local' (faster-whisper) | 'soniox' | 'auto'
lang: Optional[str] = None # ostane original če None
auto_upload: bool = False # po končanem renderu naloži v Nextcloud (overwrites obstoječ)
@app.post("/api/jobs/{job_id}/retranscribe")
async def retranscribe_job(job_id: str, payload: RetranscribeRequest, user: str = Depends(check_auth)):
"""Ponovi transkripcijo z drugim STT providerjem in re-renderaj.
Ohrani isti clip range (start/end iz obstoječe analize) — uporabnik
ne potrebuje ponovno pozicionirati IN/OUT. Samo besedilo se popravi.
Pogosto: Soniox je narobe slišal v slovenskem folkloru, gremo na Scribe.
"""
job = load_job(job_id)
if not job:
raise HTTPException(404, "Ne obstaja")
if job.get("status") in ("queued", "processing", "downloading"):
raise HTTPException(409, "Job je že v obdelavi")
# Validate provider
valid_providers = {"elevenlabs", "local", "soniox", "auto"}
if payload.provider not in valid_providers:
raise HTTPException(400, f"Neveljaven provider. Dovoljen: {sorted(valid_providers)}")
# Original input mora obstajati (lokalno ali v S3)
src = job.get("input_path")
if not src:
raise HTTPException(400, "Original video manjka")
_ensure_local(src, "upload")
if not Path(src).exists():
raise HTTPException(400, "Original video ne obstaja niti lokalno niti v S3")
# Briši stari output + analysis (ker bo regen)
out_mp4 = OUTPUT_DIR / f"{job_id}.mp4"
if out_mp4.exists():
out_mp4.unlink()
_delete_from_s3(out_mp4.name, "output")
for ext in ("srt", "ass"):
p = OUTPUT_DIR / f"{job_id}.subtitles.{ext}"
if p.exists():
p.unlink()
_delete_from_s3(p.name, "output")
# Briši tudi analysis.json — zaženemo svežo analizo
analysis_path = OUTPUT_DIR / f"{job_id}.analysis.json"
if analysis_path.exists():
analysis_path.unlink()
_delete_from_s3(analysis_path.name, "output")
# Re-queue job — pomembno: NE postavi custom_clip=True (pustimo polno re-analizo)
# whisper_provider override poskrbi, da bo tokrat drug STT
updates = {
"status": "queued",
"current_step": f"V vrsti za retranscribe ({payload.provider})",
"whisper_provider": payload.provider,
"auto_upload_to_nextcloud": payload.auto_upload,
"hidden_after_upload": False,
"nextcloud_status": "retranscribing",
"error": None,
"chorus_error": None,
"custom_clip": False,
"retranscribe_count": (job.get("retranscribe_count", 0) or 0) + 1,
}
if payload.lang and payload.lang not in ("auto", ""):
updates["lang"] = payload.lang
update_job(job_id, **updates)
return {
"status": "queued",
"job_id": job_id,
"provider": payload.provider,
"retranscribe_count": updates["retranscribe_count"],
}
# ────────────────────────────────────────────────────────────────
# Nextcloud upload (folxspeed/REELS/)
# ────────────────────────────────────────────────────────────────