⬆️ ⬇️

Working with webcam and microphone in Silverlight 4

Introduction

What many Silverlight developers have been waiting for has happened. Fourth Silverlight allows you to access the webcam and microphone. And let it not be a revolution, unlike many other new features (competing technologies supported the camera and microphone for a long time), but the power, simplicity and convenience of the API deserve that you pay close attention to this part of the functionality of the fourth Silverlight.

Work with webcam and microphone

So, the webcam and microphone on the user's computer may or may not be present. There are also situations when there are several sources of video and sound. In order to determine with which devices we will work, and also, if necessary, request the user to access these devices (Silverlight does not allow the user to access the web camera or microphone without explicit permission of the user), there is a static class CaptureDeviceConfiguration. Let's see how to work with this class. But first create a new Silverlight application project in Visual Studio 2010 and add some XAML markup to the MainPage.xaml page:

< StackPanel Orientation ="Vertical" VerticalAlignment ="Center"

HorizontalAlignment ="Center" >

< Rectangle Width ="320" Height ="240" x:Name ="videoRect" />

< StackPanel Orientation ="Horizontal" HorizontalAlignment ="Center" >

< ListBox x:Name ="VideoSources" >

< ListBox.ItemTemplate >

< DataTemplate >

< TextBlock Text ="{Binding FriendlyName}" />

</ DataTemplate >

</ ListBox.ItemTemplate >

</ ListBox >

< ListBox x:Name ="AudioSources" >

< ListBox.ItemTemplate >

< DataTemplate >

< TextBlock Text ="{Binding FriendlyName}" />

</ DataTemplate >

</ ListBox.ItemTemplate >

</ ListBox >

</ StackPanel >

< StackPanel Orientation ="Horizontal" HorizontalAlignment ="Center" >

< Button Margin ="5" Content =" " x:Name ="startCapture" />

< Button Margin ="5" Content =" " x:Name ="endCapture" />

</ StackPanel >

</ StackPanel >



* This source code was highlighted with Source Code Highlighter .


In this markup, you should pay attention to the “VideoRect” rectangle (Rectangle), the video from the webcam will be displayed in it.



Below are two lists (ListBox) "VideoSources" and "AudioSources", they will display the names of the device sources of video and audio. The user can select the desired device by clicking on his name. In addition, there are two buttons on the page that we will use to start and stop capturing from both devices.



The running application will look like this (in the screenshot I show the “ask me about Silverlight icon” via the webcam):

')

image



But let's move on to the source code of the MainPage.xaml page in C #. And in the constructor, let's subscribe to the event of loading this page:

this .Loaded += new RoutedEventHandler(MainPage_Loaded);



* This source code was highlighted with Source Code Highlighter .


In the event handler, we obtain the available devices and display them in our VideoSources and AudioSources lists, respectively:

void MainPage_Loaded( object sender, RoutedEventArgs e)

{

VideoSources.ItemsSource = CaptureDeviceConfiguration.GetAvailableVideoCaptureDevices();

AudioSources.ItemsSource = CaptureDeviceConfiguration.GetAvailableAudioCaptureDevices();

}



* This source code was highlighted with Source Code Highlighter .


The CaptureDeviceConfiguration class allows you to get a list of all video and audio capture devices, as well as default devices using the GetDefaultVideoCaptureDevice and GetDefaultAudioCaptureDevice methods, respectively. Devices are automatically installed by default, but the user can configure them using the Microsoft Silverlight Configuration utility. To launch this utility, right-click on any Silverlight application and select Silverlight from the context menu. This will open the window we need, in which in the fourth version of Silverlight a new tab “Webcam / Mic” has appeared.



image



You can change the default device or leave it the same. For now, we are going back to the source code.



So now we add a field of type CaptureSource to the MainPage class. Objects of this class are used to capture video and sound from the corresponding devices.

private CaptureSource _captureSource;



* This source code was highlighted with Source Code Highlighter .


In the MainPage_Loaded method, we initialize the field we just created:

_captureSource = new CaptureSource();



* This source code was highlighted with Source Code Highlighter .


Now we define the actions performed when the start button is captured. To do this, add the “Click” event handler of the corresponding button (startCapture) and write the following code in the handler:

private void startCapture_Click( object sender, RoutedEventArgs e)

{

if (_captureSource != null )

{

_captureSource.Stop();



_captureSource.VideoCaptureDevice = (VideoCaptureDevice)VideoSources.SelectedItem;

_captureSource.AudioCaptureDevice = (AudioCaptureDevice)AudioSources.SelectedItem;



VideoBrush vidBrush = new VideoBrush();

vidBrush.SetSource(_captureSource);



videoRect.Fill = vidBrush;



if (CaptureDeviceConfiguration.AllowedDeviceAccess ||

CaptureDeviceConfiguration.RequestDeviceAccess())

{

_captureSource.Start();

}

}

}



* This source code was highlighted with Source Code Highlighter .


First, we check that the _captureSource media source is not null, and stop the entire current capture for this source. After that, we set up for the _captureSource user-selected video and audio capture devices, and create a brush (vidBrush) that will fill in the real-time rectangle videoRect video received from the web camera.



But that is not all. Before we start capturing, we need to check that we have the necessary access rights (CaptureDeviceConfiguration.AllowedDeviceAccess) and in case of their absence request access from the user (CaptureDeviceConfiguration.RequestDeviceAccess ()).



When requesting permissions, the user will see a similar dialog box:



image



And if he clicks “Yes”, we can start capturing (_captureSource.Start ()). Otherwise, it remains only to reproach fate for incredulous users.



Handler button stop capture is much easier. Its code is fairly obvious:

private void endCapture_Click( object sender, RoutedEventArgs e)

{

if (_captureSource != null )

{

_captureSource.Stop();

}

}




* This source code was highlighted with Source Code Highlighter .


That's all, the basic application is ready. Launch it and you will have a unique opportunity to see the world through the eyes of a webcam.



The following is the full C # code of the MainPage page:

public partial class MainPage : UserControl

{

private CaptureSource _captureSource;



public MainPage()

{

InitializeComponent();



this .Loaded += new RoutedEventHandler(MainPage_Loaded);

}



void MainPage_Loaded( object sender, RoutedEventArgs e)

{

VideoSources.ItemsSource = CaptureDeviceConfiguration.GetAvailableVideoCaptureDevices();

AudioSources.ItemsSource = CaptureDeviceConfiguration.GetAvailableAudioCaptureDevices();



_captureSource = new CaptureSource();

}



private void startCapture_Click( object sender, RoutedEventArgs e)

{

if (_captureSource != null )

{

_captureSource.Stop();



_captureSource.VideoCaptureDevice = (VideoCaptureDevice)VideoSources.SelectedItem;

_captureSource.AudioCaptureDevice = (AudioCaptureDevice)AudioSources.SelectedItem;



VideoBrush vidBrush = new VideoBrush();

vidBrush.SetSource(_captureSource);



videoRect.Fill = vidBrush;



if (CaptureDeviceConfiguration.AllowedDeviceAccess ||

CaptureDeviceConfiguration.RequestDeviceAccess())

{

_captureSource.Start();

}

}

}



private void endCapture_Click( object sender, RoutedEventArgs e)

{

if (_captureSource != null )

{

_captureSource.Stop();

}

}

}




* This source code was highlighted with Source Code Highlighter .


Take snapshots

The application is working. But I want something else. For example, I want to press a button and save what the camera is currently showing as an image. There is nothing easier. First of all we need to add a button.

< Button Margin ="5" Content ="Snapshot" x:Name ="takeSnapshot" Click ="takeSnapshot_Click" />



* This source code was highlighted with Source Code Highlighter .


You also need to create an event handler for clicking on this button. And add the markup code in XAML to display our snapshots:

< ScrollViewer Width ="400" VerticalScrollBarVisibility ="Hidden" HorizontalScrollBarVisibility ="Auto"

HorizontalAlignment ="Center" >

< ItemsControl x:Name ="snapshots" >

< ItemsControl.ItemTemplate >

< DataTemplate >

< Image Source ="{Binding}" Margin ="5" Height ="50" Stretch ="UniformToFill" ></ Image >

</ DataTemplate >

</ ItemsControl.ItemTemplate >

< ItemsControl.ItemsPanel >

< ItemsPanelTemplate >

< StackPanel Orientation ="Horizontal" />

</ ItemsPanelTemplate >

</ ItemsControl.ItemsPanel >

</ ItemsControl >

</ ScrollViewer >




* This source code was highlighted with Source Code Highlighter .


We create a scroll area (ScrollViewer) where snapshots will be located. ElementControl element is responsible for their display.



Add a “_images” field to the MainPage class, in which the images will be stored:

private ObservableCollection<WriteableBitmap> _images = new ObservableCollection<WriteableBitmap>();



* This source code was highlighted with Source Code Highlighter .


And in the handler for clicking on the “takeSnapshot” button and writing the following code:

private void takeSnapshot_Click( object sender, RoutedEventArgs e)

{

if (_captureSource != null )

{

_captureSource.AsyncCaptureImage((snapImage) =>

{

_images.Add(snapImage);

});

}

}




* This source code was highlighted with Source Code Highlighter .


Here we asynchronously add a new snapshot to the snapshot collection.



All that now remains for us to do is to associate the “_images” collection with a visual presentation. To do this, in the MainPage_Loaded method, we add the following code:

snapshots.ItemsSource = _images;



* This source code was highlighted with Source Code Highlighter .


Now the application can be run. And if something can be done, then let's do it. Run the application and try to take a few snapshots, not for nothing that we wrote this functionality.



image



Screencast is available in English on this topic: watch

Source: https://habr.com/ru/post/75744/



All Articles