Reccenter.com LLC

Installing and Using Ruby-filemagic and Libmagic on OS X Lion With Homebrew & Paperclip

Much of my work has to do with uploaded audio and video, and checking mime-types from uploaded audio and video not fun. The only reliable way i have found to check files is with the libmagic library, using the ruby-filemagic gem to cross the bridge from ruby to that library.

Whenever possible i install all libraries and software with Homebrew for OS X.

Installing libmagic used to be a multistep error-prone process. Fortunately it has gotten easier, but still causes trip-ups due to the need to “link” the libmagic libraries.

$ brew install libmagic
$ brew link libmagic

Now you can install ruby-filemagic gem

$ [sudo] gem install ruby-filemagic

EDIT - I will be releasing code to reuse this as a paperclip preprocessor. The more I look at this the messier i think it is.

I use a before_filter to check mime-types because the Paperclip mime-type checker coupled with Firefox is notoriously terrible, especially when dealing with mp3 audio. Note that this should likely be a Paperclip Preprocessor.

Add the ruby-filemagic gem to your Gemfile.

gem "ruby-filemagic"

And setup your model’s before_validation .

has_attached_file :attachment

def before_validation
  self.audio_content_type = FileMagic.new(FileMagic::MAGIC_MIME).file(self.audio.to_file.path).gsub(/\n/,"").split(";").first

  if @song.audio_content_type != 'audio/mpeg' && @song.audio_content_type != 'audio/mp3'
    @song.errors.add_to_base("This file is not an MP3 - it's mimetype is #{@song.audio_content_type}.")
  else
    begin
      mp3_info = Mp3Info.open(audio_data.path)
      if mp3_info.vbr
        @song.errors.add_to_base("This MP3 is VBR (variable bit rate) — we only support CBR (constant bit rate).")
        # VBR mp3s do odd things when streaming.
      end

      if mp3_info.samplerate != 44100 
        @song.errors.add_to_base("This MP3 has an unsupported sample rate - it is #{ "%.3f" % (mp3_info.samplerate.to_f / 1000.0)}khz — we only support 44.100khz.")
        # MP3s with odd sample rates are buggy when streaming via flash
      end

      if mp3_info.bitrate > 320
        @song.errors.add_to_base("This MP3 has an unsupported bitrate - it is #{mp3_info.bitrate}kbps — we only support up to 320kbps.")
        # A bit rate higher than 320 is ridiculous
      end
    rescue
      @song.errors.add_to_base("This file does not appear to be an MP3.")
    end
  end
end

Any questions? Have a better way?

Comments