Commits

Robert Lowry committed ae58b3d

added (ugly) ID3v1 support

Comments (0)

Files changed (4)

 // to seek in the input.
 func Read(reader io.Reader) (*File, error) {
 	buf := bufio.NewReader(reader)
-	data, err := buf.Peek(3)
-	if err != nil || len(data) < 3 || string(data) != "ID3" {
+	if !hasID3v2Tag(buf) {
 		return nil, fmt.Errorf("no id3 tags")
 	}
 	tags, err := parseID3v2File(buf)
 	}
 	return tags, nil
 }
+
+func ReadFile(reader io.ReadSeeker) (*File, error) {
+	buf := bufio.NewReader(reader)
+	if hasID3v1Tag(reader) {
+		tags, err := parseID3v1File(reader)
+		if err != nil {
+			return nil, err
+		}
+		return tags, err
+	} else if hasID3v2Tag(buf) {
+		tags, err := parseID3v2File(buf)
+		if err != nil {
+			return nil, fmt.Errorf("error parsing ID3v2 tags")
+		}
+		return tags, err
+	}
+	return nil, fmt.Errorf("no id3 tags")
+}
+// Copyright 2011 Andrew Scherkus
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package id3
+
+import (
+	"bufio"
+	"fmt"
+	"io"
+	"strings"
+)
+
+func hasID3v1Tag(reader io.ReadSeeker) bool {
+	origin, err := reader.Seek(0, 1)
+	if err != nil {
+		return false
+	}
+	_, err = reader.Seek(-128, 2)
+	if err != nil {
+		return false
+	}
+	buf := make([]byte, 3)
+	num, err := reader.Read(buf)
+	if err != nil || num != 3 {
+		return false
+	}
+	reader.Seek(origin, 0)
+	return string(buf) == "TAG"
+}
+
+func parseID3v1File(reader io.ReadSeeker) (*File, error) {
+	origin, err := reader.Seek(-128, 2)
+	if err != nil {
+		return nil, fmt.Errorf("seek failed")
+	}
+	buf := bufio.NewReader(reader)
+
+	header, err := readBytes(buf, 3)
+	if err != nil {
+		return nil, fmt.Errorf("read error")
+	}
+	if string(header) != "TAG" {
+		return nil, fmt.Errorf("ID3v1 tag not found")
+	}
+	file := new(File)
+
+	data, err := readBytes(buf, 30)
+	if err != nil {
+		return nil, fmt.Errorf("read error")
+	}
+	file.Name = strings.TrimRight(string(data), "\u0000")
+
+	data, err = readBytes(buf, 30)
+	if err != nil {
+		return nil, fmt.Errorf("read error")
+	}
+	file.Artist = strings.TrimRight(string(data), "\u0000")
+
+	data, err = readBytes(buf, 30)
+	if err != nil {
+		return nil, fmt.Errorf("read error")
+	}
+	file.Album = strings.TrimRight(string(data), "\u0000")
+
+	data, err = readBytes(buf, 4)
+	if err != nil {
+		return nil, fmt.Errorf("read error")
+	}
+	file.Year = strings.TrimRight(string(data), "\u0000")
+
+	data, err = readBytes(buf, 30)
+	if err != nil {
+		return nil, fmt.Errorf("read error")
+	}
+	if data[28] == 0 {
+		file.Track = fmt.Sprint(data[29])
+	}
+
+	data, err = readBytes(buf, 1)
+	if err != nil {
+		return nil, fmt.Errorf("read error")
+	}
+	if int(data[0]) > len(id3v1Genres) {
+		file.Genre = "Unspecified"
+	} else {
+		file.Genre = id3v1Genres[int(data[0])]
+	}
+	reader.Seek(origin, 0)
+	return file, nil
+}
 	"TLEN": "length",
 }
 
+func hasID3v2Tag(reader *bufio.Reader) bool {
+	data, err := reader.Peek(3)
+	if err != nil || len(data) < 3 {
+		return false
+	}
+	return string(data) == "ID3"
+}
+
 func parseID3v2Header(reader *bufio.Reader) (*ID3v2Header, error) {
 	h := new(ID3v2Header)
 	data, err := readBytes(reader, 10)

tagreader/main.go

 	}
 	defer f.Close()
 
-	tags, err := id3.Read(f)
+	tags, err := id3.ReadFile(f)
 	if err != nil {
 		fmt.Fprintf(os.Stderr, "id3.Read(%s): %s\n", path, err)
 		return
 	}
 
 	fmt.Println(path)
-	fmt.Printf("Header\t%#v\n", *tags.Header)
+	if tags.Header != nil {
+		fmt.Printf("Header\t%#v\n", *tags.Header)
+	}
 	fmt.Printf("Name\t%s\n", tags.Name)
 	fmt.Printf("Artist\t%s\n", tags.Artist)
 	fmt.Printf("Album\t%s\n", tags.Album)