Use ffprobe json parsing for thumbnail video info
This commit is contained in:
parent
799102cac7
commit
eff752a97c
|
|
@ -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
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user