Foundation: config, schema/migrations, auth, stable IDs, metadata probing

This commit is contained in:
2026-08-22 23:29:16 -05:00
commit d4ea7a4ca9
40 changed files with 3874 additions and 0 deletions
+69
View File
@@ -0,0 +1,69 @@
package metadata
import (
"context"
"encoding/json"
"fmt"
"os/exec"
)
type ffprobeOutput struct {
Format ffprobeFormat `json:"format"`
Streams []ffprobeStream `json:"streams"`
}
type ffprobeFormat struct {
FormatName string `json:"format_name"`
Duration string `json:"duration"`
BitRate string `json:"bit_rate"`
Tags map[string]string `json:"tags"`
}
type ffprobeStream struct {
Index int `json:"index"`
CodecType string `json:"codec_type"` // "audio", "video", "subtitle", ...
CodecName string `json:"codec_name"`
SampleRate string `json:"sample_rate"`
Channels int `json:"channels"`
Duration string `json:"duration"`
BitRate string `json:"bit_rate"`
Disposition map[string]int `json:"disposition"`
Tags map[string]string `json:"tags"`
}
// Prober runs ffprobe to extract tags and technical properties from a
// media file.
type Prober struct {
FFprobePath string
}
// Probe reads metadata from the file at path. path must already be a
// validated, absolute filesystem path within a configured music
// folder — Probe does not perform any authorization or traversal checks
// itself.
func (p *Prober) Probe(ctx context.Context, path string) (*Tags, error) {
ffprobePath := p.FFprobePath
if ffprobePath == "" {
ffprobePath = "ffprobe"
}
cmd := exec.CommandContext(ctx, ffprobePath,
"-v", "error",
"-print_format", "json",
"-show_format",
"-show_streams",
"--", path,
)
out, err := cmd.Output()
if err != nil {
if ee, ok := err.(*exec.ExitError); ok {
return nil, fmt.Errorf("ffprobe: %w: %s", err, string(ee.Stderr))
}
return nil, fmt.Errorf("ffprobe: %w", err)
}
var raw ffprobeOutput
if err := json.Unmarshal(out, &raw); err != nil {
return nil, fmt.Errorf("parsing ffprobe output: %w", err)
}
return parseFFprobeOutput(raw), nil
}