package artwork import ( "bytes" "context" "crypto/sha1" "fmt" "os" "os/exec" "path/filepath" "strconv" "strings" ) func sha1sum(data []byte) []byte { sum := sha1.Sum(data) return sum[:] } func execCommandContext(ctx context.Context, name string, args ...string) *exec.Cmd { return exec.CommandContext(ctx, name, args...) } func Optimize(ctx context.Context, src string, maxPx int, quality int, outPath string) (int64, error) { if maxPx <= 0 { maxPx = 1000 } if quality <= 0 { quality = 85 } if err := os.MkdirAll(filepath.Dir(outPath), 0o755); err != nil { return 0, err } args := []string{ src, "-resize", fmt.Sprintf("%dx%d>", maxPx, maxPx), "-strip", "-interlace", "Plane", "-quality", strconv.Itoa(quality), outPath, } var errb bytes.Buffer cmd := execCommandContext(ctx, "magick", args...) cmd.Stderr = &errb if err := cmd.Run(); err != nil { return 0, fmt.Errorf("optimising cover: %s", strings.TrimSpace(errb.String())) } info, err := os.Stat(outPath) if err != nil { return 0, err } return info.Size(), nil } func Embed(ctx context.Context, audioPath, imagePath string) error { clear := execCommandContext(ctx, "metaflac", "--remove", "--block-type=PICTURE", audioPath) if out, err := clear.CombinedOutput(); err != nil { return fmt.Errorf("clearing existing art in %s: %s", filepath.Base(audioPath), strings.TrimSpace(string(out))) } cmd := execCommandContext(ctx, "metaflac", "--import-picture-from="+imagePath, audioPath) if out, err := cmd.CombinedOutput(); err != nil { return fmt.Errorf("embedding cover in %s: %s", filepath.Base(audioPath), strings.TrimSpace(string(out))) } return nil }