You are here: Home » Video Asset Management » Building a Simple Transcoder with FFMPEG

Building a Simple Transcoder with FFMPEG

by Naresh Sarwan on September 22, 2009

This tutorial explains how to build a very simple transcoder for a DAM system using FFMPEG and Windows Scripting Host (using JScript as the scripting language). The code provided will convert an input video into FLV (Flash Video) format that can be used for previewing and produce a single thumbnail image to be used for representation of the asset in searches etc. FFMPEG is capable of much more than this, however, for the majority of DAM or Content Management Systems, this is usually sufficient to provide a basic representation of ingested digital video for previewing purposes.

Audience

To utilise this example you will need intermediate level Windows Scripting Host (WSH) expertise and knowledge of JScript, however, no direct prior experience with FFMPEG is needed. The script is best suited for a dedicated hosting environment or a test server. It may work with virtual servers but will almost certainly require some modification and may present some problems with file permissions when used in this environment. Please note the disclaimer below.

Disclaimer

As you will see from the limitations section of the article, there is a lot of important functionality missing from this script. It is very much intended to be a simple tutorial to illustrate what is involved in creating a transcoder and to serve as an inspiration to help you to create your own solution. It would be unwise to use this in a production environment. If this is your intention, you are advised to investigate alternatives, or at least be willing to invest time into testing and improving the basic technique outlined.

Licence

The code included with this article is distributed with a BSD Licence.

Dependencies

Apart from FFMPEG, this transcoder has minimal dependencies. WSH/JScript has been chosen rather than a .NET based approach as it simpler to modify without compilation and does not require the installation of frameworks etc. yet it will still interoperate with a web application without modification (e.g ASP.NET, Classic ASP, PHP, Ruby etc). I have used JScript because I prefer coding with it, but a conversion to VBScript would be a simple enough task as would ports to other languages. See the FFMPEG resources section as a starting point.

FFMPEG

A compiled FFMPEG binary is required. See the resources section for details of where to obtain one. For the purposes of this article, we have used FFMPEG 13537 released in May 2008.

Downloads

The code and other files are included at the end of this article.

Overview of Technique

This transcoder is intended to be run on a scheduled basis using a ‘watched folder’ technique to detect recently added files and process them sequentially. With some modification, it could be used in real-time so the user does not have to wait until the next schedule point, although using a shell based approach that runs discretely in the background is simpler to implement and presents fewer security issues to worry about. With larger video files, the processing time can be quite lengthy, so it may not be advisable to keep users waiting for completion.

The overview of the process is as follows:

  • Check for input video in the specified folder
  • If a file is found:
    1. Move the file to a processing folder.
    2. Attempt transcode to FLV.
    3. Attempt to generate a thumbnail in the target folder.
    4. Report success or failure via an http call-back
    5. Move the original file to another folder to stop it being re-processed.

The call back is http based to simplify integration with a web based DAM system, although it is not mandatory to use one if you just want to batch process files or would prefer to parse the log files to check the result of each operation.

Deployment

Before deploying, ensure you have obtained an FFMPEG binary. A copy of one tested with this script is provided below. To deploy the scripts, the following steps must be carried out:

1. Copy the ffmpeg.exe file to your server.

2. Create (or identify) the folders required by the application. Below is a summary:

Setting Purpose
VIDEO_IN_PATH
The location where videos will be deposited prior to transcoding.
VIDEO_PROCESSING_PATH
An intermediate location where videos that are about to be processed can be moved into to stop the transcoder running over them twice.
VIDEO_SUCCEEDED_PATH
The output location where videos that were successfully converted are moved to.
VIDEO_FAILED_PATH
The output location where failed videos are held.
VIDEO_PREVIEW_PATH
The location where the transcoded video is stored.
VIDEO_THUMBNAILS_PATH
The location of the thumbnail of each video.
FFMPEG_PATH
The location of the FFMPEG binary (ffmepg.exe)
RESULT_LOG_PATH
A folder to hold the results of processing each video.

3. Open the transcode.js file with a text editor and make the necessary amends to the paths and the settings described in the Key Settings section below.

4. Test the script is working by adding some video into VIDEO_IN_PATH and running the script manually from the command line. To do this, enter:

cscript transcode.js

The result should be displayed on screen. A command window will be spawned by FFMPEG to carry out the processing. In the code, there is a switch /C. If you change this to /K the FFMPEG output will be visible on-screen.

5. Use the debug option switch to get alerts at each stage of the process. If the processing is successful, you should find a converted FLV file and thumbnail in the folders you have specified. If you run into problems, experiment with videos of different types to see if the problem is input file related. In this article, we are concerned with the transcoding workflow and framework rather than processing options which will be covered later. See the resources section for some other links that might help if you need to get this working with a particular video file.

6. Once you have verified that all is well, open the Windows task scheduler and add transcode.js to it. Set the interval to the required maximum time between processing jobs. 5 minutes or more is recommended depending on the size of your input files.

When the above is complete, the transcoder should be ready for use.

Key Settings

The key settings that require amendment are:

Settings
[Paths]
See above, these are the paths used for videos, FFMPEG etc.
CALL_BACK_URL
This is a URL of an http callback script that can receive the success or failure status of the current processing operation.
FFMPEG_PROCESSING_OPTIONS
The FFMPEG processing options. The examples given are very simplistic and only convert the incoming video to FLV.
THUMB_FRAME_OFFSET
Since the first frame of most videos is usually a blank screen, this option allows you to specify a number of seconds into the movie to take the thumbnail frame from instead.
THUMB_FRAME_SIZE
The standard thumbnails size.

In addition, the following options are provided:

callback
If false, will stop an http request being made (true by default).  If there is no callback URL specified or it is wrong/unavailable,the script will continue to process.
debug
If false, will suppress verbose output (true by default).
output_logging
If true this will write the results of the FFMPEG processing to a text file where it can be inspected later.

Limitations

As described, there are many limitations to this script. Some of the more glaring ones are described below.

Hard-coded settings

The settings are hard-coded constants. To deploy this on multiple hosts, it would be necessary to amend the code manually rather than an external settings file.

No parsing of FFMPEG output

The information returned by FFMPEG provides a variety of potentially useful information such as the duration of the file and dimensions. This is not parsed by this script. A more advanced edition would post this back to the call back URL to provide more in-depth information that could be included with the asset metadata.

Encoded video doesn’t playback properly on streaming servers

If you intend to playback the video via a streaming server such as Wowza, Flash Media Server, Red5 or a streaming CDN, you will find the vide will not work properly. The video needs additional metadata injected into it using something like FLVTool (see resources section below). This could be relatively easily added to the script, but it is not present in this version.

FLV not H.264

As of version 9, Flash supports H.264 video playback as well as FLV. H.264 offers superior quality and may be a better choice for a number of DAM solutions. FFMPEG can also output H.264, so you may consider switching to that (see below for more details on refining the processing techniques used).

Simplistic processing technique

To get the most out of FFMEPG, it is necessary to use a variety of tricks and techniques. This transcoder uses a single FFMPEG command string for all files. You will almost certainly be able to find many it will not process even within those formats that FFMPEG officially supports (if particularly unlucky you may find they all fail). If you run FFMPEG.exe from the command line without any options specified, you will notice that it includes a vast array of switches and settings that are initially bewildering for the newcomer. To experiment with FFMPEG and fine-tune settings, FFMPEG GUI can be useful to try things out and generate the required command string.

Inability to switch FFMPEG command strings based on the input file

Similarly, you will often find peculiarities and characteristics that prevent a single generic command being used and you may need to have a series of strings that get swapped depending on the characteristics of the input video. See the previous section on parsing the FFMPEG output also. It will probably be necessary to analyse the output to identify common errors and modify the required command accordingly.

Inefficient file management

A watched folders technique is effective for a stand-alone transcoder, but when integrated into your own application, it might be an inefficient technique that involves making multiple copies of files and moving them around unnecessarily. Currently, you would need to ingest the file to the watched folder, then move it to a processing folder, then to the asset storage folder (or possibly into the database if using a BLOB based method). The use of an intermediate processing folder helps to prevent assets getting ‘stuck’ during conversion and the same command repeating over and over, but there is still a risk of some assets remaining in limbo between processing and completion.

Lack of call-back exception handling

The transcoder issues the call-back and just assumes that the http server is available and can process the command. No exception handling is provided to verify that a response has been received. The technique for determining whether processing has failed or succeeded by checking for the existence of the target output file is not particularly elegant and could be improved upon (see parsing of the FFMPEG output above).

No duplicate filename handling or overwrite protection

This transcoder does not check for duplicate filenames. In the event that one of your assets is named the same as another, the earlier file will be overwritten.

Lacking summary logs

Although there is a log of FFMPEG output and a callback to signal whether the conversion has failed or succeeded, there is no log file to keep a summary log of everything that has been processed, the result and any reason why it failed. This could be captured by the receiving callback script, but if this fails, there will be no record.

Conclusion

Code & Associated Files

>> transcode.js
>> FFMPEG (13537) Windows binary
>> transcode.js & FFMPEG.exe in one zip

Find out more about FFMPEG:

>> FFMPEG Original Site: The official site of FFMPEG and the definitive source for code, information etc.
>> FLVTool: Will inject metadata into an FLV so it can be played back on a streaming server.
>> FFMPEG GUI: Basic GUI for generating FFMPEG command strings and testing them.
>> Videohelp.com: Provides a vast range of video processing tools.

Windows FFMPEG Binaries

The following contain links to compiled FFMPEG binaries

http://ffmpeg.arrozcru.org
A very useful site for those planning on using FFMPEG with Windows, contains up to date compiled binaries, a Windows-specific FFMPEG forum and a variety of other resources. This site is highly recommended.

http://www.paehl.com/open_source/?Convert_Tools:FFMPEG
Contains the latest builds of FFMPEG.

http://ffdshow.faireal.net/mirror/ffmpeg/
This repository used to be quite widely linked to, but appears not to have been updated since April 2008 and the latest version available is 12665.

FFMPEG Scripting Tools For Other Languages

Below are some links for using FFMPEG with something else other than WSH.

FFMPEG & C#/.NET
Some useful examples for integrating FFMPEG with .NET applications, in particular building ‘YouTube’ style video upload sites. Many of the examples rely on Media Handler Pro, a commercial FFMPEG wrapper from the author.

FFMPEG-PHP
A set of libraries for using FFMPEG with PHP.

PHP Video Toolkit
A wrapper around FFMPEG, Mencoder and FLVTools that provides PHP developers with a set of tools for manipulating video.

FFMPEG With Perl
A CPAN module for handling FFMPEG with Perl.

FFMPEG With Ruby
Explains how to transcode video with Ruby using Mencoder and FFMPEG.

Related posts:


Leave a Comment

Previous post:

Next post: