Browse Source

Moved constant values into their own file, started working on ID3v2

main
Unbewohnte 3 years ago
parent
commit
eb371e4840
  1. 11
      constants.go
  2. 16
      id3v10.go
  3. 8
      id3v11.go
  4. 38
      id3v20.go

11
constants.go

@ -0,0 +1,11 @@
package id3ed
// ID3v1
const ID3v1IDENTIFIER string = "TAG"
const ID3v1SIZE int = 128 // bytes
const ID3v1INVALIDGENRE int = 255
//ID3v2
const ID3v2IDENTIFIER string = "ID3"
const ID3v2HEADERSIZE int = 10 // bytes
const ID3v2MAXSIZE int = 268435456 // bytes (256 MB)

16
id3v10.go

@ -11,8 +11,6 @@ import (
// https://id3.org/ID3v1 - documentation // https://id3.org/ID3v1 - documentation
const ID3V1SIZE int = 128
type ID3v1Tags struct { type ID3v1Tags struct {
SongName string SongName string
Artist string Artist string
@ -25,7 +23,7 @@ type ID3v1Tags struct {
// Retrieves ID3v1 field values of provided io.ReadSeeker (usually a file) // Retrieves ID3v1 field values of provided io.ReadSeeker (usually a file)
func GetID3v1Tags(rs io.ReadSeeker) (*ID3v1Tags, error) { func GetID3v1Tags(rs io.ReadSeeker) (*ID3v1Tags, error) {
// set reader to the last 128 bytes // set reader to the last 128 bytes
_, err := rs.Seek(-int64(ID3V1SIZE), io.SeekEnd) _, err := rs.Seek(-int64(ID3v1SIZE), io.SeekEnd)
if err != nil { if err != nil {
return nil, fmt.Errorf("could not seek: %s", err) return nil, fmt.Errorf("could not seek: %s", err)
} }
@ -35,7 +33,7 @@ func GetID3v1Tags(rs io.ReadSeeker) (*ID3v1Tags, error) {
return nil, err return nil, err
} }
if !bytes.Equal(tag, []byte("TAG")) { if !bytes.Equal(tag, []byte(ID3v1IDENTIFIER)) {
// no TAG, given file does not use ID3v1 // no TAG, given file does not use ID3v1
return nil, fmt.Errorf("does not use ID3v1: expected %s; got %s", "TAG", tag) return nil, fmt.Errorf("does not use ID3v1: expected %s; got %s", "TAG", tag)
} }
@ -97,7 +95,7 @@ func (tags *ID3v1Tags) Write(dst io.WriteSeeker) error {
dst.Seek(0, io.SeekEnd) dst.Seek(0, io.SeekEnd)
// TAG // TAG
_, err := dst.Write([]byte("TAG")) _, err := dst.Write([]byte(ID3v1IDENTIFIER))
if err != nil { if err != nil {
return err return err
} }
@ -136,7 +134,7 @@ func (tags *ID3v1Tags) Write(dst io.WriteSeeker) error {
genreCode := getKey(id3v1genres, tags.Genre) genreCode := getKey(id3v1genres, tags.Genre)
if genreCode == -1 { if genreCode == -1 {
// if no genre found - encode genre code as 255 // if no genre found - encode genre code as 255
genreCode = 255 genreCode = ID3v1INVALIDGENRE
} }
genrebyte := make([]byte, 1) genrebyte := make([]byte, 1)
binary.PutVarint(genrebyte, int64(genreCode)) binary.PutVarint(genrebyte, int64(genreCode))
@ -154,14 +152,14 @@ func (tags *ID3v1Tags) WriteToFile(f *os.File) error {
defer f.Close() defer f.Close()
// check for existing ID3v1 tag // check for existing ID3v1 tag
f.Seek(-int64(ID3V1SIZE), io.SeekEnd) f.Seek(-int64(ID3v1SIZE), io.SeekEnd)
tag, err := read(f, 3) tag, err := read(f, 3)
if err != nil { if err != nil {
return err return err
} }
if !bytes.Equal(tag, []byte("TAG")) { if !bytes.Equal(tag, []byte(ID3v1IDENTIFIER)) {
// no existing tag, just write given tags // no existing tag, just write given tags
err = tags.Write(f) err = tags.Write(f)
if err != nil { if err != nil {
@ -176,7 +174,7 @@ func (tags *ID3v1Tags) WriteToFile(f *os.File) error {
return err return err
} }
err = f.Truncate(fStats.Size() - int64(ID3V1SIZE)) err = f.Truncate(fStats.Size() - int64(ID3v1SIZE))
if err != nil { if err != nil {
return nil return nil
} }

8
id3v11.go

@ -22,7 +22,7 @@ type ID3v11Tags struct {
// Retrieves ID3v1.1 field values of provided io.ReadSeeker // Retrieves ID3v1.1 field values of provided io.ReadSeeker
func GetID3v11Tags(rs io.ReadSeeker) (*ID3v11Tags, error) { func GetID3v11Tags(rs io.ReadSeeker) (*ID3v11Tags, error) {
// set reader to the last 128 bytes // set reader to the last 128 bytes
_, err := rs.Seek(-int64(ID3V1SIZE), io.SeekEnd) _, err := rs.Seek(-int64(ID3v1SIZE), io.SeekEnd)
if err != nil { if err != nil {
return nil, fmt.Errorf("could not seek: %s", err) return nil, fmt.Errorf("could not seek: %s", err)
} }
@ -164,7 +164,7 @@ func (tags *ID3v11Tags) Write(dst io.WriteSeeker) error {
genreCode := getKey(id3v1genres, tags.Genre) genreCode := getKey(id3v1genres, tags.Genre)
if genreCode == -1 { if genreCode == -1 {
// if no genre found - encode genre code as 255 // if no genre found - encode genre code as 255
genreCode = 255 genreCode = ID3v1INVALIDGENRE
} }
genrebyte := make([]byte, 1) genrebyte := make([]byte, 1)
binary.PutVarint(genrebyte, int64(genreCode)) binary.PutVarint(genrebyte, int64(genreCode))
@ -182,7 +182,7 @@ func (tags *ID3v11Tags) WriteToFile(f *os.File) error {
defer f.Close() defer f.Close()
// check for existing ID3v1.1 tag // check for existing ID3v1.1 tag
f.Seek(-int64(ID3V1SIZE), io.SeekEnd) f.Seek(-int64(ID3v1SIZE), io.SeekEnd)
tag, err := read(f, 3) tag, err := read(f, 3)
if err != nil { if err != nil {
@ -204,7 +204,7 @@ func (tags *ID3v11Tags) WriteToFile(f *os.File) error {
return err return err
} }
err = f.Truncate(fStats.Size() - int64(ID3V1SIZE)) err = f.Truncate(fStats.Size() - int64(ID3v1SIZE))
if err != nil { if err != nil {
return nil return nil
} }

38
id3v20.go

@ -0,0 +1,38 @@
package id3ed
//////////////////////////////////////
//(ᗜˬᗜ)~⭐//Under construction//(ᗜ‸ᗜ)//
//////////////////////////////////////
import (
"bytes"
"fmt"
"io"
)
type Header struct {
Identifier string
Version int
Flags int
Size int64
}
func GetHeader(rs io.ReadSeeker) (*Header, error) {
var header Header
rs.Seek(0, io.SeekStart)
identifier, err := read(rs, 3)
if err != nil {
return nil, err
}
// check if ID3v2 is used
if !bytes.Equal([]byte(ID3v2IDENTIFIER), identifier) {
return nil, fmt.Errorf("does not use ID3v2")
}
////
header.Identifier = string(identifier)
return &header, nil
}
Loading…
Cancel
Save