Enigmamachine is a video processor which queues and encodes videos according to target profiles that you define. Videos must be on a locally mounted filesystem. The processor takes the path to the video, and executes one or more ffmpeg commands on the video. There is a handy web interface for defining encoding tasks, and a restful web service which takes encoding commands.
Enigmamachine is written using Sinatra, Thin, and Eventmachine.
Why would you want one?
If you're not running a server, you probably don't need enigmamachine, because there are already lots of great client-side batch processors for all kinds of different operating systems. However, if you are running a web application, and you want to process uploaded video, enigmamachine offers you a convenient fire-and-forget video encoder.
The main problem with encoding video on a server is that it takes a really, really long time - you don't want to do it within the scope of a single HTTP request, because you want the user's browser to return to their control as soon as the upload is finished. If the video took ten minutes to upload, you don't want to keep their browser (and your webapp) busy for a further ten minutes while the encoding happens.
The right way to deal with the uploaded video is to fire up a new thread which can take over responsibility for encoding the video, while your web app goes on its merry way. Unfortunately, this is difficult in some languages (PHP, for example, doesn't have lightweight threading support), and even in languages with good threading support it still sort of sucks. With Enigmamachine, all you need to do to trigger encoding of a video is shoot off an HTTP request, and everything else is handled for you.
Once you've installed the gem (see below), you can do something like:
mkdir enigma cd enigma enigmamachine start # -d to daemonize
Then check it out in your browser, at localhost:2002.
Your application receives a video, and you do an HTTP call like:
with the params:
params["video"] # the full path to a file on your local filesystem params["encoder_id"] # the id of an encoder defined in your database
The enigmamachine will run all encoding tasks on the video. If a new video is uploaded while the first one is still encoding, it will be placed in a queue. Videos are encoded sequentially as they arrive.
Encoders and Encoding Tasks
When you POST the location of a video to your enigmamachine, you need to tell your EM what you want to do to the video. For example, you might want to take an uploaded video and encode it as a 320x240 FLV video, with a 320x240 JPEG thumbnail, and a 160x120 miniature thumbnail.
To do this, you'd fire up your enigmamachine by typing
and go to localhost:2002/encoders. Clicking the “new encoder” link will allow you to define a new encoder. Let's call it “Flash video with a couple thumbnails”, and save it.
So, now there's an encoder, but it won't do anything. Let's add some tasks, by clicking on the “new task” link.
Give the first task a name, like _Encode a 320x240 flv at 25 frames per second_.
The output file suffix in this case will be .flv.
The encoding command you'll want to use would be _-ab 128 -ar 22050 -b 500000 -r 25 -s 320x240_. This cryptic command string tells ffmpeg to encode a Flash video at 320x240 pixels, with an audio bitrate of 128kbps, an audio sample rate of 22.050khz, and a frame rate of 25fps. You can find out what all the ffmpeg command line switches do by RTFMing at www.ffmpeg.org/ffmpeg-doc.html
You would go on to define a couple more encoding tasks for your encoder. Grabbing a screen frame in ffmpeg can be done with the following command-line switches, which you can put into a task called, let's say, _Grab a 320x240 JPEG thumbnail_:
-ss 00:00:05 -t 00:00:01 -vcodec mjpeg -vframes 1 -an -f rawvideo -s 320x240
Rinse and repeat for the 160x120 thumbnail.
Enigmamachine is set to bind by default to 127.0.0.1 (your system's loopback) interface rather than on all network interfaces.
Making an enigmamachine available on an untrusted network (like the Internet) would be a suicidal move on your part, since the code used to talk to ffmpeg is a simple exec call and you'll be inviting everyone in the world to execute commands on your server. Have fun with that.
If you don't know what any of this means, don't run it. I'm not responsible if your enigmamachine screws up your system, allows people to exploit you, or eats your mother.
Enigmamachine is written in Ruby and uses the Sinatra web framework, the Datamapper ORM library, the Eventmachine event-processing library, and the Thin webserver. If you're not a Ruby person, you don't need to care about any of this. Enigmamachine can be triggered by any language that can send a POST request - so all you PHPistas, python-lovers, droopy-moustachists, or blue-suited java types can all use it just as easy as us fashionable-haircut-language people.
You can install it as a gem by doing:
gem install enigmamachine
If this command doesn't make any sense to you, it's because you don't know that “gems” are ruby code packages, somewhat like apt-get except for ruby code only. You can install rubygems, necessary sqlite headers, and a C compiler on righteous operating systems by typing:
apt-get install rubygems ruby1.8-dev libopenssl-ruby build-essential libsqlite3-dev # as root
You'll need to add the following line to your ~/.bashrc file, as well:
Then gem install enigmamachine should theoretically work. You'll also need a copy of ffmpeg installed and available in your path. On Mac OS X, rubygems should already be installed, although you'll need to have a C compiler available (make sure you install the developer tools that came with your operating system).
This thing is still pre-release.
I'm just working on getting the gem dependencies correct, so you may need to manually install a few things to get it to work. You'll also need a working copy of ffmpeg available on your path.
Note on Patches/Pull Requests
Fork the project.
Make your feature addition or bug fix.
Add tests for it. This is important so I don't break it in a future version unintentionally.
Commit, do not mess with rakefile, version, or history. (if you want to have your own version, that is fine but bump version in a commit by itself I can ignore when I pull)
Send me a pull request. Bonus points for topic branches.
Copyright © 2010 Dave Hrycyszyn. See LICENSE for details.