ruby-mp3info 0.6.13 → 0.6.14

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,3 +1,12 @@
1
+ === 0.6.14 / 2011-06-17
2
+
3
+ * Added a check for nil that was seen causing problems when processing files. (thanks to Carl Hall)
4
+ * Fixed reading on win32, requires binary flag. (thanks to Jonas Tingeborn)
5
+ * Fixed white spaces. Replaced tabs with spaces to make the source readable on for users other than the original author. (thanks to Jonas Tingeborn)
6
+ * Add :parse_mp3 flag to new/open. (thanks to Dave Lee)
7
+ * Add benchmark for parsing performance. (thanks to Dave Lee)
8
+ * fixed ID3v2#io_position computing, so Mp3Info#audio_content() is correct now
9
+
1
10
  === 0.6.13 / 2009-05-26
2
11
 
3
12
  * fixed bad mapping of artist inside id3 2.2
@@ -1,6 +1,6 @@
1
1
  History.txt
2
2
  Manifest.txt
3
- README.txt
3
+ README.rdoc
4
4
  Rakefile
5
5
  install.rb
6
6
  lib/mp3info.rb
@@ -3,7 +3,7 @@ ruby-mp3info
3
3
  by Guillaume Pierronnet
4
4
  * http://ruby-mp3info.rubyforge.org/
5
5
  * http://rubyforge.org/projects/ruby-mp3info/
6
- * mercurial repository since v0.6.10: http://www.bitbucket.org/moumar/ruby-mp3info/overview/
6
+ * https://github.com/moumar/ruby-mp3info
7
7
 
8
8
  == DESCRIPTION:
9
9
 
data/Rakefile CHANGED
@@ -2,6 +2,9 @@
2
2
 
3
3
  require 'rubygems'
4
4
  require 'hoe'
5
+
6
+ Hoe.plugin :yard
7
+
5
8
  $:.unshift("./lib/")
6
9
  require 'mp3info'
7
10
 
@@ -10,10 +13,11 @@ Hoe.new('ruby-mp3info', Mp3Info::VERSION) do |p|
10
13
  p.author = "Guillaume Pierronnet"
11
14
  p.email = "moumar@rubyforge.org"
12
15
  p.summary = "ruby-mp3info is a pure-ruby library to retrieve low level informations on mp3 files and manipulate id3v1 and id3v2 tags"
13
- p.description = p.paragraphs_of('README.txt', 5..9).join("\n\n")
14
- p.url = p.paragraphs_of('README.txt', 0).first.split(/\n/)[1..-1]
16
+ p.description = p.paragraphs_of('README.rdoc', 5..9).join("\n\n")
17
+ p.url = p.paragraphs_of('README.rdoc', 0).first.split(/\n/)[1..-1]
15
18
  p.changes = p.paragraphs_of('History.txt', 0..1).join("\n\n")
16
19
  p.remote_rdoc_dir = ''
20
+ p.rdoc_locations << "rubyforge.org:/var/www/gforge-projects/ruby-mp3info/"
17
21
  end
18
22
 
19
23
  # vim: syntax=Ruby
@@ -1,5 +1,4 @@
1
1
  # coding:utf-8
2
- # $Id: mp3info.rb 98 2008-09-16 11:07:31Z moumar $
3
2
  # License:: Ruby
4
3
  # Author:: Guillaume Pierronnet (mailto:moumar_AT__rubyforge_DOT_org)
5
4
  # Website:: http://ruby-mp3info.rubyforge.org/
@@ -18,7 +17,7 @@ end
18
17
 
19
18
  class Mp3Info
20
19
 
21
- VERSION = "0.6.13"
20
+ VERSION = "0.6.14"
22
21
 
23
22
  LAYER = [ nil, 3, 2, 1]
24
23
  BITRATE = {
@@ -161,7 +160,7 @@ class Mp3Info
161
160
 
162
161
  # Test the presence of an id3v1 tag in file +filename+
163
162
  def self.hastag1?(filename)
164
- File.open(filename) { |f|
163
+ File.open(filename,"rb") { |f|
165
164
  f.seek(-TAG1_SIZE, File::SEEK_END)
166
165
  f.read(3) == "TAG"
167
166
  }
@@ -169,7 +168,7 @@ class Mp3Info
169
168
 
170
169
  # Test the presence of an id3v2 tag in file +filename+
171
170
  def self.hastag2?(filename)
172
- File.open(filename) { |f|
171
+ File.open(filename,"rb") { |f|
173
172
  f.read(3) == "ID3"
174
173
  }
175
174
  end
@@ -191,15 +190,15 @@ class Mp3Info
191
190
 
192
191
  # Instantiate Mp3Info object with name +filename+.
193
192
  # options hash is used for ID3v2#new.
194
- # You can specify :parse_tags => false to disable the processing
193
+ # Specify :parse_tags => false to disable the processing
195
194
  # of the tags (read and write).
195
+ # Specify :parse_mp3 => false to disable processing of the mp3
196
196
  def initialize(filename, options = {})
197
197
  warn("#{self.class}::new() does not take block; use #{self.class}::open() instead") if block_given?
198
198
  @filename = filename
199
+ options = {:parse_mp3 => true, :parse_tags => true}.update(options)
199
200
  @tag_parsing_enabled = options.delete(:parse_tags)
200
- if @tag_parsing_enabled == nil
201
- @tag_parsing_enabled = true
202
- end
201
+ @mp3_parsing_enabled = options.delete(:parse_mp3)
203
202
  @id3v2_options = options
204
203
  reload
205
204
  end
@@ -249,74 +248,10 @@ class Mp3Info
249
248
  @tag_orig = @tag.dup
250
249
  end
251
250
 
252
-
253
- ### extracts MPEG info from MPEG header and stores it in the hash @mpeg
254
- ### head (fixnum) = valid 4 byte MPEG header
255
-
256
- found = false
257
-
258
- head = nil
259
- 5.times do
260
- head = find_next_frame()
261
- @first_frame_pos = @file.pos - 4
262
- current_frame = Mp3Info.get_frames_infos(head)
263
- @mpeg_version = current_frame[:mpeg_version]
264
- @layer = current_frame[:layer]
265
- @header[:error_protection] = head[16] == 0 ? true : false
266
- @bitrate = current_frame[:bitrate]
267
- @samplerate = current_frame[:samplerate]
268
- @header[:padding] = current_frame[:padding]
269
- @header[:private] = head[8] == 0 ? true : false
270
- @channel_mode = CHANNEL_MODE[@channel_num = Mp3Info.bits(head, 7,6)]
271
- @header[:mode_extension] = Mp3Info.bits(head, 5,4)
272
- @header[:copyright] = (head[3] == 1 ? true : false)
273
- @header[:original] = (head[2] == 1 ? true : false)
274
- @header[:emphasis] = Mp3Info.bits(head, 1,0)
275
- @vbr = false
276
- found = true
277
- break
251
+ if @mp3_parsing_enabled
252
+ parse_mp3
278
253
  end
279
254
 
280
- raise(Mp3InfoError, "Cannot find good frame") unless found
281
-
282
- seek = @mpeg_version == 1 ?
283
- (@channel_num == 3 ? 17 : 32) :
284
- (@channel_num == 3 ? 9 : 17)
285
-
286
- @file.seek(seek, IO::SEEK_CUR)
287
-
288
- vbr_head = @file.read(4)
289
- if vbr_head == "Xing"
290
- puts "Xing header (VBR) detected" if $DEBUG
291
- flags = @file.get32bits
292
- stream_size = frame_count = 0
293
- flags[1] == 1 and frame_count = @file.get32bits
294
- flags[2] == 1 and stream_size = @file.get32bits
295
- puts "#{frame_count} frames" if $DEBUG
296
- raise(Mp3InfoError, "bad VBR header") if frame_count.zero?
297
- # currently this just skips the TOC entries if they're found
298
- @file.seek(100, IO::SEEK_CUR) if flags[0] == 1
299
- #@vbr_quality = @file.get32bits if flags[3] == 1
300
-
301
- samples_per_frame = SAMPLES_PER_FRAME[@layer][@mpeg_version]
302
- @length = frame_count * samples_per_frame / Float(@samplerate)
303
-
304
- @bitrate = (((stream_size/frame_count)*@samplerate)/144) / 1024
305
- @vbr = true
306
- else
307
- # for cbr, calculate duration with the given bitrate
308
- stream_size = @file.stat.size - (hastag1? ? TAG1_SIZE : 0) - (@tag2.io_position || 0)
309
- @length = ((stream_size << 3)/1000.0)/@bitrate
310
- # read the first 100 frames and decide if the mp3 is vbr and needs full scan
311
- begin
312
- bitrate, length = frame_scan(100)
313
- if @bitrate != bitrate
314
- @vbr = true
315
- @bitrate, @length = frame_scan
316
- end
317
- rescue Mp3InfoInternalError
318
- end
319
- end
320
255
  ensure
321
256
  @file.close
322
257
  end
@@ -403,9 +338,9 @@ class Mp3Info
403
338
 
404
339
  # @tag1 has precedence over @tag
405
340
  if @tag1 == @tag1_orig
406
- @tag.each do |k, v|
407
- @tag1[k] = v
408
- end
341
+ @tag.each do |k, v|
342
+ @tag1[k] = v
343
+ end
409
344
  end
410
345
 
411
346
  # ruby-mp3info can only write v2.3 tags
@@ -452,28 +387,28 @@ class Mp3Info
452
387
  raise(Mp3InfoError, "file is not writable") unless File.writable?(@filename)
453
388
  tempfile_name = nil
454
389
  File.open(@filename, 'rb+') do |file|
455
- #if tag2 already exists, seek to end of it
456
- if @tag2.parsed?
457
- file.seek(@tag2.io_position)
458
- end
390
+ #if tag2 already exists, seek to end of it
391
+ if @tag2.parsed?
392
+ file.seek(@tag2.io_position)
393
+ end
459
394
  # if @file.read(3) == "ID3"
460
395
  # version_maj, version_min, flags = @file.read(3).unpack("CCB4")
461
396
  # unsync, ext_header, experimental, footer = (0..3).collect { |i| flags[i].chr == '1' }
462
- # tag2_len = @file.get_syncsafe
397
+ # tag2_len = @file.get_syncsafe
463
398
  # @file.seek(@file.get_syncsafe - 4, IO::SEEK_CUR) if ext_header
464
- # @file.seek(tag2_len, IO::SEEK_CUR)
399
+ # @file.seek(tag2_len, IO::SEEK_CUR)
465
400
  # end
466
- tempfile_name = @filename + ".tmp"
467
- File.open(tempfile_name, "wb") do |tempfile|
468
- unless @tag2.empty?
469
- tempfile.write(@tag2.to_bin)
470
- end
471
-
472
- bufsiz = file.stat.blksize || 4096
473
- while buf = file.read(bufsiz)
474
- tempfile.write(buf)
475
- end
476
- end
401
+ tempfile_name = @filename + ".tmp"
402
+ File.open(tempfile_name, "wb") do |tempfile|
403
+ unless @tag2.empty?
404
+ tempfile.write(@tag2.to_bin)
405
+ end
406
+
407
+ bufsiz = file.stat.blksize || 4096
408
+ while buf = file.read(bufsiz)
409
+ tempfile.write(buf)
410
+ end
411
+ end
477
412
  end
478
413
  File.rename(tempfile_name, @filename)
479
414
  end
@@ -499,7 +434,7 @@ class Mp3Info
499
434
  # counter, or whatever you like ;) +frame+ is a hash with the following keys:
500
435
  # :layer, :bitrate, :samplerate, :mpeg_version, :padding and :size (in bytes)
501
436
  def each_frame
502
- File.open(@filename, 'r') do |file|
437
+ File.open(@filename, 'rb') do |file|
503
438
  file.seek(@first_frame_pos, File::SEEK_SET)
504
439
  loop do
505
440
  head = file.read(4).unpack("N").first
@@ -639,6 +574,75 @@ private
639
574
  [average_bitrate, length]
640
575
  end
641
576
 
577
+ def parse_mp3
578
+ ### extracts MPEG info from MPEG header and stores it in the hash @mpeg
579
+ ### head (fixnum) = valid 4 byte MPEG header
580
+
581
+ found = false
582
+
583
+ head = nil
584
+ 5.times do
585
+ head = find_next_frame()
586
+ @first_frame_pos = @file.pos - 4
587
+ current_frame = Mp3Info.get_frames_infos(head)
588
+ @mpeg_version = current_frame[:mpeg_version]
589
+ @layer = current_frame[:layer]
590
+ @header[:error_protection] = head[16] == 0 ? true : false
591
+ @bitrate = current_frame[:bitrate]
592
+ @samplerate = current_frame[:samplerate]
593
+ @header[:padding] = current_frame[:padding]
594
+ @header[:private] = head[8] == 0 ? true : false
595
+ @channel_mode = CHANNEL_MODE[@channel_num = Mp3Info.bits(head, 7,6)]
596
+ @header[:mode_extension] = Mp3Info.bits(head, 5,4)
597
+ @header[:copyright] = (head[3] == 1 ? true : false)
598
+ @header[:original] = (head[2] == 1 ? true : false)
599
+ @header[:emphasis] = Mp3Info.bits(head, 1,0)
600
+ @vbr = false
601
+ found = true
602
+ break
603
+ end
604
+
605
+ raise(Mp3InfoError, "Cannot find good frame") unless found
606
+
607
+ seek = @mpeg_version == 1 ?
608
+ (@channel_num == 3 ? 17 : 32) :
609
+ (@channel_num == 3 ? 9 : 17)
610
+
611
+ @file.seek(seek, IO::SEEK_CUR)
612
+
613
+ vbr_head = @file.read(4)
614
+ if vbr_head == "Xing"
615
+ puts "Xing header (VBR) detected" if $DEBUG
616
+ flags = @file.get32bits
617
+ stream_size = frame_count = 0
618
+ flags[1] == 1 and frame_count = @file.get32bits
619
+ flags[2] == 1 and stream_size = @file.get32bits
620
+ puts "#{frame_count} frames" if $DEBUG
621
+ raise(Mp3InfoError, "bad VBR header") if frame_count.zero?
622
+ # currently this just skips the TOC entries if they're found
623
+ @file.seek(100, IO::SEEK_CUR) if flags[0] == 1
624
+ #@vbr_quality = @file.get32bits if flags[3] == 1
625
+
626
+ samples_per_frame = SAMPLES_PER_FRAME[@layer][@mpeg_version]
627
+ @length = frame_count * samples_per_frame / Float(@samplerate)
628
+
629
+ @bitrate = (((stream_size/frame_count)*@samplerate)/144) / 1024
630
+ @vbr = true
631
+ else
632
+ # for cbr, calculate duration with the given bitrate
633
+ stream_size = @file.stat.size - (hastag1? ? TAG1_SIZE : 0) - (@tag2.io_position || 0)
634
+ @length = ((stream_size << 3)/1000.0)/@bitrate
635
+ # read the first 100 frames and decide if the mp3 is vbr and needs full scan
636
+ begin
637
+ bitrate, length = frame_scan(100)
638
+ if @bitrate != bitrate
639
+ @vbr = true
640
+ @bitrate, @length = frame_scan
641
+ end
642
+ rescue Mp3InfoInternalError
643
+ end
644
+ end
645
+ end
642
646
 
643
647
  ### returns the selected bit range (b, a) as a number
644
648
  ### NOTE: b > a if not, returns 0
@@ -1,3 +1,8 @@
1
+ # coding:utf-8
2
+ # License:: Ruby
3
+ # Author:: Guillaume Pierronnet (mailto:moumar_AT__rubyforge_DOT_org)
4
+ # Website:: http://ruby-mp3info.rubyforge.org/
5
+
1
6
  class Mp3Info
2
7
  module HashKeys #:nodoc:
3
8
  ### lets you specify hash["key"] as hash.key
@@ -18,7 +23,7 @@ class Mp3Info
18
23
  alias getbyte []
19
24
  else
20
25
  def getbyte(i)
21
- self[i].ord
26
+ self[i].ord unless self[i].nil?
22
27
  end
23
28
  end
24
29
  end
@@ -1,3 +1,8 @@
1
+ # coding:utf-8
2
+ # License:: Ruby
3
+ # Author:: Guillaume Pierronnet (mailto:moumar_AT__rubyforge_DOT_org)
4
+ # Website:: http://ruby-mp3info.rubyforge.org/
5
+
1
6
  require "delegate"
2
7
  require "iconv"
3
8
 
@@ -223,7 +228,6 @@ class ID3v2 < DelegateClass(Hash)
223
228
  raise(ID3v2Error, "can't find version_maj ('#{version_maj}')") unless [2, 3, 4].include?(version_maj)
224
229
  @version_maj, @version_min = version_maj, version_min
225
230
  @tag_length = @io.get_syncsafe
226
- @io_position = original_pos + @tag_length
227
231
 
228
232
  @parsed = true
229
233
  begin
@@ -238,6 +242,8 @@ class ID3v2 < DelegateClass(Hash)
238
242
  rescue ID3v2Error => e
239
243
  warn("warning: id3v2 tag not fully parsed: #{e.message}")
240
244
  end
245
+ @io_position = @io.pos
246
+ @tag_length = @io_position - original_pos
241
247
 
242
248
  @hash_orig = @hash.dup
243
249
  #no more reading
@@ -339,7 +345,7 @@ class ID3v2 < DelegateClass(Hash)
339
345
  end
340
346
  end
341
347
  # remove padding zeros for textual tags
342
- out.sub!(/\0*$/, '')
348
+ out.sub!(/\0*$/, '') unless out.nil?
343
349
  return out
344
350
  else
345
351
  return raw_value
@@ -441,6 +441,16 @@ class Mp3InfoTest < Test::Unit::TestCase
441
441
  end
442
442
  end
443
443
 
444
+ def test_audio_content_problematic
445
+ File.open(TEMP_FILE, "w") { |f| f.write(FIXTURES["audio_content_fixture"]) }
446
+ Mp3Info.open(TEMP_FILE) do |mp3|
447
+ expected_pos = 150
448
+ audio_content_pos, audio_content_size = mp3.audio_content
449
+ assert_equal expected_pos, audio_content_pos
450
+ assert_equal File.size(TEMP_FILE) - expected_pos, audio_content_size
451
+ end
452
+ end
453
+
444
454
  def test_headerless_vbr_file
445
455
  mp3_length = 3
446
456
  # this will generate a 15 sec mp3 file (44100hz*16bit*2channels) = 60/4 = 15
metadata CHANGED
@@ -1,7 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ruby-mp3info
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.6.13
4
+ hash: 27
5
+ prerelease:
6
+ segments:
7
+ - 0
8
+ - 6
9
+ - 14
10
+ version: 0.6.14
5
11
  platform: ruby
6
12
  authors:
7
13
  - Guillaume Pierronnet
@@ -9,20 +15,80 @@ autorequire:
9
15
  bindir: bin
10
16
  cert_chain: []
11
17
 
12
- date: 2009-05-26 00:00:00 +02:00
13
- default_executable:
18
+ date: 2011-06-17 00:00:00 Z
14
19
  dependencies:
15
20
  - !ruby/object:Gem::Dependency
16
- name: hoe
21
+ name: hoe-yard
22
+ prerelease: false
23
+ requirement: &id001 !ruby/object:Gem::Requirement
24
+ none: false
25
+ requirements:
26
+ - - ">="
27
+ - !ruby/object:Gem::Version
28
+ hash: 31
29
+ segments:
30
+ - 0
31
+ - 1
32
+ - 2
33
+ version: 0.1.2
17
34
  type: :development
18
- version_requirement:
19
- version_requirements: !ruby/object:Gem::Requirement
35
+ version_requirements: *id001
36
+ - !ruby/object:Gem::Dependency
37
+ name: hoe
38
+ prerelease: false
39
+ requirement: &id002 !ruby/object:Gem::Requirement
40
+ none: false
20
41
  requirements:
21
42
  - - ">="
22
43
  - !ruby/object:Gem::Version
23
- version: 1.9.0
24
- version:
25
- description: "* written in pure ruby * read low-level informations like bitrate, length, samplerate, etc... * read, write, remove id3v1 and id3v2 tags * correctly read VBR files (with or without Xing header) * only 2.3 version is supported for writings id3v2 tags == SYNOPSIS: a good exercise is to read the test.rb to understand how the library works deeper require \"mp3info\" # read and display infos & tags Mp3Info.open(\"myfile.mp3\") do |mp3info| puts mp3info end # read/write tag1 and tag2 with Mp3Info#tag attribute # when reading tag2 have priority over tag1 # when writing, each tag is written. Mp3Info.open(\"myfile.mp3\") do |mp3| puts mp3.tag.title puts mp3.tag.artist puts mp3.tag.album puts mp3.tag.tracknum mp3.tag.title = \"track title\" mp3.tag.artist = \"artist name\" end Mp3Info.open(\"myfile.mp3\") do |mp3| # you can access four letter v2 tags like this puts mp3.tag2.TIT2 mp3.tag2.TIT2 = \"new TIT2\" # or like that mp3.tag2[\"TIT2\"] # at this time, only COMM tag is processed after reading and before writing # according to ID3v2#options hash mp3.tag2.options[:lang] = \"FRE\" mp3.tag2.COMM = \"my comment in french, correctly handled when reading and writing\" end"
44
+ hash: 47
45
+ segments:
46
+ - 2
47
+ - 8
48
+ - 0
49
+ version: 2.8.0
50
+ type: :development
51
+ version_requirements: *id002
52
+ description: |-
53
+ * written in pure ruby
54
+ * read low-level informations like bitrate, length, samplerate, etc...
55
+ * read, write, remove id3v1 and id3v2 tags
56
+ * correctly read VBR files (with or without Xing header)
57
+ * only 2.3 version is supported for writings id3v2 tags
58
+
59
+ == SYNOPSIS:
60
+
61
+ a good exercise is to read the test.rb to understand how the library works deeper
62
+
63
+ require "mp3info"
64
+ # read and display infos & tags
65
+ Mp3Info.open("myfile.mp3") do |mp3info|
66
+ puts mp3info
67
+ end
68
+
69
+ # read/write tag1 and tag2 with Mp3Info#tag attribute
70
+ # when reading tag2 have priority over tag1
71
+ # when writing, each tag is written.
72
+ Mp3Info.open("myfile.mp3") do |mp3|
73
+ puts mp3.tag.title
74
+ puts mp3.tag.artist
75
+ puts mp3.tag.album
76
+ puts mp3.tag.tracknum
77
+ mp3.tag.title = "track title"
78
+ mp3.tag.artist = "artist name"
79
+ end
80
+
81
+ Mp3Info.open("myfile.mp3") do |mp3|
82
+ # you can access four letter v2 tags like this
83
+ puts mp3.tag2.TIT2
84
+ mp3.tag2.TIT2 = "new TIT2"
85
+ # or like that
86
+ mp3.tag2["TIT2"]
87
+ # at this time, only COMM tag is processed after reading and before writing
88
+ # according to ID3v2#options hash
89
+ mp3.tag2.options[:lang] = "FRE"
90
+ mp3.tag2.COMM = "my comment in french, correctly handled when reading and writing"
91
+ end
26
92
  email: moumar@rubyforge.org
27
93
  executables: []
28
94
 
@@ -31,43 +97,50 @@ extensions: []
31
97
  extra_rdoc_files:
32
98
  - History.txt
33
99
  - Manifest.txt
34
- - README.txt
35
100
  files:
36
101
  - History.txt
37
102
  - Manifest.txt
38
- - README.txt
103
+ - README.rdoc
39
104
  - Rakefile
40
105
  - install.rb
41
106
  - lib/mp3info.rb
42
107
  - lib/mp3info/extension_modules.rb
43
108
  - lib/mp3info/id3v2.rb
44
109
  - test/test_ruby-mp3info.rb
45
- has_rdoc: true
46
110
  homepage:
111
+ licenses: []
112
+
47
113
  post_install_message:
48
114
  rdoc_options:
49
- - --main
50
- - README.txt
115
+ - --title
116
+ - RubyMp3info Documentation
117
+ - --quiet
51
118
  require_paths:
52
119
  - lib
53
120
  required_ruby_version: !ruby/object:Gem::Requirement
121
+ none: false
54
122
  requirements:
55
123
  - - ">="
56
124
  - !ruby/object:Gem::Version
125
+ hash: 3
126
+ segments:
127
+ - 0
57
128
  version: "0"
58
- version:
59
129
  required_rubygems_version: !ruby/object:Gem::Requirement
130
+ none: false
60
131
  requirements:
61
132
  - - ">="
62
133
  - !ruby/object:Gem::Version
134
+ hash: 3
135
+ segments:
136
+ - 0
63
137
  version: "0"
64
- version:
65
138
  requirements: []
66
139
 
67
140
  rubyforge_project: ruby-mp3info
68
- rubygems_version: 1.3.1
141
+ rubygems_version: 1.8.5
69
142
  signing_key:
70
- specification_version: 2
143
+ specification_version: 3
71
144
  summary: ruby-mp3info is a pure-ruby library to retrieve low level informations on mp3 files and manipulate id3v1 and id3v2 tags
72
145
  test_files:
73
146
  - test/test_ruby-mp3info.rb