Tuesday, April 26, 2011

Play AVI files in Silverlight 4 using MediaElement and MediaStreamSource

Introduction
This article tries demostrate the power of the MediaElement and the MediaStreamSource class that is available to Developers. In this article we shall try to write some code to play an avi video located locally on your computer.

Background
With the new features introduced into Silverlight 4, I had wanted to try and write a simple Application to play an AVI video file. To do this I had to sacrifice quite some time to do research on the subject. Initially I played around with the WriteableBitmap but later discovered the powerful capabilities and features provided by the MediaStreamSource Class.
This article barely touches the surface of those capabilities provided by the MediaStreamSource Class to developers. This article therefore does not delve into decoding video files, it only demonstrates how to buffer samples and provide them to MediaElement control using a custom class derived from MediaStreamSource class. The decoding is handled by a dll (AVIDll.dll) which is also included in the sample which we shall use to return video samples as byte array. The source of this dll is not included in this article. It is only a simple wrapper for the methods using P/Invoke and was written in VB6 as an ActiveX dll. There are a good number of articles out there including some from codeproject that deal with opening avi files (using avifil32.dll and other dlls) such as http://www.codeproject.com/KB/audio-video/avifilewrapper.aspx and a very old yet still very useful website http://www.shrinkwrapvb.com/avihelp/avihelp.htm
In our sample code, we need to first derive our custom class from System.Windows.Media.MediaStreamSource. This will require us to override a number of methods. Without going into too much detail the methods are OpenMediaAsync, GetSampleAsync, CloseMedia, SeekAsync, GetDiagnosticsAsync and SwitchMediaStreamAsync. I will not dig deep into defining these methods but the ones we shall use in our example code are:
OpenMediaAsync: We override this method and an in it we initialize and report some metadata about the media by calling ReportOpenMediaCompleted() method.
GetSampleAsync: We override this method and retrieve the next requested Sample by the MediaElement. MediaElement will call this method every time it needs a Sample. To report back to MediaElement that the Sample is ready, we call ReportGetSampleCompleted() method.
Some good books to read on the subject include 'Silverlight 4 in Action' and 'Silverlight Recipes - A problem Solution Approach'.
Our main objective in this article is to write a simple Silverlight Application that plays back an avi video. Well, for the video (.avi) to play you must have the relevant codec on your machine first.

Read more: Codeproject