使用上述视频的屏幕捕获视频。FFMPEG / AForge.Video.VFW。帧率问题

时间:2021-05-14 16:01:22

My WinForms .NET 4 C# application records the desktop while the user interacts with it.

我的WinForms . 4 c#应用程序在用户与桌面交互时记录桌面。

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.

它根据系统的速度使用AForge FFMPEG或VFW包装器。捕获当然是在后台线程中完成的。

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.

无论哪种情况,包装器都要求预先指定帧速率。这是有问题的,因为捕获频率是不确定的,很容易受到目标机器的繁忙程度的影响。在一个好的系统中,我最多能得到10个FPS。

So two issues here:

所以两个问题:

  • How to align frames based on actual capture frame rate?
  • 如何根据实际捕获帧率对帧进行对齐?
  • How to increase the frame rate, perhaps by using a solution other than AForge?
  • 如何增加帧速率,也许是通过使用AForge以外的解决方案?

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));
}

1 个解决方案

#1


3  

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.

您可以将帧捕获到临时文件夹作为jpeg文件或mjpeg文件,然后在用户需要时将其重新处理为avi视频文件。这将减少您需要进行的“动态”处理的数量,并释放资源——并允许您的系统达到更高、更常规的帧速率。

#1


3  

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.

您可以将帧捕获到临时文件夹作为jpeg文件或mjpeg文件,然后在用户需要时将其重新处理为avi视频文件。这将减少您需要进行的“动态”处理的数量,并释放资源——并允许您的系统达到更高、更常规的帧速率。