Files
godeez/internal/tag/flac.go
T

96 lines
2.6 KiB
Go

package tag
import (
"os"
"strings"
"github.com/go-flac/flacpicture/v2"
"github.com/go-flac/flacvorbis/v2"
"github.com/go-flac/go-flac/v2"
)
type flacTagger struct {
file *flac.File
cmts *flacvorbis.MetaDataBlockVorbisComment
index int
path string
}
func (t *flacTagger) write(m Metadata) error {
if m.Album != nil {
date := m.Album.ReleaseDate
if parts := strings.Split(date, "-"); len(parts) == 3 {
date = parts[0]
}
t.addTag("TRACKNUMBER", m.TrackNumber)
t.addTag("ALBUMARTIST", m.Album.Artist)
t.addTag("ALBUM", m.Album.Title)
t.addTag("PUBLISHER", m.Album.Label)
t.addTag("ORIGINALDATE", m.Album.OriginalReleaseDate)
t.addTag("DATE", date)
t.addTag("COMMENT", m.Album.ProducerLine)
t.addTag("COPYRIGHT", m.Album.Copyright)
}
t.addTag("ARTIST", m.Artists)
t.addTag("TITLE", m.Title)
t.addTag("COMPOSER", m.Composers)
t.addTag("LYRICIST", m.Lyricists)
t.addTag("GENRE", m.Genre)
t.addTag("REPLAYGAIN_TRACK_GAIN", m.Gain)
t.addTag("ISRC", m.ISRC)
t.addTag("BPM", m.BPM)
t.addTag("KEY", m.Key)
t.addTag("INITIALKEY", m.Key)
cmtsMeta := t.cmts.Marshal()
// index 0 means no comment block was found: a valid flac always starts
// with STREAMINFO, so a real Vorbis comment can never be the first block.
// Anything else is the index of the block being replaced.
if t.index > 0 {
t.file.Meta[t.index] = &cmtsMeta
} else {
t.file.Meta = append(t.file.Meta, &cmtsMeta)
}
if len(m.Cover) > 0 {
if picture, err := flacpicture.NewFromImageData(flacpicture.PictureTypeFrontCover, "Front cover", m.Cover, "image/jpeg"); err == nil {
pictureMeta := picture.Marshal()
t.file.Meta = append(t.file.Meta, &pictureMeta)
}
}
tmpPath := t.path + ".tmp"
if err := t.file.Save(tmpPath); err != nil {
os.Remove(tmpPath)
return err
}
return os.Rename(tmpPath, t.path)
}
// addTag appends a Vorbis comment. Vorbis allows repeated keys, so this adds
// to whatever the file already had rather than replacing it; re-tagging a
// file that was already tagged would therefore duplicate entries. That does
// not arise in practice because godeez only tags files it just downloaded.
//
// The key is written twice for the musical key: KEY is the common spelling
// and INITIALKEY is what several DJ applications look for.
func (t *flacTagger) addTag(name, value string) {
if value != "" {
t.cmts.Add(name, value)
}
}
func extractFLACComment(file *flac.File) (*flacvorbis.MetaDataBlockVorbisComment, int) {
for idx, meta := range file.Meta {
if meta.Type == flac.VorbisComment {
cmt, err := flacvorbis.ParseFromMetaDataBlock(*meta)
if err == nil {
return cmt, idx
}
}
}
return nil, 0
}