Web Camera Integration in Silverlight 4 Beta – well it’s half way there…

Former Slalom Consulting Practice Lead Peter Tweed

Peter Tweed was a Practice Lead for Technology Enablement in Slalom Consulting's San Franciso office when he wrote this post.

by Peter Tweed

Silverlight 4 Beta introduces some very simple APIs to integrate a Silverlight application with the web camera.  The developer can capture video and audio and can reflect display of the video in the application.  The developer can also write a video or audio sink to tap into the streams as they are captured in the application for further processing.  The missing piece is having APIs to do something with the video and audio streams – such as streaming them to a server for someone else to consume (like a video conferencing solution) or to save them to disk (for creating WMV or a similar format in video).  There are blogs out there that show how to convert an audio stream by manipulating the a byte array from a memory stream captured from the audio sink – but it’s a VERY manual process.

Anyhoo, while we are waiting for the missing pieces to be supplied by Microsoft, I’ll show you how to integrate a web camera into your Silverlight application.

The scenario – we’ll have buttons to start and stop capture from the web camera and a button to take a still image from the web camera (like taking a picture).  The web camera feed will be displayed in the Silverlight application and when the still picture is taken it will pop up the image in a child window.

Steps:

1.  Create a Silverlight 4 Beta project

2. Copy the following XAML into the LayoutRoot grid in the MainPage.xaml file

<Grid.ColumnDefinitions>
    <ColumnDefinition Width="42*" />
    <ColumnDefinition Width="310*" />
    <ColumnDefinition Width="48*" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
    <RowDefinition Height="36*" />
    <RowDefinition Height="212*" />
    <RowDefinition Height="30" />
    <RowDefinition Height="10*" />
</Grid.RowDefinitions>
<StackPanel Orientation="Horizontal" HorizontalAlignment="Center" Grid.Row="2" Grid.Column="1"  >
    <Button Content="Start Camera" Name="StartButton" Click="StartButton_Click"></Button>
    <Button Content="Stop Camera" Margin="5,0,0,0" Name="StopButton" Click="StopButton_Click" IsEnabled="False" />
    <Button Content="Take Picture" Margin="5,0,0,0" Name="CaptureButton" Click="CaptureButton_Click" IsEnabled="False" />
</StackPanel>
<Border BorderBrush="#FFC70808" Margin="10" BorderThickness="5" Grid.Column="1" Grid.Row="1" HorizontalAlignment="Stretch" Name="CameraBorder" VerticalAlignment="Stretch" CornerRadius="5" >
</Border>

3. Copy the following C# code into the MainPage class in the MainPage.xaml.cs file replacing the class constructor

CaptureSource src;

public MainPage()
{
    InitializeComponent();
    this.Loaded += new RoutedEventHandler(MainPage_Loaded);
}

void MainPage_Loaded(object sender, RoutedEventArgs e)
{
    src = new CaptureSource();
}

This allows a CaptureSource object to be initialized. This is the object that manages the intregration with the web camera.

4. Add the following code to the MainPage class

private void StartButton_Click(object sender, RoutedEventArgs e)
{
    if (src != null)
    {
        if (CaptureDeviceConfiguration.AllowedDeviceAccess || CaptureDeviceConfiguration.RequestDeviceAccess())
        {
            src.VideoCaptureDevice = CaptureDeviceConfiguration.GetDefaultVideoCaptureDevice();
            src.Stop();

            VideoBrush vid = new VideoBrush();
            vid.Stretch = Stretch.Uniform;
            vid.SetSource(src);
            CameraBorder.Background = vid;

            src.Start();
        }

       StartButton.IsEnabled = false;
       StopButton.IsEnabled = true;
       CaptureButton.IsEnabled = true;
    }
}

This event handler for the StartButton does most of the work for this exercise. It verifies a CaptureSource object exists and if so, verifies through the static CaptureDeviceConfiguration object that the user can access the web camera. The CaptureDeviceConfiguration.RequestDeviceAccess() function pops up a window to the user asking them to authorize device access by the application.

default device configuration

This is needed as the application does not have the local permissions to run and interact with a peripheral device without user authorization. As long as the user authorizes the use of the web camera, the default video device is retrieved into the CaptureSource object. The default device is set up by the user when the user opens the Silverlight menu of a Silverlight application under the WebCam/Mic. Silverlight can retrieve a list of available devices using the CaptureDeviceConfiguration.GetAvailableVideoCaptureDevices() and CaptureDeviceConfiguration.GetAvailableAudioCaptureDevices() functions; this would allow the user to be able to choose which device to use. The CaptureSource object then controls interaction with the camera moving forward. The source is stopped – just in case it is being used already. A video brush is created, whose source is assigned to CaptureSource object from the web camera, which is then set as the background for the border control displayed in the UI. The source (i.e. the web camera) is then started.

5. Copied the following code into the MainPage class

private void StopButton_Click(object sender, RoutedEventArgs e)
{
    if (src != null)
    {
        StopVideo();
    }
}

private void StopVideo()
{
    src.Stop();

    StartButton.IsEnabled = true;
    StopButton.IsEnabled = false;
    CaptureButton.IsEnabled = false;
}

This code stops the CaptureSource object (i.e. the web camera).

6. Add a new Silverlight ChildWindow class to your project named CapturedImage. Replace the XAML in the CapturedImage.xaml file with

<controls:ChildWindow x:Class="SilverlightApplication3.CapturedImage" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentatio xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:controls="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls" Width="400" Height="300" Title="Your Picture">
    <Grid x:Name="LayoutRoot" Margin="2">
        <Grid.RowDefinitions>
            <RowDefinition />
            <RowDefinition Height="Auto" />
        </Grid.RowDefinitions>
        <Image Name="YourImage" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Grid.Row="0"></Image>
        <Button x:Name="OKButton" Content="OK" Click="OKButton_Click" Width="75" Height="23" HorizontalAlignment="Right" Margin="0,12,5,0" Grid.Row="1" />
    </Grid>
</controls:ChildWindow>

This UI defines the Image object that will display the snapshot taken by the web camera.

7. Add the following code to the CapturedImage class in the CapturedImage.xaml.cs file

public WriteableBitmap YourCapturedImage
{
    set
    {
        YourImage.Source = value;
    }
}

8. Copy the following code into the MainPage class

private void CaptureButton_Click(object sender, RoutedEventArgs e)
{
    if (src != null)
    {
        src.AsyncCaptureImage((image) =>
        {
            CapturedImage yourImage = new CapturedImage();
            yourImage.YourCapturedImage = image;
            yourImage.Show();
        });
    }
}

This code uses the AsyncCaptureImage() function of the source to take a still picture with the web camera. The function is asynchronous and so takes an lambda anonymous delegate accepting a WriteableBitmap object, which is then displayed using a CapturedImage control.

9. Run the application, click the Start Camera button, authorize the use of the web camera and see your web camera view

authorize capture

camera

10. Click the Take Picture button and see the image captured in a popup

captured image

11. Click the Stop Camera button and the web camera display will stop

So As you can see it’s very easy to tap into a web camera in Silverlight 4 Beta. The question for the future is – what APIs will Microsoft provide to support streaming or saving the media captured?!

- Peter

About Slalom Consulting
Slalom Consulting brings business and technology expertise together to help companies drive enterprise performance, accelerate innovation, enhance the customer experience, and increase employee productivity. We deliver award-winning solutions in areas such as business intelligence, mobility, and cloud through a national network of local offices across 10 North American cities. Founded in 2001 and based in Seattle, WA, Slalom has rapidly grown to more than 1,100 employees and has earned recognition from Microsoft as the "United States Partner of the Year" and "Online Services Partner of the Year," as well as one of the "Top 10 Best Firms to Work For" by Consulting Magazine. For more information, please visit www.slalom.com.

3 Responses to Web Camera Integration in Silverlight 4 Beta – well it’s half way there…

  1. Junaid Ameen says:

    Very good post on Integrating Webcam on silverlight app.

    I would like to point out two things.

    1. You need to add using System.Windows.Media.Imaging; namespace in the childwindow class in order to recognize WriteableBitmap.

    2. In the MainPage.xaml.cs file, on the method CaptureButton_Click, copy the below code.

    if (src != null)
    {
    src.CaptureImageCompleted += new EventHandler(src_CaptureImageCompleted);
    src.CaptureImageAsync();

    }

    And as we have added the EventHandler, we need to write the code for the eventHandler method.

    void src_CaptureImageCompleted(object sender, CaptureImageCompletedEventArgs e)
    {
    CapturedImage yourImage = new CapturedImage();
    yourImage.YourCapturedImage = e.Result;
    yourImage.Show();
    }

    You are done!! Happy Programming.

  2. Amit says:

    hi,
    this post was good but what i need to do is to take the video stream from from one client and display on the other client. can u give a brief idea regarding this..

  3. Jamp says:

    Hi. Good day.

    Is it also possible to have the live audio while you are on cam?

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

Follow

Get every new post delivered to your Inbox.

Join 126 other followers

%d bloggers like this: