WPF: Webcam Control
- Download WebcamControl_dll - 6.62 KB
- Download WebcamControl_src - 58.22 KB
- Download WPF_Webcam_CSharp_src.zip - 40.93 KB
Introduction
It is with this pain and envy in mind that I decided to try my hand at creating a WPF control that could;
- Display webcam video with little coding effort,
- Allow saving of webcam video to harddisk, with little coding effort,
- Save the webcam video in a variety of video formats.
Background
With the previously mentioned goals in mind I created a WPF UserControl that has the following features;
- Displays webcam video,
- Enables saving of webcam videos to harddisk,
- Enables saving of webcam videos in either; .wmv, .mp4, or .flv format.
The Webcam
control makes heavy use of the Expression Encoder 4 SDK. You therefore need to have the SDK installed on your machine to make use of the UserControl
. You can download the SDK from here.
Requirements
To make use of the Webcam control you require;
- .NET Framework 4.0,
- Expression Encoder SDK
Using the Webcam Control
To use the Webcam
control in your WPF application add a reference to WebcamControl.dll and a using/imports statement for WebcamControl
at the top of your class.
Add a reference to Microsoft.Expression.Encoder.dll . Do this by using the Add Reference dialog box, selecting the .NET tab, and selecting Microsoft.Expression.Encoder from the listbox. The Expression Encoder assemblies should be available if you have installed Expression Encoder 4.
The following example, which is the code for the downloadable sample application, shows the use of the Webcam
control. The sample application contains; a ContentControl
that will host the Webcam
control, two ComboBox
es for displaying the names of audio and video devices connected to the machine, and four buttons.
VB.NET
Imports Microsoft.Expression.Encoder.Devices
Imports WebcamControl
Class MainWindow
Private webCamCtrl As New Webcam
Private Sub MainWindow_Loaded(ByVal sender As Object, _
ByVal e As System.Windows.RoutedEventArgs) Handles Me.Loaded
FindDevices()
Dim path As String = "C:\VideoClips"
If Directory.Exists(path) = False Then
Directory.CreateDirectory(path)
End If
' Set some properties of the Webcam control.
webCamCtrl.VideoDirectory = path
webCamCtrl.VidFormat = VideoFormat.wmv
' Set the Webcam control as the ContentControl's content.
ContentControl1.Content = webCamCtrl
VidDvcsComboBox.SelectedIndex = 0
AudDvcsComboBox.SelectedIndex = 0
End Sub
' Find available a/v devices.
Private Sub FindDevices()
Dim vidDevices = EncoderDevices.FindDevices(EncoderDeviceType.Video)
Dim audDevices = EncoderDevices.FindDevices(EncoderDeviceType.Audio)
For Each dvc In vidDevices
VidDvcsComboBox.Items.Add(dvc.Name)
Next
For Each dvc In audDevices
AudDvcsComboBox.Items.Add(dvc.Name)
Next
End Sub
Private Sub StartButton_Click(ByVal sender As System.Object, _
ByVal e As System.Windows.RoutedEventArgs) Handles StartButton.Click
' Display webcam images on control.
Try
webCamCtrl.StartCapture()
Catch ex As Microsoft.Expression.Encoder.SystemErrorException
MessageBox.Show("Device is in use by another application")
End Try
End Sub
Private Sub EndButton_Click(ByVal sender As Object, _
ByVal e As System.Windows.RoutedEventArgs) Handles EndButton.Click
' Stop the display of webcam video.
webCamCtrl.StopCapture()
End Sub
Private Sub RecordButton_Click(ByVal sender As System.Object, _
ByVal e As System.Windows.RoutedEventArgs) Handles RecordButton.Click
' Start recording of webcam video to harddisk.
webCamCtrl.StartRecording()
End Sub
Private Sub StopRecordButton_Click(ByVal sender As Object, _
ByVal e As System.Windows.RoutedEventArgs) Handles StopRecordButton.Click
' Stop recording of webcam video to harddisk.
webCamCtrl.StopRecording()
End Sub
Private Sub VidDvcsComboBox_SelectionChanged(ByVal sender As Object, _
ByVal e As System.Windows.Controls.SelectionChangedEventArgs) _
Handles VidDvcsComboBox.SelectionChanged
' Set which video device to use.
webCamCtrl.VideoDevice = VidDvcsComboBox.SelectedValue
End Sub
Private Sub AudDvcsComboBox_SelectionChanged(ByVal sender As Object, _
ByVal e As System.Windows.Controls.SelectionChangedEventArgs) _
Handles AudDvcsComboBox.SelectionChanged
' Set which audio device to use.
webCamCtrl.AudioDevice = AudDvcsComboBox.SelectedValue
End Sub
End Class
The VideoDevice
and AudioDevice
properties of Webcam
control are dependency properties and can therefore be data-bound to the SelectedValue
property of the necessary ComboBox
.
Private Sub MainWindow_Initialized(ByVal sender As Object, _
ByVal e As System.EventArgs) Handles Me.Initialized
Dim bndg_1 As New Binding("SelectedValue")
bndg_1.Source = VidDvcsComboBox
webCamCtrl.SetBinding(Webcam.VideoDeviceProperty, bndg_1)
Dim bndg_2 As New Binding("SelectedValue")
bndg_2.Source = AudDvcsComboBox
webCamCtrl.SetBinding(Webcam.AudioDeviceProperty, bndg_2)
End Sub
C#
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using Microsoft.Expression.Encoder.Devices;
using WebcamControl;
using System.IO;
namespace WPF_Webcam
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
private Webcam webCamCtrl;
public MainWindow()
{
InitializeComponent();
webCamCtrl = new Webcam();
// Bind the Video and Audio device properties of the
// Webcam control to the SelectedValue property of
// the necessary ComboBox.
Binding bndg_1 = new Binding("SelectedValue");
bndg_1.Source = VidDvcsComboBox;
webCamCtrl.SetBinding(Webcam.VideoDeviceProperty, bndg_1);
Binding bndg_2 = new Binding("SelectedValue");
bndg_2.Source = AudDvcsComboBox;
webCamCtrl.SetBinding(Webcam.AudioDeviceProperty, bndg_2);
// Create directory for saving video files.
string vidPath = @"C:\VideoClips";
if (Directory.Exists(vidPath) == false)
{
Directory.CreateDirectory(vidPath);
}
// Set some properties of the Webcam control
webCamCtrl.VideoDirectory = vidPath;
webCamCtrl.VidFormat = VideoFormat.wmv;
// Set the Webcam control as the ContentControl's content.
ContentControl1.Content = webCamCtrl;
// Find a/v devices connected to the machine.
FindDevices();
VidDvcsComboBox.SelectedIndex = 0;
AudDvcsComboBox.SelectedIndex = 0;
}
private void FindDevices()
{
var vidDevices = EncoderDevices.FindDevices(EncoderDeviceType.Video);
var audDevices = EncoderDevices.FindDevices(EncoderDeviceType.Audio);
foreach (EncoderDevice dvc in vidDevices)
{
VidDvcsComboBox.Items.Add(dvc.Name);
}
foreach (EncoderDevice dvc in audDevices)
{
AudDvcsComboBox.Items.Add(dvc.Name);
}
}
private void StartButton_Click(object sender, RoutedEventArgs e)
{
try
{
// Display webcam video on control.
webCamCtrl.StartCapture();
}
catch (Microsoft.Expression.Encoder.SystemErrorException ex)
{
MessageBox.Show("Device is in use by another application");
}
}
private void EndButton_Click(object sender, RoutedEventArgs e)
{
// Stop the display of webcam video.
webCamCtrl.StopCapture();
}
private void RecordButton_Click(object sender, RoutedEventArgs e)
{
// Start recording of webcam video to harddisk.
webCamCtrl.StartRecording();
}
private void StopRecordButton_Click(object sender, RoutedEventArgs e)
{
// Stop recording of webcam video to harddisk.
webCamCtrl.StopRecording();
}
}
}
As you can see from the sample code using the Webcam
control is not a hard affair once you have the necessary references and imports/using statements.
Webcam
The following are the members of interest in class Webcam
;
Properties
Name | Description | Type | |
---|---|---|---|
![]() |
VideoDirectory |
Gets or Sets the folder where the recorded webcam video will be saved. This is a dependency property. | String |
![]() |
VidFormat |
Gets or Sets the video format in which the webcam video will be saved. This is a dependency property. (The default format is .wmv) | VideoFormat |
![]() |
VideoDevice |
Gets or Sets the name of the video device to be used. This is a dependency property. | String |
![]() |
AudioDevice |
Gets or Sets the name of the audio device to be used. This is a dependency property. | String |
![]() |
IsRecording |
Gets a value indicating whether video recording is taking place. This is a read-only property. | Boolean |
Methods
Name | Description | |
---|---|---|
![]() |
StartCapture |
Displays webcam video on control. (Throws a Microsoft.Expression.Encoder.SystemErrorException if a specified device is already in use by another application) |
![]() |
StopCapture |
Stops the capturing/display of webcam video. (Stops any current recording of webcam video) |
![]() |
StartRecording |
Starts the recording of webcam video to a video file. (Throws a DirectoryNotFoundException if the directory specified in the VideoDirectory property is not found) |
![]() |
StopRecording |
Stops the recording of webcam video. |
The Code
The XAML markup for the UserControl is;
<UserControl x:Class="Webcam"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Height="Auto" Width="Auto" MinHeight="100" MinWidth="100"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:wf="clr-namespace:System.Windows.Forms;assembly=System.Windows.Forms"
mc:Ignorable="d" d:DesignWidth="320" d:DesignHeight="240" Name="Webcam">
<Grid>
<WindowsFormsHost Margin="0,0,0,0" Name="WinFormHost" Background="{x:Null}">
<wf:Panel x:Name="WebcamPanel" Size="320,240" />
</WindowsFormsHost>
</Grid>
</UserControl>
The dimensions of the WinForm Panel
are adjusted when the control is loaded so that the webcam video will occupy the entire area of the Panel
's parent element.
Private Sub Webcam_Loaded(ByVal sender As Object, _
ByVal e As System.Windows.RoutedEventArgs) Handles Me.Loaded
' Set dimensions of WinForm Panel to current dimensions
' of the UserControl.
Dim panelWidth As Integer = CInt(Me.ActualWidth)
Dim panelHeight As Integer = CInt(Me.ActualHeight)
WebcamPanel.Width = panelWidth
WebcamPanel.Height = panelHeight
End Sub
As highlighted earlier, Webcam
contains several properties and methods that aid in its operation. The VideoDevice
dependency property is defined as follows;
''' <summary>
''' Gets or Sets the name of the video device to be used.
''' </summary>
Public Property VideoDevice() As String
Get
Return CType(GetValue(VideoDeviceProperty), String)
End Get
Set(ByVal value As String)
SetValue(VideoDeviceProperty, value)
End Set
End Property
Public Shared VideoDeviceProperty As DependencyProperty = _
DependencyProperty.Register("VideoDevice", GetType(String), GetType(Webcam), _
New FrameworkPropertyMetadata(New PropertyChangedCallback( _
AddressOf VidDeviceChange)))
Private Shared Sub VidDeviceChange(ByVal source As DependencyObject, ByVal e As DependencyPropertyChangedEventArgs)
Dim deviceName As String = CType(e.NewValue, String)
Dim eDev = EncoderDevices.FindDevices(EncoderDeviceType.Video).Where _
(Function(dv) dv.Name = deviceName)
If (eDev.Count > 0) Then
CType(source, Webcam).vidDevice = eDev.First
Try
CType(source, Webcam).Display()
Catch ex As Microsoft.Expression.Encoder.SystemErrorException
Exit Sub
End Try
End If
End Sub
The StartCapture
method displays the webcam video in the WinForm Panel
, if the necessary properties are set;
''' <summary>
''' Display webcam video on control.
''' </summary>
Public Sub StartCapture()
If (canCapture = False) Then
canCapture = True
Try
Display()
Catch ex As Microsoft.Expression.Encoder.SystemErrorException
canCapture = False
Throw New Microsoft.Expression.Encoder.SystemErrorException
End Try
Else
Exit Sub
End If
End Sub
' Display video from webcam.
Private Sub Display()
If (canCapture = True) Then
If (vidDevice IsNot Nothing) Then
StopRecording()
Dispose()
job = New LiveJob
deviceSource = job.AddDeviceSource(vidDevice, audDevice)
deviceSource.PreviewWindow = New PreviewWindow(New HandleRef(WebcamPanel, WebcamPanel.Handle))
job.ActivateSource(deviceSource)
End If
End If
End Sub
The StartRecording
method records video from the webcam to the harddisk;
''' <summary>
''' Starts the recording of webcam video to a video file.
''' </summary>
Public Sub StartRecording()
If (dir <> String.Empty AndAlso job IsNot Nothing) Then
If (Directory.Exists(dir) = False) Then
Throw New DirectoryNotFoundException("The specified directory does not exist")
Exit Sub
End If
' If canCapture is true then it means the control is capturing video
' from the webcam.
If (canCapture = True) Then
StopRecording()
job.PublishFormats.Clear()
Dim timeStamp As String = DateTime.Now.ToString
timeStamp = timeStamp.Replace("/", "-")
timeStamp = timeStamp.Replace(":", ".")
Dim filePath As String = dir & "\WebcamVid " & timeStamp & "." & format
Dim fileArchFormat As New FileArchivePublishFormat(filePath)
job.PublishFormats.Add(fileArchFormat)
job.StartEncoding()
_isRecording = True
End If
End If
End Sub
The VideoFormat
enumeration contains three members;
Public Enum VideoFormat
wmv
mp4
flv
End Enum
You can take a look at the other properties and methods defined in class Webcam
by downloading the src files from the download link at the top of this article.
Post Comment
p3KlyE wow, awesome post.Really looking forward to read more. Will read on...
WF6GRc Whoa! This blog Whoa! This blog looks just like my old one! It as on a totally different subject but it has pretty much the same layout and design. Outstanding choice of colors!
s8ulSm Very interesting info !Perfect just what I was searching for! If you want to test your memory, try to recall what you were worrying about one year ago today. by Rotarian.
DcLCVq I think this is a real great blog.Really thank you! Want more.
An impressive share! I have just forwarded this onto a co-worker who had been conducting a little homework on this.
Hello! Please help me with a flight into space!
I want to fly into space but I have no money.
Please send me cryptocurrencies Bitcoin, my wallet:
1C4TnxWHDfjH4hyk1sziGapyTHAVBfnJ6A
Fly into space the dream of my life!
My fate is in your hands. Thanks!Do you have any helpful hints for first-time blog writers? I’d definitely appreciate it.
What is the easiest way to get updates from my subscribed blogs?
Im grateful for the article.Thanks Again. Fantastic.
EDJOOR Just wanna comment that you have a very decent website , I enjoy the layout it really stands out.
LvNqRE Im obliged for the blog.Really looking forward to read more. Keep writing.
AKRkgf Really appreciate you sharing this blog post.Really looking forward to read more. Fantastic.
pxE7L4 Way cool! Some very valid points! I appreciate you writing this post plus the rest of the site is very good.
a4uEZ8 Very nice post. I just stumbled upon your weblog and wanted to say that I have truly enjoyed browsing your blog posts. After all I all be subscribing to your feed and I hope you write again very soon!
N3vDBN I was suggested this website by my cousin. I am not sure whether this post is written by him as nobody else know such detailed about my difficulty. You are wonderful! Thanks!
a4oGm8 There exists noticeably a bundle to comprehend this. I suppose you might have made distinct good points in features also.
VeSxJX Thanks for all аАааБТour vаА аЂаluablаА аЂа laboаА аБТ on this ?аА аЂаbsite.
j85K6Z Thanks so much for the blog.Thanks Again. Awesome.
zmzHld thoroughly mixed. Promotional merchandise is a great approach to advertise your organization.
Veuxtu What is the best website to start a blog on?
8guKFI Some really wonderful blog posts on this internet site , regards for contribution.
CFp8Gt This blog was how do I say it? Relevant!! Finally I ave found something which helped me. Cheers!
oU5IaL Really informative blog post.Really thank you! Cool.
opAAVd Really informative blog.Really thank you! Cool.
FGE7qS Just Browsing While I was surfing yesterday I saw a great post concerning
QvF7EA the idea beach towel should be colored white because it reflects heat away-
fYwCZL Ultimately, a problem that I am passionate about. I have looked for data of this caliber for the previous various hours. Your site is greatly appreciated.
9iiL07 Very good blog post.Really looking forward to read more. Keep writing.
You created some decent points there. I looked on the net for that challenge and discovered most of the people will go coupled with with all of your internet site.
There is visibly a bundle to identify about this. I think you made some nice points in features also.
Z8f3gL I really liked your blog article.Really looking forward to read more. Will read on...
x5zlZL Thanks a lot for the post.Much thanks again. Great.
ZHItbp Thanks, I ave recently been hunting for information about this subject matter for ages and yours is the best I ave found so far.
K8YpML Very good article.Really looking forward to read more. Cool.
11Es0t Wow, fantastic blog layout! How long have you been blogging for? you made blogging look easy. The overall look of your site is fantastic, as well as the content!
GIPsBw Only wanna input that you have a very nice internet site , I love the design and style it really stands out.
ZzSnWF Whoa! This blog looks exactly like my old one! It as on a entirely different topic but it has pretty much the same page layout and design. Outstanding choice of colors!
bgLah4 sure, analysis is having to pay off. Loving the page.. all the best Loving the page.. glad I found it So pleased to have located this article..
bAmEDB
QQnPkO
O3ioya Muchos Gracias for your blog post. Keep writing.
urID4B more at Voice of America (blog). Filed Under:
3uiZOY Sources Wow! Thank you! I always needed to write on my blog something like that. Can I take a fragment of your post to my website?
VHQ5LW Major thanks for the blog post. Fantastic.
ZF0N27 Thanks a lot for the post.Really thank you! Really Cool.
tE3DNk This is really interesting, You are a very skilled blogger. I have joined your rss feed and look forward to seeking more of your magnificent post. Also, I ave shared your site in my social networks!
KGqn8S I?аАТаЂаll right away grasp your rss as I can not in finding your e-mail subscription hyperlink or newsletter service. Do you ave any? Please allow me recognize in order that I could subscribe. Thanks.
6jNDQFpp
NjMdR5 This is one awesome post.Really looking forward to read more. Great.
4xRTPc I really enjoy the article.Thanks Again. Want more.