Giter Club home page Giter Club logo

tag's Introduction

MP3/MP4/OGG/FLAC metadata parsing library

GoDoc

This package provides MP3 (ID3v1,2.{2,3,4}) and MP4 (ACC, M4A, ALAC), OGG and FLAC metadata detection, parsing and artwork extraction.

Detect and parse tag metadata from an io.ReadSeeker (i.e. an *os.File):

m, err := tag.ReadFrom(f)
if err != nil {
	log.Fatal(err)
}
log.Print(m.Format()) // The detected format.
log.Print(m.Title())  // The title of the track (see Metadata interface for more details).

Parsed metadata is exported via a single interface (giving a consistent API for all supported metadata formats).

// Metadata is an interface which is used to describe metadata retrieved by this package.
type Metadata interface {
	Format() Format
	FileType() FileType

	Title() string
	Album() string
	Artist() string
	AlbumArtist() string
	Composer() string
	Genre() string
	Year() int

	Track() (int, int) // Number, Total
	Disc() (int, int) // Number, Total

	Picture() *Picture // Artwork
	Lyrics() string
	Comment() string

	Raw() map[string]interface{} // NB: raw tag names are not consistent across formats.
}

Audio Data Checksum (SHA1)

This package also provides a metadata-invariant checksum for audio files: only the audio data is used to construct the checksum.

https://pkg.go.dev/github.com/dhowden/tag#Sum

Tools

There are simple command-line tools which demonstrate basic tag extraction and summing:

$ go install github.com/dhowden/tag/cmd/tag@latest
$ cd $GOPATH/bin
$ ./tag 11\ High\ Hopes.m4a
Metadata Format: MP4
Title: High Hopes
Album: The Division Bell
Artist: Pink Floyd
Composer: Abbey Road Recording Studios/David Gilmour/Polly Samson
Year: 1994
Track: 11 of 11
Disc: 1 of 1
Picture: Picture{Ext: jpeg, MIMEType: image/jpeg, Type: , Description: , Data.Size: 606109}

$ ./sum 11\ High\ Hopes.m4a
2ae208c5f00a1f21f5fac9b7f6e0b8e52c06da29

tag's People

Contributors

bretttolbert avatar dhowden avatar ilkomiliev avatar jooola avatar jorgelnjunior avatar melvyn2 avatar mkrogh avatar nzoschke avatar simon-l avatar solarnz avatar steve-hellwege-wdc avatar thraxil avatar upperstream avatar w1ck3dg0ph3r avatar wader avatar xhenner avatar yabobay avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

tag's Issues

panic: runtime error: makeslice: len out of range in tag.readBytes

Hello.

I found a makeslice: len out of range bug in tag.

Please confirm.

Thanks.

reproduce code:

package tag

import (
	"strings"
	"testing"
)

func TestFuzzCrashers(t *testing.T) {

	var crashers = []string{
		 "fLaC\x84000000\x82",

	}

	for _, f := range crashers {
		ReadFLACTags(strings.NewReader(f))
	}
}

Crash Log

--- FAIL: TestFuzzCrashers (0.00s)
panic: runtime error: makeslice: len out of range [recovered]
	panic: runtime error: makeslice: len out of range

goroutine 5 [running]:
testing.tRunner.func1(0xc42004e9c0)
	/usr/lib/go-1.8/src/testing/testing.go:622 +0x29d
panic(0x536a20, 0xc42000ef80)
	/usr/lib/go-1.8/src/runtime/panic.go:489 +0x2cf
github.com/dhowden/tag.readBytes(0x7fea805b0000, 0xc42000ae00, 0xffffffff82303030, 0x521f00, 0xc42000ef5c, 0x0, 0x0, 0xc42000ef5c)
	/home/karas/go/src/github.com/dhowden/tag/util.go:36 +0x40
github.com/dhowden/tag.readString(0x7fea805b0000, 0xc42000ae00, 0xffffffff82303030, 0x0, 0x0, 0x3, 0x7fea805b0000)
	/home/karas/go/src/github.com/dhowden/tag/util.go:45 +0x43
github.com/dhowden/tag.(*metadataVorbis).readVorbisComment(0xc42000ef60, 0x7fea805b0000, 0xc42000ae00, 0x7fea805b0000, 0xc42000ae00)
	/home/karas/go/src/github.com/dhowden/tag/vorbis.go:32 +0x88
github.com/dhowden/tag.(*metadataFLAC).readFLACMetadataBlock(0xc42000c098, 0x5f5f00, 0xc42000ae00, 0x0, 0xc420014cf0, 0x0)
	/home/karas/go/src/github.com/dhowden/tag/flac.go:77 +0x22a
github.com/dhowden/tag.ReadFLACTags(0x5f5f00, 0xc42000ae00, 0xffffffee, 0x1000, 0xc420027f78, 0x4544c3)
	/home/karas/go/src/github.com/dhowden/tag/flac.go:43 +0x208
github.com/dhowden/tag.TestFuzzCrashers(0xc42004e9c0)
	/home/karas/go/src/github.com/dhowden/tag/fuzz_test.go:16 +0xbf
testing.tRunner(0xc42004e9c0, 0x567ed0)
	/usr/lib/go-1.8/src/testing/testing.go:657 +0x96
created by testing.(*T).Run
	/usr/lib/go-1.8/src/testing/testing.go:697 +0x2ca
exit status 2
FAIL	github.com/dhowden/tag	0.005s

=================
[Acknowledgement]
This work was supported by ICT R&D program of MSIP/IITP. [R7518-16-1001, Innovation hub for high Performance Computing]

Can't get multiple values for a tag in ID3v2.4

In ID3v2.4, frames can have multiple strings (eg multiple artists), separated by null byte(s). But in the code, the null bytes are stripped from the string before it's passed out, resulting in a string that's just a concatenation of all the values.

Is there a way to get the multiple values for a tag?

Cannot extract metadata from OGG file

(Sorry for bombarding you with issues, but this is the best pure Go tag library out there and this is my way of contributing to make it even better! Thanks for your awesome job!)

I think the way that the picture is embedded in this file is breaking the library. This is what I get:

$ tag Indila.ogg
error reading file: unexpected EOF

Indila.ogg.zip

I think it may be caused by the way the picture is embedded. Normally ffmpeg reports the embedded art as a separated stream like this:

    Stream #0:1: Video: mjpeg (Baseline), yuvj444p(pc, bt470bg/unknown/unknown), 700x700 [SAR 72:72 DAR 1:1], 90k tbr, 90k tbn, 90k tbc (attached pic)
    Metadata:
      comment         : Cover (front)

But in the attached file, it appears as a tag of the audio stream:

    Stream #0:0(fra): Audio: vorbis, 44100 Hz, stereo, fltp, 320 kb/s
    Metadata:
      metadata_block_picture: AAAAAwAAAAppbWFnZS9qcGVnAAAAAAAAAAAAAAAAAAAAAAAAAAAAA5FA/9j/4AAQSkZJRgABAQAAAQABAAD/2wBDAAUDBAQEAwUEBAQFBQUGBwwIBwcHBw8LCwkMEQ8SEhEPERETFhwXExQaFRERGCEYGh0dHx8fExciJCIeJBweHx7/2wBDAQUFBQcGBw4ICA4eFBEUHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4

ID3v2 text frames with encoding type 1 but no BOM

Hi, i have some mp3 files (BBC radio podcasts) that have UTLS frames with encoding type 1 but no BOM. They have string data in UTF16 little endian.

00000100  79 6e 65 73 2e 55 53 4c  54 00 00 01 84 00 00 01  |ynes.USLT.......|
                                                        ^- encoding 1
00000110  65 6e 67 44 00 65 00 73  00 63 00 72 00 69 00 70  |engD.e.s.c.r.i.p|
                   ^- no BOM :(
00000120  00 74 00 69 00 6f 00 6e  00 00 00 41 00 6d 00 65  |.t.i.o.n...A.m.e|
00000130  00 72 00 69 00 63 00 61  00 6e 00 20 00 73 00 61  |.r.i.c.a.n. .s.a|
00000140  00 74 00 69 00 72 00 69  00 73 00 74 00 20 00 4a  |.t.i.r.i.s.t. .J|
00000150  00 6f 00 65 00 20 00 51  00 75 00 65 00 65 00 6e  |.o.e. .Q.u.e.e.n|
00000160  00 61 00 6e 00 20 00 63  00 68 00 61 00 72 00 74  |.a.n. .c.h.a.r.t|
00000170  00 73 00 20 00 74 00 68  00 65 00 20 00 72 00 69  |.s. .t.h.e. .r.i|
00000180  00 73 00 65 00 20 00 61  00 6e 00 64 00 20 00 66  |.s.e. .a.n.d. .f|
00000190  00 61 00 6c 00 6c 00 20  00 6f 00 66 00 20 00 74  |.a.l.l. .o.f. .t|
000001a0  00 68 00 65 00 20 00 6e  00 75 00 64 00 67 00 65  |.h.e. .n.u.d.g.e|
000001b0  00 20 00 6e 00 75 00 64  00 67 00 65 00 20 00 77  |. .n.u.d.g.e. .w|
000001c0  00 69 00 6e 00 6b 00 20  00 77 00 69 00 6e 00 6b  |.i.n.k. .w.i.n.k|
000001d0  00 20 00 65 00 70 00 69  00 64 00 65 00 6d 00 69  |. .e.p.i.d.e.m.i|
000001e0  00 63 00 2c 00 20 00 77  00 69 00 74 00 68 00 20  |.c.,. .w.i.t.h. |
000001f0  00 68 00 65 00 6c 00 70  00 20 00 66 00 72 00 6f  |.h.e.l.p. .f.r.o|
00000200  00 6d 00 20 00 49 00 61  00 6e 00 20 00 48 00 69  |.m. .I.a.n. .H.i|
00000210  00 73 00 6c 00 6f 00 70  00 2c 00 20 00 4a 00 6f  |.s.l.o.p.,. .J.o|
00000220  00 68 00 6e 00 20 00 53  00 65 00 72 00 67 00 65  |.h.n. .S.e.r.g.e|
00000230  00 61 00 6e 00 74 00 2c  00 20 00 4b 00 61 00 74  |.a.n.t.,. .K.a.t|
00000240  00 68 00 79 00 20 00 4c  00 65 00 74 00 74 00 65  |.h.y. .L.e.t.t.e|
00000250  00 2c 00 20 00 42 00 61  00 72 00 72 00 79 00 20  |.,. .B.a.r.r.y. |
00000260  00 43 00 72 00 79 00 65  00 72 00 20 00 61 00 6e  |.C.r.y.e.r. .a.n|
00000270  00 64 00 20 00 4e 00 61  00 74 00 61 00 6c 00 69  |.d. .N.a.t.a.l.i|
00000280  00 65 00 20 00 48 00 61  00 79 00 6e 00 65 00 73  |.e. .H.a.y.n.e.s|
00000290  00 2e 00 54 43 4f 4e 00  00 00 08 00 00 00 50 6f  |...TCON.......Po|

Do you think it's worth even trying to do some kind of fallback?

panic: runtime error: slice bounds out of range [:3] with capacity 1

Found the above panic when reading tags from the following file: 03.-.Semblance.Of.Confusion.-.defect.zip

When using the tag command line. tool, I get this stack trace:

$ tag ~/Downloads/03\ -\ Semblance\ Of\ Confusion\ -\ defect.mp3
panic: runtime error: slice bounds out of range [:3] with capacity 1

goroutine 1 [running]:
github.com/dhowden/tag.readTextWithDescrFrame(0xc00008c0c8, 0x2, 0x2, 0x101, 0x1277b20, 0x0, 0x0)
	/Users/deluan/Development/go/src/github.com/dhowden/tag/id3v2frames.go:460 +0x46b
github.com/dhowden/tag.readID3v2Frames(0x1795008, 0xc00000e030, 0x4e, 0xc00008e000, 0xc00000e030, 0x0, 0x0)
	/Users/deluan/Development/go/src/github.com/dhowden/tag/id3v2.go:364 +0x8b7
github.com/dhowden/tag.ReadID3v2Tags(0x1173320, 0xc00000e030, 0x1, 0x0, 0x0, 0x0)
	/Users/deluan/Development/go/src/github.com/dhowden/tag/id3v2.go:428 +0xde
github.com/dhowden/tag.ReadFrom(0x1173320, 0xc00000e030, 0x0, 0x0, 0xc00000e030, 0x0)
	/Users/deluan/Development/go/src/github.com/dhowden/tag/tag.go:52 +0x324
main.main()
	/Users/deluan/Development/go/src/github.com/dhowden/tag/cmd/tag/main.go:46 +0x1be

Tried with other tag extractors (TagLib and ffmpeg) and they are both able to extract the tags. Ex. with tagreader from TagLib:

$ tagreader ~/Downloads/03\ -\ Semblance\ Of\ Confusion\ -\ defect.mp3
******************** "/Users/deluan/Downloads/03 - Semblance Of Confusion - defect.mp3" ********************
-- TAG (basic) --
title   - "Semblance Of Confusion"
artist  - "After Forever"
album   - "Prison of Desire"
year    - "2000"
comment - ""
track   - "3"
genre   - "Metal"
-- TAG (properties) --
ALBUM          - "Prison of Desire"
ARTIST         - "After Forever"
COMMENT        - ""
DATE           - "2000"
GENRE          - "Metal"
MEDIA          - "DIG"
TITLE          - "Semblance Of Confusion"
TRACKNUMBER    - "03"
URL            - ""
-- AUDIO --
bitrate     - 128
sample rate - 44100
channels    - 2
length      - 4:90

from navidrome/navidrome#596

Thanks!

testdata/with_tags/sample.id3v22.mp3 seems to be a v2.3 tag

Hey! I was using the test files for some parser testing when i noticed that sample.id3v22.mp3 seems a have version 2.3 tag not a 2.2.

$ tag sample.id3v22.mp3
Metadata Format: ID3v2.3
File Type: MP3
 Title: Test Title
 Album: Test Album
 Artist: Test Artist
 Composer: Test Composer
 Genre: Jazz
 Year: 2000
 Track: 3 of 6
 Disc: 2 of 0
 Picture: <nil>
 Lyrics:
 Comment: Test Comment

Ogg Vorbis files where comments span multiple pages cause issues

I have Ogg files which include encoded pictures. These are large (>64k) and the code misreads the lengths of the next part and end up falling off the EOF. Looking at building a simple patch, but not yet had time.

The cmd/tag/main.so reports , for example:

$ go run main.go ~/tmp/09\ -\ The\ Boxer.ogg
error reading file: unexpected EOF

Merge multiple Vorbis (and FLAC) tags

Another small patch, but needs thought:

diff --git a/vorbis.go b/vorbis.go
index c250615..bf8fc96 100644
--- a/vorbis.go
+++ b/vorbis.go
@@ -64,7 +64,11 @@ func (m *metadataVorbis) readVorbisComment(r io.Reader) error {
                if err != nil {
                        return err
                }
-               m.c[strings.ToLower(k)] = v
+               if _, ok := m.c[strings.ToLower(k)]; ok {
+                       m.c[strings.ToLower(k)] = m.c[strings.ToLower(k)] + "\\" + "\\" + v
+               } else {
+                       m.c[strings.ToLower(k)] = v
+               }
        }
        return nil
 }

The convention in many editors and players is two literal backslahes as value separators, but I would also propose being able to pass this down into ReadFrom() perhaps? mediainfo uses " / "

(I know my golang may not be perfectly clean, just learning it coming from C and perl)

Before:

 $ ./tag -raw  '/media/sda/Music/Compilations/Latin Fever/Disc 1 - 01 - Ricky Martin - Livin'\'' La Vida Loca (Pablo Flores English Radio Edit).flac'
Metadata Format: VORBIS
File Type: FLAC
 Title: Livin' La Visa Loca (Pablo Flores English radio edit)
 Album: Latin Fever
 Artist: Ricky Martin
 Composer: Desmond Child
 Genre: Latin
 Year: 2000
 Track: 1 of 19
 Disc: 1 of 2
 Picture: Picture{Ext: jpg, MIMEType: image/jpeg, Type: Cover (front), Description: , Data.Size: 27688}
 Lyrics:
 Comment:

[...]
"style": "Latin Pop"
"composer": "Desmond Child"
...

After:

$ ./tag -raw  '/media/sda/Music/Compilations/Latin Fever/Disc 1 - 01 - Ricky Martin - Livin'\'' La Vida Loca (Pablo Flores English Radio Edit).flac'
Metadata Format: VORBIS
File Type: FLAC
 Title: Livin' La Visa Loca (Pablo Flores English radio edit)
 Album: Latin Fever
 Artist: Ricky Martin
 Composer: Robi Rosa\Desmond Child
 Genre: Latin
 Year: 2000
 Track: 1 of 19
 Disc: 1 of 2
 Picture: Picture{Ext: jpg, MIMEType: image/jpeg, Type: Cover (front), Description: , Data.Size: 27688}
 Lyrics:
 Comment:


[...]
"composer": "Robi Rosa\\Desmond Child"
"style": "Urban\\Early Pop/Rock\\Mambo\\Salsa\\Latin Dance\\Adult Contemporary\\Club/Dance\\Dance-Pop\\Tropical\\Latin Pop"

file-trimmed.zip

Metadata.Picture() returning invalid image

If I try to extract the album art from the attached mp3, I get an invalid image. This is what I get when running tag against the file:

$ tag thoh.mp3
Metadata Format: ID3v2.4
File Type: MP3
 Title: The House Of House (Thomas Schumacher Remix)
 Album: Spiritika 25
 Artist: Cherrymoon Trax
 Composer:
 Genre: Techno
 Year: 2019
 Track: 13 of 0
 Disc: 0 of 0
 Picture: Picture{Ext: , MIMEType: >}, Type: , Description: mage/jpeg, Data.Size: 240139}
 Lyrics:

Note the invalid mime type and description. It's worth to note that I can successfully extract the image with ffmpeg, and iTunes also displays the image with no issues.

thoh.mp3.zip

Thanks

Get picture from OGG file

It seems that the library is not able to get embedded pictures from OGG files. Ex from the attached file:

$ tag 01.ogg
Metadata Format: VORBIS
File Type: OGG
 Title: Over
 Album: Mer de noms
 Artist: Maynard James Keenan (lead vocals)
 Composer: Maynard James Keenan
 Genre: Alternative Rock
 Year: 0
 Track: 12 of 12
 Disc: 1 of 1
 Picture: <nil>
 Lyrics:

01.ogg.zip

Is it a bug? If not, do you have plans to support this?

Encoding error reading file

Running this code:

package main

import (
	"log"
	"os"

	"github.com/dhowden/tag"
)

func main() {
	f, err := os.Open("test.mp3")
	if err != nil {
		log.Fatal(err)
	}
	m, err := tag.ReadFrom(f)
	if err != nil {
		log.Fatal(err)
	}
	log.Println(m.Format())
}

On the attached file (in a zip to get github to accept it) test.zip

Gives this error:

error decoding tag description text: invalid encoding: expected even number of bytes for UTF-16 encoded text

The file has non-ASCII characters in the metadata.
I thought it might be a bad file but windows, foobar, etc. are fine with it and displaying its metadata.

How do you install this?

I read the documentation and Go documentation and nothing is installing. :(

It would be useful to know how to install it. Or perhaps you could provide binary releases?

Allow FLAC files with ID3 tags to be correctly processed

Apologies for not a pull request - I am still learning git and don't want to get it too wrong.

Short patch to check if the ID3 tag is actually on a FLAC file and if so call out to the FLAC tag code. I have a number of older FLAC files with ID3 tags and I am sure others do too. Most other tools also do this.

Edit: updated to actually recover offset correctly
Edit 2: Handle EOF where ID3 block is at the end of the file, like DSF

diff --git a/id3v2.go b/id3v2.go
index 063e6cb..7449e5e 100644
--- a/id3v2.go
+++ b/id3v2.go
@@ -396,6 +396,36 @@ func ReadID3v2Tags(r io.ReadSeeker) (Metadata, error) {
                return nil, err
        }

+       // peek if this is actually a FLAC file first
+       // if it is, call the FLAC reader
+       _, err = r.Seek(int64(h.Size), io.SeekCurrent)
+       if err != nil {
+               return nil,err
+       }
+
+       b, err := readString(r, 4)
+
+       // if EOF then we have skipped an ID3 block at the end of a file, such as DSF
+       if err != io.EOF {
+               if err != nil {
+                       return nil,err
+               }
+
+               _, err = r.Seek(-4, io.SeekCurrent)
+               if err != nil {
+                       return nil,err
+               }
+
+               if (b == "fLaC") {
+                       return ReadFLACTags(r)
+               }
+       }
+
+       _, err = r.Seek(int64(-h.Size), io.SeekCurrent)
+       if err != nil {
+               return nil,err
+       }
+
        var ur io.Reader = r
        if h.Unsynchronisation {
                ur = &unsynchroniser{Reader: r}

The line offsets are from my local fork, but it should just drop in.

Provide AIFF metadata detection

I was wondering if you could support reading standard ID3 tags from .aiff and .aif files, as unlike .wav they don't use RIFF/ID3 tags.

some vulnerability - 0x03 an out-of-bound vulnerability in readTextWithDescrFrame function

This is the third vulnerability in id3v2frames.go

In readTextWithDescrFrame function, you don't check the size of b , program will happen panic when the size of b is 2 or less than 2 .

testcase 8eff69ad26a59a05ec11e38f3ca6c592f08dcc54.zip

panic: runtime error: slice bounds out of range [:3] with capacity 2

goroutine 1 [running]:
github.com/dhowden/tag.readTextWithDescrFrame(0xc0000da038, 0x3, 0x3, 0x101, 0x122b1a0, 0x0, 0x0)
        /Users/jaylin/go/pkg/mod/github.com/dhowden/[email protected]/id3v2frames.go:460 +0x46e
github.com/dhowden/tag.readID3v2Frames(0x114d680, 0xc0000d8000, 0x17, 0xc0000dc000, 0xc0000d8000, 0x0, 0xb)
        /Users/jaylin/go/pkg/mod/github.com/dhowden/[email protected]/id3v2.go:364 +0x90b
github.com/dhowden/tag.ReadID3v2Tags(0x114daa0, 0xc0000d8000, 0x1, 0x0, 0x0, 0x0)
        /Users/jaylin/go/pkg/mod/github.com/dhowden/[email protected]/id3v2.go:428 +0xde
github.com/dhowden/tag.ReadFrom(0x114daa0, 0xc0000d8000, 0xc0000d6000, 0x17, 0x217, 0x0)
        /Users/jaylin/go/pkg/mod/github.com/dhowden/[email protected]/tag.go:52 +0x324
main.main()
        /Users/jaylin/GolandProjects/gofuzz_test/main.go:20 +0xb5

some vulnerability - 0x04 an out-of-bound vulnerability in readAPICFrame function

This is the fourth vulnerability in id3v2frames.go.

In readAPICFrame function, you don't check the size of b parameter. If the b parameter don't end with double zero, the size of mimeDataSplit is one after bytes.SplitN and then program will happen panic beause your check logic is a little late in line 609 .

testcase 09c7c9d4e8fcee39048684570266ce162d9437c7.zip

panic: runtime error: index out of range [1] with length 1

goroutine 1 [running]:
github.com/dhowden/tag.readAPICFrame(0xc0000d403e, 0x2, 0x2, 0x4, 0x122b1a0, 0x0)
        /Users/jaylin/go/pkg/mod/github.com/dhowden/[email protected]/id3v2frames.go:608 +0x556
github.com/dhowden/tag.readID3v2Frames(0x114d680, 0xc0000d2000, 0x60c1844, 0xc0000d6000, 0xc0000d2000, 0x0, 0xb)
        /Users/jaylin/go/pkg/mod/github.com/dhowden/[email protected]/id3v2.go:371 +0x810
github.com/dhowden/tag.ReadID3v2Tags(0x114daa0, 0xc0000d2000, 0x1, 0x0, 0x0, 0x0)
        /Users/jaylin/go/pkg/mod/github.com/dhowden/[email protected]/id3v2.go:428 +0xde
github.com/dhowden/tag.ReadFrom(0x114daa0, 0xc0000d2000, 0xc0000d0000, 0x1b, 0x21b, 0x0)
        /Users/jaylin/go/pkg/mod/github.com/dhowden/[email protected]/tag.go:52 +0x324
main.main()
        /Users/jaylin/GolandProjects/gofuzz_test/main.go:20 +0xb5

Feature Request: expose Duration() for each audio type

Hello!
I'm using your library to parse out information from a variety of different audio files for storage in a database. I'd like to store the duration of each track as well, but it looks like this library doesn't have support for getting each track's duration from the metadata headers yet. To confirm this is possible, I looked through the specs of all the formats currently supported- there are fields in all for retrieving the duration (or length as it's sometimes called). As an example, here's a python library which appears to parse all of them. I would appreciate support for this field! If you are short on time, I will start work on implementing this.

Feature Request: Expose Date() ISO-8601 string

The current Year() API is somewhat lacking. An artist may release multiple albums in one year, but with this API one cannot sort those albums chronologically.

I humbly suggest that we expose a new Date() string{...} method that returns ISO-8601 dates, which is to say, depending on available metadata:

  • empty string (no date metadata found)
  • 2018
  • 2018-01
  • 2018-01-15

If this sounds feasible I might try a hand at writing it myself and putting in a PR, but it seems obvious and I wonder if I'm missing a technical reason why Year() was done the way it was.

panic: runtime error: slice bounds out of range in decodeUTF16

Hello, i stumbled upon a slice bounds out of range bug.
I'm not sure what is the cause but it happens every time i try to process more than 79 files.
From my testing it doesn't seem to be related to a specific file.

Crash log:

panic: runtime error: slice bounds out of range

goroutine 1 [running]:
github.com/dhowden/tag.decodeUTF16(0xc042075053, 0x15, 0x15, 0x545180, 0x5f2908, 0xc042075051, 0x20)
	D:/Projects/go-projects/DirScan/go/src/github.com/dhowden/tag/id3v2frames.go:406 +0x1d4
github.com/dhowden/tag.decodeUTF16WithBOM(0xc042075051, 0x17, 0x17, 0xc04206ac90, 0x2)
	D:/Projects/go-projects/DirScan/go/src/github.com/dhowden/tag/id3v2frames.go:400 +0x9f
github.com/dhowden/tag.decodeText(0xc042075001, 0xc042075051, 0x17, 0x17, 0xc04206ac90, 0x2, 0x2, 0x0)
	D:/Projects/go-projects/DirScan/go/src/github.com/dhowden/tag/id3v2frames.go:329 +0x82
github.com/dhowden/tag.readTextWithDescrFrame(0xc042075050, 0x21, 0x21, 0x100, 0x5f2f60, 0x0, 0x0)
	D:/Projects/go-projects/DirScan/go/src/github.com/dhowden/tag/id3v2frames.go:460 +0x1bb
github.com/dhowden/tag.readID3v2Frames(0x544880, 0xc042076070, 0x120, 0xc042050d60, 0xc042076070, 0x0, 0x0)
	D:/Projects/go-projects/DirScan/go/src/github.com/dhowden/tag/id3v2.go:305 +0xddf
github.com/dhowden/tag.ReadID3v2Tags(0x544ae0, 0xc042076070, 0x1, 0x0, 0x0, 0x0)
	D:/Projects/go-projects/DirScan/go/src/github.com/dhowden/tag/id3v2.go:405 +0xe7
github.com/dhowden/tag.ReadFrom(0x544ae0, 0xc042076070, 0x5450c0, 0xc0422c5a40, 0x0, 0x0)
	D:/Projects/go-projects/DirScan/go/src/github.com/dhowden/tag/tag.go:53 +0x2a0
main.getArtistAlbumTitleYear(0xc0420a1030, 0x61, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, ...)
	D:/Projects/go-projects/DirScan/go/src/main/main.go:259 +0xea
main.main.func1(0xc0420a1030, 0x61, 0x5450c0, 0xc0422c59e0, 0x0, 0x0, 0x0, 0x0)
	D:/Projects/go-projects/DirScan/go/src/main/main.go:77 +0x358
path/filepath.walk(0xc0420a1030, 0x61, 0x5450c0, 0xc0422c59e0, 0xc042050480, 0x0, 0x0)
	C:/Go/src/path/filepath/path.go:357 +0x409
path/filepath.walk(0xc04207c240, 0x3f, 0x5450c0, 0xc0422c5740, 0xc042050480, 0x0, 0x0)
	C:/Go/src/path/filepath/path.go:381 +0x2c9
path/filepath.walk(0x5333bf, 0x25, 0x5450c0, 0xc042098060, 0xc042050480, 0x0, 0x20)
	C:/Go/src/path/filepath/path.go:381 +0x2c9
path/filepath.Walk(0x5333bf, 0x25, 0xc042050480, 0x12, 0x0)
	C:/Go/src/path/filepath/path.go:403 +0x10d
main.main()
	D:/Projects/go-projects/DirScan/go/src/main/main.go:53 +0x481

panic: runtime error: slice bounds out of range in readAtomData

Hello.

I found a slice bounds out of range bug in tag.

Please confirm.

Thanks.

reproduce code:

package tag

import (
	"strings"
	"testing"
)

func TestFuzzCrashers(t *testing.T) {

	var crashers = []string{
		"\x00\x00\x00\bkeyw",

	}

	for _, f := range crashers {
		ReadAtoms(strings.NewReader(f))
	}
}

Crash Log

--- FAIL: TestFuzzCrashers (0.00s)
panic: runtime error: slice bounds out of range [recovered]
	panic: runtime error: slice bounds out of range

goroutine 5 [running]:
testing.tRunner.func1(0xc42004ea90)
	/usr/lib/go-1.8/src/testing/testing.go:622 +0x29d
panic(0x5379a0, 0x605120)
	/usr/lib/go-1.8/src/runtime/panic.go:489 +0x2cf
github.com/dhowden/tag.metadataMP4.readAtomData(0x0, 0x0, 0xc420014cf0, 0x5f5f20, 0xc42000ae00, 0xc42000ef64, 0x4, 0xc400000000, 0x20, 0x5449c0)
	/home/karas/go/src/github.com/dhowden/tag/mp4.go:137 +0xd87
github.com/dhowden/tag.metadataMP4.readAtoms(0x0, 0x0, 0xc420014cf0, 0x5f5f20, 0xc42000ae00, 0x0, 0x0)
	/home/karas/go/src/github.com/dhowden/tag/mp4.go:123 +0x1bf
github.com/dhowden/tag.ReadAtoms(0x5f5f20, 0xc42000ae00, 0xffffffee, 0x1000, 0xc420027f78, 0x4544c3)
	/home/karas/go/src/github.com/dhowden/tag/mp4.go:76 +0x88
github.com/dhowden/tag.TestFuzzCrashers(0xc42004ea90)
	/home/karas/go/src/github.com/dhowden/tag/fuzz_test.go:16 +0xbf
testing.tRunner(0xc42004ea90, 0x568cc8)
	/usr/lib/go-1.8/src/testing/testing.go:657 +0x96
created by testing.(*T).Run
	/usr/lib/go-1.8/src/testing/testing.go:697 +0x2ca
exit status 2
FAIL	github.com/dhowden/tag	0.006s

=================
[Acknowledgement]
This work was supported by ICT R&D program of MSIP/IITP. [R7518-16-1001, Innovation hub for high Performance Computing]

Tag not recognized

This is another file from my library whose tag is not recognized: https://goo.gl/ov75zy

$ tag 04\ The\ Man\ With\ X-Ray\ Eyes.mp3
error reading file: invalid encoding byte 20

This file is recognized normally in a number of other tag tools. I didn't have time to dig into tag's code to figure out what is going on, but I hope the file sample can help. Thanks for this awesome library.

My environment:
Mac OS X 10.11.1
Go 1.6

Same mp3 files with slightly different tags do not produce the same sum

The 2 offending files in a zip file: https://dl.ugjka.net/sumtest.zip

Code:

package main

import (
	"fmt"
	"os"

	"github.com/dhowden/tag"
)

func main() {
	f, _ := os.Open("test.mp3")
	f2, _ := os.Open("test2.mp3")
	fmt.Println(tag.Identify(f))
	fmt.Println(tag.Sum(f))
	fmt.Println(tag.Identify(f2))
	fmt.Println(tag.Sum(f2))
}

Output:

ID3v2.3 MP3 <nil>
533abd81b8664e1371f7013f6453d2cce5ed28f5 <nil>
ID3v2.3 MP3 <nil>
741efd6ba8e88a3d1278160b952ac4b634edc684 <nil>

Why does metadataVorbis#Composer and #Artist return a value that was unasked for?

I encountered this issue with my program alto where I was expecting the %artist% variable to return m.c["artist"], which is the actual artist field defined within the metadata, but it returned m.c["performer"] instead. Unbeknownst to me, I thought this was an error with my code, so after a few minutes of trial and error still yielded the same result. I was puzzled, but then decided to check Windows Explorer and said that the artist field was defined. I was confused at why it wasn't returning m.c["artist"] when Windows Explorer was, but that was when I finally decided to conclude my confusion by going directly to the source only to see the following code:

https://github.com/dhowden/tag/blob/master/vorbis.go#L175-L185

func (m *metadataVorbis) Artist() string {
	// PERFORMER
	// The artist(s) who performed the work. In classical music this would be the
	// conductor, orchestra, soloists. In an audio book it would be the actor who
	// did the reading. In popular music this is typically the same as the ARTIST
	// and is omitted.
	if m.c["performer"] != "" {
		return m.c["performer"]
	}
	return m.c["artist"]
}

It turned out that m.c["performer"] was " " which caused the library to return it instead.

ID3v1 and ID3v2 doesn't do this, so why does Vorbis? Metadata for each audio file varies, and when I call a method like Artist, I expect m.c["artist"], not m.c["performer"].

I was originally thinking about using Metadata#Raw() to mitigate this, but after seeing the note that says that it is an unstable mapping, which was expected, I couldn't risk instability for my program.

Reading ID3v2.4 tags failing

When reading an MP3 with an ID3v2.4 tag, it doesn't read any of the tags.

Edit: this is what I thought, but it's not the case...

I've tracked it down to this: in the song file I have an embedded picture, which has a size that is significantly larger than the size of the header. Hence it reads one picture (which oddly returns with name == "", would actually expect APIC, right?), then offset > h.Size and the loop exits.

This all happens in the readID3v2Frames function.

Feature Request: Writing Tags

Hey Guys and Gals,

I'm not sure if this feature has been requested but I would love to be able to write tags like title, artist, album, etc. as well. Is this a feature that's feasible or could I add it on my own?

Thanks for your great work!

panic on bad APICFrame

I've got a file with a stray null byte at the beginning of the mimetype part of the APICFrame. Attempting to read it causes a panic:

panic: runtime error: index out of range

goroutine 1 [running]:
github.com/dhowden/tag.readAPICFrame(0xc4200102e0, 0xc, 0xc, 0x4, 0x5ef720, 0x0)
         /home/anders/code/go/src/github.com/dhowden/tag/id3v2frames.go:600 +0x55c
github.com/dhowden/tag.readID3v2Frames(0x7fc0a37d2fc0, 0xc42000c028, 0xe9, 0xc42000a100, 
0xc42000c028, 0x0, 0x0)
        /home/anders/code/go/src/github.com/dhowden/tag/id3v2.go:347 +0x796
github.com/dhowden/tag.ReadID3v2Tags(0x5bbac0, 0xc42000c028, 0x1, 0x0, 0x0, 0x0)
        /home/anders/code/go/src/github.com/dhowden/tag/id3v2.go:405 +0xe0
github.com/dhowden/tag.ReadFrom(0x5bbac0, 0xc42000c028, 0xc42000c028, 0x0, 0x0, 0x30)
        /home/anders/code/go/src/github.com/dhowden/tag/tag.go:53 +0x2d2

Digging into it a bit, they bytes being passed into readAPICFrame() are 00 69 6d 61 67 65 2f 6a 70 65 67 00 which is just image/jpeg with a null byte at the beginning and end.

I think the file is invalid so it's fair for the library to refuse to parse it, but it should probably just return an error rather than panicking. It's a pretty simple change to add a if len(b) < 1 check to id3v2frames.go right before line 600.

Installation instructions in README are outdated ("go get" is deprecated)

Hello,

I can't install the package with :
$ go get github.com/dhowden/tag/... because using "go get" is apparently deprecated.
I also tried $ go install github.com/dhowden/tag and $ go install github.com/dhowden/tag@latest but neither works.

Could you please provide clarification for the install?

Crash on malformed input

Hello,

please find attached a reproducer to reproduce the following stacktrace:

goroutine 17 [running, locked to thread]:
--
  | tag.readBytes(0x7f345b63c158, 0x10c000012c00, 0xffffffffffffffff, 0x5599508329b0, 0x55994f5c4840, 0x10c00001a5e4, 0x0, 0x0)
  | third_party/golang/mediatag/util.go:36 +0x42
  | tag.readString(...)
  | third_party/golang/mediatag/util.go:45
  | tag.(*metadataVorbis).readVorbisComment(0x10c000056790, 0x7f345b63c158, 0x10c000012c00, 0x7f345b63c158, 0x10c000012c00)
  | third_party/golang/mediatag/vorbis.go:48 +0x2a9
  | tag.(*metadataFLAC).readFLACMetadataBlock(0x10c000010060, 0x55994f6137c0, 0x10c000012c00, 0x0, 0x0, 0x0)
  | third_party/golang/mediatag/flac.go:77 +0x22a
  | ag.ReadFLACTags(0x55994f6137c0, 0x10c000012c00, 0x1, 0x0, 0x0, 0x0)
  | third_party/golang/mediatag/flac.go:43 +0x194
  | tag.ReadFrom(0x55994f6137c0, 0x10c000012c00, 0x55994d26e896, 0x6, 0x55994d26de4b, 0x4)
  | third_party/golang/mediatag/tag.go:44 +0x442
  | google3/getmeta_fuzz_go_fuzz.FuzzGetMeta(0x62f00000e400, 0xc6d8, 0xc6d8)
  | google3/getmeta_fuzz.go:16 +0xa3
  | google3/getmeta_fuzz_go_fuzz.LLVMFuzzerTestOneInput(0x62f00000e400, 0xc6d8, 0x8)
  | getmeta_fuzz_gen.go:33 +0x66
  | google3/objs/getmeta_fuzz_go_fuzz/_cgo_gotypes.go:56 +0x37
  |  
  | panic: runtime error: makeslice: len out of range

reproducer:

func Fuzz(in []byte) {
	r := bytes.NewReader(in)

	tag.Identify(r)

	m, err := tag.ReadFrom(r)
	if err != nil {
		return
	}

	m.Format()
	m.FileType()
	m.Title()
	m.Album()
	m.Artist()
	m.AlbumArtist()
	m.Composer()
	m.Year()
	m.Genre()
	m.Track()
	m.Disc()
	m.Picture()
	m.Lyrics()

	tag.Sum(r)
}

clusterfuzz-testcase-minimized-getmeta_fuzz-5120942988066816.zip

Picture tag is reading as `int`

I found a weird problem with this file: https://www.dropbox.com/s/avnkb5hro9g1jgc/05%20Freaky.m4a?dl=0

When trying to get the Picture from it, tag panics trying to convert an int(!!) to *tag.Picture, as you can see in the stack trace:

$ tag ~/Downloads/05\ Freaky.m4a
Metadata Format: MP4
File Type:
 Title: Freaky
 Album: Goddess
 Artist: SOHO
 Composer: SOHO
 Genre: 'lectricPop
 Year: 1990
 Track: 5 of 12
 Disc: 0 of 0
panic: interface conversion: interface {} is int, not *tag.Picture

goroutine 1 [running]:
panic(0x170300, 0xc82000e4c0)
    /usr/local/Cellar/go/1.6/libexec/src/runtime/panic.go:464 +0x3e6
github.com/dhowden/tag.(*metadataMP4).Picture(0xc82000a460, 0x10)
    <autogenerated>:97 +0x13b
main.printMetadata(0x32b468, 0xc82000a460)
    /Users/deluan/Development/go/src/github.com/dhowden/tag/tag/tag.go:100 +0xbb6
main.main()
    /Users/deluan/Development/go/src/github.com/dhowden/tag/tag/tag.go:56 +0x3d3

My environment:

  • GoLang 1.6
  • Mac OS X 10.11.1

panic: runtime error: slice bounds out of range in readCustomAtom

Hello.

I found a slice bounds out of range bug in tag.

Please confirm.

Thanks.

reproduce code:

package tag

import (
	"strings"
	"testing"
)

func TestFuzzCrashers(t *testing.T) {

	var crashers = []string{
		"0000meta00\x00\b\xda\xca\x15\x1fmeta" +
		"\x00ETCO\x00\x00\xcameta\u007f\x00\x00\b\x00\x00\x02\xca" +
		"----\x00\x00\x00\bname",
	}

	for _, f := range crashers {
		ReadAtoms(strings.NewReader(f))
	}
}

Log

--- FAIL: TestFuzzCrashers (0.00s)
panic: runtime error: slice bounds out of range [recovered]
	panic: runtime error: slice bounds out of range

goroutine 5 [running]:
testing.tRunner.func1(0xc42004ec30)
	/usr/lib/go-1.8/src/testing/testing.go:622 +0x29d
panic(0x5379a0, 0x605120)
	/usr/lib/go-1.8/src/runtime/panic.go:489 +0x2cf
github.com/dhowden/tag.readCustomAtom(0x5f5f20, 0xc42000ae00, 0xc4000002c2, 0x4, 0x6284e0, 0x0, 0x0, 0x4)
	/home/karas/go/src/github.com/dhowden/tag/mp4.go:223 +0x575
github.com/dhowden/tag.metadataMP4.readAtoms(0x0, 0x0, 0xc420014cf0, 0x5f5f20, 0xc42000ae00, 0x4, 0x0)
	/home/karas/go/src/github.com/dhowden/tag/mp4.go:105 +0x274
github.com/dhowden/tag.metadataMP4.readAtoms(0x0, 0x0, 0xc420014cf0, 0x5f5f20, 0xc42000ae00, 0x4, 0x0)
	/home/karas/go/src/github.com/dhowden/tag/mp4.go:100 +0x3b4
github.com/dhowden/tag.metadataMP4.readAtoms(0x0, 0x0, 0xc420014cf0, 0x5f5f20, 0xc42000ae00, 0x4, 0x0)
	/home/karas/go/src/github.com/dhowden/tag/mp4.go:100 +0x3b4
github.com/dhowden/tag.metadataMP4.readAtoms(0x0, 0x0, 0xc420014cf0, 0x5f5f20, 0xc42000ae00, 0x0, 0x0)
	/home/karas/go/src/github.com/dhowden/tag/mp4.go:100 +0x3b4
github.com/dhowden/tag.ReadAtoms(0x5f5f20, 0xc42000ae00, 0xffffffee, 0x1000, 0xc420027f78, 0x4544c3)
	/home/karas/go/src/github.com/dhowden/tag/mp4.go:76 +0x88
github.com/dhowden/tag.TestFuzzCrashers(0xc42004ec30)
	/home/karas/go/src/github.com/dhowden/tag/fuzz_test.go:17 +0xbf
testing.tRunner(0xc42004ec30, 0x568cf8)
	/usr/lib/go-1.8/src/testing/testing.go:657 +0x96
created by testing.(*T).Run
	/usr/lib/go-1.8/src/testing/testing.go:697 +0x2ca
exit status 2
FAIL	github.com/dhowden/tag	0.006s

=================
[Acknowledgement]
This work was supported by ICT R&D program of MSIP/IITP. [R7518-16-1001, Innovation hub for high Performance Computing]

some vulnerability - 0x02 an out-of-bound vulnerability in readAtomData function

This is the second vulnerability in mp4.go.

In readAtomData function, although you check the size of b , program also will happen panic when the size of b is 3 .

testcase 8a27ec34f36eb99f06de03422f00340f091b7b67.zip

panic: runtime error: slice bounds out of range [:4] with capacity 3

goroutine 1 [running]:
github.com/dhowden/tag.metadataMP4.readAtomData(0x0, 0x0, 0xc000078180, 0x114daa0, 0xc000078150, 0xc0000d4028, 0x4, 0xb, 0x0, 0x0, ...)
        /Users/jaylin/go/pkg/mod/github.com/dhowden/[email protected]/mp4.go:155 +0xe28
github.com/dhowden/tag.metadataMP4.readAtoms(0x0, 0x0, 0xc000078180, 0x114daa0, 0xc000078150, 0x0, 0x0)
        /Users/jaylin/go/pkg/mod/github.com/dhowden/[email protected]/mp4.go:125 +0x16f
github.com/dhowden/tag.ReadAtoms(...)
        /Users/jaylin/go/pkg/mod/github.com/dhowden/[email protected]/mp4.go:76
github.com/dhowden/tag.ReadFrom(0x114daa0, 0xc000078150, 0xc0000d2000, 0x2f, 0x22f, 0x0)
        /Users/jaylin/go/pkg/mod/github.com/dhowden/[email protected]/tag.go:49 +0x3a1
main.main()
        /Users/jaylin/GolandProjects/gofuzz_test/main.go:20 +0xb5

some vulnerability - 0x01 an out-of-bound vulnerability in readPICFrame function

Hello, I found some vulnerability in this respository, they are could be used to cause a denial of service via decode some evil file.

This is the first vulnerability in id3v2frames.go.

In readPICFrame function, you don't check the size of b parameter. If the size of b is zero or less than 6 , program will happen panic.

testcase 147678a9d5f9418743fccc6bd8e9e2ca8f4f2f59.zip

info

panic: runtime error: index out of range [4] with length 4

goroutine 1 [running]:
github.com/dhowden/tag.readPICFrame(0xc00001a114, 0x4, 0x4, 0x3, 0x12733a0, 0x0)
	/Users/jaylin/go/pkg/mod/github.com/dhowden/[email protected]/id3v2frames.go:566 +0x568
github.com/dhowden/tag.readID3v2Frames(0x1182da0, 0xc0000743c0, 0x14, 0xc00000c120, 0xc0000743c0, 0x0, 0xb)
	/Users/jaylin/go/pkg/mod/github.com/dhowden/[email protected]/id3v2.go:378 +0x913
github.com/dhowden/tag.ReadID3v2Tags(0x1183160, 0xc0000743c0, 0x1, 0x0, 0x0, 0x0)
	/Users/jaylin/go/pkg/mod/github.com/dhowden/[email protected]/id3v2.go:428 +0x158
github.com/dhowden/tag.ReadFrom(0x1183160, 0xc0000743c0, 0x106c936, 0x5fb6611c, 0x12044e00, 0xabb5e046976f)
	/Users/jaylin/go/pkg/mod/github.com/dhowden/[email protected]/tag.go:52 +0x486
gofuzz_test/tag.Fuzz(0x4010000, 0x14, 0x14, 0x4)
	/Users/jaylin/GolandProjects/gofuzz_test/tag/tag_fuzzer.go:9 +0xb2
go-fuzz-dep.Main(0xc0000b9f48, 0x1, 0x1)
	go-fuzz-dep/main.go:36 +0x1ad
main.main()
	gofuzz_test/tag/go.fuzz.main/main.go:15 +0x52
exit status 2

flac.parseStreamInfo: invalid FLAC signature

I'm getting flac.parseStreamInfo: invalid FLAC signature; expected "fLaC", got "\xff\xf8\xcb\x1c"

Here is the entire function:

func listFiles() ([]string, error) {
    searchDir := "./"

    fileList := []string{}
    err := filepath.Walk(searchDir, func(path string, f os.FileInfo, err error) error {
            if err != nil {
                    log.Fatal(err)
            }
            fileList = append(fileList, path)
            return nil
    })

    for _, file := range fileList {
            if filepath.Ext(file) == ".flac" {
                    fmt.Println(file)
                    f, err := os.Open(file)
                    m, _ := tag.ReadFrom(f)
                    log.Print(m.Title())
                    streamer, format, err := flac.Decode(f)
                    if err != nil {
                            log.Fatal(err)
                    }
                    defer streamer.Close()

                    speaker.Init(format.SampleRate, format.SampleRate.N(time.Second/10))

                    done := make(chan bool)

                    speaker.Play(beep.Seq(streamer, beep.Callback(func() {
                            done <- true
                    })))
                    <-done
            }
    }
    return fileList, err
}

What am i doing wrong? It happens with different flac files from different albums.

Vorbis AlbumArtist tag

From the source file vorbis.go:179:

func (m *metadataVorbis) AlbumArtist() string {
    // This field isn't included in the standard.
    return ""
}

It may not be included in the standard, I have found that many FLAC files nonetheless use the field albumartist; this is also supported by a least a few media applications. I haven't done any extensive testing, but it seems to work. Additionally, when converting a FLAC file to MP3, this field is used to populate the ID3 AlbumArtist tag.

I propose therefore to change this to simply return that field.

Sum changes when mp3 tag metadata changes

I copied an mp3 file and changed the tag info (album, title, and artist), and hashed the origin and the copy, and they came up as different values.

The format of the files was ID3v2.3

mp4: multiple data atoms can cause size overflow and hang

A mis-sized data atom can cause a condition where the size calculation overflows, creating a hang condition. The size should be checked in the readCustomAtom function to prevent an overflow.

m4a file demonstrating this issue can be provided upon request.

Year() not working for ID3v2.4

Hi,

I tagged an mp3 using windows 10 explorer with a year tag = 2017, but calling tags.Year() always returns 0, even as I can read that the correct year is in the Metadata object.

The code:

package main

import (
	"os"
	"fmt"
	"github.com/dhowden/tag"
)

func main() {
	file, _ := os.OpenFile("test.mp3", os.O_RDONLY, 0666)
	defer file.Close()

	tags, _ := tag.ReadFrom(file)
	fmt.Println(tags)
	fmt.Println(tags.Format())
	fmt.Println(tags.Year())
}

the result:

{0xc042002720 map[TPE1:Artist #1 TDRC:2017 TRCK:1 TALB:Artist #1 - Album #1 TIT2:Artist #1 - Album #1 - Track #1 TCON:Genre #1]}
ID3v2.4
0

metadataID3v2.Year() seems to be reading the frame TYER and not the frame TDRC in which in my case the year is stored.
This issue is mentionned in #14 but it seems it has not been fixed.

I attached the mp3 test file.
test.zip

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.