taggart

Simple golang tagging filesystem webapp
Log | Files | Refs

commit 116eaaae012aa23b30195d75c8400c7cf1b842c6
parent 40b4f8827bd690fe08b0c08ebc6f25de26e3df84
Author: breadcat <breadcat@users.noreply.github.com>
Date:   Sat, 27 Sep 2025 00:36:04 +0100

Generate thumbnails on video upload

And use in gallery pages

Diffstat:
Mmain.go | 44++++++++++++++++++++++++++++++++++++++++++++
Mstatic/style.css | 2++
Mtemplates/_gallery.html | 6+++---
3 files changed, 49 insertions(+), 3 deletions(-)

diff --git a/main.go b/main.go @@ -1257,6 +1257,13 @@ func processVideoFile(tempPath, finalPath string) (string, string, error) { return "", "", fmt.Errorf("failed to move file: %v", err) } + ext := strings.ToLower(filepath.Ext(finalPath)) + if ext == ".mp4" || ext == ".mov" || ext == ".avi" || ext == ".mkv" || ext == ".webm" { + if err := generateThumbnail(finalPath, config.UploadDir, filepath.Base(finalPath)); err != nil { + log.Printf("Warning: could not generate thumbnail: %v", err) + } + } + return finalPath, "", nil } @@ -1334,4 +1341,41 @@ func orphansHandler(w http.ResponseWriter, r *http.Request) { pageData := buildPageData("Orphaned Files", orphans) renderTemplate(w, "orphans.html", pageData) +} +func generateThumbnail(videoPath, uploadDir, filename string) error { + thumbDir := filepath.Join(uploadDir, "thumbnails") + if err := os.MkdirAll(thumbDir, 0755); err != nil { + return fmt.Errorf("failed to create thumbnails directory: %v", err) + } + + thumbPath := filepath.Join(thumbDir, filename+".jpg") + + // Use ffmpeg to grab a frame in the first 5s, resize width to 400px + cmd := exec.Command("ffmpeg", "-y", + "-ss", "00:00:05", // seek to 5s + "-i", videoPath, + "-vframes", "1", + "-vf", "scale=400:-1", + thumbPath, + ) + + cmd.Stdout = os.Stdout + cmd.Stderr = os.Stderr + + if err := cmd.Run(); err != nil { + // fallback: try frame 0 if grabbing at 5s fails + cmd := exec.Command("ffmpeg", "-y", + "-i", videoPath, + "-vframes", "1", + "-vf", "scale=400:-1", + thumbPath, + ) + cmd.Stdout = os.Stdout + cmd.Stderr = os.Stderr + if err2 := cmd.Run(); err2 != nil { + return fmt.Errorf("failed to generate thumbnail: %v", err2) + } + } + + return nil } \ No newline at end of file diff --git a/static/style.css b/static/style.css @@ -29,6 +29,8 @@ span#searchToggle{cursor:pointer;color:#add8e6;padding:8px} div.gallery-item a{overflow:hidden;text-overflow:ellipsis} div.gallery-item,div.gallery-item a,nav ul li,nav>ul>li{display:inline-block} div.gallery-item,div.gallery-item a{width:250px;display:inline-block} +div.play-button {position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); width: 0; height: 0; border-left: 15px solid white; border-top: 10px solid transparent; border-bottom: 10px solid transparent; opacity: 0.8;} +div.gallery-video {position: relative; display: inline-block; width: 150px; max-width: 100%;} /* descriptions */ div.description-section {margin: 20px 0; padding: 15px;} diff --git a/templates/_gallery.html b/templates/_gallery.html @@ -1,9 +1,9 @@ {{define "_gallery"}} <div class="gallery-item"> <a href="/file/{{.ID}}" title="{{.Filename}}"> - {{if hasAnySuffix .Filename ".jpg" ".jpeg" ".png" ".gif" ".webp"}}<img src="/uploads/{{.EscapedFilename}}" style="max-width:150px"><br /> - {{else if hasAnySuffix .Filename ".mp4" ".webm" ".mov"}}<video width="150" controls><source src="/uploads/{{.EscapedFilename}}"></video><br /> + {{if hasAnySuffix .Filename ".jpg" ".jpeg" ".png" ".gif" ".webp"}}<img src="/uploads/{{.EscapedFilename}}" style="max-width:150px"> + {{else if hasAnySuffix .Filename ".mp4" ".webm" ".mov"}}<div class="gallery-video"><img src="/uploads/thumbnails/{{.EscapedFilename}}.jpg" style="width: 100%; display: block;" /><div class="play-button"></div></div> {{end}} - {{.Filename}}</a> + <br>{{.Filename}}</a> </div> {{end}} \ No newline at end of file