118 lines
3.4 KiB
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()
|
|
}
|