package backend import ( "fmt" "os" "strconv" "github.com/go-flac/flacpicture" "github.com/go-flac/flacvorbis" "github.com/go-flac/go-flac" ) type Metadata struct { Title string Artist string Album string Date string TrackNumber int DiscNumber int ISRC string } func EmbedMetadata(filepath string, metadata Metadata, coverPath string) error { f, err := flac.ParseFile(filepath) if err != nil { return fmt.Errorf("failed to parse FLAC file: %w", err) } var cmtIdx = -1 for idx, block := range f.Meta { if block.Type == flac.VorbisComment { cmtIdx = idx break } } cmt := flacvorbis.New() if metadata.Title != "" { _ = cmt.Add(flacvorbis.FIELD_TITLE, metadata.Title) } if metadata.Artist != "" { _ = cmt.Add(flacvorbis.FIELD_ARTIST, metadata.Artist) } if metadata.Album != "" { _ = cmt.Add(flacvorbis.FIELD_ALBUM, metadata.Album) } if metadata.Date != "" { _ = cmt.Add(flacvorbis.FIELD_DATE, metadata.Date) } if metadata.TrackNumber > 0 { _ = cmt.Add(flacvorbis.FIELD_TRACKNUMBER, strconv.Itoa(metadata.TrackNumber)) } if metadata.DiscNumber > 0 { _ = cmt.Add("DISCNUMBER", strconv.Itoa(metadata.DiscNumber)) } if metadata.ISRC != "" { _ = cmt.Add(flacvorbis.FIELD_ISRC, metadata.ISRC) } cmtBlock := cmt.Marshal() if cmtIdx < 0 { f.Meta = append(f.Meta, &cmtBlock) } else { f.Meta[cmtIdx] = &cmtBlock } if coverPath != "" && fileExists(coverPath) { if err := embedCoverArt(f, coverPath); err != nil { fmt.Printf("Warning: Failed to embed cover art: %v\n", err) } } if err := f.Save(filepath); err != nil { return fmt.Errorf("failed to save FLAC file: %w", err) } return nil } func embedCoverArt(f *flac.File, coverPath string) error { imgData, err := os.ReadFile(coverPath) if err != nil { return fmt.Errorf("failed to read cover image: %w", err) } picture, err := flacpicture.NewFromImageData( flacpicture.PictureTypeFrontCover, "Cover", imgData, "image/jpeg", ) if err != nil { return fmt.Errorf("failed to create picture block: %w", err) } pictureBlock := picture.Marshal() for i := len(f.Meta) - 1; i >= 0; i-- { if f.Meta[i].Type == flac.Picture { f.Meta = append(f.Meta[:i], f.Meta[i+1:]...) } } f.Meta = append(f.Meta, &pictureBlock) return nil } func fileExists(path string) bool { _, err := os.Stat(path) return err == nil }