Phase 5: scaffold Crucible (sow-tools) — dispatcher + builder shims, container, PR-first CI, fail-closed (D11, D19).

This commit is contained in:
2026-06-11 20:36:13 +02:00
parent ff264f0d7c
commit 97f8427c4b
154 changed files with 948 additions and 76902 deletions
-62
View File
@@ -1,62 +0,0 @@
package music
import (
"encoding/json"
"fmt"
"os/exec"
"strings"
)
func ProbeMetadata(ffprobePath, sourcePath string) (Metadata, error) {
cmd := exec.Command(ffprobePath, "-v", "quiet", "-print_format", "json", "-show_format", sourcePath)
output, err := cmd.Output()
if err != nil {
return Metadata{}, err
}
var payload struct {
Format struct {
Tags map[string]string `json:"tags"`
} `json:"format"`
}
if err := json.Unmarshal(output, &payload); err != nil {
return Metadata{}, err
}
tags := make(map[string]string, len(payload.Format.Tags))
for key, value := range payload.Format.Tags {
tags[strings.ToLower(strings.TrimSpace(key))] = strings.TrimSpace(value)
}
return Metadata{
Title: FirstNonEmpty(tags["title"]),
Artist: FirstNonEmpty(tags["artist"], tags["album_artist"], tags["composer"]),
Album: FirstNonEmpty(tags["album"]),
Date: FirstNonEmpty(tags["date"], tags["year"]),
Comment: FirstNonEmpty(tags["comment"], tags["description"]),
Copyright: FirstNonEmpty(tags["copyright"]),
License: FirstNonEmpty(tags["license"], tags["license_url"]),
}, nil
}
func ConvertSource(ffmpegPath, sourcePath, outputPath string) error {
cmd := exec.Command(
ffmpegPath, "-y",
"-i", sourcePath,
"-vn",
"-map_metadata", "-1",
"-ar", "44100",
"-ac", "2",
"-b:a", "192k",
"-codec:a", "libmp3lame",
"-write_xing", "0",
"-f", "mp3",
outputPath,
)
output, err := cmd.CombinedOutput()
if err != nil {
message := strings.TrimSpace(string(output))
if message == "" {
message = err.Error()
}
return fmt.Errorf("%s", message)
}
return nil
}