Click here to Skip to main content
15,867,453 members
Articles / Multimedia / DirectX
Article

Media files conversion using C#

Rate me:
Please Sign up or sign in to vote.
4.21/5 (14 votes)
28 Jul 20055 min read 339.2K   12.3K   87   74
Demonstrates building DirectShow filter graphs for file conversion.

Introduction

The GraphEdit utility, from the DirectShow SDK, is a popular tool to simulate the processing of media files on the Windows platform. Recently, DirectShowLib, an open-source .NET wrapper for DirectShow has been released. Version 1.0 of DirectShowLib wraps the most important interfaces and, already provides much more functionality than the interop assembly generated from the Quartz.dll. In this article, we'll present an application that builds filter graphs for the conversion of media files using C#. Hence, we'll show how to create applications in C# that provide some functionality that GraphEdit does.

Background

There are plenty of file formats for multimedia applications. The most popular ones are those in the MPEG family (MPEG-1/2, MPEG 4 (part 2 or 10)...), the Microsoft family (AVI, ASF, WMV,...), QuickTime family (QT, MOV,...) and RealMedia (RM, RAM,...). Each has its advantages and disadvantages. Moreover, some are covered by those silly little things called "software patents" (probably invented by fat, lazy middle managers in large corporations, who find it easier to dump work on their law department than actually developing products that their customers want ;-).

So for this application, I have decided to write a conversion utility that will convert many media files to the Windows Media Video (.wmv) format. Moreover, since Microsoft holds patents on the ASF format (from which .wmv is derived), I have code to convert to the open format initiative known as Matroska.

Using the code

This web site has many resources for using DirectShow from .NET. The ancestor of DirectShowLib was a project by .netmaster on this site. I have studied their code and you can look at them for things that I haven't explained in this article.

First, the command line to compile the application (provided in build.cmd and assuming that the C# compiler is accessible from the current path) refers to the DirectShowLib assembly. In the code, we start with:

C#
using DirectShowLib;

Then, we use the following variables to build the filter graph:

C#
// The main com object
FilterGraph fg = null;
// The graphbuilder interface ref
IGraphBuilder gb = null;
// The mediacontrol interface ref
IMediaControl mc = null;
// The mediaevent interface ref
IMediaEventEx me = null;

After some initial steps (common to all DirectShow applications in C#), we convert a media file to a .wmv file using the following code:

C#
// here we use the asf writer to create wmv files
WMAsfWriter asf_filter = new WMAsfWriter();
IFileSinkFilter fs = (IFileSinkFilter)asf_filter;
        
hr = fs.SetFileName( fileName + ".wmv", null );
DsError.ThrowExceptionForHR( hr );

hr = gb.AddFilter( (IBaseFilter)asf_filter, "WM Asf Writer" );
DsError.ThrowExceptionForHR( hr );
        
hr = gb.RenderFile( fileName + fExt, null );
DsError.ThrowExceptionForHR( hr );

hr = mc.Run();          
DsError.ThrowExceptionForHR( hr );

This code creates a WMAsfWriter object, and accesses its IFileSinkFilter interface to set its file name. Then it adds the filter to the graph using the GraphBuilder interface method AddFilter. After this, we use "Intelligent Connect" (done through the call to RenderFile) to let the DirectShow runtime build the rest of the graph. Then, when we call the method Run on the MediaControl interface, we are actually writing the file because the renderer filter in this graph is a file writer.

Points of Interest

From my earlier comments, you probably guessed that I am not a big fan of software patents. After having written the code for the conversion to .wmv files, I learned that Microsoft has patents on the file format on which it is based. So I looked for alternatives, and I realized that this field is replete with those "silly little things". So I decided to add support for conversion to the Matroska file format which is "patent-free", as far as I know.

Matroska support

The code to build a filter graph that will write .mkv files is similar to the code for writing .wmv files. Except that we don't create a WMAsfWriter but we create a FileWriter object (and, again, access its IFileSinkFilter interface to set its name). Then we use the following to add the Matroska Mux filter:

C#
// create an instance of the matroska multiplex filter and add it
// Matroska Mux Clsid = {1E1299A2-9D42-4F12-8791-D79E376F4143}
Guid guid = new Guid( "1E1299A2-9D42-4F12-8791-D79E376F4143" );
Type comtype = Type.GetTypeFromCLSID( guid );
IBaseFilter matroska_mux = (IBaseFilter)Activator.CreateInstance( comtype );

If you have installed support for Matroska to your system (download the codec pack from www.matroska.org if you don't consider codec packs "evil"), the CLSID for the Matroska Muxer will be included in your registry. Then you can create a type object and call Activator.CreateInstance to have an IBaseFilter object that can be added to the filter graph.

Using GraphBuilder.RenderFile will again try to build the rest of the graph from a source media file. This process doesn't always work as expected and you should consider the Matroska support as experimental and mainly used for illustrative purposes.

Limitations and known issues

I originally developed this application because I had some Real Media files that I wanted to convert to .wmv. I manually built the filter graph in the GraphEdit tool and rebuild it for every file. So I decided a little application that would do the same would be handy. Real Media files can be converted to Windows Media files without any problem if you have the Real Media Splitter installed on your system (with a Real Player or Real Alternative).

The Window Media file to Matroska file conversion seems to be working fairly well. But MPEG files don't convert to Matroska files with this application (and I didn't look into the problem). But you can convert MPEGs to WMVs and then convert it once more to a Matroska file. (This second conversion seems to hang on some files but the files are not corrupted and can be played in your favorite player. GraphEdit had the some difficulty on these files.) As mentioned, the Matroska support is experimental and mainly for illustrative purposes. So I don't promise that I'll support this functionality of the application.

Installing the codec pack for Matroska with its shell extension facility created problems on my system (and it seems to be a problem on other machines). But the default installation script doesn't include this functionality. Nevertheless, searching Google reveals that other people had problems after installing the Matroska codec pack on XP.

The timing on some Matroska files looks odd and I'll intent to look at this issue.

If the file is large, the conversion can take some time. I use the Task Manager application and check the CPU usage to find out when the conversion is over.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here


Written By
United States United States
You can read my blog entries at:
http://wwww.informikon.com/blog/

Comments and Discussions

 
QuestionHi Pin
Pyae Phyo26-Jul-16 22:15
Pyae Phyo26-Jul-16 22:15 
Questionexception Pin
sileen_Mohammad13-Apr-12 4:50
sileen_Mohammad13-Apr-12 4:50 
Questiondidn't work well Pin
Member 832343616-Oct-11 18:06
Member 832343616-Oct-11 18:06 
Generalhi Pin
nid4may25-Jun-10 20:35
nid4may25-Jun-10 20:35 
GeneralVery useful Pin
Cinni3-Dec-09 0:45
Cinni3-Dec-09 0:45 
GeneralC# CODE FOR VEDIO CUTTER FEATURES........ Pin
Babita Shivade2-Apr-09 3:15
Babita Shivade2-Apr-09 3:15 
GeneralMatroska (mkv) is not a codec! Pin
Qwertie29-Jan-09 9:08
Qwertie29-Jan-09 9:08 
GeneralProprietary Codec Pin
kicknit222-Dec-08 11:18
kicknit222-Dec-08 11:18 
GeneralError in Execution Pin
apons17-Jul-08 3:01
apons17-Jul-08 3:01 
GeneralRe: Error in Execution Pin
Disha43917-Jul-09 8:59
Disha43917-Jul-09 8:59 
GeneralConvert wmv to wav Pin
Webrat24-Feb-08 16:02
Webrat24-Feb-08 16:02 
QuestionRe: Convert wmv to wav Pin
Webrat25-Feb-08 1:41
Webrat25-Feb-08 1:41 
GeneralRe: Convert wmv to wav Pin
daniel04925-Feb-08 7:06
daniel04925-Feb-08 7:06 
GeneralRealVideo 10 Pin
#realJSOP10-Jan-08 11:10
mve#realJSOP10-Jan-08 11:10 
GeneralRe: RealVideo 10 Pin
daniel04911-Jan-08 3:58
daniel04911-Jan-08 3:58 
GeneralWMV Profiles Pin
izmoto1-Jan-08 23:06
izmoto1-Jan-08 23:06 
GeneralRe: WMV Profiles Pin
daniel0492-Jan-08 7:38
daniel0492-Jan-08 7:38 
Hi,

I've done something similar in the past with the following code:

Add this to the conversion method
IConfigAsfWriter icw = (IConfigAsfWriter)asf_filter;
icw.ConfigureFilterUsingProfileGuid( ref profileGuid );

where your profile guid is the following (i've googled it)
EC298949-639B-45e2-96FD-4AB32D5919C2

I've used the following idl to generate the typelib
for the IConfigAsfWriter method:
import "dshowasf.idl";
[
uuid(857FF9C7-4397-42d9-8216-FB89940119C5),
helpstring("Asf type library")
]
library ToWavTypeLib
{
importlib("STDOLE2.TLB");

interface IConfigAsfWriter;
};

I believe it was working well.
GeneralProblems with demo code Pin
Anil KumarThanga2-Oct-07 21:57
Anil KumarThanga2-Oct-07 21:57 
GeneralRe: Problems with demo code Pin
daniel0496-Oct-07 11:05
daniel0496-Oct-07 11:05 
GeneralRe: Problems with demo code Pin
#realJSOP9-Jan-08 5:41
mve#realJSOP9-Jan-08 5:41 
QuestionVOB to GBM+GBS [modified] Pin
a stupid person27-Jul-07 15:22
a stupid person27-Jul-07 15:22 
GeneralTranscoding to Ogg Theora on Windows Pin
daniel04920-Mar-07 8:06
daniel04920-Mar-07 8:06 
QuestionRe: Transcoding to Ogg Theora on Windows Pin
PeaceTiger20-Jun-07 4:53
PeaceTiger20-Jun-07 4:53 
AnswerRe: Transcoding to Ogg Theora on Windows Pin
daniel04920-Jun-07 6:51
daniel04920-Jun-07 6:51 
GeneralRe: Transcoding to Ogg Theora on Windows - Updated Link Pin
David P. Ward30-Oct-09 18:27
David P. Ward30-Oct-09 18:27 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.