Click here to Skip to main content
Click here to Skip to main content

Media files conversion using C#

By , 28 Jul 2005
Rate this:
Please Sign up or sign in to vote.

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 Wink | ;-) .

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:

using DirectShowLib;

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

// 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:

// 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:

// 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

About the Author

daniel049

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

Comments and Discussions

 
GeneralRe: Demo project will not work PinmemberTheBigOnion231-Jul-06 6:19 
GeneralRe: Demo project will not work Pinmemberdaniel04931-Jul-06 10:52 
GeneralRe: Demo project will not work [modified] PinmemberTheBigOnion231-Jul-06 12:49 
GeneralRe: Demo project will not work Pinmemberdaniel0492-Aug-06 3:59 
GeneralRe: Demo project will not work [modified] PinmemberTheBigOnion28-Aug-06 9:33 
GeneralRe: Demo project will not work Pinmemberdaniel0498-Aug-06 13:25 
GeneralRe: Demo project will not work PinmemberTheBigOnion29-Aug-06 5:03 
GeneralExtracting video clips and decoding the audio channel PinmemberBrent_Daignault11-May-06 16:10 
Hi Daniel049,
I have an interesting project that will keep me up for a while. I am looking for a way to start this and I'm hoping there is a .net C# library to get me started.
 
I have a video file that was recorded with a GPS overlay in the audio channel. The device used to do this is called GeoStamp from Intuitive Circuits. Apparently, it's a standard method for displaying text such as the date and time on top of the video.
 
Since the gps information is linked to the video by way of the audio channel, I would like to extract 10 second video clips from the video that correspond to specific coordinates. This is really the same as extracting clips at specific times if I was reading the time stamp instead of the gps coordinates.
 
Two things come to mind: how do I decode the audio channel to retrieve the text string associated with each frame of the video, and how do I search through a video file to directly access a specific frame. Are frame numbers or some other id built into the video file format, or do I have to preprocess and mark them first. If I read through the entire file and build an index file of frame numbers and coordinates, I could then go back and extract clips based on a lookup of the specified coordinates.
 
Is this functionality available in DirectShow, the DirectX API, or any other .net MM library at the present time. Can you comment on the level of difficulty you see with this. This seems to be related to applying sub-titles and captioning to video where the text is stored in the audio channel.
 
Regards,
Brent
GeneralRe: Extracting video clips and decoding the audio channel Pinmemberdaniel04914-May-06 14:28 
GeneralConvertin a MOV file from adigital camera PinmemberAlexEvans23-Apr-06 5:43 
GeneralRe: Convertin a MOV file from adigital camera Pinmemberdaniel04923-Apr-06 8:17 
Questionwmv conversion PinmemberFurqans20-Feb-06 18:39 
AnswerRe: wmv conversion Pinmemberdaniel04921-Feb-06 16:02 
Generalavi to wmv with compression PinmemberDennis Akihiko Tanaka27-Oct-05 9:23 
GeneralRe: avi to wmv with compression Pinmemberdaniel04928-Oct-05 3:28 
QuestionRe: avi to wmv with compression Pinmemberravin200722-Nov-06 2:12 
AnswerRe: avi to wmv with compression Pinmemberdaniel04923-Nov-06 13:11 
GeneralRe: avi to wmv with compression Pinmemberdaniel04928-Oct-05 3:46 
QuestionHow to convert to WAV? Pinmemberzjpost21-Sep-05 4:35 
AnswerRe: How to convert to WAV? Pinmemberdaniel04922-Sep-05 3:22 
GeneralFilter graph and Rendering Pinmemberdaniel0499-Sep-05 14:23 
GeneralRe: Filter graph and Rendering PinmemberEmailSolidale10-Sep-05 21:35 
Generaloutput MPEG PinmemberEmailSolidale1-Sep-05 22:20 
GeneralRe: output MPEG Pinmemberdaniel0493-Sep-05 8:10 
GeneralRe: output MPEG Pinmemberdkarlton26-Oct-05 7:00 

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

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

| Advertise | Privacy | Mobile
Web04 | 2.8.140415.2 | Last Updated 29 Jul 2005
Article Copyright 2005 by daniel049
Everything else Copyright © CodeProject, 1999-2014
Terms of Use
Layout: fixed | fluid