147 lines
2.6 KiB
Go
147 lines
2.6 KiB
Go
package metadata
|
|
|
|
import (
|
|
"log/slog"
|
|
"os"
|
|
"strconv"
|
|
|
|
"github.com/go-flac/flacvorbis/v2"
|
|
"github.com/go-flac/go-flac/v2"
|
|
)
|
|
|
|
func readVorbisMetadata(file string) (*Metadata, error) {
|
|
f, err := os.Open(file)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
defer f.Close()
|
|
|
|
flacFile, err := flac.ParseMetadata(f)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
cmt, err := findVobisMetadata(*flacFile)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
titles, err := cmt.Get(flacvorbis.FIELD_TITLE)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
var title *string
|
|
if len(titles) > 0 {
|
|
title = &titles[0]
|
|
}
|
|
|
|
albums, err := cmt.Get(flacvorbis.FIELD_ALBUM)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
var album *string
|
|
if len(albums) > 0 {
|
|
album = &albums[0]
|
|
}
|
|
|
|
artists, err := cmt.Get(flacvorbis.FIELD_ARTIST)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
albumArtists, err := cmt.Get("ALBUMARTIST")
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
comments, err := cmt.Get("COMMENT")
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
var comment *string
|
|
if len(comments) > 0 {
|
|
comment = &comments[0]
|
|
}
|
|
|
|
metadata := &Metadata{
|
|
Title: title,
|
|
Artist: artists,
|
|
Album: album,
|
|
AlbumArtist: albumArtists,
|
|
Comment: comment,
|
|
}
|
|
|
|
return metadata, nil
|
|
}
|
|
|
|
func findVobisMetadata(f flac.File) (*flacvorbis.MetaDataBlockVorbisComment, error) {
|
|
for _, meta := range f.Meta {
|
|
if meta.Type == flac.VorbisComment {
|
|
return flacvorbis.ParseFromMetaDataBlock(*meta)
|
|
}
|
|
}
|
|
|
|
return nil, nil
|
|
}
|
|
|
|
func updateFlacMetadata(m Metadata, input, output string) error {
|
|
f, err := flac.ParseFile(input)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
vorbisMeta := createVorbisMetaBlock(m)
|
|
meta := vorbisMeta.Marshal()
|
|
|
|
replaced := false
|
|
for i, block := range f.Meta {
|
|
if block.Type == flac.VorbisComment {
|
|
f.Meta[i] = &meta
|
|
replaced = true
|
|
break
|
|
}
|
|
}
|
|
|
|
if !replaced {
|
|
f.Meta = append(f.Meta, &meta)
|
|
}
|
|
|
|
return f.Save(output)
|
|
}
|
|
|
|
func createVorbisMetaBlock(m Metadata) flacvorbis.MetaDataBlockVorbisComment {
|
|
vorbisMeta := flacvorbis.New()
|
|
|
|
if m.Title != nil {
|
|
vorbisMeta.Add(flacvorbis.FIELD_TITLE, *m.Title)
|
|
}
|
|
|
|
if m.Album != nil {
|
|
vorbisMeta.Add(flacvorbis.FIELD_ALBUM, *m.Album)
|
|
}
|
|
|
|
if m.Comment != nil {
|
|
vorbisMeta.Add("COMMENT", *m.Comment)
|
|
}
|
|
|
|
if m.Track != 0 {
|
|
vorbisMeta.Add("TRACKNUMBER", strconv.Itoa(m.Track))
|
|
}
|
|
|
|
if m.TotalTracks != 0 {
|
|
vorbisMeta.Add("TOTALTRACKS", strconv.Itoa(m.TotalTracks))
|
|
}
|
|
|
|
for _, artist := range m.Artist {
|
|
vorbisMeta.Add(flacvorbis.FIELD_ARTIST, artist)
|
|
slog.Debug("Added ARTIST filed to metadata", "artist", artist)
|
|
}
|
|
|
|
for _, albumArtist := range m.AlbumArtist {
|
|
vorbisMeta.Add("ALBUMARTIST", albumArtist)
|
|
}
|
|
|
|
return *vorbisMeta
|
|
}
|