Mi aplicación WinForms .NET 4 C# registra el escritorio mientras el usuario interactúa con él.Captura de pantalla de video usando AForge.Video.FFMPEG/AForge.Video.VFW. Problema de tasa de fotogramas
Utiliza las envolturas AForge FFMPEG o VFW dependiendo de la velocidad del sistema. La captura se realiza en un hilo de fondo, por supuesto.
En cualquier caso, los envoltorios requieren que la velocidad de fotogramas se especifique de antemano. Esto es problemático ya que la frecuencia de captura es indeterminada y se ve afectada fácilmente por la ocupación de la máquina objetivo. En un buen sistema, obtengo un máximo de 10 FPS.
Así que dos cuestiones:
- Cómo alinear marcos basado en la tasa real de marco de captura?
- Cómo aumentar la velocidad de fotogramas, tal vez mediante el uso de una solución que no sea AForge?
El código que utilizo se enumeran a continuación para mayor claridad:
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));
}
Gracias. Eso se ocuparía de calcular correctamente la velocidad de fotogramas real, pero desafortunadamente tomaría más tiempo en el disco IO que el método actual. Lo sincronicé en una máquina de desarrollo bastante decente. Ahora estoy buscando alternativas comerciales como LeadTools, aunque su licencia es demasiado cara. –
Si almacena en búfer los marcos, resuelve el problema de E/S de disco. Coge cada cuadro como un jpeg y almacena en la memoria. 10 mb de ram almacenará alrededor de 100 fotogramas, que es de 4 segundos a 25 fps. Luego, escríbalos en el disco como un único archivo mjpeg con encabezado de formato MIME. Mencoder, por ejemplo, puede convertir dicho archivo directamente a avi, simplemente pasando parámetros de línea de comandos. Esto significa que puede omitir una forge y obtener su avi en diferentes procesos, que pueden ser más eficientes en el uso de recursos en una máquina multinúcleo. – Sugrue