Files
filebrozer/files/write_mp3.go

67 lines
1.5 KiB
Go

package files
import (
"fmt"
"strings"
id3v2 "github.com/bogem/id3v2/v2"
)
// applyMP3Tags writes only the provided non-empty tags to the MP3 file at
// realPath. It preserves existing frames when not overwritten.
func applyMP3Tags(realPath string, tags map[string]string) error {
// Open tag for read/write
tag, err := id3v2.Open(realPath, id3v2.Options{Parse: true})
if err != nil {
return fmt.Errorf("open id3v2: %w", err)
}
defer tag.Close()
// Helper to set a text frame (replace existing)
setFrame := func(frameID, value string) {
if strings.TrimSpace(value) == "" {
return
}
tag.DeleteAllFrames(frameID)
tag.AddTextFrame(frameID, tag.DefaultEncoding(), value)
}
for k, v := range tags {
if strings.TrimSpace(v) == "" {
continue
}
switch strings.ToLower(k) {
case "title":
setFrame("TIT2", v)
case "artist":
setFrame("TPE1", v)
case "album":
setFrame("TALB", v)
case "albumartist", "album artist":
setFrame("TPE2", v)
case "composer":
setFrame("TCOM", v)
case "year", "date":
setFrame("TDRC", v)
case "track":
setFrame("TRCK", v)
case "disc":
setFrame("TPOS", v)
case "genre":
setFrame("TCON", v)
default:
// write custom text frame under TXXX with description = key
// Use description to store the original key so we don't collide
// with standard frames.
// Note: bogem/id3v2 uses AddTextFrame for TXXX as well.
tag.AddTextFrame("TXXX", tag.DefaultEncoding(), v)
}
}
if err := tag.Save(); err != nil {
return fmt.Errorf("save id3v2: %w", err)
}
return nil
}