diff --git a/flac.go b/flac.go index c370467..5032eae 100644 --- a/flac.go +++ b/flac.go @@ -34,12 +34,12 @@ func ReadFLACTags(r io.ReadSeeker) (Metadata, error) { return nil, errors.New("expected 'fLaC'") } - m := &metadataFLAC{ - newMetadataVorbis(), + m := &MetadataFLAC{ + NewMetadataVorbis(), } for { - last, err := m.readFLACMetadataBlock(r) + last, err := m.ReadFLACMetadataBlock(r) if err != nil { return nil, err } @@ -51,11 +51,11 @@ func ReadFLACTags(r io.ReadSeeker) (Metadata, error) { return m, nil } -type metadataFLAC struct { - *metadataVorbis +type MetadataFLAC struct { + *MetadataVorbis } -func (m *metadataFLAC) readFLACMetadataBlock(r io.ReadSeeker) (last bool, err error) { +func (m *MetadataFLAC) ReadFLACMetadataBlock(r io.ReadSeeker) (last bool, err error) { blockHeader, err := readBytes(r, 1) if err != nil { return @@ -73,7 +73,7 @@ func (m *metadataFLAC) readFLACMetadataBlock(r io.ReadSeeker) (last bool, err er switch blockType(blockHeader[0]) { case vorbisCommentBlock: - err = m.readVorbisComment(r) + err = m.ReadVorbisComment(r) case pictureBlock: err = m.readPictureBlock(r) @@ -84,6 +84,6 @@ func (m *metadataFLAC) readFLACMetadataBlock(r io.ReadSeeker) (last bool, err er return } -func (m *metadataFLAC) FileType() FileType { +func (m *MetadataFLAC) FileType() FileType { return FLAC } diff --git a/ogg.go b/ogg.go index f5c4770..ff23e8f 100644 --- a/ogg.go +++ b/ogg.go @@ -120,6 +120,9 @@ func (o *oggDemuxer) Read(r io.Reader) ([][]byte, error) { var packets [][]byte var p int for _, s := range segmentTable { + if !continued && !bytes.HasPrefix(segmentsData, vorbisCommentPrefix) && !bytes.HasPrefix(segmentsData, opusTagsPrefix) { + return nil, fmt.Errorf("not a metadata segment") + } packetBuf.Write(segmentsData[p : p+int(s)]) if s < 255 { packets = append(packets, packetBuf.Bytes()) @@ -150,15 +153,15 @@ func ReadOGGTags(r io.Reader) (Metadata, error) { switch { case bytes.HasPrefix(b, vorbisCommentPrefix): m := &metadataOGG{ - newMetadataVorbis(), + NewMetadataVorbis(), } - err = m.readVorbisComment(bytes.NewReader(b[len(vorbisCommentPrefix):])) + err = m.ReadVorbisComment(bytes.NewReader(b[len(vorbisCommentPrefix):])) return m, err case bytes.HasPrefix(b, opusTagsPrefix): m := &metadataOGG{ - newMetadataVorbis(), + NewMetadataVorbis(), } - err = m.readVorbisComment(bytes.NewReader(b[len(opusTagsPrefix):])) + err = m.ReadVorbisComment(bytes.NewReader(b[len(opusTagsPrefix):])) return m, err } } @@ -166,7 +169,7 @@ func ReadOGGTags(r io.Reader) (Metadata, error) { } type metadataOGG struct { - *metadataVorbis + *MetadataVorbis } func (m *metadataOGG) FileType() FileType { diff --git a/vorbis.go b/vorbis.go index f1c6a19..1689229 100644 --- a/vorbis.go +++ b/vorbis.go @@ -15,18 +15,18 @@ import ( "time" ) -func newMetadataVorbis() *metadataVorbis { - return &metadataVorbis{ +func NewMetadataVorbis() *MetadataVorbis { + return &MetadataVorbis{ c: make(map[string]string), } } -type metadataVorbis struct { +type MetadataVorbis struct { c map[string]string // the vorbis comments p *Picture } -func (m *metadataVorbis) readVorbisComment(r io.Reader) error { +func (m *MetadataVorbis) ReadVorbisComment(r io.Reader) error { vendorLen, err := readUint32LittleEndian(r) if err != nil { return err @@ -70,7 +70,7 @@ func (m *metadataVorbis) readVorbisComment(r io.Reader) error { return nil } -func (m *metadataVorbis) readPictureBlock(r io.Reader) error { +func (m *MetadataVorbis) readPictureBlock(r io.Reader) error { b, err := readInt(r, 4) if err != nil { return err @@ -156,11 +156,11 @@ func parseComment(c string) (k, v string, err error) { return } -func (m *metadataVorbis) Format() Format { +func (m *MetadataVorbis) Format() Format { return VORBIS } -func (m *metadataVorbis) Raw() map[string]interface{} { +func (m *MetadataVorbis) Raw() map[string]interface{} { raw := make(map[string]interface{}, len(m.c)) for k, v := range m.c { raw[k] = v @@ -168,11 +168,11 @@ func (m *metadataVorbis) Raw() map[string]interface{} { return raw } -func (m *metadataVorbis) Title() string { +func (m *MetadataVorbis) Title() string { return m.c["title"] } -func (m *metadataVorbis) Artist() string { +func (m *MetadataVorbis) Artist() string { // ARTIST // The artist generally considered responsible for the work. In popular music // this is usually the performing band or singer. For classical music it would @@ -180,17 +180,17 @@ func (m *metadataVorbis) Artist() string { return m.c["artist"] } -func (m *metadataVorbis) Album() string { +func (m *MetadataVorbis) Album() string { return m.c["album"] } -func (m *metadataVorbis) AlbumArtist() string { +func (m *MetadataVorbis) AlbumArtist() string { // This field isn't actually included in the standard, though // it is commonly assigned to albumartist. return m.c["albumartist"] } -func (m *metadataVorbis) Composer() string { +func (m *MetadataVorbis) Composer() string { if m.c["composer"] != "" { return m.c["composer"] } @@ -205,11 +205,11 @@ func (m *metadataVorbis) Composer() string { return m.c["artist"] } -func (m *metadataVorbis) Genre() string { +func (m *MetadataVorbis) Genre() string { return m.c["genre"] } -func (m *metadataVorbis) Year() int { +func (m *MetadataVorbis) Year() int { var dateFormat string // The date need to follow the international standard https://en.wikipedia.org/wiki/ISO_8601 @@ -236,31 +236,31 @@ func (m *metadataVorbis) Year() int { return t.Year() } -func (m *metadataVorbis) Track() (int, int) { +func (m *MetadataVorbis) Track() (int, int) { x, _ := strconv.Atoi(m.c["tracknumber"]) // https://wiki.xiph.org/Field_names n, _ := strconv.Atoi(m.c["tracktotal"]) return x, n } -func (m *metadataVorbis) Disc() (int, int) { +func (m *MetadataVorbis) Disc() (int, int) { // https://wiki.xiph.org/Field_names x, _ := strconv.Atoi(m.c["discnumber"]) n, _ := strconv.Atoi(m.c["disctotal"]) return x, n } -func (m *metadataVorbis) Lyrics() string { +func (m *MetadataVorbis) Lyrics() string { return m.c["lyrics"] } -func (m *metadataVorbis) Comment() string { +func (m *MetadataVorbis) Comment() string { if m.c["comment"] != "" { return m.c["comment"] } return m.c["description"] } -func (m *metadataVorbis) Picture() *Picture { +func (m *MetadataVorbis) Picture() *Picture { return m.p }