Capture Video From Separate Thread - C#
Screen Capturing SDK sample in C# demonstrating ‘Capture Video From Separate Thread’
CapturingThread.cs
using System;
using System.Collections.Generic;
using System.IO;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading;
using System.Drawing;
using BytescoutScreenCapturingLib;
// NOTE: if you are getting error like "invalid image" related to loading the SDK's dll then
// try to do the following:
// 1) remove the reference to the SDK by View - Solution Explorer
// then click on References, select Bytescout... reference name and right-click it and select Remove
// 2) To re-add click on the menu: Project - Add Reference
// 3) In "Add Reference" dialog switch to "COM" tab and find Bytescout...
// 4) Select it and click "Add"
// 5) Recompile the application
// Note: if you need to run on both x64 and x86 then please make sure you have set "Embed Interop Types" to True for this reference
namespace CaptureFromSeparateThread
{
public class CapturingThread
{
public static void ThreadProc(Object obj)
{
CapturingThreadData data = (CapturingThreadData) obj;
data.Success = true;
// Prepare Capturer:
Capturer capturer = new Capturer(); // create new screen capturer object
capturer.RegistrationName = "demo";
capturer.RegistrationKey = "demo";
capturer.CaptureRectLeft = data.CaptureRectangle.Left;
capturer.CaptureRectTop = data.CaptureRectangle.Top;
capturer.CaptureRectWidth = data.CaptureRectangle.Width;
capturer.CaptureRectHeight = data.CaptureRectangle.Height;
capturer.OutputWidth = 640;
capturer.OutputHeight = 480;
// WMV and WEBM output use WMVVideoBitrate property to control output video bitrate
// so try to increase it by x2 or x3 times if you think the output video are you are getting is laggy
// capturer.WMVVideoBitrate = capturer.WMVVideoBitrate * 2;
capturer.CaptureRectWidth = 320;
capturer.CaptureRectHeight = 240;
data.TempFile = Path.GetTempFileName();
data.TempFile = Path.ChangeExtension(data.TempFile, ".wmv");
capturer.OutputFileName = data.TempFile;
capturer.CapturingType = data.CaptureType;
// set border around captured area if we are not capturing entire screen
if (capturer.CapturingType != CaptureAreaType.catScreen &&
capturer.CapturingType != CaptureAreaType.catWebcamFullScreen)
{
capturer.CaptureAreaBorderType = CaptureAreaBorderType.cabtDashed;
capturer.CaptureAreaBorderColor = (uint) ColorTranslator.ToOle(Color.Red);
}
// Wait for events:
WaitHandle[] events = new WaitHandle[] {data.StartOrResumeEvent, data.PauseEvent, data.StopEvent};
try
{
while (true)
{
int i = WaitHandle.WaitAny(events);
if (events[i] == data.StartOrResumeEvent)
{
if (!capturer.IsRunning)
capturer.Run();
}
else if (events[i] == data.PauseEvent)
{
if (capturer.IsRunning)
capturer.Pause();
}
else if (events[i] == data.StopEvent)
{
capturer.Stop();
break;
}
}
}
catch (Exception ex)
{
data.ErrorText = ex.Message;
data.Success = false;
}
finally
{
// Release resources
Marshal.ReleaseComObject(capturer);
}
}
}
}
CapturingThreadData.cs
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Text;
using System.Threading;
using BytescoutScreenCapturingLib;
// NOTE: if you are getting error like "invalid image" related to loading the SDK's dll then
// try to do the following:
// 1) remove the reference to the SDK by View - Solution Explorer
// then click on References, select Bytescout... reference name and right-click it and select Remove
// 2) To re-add click on the menu: Project - Add Reference
// 3) In "Add Reference" dialog switch to "COM" tab and find Bytescout...
// 4) Select it and click "Add"
// 5) Recompile the application
namespace CaptureFromSeparateThread
{
public class CapturingThreadData
{
public CaptureAreaType CaptureType;
public String TempFile;
public Rectangle CaptureRectangle = new Rectangle(0, 0, 320, 240);
public bool Success;
public string ErrorText;
public AutoResetEvent StartOrResumeEvent = new AutoResetEvent(false); // event signalling to start or resume the recodring
public AutoResetEvent PauseEvent = new AutoResetEvent(false); // event signalling to pause the recodring
public AutoResetEvent StopEvent = new AutoResetEvent(false); // event signalling to stop the recording
}
}
Form1.cs
using System;
using System.Diagnostics;
using System.IO;
using System.Threading;
using System.Windows.Forms;
using BytescoutScreenCapturingLib;
// NOTE: if you are getting error like "invalid image" related to loading the SDK's dll then
// try to do the following:
// 1) remove the reference to the SDK by View - Solution Explorer
// then click on References, select Bytescout... reference name and right-click it and select Remove
// 2) To re-add click on the menu: Project - Add Reference
// 3) In "Add Reference" dialog switch to "COM" tab and find Bytescout...
// 4) Select it and click "Add"
// 5) Recompile the application
// Note: if you need to run on both x64 and x86 then please make sure you have set "Embed Interop Types" to True for this reference
namespace CaptureFromSeparateThread
{
public partial class Form1 : Form
{
private Thread _capturingThread;
private CapturingThreadData _capturingThreadData; // data to exchange between form and capturing thread
public Form1()
{
InitializeComponent();
_capturingThreadData = new CapturingThreadData();
cmbCapturingType.SelectedIndex = 0;
}
private void btnStart_Click(object sender, EventArgs e)
{
CaptureAreaType captureType = CaptureAreaType.catMouse;
if (cmbCapturingType.SelectedIndex == 1)
captureType = CaptureAreaType.catScreen;
StartRecording(captureType);
}
private void btnPauseResume_Click(object sender, EventArgs e)
{
PauseOrResumeRecording();
}
private void btnStop_Click(object sender, EventArgs e)
{
StopRecording();
}
private void StartRecording(CaptureAreaType captureType)
{
btnStart.Enabled = false;
btnPauseResume.Enabled = true;
btnStop.Enabled = true;
_capturingThreadData.CaptureType = captureType;
// Start thread
_capturingThread = new Thread(CapturingThread.ThreadProc);
_capturingThread.Start(_capturingThreadData);
// Signal to start the recording
_capturingThreadData.StartOrResumeEvent.Set();
}
private void PauseOrResumeRecording()
{
btnStart.Enabled = false;
btnPauseResume.Enabled = true;
btnStop.Enabled = true;
if (btnPauseResume.Text == "Pause")
{
// Signal to pause
_capturingThreadData.PauseEvent.Set();
btnPauseResume.Text = "Resume";
}
else
{
// Signal to resume
_capturingThreadData.StartOrResumeEvent.Set();
btnPauseResume.Text = "Pause";
}
}
private void StopRecording()
{
Cursor = Cursors.WaitCursor;
// Signal to stop
_capturingThreadData.StopEvent.Set();
try
{
_capturingThread.Join();
}
finally
{
Cursor = Cursors.Default;
}
if (!_capturingThreadData.Success)
{
MessageBox.Show("Capturing failed. Error: " + _capturingThreadData.ErrorText);
}
else
{
SaveFileDialog dlg = new SaveFileDialog();
dlg.DefaultExt = "*.wmv";
dlg.Filter = "WMV files (*.wmv)|*.wmv|All files (*.*)|*.*";
dlg.FileName = "Screencast";
dlg.Title = "Save captured video as";
if (dlg.ShowDialog() == DialogResult.OK)
{
File.Copy(_capturingThreadData.TempFile, dlg.FileName, true);
Process.Start(dlg.FileName); // start the video in default associated application
}
File.Delete(_capturingThreadData.TempFile);
}
btnStart.Enabled = true;
btnPauseResume.Enabled = false;
btnStop.Enabled = false;
btnPauseResume.Text = "Pause";
}
private void Form1_FormClosing(object sender, FormClosingEventArgs e)
{
_capturingThreadData.StopEvent.Set();
}
}
}
Form1.Designer.cs
��n a m e s p a c e C a p t u r e F r o m S e p a r a t e T h r e a d
{
p a r t i a l c l a s s F o r m 1
{
/ / / <