From a3550a444ae36aa5a4282f949d287a863302cb96 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastjan=20Arti=C4=8D?= Date: Thu, 30 Apr 2026 11:21:43 +0000 Subject: [PATCH] Fix trim bar handles not visible MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Bug from screenshot: trim bar visible but red handles not showing. Causes: 1. video_duration in job is None for old jobs (was not saved on initial processing). Without it, fallback was endInit+60 which placed handles off-screen. 2. videoDuration was const, couldn't be updated when video metadata loads. 3. Handle offset was 9px but handles are now 24px wide (need 12px offset). Fixes: - Backend /api/transcript: fallback to last segment end time if video_duration missing in job - Frontend: videoDuration is let, updated on loadedmetadata - Handle offset 9px → 12px for 24px wide handles - Re-render trim after metadata loads to pick up actual video.duration --- app/main.py | 6 +++++- templates/index.html | 23 ++++++++++++++--------- 2 files changed, 19 insertions(+), 10 deletions(-) diff --git a/app/main.py b/app/main.py index c59200d..8da7762 100644 --- a/app/main.py +++ b/app/main.py @@ -1262,11 +1262,15 @@ async def get_transcript(job_id: str, user: str = Depends(check_auth)): analysis = json.loads(analysis_path.read_text()) transcript = analysis.get("transcript", {}) clip_range = analysis.get("clip_range", {}) + # video_duration: probaj iz analysis, sicer iz zadnjega segmenta, sicer 0 + video_dur = analysis.get("video_duration") or job.get("video_duration") or 0 + if not video_dur and transcript.get("segments"): + video_dur = max((s.get("end", 0) for s in transcript["segments"]), default=0) return { "segments": transcript.get("segments", []), "language": transcript.get("language", "?"), "clip_range": clip_range, - "video_duration": job.get("video_duration", 0), + "video_duration": video_dur, } except Exception as e: raise HTTPException(500, f"Napaka pri branju: {e}") diff --git a/templates/index.html b/templates/index.html index df4de41..3d8dfe0 100644 --- a/templates/index.html +++ b/templates/index.html @@ -1011,7 +1011,7 @@ const startInit = data.clip_range?.start || 0; const endInit = data.clip_range?.end || (startInit + 30); - const videoDuration = data.video_duration || endInit + 60; + let videoDuration = data.video_duration || endInit + 60; const segments = data.segments || []; const overlay = document.createElement("div"); @@ -1127,8 +1127,9 @@ const rPct = pctOf(trimEnd); trimRegion.style.left = lPct + '%'; trimRegion.style.right = (100 - rPct) + '%'; - handleL.style.left = `calc(${lPct}% - 9px)`; - handleR.style.left = `calc(${rPct}% - 9px)`; + // Handle 24px width → offset 12px + handleL.style.left = `calc(${lPct}% - 12px)`; + handleR.style.left = `calc(${rPct}% - 12px)`; startVal.textContent = formatTime(trimStart); endVal.textContent = formatTime(trimEnd); durVal.textContent = (trimEnd - trimStart).toFixed(1) + "s"; @@ -1187,16 +1188,20 @@ if (video) video.currentTime = t; }); - // Update playhead during playback + // Update playhead during playback + re-render če videoDuration manjkalo if (video) { video.addEventListener("timeupdate", renderPlayhead); video.addEventListener("loadedmetadata", () => { - // Če videoDuration ni bilo podanih, vzemi iz videa - if (!data.video_duration && video.duration) { - // Recalculate render - renderTrim(); - renderPlayhead(); + // Če videoDuration ni bilo podanih iz API, vzemi iz video elementa + if ((!videoDuration || videoDuration < 1) && video.duration) { + videoDuration = video.duration; } + // Refresh end label + const endLabel = document.getElementById("trim-end-label"); + if (endLabel) endLabel.textContent = formatTime(videoDuration); + // Re-render handles z pravilnim videoDuration + renderTrim(); + renderPlayhead(); }); }