Browse Source

◎ Improved handling of frames in v2tag! ◎

main
Unbewohnte 3 years ago
parent
commit
22c13255a5
  1. 13
      README.md
  2. BIN
      testData/testwritev1.mp3
  3. 29
      v2/frame_identifiers.go
  4. 24
      v2/frame_identifiers_test.go
  5. 8
      v2/read.go
  6. 10
      v2/read_test.go
  7. 65
      v2/v2tag.go

13
README.md

@ -119,15 +119,12 @@ func main() {
panic(err) panic(err)
} }
if mp3tag.Header.Version == id3v2.V2_3 { // you can get some essential frames` contents from getters
// get certain frame by identifier. title := tag.Title() // string
// Contents is []byte. CAN AND PROBABLY WILL
// CONTAIN NULL OR OTHER NON-PRINTABLE BYTES !!!
// Text encoding support is still not implemented.
title := mp3tag.Frames["TIT2"].Contents
artist := mp3tag.Frames["TPE1"].Contents
}
// or get direct frame by id
commentFrame := tag.GetFrame("COMM") // *Frame
// commentFrame.(Header.(...)|Contents)
// etc. // etc.
} }

BIN
testData/testwritev1.mp3

Binary file not shown.

29
v2/frame_identifiers.go

@ -2,7 +2,7 @@ package v2
// from [https://id3.org/] // from [https://id3.org/]
var V2_2FrameIdentifiers = map[string]string{ var V2_2FrameIdentifiers = map[string]string{
"BUF": "Recommended buffer size", "BUF": "Recommended buffer size",
"CNT": "Play counter", "CNT": "Play counter",
"COM": "Comments", "COM": "Comments",
@ -232,3 +232,30 @@ var V2_4FrameIdentifiers = map[string]string{
"WPUB": "Publishers official webpage", "WPUB": "Publishers official webpage",
"WXXX": "User defined URL link frame", "WXXX": "User defined URL link frame",
} }
// Searches for given ID3v2 frame identifier and returns its
// description if found, else returns a ""
func GetFIdentifierDescription(id string) string {
if len(id) == 3 {
// ID3v2.2.0 identifier
description, ok := V2_2FrameIdentifiers[id]
if !ok {
return ""
}
return description
} else if len(id) == 4 {
// ID3v2.(3|4).0 identifier
description, ok := V2_3FrameIdentifiers[id]
if !ok {
// not in v3, search in v4
description, ok = V2_4FrameIdentifiers[id]
if !ok {
return ""
}
}
return description
}
return ""
}

24
v2/frame_identifiers_test.go

@ -0,0 +1,24 @@
package v2
import "testing"
func Test_GetFIdentifierDescription(t *testing.T) {
description := GetFIdentifierDescription("TIT2")
if description != "Title/songname/content description" {
t.Errorf("GetFIdentifierDescription failed: expected description for TIT2 to be %s, got %s",
"Title/songname/content description", description)
}
description = GetFIdentifierDescription("TBP")
if description != "BPM (Beats Per Minute)" {
t.Errorf("GetFIdentifierDescription failed: expected description for TBP to be %s, got %s",
"BPM (Beats Per Minute)", description)
}
description = GetFIdentifierDescription("SomeInvalidFrameIDName")
if description != "" {
t.Errorf("GetFIdentifierDescription failed: expected description for SomeInvalidFrameIDName to be \"\", got %s",
description)
}
}

8
v2/read.go

@ -34,14 +34,8 @@ func ReadV2Tag(rs io.ReadSeeker) (*ID3v2Tag, error) {
frames = append(frames, frame) frames = append(frames, frame)
} }
// create a map from collected frames
framesMp := make(map[string]Frame)
for _, frame := range frames {
framesMp[frame.Header.ID] = frame
}
return &ID3v2Tag{ return &ID3v2Tag{
Header: header, Header: header,
Frames: framesMp, Frames: frames,
}, nil }, nil
} }

10
v2/read_test.go

@ -19,10 +19,16 @@ func TestReadV2Tag(t *testing.T) {
t.Errorf("GetV2Tag failed: %s", err) t.Errorf("GetV2Tag failed: %s", err)
} }
titleFrame := tag.Frames["TIT2"] titleFrame := tag.GetFrame("TIT2")
if util.ToStringLossy(titleFrame.Contents) != "title" { if util.ToStringLossy(titleFrame.Contents) != "title" {
t.Errorf("ReadV2Tag failed: expected contents to be %s; got %s", t.Errorf("ReadV2Tag failed: expected contents of the title frame to be %s; got %s",
"title", util.ToStringLossy(titleFrame.Contents)) "title", util.ToStringLossy(titleFrame.Contents))
} }
album := tag.Album()
if album != "album" {
t.Errorf("ReadV2Tag failed: expected contents of the album to be %s; got %s",
"album", album)
}
} }

65
v2/v2tag.go

@ -1,6 +1,69 @@
package v2 package v2
import "github.com/Unbewohnte/id3ed/util"
type ID3v2Tag struct { type ID3v2Tag struct {
Header Header Header Header
Frames map[string]Frame Frames []Frame
}
// Searches for frame with the same identifier as id in tag,
// returns &it if found
func (tag *ID3v2Tag) GetFrame(id string) *Frame {
for _, frame := range tag.Frames {
if frame.Header.ID == id {
return &frame
}
}
return nil
}
// Returns the contents for the title frame
func (tag *ID3v2Tag) Title() string {
switch tag.Header.Version {
case V2_2:
return util.ToStringLossy(tag.GetFrame("TT2").Contents)
default:
return util.ToStringLossy(tag.GetFrame("TIT2").Contents)
}
}
// Returns the contents for the album frame
func (tag *ID3v2Tag) Album() string {
switch tag.Header.Version {
case V2_2:
return util.ToStringLossy(tag.GetFrame("TAL").Contents)
default:
return util.ToStringLossy(tag.GetFrame("TALB").Contents)
}
}
// Returns the contents for the artist frame
func (tag *ID3v2Tag) Artist() string {
switch tag.Header.Version {
case V2_2:
return util.ToStringLossy(tag.GetFrame("TP1").Contents)
default:
return util.ToStringLossy(tag.GetFrame("TPE1").Contents)
}
}
// Returns the contents for the year frame
func (tag *ID3v2Tag) Year() string {
switch tag.Header.Version {
case V2_2:
return util.ToStringLossy(tag.GetFrame("TYE").Contents)
default:
return util.ToStringLossy(tag.GetFrame("TYER").Contents)
}
}
// Returns the contents for the comment frame
func (tag *ID3v2Tag) Comment() string {
switch tag.Header.Version {
case V2_2:
return util.ToStringLossy(tag.GetFrame("COM").Contents)
default:
return util.ToStringLossy(tag.GetFrame("COMM").Contents)
}
} }

Loading…
Cancel
Save