【问题标题】:How to stream video from videogame to another computer in realtime?如何将视频游戏中的视频实时传输到另一台计算机?
【发布时间】:2012-07-14 05:50:03
【问题描述】:

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

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

那么我该如何处理编码/流式传输?我在想原始 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

Crysis 2 Capture (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 钩子方法来获取帧。

【问题讨论】:

    标签: c# encoding streaming capture


    【解决方案1】:

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

    按名称捕获窗口

    我想您可以尝试使用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/。它可以帮助您提高屏幕捕获过程的性能,但正如您所见,实现的帧速率仍然太低,无法提供高质量的游戏体验。

    【讨论】:

    • 也许我测量错了,但我得到了 16 毫秒的帧时间(在绘制图像之前)
    • 好吧,我试过你的代码,即使游戏窗口在后台,它也有助于捕获,谢谢!
    • 很高兴它对您有所帮助:)。测量的时间取决于执行测量的特定机器。我没有注意到我链接到的那篇文章是 2009 年写的,所以你的机器可能比文章作者使用的机器快得多。如果这回答了您的问题,请将其标记为答案,如果没有,请告诉我您还想问什么:)。
    • 现在我需要将帧编码为视频,根据我的测量,从我请求捕获的那一刻到帧被保存到磁盘的那一刻,我得到了 60 毫秒,这相当于大约 60 fps,所以它应该我猜是可行的。我会尝试 StreamMyGame 和 SPGTS 看看它们是否流畅
    • 好吧,如果您对此有任何想法,我仍然会错过编码/流式传输部分。
    【解决方案2】:

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

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-06-22
      • 1970-01-01
      相关资源
      最近更新 更多