No Clean Feed - Stop Internet Censorship in Australia

ColdFusion & FFmpeg - video conversion plus thumbnails

While writing an application last year for a large client I came across the need to convert uploaded video files and create thumbnails of those videos... on the fly. At the time I found it difficult to get many good search results from The Googs but from what I did find I ended up creating a great solution.

Note for the reader:

  • This article is targeted at Windows users, but the idea is the same for other Operating Systems
  • To use FFmpeg with ColdFusion your hosting environment will need to allow the use of CFEXECUTE - some Shared Hosts do not allow the use of this tag.

Scenario:

Client staff are to be able to upload vidoes from their PCs via the admin/CMS section of the site and be able to indicate at what second in the video they wish to capture a thumbnail preview. The videos uploaded are to be converted to FLV on the fly to enable instant playability in the site's flash-driven video player.

Solution:

You need,

  • Adobe ColdFusion
  • Hosting environment permission to use CFEXECUTE (CFEXECUTE is blocked/disabled by some Shared Hosting services)
  • FFmpeg (Download, Author, Documentation) - FFmpeg is a complete solution to record, convert and stream audio and video. It is a command line tool to convert one video file format to another. It also supports grabbing and encoding in real time from a TV card. Several FrontEnds/GUIs available like WinFF, Super, Avanti, AutoFF, Xpegt, GVC.

FFmpeg will download as an archive, you can extract the folder in this archive to a specific site you have or to anywhere centralised on your server, for example: "X:\ffmpeg". This location will be your installation directory.

Create a .bat (Windows Batch) file (in Notepad will do). here is an example:

video-converter-ffmpeg.bat

CALL X:\ffmpeg\ffmpeg -i %1 -ar 22050 -ab 64 -aspect 16:9 -b 400 -r 12 -f flv -s 460x258 -qscale 5 -ac 1 -y %2
EXIT

The above batch file calls the ffmpeg.exe and passes a string of arguments. This batch file script example also accepts arguments (%1 & %2). You will see these later when we call and run this batch file from ColdFusion.

FFmpeg Argument definitions:

  • -i filename Input file name
  • -ar freq Set the audio sampling frequency (default = 44100 Hz)
  • -aspect aspect Set aspect ratio (4:3, 16:9 or 1.3333, 1.7777)
  • -b bitrate Set the video bitrate in bit/s (default = 200 kb/s)
  • -r fps Set frame rate (Hz value, fraction or abbreviation), (default = 25)
  • -f fmt Force format
  • -s size Set frame size. The format is `wxh' (ffserver default = 160x128, ffmpeg default = same as source)
  • -qscale q Use fixed video quantizer scale (VBR).
  • -ac channels Set the number of audio channels (default = 1).
  • -y Overwrite output files

Definitions for all other FFmpeg arguments can be found in the ffmpeg documentation (linked to above).

Now to call on this batch file and run it from ColdFusion, you simply need to use the CFEXECUTE tag built into ColdFusion. Example:

<cfexecute name="{path_to_batch_file}\video-converter-ffmpeg.bat" arguments="{argument_1} {argument_2}" timeout="600" errorVariable="variables.ffmpegExecuteError" />

Note that the "{argument_1}" and "{argument_2}" correspond to "%1" and "%2" argument variables within the batch file script.

So that's it!

If you are also wanting to generate a thumbnail preview for the video then you simply need to add that to your batch file script. I personally made a separate batch file for my application. Example:

thumbnail-generate-ffmpeg.bat

CALL C:\ffmpeg\ffmpeg -i %1 -vcodec mjpeg -ss %3 -vframes 1 -an -f rawvideo -s 130x72 -y %2
EXIT

FFmpeg argument definitions:

  • -i filename Input file name
  • -vcodec codec Force video codec to codec. Use the copy special value to tell that the raw codec data must be copied as is.
  • -ss position Seek to given time position in seconds. hh:mm:ss[.xxx] syntax is also supported
  • -vframes number Set the number of video frames to record.
  • -an Disable audio recording
  • -f fmt Force format
  • -s size Set frame size. The format is `wxh' (ffserver default = 160x128, ffmpeg default = same as source)
  • -y Overwrite output files

Then the ColdFusion call, as before:

<cfexecute name="{path_to_batch_file}\thumbnail-generate-ffmpeg.bat" arguments="{argument_1} {argument_2} {argument_3}" timeout="600" errorVariable="variables.ffmpegExecuteError" />

So there you go... you can go play now. Of course, one thing to keep in mind is that you really don't even need batch files; you could always just call ffmpeg.exe directly from CFEXECUTE and pass the whole string of arguments as you please.

As for an example live site that uses this approach to handle and manage it's videos, try CliniqueTV

Bookmark and ShareSubscribe

ColdFusion & FFmpeg - video conversion plus thumbnails

Comments

Robert Shane Zehnder

Robert Shane Zehnder wrote on 12/25/09 8:33 PM

I know at one point in time there was an issue where you had to redirect stderr to stdout to avoid certain situations where the application would have an error and would appear to hang. Have you run into this situation? I need to attempt to do something similar on a Linux VPS so it would be great if this was working and could also be ported over to Linux.
Steve

Steve wrote on 12/25/09 10:49 PM

@Robert
I don't think I have come across that problem I'm sorry. Any errors that occur get caught in errorVariable, I check the contents of errorVariable after cfexecute runs.

Note on cfexecute timeout (also read comments under article): http://blog.kukiel.net/2010/01/small-gotcha-with-cfexecute-with.html

As far as the application hanging goes - I have found that when I've come across any app hangs or resource deadlocks/hangs I look for any latest ColdFusion hotfixes and it solves my problem. The only problem I remember coming across that involved resource deadlock and therefore hang, was with CFIMAGE. After updating hotfixes and jumping up to 8.1 it was all fixed.

I can't see why this should not work for you though. To test it you really only need the bits of code I have above, hard code references to videos on your hard drive you want to convert and go for it.

You can get the latest source from http://ffmpeg.org/download.html, but you may need to compile it for linux. SVN details are there too.

Really hope this has helped with your question.
Steve

Steve wrote on 12/26/09 12:40 AM

Also it's worth noting that a lot of the time if you don't have direct access to your server then you can request from whoever is handling the hosting that FFmpeg be installed ... but again, there's always the issue where your Shared Hosting provider has CFEXECUTE and other tags/functions disabled. Fortunately for me, GoWest Hosting is very generous with CF tag/function availability but I have been with hosts in the passed that have varying security policies and CF configurations.
Robert Shane Zehnder

Robert Shane Zehnder wrote on 12/26/09 1:14 PM

Thanks Steve, I will definitely give it a shot. You gave me a great head start. :)
Marc Ackermann

Marc Ackermann wrote on 01/04/10 2:59 AM

How about server performance? Do you run the video converting on the same server as the website is on? I'm afraid that a large video file or too many user uploads at the same time will crash the system?!?
Steve

Steve wrote on 01/07/10 1:25 PM

@Marc - sorry for the delayed resonse - holiday season :)

Thanks for the question. In my case I used the same server for video processing as the video uploading was done from an admin area, and not by public users. Processing video does use more server resources of course, but it does depend on how many videos are being uploaded over a period of time and the size of the videos being uploaded.

In the case where you have a lot of videos being uploaded by a lot of people, I would definitely think about spreading out your resources. Either by using a separate server for processing/storage of video content and/or scheduled tasks to process batches of videos in server downtime. You could also impose restrictions on maximum size videos that you allow people to upload.

If you are working on a serious media content site then you also really need to consider the hardware and environment this app is running on (cpu, memory, load balancing, storage space).

Your testing environment should match your planned production environment, of course, so you can get a real feel for how it is going to perform and be able to run accurate tests before pushing it live only to realise that your planned environment cannot handle the strain. You really need to take the time to plan out exactly what environment you will need for the load requirements of your application.

I know this is a rather generic answer to your question but I do hope it at least helps a little or triggers some ideas for you. This post was really just about the basics, the degree of complexity in which you apply these methods is entirely up to you :)

Leave a comment

Tell us about yourself
(required field)
(required field)
Comment and preferences
Leave this field empty: