A port of the FFMPEG DSL for Ruby to CFML (ColdFusion).
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Failed to load latest commit information.



A port of the FFMPEG DSL for Ruby to CFML.


  1. FFMpeg is the standard for converting video and audio to different formats on the web. It's a shame that we don't have a native interface to this great tool and have to rely on cfexecute and hacks to work with it. By creating a native DSL that anyone can use, it will hopefully make this great tool easier and fun to work with.
  2. A DSL allows us to add aditional methods to make converting videos to popular format as simple as calling a method.
  3. I never wrote a DSL before and I thought that this would make for an interesting project.

How to use

Simply unzip the zip file into a directory that your CFML engine can access (for argument's sake, we'll use lib/cfffmpeg).

Next create the cfffmpeg object using createobject().

Once created you can then use the dsl.

In order to use the DSL, you chain methods which translate to arguments that will be passed to the ffmpeg executable. once you have chaining all the methods together, you call the end() method which will then invoke the ffmpeg executable and convert the movie.


The CFFFMpeg object has 3 global properties used to change the paths of the FFMpeg executable and where the log file are written:

<cfset source = expandPath("vids/test1.wmv")>
<cfset target = expandPath("vids/test1.mpg")>
<cfset ffmpeg = createobject("component", "lib.cfffmpeg.cfffmpeg").init()>
<!--- change the path to FFMpeg --->
<cfset ffmpeg.ffmpegPath = {Path to FFMpeg executable}>
<!--- now we can convert our movie --->
<cfset result = ffmpeg.convert(source, target).target("ntsc-vcd").end()>

ffmpeg - path to the FFmpeg executable (defaults to bin/ffmpeg.exe)

errorLog - path and name of the error log generated by FFMpeg (defaults to getTempDirectory() & "ffmpeg_error_log.txt">

resultLog - path and name of the result log generated by FFMpeg (defaults to getTempDirectory() & "ffmpeg_result_log.txt">

Main Methods

The DSL has 2 endpoints that you can call:

end() - this will pass all the arguments that you have chained to the ffmpeg executable and convert your movie

inspect() - returns that entire command that will be executed (including the path to ffmpeg, your source and target movie path and all arguments you chained). good for debugging.

Besides calling chaining methods you may also pass any arguments directly to ffmpeg by using the cmd() method.

Convert a WMV file to MPEG1

<cfset source = expandPath("vids/test1.wmv")>
<cfset target = expandPath("vids/test1.mpg")>
<cfset ffmpeg = createobject("component", "lib.cfffmpeg.cfffmpeg").init()>
<cfset result = ffmpeg.convert(source, target).target("ntsc-vcd").end()>

<p>Success: #result.cmd#</p>
<p>Command Executed: #result.cmd#</p>
<p>Log File: #result.cmd#</p>

Return Data

CFFFMpeg will return a structure contain the following keys:

  • success (boolean) - tells whether errors have occurred.
  • command (string) - the actually ffmpeg command that is generated and run against the environment.
  • logfile (string) - the entire log output the is generated by ffmpeg. good for determining what the error was.


write up about presets

Running tests

clone the repo to a directory under your webroot called cfffmpeg

browse to the test directory under the repo: http:///cfffmpeg/tests

RocketUnit is used as the testing framework

Thanks and credits

I want to thank Patrik Hedman (polly) who wrote the ffmpeg DSL for Ruby which this project is a port of and inspired by.

I also want to thank CFSearching whose posts about using ffmpeg with CFML were invaluable to getting this project done as I copied most of the processing code from his post :)

Enhancements and Bug Fixes

If you have issues please report them in the bug tracker.

I am NOT taking enhancment request for this project. If you have a feature that you would like to add, fork the project, add the feature yourself and submit a pull request back. I have too many other projects that I'm already working on and I do not have the time to devote this one.