ruby-audioinfo 0.4 → 0.5.5

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.
data/Rakefile CHANGED
@@ -1,40 +1,16 @@
1
- # -*- ruby -*-
1
+ # frozen_string_literal: true
2
2
 
3
- require 'hoe'
3
+ require 'bundler/gem_tasks'
4
+ require 'rake/testtask'
4
5
 
5
- Hoe.plugin :yard
6
- Hoe.plugin :gemspec
7
-
8
- Hoe.spec('ruby-audioinfo') do
9
- developer "Guillaume Pierronnet", "guillaume.pierronnet@gmail.com"
10
- developer 'Marcello Barnaba', "unknown"
11
- remote_rdoc_dir = ''
12
- rdoc_locations << "rubyforge.org:/var/www/gforge-projects/ruby-audioinfo/"
13
-
14
- self.extra_rdoc_files = FileList["*.rdoc"]
15
- #history_file = "History.txt"
16
- self.readme_file = "README.rdoc"
17
- self.test_globs = ["test/test_*.rb"]
18
- self.rsync_args = "-rv --delete"
19
-
20
- extra_deps << ['ruby-mp3info', '>= 0.8']
21
- extra_deps << ['ruby-ogginfo', '>= 0.7']
22
- extra_deps << ['mp4info', '>= 1.7.3']
23
- extra_deps << ['moumar-wmainfo-rb', '>= 0.7']
24
- extra_deps << ['flacinfo-rb', '>= 0.4']
25
- extra_deps << ['apetag', '>= 1.1.4']
26
- #extra_dev_deps << ["rake", ">=0"]
6
+ Rake::TestTask.new(:test) do |t|
7
+ t.libs << 'test'
8
+ t.libs << 'lib'
9
+ t.test_files = FileList['test/**/*_test.rb']
27
10
  end
28
11
 
29
- =begin
30
- # vim: syntax=Ruby
31
- require 'rubygems'
32
- require "rake/rdoctask"
12
+ require 'rubocop/rake_task'
33
13
 
34
- Rake::RDocTask.new do |rd|
35
- rd.main = "README.rdoc"
36
- rd.rdoc_dir = "rdoc"
37
- rd.rdoc_files.include("README.rdoc", "History.txt", "lib/**/*.rb")
38
- rd.title = "ruby-audioinfo #{AudioInfo::VERSION}"
39
- end
40
- =end
14
+ RuboCop::RakeTask.new
15
+
16
+ task default: %i[test rubocop]
@@ -0,0 +1,15 @@
1
+ #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
3
+
4
+ require 'bundler/setup'
5
+ require 'audioinfo'
6
+
7
+ # You can add fixtures and/or initialization code here to make experimenting
8
+ # with your gem easier. You can also use a different console, if you like.
9
+
10
+ # (If you use this, don't forget to add pry to your Gemfile!)
11
+ # require "pry"
12
+ # Pry.start
13
+
14
+ require 'irb'
15
+ IRB.start(__FILE__)
@@ -0,0 +1 @@
1
+ comment: false
@@ -1,52 +1,45 @@
1
- # encoding: utf-8
2
- require "stringio"
1
+ # frozen_string_literal: true
3
2
 
4
- require "mp3info"
5
- require "ogginfo"
6
- require "wmainfo"
7
- require "mp4info"
8
- require "flacinfo"
9
- require "apetag"
3
+ require 'stringio'
10
4
 
11
- $: << File.expand_path(File.dirname(__FILE__))
5
+ require 'mp3info'
6
+ require 'ogginfo'
7
+ require 'wmainfo'
8
+ require 'mp4info'
9
+ require 'flacinfo'
10
+ require 'apetag'
11
+ require 'wavefile'
12
12
 
13
- require "audioinfo/mpcinfo"
14
- require "audioinfo/case_insensitive_hash"
13
+ $LOAD_PATH << __dir__
15
14
 
16
- class AudioInfoError < StandardError ; end
15
+ require 'audioinfo/mpcinfo'
16
+ require 'audioinfo/case_insensitive_hash'
17
+ require 'audioinfo/version'
17
18
 
18
- class AudioInfo
19
- if RUBY_VERSION[0..2] == "1.8"
20
- RUBY_1_8 = true
21
- require "iconv"
22
- else
23
- RUBY_1_8 = false
24
- end
25
-
26
- MUSICBRAINZ_FIELDS = {
27
- "trmid" => "TRM Id",
28
- "artistid" => "Artist Id",
29
- "albumid" => "Album Id",
30
- "albumtype" => "Album Type",
31
- "albumstatus" => "Album Status",
32
- "albumartistid" => "Album Artist Id",
33
- "sortname" => "Sort Name",
34
- "trackid" => "Track Id"
35
- }
19
+ class AudioInfoError < StandardError; end
36
20
 
37
- SUPPORTED_EXTENSIONS = %w{mp3 ogg opus spx mpc wma mp4 aac m4a flac}
21
+ class AudioInfo
22
+ MUSICBRAINZ_FIELDS = {
23
+ 'trmid' => 'TRM Id',
24
+ 'artistid' => 'Artist Id',
25
+ 'albumid' => 'Album Id',
26
+ 'albumtype' => 'Album Type',
27
+ 'albumstatus' => 'Album Status',
28
+ 'albumartistid' => 'Album Artist Id',
29
+ 'sortname' => 'Sort Name',
30
+ 'trackid' => 'Track Id'
31
+ }.freeze
38
32
 
39
- VERSION = "0.4"
33
+ SUPPORTED_EXTENSIONS = %w[mp3 ogg opus spx mpc wma mp4 aac m4a flac wav].freeze
40
34
 
41
- attr_reader :path, :extension, :musicbrainz_infos, :tracknum, :bitrate, :vbr
42
- attr_reader :artist, :album, :title, :length, :date
35
+ attr_reader :path, :extension, :musicbrainz_infos, :tracknum, :bitrate, :vbr, :artist, :album, :title, :length, :date
43
36
 
44
37
  # Part of testing API - you should not use this directly
45
38
  attr_reader :info
46
-
39
+
47
40
  # "block version" of #new()
48
41
  def self.open(*args)
49
- audio_info = self.new(*args)
42
+ audio_info = new(*args)
50
43
  ret = nil
51
44
  if block_given?
52
45
  begin
@@ -62,163 +55,163 @@ class AudioInfo
62
55
 
63
56
  # test whether +path+ is a valid and supported audiofile
64
57
  def self.is_audio_file?(path)
65
- begin
66
- AudioInfo.new(path)
67
- return true
68
- rescue AudioInfoError
69
- return false
70
- end
58
+ AudioInfo.new(path)
59
+ true
60
+ rescue AudioInfoError
61
+ false
71
62
  end
72
63
 
73
64
  # open the file with path +fn+
74
- def initialize(filename)
75
- raise(AudioInfoError, "path is nil") if filename.nil?
65
+ def initialize(filename, extension = nil)
66
+ raise(AudioInfoError, 'path is nil') if filename.nil?
67
+
76
68
  @path = filename
77
69
  ext = File.extname(@path)
78
- raise(AudioInfoError, "cannot find extension") if ext.empty?
79
- @extension = ext[1..-1].downcase
70
+ @extension = extension || (ext && ext[1..-1].downcase)
71
+ raise(AudioInfoError, 'cannot find extension') if @extension.empty?
72
+
80
73
  @musicbrainz_infos = {}
81
74
 
82
75
  begin
83
76
  case @extension
84
- when 'mp3'
85
- @info = Mp3Info.new(filename)
86
- default_tag_fill
87
- #"TXXX"=>
88
- #["MusicBrainz TRM Id\000",
89
- #"MusicBrainz Artist Id\000aba64937-3334-4c65-90a1-4e6b9d4d7ada",
90
- #"MusicBrainz Album Id\000e1a223c1-cbc2-427f-a192-5d22fefd7c4c",
91
- #"MusicBrainz Album Type\000album",
92
- #"MusicBrainz Album Status\000official",
93
- #"MusicBrainz Album Artist Id\000"]
94
-
95
- if (arr = @info.tag2["TXXX"]).is_a?(Array)
96
- fields = MUSICBRAINZ_FIELDS.invert
97
- arr.each do |val|
98
- if val =~ /^MusicBrainz (.+)\000(.*)$/
99
- short_name = fields[$1]
100
- @musicbrainz_infos[short_name] = $2.gsub("\xEF\xBB\xBF".force_encoding("UTF-8"), '')
101
- end
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
77
+ when 'mp3'
78
+ @info = Mp3Info.new(filename)
79
+ default_tag_fill
80
+ # "TXXX"=>
81
+ # ["MusicBrainz TRM Id\000",
82
+ # "MusicBrainz Artist Id\000aba64937-3334-4c65-90a1-4e6b9d4d7ada",
83
+ # "MusicBrainz Album Id\000e1a223c1-cbc2-427f-a192-5d22fefd7c4c",
84
+ # "MusicBrainz Album Type\000album",
85
+ # "MusicBrainz Album Status\000official",
86
+ # "MusicBrainz Album Artist Id\000"]
87
+
88
+ if (arr = @info.tag2['TXXX']).is_a?(Array)
89
+ fields = MUSICBRAINZ_FIELDS.invert
90
+ arr.each do |val|
91
+ if val =~ /^MusicBrainz (.+)\000(.*)$/
92
+ short_name = fields[Regexp.last_match(1)]
93
+ @musicbrainz_infos[short_name] = Regexp.last_match(2).gsub("\xEF\xBB\xBF".force_encoding('UTF-8'), '')
179
94
  end
180
95
  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)
96
+ end
97
+ @bitrate = @info.bitrate
98
+ i = @info.tag.tracknum
99
+ @tracknum = (i.is_a?(Array) ? i.last : i).to_i
100
+ @length = @info.length.to_i
101
+ @date = @info.tag['date']
102
+ @vbr = @info.vbr
103
+ @info.close
104
+
105
+ when 'ogg', 'opus', 'spx'
106
+ @info = OggInfo.new(filename)
107
+ default_fill_musicbrainz_fields
108
+ default_tag_fill
109
+ @bitrate = @info.bitrate / 1000
110
+ @tracknum = @info.tag.tracknumber.to_i
111
+ @length = @info.length.to_i
112
+ @date = @info.tag['date']
113
+ @vbr = true
114
+ @info.close
115
+
116
+ when 'mpc'
117
+ fill_ape_tag(filename)
118
+ mpc_info = MpcInfo.new(filename)
119
+ @bitrate = mpc_info.infos['bitrate'] / 1000
120
+ @length = mpc_info.infos['length']
121
+
122
+ when 'ape'
123
+ fill_ape_tag(filename)
124
+
125
+ when 'wma'
126
+ @info = WmaInfo.new(filename, encoding: 'utf-8')
127
+ @artist = @info.tags['Author']
128
+ @album = @info.tags['AlbumTitle']
129
+ @title = @info.tags['Title']
130
+ @tracknum = @info.tags['TrackNumber'].to_i
131
+ @date = @info.tags['Year']
132
+ @bitrate = @info.info['bitrate']
133
+ @length = @info.info['playtime_seconds']
134
+ MUSICBRAINZ_FIELDS.each do |key, original_key|
135
+ @musicbrainz_infos[key] =
136
+ @info.info["MusicBrainz/#{original_key.tr(' ', '')}"] ||
137
+ @info.info["MusicBrainz/#{original_key}"]
138
+ end
139
+
140
+ when 'mp4', 'aac', 'm4a'
141
+ @extension = 'mp4'
142
+ @info = MP4Info.open(filename)
143
+ @artist = @info.ART
144
+ @album = @info.ALB
145
+ @title = @info.NAM
146
+ @tracknum = (t = @info.TRKN) ? t.first : 0
147
+ @date = @info.DAY
148
+ @bitrate = @info.BITRATE
149
+ @length = @info.SECS
150
+ mapping = MUSICBRAINZ_FIELDS.invert
151
+
152
+ faad_info(filename).scan(/^MusicBrainz (.+): (.+)$/) do |match|
153
+ name, value = match
154
+ key = mapping[name]
155
+ next unless key
156
+
157
+ @musicbrainz_infos[key] = value.strip.gsub("\u0000", '')
158
+ end
159
+
160
+ when 'flac'
161
+ @info = FlacInfo.new(filename)
162
+ # Unfortunately, FlacInfo doesn't allow us to fiddle inside
163
+ # their class, so we have to brute force it. Any other
164
+ # solution (e.g. creating another abstraction or getting
165
+ # methods) lands up being more messy and brittle.
166
+ @info.instance_variable_set('@tags', CaseInsensitiveHash.new(@info.tags))
167
+
168
+ get_tag = proc do |name|
169
+ if t = @info.tags[name]
170
+ t.dup.force_encoding('utf-8')
195
171
  end
196
- @musicbrainz_infos["trmid"] = @info.tags["musicip_puid"]
197
- #default_fill_musicbrainz_fields
198
- else
199
- raise(AudioInfoError, "unsupported extension '.#{@extension}'")
200
- end
172
+ end
173
+
174
+ @artist = get_tag.call('artist')
175
+ @album = get_tag.call('album')
176
+ @title = get_tag.call('title')
177
+ @tracknum = @info.tags['tracknumber'].to_i
178
+ @date = get_tag.call('date')
179
+ @bitrate = 0
180
+ @length = @info.streaminfo['total_samples'] / @info.streaminfo['samplerate'].to_f
181
+ @bitrate = File.size(filename).to_f * 8 / @length / 1024 if @length.positive?
182
+ @info.tags.each do |tagname, _tagvalue|
183
+ next unless tagname =~ /^musicbrainz_(.+)$/
184
+
185
+ @musicbrainz_infos[Regexp.last_match(1)] = get_tag.call(tagname)
186
+ end
187
+ @musicbrainz_infos['trmid'] = @info.tags['musicip_puid']
188
+ # default_fill_musicbrainz_fields
201
189
 
202
- if @tracknum == 0
203
- @tracknum = nil
190
+ when 'wav'
191
+ @info = WaveFile::Reader.info(filename)
192
+ @length = @info.duration.hours * 3600 + @info.duration.minutes * 60 + @info.duration.seconds +
193
+ @info.duration.milliseconds * 0.001
194
+ @bitrate = File.size(filename) * 8 / @length / 1024
195
+
196
+ else
197
+ raise(AudioInfoError, "unsupported extension '.#{@extension}'")
204
198
  end
205
199
 
206
- @musicbrainz_infos.delete_if { |k, v| v.nil? }
207
- @hash = { "artist" => @artist,
208
- "album" => @album,
209
- "title" => @title,
210
- "tracknum" => @tracknum,
211
- "date" => @date,
212
- "length" => @length,
213
- "bitrate" => @bitrate,
214
- }
215
-
216
- rescue Exception, Mp3InfoError, OggInfoError, ApeTagError => e
200
+ @tracknum = nil if @tracknum&.zero?
201
+
202
+ @musicbrainz_infos.delete_if { |_k, v| v.nil? }
203
+ @hash = { 'artist' => @artist,
204
+ 'album' => @album,
205
+ 'title' => @title,
206
+ 'tracknum' => @tracknum,
207
+ 'date' => @date,
208
+ 'length' => @length,
209
+ 'bitrate' => @bitrate }
210
+ rescue StandardError, Mp3InfoError, OggInfoError, ApeTagError => e
217
211
  raise AudioInfoError, e.to_s, e.backtrace
218
212
  end
219
213
 
220
214
  @needs_commit = false
221
-
222
215
  end
223
216
 
224
217
  # set the title of the file
@@ -275,150 +268,134 @@ class AudioInfo
275
268
  def close
276
269
  if @needs_commit
277
270
  case @info
278
- when Mp3Info
279
- Mp3Info.open(@path) do |info|
280
- info.tag.artist = @artist
281
- info.tag.title = @title
282
- info.tag.album = @album
283
- info.tag.tracknum = @tracknum
284
- if @picture
285
- info.tag2.remove_pictures
286
- info.tag2.add_picture(File.binread(@picture))
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
271
+ when Mp3Info
272
+ Mp3Info.open(@path) do |info|
273
+ info.tag.artist = @artist
274
+ info.tag.title = @title
275
+ info.tag.album = @album
276
+ info.tag.tracknum = @tracknum
277
+ if @picture
278
+ info.tag2.remove_pictures
279
+ info.tag2.add_picture(File.binread(@picture))
309
280
  end
310
- else
311
- have_metaflac = system("which metaflac > /dev/null")
312
- have_ffmpeg = system("which ffmpeg > /dev/null")
313
- if have_metaflac and @info.is_a?(FlacInfo)
314
- tags = {"ARTIST" => @artist,
315
- "ALBUM" => @album,
316
- "TITLE" => @title,
317
- "TRACKNUMBER" => @tracknum}.inject([]) do |tags, (key, value)|
318
- tags + ["--set-tag", "#{key}=#{value.to_s}"]
319
- end
320
- tag_with_shell_command("metaflac", "--remove-all", :src)
321
- tag_with_shell_command("metaflac", tags, :src)
322
- elsif have_ffmpeg
323
- tags = {"artist" => @artist,
324
- "album" => @album,
325
- "title" => @title}.inject([]) do |tags, (key, value)|
326
- tags + ["-metadata", "#{key}=#{value.to_s}"]
327
- end
328
- tag_with_shell_command("ffmpeg", "-y", "-i", :src, "-loglevel", "quiet", tags, :dst)
329
- else
330
- raise(AudioInfoError, "implement me")
281
+ end
282
+ when OggInfo
283
+ OggInfo.open(@path) do |ogg|
284
+ { 'artist' => @artist,
285
+ 'album' => @album,
286
+ 'title' => @title,
287
+ 'tracknumber' => @tracknum }.each do |k, v|
288
+ ogg.tag[k] = v.to_s
331
289
  end
290
+ ogg.picture = @picture if @picture
291
+ end
292
+
293
+ when ApeTag
294
+ ape = ApeTag.new(@path)
295
+ ape.update do |fields|
296
+ fields['Artist'] = @artist
297
+ fields['Album'] = @album
298
+ fields['Title'] = @title
299
+ fields['Track'] = @tracknum.to_s
300
+ end
301
+ else
302
+ have_metaflac = system('which metaflac > /dev/null')
303
+ have_ffmpeg = system('which ffmpeg > /dev/null')
304
+ if have_metaflac && @info.is_a?(FlacInfo)
305
+ tags = { 'ARTIST' => @artist,
306
+ 'ALBUM' => @album,
307
+ 'TITLE' => @title,
308
+ 'TRACKNUMBER' => @tracknum }.inject([]) do |tags, (key, value)|
309
+ tags + ['--set-tag', "#{key}=#{value}"]
310
+ end
311
+ tag_with_shell_command('metaflac', '--remove-all', :src)
312
+ tag_with_shell_command('metaflac', tags, :src)
313
+ elsif have_ffmpeg
314
+ tags = { 'artist' => @artist,
315
+ 'album' => @album,
316
+ 'title' => @title }.inject([]) do |tags, (key, value)|
317
+ tags + ['-metadata', "#{key}=#{value}"]
318
+ end
319
+ tag_with_shell_command('ffmpeg', '-y', '-i', :src, '-loglevel', 'quiet', tags, :dst)
320
+ else
321
+ raise(AudioInfoError, 'implement me')
322
+ end
332
323
  end
333
-
334
324
  end
335
325
  @needs_commit
336
326
  end
337
- =begin
338
- {"musicbrainz_albumstatus"=>"official",
339
- "artist"=>"Jill Scott",
340
- "replaygain_track_gain"=>"-3.29 dB",
341
- "tracknumber"=>"1",
342
- "title"=>"A long walk (A touch of Jazz Mix)..Jazzanova Love Beats...",
343
- "musicbrainz_sortname"=>"Scott, Jill",
344
- "musicbrainz_artistid"=>"b1fb6a18-1626-4011-80fb-eaf83dfebcb6",
345
- "musicbrainz_albumid"=>"cb2ad8c7-4a02-4e46-ae9a-c7c2463c7235",
346
- "replaygain_track_peak"=>"0.82040048",
347
- "musicbrainz_albumtype"=>"compilation",
348
- "album"=>"...Mixing (Jazzanova)",
349
- "musicbrainz_trmid"=>"1ecec0a6-c7c3-4179-abea-ef12dabc7cbd",
350
- "musicbrainz_trackid"=>"0a368e63-dddf-441f-849c-ca23f9cb2d49",
351
- "musicbrainz_albumartistid"=>"89ad4ac3-39f7-470e-963a-56509c546377"}>
352
- =end
327
+ # {"musicbrainz_albumstatus"=>"official",
328
+ # "artist"=>"Jill Scott",
329
+ # "replaygain_track_gain"=>"-3.29 dB",
330
+ # "tracknumber"=>"1",
331
+ # "title"=>"A long walk (A touch of Jazz Mix)..Jazzanova Love Beats...",
332
+ # "musicbrainz_sortname"=>"Scott, Jill",
333
+ # "musicbrainz_artistid"=>"b1fb6a18-1626-4011-80fb-eaf83dfebcb6",
334
+ # "musicbrainz_albumid"=>"cb2ad8c7-4a02-4e46-ae9a-c7c2463c7235",
335
+ # "replaygain_track_peak"=>"0.82040048",
336
+ # "musicbrainz_albumtype"=>"compilation",
337
+ # "album"=>"...Mixing (Jazzanova)",
338
+ # "musicbrainz_trmid"=>"1ecec0a6-c7c3-4179-abea-ef12dabc7cbd",
339
+ # "musicbrainz_trackid"=>"0a368e63-dddf-441f-849c-ca23f9cb2d49",
340
+ # "musicbrainz_albumartistid"=>"89ad4ac3-39f7-470e-963a-56509c546377"}>
353
341
 
354
342
  # check if the file is correctly tagged by MusicBrainz
355
343
  def mb_tagged?
356
- ! @musicbrainz_infos.empty?
344
+ !@musicbrainz_infos.empty?
357
345
  end
358
346
 
359
- private
347
+ private
360
348
 
361
349
  def sanitize(input)
362
350
  s = input.is_a?(Array) ? input.first : input
363
- s.gsub("\000", "")
351
+ s.delete("\000")
364
352
  end
365
353
 
366
354
  def default_fill_musicbrainz_fields(tags = @info.tag)
367
- MUSICBRAINZ_FIELDS.keys.each do |field|
355
+ MUSICBRAINZ_FIELDS.each_key do |field|
368
356
  val = tags["musicbrainz_#{field}"]
369
357
  @musicbrainz_infos[field] = val if val
370
358
  end
371
359
  end
372
360
 
373
361
  def default_tag_fill(tags = @info.tag)
374
- %w{artist album title}.each do |v|
375
- instance_variable_set( "@#{v}".to_sym, sanitize(tags[v]||"") )
362
+ %w[artist album title].each do |v|
363
+ instance_variable_set("@#{v}".to_sym, sanitize(tags[v] || ''))
376
364
  end
377
365
  end
378
366
 
379
367
  def fill_ape_tag(filename)
380
- begin
381
- @info = ApeTag.new(filename)
382
- tags = @info.fields.inject({}) do |hash, (k, v)|
383
- hash[k.downcase] = v ? v.first : nil
384
- hash
385
- end
386
- default_fill_musicbrainz_fields(tags)
387
- default_tag_fill(tags)
388
-
389
- @date = tags["year"]
390
- @tracknum = tags['track'].to_i
391
- rescue ApeTagError
368
+ @info = ApeTag.new(filename)
369
+ tags = @info.fields.each_with_object({}) do |(k, v), hash|
370
+ hash[k.downcase] = v ? v.first : nil
392
371
  end
393
- end
372
+ default_fill_musicbrainz_fields(tags)
373
+ default_tag_fill(tags)
394
374
 
395
- def faad_info(file)
396
- stdout, stdout_w = IO.pipe
397
- stderr, stderr_w = IO.pipe
375
+ @date = tags['year']
376
+ @tracknum = tags['track'].to_i
377
+ rescue ApeTagError
378
+ end
398
379
 
399
- fork do
400
- stdout.close
401
- stderr.close
402
- STDOUT.reopen(stdout_w)
403
- STDERR.reopen(stderr_w)
404
- exec 'faad', '-i', file
405
- end
380
+ def faad_info(path)
381
+ require 'open3'
406
382
 
407
- stdout_w.close
408
- stderr_w.close
409
- pid, status = Process.wait2
383
+ output = ''
384
+ status = nil
410
385
 
411
- out = stdout.read.chomp
412
- stdout.close
413
- err = stderr.read.chomp
414
- stderr.close
386
+ begin
387
+ Open3.popen3('faad', '-i', path) do |_stdin, _stdout, stderr, wait_thr|
388
+ output = stderr.read.chomp
389
+ status = wait_thr.value
390
+ end
391
+ rescue StandardError
392
+ end
415
393
 
416
- # Return the stderr because faad prints info on that fd...
417
- status.exitstatus.zero? ? err : ''
394
+ status&.exitstatus&.zero? ? output : ''
418
395
  end
419
396
 
420
397
  def shell_escape(s)
421
- "'" + s.gsub(/'/) { "'\\''" } + "'"
398
+ "'#{s.gsub(/'/) { "'\\''" }}'"
422
399
  end
423
400
 
424
401
  def tag_with_shell_command(*command_arr)
@@ -428,10 +405,10 @@ class AudioInfo
428
405
  end.flatten
429
406
  end
430
407
 
431
- hash = {:src => @path}
408
+ hash = { src: @path }
432
409
  if command_arr.include?(:dst)
433
- Tempfile.open(["ruby-audioinfo", "."+@extension]) do |tf|
434
- cmd = expand_command.call(hash.merge(:dst => tf.path))
410
+ Tempfile.open(['ruby-audioinfo', ".#{@extension}"]) do |tf|
411
+ cmd = expand_command.call(hash.merge(dst: tf.path))
435
412
  tf.close
436
413
  if system(*cmd)
437
414
  FileUtils.mv(tf.path, @path)