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! :)