106 lines
2.5 KiB
Go
106 lines
2.5 KiB
Go
package main
|
|
|
|
import (
|
|
"math"
|
|
"strings"
|
|
)
|
|
|
|
func setJobProgress(job *RecordJob, phase string, pct int) {
|
|
phase = strings.TrimSpace(phase)
|
|
phaseLower := strings.ToLower(phase)
|
|
|
|
// clamp pct 0..100
|
|
if pct < 0 {
|
|
pct = 0
|
|
}
|
|
if pct > 100 {
|
|
pct = 100
|
|
}
|
|
|
|
// "globale" Zielbereiche pro Phase (dein Pipeline-Modell)
|
|
// postwork wartet: 70..72
|
|
// remuxing: 72..78
|
|
// moving: 78..84
|
|
// probe: 84..86
|
|
// assets: 86..99
|
|
type rng struct{ start, end int }
|
|
rangeFor := func(ph string) rng {
|
|
switch ph {
|
|
case "postwork":
|
|
return rng{0, 5}
|
|
case "remuxing":
|
|
return rng{5, 65}
|
|
case "moving":
|
|
return rng{65, 75}
|
|
case "probe":
|
|
return rng{75, 80}
|
|
case "assets":
|
|
return rng{80, 99}
|
|
default:
|
|
return rng{0, 100}
|
|
}
|
|
}
|
|
|
|
jobsMu.Lock()
|
|
defer jobsMu.Unlock()
|
|
|
|
// Sobald Postwork läuft oder Aufnahme beendet ist -> Recorder darf NICHTS mehr überschreiben.
|
|
inPostwork := job.EndedAt != nil || (strings.TrimSpace(job.Phase) != "" && strings.ToLower(strings.TrimSpace(job.Phase)) != "recording")
|
|
if inPostwork {
|
|
// harte Blockade: alte recording-Updates dürfen weder Phase noch Progress anfassen
|
|
if phaseLower == "" || phaseLower == "recording" {
|
|
return
|
|
}
|
|
}
|
|
|
|
// Phase aktualisieren (aber nur wenn nicht leer)
|
|
if phase != "" {
|
|
job.Phase = phase
|
|
}
|
|
|
|
// ✅ Sonderfall: "wartet auf Nachbearbeitung" => Progress bleibt 0%
|
|
// Erwartung: Caller sendet phase="postwork" und pct=0 solange nur gewartet wird.
|
|
// Muss vor "niemals rückwärts" passieren, sonst käme man von Recording-Progress nicht mehr auf 0.
|
|
if phaseLower == "postwork" && pct == 0 {
|
|
job.Progress = 0
|
|
return
|
|
}
|
|
|
|
// Progress-Logik:
|
|
// - wenn wir in Postwork sind und jemand phasenlokale 0..100 liefert (z.B. remuxing 25),
|
|
// mappe das in den globalen Bereich der Phase.
|
|
// - danach: niemals rückwärts.
|
|
mapped := pct
|
|
|
|
if inPostwork {
|
|
r := rangeFor(phaseLower)
|
|
if r.end >= r.start {
|
|
// Heuristik:
|
|
// - Wenn pct bereits im globalen Bereich der Phase liegt => als global interpretieren, clampen.
|
|
// - Sonst => als lokales 0..100 interpretieren und in [start..end] mappen.
|
|
if pct >= r.start && pct <= r.end {
|
|
// schon global
|
|
mapped = pct
|
|
} else {
|
|
// lokal 0..100 -> global
|
|
width := float64(r.end - r.start)
|
|
mapped = r.start + int(math.Round((float64(pct)/100.0)*width))
|
|
}
|
|
|
|
// clamp in den Bereich
|
|
if mapped < r.start {
|
|
mapped = r.start
|
|
}
|
|
if mapped > r.end {
|
|
mapped = r.end
|
|
}
|
|
}
|
|
}
|
|
|
|
// niemals rückwärts
|
|
if mapped < job.Progress {
|
|
mapped = job.Progress
|
|
}
|
|
job.Progress = mapped
|
|
}
|