updated
This commit is contained in:
parent
f24d62d2df
commit
bdf14f8940
@ -69,7 +69,7 @@ func assetIDFromVideoPath(videoPath string) string {
|
|||||||
return strings.TrimSpace(id)
|
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) {
|
func assetPathsForID(id string) (assetDir, thumbPath, previewPath, spritePath, metaPath string, err error) {
|
||||||
id = strings.TrimSpace(id)
|
id = strings.TrimSpace(id)
|
||||||
if id == "" {
|
if id == "" {
|
||||||
@ -81,7 +81,7 @@ func assetPathsForID(id string) (assetDir, thumbPath, previewPath, spritePath, m
|
|||||||
return "", "", "", "", "", fmt.Errorf("generated dir: %v", err)
|
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")
|
previewPath = filepath.Join(assetDir, "preview.mp4")
|
||||||
spritePath = filepath.Join(assetDir, "preview-sprite.webp")
|
spritePath = filepath.Join(assetDir, "preview-sprite.webp")
|
||||||
|
|
||||||
|
|||||||
@ -1340,7 +1340,7 @@ func generatedMetaRoot() (string, error) {
|
|||||||
return resolvePathRelativeToApp(filepath.Join("generated", "meta"))
|
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.
|
// assetID darf "HOT " enthalten; wird entfernt und wie überall sonst sanitisiert.
|
||||||
func generatedThumbWebPFile(assetID string) (string, error) {
|
func generatedThumbWebPFile(assetID string) (string, error) {
|
||||||
assetID = stripHotPrefix(strings.TrimSpace(assetID))
|
assetID = stripHotPrefix(strings.TrimSpace(assetID))
|
||||||
@ -1360,7 +1360,7 @@ func generatedThumbWebPFile(assetID string) (string, error) {
|
|||||||
return "", fmt.Errorf("ensureGeneratedDir: %w", err)
|
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):
|
// Legacy (falls noch alte Assets liegen):
|
||||||
|
|||||||
@ -498,7 +498,7 @@ func generatedThumbFile(id string) (string, error) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return "", err
|
return "", err
|
||||||
}
|
}
|
||||||
return filepath.Join(dir, "thumbs.webp"), nil
|
return filepath.Join(dir, "preview.webp"), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func generatedPreviewFile(id string) (string, error) {
|
func generatedPreviewFile(id string) (string, error) {
|
||||||
|
|||||||
@ -712,9 +712,9 @@ func inferModelFromStem(stem string) string {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// akzeptiert:
|
// akzeptiert:
|
||||||
// - "/generated/meta/<id>/thumbs.webp"
|
// - "/generated/meta/<id>/preview.webp"
|
||||||
// - "C:\...\generated\meta\<id>\thumbs.webp"
|
// - "C:\...\generated\meta\<id>\preview.webp"
|
||||||
// - "http(s)://host/generated/meta/<id>/thumbs.webp"
|
// - "http(s)://host/generated/meta/<id>/preview.webp"
|
||||||
// - (fallback) irgendeinen Dateinamen-Stem, der wie "<model>_MM_DD_YYYY__HH-MM-ss" aussieht
|
// - (fallback) irgendeinen Dateinamen-Stem, der wie "<model>_MM_DD_YYYY__HH-MM-ss" aussieht
|
||||||
func inferModelFromThumbLike(srcOrPath string) string {
|
func inferModelFromThumbLike(srcOrPath string) string {
|
||||||
s := strings.TrimSpace(srcOrPath)
|
s := strings.TrimSpace(srcOrPath)
|
||||||
@ -730,7 +730,7 @@ func inferModelFromThumbLike(srcOrPath string) string {
|
|||||||
s = u.Path
|
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)
|
base := path.Base(s)
|
||||||
lb := strings.ToLower(base)
|
lb := strings.ToLower(base)
|
||||||
if strings.HasPrefix(lb, "thumbs.") {
|
if strings.HasPrefix(lb, "thumbs.") {
|
||||||
|
|||||||
@ -386,7 +386,7 @@ func startPreviewHLS(ctx context.Context, job *RecordJob, m3u8URL, previewDir, h
|
|||||||
jobsMu.Unlock()
|
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)
|
startLiveThumbWebPLoop(ctx, job)
|
||||||
|
|
||||||
return nil
|
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("Content-Type", "image/webp")
|
||||||
w.Header().Set("Cache-Control", "no-store")
|
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) {
|
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) {
|
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 != "" {
|
if file := strings.TrimSpace(r.URL.Query().Get("file")); file != "" {
|
||||||
low := strings.ToLower(file)
|
low := strings.ToLower(file)
|
||||||
// ✅ NUR WEBP
|
// ✅ NUR WEBP
|
||||||
if low == "thumbs.webp" || low == "preview.webp" {
|
if low == "preview.webp" || low == "preview.webp" {
|
||||||
servePreviewWebPAlias(w, r, id)
|
servePreviewWebPAlias(w, r, id)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -437,7 +437,7 @@ func recordPreview(w http.ResponseWriter, r *http.Request) {
|
|||||||
jobsMu.Unlock()
|
jobsMu.Unlock()
|
||||||
|
|
||||||
if ok {
|
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)
|
// (kein ffmpeg pro HTTP-Request)
|
||||||
if job.Status == JobRunning {
|
if job.Status == JobRunning {
|
||||||
assetID := assetIDForJob(job)
|
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()
|
job.previewMu.Lock()
|
||||||
cached := job.previewWebp
|
cached := job.previewWebp
|
||||||
cachedAt := job.previewWebpAt
|
cachedAt := job.previewWebpAt
|
||||||
@ -554,7 +554,7 @@ func updateLiveThumbWebPOnce(ctx context.Context, job *RecordJob) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// Zielpfad: generated/<assetID>/thumbs.webp
|
// Zielpfad: generated/<assetID>/preview.webp
|
||||||
assetID := assetIDForJob(job)
|
assetID := assetIDForJob(job)
|
||||||
thumbPath, err := generatedThumbWebPFile(assetID)
|
thumbPath, err := generatedThumbWebPFile(assetID)
|
||||||
if err != nil {
|
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
|
// 1) Cache hit
|
||||||
if fi, err := os.Stat(thumbPath); err == nil && !fi.IsDir() && fi.Size() > 0 {
|
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 (
|
const (
|
||||||
assetsStart = 86
|
assetsStart = 86
|
||||||
assetsEnd = 99
|
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
|
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 {
|
function thumbUrlFromOutput(output: string): string | null {
|
||||||
const id = assetIdFromOutput(output)
|
const id = assetIdFromOutput(output)
|
||||||
if (!id) return null
|
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) {
|
async function ensureCover(category: string, thumbPath: string, modelName: string | null, refresh: boolean) {
|
||||||
|
|||||||
@ -108,9 +108,9 @@ const jobThumbsWebpCandidates = (job: RecordJob): string[] => {
|
|||||||
]
|
]
|
||||||
|
|
||||||
const base = [
|
const base = [
|
||||||
j.previewBaseUrl ? `${String(j.previewBaseUrl).replace(/\/+$/, '')}/thumbs.webp` : '',
|
j.previewBaseUrl ? `${String(j.previewBaseUrl).replace(/\/+$/, '')}/preview.webp` : '',
|
||||||
j.assetBaseUrl ? `${String(j.assetBaseUrl).replace(/\/+$/, '')}/thumbs.webp` : '',
|
j.assetBaseUrl ? `${String(j.assetBaseUrl).replace(/\/+$/, '')}/preview.webp` : '',
|
||||||
j.thumbsBaseUrl ? `${String(j.thumbsBaseUrl).replace(/\/+$/, '')}/thumbs.webp` : '',
|
j.thumbsBaseUrl ? `${String(j.thumbsBaseUrl).replace(/\/+$/, '')}/preview.webp` : '',
|
||||||
]
|
]
|
||||||
|
|
||||||
return [...direct, ...base]
|
return [...direct, ...base]
|
||||||
|
|||||||
@ -320,7 +320,7 @@ export default function ModelPreview({
|
|||||||
else setApiImgError(false)
|
else setApiImgError(false)
|
||||||
}}
|
}}
|
||||||
onError={() => {
|
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) {
|
if (useDirectThumb) {
|
||||||
setDirectImgError(true)
|
setDirectImgError(true)
|
||||||
return
|
return
|
||||||
|
|||||||
@ -411,7 +411,7 @@ export default function Player({
|
|||||||
|
|
||||||
// Vorschaubild oben
|
// Vorschaubild oben
|
||||||
const previewA = React.useMemo(
|
const previewA = React.useMemo(
|
||||||
() => apiUrl(`/api/preview?id=${encodeURIComponent(previewId)}&file=thumbs.webp`),
|
() => apiUrl(`/api/preview?id=${encodeURIComponent(previewId)}&file=preview.webp`),
|
||||||
[previewId]
|
[previewId]
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user