Displaying Webcam Preview in a Metro App Using WinRT and XAML

Note: the WinRT XAML Toolkit library that I share here has a CameraCaptureControl that makes it simple to host the camera preview, take pictures or record videos.
Note: This article is based on Windows 8 Developer Preview version and it should still be relevant with Windows 8 RTM, but please let me know if that is not the case.

I was looking at the controls available in WinRT () and I’ve stumbled upon this control called – CaptureElement. What it does is it “Represents a media capture from a capture device, for example recorded video content.” I thought I’d give it a go and see if I can display the output from the webcam on screen – which could be useful for AR (Augmented Reality) applications or even just for fun. This is how you do a preview then…

Start by creating a new “Windows Metro style/Application”.

Then enable access to webcam and microphone in Package.appxmanifest.

image

If you skip this step – you will do all the coding only to get a black screen instead of your mug when you are done and start your app. Then you might start wondering – is my webcam dead? Problems with WinRT preview? Well, no – it is just how Windows 8 handles these missing capability declarations – no error, just no output.

If you declare these capabilities – you will still get this dialog from the OS the first time you try to capture video:

image

Now how do you access that webcam…

The CameraCaptureUI Way

If all you want to do is record the output from the camera or see what it can see – you can use the built in CameraCaptureUI dialog. It allows you to capture an image or a video and it has built in controls for camera settings (resolution, device, stabilization, brightness, contrast, flicker compensation, focus and exposure). It will even allow you to crop the image when you take it.

To just see the output – you need two lines:

var dialog = new CameraCaptureUI(); 
await dialog.CaptureFileAsync(CameraCaptureUIMode.PhotoOrVideo); 

If you are like me Smile – you will see this:

image

image
image

image

If you want to do more – like capture a video, or play back the video that was captured you can declare a MediaElement to display the video:

<MediaElement x:Name="mediaElement" />;

Then capture to file like this:

private async void StartCameraCaptureUI() 
{ 
    var dialog = new CameraCaptureUI(); 
    dialog.VideoSettings.Format = CameraCaptureUIVideoFormat.Wmv; 
    var file = await dialog.CaptureFileAsync(CameraCaptureUIMode.PhotoOrVideo); 

    if (file != null) 
    { 
        var fileStream = await file.OpenAsync(Windows.Storage.FileAccessMode.Read); 
        mediaElement.SetSource(fileStream, file.FileType); 
    } 
} 

This method is great if you just want to see the webcam input or capture it to a file with no hassle. If you want to process the video in real time or overlay some other UI components – enter…

The CaptureElement & MediaCapture Way

You can use the CaptureElement in conjunction with MediaCapture to embed the video preview inside of your application and get more control of the video stream.

<CaptureElement x:Name="captureElement" />

var mediaCapture = new MediaCapture(); 
await mediaCapture.InitializeAsync(); 
this.captureElement.Source = mediaCapture; 
await mediaCapture.StartPreviewAsync(); 

Using the VideoDeviceController property of MediaCapture you can control all the basic video settings of the CameraCaptureUI. You can also flip or rotate the image, add image stabilization or any other effect (assuming you know how to implement IMediaPlugin).

The one thing I could not figure out was how to release the webcam input, so after I used the MediaCapture once – I could not do it again or use the CameraCaptureUI. Maybe a problem with the API or just a problem with documentation.

Full Source

Available on dropbox.

References

Advertisements
Tagged , ,

16 thoughts on “Displaying Webcam Preview in a Metro App Using WinRT and XAML

  1. […] Displaying Webcam Preview in a Metro App Using WinRT and XAML […]

  2. Reblogged this on World Wide Code and commented:
    A good way to inetgrate the camera in a WP7 app.

  3. gg says:

    Any idea how to apply a filter to the stream? I wrote a WPF app that used Pixel Shaders to apply a filter to a webcam stream, but since Metro doesn’t support Pixel Shaders I’m running into issues.

  4. mukund89@live.in says:

    @xyzzer, great post… the reason you are not able to start up the video again is because of the call to InitializeAsync(). Try doing something like this in your capture function.
    if (captureMgr == null)
    {
    captureMgr = new MediaCapture();
    this.capturePreview.Visibility = Visibility.Visible;
    await captureMgr.InitializeAsync();
    }
    this.capturePreview.Source = captureMgr;
    await captureMgr.StartPreviewAsync();

  5. Dear xyzzer, I am being stuck with the following http://stackoverflow.com/questions/12836017/perform-live-video-stream-processing-from-captureelement-mediacapture after reading your blog. Not sure you are willing to provide some valuable feedback? Thanks.

  6. Anonymous says:

    how to save the image captured inn picture library??

  7. Anonymous says:

    please help me out, i am making a metro app in which i need to capture an image and then save it in picture library and my deadlines are very near and i know how to capture and display it in image control but no idea of how to save it in picture library??

  8. zpc says:

    It will crash when switch camera frequently when use CameraCaptureControl .

  9. Apoorva says:

    Kindly help me out, how to access back camera like web cam or front camera of Surface Device.

    • xyzzer says:

      The panel part of device.EnclosureLocation.Panel if not null – specifies which panel the device is located on. See Windows.Devices.Enumeration.Panel for all options.

      You can list your devices and get the like that:
      DeviceInformation frontWebCam =
      (await DeviceInformation.FindAllAsync(DeviceClass.VideoCapture))
      .FirstOrDefault(
      d =>
      d.EnclosureLocation.Panel != null &&
      d.EnclosureLocation.Panel == Panel.Front);

      You can check the CameraCaptureControl code here for reference for how to do some things you might also need.

  10. Prashant says:

    Can I use this to capture video from my external wifi ip camera?

    • xyzzer says:

      That’s a good question. I’ve never even heard of such a thing, but it would be interesting to find out. Does your external camera show up in the standard CameraCaptureUI? Does it show up in Skype?

      • prashant says:

        The ip camera can stream to vlc and has a mp4 output. The camera has its own video server inbuilt with a ip address where its broadcasting. I am trying to develop a windows store app to show and record the video

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

%d bloggers like this: