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.
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:
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 – you will see this:
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
- Capturing personal photos, video, and audio in Metro style apps
http://channel9.msdn.com/Events/BUILD/BUILD2011/PLAT-777T
[…] Displaying Webcam Preview in a Metro App Using WinRT and XAML […]
Reblogged this on World Wide Code and commented:
A good way to inetgrate the camera in a WP7 app.
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.
Yes, I answered a similar question on StackOverflow earlier. You can check here: http://stackoverflow.com/questions/9858144/how-to-apply-image-effects-like-edge-detection-oncamera-stream-in-windows-8-app
Basically you need to either do the filtering on the CPU or transfer the video frame by frame onto a Direct3D surface and apply shading on it there.
Jeremiah Morrill also wrote a short post and has a sample here: http://jeremiahmorrill.wordpress.com/2012/04/25/gpu-accelerated-media-effects-in-windows-8-metro/
@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();
I think this must have been something else. I was doing this on the Developer Preview build of Win8 and I tried many different things. The implementation in WinRT XAML Toolkit (http://winrtxamltoolkit.codeplex.com/) seems to work fine.
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.
how to save the image captured inn picture library??
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??
Use KnownFolders.PicturesLibrary. The CameraCaptureControl in the WinRT XAML Toolkit has a method called CapturePhotoToStorageFileAsync that could shed some light on how to do it. http://winrtxamltoolkit.codeplex.com/SourceControl/changeset/view/54997eced4de#WinRTXamlToolkit%2fControls%2fCameraCaptureControl.cs
It will crash when switch camera frequently when use CameraCaptureControl .
Kindly help me out, how to access back camera like web cam or front camera of Surface Device.
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.
Can I use this to capture video from my external wifi ip camera?
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?
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