E_NO_SUCH_BLOG

Programming, philosophy, pedaling.


Mini-post: Introducing ruby-mpv

Jan 16, 2017

Tags: programming, ruby

Preword: I’ve decided to stop doing weekly muzak development posts, but I figured I would give a brief introduction to a new library that I spun off of muzak during its development.

First of all: mpv is a fantastic media player. It’s lightweight, flexible, embeddable, scriptable, and can be used for just about anything involving streams of audio and/or video. It’s simultaneously one of the most powerful programs in my toolbox and one of the easiest to use — not an easy feat.

I use it on a daily basis to watch YouTube videos (and every other source that youtube-dl supports) via the built-in ytdl_hook. I also have a few custom scripts to use mpv for things like video links in subreddits and pandora streaming. These take advantage of mpv’s excellent JSON IPC and Lars Gustäbel’s python-mpv library to provide fine-grained control of an mpv process.

This was all fine, but I wanted a (full) Ruby equivalent of python-mpv. Among other things, this meant supporting:

I found Stefan Dorn’s mpv-slave during my initial research, but it doesn’t seem to be actively developed and, more unfortunately, doesn’t support real-time events or client/server isolation.

Therefore, it was time for ruby-mpv:

require "mpv"

# an example class that we might want to interface with mpv
class Foo
  def bar(event)
    puts event
  end
end

foo = Foo.new

# a server/client pair
mpv = MPV::Session.new

# tell mpv to call this method from this object whenever an event occurs
mpv.callbacks << MPV::Callback.new(foo, :bar)

# issue a command to the mpv process
mpv.command "loadfile", "song.mp3", "append-play"

# terminate the MPV::Session
mpv.quit!

Internally, ruby-mpv is very simple - it’s just four classes:

Full documentation of these classes is available on RubyDoc, or via yard:

$ git clone https://github.com/woodruffw/ruby-mpv
$ cd ruby-mpv
$ yard
$ ${BROWSER} doc/index.html

It’s also, of course, been published as a gem:

$ gem install mpv # require "mpv"

Happy hacking!

- William