mp3file 0.0.4 → 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 239aaea4897a1eb4494c5a1668ef5a8ce3e40645
4
+ data.tar.gz: eeeadc21db81420c767b4dd89283d30a3fa17436
5
+ SHA512:
6
+ metadata.gz: f1ff36c98e1ad5c084664cad9cc85d5b3d9c31bfd18d559295a259876410d1f55bdc656a4bc0cf7065c5ce94fbd6db88621674b33127daed3158eeda557cf512
7
+ data.tar.gz: 1abdf307e37627eecb33a813c1f205ffcec20ea8678c3943dd1f5f80354baf96c47f2949bfa29f3ab850c740230ee29b0724a22cd12d95f505663123a3648304
@@ -0,0 +1,22 @@
1
+ # Auto detect text files and perform LF normalization
2
+ * text=auto
3
+
4
+ # Custom for Visual Studio
5
+ *.cs diff=csharp
6
+ *.sln merge=union
7
+ *.csproj merge=union
8
+ *.vbproj merge=union
9
+ *.fsproj merge=union
10
+ *.dbproj merge=union
11
+
12
+ # Standard to msysgit
13
+ *.doc diff=astextplain
14
+ *.DOC diff=astextplain
15
+ *.docx diff=astextplain
16
+ *.DOCX diff=astextplain
17
+ *.dot diff=astextplain
18
+ *.DOT diff=astextplain
19
+ *.pdf diff=astextplain
20
+ *.PDF diff=astextplain
21
+ *.rtf diff=astextplain
22
+ *.RTF diff=astextplain
@@ -0,0 +1 @@
1
+ mp3file
@@ -0,0 +1 @@
1
+ ruby-2.1
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- mp3file (0.0.4)
4
+ mp3file (1.0.0)
5
5
  bindata
6
6
 
7
7
  GEM
@@ -0,0 +1,14 @@
1
+ # Mp3file
2
+
3
+ This is a pure-Ruby MP3 metadata extractor. We use it to identify the
4
+ bitrate and duration of songs that people upload to [http://www.reverbnation.com].
5
+
6
+ It handles a bunch of things:
7
+ * ID3v1 tags
8
+ * ID3v2 tags (although it doesn't actually parse the frames)
9
+ * VBR files (with Xing headers)
10
+ * Multiple ID3v2 tags (because these exist in the wild)
11
+
12
+ Don't think of this as an example of good code. This is some of the
13
+ most terrible, ugly, brutally hacky code I think I've ever written. I
14
+ apologize to anyone who looks at it.
@@ -0,0 +1,80 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ $LOAD_PATH << File.expand_path(File.join(File.dirname(__FILE__), '..', 'lib'))
4
+ require 'mp3file'
5
+
6
+ ARGV.each do |file|
7
+ begin
8
+ mp3 = Mp3file::MP3File.new(file)
9
+
10
+ puts("File: #{mp3.file.path}")
11
+ puts(" Size: #{mp3.file_size} bytes Audio_size: #{mp3.audio_size} bytes")
12
+ puts(" #{mp3.mpeg_version} #{mp3.layer}")
13
+ puts(" Bitrate: #{mp3.bitrate} kbps Samplerate: #{mp3.samplerate} Hz Mode: #{mp3.mode}")
14
+ puts(" Duration: #{mp3.length} s")
15
+ puts(" Frames: #{mp3.num_frames} Samples: #{mp3.total_samples}")
16
+
17
+ header = mp3.first_header
18
+ puts(" First MPEG frame at #{mp3.first_header_offset} bytes:")
19
+ puts(" #{header.version} #{header.layer}")
20
+ puts(" Bitrate: #{header.bitrate} bps Samplerate: #{header.samplerate} Hz")
21
+ puts(" Mode: #{header.mode} Mode Extension: #{header.mode_extension} Emphasis: #{header.emphasis}")
22
+ puts(" CRC: #{header.has_crc} Padding: #{header.has_padding}")
23
+ puts(" Copyright: #{header.copyright} Original: #{header.original}")
24
+ puts(" Samples: #{header.samples} Frame size: #{header.frame_size} Side bytes: #{header.side_bytes}")
25
+
26
+ if mp3.xing_header
27
+ xing = mp3.xing_header
28
+ puts(" Xing header:")
29
+ puts(" Frames: #{xing.frames} Bytes: #{xing.bytes} Quality: #{xing.quality} TOC: #{xing.toc ? 'present' : 'not present'}")
30
+ end
31
+
32
+ if mp3.vbri_header
33
+ puts(" VBRI header!")
34
+ end
35
+
36
+ if mp3.id3v1tag?
37
+ tag = mp3.id3v1_tag
38
+ puts(" ID3v1 tag:")
39
+ puts(" Title: #{tag.title.inspect}")
40
+ puts(" Artist: #{tag.artist.inspect}")
41
+ puts(" Album: #{tag.album.inspect}")
42
+ puts(" Year: #{tag.year.inspect}")
43
+ puts(" Comment: #{tag.comment.inspect}")
44
+ puts(" Genre: #{tag.genre.inspect} (#{tag.genre_id.inspect})")
45
+ end
46
+
47
+ if mp3.id3v2tag?
48
+ tag = mp3.id3v2_tag
49
+ puts(" ID3v2 tag:")
50
+ puts(" Size: #{tag.size} bytes")
51
+ puts(" Version: #{tag.version.inspect}")
52
+ puts(" Unused byes: #{tag.unused_bytes.inspect}")
53
+ if !tag.frames.empty?
54
+ puts(" Frames:")
55
+ tag.frames.each do |frame|
56
+ puts(" ID: #{frame.frame_id.inspect} size: #{frame.frame_size}")
57
+ end
58
+ end
59
+ end
60
+
61
+ mp3.extra_id3v2_tags.each do |offset, tag2|
62
+ puts(" Extra ID3v2 tag:")
63
+ puts(" Offset: #{offset} bytes")
64
+ puts(" Size: #{tag2.size} bytes")
65
+ puts(" Version: #{tag2.version.inspect}")
66
+ puts(" Unused byes: #{tag2.unused_bytes.inspect}")
67
+ if !tag2.frames.empty?
68
+ puts(" Frames:")
69
+ tag2.frames.each do |frame|
70
+ puts(" ID: #{frame.frame_id.inspect} size: #{frame.frame_size}")
71
+ end
72
+ end
73
+ end
74
+
75
+ puts
76
+ rescue
77
+ $stderr.puts("Exception reading MP3 file %s: %s (%p)\n\t%s" %
78
+ [ file, $!.message, $!.class, $!.backtrace.join("\n\t") ])
79
+ end
80
+ end
@@ -2,7 +2,7 @@ module Mp3file
2
2
  class InvalidID3v1TagError < Mp3fileError; end
3
3
 
4
4
  class ID3v1Tag
5
- attr_accessor(:title, :artist, :album, :year, :comment, :track, :genre)
5
+ attr_accessor(:title, :artist, :album, :year, :comment, :track, :genre_id, :genre)
6
6
 
7
7
  class ID3v1TagFormat < BinData::Record
8
8
  string(:tag_id, :length => 3, :check_value => lambda { value == 'TAG' })
@@ -35,24 +35,38 @@ module Mp3file
35
35
  Samba Folklore Ballad Power\ Ballad Rhythmic\ Soul Freestyle Duet Punk\ Rock
36
36
  Drum\ Solo A\ capella Euro-House Dance\ Hall }
37
37
 
38
- def initialize(io)
39
- @tag = nil
38
+ def self.parse(io)
39
+ tag_data = nil
40
+
40
41
  begin
41
- @tag = ID3v1TagFormat.read(io)
42
+ tag_data = ID3v1TagFormat.read(io)
42
43
  rescue BinData::ValidityError => ve
43
44
  raise InvalidID3v1TagError, ve.message
44
45
  end
45
46
 
46
- @title = @tag.title.split("\x00").first
47
- @artist = @tag.artist.split("\x00").first
48
- @album = @tag.album.split("\x00").first
49
- @year = @tag.year
50
- split_comment = @tag.comment.split("\x00").reject { |s| s == '' }
47
+ if tag_data.nil?
48
+ nil
49
+ else
50
+ new.tap { |rv| rv.load_format(tag_data) }
51
+ end
52
+ end
53
+
54
+ def load_format(tag_data)
55
+ @title = tag_data.title.split("\x00").first
56
+ @artist = tag_data.artist.split("\x00").first
57
+ @album = tag_data.album.split("\x00").first
58
+ @year = tag_data.year
59
+ split_comment = tag_data.comment.split("\x00").reject { |s| s == '' }
51
60
  @comment = split_comment.first
52
61
  if split_comment.size > 1
53
62
  @track = split_comment.last.bytes.first
54
63
  end
55
- @genre = GENRES[@tag.genre_id]
64
+ @genre_id = tag_data.genre_id
65
+ @genre = GENRES[tag_data.genre_id]
66
+ end
67
+
68
+ def initialize
69
+ @title = @artist = @album = @year = @comment = @track = @genre_id = @genre = nil
56
70
  end
57
71
  end
58
72
  end
@@ -11,11 +11,11 @@ module Mp3file::ID3v2
11
11
  bit1(:tag_alter_preserve)
12
12
  bit1(:file_alter_preserve)
13
13
  bit1(:read_only)
14
- bit5(:unused1, :check_value => lambda { value == 0 })
14
+ bit5(:unused1) # , :check_value => lambda { value == 0 })
15
15
  bit1(:compression)
16
16
  bit1(:encryption)
17
17
  bit1(:has_group)
18
- bit5(:unused2, :check_value => lambda { value == 0 })
18
+ bit5(:unused2) # , :check_value => lambda { value == 0 })
19
19
  uint8(:encryption_type, :onlyif => lambda { encryption == 1 })
20
20
  uint8(:group_id, :onlyif => lambda { has_group == 1 })
21
21
  end
@@ -23,21 +23,24 @@ module Mp3file::ID3v2
23
23
  class ID3v240FrameHeaderFormat < BinData::Record
24
24
  string(:frame_id, :length => 4)
25
25
  uint32be(:frame_size)
26
- bit1(:unused1, :check_value => lambda { value == 0 })
26
+ bit1(:unused1) # , :check_value => lambda { value == 0 })
27
27
  bit1(:tag_alter_preserve)
28
28
  bit1(:file_alter_preserve)
29
29
  bit1(:read_only)
30
- bit4(:unused2, :check_value => lambda { value == 0 })
31
- bit1(:unused3, :check_value => lambda { value == 0 })
30
+
31
+ bit4(:unused2) # , :check_value => lambda { value == 0 })
32
+
33
+ bit1(:unused3) # , :check_value => lambda { value == 0 })
32
34
  bit1(:group)
33
- bit2(:unused4, :check_value => lambda { value == 0 })
35
+ bit2(:unused4) # , :check_value => lambda { value == 0 })
36
+
34
37
  bit1(:compression)
35
38
  bit1(:encryption)
36
39
  bit1(:unsynchronized)
37
40
  bit1(:data_length_indicator)
38
41
  end
39
42
 
40
- attr_reader(:frame_id, :size,
43
+ attr_reader(:frame_id, :header_size, :frame_size, :size,
41
44
  :preserve_on_altered_tag, :preserve_on_altered_file,
42
45
  :read_only, :compressed, :encrypted, :encryption_type,
43
46
  :group, :unsynchronized, :data_length)
@@ -57,8 +60,10 @@ module Mp3file::ID3v2
57
60
  begin
58
61
  if @tag.version >= ID3V2_2_0 && @tag.version < ID3V2_3_0
59
62
  header = ID3v220FrameHeaderFormat.read(io)
63
+ @header_size = 6
60
64
  elsif @tag.version >= ID3V2_3_0 && @tag.version < ID3V2_4_0
61
65
  header = ID3v230FrameHeaderFormat.read(io)
66
+ @header_size = 10
62
67
  @preserve_on_altered_tag = header.tag_alter_preserve == 1
63
68
  @preserve_on_altered_file = header.file_alter_preserve == 1
64
69
  @read_only = header.read_only == 1
@@ -72,13 +77,15 @@ module Mp3file::ID3v2
72
77
  end
73
78
  elsif @tag.version >= ID3V2_4_0
74
79
  header = ID3v240FrameHeaderFormat.read(io)
80
+ @header_size = 10
75
81
  end
76
82
  rescue BinData::ValidityError => ve
77
83
  raise InvalidID3v2TagError, ve.message
78
84
  end
79
85
 
80
86
  @frame_id = header.frame_id
81
- @size = BitPaddedInt.unpad_number(header.frame_size)
87
+ @frame_size = BitPaddedInt.unpad_number(header.frame_size)
88
+ @size = @header_size + @frame_size
82
89
  end
83
90
  end
84
91
  end
@@ -7,19 +7,53 @@ module Mp3file::ID3v2
7
7
  def_delegators(:@header, :version, :unsynchronized, :extended_header,
8
8
  :compression, :experimental, :footer)
9
9
 
10
- attr_reader(:header, :frames)
10
+ attr_reader(:header, :frames, :unused_bytes)
11
+
12
+ FRAME_HEADER_NAME_REGEX = /[A-Z][A-Z0-9]{2,3}/
11
13
 
12
14
  def initialize(io)
13
15
  @header = Header.new(io)
14
- @frames = []
16
+ load_frames(io)
17
+ used_bytes = @frames.inject(0) { |m, f| m += f.size }
18
+ @unused_bytes = @header.tag_size - used_bytes
15
19
  end
16
20
 
17
- def load_frames
21
+ def load_frames(io)
18
22
  @frames = []
23
+
24
+ data = io.read(@header.tag_size)
25
+ data.force_encoding("ASCII-8BIT")
26
+ offset = 0
27
+
28
+ frame_offset, frame = get_next_frame_header(data, offset)
29
+ while frame
30
+ @frames << frame
31
+ offset = frame_offset + frame.size
32
+ frame_offset, frame = get_next_frame_header(data, offset)
33
+ end
19
34
  end
20
35
 
21
36
  def size
22
37
  @header.tag_size + 10
23
38
  end
39
+
40
+ def get_next_frame_header(data, offset)
41
+ md = data.match(FRAME_HEADER_NAME_REGEX, offset)
42
+
43
+ while md
44
+ frame_offset = md.begin(0)
45
+ io = StringIO.new(data[frame_offset, 32])
46
+ frame = FrameHeader.new(io, self)
47
+
48
+ if frame.frame_id.to_s =~ FRAME_HEADER_NAME_REGEX
49
+ return [ frame_offset, frame ]
50
+ else
51
+ frame_offset = md.end(0) + 1
52
+ md = data.match(FRAME_HEADER_NAME_REGEX, frame_offset)
53
+ end
54
+ end
55
+
56
+ [ nil, nil ]
57
+ end
24
58
  end
25
59
  end
@@ -9,7 +9,7 @@ module Mp3file
9
9
  attr_reader(:mpeg_version, :layer, :bitrate, :samplerate, :mode)
10
10
  attr_reader(:num_frames, :total_samples, :length)
11
11
 
12
- attr_accessor(:id3v1_tag)
12
+ attr_accessor(:id3v1_tag, :id3v2_tag, :extra_id3v2_tags)
13
13
 
14
14
  def initialize(file_path)
15
15
  file_path = Pathname.new(file_path).expand_path if file_path.is_a?(String)
@@ -73,30 +73,57 @@ module Mp3file
73
73
 
74
74
  # Try to read an ID3v1 tag.
75
75
  @id3v1_tag = nil
76
- @file.seek(-128, IO::SEEK_END)
77
76
  begin
78
- @id3v1_tag = ID3v1Tag.new(@file)
79
- rescue InvalidID3v1TagError => e
77
+ @file.seek(-128, IO::SEEK_END)
78
+ @id3v1_tag = ID3v1Tag.parse(@file)
79
+ rescue Mp3file::InvalidID3v1TagError
80
80
  @id3v1_tag = nil
81
+ ensure
82
+ @file.seek(0, IO::SEEK_SET)
81
83
  end
82
- @file.seek(0, IO::SEEK_SET)
83
84
 
84
85
  # Try to detect an ID3v2 header.
85
- @id3v2_header = nil
86
+ @id3v2_tag = nil
86
87
  begin
87
- @id3v2_header = ID3v2::Header.new(@file)
88
- rescue ID3v2::InvalidID3v2TagError => e
89
- @id3v2_header = nil
88
+ @id3v2_tag = ID3v2::Tag.new(@file)
89
+ rescue ID3v2::InvalidID3v2TagError # => e
90
+ # $stderr.puts "Error parsing ID3v2 tag: %s\n\t%s" %
91
+ # [ e.message, e.backtrace.join("\n\t") ]
92
+ @id3v2_tag = nil
90
93
  @file.seek(0, IO::SEEK_SET)
91
94
  end
92
95
 
93
96
  # Skip past the ID3v2 header if it's present.
94
- if @id3v2_header
95
- @file.seek(@id3v2_header.tag_size + 10, IO::SEEK_SET)
97
+ if @id3v2_tag
98
+ @file.seek(@id3v2_tag.size, IO::SEEK_SET)
96
99
  end
97
100
 
98
- # Try to find the first MP3 header.
99
- @first_header_offset, @first_header = get_next_header(@file)
101
+ # Some files have more than one ID3v2 tag. If we can't find an
102
+ # MP3 header in the next 4k, try reading another ID3v2 tag and
103
+ # repeat.
104
+ @extra_id3v2_tags = []
105
+ begin
106
+ # Try to find the first MP3 header.
107
+ @first_header_offset, @first_header = get_next_header(@file)
108
+ rescue InvalidMP3FileError
109
+ end_of_tags = @id3v2_tag.size + @extra_id3v2_tags.map(&:last).map(&:size).reduce(:+).to_i
110
+ @file.seek(end_of_tags, IO::SEEK_SET)
111
+
112
+ tag = nil
113
+ begin
114
+ tag = ID3v2::Tag.new(@file)
115
+ rescue ID3v2::InvalidID3v2TagError
116
+ tag = nil
117
+ @file.seek(end_of_tags, IO::SEEK_SET)
118
+ end
119
+
120
+ if tag
121
+ @extra_id3v2_tags << [ end_of_tags, tag ]
122
+ retry
123
+ else
124
+ raise
125
+ end
126
+ end
100
127
 
101
128
  @mpeg_version = @first_header.version
102
129
  @layer = @first_header.layer
@@ -117,7 +144,7 @@ module Mp3file
117
144
  @file.seek(@first_header.side_bytes, IO::SEEK_CUR)
118
145
  begin
119
146
  @xing_header = XingHeader.new(@file)
120
- rescue InvalidXingHeaderError => ve
147
+ rescue InvalidXingHeaderError
121
148
  @file.seek(@first_header_offset + 4, IO::SEEK_CUR)
122
149
  end
123
150
 
@@ -155,7 +182,7 @@ module Mp3file
155
182
  begin
156
183
  header = MP3Header.new(file)
157
184
  header_offset = file.tell - 4
158
- rescue InvalidMP3HeaderError => e
185
+ rescue InvalidMP3HeaderError
159
186
  header_offset += 1
160
187
  if header_offset - initial_header_offset > 4096
161
188
  raise InvalidMP3FileError, "Could not find a valid MP3 header in the first 4096 bytes."
@@ -1,3 +1,3 @@
1
1
  module Mp3file
2
- VERSION = "0.0.4"
2
+ VERSION = "1.0.0"
3
3
  end
@@ -5,7 +5,7 @@ include CommonHelpers
5
5
 
6
6
  describe Mp3file::ID3v1Tag do
7
7
  it "rejects an ID3v1 tag if it doesn't begin with TAG" do
8
- lambda { Mp3file::ID3v1Tag.new(StringIO.new("\x00" * 128)) }.
8
+ lambda { Mp3file::ID3v1Tag.parse(StringIO.new("\x00" * 128)) }.
9
9
  should(raise_error(Mp3file::InvalidID3v1TagError))
10
10
  end
11
11
 
@@ -17,7 +17,7 @@ describe Mp3file::ID3v1Tag do
17
17
  year = "1996"
18
18
  comment = "This is a comment"; comment += "\x00" * (30 - comment.size)
19
19
  genre = 17.chr
20
- Mp3file::ID3v1Tag.new(StringIO.new('TAG' + title + artist + album + year + comment + genre))
20
+ Mp3file::ID3v1Tag.parse(StringIO.new('TAG' + title + artist + album + year + comment + genre))
21
21
  end
22
22
 
23
23
  its(:title) { should == 'Big Dipper' }
@@ -38,7 +38,7 @@ describe Mp3file::ID3v1Tag do
38
38
  comment = "This is a comment"; comment += "\x00" * (29 - comment.size)
39
39
  tracknum = 3.chr
40
40
  genre = 17.chr
41
- Mp3file::ID3v1Tag.new(StringIO.new('TAG' + title + artist + album + year + comment + tracknum + genre))
41
+ Mp3file::ID3v1Tag.parse(StringIO.new('TAG' + title + artist + album + year + comment + tracknum + genre))
42
42
  end
43
43
 
44
44
  its(:title) { should == 'Big Dipper' }
@@ -51,7 +51,7 @@ describe Mp3file::ID3v1Tag do
51
51
  end
52
52
 
53
53
  describe "When created with a blank ID3v1 tag" do
54
- subject { Mp3file::ID3v1Tag.new(StringIO.new("TAG" + ("\x00" * 125))) }
54
+ subject { Mp3file::ID3v1Tag.parse(StringIO.new("TAG" + ("\x00" * 125))) }
55
55
  its(:title) { should == nil }
56
56
  its(:artist) { should == nil }
57
57
  its(:album) { should == nil }
@@ -26,13 +26,13 @@ describe Mp3file::ID3v2::FrameHeader do
26
26
  context "with ID3v2.3 tags" do
27
27
  let(:tag) { Mp3file::ID3v2::Tag.new(StringIO.new("ID3\x03\x00\x00\x00\x00\x00\x00")) }
28
28
 
29
- describe("A header with invalid flag bits set") do
30
- it("Should raise an error") do
31
- io = StringIO.new("TIT2\x00\x00\x00\x09\x01\x00")
32
- lambda { Mp3file::ID3v2::FrameHeader.new(io, tag) }.
33
- should(raise_error(Mp3file::ID3v2::InvalidID3v2TagError))
34
- end
35
- end
29
+ # describe("A header with invalid flag bits set") do
30
+ # it("Should raise an error") do
31
+ # io = StringIO.new("TIT2\x00\x00\x00\x09\x01\x00")
32
+ # lambda { Mp3file::ID3v2::FrameHeader.new(io, tag) }.
33
+ # should(raise_error(Mp3file::ID3v2::InvalidID3v2TagError))
34
+ # end
35
+ # end
36
36
 
37
37
  describe("A 9-byte TIT2 frame header.") do
38
38
  subject { Mp3file::ID3v2::FrameHeader.new(StringIO.new("TIT2\x00\x00\x00\x09\x00\x00"), tag) }
@@ -68,12 +68,12 @@ describe Mp3file::ID3v2::FrameHeader do
68
68
  context "with ID3v2.4 tags" do
69
69
  let(:tag) { Mp3file::ID3v2::Tag.new(StringIO.new("ID3\x04\x00\x00\x00\x00\x00\x00")) }
70
70
 
71
- describe("A header with invalid flag bits set") do
72
- it("Should raise an error") do
73
- io = StringIO.new("TIT2\x00\x00\x00\x09\x01\x00")
74
- lambda { Mp3file::ID3v2::FrameHeader.new(io, tag) }.
75
- should(raise_error(Mp3file::ID3v2::InvalidID3v2TagError))
76
- end
77
- end
71
+ # describe("A header with invalid flag bits set") do
72
+ # it("Should raise an error") do
73
+ # io = StringIO.new("TIT2\x00\x00\x00\x09\x01\x00")
74
+ # lambda { Mp3file::ID3v2::FrameHeader.new(io, tag) }.
75
+ # should(raise_error(Mp3file::ID3v2::InvalidID3v2TagError))
76
+ # end
77
+ # end
78
78
  end
79
79
  end
@@ -5,11 +5,7 @@ include CommonHelpers
5
5
 
6
6
  describe Mp3file::ID3v2::Tag do
7
7
  describe "An empty tag" do
8
- subject do
9
- t = Mp3file::ID3v2::Tag.new(StringIO.new("ID3\x03\x00\x00\x00\x00\x00\x00"))
10
- t.load_frames
11
- t
12
- end
8
+ subject { Mp3file::ID3v2::Tag.new(StringIO.new("ID3\x03\x00\x00\x00\x00\x00\x00")) }
13
9
  its(:version) { should == Mp3file::ID3v2::ID3V2_3_0 }
14
10
  its(:unsynchronized) { should == false }
15
11
  its(:extended_header) { should == false }
@@ -70,7 +70,7 @@ describe Mp3file::MP3File do
70
70
 
71
71
  describe "A 96 kbps 34 kHz Joint Stereo CBR file with an ID3v2 tag" do
72
72
  subject { Mp3file::MP3File.new(fixture_file('bret_id3v2.mp3')) }
73
- # its(:id3v2tag?) { should == true }
73
+ its(:id3v2tag?) { should == true }
74
74
  its(:id3v1tag?) { should == false }
75
75
  its("file.path") { should == fixture_file('bret_id3v2.mp3').to_s }
76
76
  its("file.closed?") { should == true }
metadata CHANGED
@@ -1,62 +1,74 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: mp3file
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.4
5
- prerelease:
4
+ version: 1.0.0
6
5
  platform: ruby
7
6
  authors:
8
7
  - Andrew Watts
9
8
  autorequire:
10
9
  bindir: bin
11
10
  cert_chain: []
12
- date: 2011-08-02 00:00:00.000000000 -04:00
13
- default_executable:
11
+ date: 2014-11-05 00:00:00.000000000 Z
14
12
  dependencies:
15
13
  - !ruby/object:Gem::Dependency
16
14
  name: rspec
17
- requirement: &12412640 !ruby/object:Gem::Requirement
18
- none: false
15
+ requirement: !ruby/object:Gem::Requirement
19
16
  requirements:
20
- - - ! '>='
17
+ - - ">="
21
18
  - !ruby/object:Gem::Version
22
19
  version: '0'
23
20
  type: :development
24
21
  prerelease: false
25
- version_requirements: *12412640
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: '0'
26
27
  - !ruby/object:Gem::Dependency
27
28
  name: rake
28
- requirement: &12412220 !ruby/object:Gem::Requirement
29
- none: false
29
+ requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
- - - ! '>='
31
+ - - ">="
32
32
  - !ruby/object:Gem::Version
33
33
  version: '0'
34
34
  type: :development
35
35
  prerelease: false
36
- version_requirements: *12412220
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
37
41
  - !ruby/object:Gem::Dependency
38
42
  name: bindata
39
- requirement: &12449280 !ruby/object:Gem::Requirement
40
- none: false
43
+ requirement: !ruby/object:Gem::Requirement
41
44
  requirements:
42
- - - ! '>='
45
+ - - ">="
43
46
  - !ruby/object:Gem::Version
44
47
  version: '0'
45
48
  type: :runtime
46
49
  prerelease: false
47
- version_requirements: *12449280
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
48
55
  description: Reads MP3 headers and returns their information.
49
56
  email:
50
57
  - ahwatts@gmail.com
51
- executables: []
58
+ executables:
59
+ - mp3info
52
60
  extensions: []
53
61
  extra_rdoc_files: []
54
62
  files:
55
- - .gitignore
56
- - .rvmrc
63
+ - ".gitattributes"
64
+ - ".gitignore"
65
+ - ".ruby-gemset"
66
+ - ".ruby-version"
57
67
  - Gemfile
58
68
  - Gemfile.lock
69
+ - README.md
59
70
  - Rakefile
71
+ - bin/mp3info
60
72
  - doc/id3v2.2.0.txt
61
73
  - doc/id3v2.3.0.txt
62
74
  - doc/id3v2.4.0-frames.txt
@@ -90,29 +102,42 @@ files:
90
102
  - spec/mp3file/mp3_file_spec.rb
91
103
  - spec/mp3file/mp3_header_spec.rb
92
104
  - spec/mp3file/xing_header_spec.rb
93
- has_rdoc: true
94
105
  homepage: http://rubygems.org/gems/mp3file
95
106
  licenses: []
107
+ metadata: {}
96
108
  post_install_message:
97
109
  rdoc_options: []
98
110
  require_paths:
99
111
  - lib
100
112
  required_ruby_version: !ruby/object:Gem::Requirement
101
- none: false
102
113
  requirements:
103
- - - ! '>='
114
+ - - ">="
104
115
  - !ruby/object:Gem::Version
105
116
  version: '0'
106
117
  required_rubygems_version: !ruby/object:Gem::Requirement
107
- none: false
108
118
  requirements:
109
- - - ! '>='
119
+ - - ">="
110
120
  - !ruby/object:Gem::Version
111
121
  version: '0'
112
122
  requirements: []
113
123
  rubyforge_project: mp3file
114
- rubygems_version: 1.6.2
124
+ rubygems_version: 2.4.2
115
125
  signing_key:
116
- specification_version: 3
126
+ specification_version: 4
117
127
  summary: Reads MP3 headers and returns their information.
118
- test_files: []
128
+ test_files:
129
+ - spec/common_helpers.rb
130
+ - spec/files/bret_96.mp3
131
+ - spec/files/bret_id3v1.mp3
132
+ - spec/files/bret_id3v2.mp3
133
+ - spec/files/bret_vbr_6.mp3
134
+ - spec/files/zeroes.mp3
135
+ - spec/mp3file/id3v1_tag_spec.rb
136
+ - spec/mp3file/id3v2/bit_padded_int_spec.rb
137
+ - spec/mp3file/id3v2/frame_header_spec.rb
138
+ - spec/mp3file/id3v2/header_spec.rb
139
+ - spec/mp3file/id3v2/tag_spec.rb
140
+ - spec/mp3file/id3v2/version_spec.rb
141
+ - spec/mp3file/mp3_file_spec.rb
142
+ - spec/mp3file/mp3_header_spec.rb
143
+ - spec/mp3file/xing_header_spec.rb
data/.rvmrc DELETED
@@ -1 +0,0 @@
1
- rvm 1.9.2@mp3file