added sprites check
This commit is contained in:
parent
cc2befe093
commit
c9f2086b79
@ -166,6 +166,12 @@ func ensureAnalyzeAllGoalsForVideoCtxForce(
|
|||||||
return false, appErrorf("videolänge konnte nicht bestimmt werden")
|
return false, appErrorf("videolänge konnte nicht bestimmt werden")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if skip, reason, err := checkPreviewSpriteBeforeAnalysis(actx, videoPath); err != nil {
|
||||||
|
return false, err
|
||||||
|
} else if skip {
|
||||||
|
return false, skipAnalysisBecauseBadSpriteError(reason)
|
||||||
|
}
|
||||||
|
|
||||||
hits, err := analyzeVideoFromFrames(actx, videoPath)
|
hits, err := analyzeVideoFromFrames(actx, videoPath)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return false, err
|
return false, err
|
||||||
|
|||||||
@ -1619,10 +1619,18 @@ func runDeferredEnrichPipeline(ctx context.Context, outPath string, sourceURL st
|
|||||||
|
|
||||||
// Ohne Sprite kann keine Sprite-basierte Analyse laufen.
|
// Ohne Sprite kann keine Sprite-basierte Analyse laufen.
|
||||||
if !truth.SpritesReady {
|
if !truth.SpritesReady {
|
||||||
if firstErr == nil {
|
err := skipAnalysisBecauseBadSpriteError("preview-sprite.jpg fehlt")
|
||||||
firstErr = appErrorf("Analysen übersprungen: preview-sprite.jpg fehlt")
|
publishDeferredPhase(
|
||||||
}
|
fileName,
|
||||||
return firstErr
|
assetID,
|
||||||
|
"enrich",
|
||||||
|
"analyze",
|
||||||
|
"error",
|
||||||
|
"Analyse übersprungen",
|
||||||
|
err,
|
||||||
|
)
|
||||||
|
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// -------------------------------------------------
|
// -------------------------------------------------
|
||||||
@ -1643,6 +1651,22 @@ func runDeferredEnrichPipeline(ctx context.Context, outPath string, sourceURL st
|
|||||||
return cerr
|
return cerr
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if analysisSkippedByBadSprite(err) {
|
||||||
|
publishDeferredPhase(
|
||||||
|
fileName,
|
||||||
|
assetID,
|
||||||
|
"enrich",
|
||||||
|
"analyze",
|
||||||
|
"error",
|
||||||
|
"Analyse übersprungen",
|
||||||
|
err,
|
||||||
|
)
|
||||||
|
|
||||||
|
// Wichtig: nicht als Queue-Fehler zurückgeben,
|
||||||
|
// sonst wird die enrichQ unnötig weiter belastet/retryt.
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
analyzeReady = hasAIResultsForAllOutputGoals(outPath, requiredGoals)
|
analyzeReady = hasAIResultsForAllOutputGoals(outPath, requiredGoals)
|
||||||
|
|
||||||
if err != nil || !analyzeReady {
|
if err != nil || !analyzeReady {
|
||||||
|
|||||||
@ -916,6 +916,19 @@ func runGenerateMissingAssetsJob(jobID string, ctx context.Context) {
|
|||||||
publishAssetsTaskPhase(it.name, "enrich", "analyze", "running", "Analyse")
|
publishAssetsTaskPhase(it.name, "enrich", "analyze", "running", "Analyse")
|
||||||
|
|
||||||
_, aerr := ensureAnalyzeForVideoCtx(fileCtx, it.path, sourceURL, "highlights")
|
_, aerr := ensureAnalyzeForVideoCtx(fileCtx, it.path, sourceURL, "highlights")
|
||||||
|
if analysisSkippedByBadSprite(aerr) {
|
||||||
|
publishFinishedPostworkPhase(
|
||||||
|
it.name,
|
||||||
|
id,
|
||||||
|
"enrich",
|
||||||
|
"analyze",
|
||||||
|
"error",
|
||||||
|
"Analyse übersprungen",
|
||||||
|
aerr.Error(),
|
||||||
|
)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
if skipFile, stopAll := handleFileAbort(aerr); stopAll {
|
if skipFile, stopAll := handleFileAbort(aerr); stopAll {
|
||||||
return
|
return
|
||||||
} else if skipFile {
|
} else if skipFile {
|
||||||
|
|||||||
@ -703,3 +703,81 @@ func runTailBlackoutCheck(ctx context.Context, videoPath string) (*tailBlackoutR
|
|||||||
|
|
||||||
return res, nil
|
return res, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var errAnalysisSkippedByBadSprite = errors.New("analysis skipped because preview-sprite.jpg is invalid")
|
||||||
|
|
||||||
|
func analysisSkippedByBadSprite(err error) bool {
|
||||||
|
return errors.Is(err, errAnalysisSkippedByBadSprite)
|
||||||
|
}
|
||||||
|
|
||||||
|
func skipAnalysisBecauseBadSpriteError(reason string) error {
|
||||||
|
reason = strings.TrimSpace(reason)
|
||||||
|
if reason == "" {
|
||||||
|
reason = "preview-sprite.jpg ist fehlerhaft"
|
||||||
|
}
|
||||||
|
|
||||||
|
return fmt.Errorf("%w: %s", errAnalysisSkippedByBadSprite, reason)
|
||||||
|
}
|
||||||
|
|
||||||
|
func persistBadPreviewSpriteReason(videoPath string, reason string) {
|
||||||
|
reason = strings.TrimSpace(reason)
|
||||||
|
if reason == "" {
|
||||||
|
reason = "preview-sprite.jpg ist fehlerhaft"
|
||||||
|
}
|
||||||
|
|
||||||
|
err := persistTailBlackoutResult(videoPath, &tailBlackoutResult{
|
||||||
|
CheckedAt: time.Now().Format(time.RFC3339Nano),
|
||||||
|
IsCorrupt: true,
|
||||||
|
Reason: reason,
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
appLogln("⚠️ preview-sprite validation persist failed:", videoPath, err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func checkPreviewSpriteBeforeAnalysis(
|
||||||
|
ctx context.Context,
|
||||||
|
videoPath string,
|
||||||
|
) (skip bool, reason string, err error) {
|
||||||
|
videoPath = strings.TrimSpace(videoPath)
|
||||||
|
if videoPath == "" {
|
||||||
|
return true, "videoPath ist leer", nil
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := ctx.Err(); err != nil {
|
||||||
|
return false, "", err
|
||||||
|
}
|
||||||
|
|
||||||
|
assetID := assetIDFromVideoPath(videoPath)
|
||||||
|
if assetID == "" {
|
||||||
|
return true, "asset id fehlt", nil
|
||||||
|
}
|
||||||
|
|
||||||
|
_, _, _, spritePath, _, perr := assetPathsForID(assetID)
|
||||||
|
if perr != nil {
|
||||||
|
return true, perr.Error(), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
if !fileExistsNonEmpty(spritePath) {
|
||||||
|
reason := "preview-sprite.jpg fehlt oder ist leer"
|
||||||
|
persistBadPreviewSpriteReason(videoPath, reason)
|
||||||
|
return true, reason, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
res, checkErr := runTailBlackoutCheck(ctx, videoPath)
|
||||||
|
if checkErr != nil {
|
||||||
|
reason := "preview-sprite.jpg konnte nicht geprüft werden: " + checkErr.Error()
|
||||||
|
persistBadPreviewSpriteReason(videoPath, reason)
|
||||||
|
return true, reason, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
if res != nil && res.IsCorrupt {
|
||||||
|
reason := strings.TrimSpace(res.Reason)
|
||||||
|
if reason == "" {
|
||||||
|
reason = "preview-sprite.jpg deutet auf beschädigtes Videoende hin"
|
||||||
|
}
|
||||||
|
return true, reason, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
return false, "", nil
|
||||||
|
}
|
||||||
|
|||||||
@ -466,8 +466,6 @@ func runRegenerateAssetsJob(job *regenerateAssetsJob) {
|
|||||||
publishFinishedPostworkPhase(file, id, "postwork", "sprites", "done", "Sprites", "")
|
publishFinishedPostworkPhase(file, id, "postwork", "sprites", "done", "Sprites", "")
|
||||||
}
|
}
|
||||||
|
|
||||||
publishFinishedPostworkPhase(file, id, "postwork", "sprites", "done", "Sprites", "")
|
|
||||||
|
|
||||||
// 5) Analyse
|
// 5) Analyse
|
||||||
publishFinishedPostworkPhase(file, id, "enrich", "analyze", "running", "Analyse", "")
|
publishFinishedPostworkPhase(file, id, "enrich", "analyze", "running", "Analyse", "")
|
||||||
|
|
||||||
@ -476,6 +474,24 @@ func runRegenerateAssetsJob(job *regenerateAssetsJob) {
|
|||||||
cancelJob()
|
cancelJob()
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if analysisSkippedByBadSprite(err) {
|
||||||
|
publishFinishedPostworkPhase(
|
||||||
|
file,
|
||||||
|
id,
|
||||||
|
"enrich",
|
||||||
|
"analyze",
|
||||||
|
"error",
|
||||||
|
"Analyse übersprungen",
|
||||||
|
err.Error(),
|
||||||
|
)
|
||||||
|
|
||||||
|
finishRegenerateAssetsJob(file, "done", "")
|
||||||
|
setRegenerateAssetsTaskDone(file, "Fertig, Analyse übersprungen")
|
||||||
|
removeRegenerateAssetsJobLater(file, 3*time.Second)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
failJob("enrich", "analyze", err.Error())
|
failJob("enrich", "analyze", err.Error())
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user