Files
ffmpeg-gui/internal/media/info.go
T

72 lines
1.9 KiB
Go
Raw Normal View History

2026-07-29 02:17:57 +08:00
package media
import (
"encoding/json"
"ffmpeg-gui/internal/ffmpeg"
"fmt"
)
2026-07-29 19:33:46 +08:00
// StreamTags holds tag metadata from ffprobe's nested JSON output.
type StreamTags struct {
Language string `json:"language"`
Title string `json:"title"`
}
2026-07-29 02:17:57 +08:00
// StreamInfo holds information about a single stream.
type StreamInfo struct {
2026-07-29 19:33:46 +08:00
Index int `json:"index"`
CodecType string `json:"codec_type"`
CodecName string `json:"codec_name"`
Width int `json:"width,omitempty"`
Height int `json:"height,omitempty"`
Duration string `json:"duration,omitempty"`
BitRate string `json:"bit_rate,omitempty"`
FPS string `json:"r_frame_rate,omitempty"`
Tags StreamTags `json:"tags"`
2026-07-29 02:17:57 +08:00
}
// FormatInfo holds container format information.
type FormatInfo struct {
Filename string `json:"filename"`
Format string `json:"format_name"`
Duration string `json:"duration,omitempty"`
Size string `json:"size,omitempty"`
BitRate string `json:"bit_rate,omitempty"`
}
// MediaInfo is the top-level ffprobe result.
type MediaInfo struct {
Streams []StreamInfo `json:"streams"`
Format FormatInfo `json:"format"`
}
// GetInfo runs ffprobe and returns parsed media information.
func GetInfo(exec *ffmpeg.Executor, inputFile string) (*MediaInfo, error) {
out, err := exec.Probe(
"-v", "quiet",
"-print_format", "json",
"-show_format",
"-show_streams",
inputFile,
)
if err != nil {
return nil, fmt.Errorf("ffprobe: %w (output: %s)", err, out)
}
var info MediaInfo
if err := json.Unmarshal([]byte(out), &info); err != nil {
return nil, fmt.Errorf("parse ffprobe json: %w", err)
}
return &info, nil
}
// GetDurationSeconds returns the duration in seconds as a float64.
func (mi *MediaInfo) GetDurationSeconds() float64 {
if mi.Format.Duration == "" {
return 0
}
var secs float64
fmt.Sscanf(mi.Format.Duration, "%f", &secs)
return secs
}