pahnin
pahnin

Reputation: 5588

optimising reading id3 tags of mp3 files

I'm trying to read mp3 files using 'mp3info' gem and by going through each file which ends with .mp3 in its file name in a directory and going inside a directory using Dir.chdir() and repeating the process and storing these tags in database. But I have 30gb of music collection and it takes around 6-10 mins for the whole scan to complete. Is there any way I can optimise this scan?

        def self.gen_list(dir)
        prev_pwd=Dir.pwd
        begin
            Dir.chdir(dir)
        rescue Errno::EACCES
        end
        counter = 0
        Dir[Dir.pwd+'/*'].each{|x|
            #puts Dir.pwd
            if File.directory?(x) then
                self.gen_list(x) do |y|
                    yield y
                end
            else if File.basename(x).match('.mp3') then
                    begin
                        Mp3Info.open(x) do |y|
                            yield [x,y.tag.title,y.tag.album,y.tag.artist]
                        end
                    rescue Mp3InfoError
                    end
                end  
            end
        }
        Dir.chdir(prev_pwd)
    end

This is the method which generates list and sends the tags to &block where data is stored in database..

Upvotes: 0

Views: 219

Answers (4)

bheeshmar
bheeshmar

Reputation: 3205

You may also benefit from a more direct way of retrieving the mp3 files.

Dir['**/*.mp3'].each |filepath|
  Mp3Info.open(filepath) do |mp3|
    ...
  end
rescue Mp3ErrorInfo
  ...
end

This will find all .mp3 files at any depth from the current directory and yield the relative path to the block. It is approximately equivalent to find . -name '*.mp3' -print

Upvotes: 0

Jeff Price
Jeff Price

Reputation: 3229

Have you tried setting the parse_mp3 flag to false? by default it is on which means you are going to pull in the entire file for each scan when all you care about is the info. I don't know how much time this will save you. See the github source for more info.

https://github.com/moumar/ruby-mp3info/blob/master/lib/mp3info.rb#L214

# Specify :parse_mp3 => false to disable processing of the mp3
def initialize(filename_or_io, options = {})

Upvotes: 1

Ch4rAss
Ch4rAss

Reputation: 754

You can try taglib-ruby gem which is unlike mp3info wrapper over C library and it could give you little bit more performance. Otherwise you have to stick to JRuby and run multiple threads (4 if you have 4 cores).

Upvotes: 1

Yuri Golobokov
Yuri Golobokov

Reputation: 1965

You can:

  1. Run several processes (for each directory in the base dir, for example)
  2. Use threads with rubinius or JRuby.

Upvotes: 1

Related Questions