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 }