ActiveVlc
Do you know VLC, the famous media player ? I'm pretty sure you do ! Do you know this is also a pretty powerfull media processing and streaming framework ? Maybe... Do you understand something about the command line syntax to access vlc's underlying powers ? If you don't this tool is for you !
ActiveVlc provides a simple syntax to configure and run transcoding/streaming/processing operations using VLC. Here's a simple example :
Setup
First and foremost, you must have VLC and libvlc installed on your system and the vlc binary must be in your PATH since we doesn't provide yet a cool configuration system for this (contribution welcomed !)
Add this line to your application's Gemfile:
gem 'activevlc'
And then execute:
$ bundle
Or use the master branch on GitHub to test de development version by replacing the line in your Gemfile by this one:
gem 'activevlc', github: 'elthariel/activevlc'
Or install it yourself as:
$ gem install activevlc
Example
Command line
Let's say you want to read an mp4 file, transcode it using different options, save the result to another file while displaying it to control what's happening. Using the standard vlc's chain syntax you'd have to write
vlc input.mp4 :sout="#transcode{deinterlace, acodec=aac, ab=128, channels=2, vcodec=h264, venc=x264{bpyramid=strict, bframes=4, no-cabac}, vb=512}:duplicate{dst=standard{mux=mp4, dst='output.mp4'}, dst=display}"
Not very readable isn't it ? Let's try the same with ActiveVlc :
ActiveVlc::pipe do
transcode do
deinterlace
audio :aac do
bitrate 128 # 128 kpbs
channels 2
end
video :h264 do
encoder :x264 do
bpyramid :strict
bframes 4
cabac false
end
bitrate 512 # 512 kbps
end
end
duplicate do
to :file do
mux :mp4
dst 'output.mp4'
end
to :display
end
end
This sintax might be a lot more verbose than the original vlc's one, it is still A LOT more readable and understandable, and since this is plain ruby you can add comment and arbitrary code ! Then you can run it using :
activevlc pipe exec /path/to/the/pipeline.rb input.mp4
From Ruby code
You can also use ActiveVlc programmatically from your ruby code :
def my_encoding_method(input, output)
# Create the pipeline.
pipe = ActiveVlc::pipe input do
transcode do
# Same syntax as above, also see spec/pipes
end
to :file, output
end
# Run it synchronously
ActiveVlc::Runner.new(pipe).run
# Your transcoding operation is over (except if there were strong errors)
end
Named parameters
My fellow developpers, i now we all love reusable stuff, whether it's socks, underwears or code. I'm pretty sure you'd also love to re-use the pipeline you have or at least to make them a little bit configurable, may it be only for the differents outputs. For this purpose, ActiveVlc provides a mecanism called 'named parameters'.
This features allows you to provide a placeholder instead of a value in the pipeline file/code and to replace the placeholder with the actual value later, just before running the pipeline, for example. Let's see how it works:
ActiveVlc::pipe do
transcode do
audio :aac do
bitrate param(:audio_bitrate) # parameter named 'audio_bitrate'
channels p(:audio_channels) # parameter named 'audio_channels'
end
end
to :file do
mux :mp4
dst p(:outfile) # parameter named 'outfile'
end
end
Pay attention to the fact the named parameters are configured Pipeline-wise, there's no namespacing.
In the example above, we define 3 named parameters that will be configured later. There's no difference between the 'param' and 'p' methods: the latter is just syntactic sugar. You have the choice between the 'explicit' and the 'lazy' way.
Now, we you want to run the pipeline you can provide the named paramters as a Hash.
Using the command line :
$> bundle exec activevlc pipe exec my_pipe input.mp3 --params=outfile:rspec.aac audio_bitrate:128 audio_channels:42
[will produce you]
:sout="#transcode{acodec=aac, ab=128, channels=42}:standard{mux=mp4, dst=rspec.aac}"
or directly from Ruby code :
>> pipe # The pipeline defined above
=> ActiveVlc::Pipeline
>> pipe.params outfile: 'rspec.aac', audio_bitrate: 128, audio_channels: 42
=> nil
>> pipe.fragment
=> ":sout=\"#transcode{acodec=aac, ab=128, channels=42}:standard{mux=mp4, dst=rspec.aac}\""
Integration
There's a pretty basic but still undocumentated carrierwave integration gem here : https://github.com/elthariel/carrierwave-activevlc It doesn't work yet very well with carrierwave-backgrounder, but i think it can be fixed.
Development status
This gem is still under development but it's already in use in one of my production box and is then already usable for many cool things.
If you have any trouble, idea or question, please use GitHub issue system. If you have an idea with code attached to it, got to the 'Contributing' section below.
Supported system/rubies
Ruby 1.8 is NOT supported.
This gem is developped using MRI 2.0.0 on Debian 7 / Ubuntu 13.04 but it should work OOB on MRI 1.9 and other GNU/Linux systems.
Altough there might me some threading issues between the interpreter and libvlc, the specs are eported to pass against :
- Jruby (1.7)
- Rubinius (head) (with some minor problems)
I doesn't have access to any OSX boxes so but it should work as well, please let me know if you encounter any issue.
Usage
Currently, the best documentation is to have a look to the spec (/spec/pipes) or to run the CLI tool to get the embedded help.
Known Issues
- We use a pretty ugly hack to be able to run pipelines synchronously
- You cannot (yet) configure output(s) from the command line, only with ruby
- There's currently almost no error reporting except from the one vlc's outputting on STDOUT. Vlc's logging and error reporting is pretty complex, i still need to take some time to figure it out.
Contributing
- Fork it
- Create your feature branch (
git checkout -b my-new-feature
) - Write some specs for your feature
- Implements your feature and make your test pass
- Commit your changes (
git commit -am 'Add some feature'
) - Push to the branch (
git push origin my-new-feature
) - Create new Pull Request