Use ffprobe json parsing for thumbnail video info

This commit is contained in:
Stu Leak 2025-12-17 17:03:08 -05:00
parent 799102cac7
commit eff752a97c

View File

@ -151,7 +151,7 @@ func (g *Generator) getVideoInfo(ctx context.Context, videoPath string) (duratio
"-select_streams", "v:0", "-select_streams", "v:0",
"-show_entries", "stream=width,height,duration", "-show_entries", "stream=width,height,duration",
"-show_entries", "format=duration", "-show_entries", "format=duration",
"-of", "default=noprint_wrappers=1", "-of", "json",
videoPath, videoPath,
) )
@ -160,18 +160,47 @@ func (g *Generator) getVideoInfo(ctx context.Context, videoPath string) (duratio
return 0, 0, 0, fmt.Errorf("ffprobe failed: %w", err) return 0, 0, 0, fmt.Errorf("ffprobe failed: %w", err)
} }
// Parse output // Parse JSON for robust extraction
var w, h int type streamInfo struct {
var d float64 Width int `json:"width"`
_, _ = fmt.Sscanf(string(output), "width=%d\nheight=%d\nduration=%f", &w, &h, &d) Height int `json:"height"`
Duration string `json:"duration"`
// If stream duration not available, try format duration }
if d == 0 { type formatInfo struct {
_, _ = fmt.Sscanf(string(output), "width=%d\nheight=%d\nwidth=%*d\nheight=%*d\nduration=%f", &w, &h, &d) Duration string `json:"duration"`
}
type ffprobeResp struct {
Streams []streamInfo `json:"streams"`
Format formatInfo `json:"format"`
} }
if w == 0 || h == 0 || d == 0 { var resp ffprobeResp
return 0, 0, 0, fmt.Errorf("failed to parse video info") if err := json.Unmarshal(output, &resp); err != nil {
return 0, 0, 0, fmt.Errorf("failed to parse ffprobe json: %w", err)
}
var w, h int
var d float64
if len(resp.Streams) > 0 {
w = resp.Streams[0].Width
h = resp.Streams[0].Height
if resp.Streams[0].Duration != "" {
if val, err := strconv.ParseFloat(resp.Streams[0].Duration, 64); err == nil {
d = val
}
}
}
if d == 0 && resp.Format.Duration != "" {
if val, err := strconv.ParseFloat(resp.Format.Duration, 64); err == nil {
d = val
}
}
if w == 0 || h == 0 {
return 0, 0, 0, fmt.Errorf("failed to parse video info (missing width/height)")
}
if d == 0 {
return 0, 0, 0, fmt.Errorf("failed to parse video info (missing duration)")
} }
return d, w, h, nil return d, w, h, nil