Using MPlayer identify with Ruby

Posted by andy

For a project I need to fetch some metadata from WAV recordings. Mplayer can extract this information nicely with the -identify command. I’m using Ruby Sessions for executing the external mplayer command, although a simple IO.POpen() might do fine too. The code wrapper class looks like this:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
require 'rubygems'
require_gem 'session'

class MediafileInfo
        MPLAYER_BINARY = "mplayer"
        MPLAYER_IDENTIFY = "-identify -vo null -ao null -frames 0"

        def initialize(filename)
                stdout, stderr = '', ''
                shell = Session::Shell.new
                shell.execute "#{MPLAYER_BINARY} #{MPLAYER_IDENTIFY} #{filename}", :stdout => stdout, :stderr => stderr

                vars = (stdout.split(/\n/).collect! { |o| o if o =~ /^ID_/ } ).compact!

                vars.each { |v|
                        a, b = v.split("=")
                        eval "@#{a.to_s.downcase} = \"#{b}\""
                }
        end

        # Intercept calls
        def method_missing(method_name, *args)
                value = eval "@id_#{method_name.to_s.downcase}"
        end
end

All ID_* lines that mplayer spits out will now be method calls (and instance variables) of your MediafileInfo object. The method_missing call is there to do proper value defaulting if the variable doesn’t exist, but I’m not using it as such right now. To get the playing time of every type of mediafile that mplayer understands you simply do someting like:
1
2
3
info = MediafileInfo.new("voicemail.wav")

puts "Voicemail playtime: #{info.length.to_i} seconds"
Ruby 0wnz! :)

Comments

Leave a response

  1. p3t0rJuly 12, 2006 @ 09:08 PM
    Cool hack! I tried to figure out why you use the compact! function... doesn't this return nil if it didn't make any changes?
    
    irb(main):001:0> ["a","b","c"].compact!
    => nil
    irb(main):002:0> ["a","b","c",nil].compact!
    => ["a", "b", "c"]
    irb(main):003:0> ["a","b","c",nil].compact
    => ["a", "b", "c"]
    
    
    Using compact seems safer to me...
  2. andyJuly 13, 2006 @ 08:58 AM
    According to the specs yes, but this is never an issue in this case. But you are right, it is still safer to use compact, nice catch :) -andy
  3. albertFebruary 16, 2007 @ 04:19 PM
    I had to do something similar. Check out my version, based on yours. http://pastie.caboo.se/40788
  4. andyApril 17, 2007 @ 03:17 PM
    @albert: much more robust implementation, nice!

    thx,
    andy