Files
filebrozer/http/id3_clear.go

118 lines
3.4 KiB
Go

package fbhttp
import (
"strings"
"unicode"
id3v2 "github.com/bogem/id3v2/v2"
)
// clearID3v2Frames removes specific ID3v2 frames from an MP3 file.
// frames: list of standard frame IDs (e.g., TIT2, TPE1, TPE2, TRCK, TPOS, TCON, TDRC, COMM, USLT)
// txxxDescs: list of UserDefinedText (TXXX) descriptions to remove (e.g., "Artists", "AlbumArtists").
func clearID3v2Frames(path string, frames []string, txxxDescs []string, removeNumericEmpty bool) error {
tag, err := id3v2.Open(path, id3v2.Options{Parse: true})
if err != nil {
return err
}
defer tag.Close()
// Delete standard frames
for _, id := range frames {
tag.DeleteFrames(id)
}
// Delete matching TXXX frames by description (preserve others)
if len(txxxDescs) > 0 {
fs := tag.GetFrames("TXXX")
keep := []id3v2.UserDefinedTextFrame{}
for _, f := range fs {
udf, ok := f.(id3v2.UserDefinedTextFrame)
if !ok {
continue
}
remove := false
for _, d := range txxxDescs {
if strings.EqualFold(udf.Description, d) {
remove = true
break
}
}
if !remove && removeNumericEmpty {
desc := strings.TrimSpace(udf.Description)
if desc == "" {
remove = true
} else {
// numeric-only descriptions like "0", "1", "2"
allDigits := true
for _, r := range desc {
if !unicode.IsDigit(r) {
allDigits = false
break
}
}
if allDigits {
remove = true
}
}
}
if !remove {
keep = append(keep, udf)
}
}
// Remove all TXXX frames, then re-add the ones we keep
tag.DeleteFrames("TXXX")
for _, udf := range keep {
tag.AddFrame("TXXX", udf)
}
}
return tag.Save()
}
// cleanupNumericEmptyTXXX removes any TXXX frames whose descriptions are empty
// or purely numeric (e.g., "0", "1", "2"…), which are common artifacts.
func cleanupNumericEmptyTXXX(path string) error {
tag, err := id3v2.Open(path, id3v2.Options{Parse: true})
if err != nil {
return err
}
defer tag.Close()
fs := tag.GetFrames("TXXX")
keep := []id3v2.UserDefinedTextFrame{}
for _, f := range fs {
udf, ok := f.(id3v2.UserDefinedTextFrame)
if !ok {
continue
}
desc := strings.TrimSpace(udf.Description)
remove := false
if desc == "" {
remove = true
} else {
allDigits := true
for _, r := range desc {
if !unicode.IsDigit(r) {
allDigits = false
break
}
}
if allDigits {
remove = true
}
}
if !remove {
keep = append(keep, udf)
}
}
// If nothing to change, return early
if len(keep) == len(fs) {
return nil
}
tag.DeleteFrames("TXXX")
for _, udf := range keep {
tag.AddFrame("TXXX", udf)
}
return tag.Save()
}