updated
This commit is contained in:
parent
f24d62d2df
commit
bdf14f8940
@ -69,7 +69,7 @@ func assetIDFromVideoPath(videoPath string) string {
|
||||
return strings.TrimSpace(id)
|
||||
}
|
||||
|
||||
// Liefert die standardisierten Pfade (thumbs.webp / preview.mp4 / preview-sprite.webp / meta.json)
|
||||
// Liefert die standardisierten Pfade (preview.webp / preview.mp4 / preview-sprite.webp / meta.json)
|
||||
func assetPathsForID(id string) (assetDir, thumbPath, previewPath, spritePath, metaPath string, err error) {
|
||||
id = strings.TrimSpace(id)
|
||||
if id == "" {
|
||||
@ -81,7 +81,7 @@ func assetPathsForID(id string) (assetDir, thumbPath, previewPath, spritePath, m
|
||||
return "", "", "", "", "", fmt.Errorf("generated dir: %v", err)
|
||||
}
|
||||
|
||||
thumbPath = filepath.Join(assetDir, "thumbs.webp")
|
||||
thumbPath = filepath.Join(assetDir, "preview.webp")
|
||||
previewPath = filepath.Join(assetDir, "preview.mp4")
|
||||
spritePath = filepath.Join(assetDir, "preview-sprite.webp")
|
||||
|
||||
|
||||
@ -1340,7 +1340,7 @@ func generatedMetaRoot() (string, error) {
|
||||
return resolvePathRelativeToApp(filepath.Join("generated", "meta"))
|
||||
}
|
||||
|
||||
// generatedThumbWebPFile gibt den Pfad zu generated/<assetID>/thumbs.webp zurück.
|
||||
// generatedThumbWebPFile gibt den Pfad zu generated/<assetID>/preview.webp zurück.
|
||||
// assetID darf "HOT " enthalten; wird entfernt und wie überall sonst sanitisiert.
|
||||
func generatedThumbWebPFile(assetID string) (string, error) {
|
||||
assetID = stripHotPrefix(strings.TrimSpace(assetID))
|
||||
@ -1360,7 +1360,7 @@ func generatedThumbWebPFile(assetID string) (string, error) {
|
||||
return "", fmt.Errorf("ensureGeneratedDir: %w", err)
|
||||
}
|
||||
|
||||
return filepath.Join(dir, "thumbs.webp"), nil
|
||||
return filepath.Join(dir, "preview.webp"), nil
|
||||
}
|
||||
|
||||
// Legacy (falls noch alte Assets liegen):
|
||||
|
||||
@ -498,7 +498,7 @@ func generatedThumbFile(id string) (string, error) {
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
return filepath.Join(dir, "thumbs.webp"), nil
|
||||
return filepath.Join(dir, "preview.webp"), nil
|
||||
}
|
||||
|
||||
func generatedPreviewFile(id string) (string, error) {
|
||||
|
||||
@ -712,9 +712,9 @@ func inferModelFromStem(stem string) string {
|
||||
}
|
||||
|
||||
// akzeptiert:
|
||||
// - "/generated/meta/<id>/thumbs.webp"
|
||||
// - "C:\...\generated\meta\<id>\thumbs.webp"
|
||||
// - "http(s)://host/generated/meta/<id>/thumbs.webp"
|
||||
// - "/generated/meta/<id>/preview.webp"
|
||||
// - "C:\...\generated\meta\<id>\preview.webp"
|
||||
// - "http(s)://host/generated/meta/<id>/preview.webp"
|
||||
// - (fallback) irgendeinen Dateinamen-Stem, der wie "<model>_MM_DD_YYYY__HH-MM-ss" aussieht
|
||||
func inferModelFromThumbLike(srcOrPath string) string {
|
||||
s := strings.TrimSpace(srcOrPath)
|
||||
@ -730,7 +730,7 @@ func inferModelFromThumbLike(srcOrPath string) string {
|
||||
s = u.Path
|
||||
}
|
||||
|
||||
// Wenn es wie ".../<id>/thumbs.webp" aussieht: parent dir ist <id>
|
||||
// Wenn es wie ".../<id>/preview.webp" aussieht: parent dir ist <id>
|
||||
base := path.Base(s)
|
||||
lb := strings.ToLower(base)
|
||||
if strings.HasPrefix(lb, "thumbs.") {
|
||||
|
||||
@ -386,7 +386,7 @@ func startPreviewHLS(ctx context.Context, job *RecordJob, m3u8URL, previewDir, h
|
||||
jobsMu.Unlock()
|
||||
}()
|
||||
|
||||
// ✅ Live thumb writer starten (schreibt generated/<assetID>/thumbs.webp regelmäßig neu)
|
||||
// ✅ Live thumb writer starten (schreibt generated/<assetID>/preview.webp regelmäßig neu)
|
||||
startLiveThumbWebPLoop(ctx, job)
|
||||
|
||||
return nil
|
||||
|
||||
@ -243,7 +243,7 @@ func serveLivePreviewWebPFile(w http.ResponseWriter, r *http.Request, path strin
|
||||
|
||||
w.Header().Set("Content-Type", "image/webp")
|
||||
w.Header().Set("Cache-Control", "no-store")
|
||||
http.ServeContent(w, r, "thumbs.webp", st.ModTime(), f)
|
||||
http.ServeContent(w, r, "preview.webp", st.ModTime(), f)
|
||||
}
|
||||
|
||||
func servePreviewWebPFile(w http.ResponseWriter, r *http.Request, path string) {
|
||||
@ -290,7 +290,7 @@ func serveLivePreviewWebPBytes(w http.ResponseWriter, b []byte) {
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------
|
||||
// Preview alias: thumbs.webp / preview.webp (webp only)
|
||||
// Preview alias: preview.webp / preview.webp (webp only)
|
||||
// ------------------------------------------------------------
|
||||
|
||||
func servePreviewWebPAlias(w http.ResponseWriter, r *http.Request, id string) {
|
||||
@ -422,7 +422,7 @@ func recordPreview(w http.ResponseWriter, r *http.Request) {
|
||||
if file := strings.TrimSpace(r.URL.Query().Get("file")); file != "" {
|
||||
low := strings.ToLower(file)
|
||||
// ✅ NUR WEBP
|
||||
if low == "thumbs.webp" || low == "preview.webp" {
|
||||
if low == "preview.webp" || low == "preview.webp" {
|
||||
servePreviewWebPAlias(w, r, id)
|
||||
return
|
||||
}
|
||||
@ -437,7 +437,7 @@ func recordPreview(w http.ResponseWriter, r *http.Request) {
|
||||
jobsMu.Unlock()
|
||||
|
||||
if ok {
|
||||
// ✅ 0) Running: wenn generated/<assetID>/thumbs.webp existiert -> sofort ausliefern
|
||||
// ✅ 0) Running: wenn generated/<assetID>/preview.webp existiert -> sofort ausliefern
|
||||
// (kein ffmpeg pro HTTP-Request)
|
||||
if job.Status == JobRunning {
|
||||
assetID := assetIDForJob(job)
|
||||
@ -451,7 +451,7 @@ func recordPreview(w http.ResponseWriter, r *http.Request) {
|
||||
}
|
||||
}
|
||||
|
||||
// ✅ Fallback: In-Memory-Cache (falls thumbs.webp noch nicht da ist)
|
||||
// ✅ Fallback: In-Memory-Cache (falls preview.webp noch nicht da ist)
|
||||
job.previewMu.Lock()
|
||||
cached := job.previewWebp
|
||||
cachedAt := job.previewWebpAt
|
||||
@ -554,7 +554,7 @@ func updateLiveThumbWebPOnce(ctx context.Context, job *RecordJob) {
|
||||
return
|
||||
}
|
||||
|
||||
// Zielpfad: generated/<assetID>/thumbs.webp
|
||||
// Zielpfad: generated/<assetID>/preview.webp
|
||||
assetID := assetIDForJob(job)
|
||||
thumbPath, err := generatedThumbWebPFile(assetID)
|
||||
if err != nil {
|
||||
@ -693,7 +693,7 @@ func servePreviewForFinishedFile(w http.ResponseWriter, r *http.Request, id stri
|
||||
}
|
||||
}
|
||||
|
||||
thumbPath := filepath.Join(assetDir, "thumbs.webp")
|
||||
thumbPath := filepath.Join(assetDir, "preview.webp")
|
||||
|
||||
// 1) Cache hit
|
||||
if fi, err := os.Stat(thumbPath); err == nil && !fi.IsDir() && fi.Size() > 0 {
|
||||
|
||||
@ -407,7 +407,7 @@ func runJob(ctx context.Context, job *RecordJob, req RecordRequest) {
|
||||
}
|
||||
}
|
||||
|
||||
// 6) Assets (thumbs.webp + preview.mp4)
|
||||
// 6) Assets (preview.webp + preview.mp4)
|
||||
const (
|
||||
assetsStart = 86
|
||||
assetsEnd = 99
|
||||
|
||||
6
backend/web/dist/assets/index-C4whm-WW.js
vendored
6
backend/web/dist/assets/index-C4whm-WW.js
vendored
File diff suppressed because one or more lines are too long
@ -62,11 +62,11 @@ function modelKeyFromFilename(fileOrPath: string): string | null {
|
||||
return stem ? stem.trim() : null
|
||||
}
|
||||
|
||||
// ✅ passt zu Backend: generated/meta/<id>/thumbs.webp
|
||||
// ✅ passt zu Backend: generated/meta/<id>/preview.webp
|
||||
function thumbUrlFromOutput(output: string): string | null {
|
||||
const id = assetIdFromOutput(output)
|
||||
if (!id) return null
|
||||
return `/generated/meta/${encodeURIComponent(id)}/thumbs.webp`
|
||||
return `/generated/meta/${encodeURIComponent(id)}/preview.webp`
|
||||
}
|
||||
|
||||
async function ensureCover(category: string, thumbPath: string, modelName: string | null, refresh: boolean) {
|
||||
|
||||
@ -108,9 +108,9 @@ const jobThumbsWebpCandidates = (job: RecordJob): string[] => {
|
||||
]
|
||||
|
||||
const base = [
|
||||
j.previewBaseUrl ? `${String(j.previewBaseUrl).replace(/\/+$/, '')}/thumbs.webp` : '',
|
||||
j.assetBaseUrl ? `${String(j.assetBaseUrl).replace(/\/+$/, '')}/thumbs.webp` : '',
|
||||
j.thumbsBaseUrl ? `${String(j.thumbsBaseUrl).replace(/\/+$/, '')}/thumbs.webp` : '',
|
||||
j.previewBaseUrl ? `${String(j.previewBaseUrl).replace(/\/+$/, '')}/preview.webp` : '',
|
||||
j.assetBaseUrl ? `${String(j.assetBaseUrl).replace(/\/+$/, '')}/preview.webp` : '',
|
||||
j.thumbsBaseUrl ? `${String(j.thumbsBaseUrl).replace(/\/+$/, '')}/preview.webp` : '',
|
||||
]
|
||||
|
||||
return [...direct, ...base]
|
||||
|
||||
@ -320,7 +320,7 @@ export default function ModelPreview({
|
||||
else setApiImgError(false)
|
||||
}}
|
||||
onError={() => {
|
||||
// 1) Wenn direkte thumbs.webp fehlschlägt -> auf API-Fallback umschalten
|
||||
// 1) Wenn direkte preview.webp fehlschlägt -> auf API-Fallback umschalten
|
||||
if (useDirectThumb) {
|
||||
setDirectImgError(true)
|
||||
return
|
||||
|
||||
@ -411,7 +411,7 @@ export default function Player({
|
||||
|
||||
// Vorschaubild oben
|
||||
const previewA = React.useMemo(
|
||||
() => apiUrl(`/api/preview?id=${encodeURIComponent(previewId)}&file=thumbs.webp`),
|
||||
() => apiUrl(`/api/preview?id=${encodeURIComponent(previewId)}&file=preview.webp`),
|
||||
[previewId]
|
||||
)
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user