Thursday, November 19, 2009

Silverlight 4 – Using the webcam

Yesterday the beta release of Silverlight 4 was announced. Of course I couldn’t resist to get started with one of the items on my personal wish list (and on lots of other peoples wish list as well).

 

Using the webcam in Silverlight 4 turned out to be a quite easy process. I only needed about 8 lines to get it started. A few lines more and I have an application which starts and stops the webcam with the click of a button.

 

Create the controls

First thing I did was create the controls in xaml using the new designer in Visual Studio 2010. I created a Grid to show the video in (I’ll explain later on why I used a Grid instead of the expected MediaElement) and a button for starting and stopping it.

 

Huh?! No Stream?

As I mentioned before we’ll be using a Grid to display the video in. Why wouldn’t you use a MediaElement? The reason for that is that, as far as I have found out until now, no Stream output for the videocapturing devices available.

This probably has something to do with the difficulty to control the videocapturing devices and with the different formats of the streams. Note that this isn’t based on anything, it’s just my assumption.

What is available then? Good question. It took me a while to figure out, so finally I gave up and goo.. euhm binged for the webcam support in Silverlight 4 and came up with an article describing how to get the video from the capturing device.

 

The code

First we need a field to save the CaptureSource in and we need to hook up the Click event of the button:

private CaptureSource _cs = new CaptureSource(); 

public MainPage()
{
InitializeComponent();
myButton.Click
+= new RoutedEventHandler(myButton_Click);
}


 



Next we will dive into the code required for getting the video from the capturing device.



Before we’re able to show the video from the CaptureSource we need to do some checks and verfications.



First of all, we’re going to check if the state of the CaptureSource is stopped. It would cause an exception if we would start it when it is already started.



if (_cs.State == CaptureState.Stopped)if (_cs.State == CaptureState.Stopped)


 



Next we’ll need to check if the user has granted us permission to use the webcam. We can do this by using the CaptureDeviceConfiguration class as follows:



 



if (!CaptureDeviceConfiguration.AllowedDeviceAccess) 
{
CaptureDeviceConfiguration.RequestDeviceAccess();
}


 



So what will happen here is that the Silverlight plug-in will show a pop-up with the question if you want allow camera and microphone access:



image



If the user responds with “Yes” we’ll continue to the next step. The code for this is:



if (!CaptureDeviceConfiguration.AllowedDeviceAccess) 
{
CaptureDeviceConfiguration.RequestDeviceAccess();
}
if (CaptureDeviceConfiguration.AllowedDeviceAccess)
{

}


The reason for the duplicate if is that I need to be sure my sure clicked on the yes button after showing the dialogbox. If I would use an else statement the user would have to click on the start button again and if I would use no if and the user would click on the “No” button an exception will be thrown when starting the CaptureSource without permission.



 



The following code needs to be placed inside the last curly braces of the previously added code:



 







System.Windows.Media.VideoCaptureDevice videodev; 
videodev
= CaptureDeviceConfiguration.GetDefaultVideoCaptureDevice();
if (videodev != null)
{
_cs.VideoCaptureDevice
= videodev;

VideoBrush vb
= new VideoBrush();
vb.SetSource(_cs);
_cs.Start();

grid1.Background
= vb;
myButton.Content
= "Stop webcam";
}



As you can see from the fifth line of the code above, the CaptureSource (_cs) needs a VideoCaptureDevice to start the capturing. We can create a VideoCaptureDevice and get the default one by using the GetDefaultVideoCaptureDevice.



We need to be sure there is a default capture device otherwise the app would crash and burn again when starting the CaptureSource.



 



In the two lines of code that follow the VideoCaptureDevice setting we created a VideoBrush and set the source to the CaptureSource. After this, most of the work is done and all we need to do now is start the capturing, set the background of my Grid to the VideoBrush and change the content of the button to “Stop webcam”.



 



In the final piece of code, which goes right after the if in the previous piece of code, we’ll create the functionality to stop the capturing and return to the state where we can start the capturing all over again:







else 
{
if (_cs.State == CaptureState.Started)
{
_cs.Stop();
myButton.Content
= "Start webcam";
}
}


 



You can find the source of the application here



 



Cheers!



 



Rob

No comments:

Post a Comment