ruby-audioinfo 0.4 → 0.5.0
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.
- checksums.yaml +4 -4
- data/Rakefile +2 -1
- data/lib/audioinfo.rb +182 -178
- data/lib/audioinfo/album.rb +4 -7
- data/test/test_wav.rb +27 -0
- metadata +10 -7
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: b3d88409c0fcd1fc60750cc12d93527e10f078c1
|
4
|
+
data.tar.gz: 0eeb6112e45fe6e71f03cba86bd6984e601c1700
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 856b773a0ea07be9223fe56d7100261b0653040c9c70ff66c121cc9126055fee2b717dd1e1c1dfd375753f5db503de0653ec39641f6ad06d3d6d2a9125c836f5
|
7
|
+
data.tar.gz: 16ecada3747678a6990459269b8bfa1054f423c72d673292b30154582d29c1378fa57a788e087b8f8dd661367c2a2dae68485485d29b79102820a6bcf39d0054
|
data/Rakefile
CHANGED
@@ -15,7 +15,8 @@ Hoe.spec('ruby-audioinfo') do
|
|
15
15
|
#history_file = "History.txt"
|
16
16
|
self.readme_file = "README.rdoc"
|
17
17
|
self.test_globs = ["test/test_*.rb"]
|
18
|
-
self.rsync_args = "-rv --delete"
|
18
|
+
self.rsync_args = "-rv --delete"
|
19
|
+
self.license 'GPL-3.0'
|
19
20
|
|
20
21
|
extra_deps << ['ruby-mp3info', '>= 0.8']
|
21
22
|
extra_deps << ['ruby-ogginfo', '>= 0.7']
|
data/lib/audioinfo.rb
CHANGED
@@ -7,6 +7,7 @@ require "wmainfo"
|
|
7
7
|
require "mp4info"
|
8
8
|
require "flacinfo"
|
9
9
|
require "apetag"
|
10
|
+
require "wavefile"
|
10
11
|
|
11
12
|
$: << File.expand_path(File.dirname(__FILE__))
|
12
13
|
|
@@ -34,16 +35,16 @@ class AudioInfo
|
|
34
35
|
"trackid" => "Track Id"
|
35
36
|
}
|
36
37
|
|
37
|
-
SUPPORTED_EXTENSIONS = %w{mp3 ogg opus spx mpc wma mp4 aac m4a flac}
|
38
|
+
SUPPORTED_EXTENSIONS = %w{mp3 ogg opus spx mpc wma mp4 aac m4a flac wav}
|
38
39
|
|
39
|
-
VERSION = "0.
|
40
|
+
VERSION = "0.5.0"
|
40
41
|
|
41
42
|
attr_reader :path, :extension, :musicbrainz_infos, :tracknum, :bitrate, :vbr
|
42
43
|
attr_reader :artist, :album, :title, :length, :date
|
43
44
|
|
44
45
|
# Part of testing API - you should not use this directly
|
45
46
|
attr_reader :info
|
46
|
-
|
47
|
+
|
47
48
|
# "block version" of #new()
|
48
49
|
def self.open(*args)
|
49
50
|
audio_info = self.new(*args)
|
@@ -81,122 +82,127 @@ class AudioInfo
|
|
81
82
|
|
82
83
|
begin
|
83
84
|
case @extension
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
end
|
103
|
-
end
|
104
|
-
@bitrate = @info.bitrate
|
105
|
-
i = @info.tag.tracknum
|
106
|
-
@tracknum = (i.is_a?(Array) ? i.last : i).to_i
|
107
|
-
@length = @info.length.to_i
|
108
|
-
@date = @info.tag["date"]
|
109
|
-
@vbr = @info.vbr
|
110
|
-
@info.close
|
111
|
-
|
112
|
-
when 'ogg', 'opus', 'spx'
|
113
|
-
@info = OggInfo.new(filename)
|
114
|
-
default_fill_musicbrainz_fields
|
115
|
-
default_tag_fill
|
116
|
-
@bitrate = @info.bitrate/1000
|
117
|
-
@tracknum = @info.tag.tracknumber.to_i
|
118
|
-
@length = @info.length.to_i
|
119
|
-
@date = @info.tag["date"]
|
120
|
-
@vbr = true
|
121
|
-
@info.close
|
122
|
-
|
123
|
-
when 'mpc'
|
124
|
-
fill_ape_tag(filename)
|
125
|
-
|
126
|
-
mpc_info = MpcInfo.new(filename)
|
127
|
-
@bitrate = mpc_info.infos['bitrate']/1000
|
128
|
-
@length = mpc_info.infos['length']
|
129
|
-
|
130
|
-
when 'ape'
|
131
|
-
fill_ape_tag(filename)
|
132
|
-
|
133
|
-
when 'wma'
|
134
|
-
@info = WmaInfo.new(filename, :encoding => 'utf-8')
|
135
|
-
@artist = @info.tags["Author"]
|
136
|
-
@album = @info.tags["AlbumTitle"]
|
137
|
-
@title = @info.tags["Title"]
|
138
|
-
@tracknum = @info.tags["TrackNumber"].to_i
|
139
|
-
@date = @info.tags["Year"]
|
140
|
-
@bitrate = @info.info["bitrate"]
|
141
|
-
@length = @info.info["playtime_seconds"]
|
142
|
-
MUSICBRAINZ_FIELDS.each do |key, original_key|
|
143
|
-
@musicbrainz_infos[key] =
|
144
|
-
@info.info["MusicBrainz/" + original_key.tr(" ", "")] ||
|
145
|
-
@info.info["MusicBrainz/" + original_key]
|
146
|
-
end
|
147
|
-
|
148
|
-
when 'mp4', 'aac', 'm4a'
|
149
|
-
@extension = 'mp4'
|
150
|
-
@info = MP4Info.open(filename)
|
151
|
-
@artist = @info.ART
|
152
|
-
@album = @info.ALB
|
153
|
-
@title = @info.NAM
|
154
|
-
@tracknum = ( t = @info.TRKN ) ? t.first : 0
|
155
|
-
@date = @info.DAY
|
156
|
-
@bitrate = @info.BITRATE
|
157
|
-
@length = @info.SECS
|
158
|
-
mapping = MUSICBRAINZ_FIELDS.invert
|
159
|
-
|
160
|
-
faad_info(filename).match(/^MusicBrainz (.+)$/) do
|
161
|
-
name, value = $1.split(/: /, 2)
|
162
|
-
key = mapping[name]
|
163
|
-
@musicbrainz_infos[key] = value
|
164
|
-
end
|
165
|
-
|
166
|
-
when 'flac'
|
167
|
-
@info = FlacInfo.new(filename)
|
168
|
-
# Unfortunately, FlacInfo doesn't allow us to fiddle inside
|
169
|
-
# their class, so we have to brute force it. Any other
|
170
|
-
# solution (e.g. creating another abstraction or getting
|
171
|
-
# methods) lands up being more messy and brittle.
|
172
|
-
@info.instance_variable_set('@tags', CaseInsensitiveHash.new(@info.tags))
|
173
|
-
|
174
|
-
get_tag = proc do |name|
|
175
|
-
if t = @info.tags[name]
|
176
|
-
t.dup.force_encoding("utf-8")
|
177
|
-
else
|
178
|
-
nil
|
179
|
-
end
|
85
|
+
when 'mp3'
|
86
|
+
@info = Mp3Info.new(filename)
|
87
|
+
default_tag_fill
|
88
|
+
#"TXXX"=>
|
89
|
+
#["MusicBrainz TRM Id\000",
|
90
|
+
#"MusicBrainz Artist Id\000aba64937-3334-4c65-90a1-4e6b9d4d7ada",
|
91
|
+
#"MusicBrainz Album Id\000e1a223c1-cbc2-427f-a192-5d22fefd7c4c",
|
92
|
+
#"MusicBrainz Album Type\000album",
|
93
|
+
#"MusicBrainz Album Status\000official",
|
94
|
+
#"MusicBrainz Album Artist Id\000"]
|
95
|
+
|
96
|
+
if (arr = @info.tag2["TXXX"]).is_a?(Array)
|
97
|
+
fields = MUSICBRAINZ_FIELDS.invert
|
98
|
+
arr.each do |val|
|
99
|
+
if val =~ /^MusicBrainz (.+)\000(.*)$/
|
100
|
+
short_name = fields[$1]
|
101
|
+
@musicbrainz_infos[short_name] = $2.gsub("\xEF\xBB\xBF".force_encoding("UTF-8"), '')
|
102
|
+
end
|
180
103
|
end
|
181
|
-
|
182
|
-
|
183
|
-
|
184
|
-
|
185
|
-
|
186
|
-
|
187
|
-
|
188
|
-
|
189
|
-
|
190
|
-
|
191
|
-
|
192
|
-
|
193
|
-
|
194
|
-
|
104
|
+
end
|
105
|
+
@bitrate = @info.bitrate
|
106
|
+
i = @info.tag.tracknum
|
107
|
+
@tracknum = (i.is_a?(Array) ? i.last : i).to_i
|
108
|
+
@length = @info.length.to_i
|
109
|
+
@date = @info.tag["date"]
|
110
|
+
@vbr = @info.vbr
|
111
|
+
@info.close
|
112
|
+
|
113
|
+
when 'ogg', 'opus', 'spx'
|
114
|
+
@info = OggInfo.new(filename)
|
115
|
+
default_fill_musicbrainz_fields
|
116
|
+
default_tag_fill
|
117
|
+
@bitrate = @info.bitrate/1000
|
118
|
+
@tracknum = @info.tag.tracknumber.to_i
|
119
|
+
@length = @info.length.to_i
|
120
|
+
@date = @info.tag["date"]
|
121
|
+
@vbr = true
|
122
|
+
@info.close
|
123
|
+
|
124
|
+
when 'mpc'
|
125
|
+
fill_ape_tag(filename)
|
126
|
+
mpc_info = MpcInfo.new(filename)
|
127
|
+
@bitrate = mpc_info.infos['bitrate']/1000
|
128
|
+
@length = mpc_info.infos['length']
|
129
|
+
|
130
|
+
when 'ape'
|
131
|
+
fill_ape_tag(filename)
|
132
|
+
|
133
|
+
when 'wma'
|
134
|
+
@info = WmaInfo.new(filename, :encoding => 'utf-8')
|
135
|
+
@artist = @info.tags["Author"]
|
136
|
+
@album = @info.tags["AlbumTitle"]
|
137
|
+
@title = @info.tags["Title"]
|
138
|
+
@tracknum = @info.tags["TrackNumber"].to_i
|
139
|
+
@date = @info.tags["Year"]
|
140
|
+
@bitrate = @info.info["bitrate"]
|
141
|
+
@length = @info.info["playtime_seconds"]
|
142
|
+
MUSICBRAINZ_FIELDS.each do |key, original_key|
|
143
|
+
@musicbrainz_infos[key] =
|
144
|
+
@info.info["MusicBrainz/" + original_key.tr(" ", "")] ||
|
145
|
+
@info.info["MusicBrainz/" + original_key]
|
146
|
+
end
|
147
|
+
|
148
|
+
when 'mp4', 'aac', 'm4a'
|
149
|
+
@extension = 'mp4'
|
150
|
+
@info = MP4Info.open(filename)
|
151
|
+
@artist = @info.ART
|
152
|
+
@album = @info.ALB
|
153
|
+
@title = @info.NAM
|
154
|
+
@tracknum = ( t = @info.TRKN ) ? t.first : 0
|
155
|
+
@date = @info.DAY
|
156
|
+
@bitrate = @info.BITRATE
|
157
|
+
@length = @info.SECS
|
158
|
+
mapping = MUSICBRAINZ_FIELDS.invert
|
159
|
+
|
160
|
+
faad_info(filename).match(/^MusicBrainz (.+)$/) do
|
161
|
+
name, value = $1.split(/: /, 2)
|
162
|
+
key = mapping[name]
|
163
|
+
@musicbrainz_infos[key] = value
|
164
|
+
end
|
165
|
+
|
166
|
+
when 'flac'
|
167
|
+
@info = FlacInfo.new(filename)
|
168
|
+
# Unfortunately, FlacInfo doesn't allow us to fiddle inside
|
169
|
+
# their class, so we have to brute force it. Any other
|
170
|
+
# solution (e.g. creating another abstraction or getting
|
171
|
+
# methods) lands up being more messy and brittle.
|
172
|
+
@info.instance_variable_set('@tags', CaseInsensitiveHash.new(@info.tags))
|
173
|
+
|
174
|
+
get_tag = proc do |name|
|
175
|
+
if t = @info.tags[name]
|
176
|
+
t.dup.force_encoding("utf-8")
|
177
|
+
else
|
178
|
+
nil
|
195
179
|
end
|
196
|
-
|
197
|
-
|
198
|
-
|
199
|
-
|
180
|
+
end
|
181
|
+
|
182
|
+
@artist = get_tag.call("artist")
|
183
|
+
@album = get_tag.call("album")
|
184
|
+
@title = get_tag.call("title")
|
185
|
+
@tracknum = @info.tags["tracknumber"].to_i
|
186
|
+
@date = get_tag.call("date")
|
187
|
+
@bitrate = 0
|
188
|
+
@length = @info.streaminfo["total_samples"] / @info.streaminfo["samplerate"].to_f
|
189
|
+
if @length > 0
|
190
|
+
@bitrate = File.size(filename).to_f*8/@length/1024
|
191
|
+
end
|
192
|
+
@info.tags.each do |tagname, tagvalue|
|
193
|
+
next unless tagname =~ /^musicbrainz_(.+)$/
|
194
|
+
@musicbrainz_infos[$1] = get_tag.call(tagname)
|
195
|
+
end
|
196
|
+
@musicbrainz_infos["trmid"] = @info.tags["musicip_puid"]
|
197
|
+
#default_fill_musicbrainz_fields
|
198
|
+
|
199
|
+
when 'wav'
|
200
|
+
@info = WaveFile::Reader.info(filename)
|
201
|
+
@length = @info.duration.seconds
|
202
|
+
@bitrate = File.size(filename) * 8 / @length / 1024
|
203
|
+
|
204
|
+
else
|
205
|
+
raise(AudioInfoError, "unsupported extension '.#{@extension}'")
|
200
206
|
end
|
201
207
|
|
202
208
|
if @tracknum == 0
|
@@ -205,12 +211,12 @@ class AudioInfo
|
|
205
211
|
|
206
212
|
@musicbrainz_infos.delete_if { |k, v| v.nil? }
|
207
213
|
@hash = { "artist" => @artist,
|
208
|
-
|
209
|
-
|
210
|
-
|
211
|
-
|
212
|
-
|
213
|
-
|
214
|
+
"album" => @album,
|
215
|
+
"title" => @title,
|
216
|
+
"tracknum" => @tracknum,
|
217
|
+
"date" => @date,
|
218
|
+
"length" => @length,
|
219
|
+
"bitrate" => @bitrate,
|
214
220
|
}
|
215
221
|
|
216
222
|
rescue Exception, Mp3InfoError, OggInfoError, ApeTagError => e
|
@@ -218,7 +224,6 @@ class AudioInfo
|
|
218
224
|
end
|
219
225
|
|
220
226
|
@needs_commit = false
|
221
|
-
|
222
227
|
end
|
223
228
|
|
224
229
|
# set the title of the file
|
@@ -275,62 +280,61 @@ class AudioInfo
|
|
275
280
|
def close
|
276
281
|
if @needs_commit
|
277
282
|
case @info
|
278
|
-
|
279
|
-
|
280
|
-
|
281
|
-
|
282
|
-
|
283
|
-
|
284
|
-
|
285
|
-
|
286
|
-
|
287
|
-
end
|
288
|
-
end
|
289
|
-
when OggInfo
|
290
|
-
OggInfo.open(@path) do |ogg|
|
291
|
-
{ "artist" => @artist,
|
292
|
-
"album" => @album,
|
293
|
-
"title" => @title,
|
294
|
-
"tracknumber" => @tracknum}.each do |k,v|
|
295
|
-
ogg.tag[k] = v.to_s
|
296
|
-
end
|
297
|
-
if @picture
|
298
|
-
ogg.picture = @picture
|
299
|
-
end
|
300
|
-
end
|
301
|
-
|
302
|
-
when ApeTag
|
303
|
-
ape = ApeTag.new(@path)
|
304
|
-
ape.update do |fields|
|
305
|
-
fields["Artist"] = @artist
|
306
|
-
fields["Album"] = @album
|
307
|
-
fields["Title"] = @title
|
308
|
-
fields["Track"] = @tracknum.to_s
|
283
|
+
when Mp3Info
|
284
|
+
Mp3Info.open(@path) do |info|
|
285
|
+
info.tag.artist = @artist
|
286
|
+
info.tag.title = @title
|
287
|
+
info.tag.album = @album
|
288
|
+
info.tag.tracknum = @tracknum
|
289
|
+
if @picture
|
290
|
+
info.tag2.remove_pictures
|
291
|
+
info.tag2.add_picture(File.binread(@picture))
|
309
292
|
end
|
310
|
-
|
311
|
-
|
312
|
-
|
313
|
-
|
314
|
-
|
315
|
-
|
316
|
-
|
317
|
-
|
318
|
-
|
319
|
-
|
320
|
-
|
321
|
-
|
322
|
-
|
323
|
-
|
324
|
-
|
325
|
-
|
326
|
-
|
327
|
-
|
328
|
-
|
329
|
-
|
330
|
-
|
293
|
+
end
|
294
|
+
when OggInfo
|
295
|
+
OggInfo.open(@path) do |ogg|
|
296
|
+
{ "artist" => @artist,
|
297
|
+
"album" => @album,
|
298
|
+
"title" => @title,
|
299
|
+
"tracknumber" => @tracknum}.each do |k,v|
|
300
|
+
ogg.tag[k] = v.to_s
|
301
|
+
end
|
302
|
+
if @picture
|
303
|
+
ogg.picture = @picture
|
304
|
+
end
|
305
|
+
end
|
306
|
+
|
307
|
+
when ApeTag
|
308
|
+
ape = ApeTag.new(@path)
|
309
|
+
ape.update do |fields|
|
310
|
+
fields["Artist"] = @artist
|
311
|
+
fields["Album"] = @album
|
312
|
+
fields["Title"] = @title
|
313
|
+
fields["Track"] = @tracknum.to_s
|
314
|
+
end
|
315
|
+
else
|
316
|
+
have_metaflac = system("which metaflac > /dev/null")
|
317
|
+
have_ffmpeg = system("which ffmpeg > /dev/null")
|
318
|
+
if have_metaflac and @info.is_a?(FlacInfo)
|
319
|
+
tags = {"ARTIST" => @artist,
|
320
|
+
"ALBUM" => @album,
|
321
|
+
"TITLE" => @title,
|
322
|
+
"TRACKNUMBER" => @tracknum}.inject([]) do |tags, (key, value)|
|
323
|
+
tags + ["--set-tag", "#{key}=#{value.to_s}"]
|
331
324
|
end
|
325
|
+
tag_with_shell_command("metaflac", "--remove-all", :src)
|
326
|
+
tag_with_shell_command("metaflac", tags, :src)
|
327
|
+
elsif have_ffmpeg
|
328
|
+
tags = {"artist" => @artist,
|
329
|
+
"album" => @album,
|
330
|
+
"title" => @title}.inject([]) do |tags, (key, value)|
|
331
|
+
tags + ["-metadata", "#{key}=#{value.to_s}"]
|
332
|
+
end
|
333
|
+
tag_with_shell_command("ffmpeg", "-y", "-i", :src, "-loglevel", "quiet", tags, :dst)
|
334
|
+
else
|
335
|
+
raise(AudioInfoError, "implement me")
|
336
|
+
end
|
332
337
|
end
|
333
|
-
|
334
338
|
end
|
335
339
|
@needs_commit
|
336
340
|
end
|
@@ -356,7 +360,7 @@ class AudioInfo
|
|
356
360
|
! @musicbrainz_infos.empty?
|
357
361
|
end
|
358
362
|
|
359
|
-
private
|
363
|
+
private
|
360
364
|
|
361
365
|
def sanitize(input)
|
362
366
|
s = input.is_a?(Array) ? input.first : input
|
data/lib/audioinfo/album.rb
CHANGED
@@ -89,7 +89,7 @@ class AudioInfo::Album
|
|
89
89
|
end
|
90
90
|
mb
|
91
91
|
end
|
92
|
-
|
92
|
+
|
93
93
|
# return an array of images with "folder.*" in first
|
94
94
|
def images
|
95
95
|
self.class.images(@path)
|
@@ -122,17 +122,17 @@ class AudioInfo::Album
|
|
122
122
|
out = StringIO.new
|
123
123
|
out.puts(@path)
|
124
124
|
out.print "'#{title}'"
|
125
|
-
|
125
|
+
|
126
126
|
unless va?
|
127
127
|
out.print " by '#{@files.first.artist}' "
|
128
128
|
end
|
129
129
|
|
130
130
|
out.puts
|
131
|
-
|
131
|
+
|
132
132
|
@files.sort_by { |f| f.tracknum }.each do |f|
|
133
133
|
out.printf("%02d %s %3d %s", f.tracknum, f.extension, f.bitrate, f.title)
|
134
134
|
if va?
|
135
|
-
|
135
|
+
out.print(" "+f.artist)
|
136
136
|
end
|
137
137
|
out.puts
|
138
138
|
end
|
@@ -143,7 +143,4 @@ class AudioInfo::Album
|
|
143
143
|
def inspect
|
144
144
|
@infos.inspect
|
145
145
|
end
|
146
|
-
|
147
146
|
end
|
148
|
-
|
149
|
-
|
data/test/test_wav.rb
ADDED
@@ -0,0 +1,27 @@
|
|
1
|
+
require_relative "../lib/audioinfo"
|
2
|
+
require "minitest/autorun"
|
3
|
+
|
4
|
+
require "fileutils"
|
5
|
+
require "tmpdir"
|
6
|
+
|
7
|
+
require_relative "test_helper"
|
8
|
+
|
9
|
+
class TestWav < MiniTest::Unit::TestCase
|
10
|
+
|
11
|
+
WAV_FILE = "#{Dir.tmpdir}/ruby-audioinfo-test.wav"
|
12
|
+
|
13
|
+
def setup
|
14
|
+
FileUtils.cp(File.join(SUPPORT_DIR, "piano2.wav"), WAV_FILE)
|
15
|
+
end
|
16
|
+
|
17
|
+
def test_wav_whitelist
|
18
|
+
i = AudioInfo.new(WAV_FILE)
|
19
|
+
assert_kind_of WaveFile::Info, i.info
|
20
|
+
end
|
21
|
+
|
22
|
+
def test_wav_length
|
23
|
+
i = AudioInfo.new(WAV_FILE)
|
24
|
+
assert_equal i.length, 6
|
25
|
+
end
|
26
|
+
|
27
|
+
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: ruby-audioinfo
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version:
|
4
|
+
version: 0.5.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Guillaume Pierronnet
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date:
|
12
|
+
date: 2014-03-24 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: ruby-mp3info
|
@@ -101,28 +101,28 @@ dependencies:
|
|
101
101
|
requirements:
|
102
102
|
- - ~>
|
103
103
|
- !ruby/object:Gem::Version
|
104
|
-
version: '
|
104
|
+
version: '4.0'
|
105
105
|
type: :development
|
106
106
|
prerelease: false
|
107
107
|
version_requirements: !ruby/object:Gem::Requirement
|
108
108
|
requirements:
|
109
109
|
- - ~>
|
110
110
|
- !ruby/object:Gem::Version
|
111
|
-
version: '
|
111
|
+
version: '4.0'
|
112
112
|
- !ruby/object:Gem::Dependency
|
113
113
|
name: hoe
|
114
114
|
requirement: !ruby/object:Gem::Requirement
|
115
115
|
requirements:
|
116
116
|
- - ~>
|
117
117
|
- !ruby/object:Gem::Version
|
118
|
-
version: '3.
|
118
|
+
version: '3.7'
|
119
119
|
type: :development
|
120
120
|
prerelease: false
|
121
121
|
version_requirements: !ruby/object:Gem::Requirement
|
122
122
|
requirements:
|
123
123
|
- - ~>
|
124
124
|
- !ruby/object:Gem::Version
|
125
|
-
version: '3.
|
125
|
+
version: '3.7'
|
126
126
|
description: |-
|
127
127
|
ruby-audioinfo glue together various audio ruby libraries and presents a unified
|
128
128
|
API to the developper. Currently, supported formats are: mp3, ogg, mpc, ape,
|
@@ -149,9 +149,11 @@ files:
|
|
149
149
|
- test/test_audioinfo.rb
|
150
150
|
- test/test_case_insensitive_hash.rb
|
151
151
|
- test/test_helper.rb
|
152
|
+
- test/test_wav.rb
|
152
153
|
- .gemtest
|
153
154
|
homepage: http://ruby-audioinfo.rubyforge.org
|
154
|
-
licenses:
|
155
|
+
licenses:
|
156
|
+
- GPL-3.0
|
155
157
|
metadata: {}
|
156
158
|
post_install_message:
|
157
159
|
rdoc_options:
|
@@ -180,3 +182,4 @@ test_files:
|
|
180
182
|
- test/test_audioinfo.rb
|
181
183
|
- test/test_case_insensitive_hash.rb
|
182
184
|
- test/test_helper.rb
|
185
|
+
- test/test_wav.rb
|