Skip to content

Commit

Permalink
uptade encoding
Browse files Browse the repository at this point in the history
  • Loading branch information
sayem314 committed Sep 28, 2024
1 parent 35ebabe commit 93c87c8
Showing 1 changed file with 21 additions and 47 deletions.
68 changes: 21 additions & 47 deletions metadata/id3_tag.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,20 +11,17 @@ import (
"github.com/d-fi/GoFi/types"
)

// WriteMetadataMp3 writes metadata to an MP3 buffer and returns the updated buffer.
func WriteMetadataMp3(buffer []byte, track types.TrackType, album *types.AlbumTypePublicApi, cover []byte) ([]byte, error) {
logger.Debug("Starting MP3 metadata writing for track: %s", track.SNG_TITLE)

reader := bytes.NewReader(buffer)
tag, err := id3v2.ParseReader(reader, id3v2.Options{Parse: true})
var audioData []byte
if err != nil {
// If no existing tags, create a new tag
tag = id3v2.NewEmptyTag()
audioData = buffer
logger.Debug("No existing tags found, creating new tag")
} else {
// Extract audio data after tags
audioData, err = io.ReadAll(reader)
if err != nil {
logger.Debug("Failed to read audio data: %v", err)
Expand All @@ -33,40 +30,32 @@ func WriteMetadataMp3(buffer []byte, track types.TrackType, album *types.AlbumTy
logger.Debug("Existing tags found, extracted audio data")
}

// Set ID3 version to 2.4
tag.SetVersion(4)
// Set default encoding to UTF-16
tag.SetDefaultEncoding(id3v2.EncodingUTF16)
tag.SetDefaultEncoding(id3v2.EncodingUTF8)

// Set standard frames
tag.SetTitle(track.SNG_TITLE)
tag.SetAlbum(track.ALB_TITLE)
tag.SetArtist(strings.Join(processArtistNames(track.ARTISTS), "/"))
tag.AddTextFrame("TLEN", id3v2.EncodingUTF16, fmt.Sprintf("%d", track.DURATION*1000)) // TLEN expects milliseconds
tag.AddTextFrame("TSRC", id3v2.EncodingUTF16, track.ISRC)
tag.AddTextFrame("TLEN", id3v2.EncodingUTF8, fmt.Sprintf("%d", track.DURATION*1000))
tag.AddTextFrame("TSRC", id3v2.EncodingUTF8, track.ISRC)

// Set album metadata if available
if album != nil {
setAlbumMetadata(tag, album)
}

// Set additional frames
tag.AddTextFrame("TMED", id3v2.EncodingUTF16, "Digital Media")
tag.AddTextFrame("TMED", id3v2.EncodingUTF8, "Digital Media")
addUserTextFrame(tag, "SOURCE", "Deezer")
addUserTextFrame(tag, "SOURCEID", track.SNG_ID)

// Set track number and disc number if available
if track.DISK_NUMBER != 0 {
setTrackNumberFrames(tag, track, album)
}

// Set contributors metadata
setContributorsMetadata(tag, track, album)

// Set lyrics and explicit lyrics
if track.LYRICS != nil {
tag.AddUnsynchronisedLyricsFrame(id3v2.UnsynchronisedLyricsFrame{
Encoding: id3v2.EncodingUTF16,
Encoding: id3v2.EncodingUTF8,
Language: "eng",
Lyrics: track.LYRICS.LYRICS_TEXT,
})
Expand All @@ -75,33 +64,30 @@ func WriteMetadataMp3(buffer []byte, track types.TrackType, album *types.AlbumTy
addUserTextFrame(tag, "EXPLICIT", fmt.Sprintf("%t", *track.EXPLICIT_LYRICS))
}

// Add cover art if available
if cover != nil {
tag.AddAttachedPicture(id3v2.PictureFrame{
Encoding: id3v2.EncodingUTF16,
pic := id3v2.PictureFrame{
Encoding: id3v2.EncodingUTF8,
MimeType: "image/jpeg",
PictureType: id3v2.PTFrontCover,
PictureType: 3,
Description: "",
Picture: cover,
})
}
tag.AddAttachedPicture(pic)
logger.Debug("Added cover art to MP3 metadata")
}

// Write the tag to a new buffer
var newBuffer bytes.Buffer
if _, err := tag.WriteTo(&newBuffer); err != nil {
logger.Debug("Failed to write MP3 tags: %v", err)
return nil, err
}

// Append the audio data
newBuffer.Write(audioData)
logger.Debug("Completed MP3 metadata writing for track: %s", track.SNG_TITLE)

return newBuffer.Bytes(), nil
}

// processArtistNames splits artist names by slash, trims them, and joins with slash without spaces.
func processArtistNames(artists []types.ArtistType) []string {
var names []string
for _, artist := range artists {
Expand All @@ -116,9 +102,7 @@ func processArtistNames(artists []types.ArtistType) []string {
return names
}

// setAlbumMetadata sets album-related metadata frames.
func setAlbumMetadata(tag *id3v2.Tag, album *types.AlbumTypePublicApi) {
// Set genre(s) if available
if len(album.Genres.Data) > 0 {
var genres []string
for _, genre := range album.Genres.Data {
Expand All @@ -127,47 +111,41 @@ func setAlbumMetadata(tag *id3v2.Tag, album *types.AlbumTypePublicApi) {
tag.SetGenre(strings.Join(genres, ", "))
}

// Set recording year using TDRC and TYER
releaseDates := strings.Split(album.ReleaseDate, "-")
if len(releaseDates) >= 1 {
year := releaseDates[0]
tag.AddTextFrame("TDRC", id3v2.EncodingUTF16, year) // Recording year
tag.AddTextFrame("TYER", id3v2.EncodingUTF16, year) // Recording year for compatibility
tag.AddTextFrame("TDRC", id3v2.EncodingUTF8, year)
tag.AddTextFrame("TYER", id3v2.EncodingUTF8, year)
}
if len(releaseDates) >= 3 {
tag.AddTextFrame("TDAT", id3v2.EncodingUTF16, releaseDates[2]+releaseDates[1])
tag.AddTextFrame("TDAT", id3v2.EncodingUTF8, releaseDates[2]+releaseDates[1])
}

// Set album artist
tag.AddTextFrame("TPE2", id3v2.EncodingUTF16, album.Artist.Name)
tag.AddTextFrame("TPE2", id3v2.EncodingUTF8, album.Artist.Name)

// Set custom frames
addUserTextFrame(tag, "RELEASETYPE", album.RecordType)
addUserTextFrame(tag, "BARCODE", album.UPC)
addUserTextFrame(tag, "LABEL", album.Label)
addUserTextFrame(tag, "COMPILATION", ifMatchVarious(album.Artist.Name))
}

// setTrackNumberFrames sets TRCK and TPOS frames.
func setTrackNumberFrames(tag *id3v2.Tag, track types.TrackType, album *types.AlbumTypePublicApi) {
trackNumber := fmt.Sprintf("%02d", int(track.TRACK_NUMBER))
if album != nil {
totalTracks := fmt.Sprintf("%02d", album.NbTracks)
tag.AddTextFrame("TRCK", id3v2.EncodingUTF16, fmt.Sprintf("%s/%s", trackNumber, totalTracks))
tag.AddTextFrame("TRCK", id3v2.EncodingUTF8, fmt.Sprintf("%s/%s", trackNumber, totalTracks))
} else {
tag.AddTextFrame("TRCK", id3v2.EncodingUTF16, trackNumber)
tag.AddTextFrame("TRCK", id3v2.EncodingUTF8, trackNumber)
}
tag.AddTextFrame("TPOS", id3v2.EncodingUTF16, fmt.Sprintf("%d", int(track.DISK_NUMBER)))
tag.AddTextFrame("TPOS", id3v2.EncodingUTF8, fmt.Sprintf("%d", int(track.DISK_NUMBER)))
}

// setContributorsMetadata sets contributor-related metadata frames.
func setContributorsMetadata(tag *id3v2.Tag, track types.TrackType, album *types.AlbumTypePublicApi) {
contributors := track.SNG_CONTRIBUTORS
if contributors == nil {
return
}

// Set TCOP (Copyright)
if len(contributors.MainArtist) > 0 {
releaseYear := ""
if album != nil {
Expand All @@ -176,20 +154,18 @@ func setContributorsMetadata(tag *id3v2.Tag, track types.TrackType, album *types
releaseYear = releaseDates[0]
}
}
tag.AddTextFrame("TCOP", id3v2.EncodingUTF16, fmt.Sprintf("%s %s", releaseYear, contributors.MainArtist[0]))
tag.AddTextFrame("TCOP", id3v2.EncodingUTF8, fmt.Sprintf("%s %s", releaseYear, contributors.MainArtist[0]))
}

// Set other contributor frames
addContributorsFrames(tag, contributors)
}

// addContributorsFrames adds various contributor frames.
func addContributorsFrames(tag *id3v2.Tag, contributors *types.SongContributors) {
if len(contributors.Publisher) > 0 {
tag.AddTextFrame("TPUB", id3v2.EncodingUTF16, strings.Join(contributors.Publisher, ", "))
tag.AddTextFrame("TPUB", id3v2.EncodingUTF8, strings.Join(contributors.Publisher, "/"))
}
if len(contributors.Composer) > 0 {
tag.AddTextFrame("TCOM", id3v2.EncodingUTF16, strings.Join(contributors.Composer, "/"))
tag.AddTextFrame("TCOM", id3v2.EncodingUTF8, strings.Join(contributors.Composer, "/"))
}
if len(contributors.Writer) > 0 {
addUserTextFrame(tag, "LYRICIST", strings.Join(contributors.Writer, "/"))
Expand All @@ -206,18 +182,16 @@ func addContributorsFrames(tag *id3v2.Tag, contributors *types.SongContributors)
}
}

// ifMatchVarious returns "1" if artist name contains "various", else "0".
func ifMatchVarious(artistName string) string {
if strings.Contains(strings.ToLower(artistName), "various") {
return "1"
}
return "0"
}

// addUserTextFrame adds a TXXX frame with the given description and value.
func addUserTextFrame(tag *id3v2.Tag, description, value string) {
tag.AddUserDefinedTextFrame(id3v2.UserDefinedTextFrame{
Encoding: id3v2.EncodingUTF16,
Encoding: id3v2.EncodingUTF8,
Description: description,
Value: value,
})
Expand Down

0 comments on commit 93c87c8

Please sign in to comment.