c# - 使用 AForge.Video.FFMPEG/AForge.Video.VFW 截屏视频。帧率问题

标签 c# .net screen-capture frame-rate aforge

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

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

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

这里有两个问题:

  • 如何根据实际捕获帧率对齐帧?
  • 如何提高帧速率,或许可以使用 AForge 以外的解决方案?

为清楚起见,下面列出了我使用的代码:

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

最佳答案

您可以将帧捕获为 jpeg 格式的临时文件夹或 mjpeg 文件,然后在用户需要时将其重新处理为 avi 视频文件。这将减少您需要“即时”执行的处理量并释放资源 - 并允许您的系统达到更高和更规则的帧速率。

关于c# - 使用 AForge.Video.FFMPEG/AForge.Video.VFW 截屏视频。帧率问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10342647/

相关文章:

c# - 把容器注入(inject)工厂可以吗?

c# - 如何在 Windows Phone 中居中弹出用户控件?

.net - 使用 TFS 代理将生成服务器配置为具有 .NET Core 2.1 和 .NET Core 3.1

c# - 将数组与 SQL Server 数据库的 "very large"表进行比较

c# - 其中一个线程阻止 .NET 程序完全停止。如何识别是哪一个?

swift - CGDisplayStream 仅捕获单个帧

c# - 是否可以禁止或 'hide' 方法来阻止开发团队使用它们?

c# - 单元测试与集成测试 : Entity Framework Core In memory

react-native - 捕获 Ref 或自定义从 JSX/HTML 生成图像 react native 而不向用户显示 UI

C# PrintWindow 返回黑色图像