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 } if len(artists) == 1 { artists = parseSeperatedTag(artists[0]) } albumArtists, err := cmt.Get("ALBUMARTIST") if err != nil { return nil, err } if len(albumArtists) == 1 { albumArtists = parseSeperatedTag(albumArtists[0]) } comments, err := cmt.Get("COMMENT") if err != nil { return nil, err } var comment *string if len(comments) > 0 { comment = &comments[0] } isrcs, err := cmt.Get("ISRC") if err != nil { return nil, err } var isrc *string if len(isrcs) > 0 { isrc = &isrcs[0] } dates, err := cmt.Get("DATE") if err != nil { return nil, err } var date *string if len(dates) > 0 { date = &dates[0] } metadata := &Metadata{ Title: title, Artist: artists, Album: album, AlbumArtist: albumArtists, Comment: comment, Date: date, ISRC: isrc, } 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)) } if m.ISRC != nil { vorbisMeta.Add("ISRC", *m.ISRC) } if m.Date != nil { vorbisMeta.Add("DATE", *m.Date) } 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 }