From d5d80944d6ad6480fd0eff28fbb6ab15cbc9aa3a Mon Sep 17 00:00:00 2001 From: Unbewohnte Date: Tue, 22 Jun 2021 13:37:28 +0300 Subject: [PATCH] Minimal ID3v1.1 support ? --- README.md | 5 +- id3v1.1.go | 125 +++++++++++++++++++++++++++++++++++++++++++++ id3v1_test.go | 17 ++++++ testData/id3v1.txt | Bin 0 -> 165 bytes 4 files changed, 145 insertions(+), 2 deletions(-) create mode 100644 id3v1.1.go create mode 100644 id3v1_test.go create mode 100644 testData/id3v1.txt diff --git a/README.md b/README.md index 810ab49..36ef5ea 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,5 @@ -# ID3ED (ID3- Encoder - Decoder) +# ID3ED (ID3 - Encoder - Decoder) ## Library for encoding/decoding ID3 tags -# Under construction ! \ No newline at end of file +# Under construction ! +## Bugs are a possibility rn in this state \ No newline at end of file diff --git a/id3v1.1.go b/id3v1.1.go new file mode 100644 index 0000000..72b5d41 --- /dev/null +++ b/id3v1.1.go @@ -0,0 +1,125 @@ +package id3ed + +import ( + "bytes" + "fmt" + "io" + "strconv" +) + +type ID3v11Tags struct { + SongName string + Artist string + Album string + Year int + Comment string + Track int + Genre int +} + +// Retrieves ID3v1.1 field values of provided io.ReadSeeker (usually a file) +func GetID3v11Tags(rs io.ReadSeeker) (*ID3v11Tags, error) { + // set reader to the last 128 bytes + _, err := rs.Seek(-int64(ID3V1SIZE), io.SeekEnd) + if err != nil { + return nil, fmt.Errorf("could not seek: %s", err) + } + + tag, err := read(rs, 3) + if err != nil { + return nil, err + } + + if !bytes.Equal(tag, []byte("TAG")) { + // no TAG, given file does not use ID3v1 + return nil, fmt.Errorf("does not use ID3v1") + } + + songname, err := read(rs, 30) + if err != nil { + return nil, err + } + + artist, err := read(rs, 30) + if err != nil { + return nil, err + } + + album, err := read(rs, 30) + if err != nil { + return nil, err + } + + yearBytes, err := read(rs, 4) + if err != nil { + return nil, err + } + year, err := strconv.Atoi(string(yearBytes)) + if err != nil { + return nil, fmt.Errorf("could not convert yearbytes into int: %s", err) + } + + comment, err := read(rs, 28) + if err != nil { + return nil, err + } + + // skip 1 null byte + _, err = read(rs, 1) + if err != nil { + return nil, err + } + + trackByte, err := read(rs, 1) + if err != nil { + return nil, err + } + + // track is one byte by specification + track := int(trackByte[0]) + + genreByte, err := read(rs, 1) + if err != nil { + return nil, err + } + // genre is one byte by specification + genre := int(genreByte[0]) + + return &ID3v11Tags{ + SongName: string(songname), + Artist: string(artist), + Album: string(album), + Year: year, + Comment: string(comment), + Track: track, + Genre: genre, + }, nil +} + +func (t *ID3v11Tags) GetSongName() string { + return t.SongName +} + +func (t *ID3v11Tags) GetArtist() string { + return t.Artist +} + +func (t *ID3v11Tags) GetAlbum() string { + return t.Album +} + +func (t *ID3v11Tags) GetYear() int { + return t.Year +} + +func (t *ID3v11Tags) GetComment() string { + return t.Comment +} + +func (t *ID3v11Tags) GetTrack() int { + return t.Track +} + +func (t *ID3v11Tags) GetGenre() int { + return t.Genre +} diff --git a/id3v1_test.go b/id3v1_test.go new file mode 100644 index 0000000..962ad32 --- /dev/null +++ b/id3v1_test.go @@ -0,0 +1,17 @@ +package id3ed + +import ( + "os" + "testing" +) + +func TestGetID3v1Tags(t *testing.T) { + testfile, err := os.Open("./testData/id3v1.txt") + if err != nil { + t.Errorf("could not open file for testing: %s", err) + } + _, err = GetID3v1Tags(testfile) + if err != nil { + t.Errorf("GetID3v1Tags failed: %s", err) + } +} diff --git a/testData/id3v1.txt b/testData/id3v1.txt new file mode 100644 index 0000000000000000000000000000000000000000..c70ca6464c5b7bf38d419dcb60341ffad0927d21 GIT binary patch literal 165 zcmWH}&rMZGNi0cJ$Ve?p>GN=;1R0)h}n_mIqzoKyx}z_F+# tv$zD8Y=~=ch=QY!Q>d?khii~4nldAEBXj5c+}zZ>60jQ-(Bv67Bml1P8uS1F literal 0 HcmV?d00001