The Silverlight webcam API came to the phone with the Windows Phone 7.5 SDK release. If you already have code for processing audio and video using the System.Windows.Media.CaptureSource
class, you will feel right at home. CaptureSource
allows you to capture both audio and video, and when used in conjunction with a FileSink
class, allows you to save video to isolated storage.
This section creates a simplified version of the Photo Camera page presented in the previous section. A page is created that allows the user to capture still images as well as video, and in both cases, you see how captured data is written to isolated storage.
The sample for this section includes a page named CaptureSourceView
and its viewmodel CaptureSourceViewModel
, both located in the /Sensors/Camera directory of the WPUnleashed.Examples project in the downloadable sample code.
To begin, the viewmodel contains a property named CaptureSource
, which is of type CaptureSource
. The CaptureSource
class is analogous to the PhotoCamera
class.
The CaptureSource
backing field is initialized in the viewmodel’s Start
method (see Listing 21.11).
Note
In Windows Phone, CaptureDeviceConfiguration.AllowedDeviceAccess
is always true, even if the app does not have the ID_CAP_ISV_CAMERA capability specified in its WMAppManifest.xml file.
In Listing 21.11, both the test for AllowedDeviceAccess
and the subsequent call to RequestDeviceAccess
exist to retain compatibility with Silverlight for the browser, which does not use a capabilities model, but instead requires that the user authorize the request to use the camera via a confirmation dialog.
A CaptureSource
instance is initialized using static methods of the System.Windows.Media.CaptureDeviceConfiguration
class, which connects the CaptureSource
to the video and audio capture device classes.
Note
If your app does not have the ID_CAP_ISV_CAMERA capability, an exception is raised after the call to CaptureSource.Start
.
Wrapping the Start
call in a try/catch block does not allow the ensuing COMException
to be caught because the exception is raised at an indeterminate point after the Start
call returns.
public void Start()
{
Stop();
if (CaptureDeviceConfiguration.AllowedDeviceAccess
|| CaptureDeviceConfiguration.RequestDeviceAccess())
{
captureSource = new CaptureSource
{
VideoCaptureDevice
= CaptureDeviceConfiguration.GetDefaultVideoCaptureDevice(),
AudioCaptureDevice
= CaptureDeviceConfiguration.GetDefaultAudioCaptureDevice()
};
captureSource.CaptureImageCompleted += HandleCaptureImageCompleted;
captureSource.CaptureFailed += HandleCaptureFailed;
captureSource.Start();
started = true;
UpdateCommands();
}
}
Specifying the image format, including the resolution of captured images, is done by setting the CaptureSource
object’s VideoCaptureDevice.DesiredFormat
property. To determine which formats are supported, the VideoCaptureDevice.SupportedFormats
property is used. On my device there are two supported formats, both with a resolution of 640 by 480, but one offering 32-bit color while the other offers 8-bit grayscale. The desired format can be indicated using one of the supported formats, as shown:
captureSource.VideoCaptureDevice.DesiredFormat
= captureSource.VideoCaptureDevice.SupportedFormats[1];
Note
Setting the DesiredFormat
affects still image captures, and not captured video.
In addition, the audio format can be specified by setting the DesiredFormat
property of the AudioCaptureDevice
to one of the supported formats, like so:
foreach (AudioFormat supportedFormat
in captureSource.AudioCaptureDevice.SupportedFormats)
{
if (supportedFormat.BitsPerSample > 16)
{
captureSource.AudioCaptureDevice.DesiredFormat = supportedFormat;
break;
}
}
3.143.5.15