2

我刚开始编写一个应用程序,我的想法是创建类似 StreamMyGame 但供个人使用的东西,已经有一个名为 Single Player Game Transmiter 的项目可以实现其中的一些(http://sourceforge.net/projects/spgt/files/ )。

到目前为止,我没有编码也没有流式传输,我只是捕获视频并将其显示在我的应用程序窗口中。

那么我该如何处理编码/流式传输呢?我在想原始JPEG的UDP流将是最简单的路径,但我不确定。

另外,我该如何优化我目前拥有的东西?它可以很好地播放视频,但是在捕获游戏窗口时,它似乎不像原始视频那样活泼,我认为这可能是因为它在后台运行。这让我想到另一个问题,如何捕获具有指定标题的窗口而不是活动窗口?

https://github.com/fr500/desktop_streamer

编辑

使用当前捕获方法的一些测试:

视频播放器捕获 (960x720p)

starting benchmark
================================================
looking for window: test.mp4
looking for window: test.mp4
looking for window: test.mp4
looking for window: test.mp4
looking for window: test.mp4
================================================
starting single thread capture only test

Time Elapsed: 19480 milliseconds
Frame Time: 32 milliseconds
Rough FPS: 30
Sleeping 2 seconds

starting single thread capture and save as bmp test

Time Elapsed: 19768 milliseconds
Frame Time: 32 milliseconds
Rough FPS: 30
Sleeping 2 seconds

starting single thread capture and save as jpg test

Time Elapsed: 28593 milliseconds
Frame Time: 47 milliseconds
Rough FPS: 20
Sleeping 2 seconds

starting dual thread capture only test

Time Elapsed: 19515 milliseconds
Frame Time: 32 milliseconds
Rough FPS: 30
Sleeping 2 seconds

starting quad thread capture only test

Time Elapsed: 19481 milliseconds
Frame Time: 32 milliseconds
Rough FPS: 30
Sleeping 2 seconds

孤岛危机 2 捕获 (1024x768p)

starting benchmark
================================================
looking for window: Crysis 2 (TM)
looking for window: Crysis 2 (TM)
looking for window: Crysis 2 (TM)
looking for window: Crysis 2 (TM)
looking for window: Crysis 2 (TM)
looking for window: Crysis 2 (TM)
looking for window: Crysis 2 (TM)
================================================
starting single thread capture only test

Time Elapsed: 20003 milliseconds
Frame Time: 33 milliseconds
Rough FPS: 29
Sleeping 2 seconds

starting single thread capture and save as bmp test

Time Elapsed: 20105 milliseconds
Frame Time: 33 milliseconds
Rough FPS: 29
Sleeping 2 seconds

starting single thread capture and save as jpg test

Time Elapsed: 17353 milliseconds
Frame Time: 28 milliseconds
Rough FPS: 34
Sleeping 2 seconds

starting dual thread capture only test

Time Elapsed: 19991 milliseconds
Frame Time: 33 milliseconds
Rough FPS: 30
Sleeping 2 seconds

starting quad thread capture only test

Time Elapsed: 19983 milliseconds
Frame Time: 33 milliseconds
Rough FPS: 30
Sleeping 2 seconds

将图像保存到 BMP 并不会真正增加任何开销,但保存为 JPG 确实让我了解了视频编码可能具有的开销。仍然最大的问题是获取帧本身,它现在太慢了,无法跟上,因此丢失了一些帧。如果可以以 60+ fps 的速度捕获帧,那么对于单人游戏来说,编码 + 流媒体延迟确实是可以管理的。

我将尝试使用 DX 钩子方法来获取帧。

4

2 回答 2

2

我不确定性能/质量问题是否是在后台运行的影响,但是我会尝试回答您的问题。

按名称捕获窗口

我想您可以尝试使用FindWindow函数而不是GetForegroundWindow应用程序中使用的函数。它允许您通过标题获取窗口的句柄。为了做到这一点(在您发布链接的 desktop_streamer 项目中),请转到ScreenCapture课程并:

  • 改变

    [DllImport("user32.dll")]
    private static extern IntPtr GetForegroundWindow();
    

    [DllImport("user32.dll", SetLastError = true)]
    private static extern IntPtr FindWindow(string lpClassName, string lpWindowName);
    
  • Capture方法中更改行

    var foregroundWindowsHandle = GetForegroundWindow();
    

    var foregroundWindowsHandle = FindWindow(null, "mywindowName");
    

我没有对此进行测试,所以如果您在运行代码时遇到任何问题,请告诉我,以便我们寻找解决方案。

有关FindWindow功能的更多信息,请查看此处:http ://www.pinvoke.net/default.aspx/user32.findwindow 。

性能和图像质量

在谈论性能时,您可能想尝试实时测量网络速度和延迟,然后使用这些信息来适当地调整图像质量(压缩级别和分辨率)。这会使传输的图像不时像素化,但会降低游戏延迟的影响。

您可能还想查看此页面,其中提供了两种屏幕捕获方法的一些性能比较:http: //blog.bobcravens.com/2009/04/fastest-screen-capture-using-c-vista-vs -win7/。它可以帮助您提高屏幕捕获过程的性能,但正如您所见,实现的帧速率仍然太低,无法提供高质量的游戏体验。

于 2012-07-14T09:14:34.070 回答
1

最近,我构建了一个名为 ScreenStreamer 的 golang 项目,它是一个将当前活动窗口(Linux 或 Windows)流式传输到其他设备(如手机或另一台 PC)的工具,如 MJPEG,它非常实时(延迟 < 100ms)

项目链接:https ://github.com/fiefdx/ScreenStreamer

于 2016-11-14T05:32:22.380 回答