MultimediaParadise - Everything about audio and video
The multimedia paradise project bundles together code that can be used for "multimedia data" - in particular for audio and video files.
Most of the functionality found within the multimedia paradise projects depends on ffmpeg, but in principle the code in the main module called MultimediaParadise should work with other toolkits as well, if a toolkit supports certain actions (such as sox). As is often the case, support for other toolkits depends on time investment - and time availability - of the main author of this project.
For all purposes, though, ffmpeg is a really excellent project. Thus, the MultimediaParadise gem will focus on ffmpeg by default. You can obtain a copy of ffmpeg at the following URL:
Installation of the MultimediaParadise project
There are several ways how to install this project, including oldschol setup.rb - but I recommend the following way:
gem install multimedia_paradise --user-install
The reason as to why I recommend the --user-install option is because the various files under the bin/ subdirectory will be available in your home directory (under e. g. ~/.gem/ruby/2.5.0/bin or whatever your local ruby version is). That way you can easily add that directory to $PATH or not, and make use of these files.
Removing audio from a video file
If you wish to remove audio from a video file, use the following API:
The MultimediaParadise project can generate .m3u files, as long as they are simple, e. g. one entry per line. For the purpose of the document here, we will call such .m3u files playlists.
The class responsible for the creation of .m3u files is class MultimediaParadise::CreateM3uPlaylist, residing at the location multimedia_paradise/audio/create_m3u_playlist.rb within the MultimediaParadise project.
The primary objective of this class is to generate that .m3u text file. Of course you can do so easily without the project - just do a "ls" and pipe it into a file - but I wanted this functionality specifically within the project, so that I can automate the creation of playlists, including batch-uploading to other sites at a later time, such as for youtube and other sites.
I myself use this class to generate playlists for various different song types - be these eurodance songs, trance songs, pop songs and so forth. Once such a .m3u file has been (auto)generated, it could then be used for upload to an external site, as mentioned, such as to youtube or other websites that support such playlists. Of course in order for this to work you may need to provide valid URLs to these individual entries somehow. The primary use case for class MultimediaParadise::CreateM3uPlaylist is for local audio files, though.
The input to class MultimediaParadise::CreateM3uPlaylist should ideally be a yaml file describing your songs (at the least the path to these songs), but you could also use the API from within Ruby, naturally (and thus use a ruby array directly that is to be passed to the class; just pass this Array to .new()).
You can also use this simpler toplevel method, in ruby instead:
The first argument to this method should contain the dataset that you will use for the .m3u file that is to be autogenerated. This should be a simple Array.
You can, naturally, rename the .m3u file after it has been created, since a default name will be used - the generic name used for generation of the file will be playlist.m3u.
For my own custom dataset, e. g. to generate a playlist with good tales-from-the-crypt videos, I can just do:
The MultimediaParadise project also comes with another class, called class Playlist, which has a different task. That class Playlist will handle audio-playlists, primarily. For example, it can play audio files at certain positions in the playlist.
Usage example from the commandline for this:
Would play the songs at position 33, then 44 and then 55. It is thus a very primitive sort of jukebox. See playlist --help for help options.
You can change positions in that playlist. To exchange position 95 with position 94, you could use input like this:
playlist "95 -> 94"
This would mean to take the song at position 95 and move it to position 94. Conversely the song at position 94 will be moved to 95; this is thus an exchange operation.
Since as of October 2018, the MultimediaParadise project comes with a small yaml file called radio_stations.yml.
x = YAML.load_file('radio_stations.yml')
The idea here is to have a few additional audio-streams (from radio stations) that could be loaded up into, for example, rhythmbox.
I also wanted to have a default "template" for testing some ruby code there, such as autogenerating a playlist from this file, or listening to radio stations via mplayer (or mpv) and similar activities.
The file radio_stations.yml is evidently catered to my own use case. If you wish to use your own .yml file then you can do so by setting the environment variable called MULTIMEDIA_PARADISE_RADIO_STATIONS to the path of a local yaml file. For the necessary format, see the file radio_stations.yml that comes distributed with this .gem.
I may listen to local internet radio stations but also to external ones, such as BBC. The following example shows how I tap into this functionality, first by showing BBC 1:
multimedia_paradise --bbc1 multimedia_paradise --bbc2 multimedia_paradise --bbc3 multimedia_paradise --bbc4 multimedia_paradise --fm4
The above list may be extended in the future, but for now (December 2018) it shall suffice.
Do note that this functionality depends on a multimedia player, such as mpv or mplayer. See elsewhere in this document how to set to use such a multimedia player.
There is code support for streamripper, just a tiny wrapper.
This can be invoked like so:
This depends on the file streamripper_wrapper.rb which is just a tiny, pure-ruby "wrapper" over streamripper. (It really only directly calls the streampripper binary, so nothing fancy.)
Modifying the timestamps of .srt files
The file srt_regex.rb can be used if you need to batch-modify .srt files, when they have the wrong timestamp, for instance. This was exactly the reason why I wrote that class - some .srt files may have a wrong offset, and so we need to correct them.
Note that this class is quite old and the code quality is not as high as other classes since I wrote it a long time ago. I may improve on it eventually, but for the time being, assume that it isn't one of the best classes in this project.
A watermark is a specific tag to a video. This can be a logo but it can also be used as some kind of (annoying) filter.
Whatever your use case may be, ffmpeg supports watermarking videos - and multimedia_paradise taps right into that functionality.
Adding a watermark to a video is possible and quite simple. The class that does so, in regards to the MultimediaParadise project, is aptly called Watermark and it allows you to use FFMPEG to embed a watermark video, using the simple MultimediaParadise.watermark() method.
I rarely need to use this method so it may not be as polished as other parts of the project, though.
The default use is to simply call that .rb file and pass a video file to it:
(vwatermark is an alias on my system.)
If you want to use your own image, then you have to pass an additional argument to the method, which should be the path to the image at hand.
vwatermark /Depot/Temp/MultimediaProject/foobar.mp4 /opt/my_awesome_logo.png
Embedding Youtube Videos
"Embedding" Youtube Videos is also possible. Note the quotes.
The code is in the file multimedia_paradise/video/youtube_embedder.rb.
Increasing the volume of an audio file
You can use the module-level method:
The first argument to this method should be the name of the file that you wish to modify or the name of the files. This is usually a file such as foobar.mp3 or similar.
The second argument is the modified percentage value that is given to -v (and to sox). For example, if you pass in 2.0, then the volume of the audio file at hand will be increased twofold. If it is 3.0, then it will be increased threefold, and so on.
Since the name of the method is "increase_volume", that particular method can not be used to decrease the volume (via negative floats such as -2.0).
Download videos from Google
The file google_video_downloader.rb can be used to download videos from Google - but we may have to use youtube-dl for this, which is python. This is not ideal since we use ruby :) but I am too lazy to clone the functionality of youtube-dl for now, so this just has to be glue code really. (Glue code is for lazy people and I am lazy.)
Extracting audio from any given video file
You can extract audio from any given video file, by making use of class MultimediaParadise::ExtractAudio. This presently depends on ffmpeg, so you must have ffmpeg available.
Usage example follows:
This assumes that a video file called foobar.avi exists.
A toplevel method exists for this functionality as well:
.(target_file_here) .('/tmp/foobar.avi') .('/home/lala.mp4')
Perhaps you may find the latter variant to be easier to read and use than the variant that uses explicit :: scoping for the instantiation of class ExtractAudio. Under the hood, both variants do the same of course.
If you want to capture the screen, that is, to record what is happening, have a look at the class called MultimediaParadise::CaptureScreen, in the file multimedia_paradise/video/capture_screen.rb.
Autoinclude the main namespace
Since April 2014 you can autoinclude this project's main namespace (toplevel MultimediaParadise constant) by using the following ruby code:
Using the executable bin/mpa
mpa is a small wrapper over mpv (or mplayer).
It is tailored to my own local videoset, which I store in a yaml file. I am not sure how to best have other people use mpa without the .yml file, but at the worst, it is possible to just use bin/multimedia_paradise to play an existing local video or audio file.
Guessing video names
I use a .yml file to keep track of registered video files.
I also needed a class that tells me the most likely name of a video file, e. g. if the input is "Ninja", then this class should report all Ninja video files, properly sorted, according to the information contained in that .yml file. (This of course requires that this genre is registered in that .yml file.)
class MultimediaParadise::GuessVideoName does precisely that. Input the given search term at hand, such as horror for horror movies, and it should hopefully report some information that may be useful in order to find/name the video file at hand.
Note that this depends on a properly formatted .yml file; and ideally you would create your own .yml file, with your own tags, videos and so forth.
The format of the .yml file should be like this:
a) The number of the video file at hand, as an Integer value, such as 1, 2, 3 and so forth. b) A hash that describes at the least the 'title', but may also contain entries such as imdb: and so forth.
Finding local videos
The file find_video.rb can be of help here as it will try to locate local videos.
This is optimized towards my own dataset compiled about videos; in the future, I will most likely provide a way so that other people can also use their own dataset. (The dataset I use is a simple yaml file storing all information about the local videos.)
Playing a random (video or audio) file
class MultimediaParadise::PlayRandomFile can play a random multimedia file. Since this will select a file randomly, you can only pass in a directory for now - although passing in an Array may also make sense, so perhaps this class will be extended at a later time.
This class is just a thin "wrapper" over mplayer or mpv really. It has been created in early June 2014.
The file can be found at multimedia_paradise/audio/audio_player/audio_player.rb.
It was originally created because I needed to play, via the commandline, audio songs in a loop - like a juke box. I wanted it to be very simple too, so no ncurses interface to it.
I also use it to perform wake-up calls in the morning, like an alarm clock.
There is an executable for this, at bin/audio_player, which acts as entry point to the code behind it, for class MultimediaParadise::AudioPlayer:
If you want to play in a loop, you can pass the argument "loop" or just "l".
Since as of the 24th February 2018, it can also act as a "timer", together with class Roebe::At. For example, if you want to play random songs at the time 21:35:00, you can do:
Note that rsong is simply an alias that I use towards bin/audio_player. Without an alias, the above becomes:
Usually I tend to use mpv, but sometimes I do use mplayer, e. g. when mpv has some problem due to recent API changes. In this case, one can specify to use mplayer on the commandline, via:
rsong 10:00:00 --use-mplayer
Delaying the audio of a video-file
FFmpeg allows you to easily delay the audio of a video file.
MultimediaParadise has this included as well, via:
The first argument to this should be the name of the file that you wish to manipulate, such as foobar.mp4.
The second argument is the amount of seconds for the delay, such as 5.53 seconds.
A new video-file will be generated as a consequence, if all goes well.
class ConvertAudioToVideoWithImage allows you to "attach" a static image file to an audio file, such as a .mp3 file.
This functionality depends on ffmpeg, so you need to have ffmpeg available in order to make use of this class.
Two arguments are necessary to class ConvertAudioToVideoWithImage:
(1) first, the audio-file (2) second, the image file that you wish to use
You can also use the following toplevel-method:
with the same parameter pattern.
To give you a specific example - say that you have your .mp3 file at:
And your image at:
Then the proper way to use the toplevel-method would be:
This subsection is about removing noise from a multimedia file.
Noise in this context refers to unwanted audio, such as scratching on a blackboard during a university lecture, and similar unwanted noises.
First, this functionality was needed because I inherited audio recordings that were made via a cheap mp3-recorder from like +10 years ago or so, say, the year 2009 - something like that.
The human voice has a frequency range between 300Hz - 3000Hz.
The noise in these files was extremey disturbing and distracting, and I wanted to get rid of it, in order to more easily hear the voice of the speaker. This also included increasing the volume as well, but that is for another subsection.
The subsection here will additionally report some of my findings from back then - as a memo.
A simple filter-strategy is to first apply highpass, and then lowpass, via ffmpeg, such as in this way:
ffmpeg -i foobar.mp3 -af "lowpass=f=3000, highpass=f=200" output.mp3
Your local file comes first, such as the file *foobar.mp3. This should remove some of the noise that you may find in a recording, but you may have to tweak the values a little in order to get the most out of it.
Note that you can use ffplay to see the effect of this:
ffplay INPUT_FILE -af lowpass=3000,highpass=200 ffplay foobar.mp3 -af lowpass=4000,highpass=200 ffplay foobar.mp3 -af lowpass=2000,highpass=200
I integrated this functionality into MultimediaParadise, via the following simple API:
This is the default use case, by just supplying the name/path to the audio file in question.
The second argument to this method is the lowpass value; the third argument is for the highpass value:
.('foobar.mp3', '250', '2000')
This, surprisingly enough, worked. But I do not think it is the ideal value.
For more information, see the following blog entry from 2017:
If you need to find out which values are best, you can use ffplay such as in this way:
ffplay INPUT -af lowpass=3000,highpass=200
Creating a screencast with multimedia_paradise and FFMPEG
Code in the file multimedia_paradise/toplevel_methods/screencast.rb can be used to record a screencast (on Linux).
The API is as follows:
The method accepts several parameters - if you need fine tuning then have a look at that file.
Presently only video without audio can be recorded, but there are tutorials out there that enable recording of audio as well. I will have a look into this at a later time (<- written in September 2018).
Changing the audio code of a video file via FFMpeg
If you want to change the audio codec in a given video file, say, foobar.avi, then you can use this API:
This essentially just combines -vcodec copy -acodec libmp3lame but I wanted to have a simpler top-level API in ruby for this too, so this method was added.
Query the audio codec of a video file
You can use this top-level API to determine the audio codec of a video file:
.() .query_the_audio_codec() .audio_codec?()
All variants listed above work; the last option is the shortest one, apparently.
The argument should be the path to a locally existing videofile.
Say that your file is at /Depot/foobar.avi then the ruby code may look like this:
require 'multimedia_paradise' uses_this_codec = .audio_codec?('/Depot/foobar.avi')
This functionality depends on ffmpeg.
Converting into .mp3 format
You can use class MultimediaParadise::Audio::ToMp3 to convert e. g. a .wav file into a .mp3 file:
As this may be a bit cumbersome to type, there exists a simpler top-level method to convert an audio-file into the .mp3 format:
.(*input_files_here) .( %( foo.wav bar.wav ) )
This subsection just shows a few options for ffmpeg; I added this mostly because I tend to be quite forgetful. That way I can have a quick overview on the homepage of this gem here.
|Commandline flag||Example||Implementation Status|
|-s||-s 500×500||convert the video into a width x height ratio, of 500 x 500 pixel|
|-vcodec||-vcodec mpeg4||specify which video-codec is to be used, e. g. for the conversion of a video file|
The toplevel method MultimediaParadise.set_player_in_use() can be used to set the main multimedia player (audio + video) in use for the MultimediaProject. Normally I set this to mplayer or mpv, but vlc or any other player could also be used here.
Playing several multimedia-files from a list/file
You can pass a list of files that the MultimediaParadise project should play.
The toplevel method is MultimediaParadise.play_this_list(), so for example:
.play_this_list ' /Users/x/VIDEO/Cartoons/Simpsons-09/Treehouse_Of_Horror_VIII.m4v /Users/x/VIDEO/Cartoons/Simpsons-09/The_Joy_Of_Sect.m4v /Users/x/VIDEO/Cartoons/Simpsons-08/The_Springfield_Files.m4v '
Empty lines will be ignored, so the method will only play these entries if they are not empty.
The alias MultimediaParadise.play_from_this_list() would also work, by the way.
I needed this functionality because sometimes other classes written in ruby may show, on the commandline, such a flat list, via a long String broken by newlines.
Environment variables for the MultimediaParadise project
The MultimediaParadise project is tailored to my own needs primarily, which means that other people may not necessarily benefit from the project as much. Additionally, as of December 2018, there are some hardcoded paths, which makes this even worse. I have decided in December 2018 that this approach will change in the future.
For the time being, you can use certain ENV (environment) flags to specify where your audio/video files are kept. This assumes that you have one central directory for these files; respectively up to two, if you keep your audio and video files separate.
For specifying where your local video files reside, you can use the constant called MULTIMEDIA_PARADISE_DEPOT_VIDEO. Simply set this, in your shell, to be the path to the directory where your video files may be, such as in:
A similar constant exists for audio files; simply set MULTIMEDIA_PARADISE_DEPOT_AUDIO.
Genre support of video files
If you have a .yml file that keeps your video files sorted, then you can also use a genre: tag identifier to classify the video at hand.
For example, the movie The Blade Runner may have an associated genre called Science Fiction. The movie Poltergeist may have a genre tag called Horror and so on.
Once the genre-tagging has been done, we can search for these genres on the commandline, via class VideoGenres.
See its --help option for commands.
If you wish to find out which science fiction movies are registered, do:
video_genres --genre="Science Fiction"
You can also use a shorter variant, via a Pseudo-Regex:
video_genres "/Science Fiction/"
Some shortcuts exist if the above is too cumbersome. For example, all science fiction movies could also be shown via this way:
To see the available video genres, do this:
It you want to play a random horror movie, provided that you have these registered tags, you can do the following:
Copying and merging the same video
If you sort of wish to "duplicate" a video, but append this onto an existing one, then you can use this method:
The first argument should be the existing video file; the second argument should be how many times it should be "repeated", which should be a number. For example, the number 5 means that the video will be merged onto itself 4 times, thus creating a video that is 5x the length (all with the same content).
There are alternatives to this, such as looping the same video; but I wanted to really be able to have the same video be played over and over again, even though this made the size larger.
class MultimediaParadise::AnalyseMultimediaFile can be used to analyse multimedia files (e. g. audio and video files), on the commandline.
I needed this because ffmpeg -i alone was tiresome to read.
Flipping and rotating video files
FFMpeg can easily flip video files. MultimediaParadise supports this functionality too, through the file multimedia_paradise/toplevel_methods/flip_and_rotate.rb.
Horizontal and vertical flipping is supported through these two toplevel APIs:
The latter variant also has a simpler, more intuitive API:
So essentially, you picture a video, and then simply flip the top to the bottom, and the bottom to the top. Easy-peasy.
The first argument to this method should be the name/path to an existing video file.
You can also rotate a video file by 90° via this API:
Since as of March 2019, two more methods were added to flip a video (rotate a video) clockwise and counter-clockwise, by 90° each:
So the older method MultimediaParadise.rotate_this_video_file_by_90_degrees() is essentially the same as the newer method MultimediaParadise.flip_video_to_the_right.
Merging audio files together
class MultimediaParadise::MergeAudioFiles can be used to merge different audio files together. If no specific input argument is provided then this class will scan for all audio files in the current working directory and all subdirectories, then merge these together into a new file called output.mp3.
I needed this functionality so that I could put lectures together into a single file - made it easier to listen to a single file, rather than find them all spread out.
Toplevel cutting multimedia files
This subsection deals with cutting multimedia files, that is, to chop a longer file into one (or several) smaller files.
The primary method for this is called MultimediaParadise.cut_from_to(), but you can also use a few aliases to this method, such as MultimediaParadise.cut().
The API is flexible.
Let's first show a few examples:
.('00:00:01-00:25:10', this_file: 'Tales_from_the_crypt_S05E10_Came_the_Dawn_1993.mp4') .('00:02:23 / 00:28:04', this_file: 'Tales_from_the_crypt_S05E10_Came_the_Dawn_1993.mp4') .cut(to: '00:22:50', this_file: 'TALES_FROM_THE_CRYPT/Tales_from_the_crypt_S06E11_Surprise_Party.mkv')
These are somewhat equivalent.
The simplest way may be to pass, as first argument, a String to the method, denoting the start position and the end position, in HH:MM:SS format. But you can also decide to use a Hash instead, such as the third example shows.
Do note that if you decide to use a String, you can either use the '-' variant or a ' / ' variant. The latter is the default display format for the mpv video/audio player, so I added support for it since copy/pasting may be a bit simpler that way.
The special key called :this_file should be the file that you wish to cut. The absolute path should be given here; for my home system I also use some fake-macros, such as TALES_FROM_THE_CRYPT/ to denote where tales from the crypt may reside (and other files). This allows me to more easily make use of my local file system.
The key :to refers to the end position, that is, when to make the cut.
The ideal scenario for this method is to simply cut from a start position to an end position - in other words, to make an existing video file shorter.
Do note that another class, called CutAudio, also exists as part of the multimedia_paradise project. This is partially due to legacy reasons; and partially due to CutAudio being primarily used for .mp3 files, and for interactive use. One day the functionality may be re-used, but for the time being I will keep it separate (less work for now).
If you rather want a simple API, where you input only two Strings usually (as parameters), then you could use:
The first argument would be the file that you wish to cut; and the second is the duration, so two Strings in total. Interally this will be passed to the method MultimediaParadise.cut_from_to() anyway, so you could even use a Hash instead - but the primary use case for that method is to allow for a simpler API. Use whatever you prefer.
Setting the title metadata of a .mp3 file
Thanks to ffmpeg we can easily modify the metadata entry of a .mp3 file. MultimediaParadise supports this too, via:
So the first argument should be the local path to a .mp3 file; and the second argument should be the title that this .mp3 file should have. I use this for batch-setting the title - and a file called bin/auto_title exists that does this from the commandline as well.
You can cut audio files via the class CutAudio. The code to this class resides under the subdirectory multimedia_paradise/audio/cut_audio/.
Invoke cut_audio (residing under bin/cut_audio) with the path to an .mp3 file or another audio file. You will then enter the interactive menu of class CutAudio, which allows you to do some specific tasks related to cutting and merging audio files (see the "help" section there, in interactive mode).
You may want to designate start and stop positions when in interactive mode. You can do so via prefixing "s" and suffixing "e", such as in the following way:
This would mean to "start at 10 seconds" and "end at 20 seconds". So we will cut out the intermediate 10 seconds between these two points.
Via "play" you can play the audio file; I recommend having installed mplayer or mpv for this task.
That way you can find out where you may wish to cut in the first place.
Once you have your start and end positions, you can run this command:
This will cut out the selected subsection; in this case the part from 10 seconds to 20 seconds.
The number specifies how many seconds are to be used. This can sometimes be a bit difficult to calculate in your head e. g. how many seconds do 83 minutes entail to.
A pseudo-calculator can be queried within class CutAudio.
This would quickly show you that the result of this is 360 seconds (the input meant 6 minutes, if you think about it).
There are many more options available, so have a look at the "help" section there. Keep in mind that CutAudio is a bit complicated to use sometimes, and also has a very few bugs as well (I did not get around to re-writing it, so for now this has to suffice).
Resizing a video
ffmpeg makes it easy to resize a video.
For example, say that you wish to re-scale an existing video to the same ratio, but with fewer pixels, like 640. You could use the following commandline invocation, with the -vf flag, for this task:
ffmpeg -i input.mp4 -vf scale=640:-1 output.mp4
In this case, output.mp4 will have 640 pixels in width.
The strange -1 is simply a way to tell ffmpeg that the same aspect ratio should be kept. That way ffmpeg will calculate which ratio value should be used, in order to retain the original width:height relation. You can sometimes see that people use the wrong aspect ratio, and then their video may look distorted.
MultimediaParadise also supports this via:
The first argument is the path to the local input-file, such as *input.mp4.
After that a Hash can be used, where height and width can be given.
.('input.mp4', height: 320, width: 220)
The argument for :width can be omitted, in which case -1 will be used as default:
.('input.mp4', height: 320)
Would be the same as:
.('input.mp4', height: 320, height: -1)
The value for height: can be ignored too, in which case it will default to 640 - but this default value may change one day in the future, so it may be better to specify at the least one value here. But, ultimately, if you don't care, this could also work:
We may even omit the first argument in the future, one day, if we assign a default file on the toplevel - but for the time being (September 2019), the API is how it is and requires at the least one argument.
Creating a video out of an audio file, such as a .mp3 file
Via the API MultimediaParadise.create_video_from_this_audio() you can "create" a video, from an audio file, such as a .mp3 file.
This requires a static image, which is the second argument to that method.
Why did I add this method? I needed a way to upload .mp3 files to a remote website but they had a filter removing .mp3 files; they allowed for .mp4 files, so I converted it into a .mp4 file and that works. That is strange, since you can always use ffmpeg to extract the .mp3 audio again - so I dont understand the filter that prevents .mp3 upload but allows .mp4 upload ...
Quite odd if you ask me.
Anyway - here an example for the official API for this, from within ruby:
this_audio_file = 'foobar.mp3' this_image_file = '/FORENSIC_CAT.jpg' .(this_audio_file, this_image_file)
class MovieSearcher can be used to look up information about a movie from http://www.omdbapi.com, if you have an API key.
The code written for this class is not great, but if all you need is some quick commandline information then this class could be used. It can be found at multimedia_paradise/video/movie_searcher.rb.
Since as of 02.01.2020, an executable is now distributed as well, called movie_searcher (under the bin subdirectory of this gem).
I have aliased this executable to videorating, and then simply do this on the commandline:
You may need an API key called OMDBAPI_API_KEY. I recommend you to set this; class MovieSearch will then try to pick it up when it was set (see the ruby code for this).
Ffmpeg has support for deshaking videos through a filter:
The deshake-filter from ffmpeg helps remove camera shake from hand-holding a camera.
The API for multimedia_paradise is the following:
If you have specific suggestions to make this gem more useful for others, please drop me an email at:
(Please keep in mind that responding to emails may take a while depending on the amount of work I may have at that moment in time due to reallife.)