LabCodeHub öffentliche Ansicht
Anmelden
Küpper / ehc-tvwall öffentlich
Branch: main
ehc-tvwall / internal / web / thumb.go
Verlauf Rohdaten
R Rüdiger Küpper fix: v1.0.0
14518d05 vor 11 Tagen
internal/web/thumb.go 79 Zeilen · 1.8 KB · Go
1
package web
2
3
import (
4
	"bytes"
5
	"context"
6
	"fmt"
7
	"os"
8
	"os/exec"
9
	"path/filepath"
10
	"time"
11
)
12
13
type diskInfo struct {
14
	Free  int64 `json:"free"`
15
	Total int64 `json:"total"`
16
}
17
18
// makeThumb erzeugt mit ffmpeg ein Vorschaubild. Bei Videos wird ein Einzelbild
19
// aus der ersten Sekunde genommen.
20
func makeThumb(src, dst, kind string) error {
21
	if err := os.MkdirAll(filepath.Dir(dst), 0o775); err != nil {
22
		return err
23
	}
24
	tmp := dst + ".tmp.jpg"
25
	defer os.Remove(tmp)
26
27
	ctx, cancel := context.WithTimeout(context.Background(), 60*time.Second)
28
	defer cancel()
29
30
	seek := "1"
31
	if kind != "video" {
32
		seek = ""
33
	}
34
	err := runFFmpeg(ctx, src, tmp, seek)
35
	if err != nil && seek != "" {
36
		// Sehr kurze Videos haben nach einer Sekunde nichts mehr: von vorne.
37
		err = runFFmpeg(ctx, src, tmp, "")
38
	}
39
	if err != nil {
40
		return err
41
	}
42
	return os.Rename(tmp, dst)
43
}
44
45
// convertToJPEG wandelt ein Standbild (etwa HEIC vom iPhone) in JPEG um.
46
func convertToJPEG(src, dst string) error {
47
	ctx, cancel := context.WithTimeout(context.Background(), 120*time.Second)
48
	defer cancel()
49
	out, err := exec.CommandContext(ctx, "ffmpeg",
50
		"-nostdin", "-loglevel", "error", "-y",
51
		"-i", src,
52
		"-frames:v", "1",
53
		"-q:v", "2",
54
		"-f", "image2", dst,
55
	).CombinedOutput()
56
	if err != nil {
57
		return fmt.Errorf("ffmpeg: %v: %s", err, bytes.TrimSpace(out))
58
	}
59
	return nil
60
}
61
62
func runFFmpeg(ctx context.Context, src, dst, seek string) error {
63
	args := []string{"-nostdin", "-loglevel", "error", "-y"}
64
	if seek != "" {
65
		args = append(args, "-ss", seek)
66
	}
67
	args = append(args,
68
		"-i", src,
69
		"-frames:v", "1",
70
		"-vf", "scale=480:-2:force_original_aspect_ratio=decrease",
71
		"-q:v", "5",
72
		dst,
73
	)
74
	out, err := exec.CommandContext(ctx, "ffmpeg", args...).CombinedOutput()
75
	if err != nil {
76
		return fmt.Errorf("ffmpeg: %v: %s", err, bytes.TrimSpace(out))
77
	}
78
	return nil
79
}