My WinForms .NET 4 C# application records the desktop while the user interacts with it.
It uses the AForge FFMPEG or VFW wrappers depending on the speed of the system. The capturing is done in a background thread of course.
In either case, the wrappers require the frame rate to be specified in advance. This is problematic since capturing frequency is undeterministic and easily affected by how busy the target machine is. On a good system, I get a maximum of 10 FPS.
So two issues here:
The code I use is listed below for clarity:
private void ThreadWork ()
{
int count = 0;
string filename = "";
RECT rect = new RECT();
System.Drawing.Bitmap bitmap = null;
System.Drawing.Graphics graphics = null;
System.DateTime dateTime = System.DateTime.Now;
System.IntPtr hWndForeground = System.IntPtr.Zero;
AForge.Video.FFMPEG.VideoFileWriter writer = null;
filename = @"c:\Users\Raheel Khan\Desktop\Temp\Capture.avi";
if (System.IO.File.Exists(filename))
System.IO.File.Delete(filename);
writer = new AForge.Video.FFMPEG.VideoFileWriter();
writer.Open
(
filename,
System.Windows.Forms.Screen.PrimaryScreen.Bounds.Width,
System.Windows.Forms.Screen.PrimaryScreen.Bounds.Height,
10, // FPS
AForge.Video.FFMPEG.VideoCodec.MPEG4
);
bitmap = new Bitmap
(
System.Windows.Forms.Screen.PrimaryScreen.Bounds.Width,
System.Windows.Forms.Screen.PrimaryScreen.Bounds.Height,
System.Drawing.Imaging.PixelFormat.Format24bppRgb
);
graphics = System.Drawing.Graphics.FromImage(bitmap);
dateTime = System.DateTime.Now;
while (System.DateTime.Now.Subtract(dateTime).TotalSeconds < 10) // 10 seconds.
{
graphics.CopyFromScreen(Screen.PrimaryScreen.Bounds.X, Screen.PrimaryScreen.Bounds.Y, 0, 0, Screen.PrimaryScreen.Bounds.Size);
rect = new RECT();
hWndForeground = GetForegroundWindow();
GetWindowRect(hWndForeground, ref rect);
graphics.DrawRectangle(Pens.Red, rect.Left, rect.Top, rect.Right - rect.Left, rect.Bottom - rect.Top);
graphics.DrawString(count++.ToString(), this.Font, Brushes.Red, 10, 10);
writer.WriteVideoFrame(bitmap);
System.Threading.Thread.Sleep(10);
}
writer.Close();
writer.Dispose();
System.Diagnostics.Process.Start(System.IO.Path.GetDirectoryName(filename));
}
You could capture the frames to a temp folder as jpegs or to a mjpeg file, and then reprocess it to an avi video file when the user desires it. This will cut down on the amount of processing you need to do 'on the fly' and free up resources - and allow your system to reach a higher and more regular frame rate.