Updated ReadFrom to take io.ReadSeeker
This commit is contained in:
parent
23f80edc48
commit
1fc6cacf34
13
id3v1.go
13
id3v1.go
@ -5,10 +5,9 @@
|
||||
package tag
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"errors"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"strconv"
|
||||
"strings"
|
||||
)
|
||||
@ -42,16 +41,14 @@ var id3v1Genres = [...]string{
|
||||
// ErrNotID3v1 is an error which is returned when no ID3v1 header is found.
|
||||
var ErrNotID3v1 = errors.New("invalid ID3v1 header")
|
||||
|
||||
// ReadID3v1Tags reads ID3v1 tags from the given io.Reader. Returns a non-nil error
|
||||
// if there was a problem.
|
||||
func ReadID3v1Tags(r io.Reader) (Metadata, error) {
|
||||
b, err := ioutil.ReadAll(r)
|
||||
// ReadID3v1Tags reads ID3v1 tags from the io.ReadSeeker. Returns ErrNotID3v1
|
||||
// if there are no ID3v1 tags, otherwise non-nil error if there was a problem.
|
||||
func ReadID3v1Tags(r io.ReadSeeker) (Metadata, error) {
|
||||
_, err := r.Seek(-128, os.SEEK_END)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
b = b[len(b)-128 : len(b)]
|
||||
r = bytes.NewReader(b)
|
||||
if tag, err := readString(r, 3); err != nil {
|
||||
return nil, err
|
||||
} else if tag != "TAG" {
|
||||
|
10
id3v2.go
10
id3v2.go
@ -7,6 +7,7 @@ package tag
|
||||
import (
|
||||
"fmt"
|
||||
"io"
|
||||
"os"
|
||||
"strings"
|
||||
)
|
||||
|
||||
@ -219,9 +220,14 @@ func readID3v2Frames(r io.Reader, h *ID3v2Header) (map[string]interface{}, error
|
||||
return result, nil
|
||||
}
|
||||
|
||||
// ReadID3v2Tags parses ID3v2.{2,3,4} tags from the given io.Reader into a Metadata, returning
|
||||
// ReadID3v2Tags parses ID3v2.{2,3,4} tags from the io.ReadSeeker into a Metadata, returning
|
||||
// non-nil error on failure.
|
||||
func ReadID3v2Tags(r io.Reader) (Metadata, error) {
|
||||
func ReadID3v2Tags(r io.ReadSeeker) (Metadata, error) {
|
||||
_, err := r.Seek(0, os.SEEK_SET)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
h, err := readID3v2Header(r)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
13
mp4.go
13
mp4.go
@ -8,6 +8,7 @@ import (
|
||||
"encoding/binary"
|
||||
"fmt"
|
||||
"io"
|
||||
"os"
|
||||
"strconv"
|
||||
)
|
||||
|
||||
@ -56,11 +57,15 @@ func (f atomNames) Name(n string) []string {
|
||||
// metadataMP4 is the implementation of Metadata for MP4 tag (atom) data.
|
||||
type metadataMP4 map[string]interface{}
|
||||
|
||||
// ReadAtoms reads MP4 metadata atoms from the reader into a Metadata, returning non-nil
|
||||
// error if there was a problem.
|
||||
func ReadAtoms(r io.Reader) (Metadata, error) {
|
||||
// ReadAtoms reads MP4 metadata atoms from the io.ReadSeeker into a Metadata, returning
|
||||
// non-nil error if there was a problem.
|
||||
func ReadAtoms(r io.ReadSeeker) (Metadata, error) {
|
||||
_, err := r.Seek(0, os.SEEK_SET)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
m := make(metadataMP4)
|
||||
err := m.readAtoms(r)
|
||||
err = m.readAtoms(r)
|
||||
return m, err
|
||||
}
|
||||
|
||||
|
26
tag.go
26
tag.go
@ -6,7 +6,6 @@
|
||||
package tag
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"errors"
|
||||
"io"
|
||||
)
|
||||
@ -16,25 +15,26 @@ import (
|
||||
var ErrNoTagsFound = errors.New("no tags found")
|
||||
|
||||
// ReadFrom parses audio file metadata tags (currently supports ID3v1,2.{2,3,4} and MP4).
|
||||
// This method attempts to determine the format of the data provided by the reader, and then
|
||||
// chooses ReadAtoms (MP4), ReadID3v2Tags (ID3v2.{2,3,4}) or ReadID3v1Tags as appropriate.
|
||||
// Returns non-nil error if the format of the given data could not be determined, or if
|
||||
// there was a problem parsing the data.
|
||||
func ReadFrom(r io.Reader) (Metadata, error) {
|
||||
// This method attempts to determine the format of the data provided by the io.ReadSeeker,
|
||||
// and then chooses ReadAtoms (MP4), ReadID3v2Tags (ID3v2.{2,3,4}) or ReadID3v1Tags as
|
||||
// appropriate. Returns non-nil error if the format of the given data could not be determined,
|
||||
// or if there was a problem parsing the data.
|
||||
func ReadFrom(r io.ReadSeeker) (Metadata, error) {
|
||||
b, err := readBytes(r, 11)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
rr := io.MultiReader(bytes.NewReader(b), r)
|
||||
if string(b[4:11]) == "ftypM4A" {
|
||||
return ReadAtoms(rr)
|
||||
}
|
||||
if string(b[0:3]) == "ID3" {
|
||||
return ReadID3v2Tags(rr)
|
||||
switch {
|
||||
|
||||
case string(b[4:11]) == "ftypM4A":
|
||||
return ReadAtoms(r)
|
||||
|
||||
case string(b[0:3]) == "ID3":
|
||||
return ReadID3v2Tags(r)
|
||||
}
|
||||
|
||||
m, err := ReadID3v1Tags(rr)
|
||||
m, err := ReadID3v1Tags(r)
|
||||
if err != nil {
|
||||
if err == ErrNotID3v1 {
|
||||
err = ErrNoTagsFound
|
||||
|
Loading…
Reference in New Issue
Block a user