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
}