diff --git a/internal/app/transcode.go b/internal/app/transcode.go new file mode 100644 index 0000000..42fa97e --- /dev/null +++ b/internal/app/transcode.go @@ -0,0 +1,37 @@ +package app + +import ( + "fmt" + "os" + "os/exec" +) + +// ffmpegArgs builds the transcode command line: FLAC -> 128k 44.1kHz stereo +// MP3 with ID3v2.3 + ID3v1 tags so even old stereo displays show the title. +func ffmpegArgs(src, dst, bitrate, title, album string) []string { + return []string{ + "-y", "-hide_banner", "-loglevel", "error", + "-i", src, + "-metadata", "title=" + title, + "-metadata", "album=" + album, + "-codec:a", "libmp3lame", + "-b:a", bitrate, + "-ar", "44100", + "-ac", "2", + "-id3v2_version", "3", + "-write_id3v1", "1", + dst, + } +} + +// Transcode runs ffmpeg src -> dst. dst is written atomically via a temp file. +func Transcode(src, dst, bitrate, title, album string) error { + tmp := dst + ".tmp.mp3" // keep .mp3 suffix so ffmpeg can detect the muxer + args := ffmpegArgs(src, tmp, bitrate, title, album) + cmd := exec.Command("ffmpeg", args...) + if out, err := cmd.CombinedOutput(); err != nil { + os.Remove(tmp) + return fmt.Errorf("ffmpeg %s: %w: %s", src, err, out) + } + return os.Rename(tmp, dst) +}