CaptureSourceViewModel

,

The viewmodel contains the following three commands:

Image TakePhotoCommand

Image ToggleVideoCaptureCommand

Image PlayVideoCommand

TakePhotoCommand uses the CaptureSource to save a still image to isolated storage. ToggleVideoCaptureCommand starts and stops the recording of video and initially causes the CaptureSource to be attached to a FileSink object so that a video file is written to isolated storage.

The commands are instantiated in the viewmodel constructor like so:

public CaptureSourceViewModel() : base("CaptureSource")
{
    takePhotoCommand
         = new DelegateCommand(obj => TakePhoto(), obj => started);

    toggleVideoCaptureCommand
         = new DelegateCommand(obj => ToggleCapturingVideo());

    playVideoCommand
         = new DelegateCommand(obj => PlayVideo(),
                               obj => !capturingVideo && IsVideoCaptured());
}

Whenever something takes place that may alter the executable state of a command, the viewmodel’s UpdateCommands method is called, which is shown in the following excerpt:

void UpdateCommands()
{
    takePhotoCommand.RaiseCanExecuteChanged();
    playVideoCommand.RaiseCanExecuteChanged();
}

The viewmodel’s TakePhoto method calls the CaptureImageAsync method of the CaptureSource object, as shown:

void TakePhoto()
{
    if (captureSource != null && captureSource.State == CaptureState.Started)
    {
        captureSource.CaptureImageAsync();
    }
}

CaptureImageAsync attempts to use the device camera to capture an image.


Note

If CaptureImageAsync is called without first calling the CaptureSource.Start method, an InvalidOperationException is raised.


The CaptureSource.CaptureImageCompleted event is raised if the call completes asynchronously, which does not necessarily mean that an image has been successfully acquired. If an error occurs during image capture, the CaptureSource.CaptureFailed event is raised.


Note

Although the resulting CaptureImageCompletedEventArgs has an Error property (inherited from its AsyncCompletedEventArgs), this property is never set; therefore, it cannot be used for error detection.


The resulting image is saved to the phone’s photo hub using the MediaLibrary class (see Listing 21.12). The dimensions of the image are supplied by the event arguments. Just as the PhotoCamera example maintained a collection of captured images, so too does the CaptureSourceViewModel.

LISTING 21.12. CaptureSourceViewModel.HandleCaptureImageCompleted Method


void HandleCaptureImageCompleted(object sender, CaptureImageCompletedEventArgs e)
{
    if (e.Result != null)
    {
        Deployment.Current.Dispatcher.BeginInvoke(() =>
        {
            MediaLibrary mediaLibrary = new MediaLibrary();
            string imageName = string.Format(
                        "Unleashed_{0:yyyy-MM-dd-HH-mm-ss}.jpg", DateTime.Now);
            using (MemoryStream stream = new MemoryStream())
            {
                e.Result.SaveJpeg(
                     stream, e.Result.PixelWidth, e.Result.PixelHeight,
                     0, 100);
                stream.Position = 0;
                mediaLibrary.SavePicture(imageName, stream);
            }
            CapturedImages.Add(e.Result);
        });
    }
}


The CaptureSource.State property, which is an enum value of type CaptureState, indicates the state of the CaptureSource object and can be either Failed, Started, or Stopped.

Recording the audio and video of a CaptureSource instance requires the attachment of a FileSink (see Listing 21.13). The FileSink object is assigned the location of a file in isolated storage, to which it writes the video file in MP4 format.


Note

The CaptureSource object must be in a stopped state to attach or detach a FileSink. Attempting to set the FileSink.CaptureSource property while the CaptureSource object is in a Started state raises an InvalidOperationException.


Stopping the capture of video involves detaching the FileSink from the CaptureSource object. Again, the FileSink can be removed only if the CaptureSource is not started; CaptureSource.State must not equal CaptureState.Started.

LISTING 21.13. CaptureSourceViewModel.ToggleCapturingVideo Method


FileSink fileSink;

void ToggleCapturingVideo()
{
    if (!capturingVideo)
    {
        fileSink = new FileSink {IsolatedStorageFileName = videoFileName};

        captureSource.Stop();
        fileSink.CaptureSource = captureSource;
        captureSource.Start();
    }
    else
    {
        captureSource.Stop();
        fileSink.CaptureSource = null;
        captureSource.Start();
    }

    CapturingVideo = !capturingVideo;
    UpdateCommands();
}


After a video has been recorded to isolated storage, it can be played back using either a MediaPlayer control within the app or via the MediaPlayerLauncher, as shown in the following excerpt:

void PlayVideo()
{
    MediaPlayerLauncher mediaPlayerLauncher = new MediaPlayerLauncher
            {
                Media = new Uri(videoFileName, UriKind.Relative),
                Location = MediaLocationType.Data,
            };
    mediaPlayerLauncher.Show();
}


Note

Although AppBar buttons were used to demonstrate the CaptureSource class, the Microsoft.Devices.CameraButtons class (presented earlier in this chapter) could be used instead. CameraButtons can be used in conjunction with the CaptureSource class to allow the hardware shutter button to start and stop video capture.


..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.116.21.232