PixelStreaming 是 UE_4.21 开始支持的一项技术,简单来说就是能够将游戏跑在服务器上,你可以通过浏览器来玩,玩家端不需要额外操作,只需要一个浏览器,所有的逻辑处理和渲染都在“云”端执行。它不仅仅只是一个插件 (虽然有 PixelStreamingPlugin 这个插件,但它只是PixelStreaming 实现中的一环),其实现具有一套独立与 UE 游戏的设计和组织方式。
本篇文章主要介绍 PixelStreaming 中的基本概念和使用 PixelStreaming 的 Demo 的实际体验。
来看一下 UE 自己的介绍:
Run your Unreal Engine application on a server in the cloud, and stream its rendered frames and audio to browsers and mobile devices over WebRTC.
PixelStreaming 的数据传输使用的是WebRTC,P2P 的连接延迟更低。
注意:本文所描述内容的测试引擎为 UE_4.22.3,目前 PixelStreaming 只能运行在 Windows 平台 (依赖于模块
D3DX11
和NvVideoEncoder
库)。
UE 提供的 PixelStreaming 展示案例的代码分成了几个部分:
- PixelStreamingPlugin:提供渲染帧与音频数据的捕获与编码,并创建一个链接将音频和渲染帧的数据传递给 WebRTC 服务器,使用的是 UE 的插件方式编写和使用。
- WebRTCProxy:应用 / 游戏与 WebServer 交流的中间层,作用是将游戏内编码好的渲染帧数据 (.h264) 与音频数据传递给 WebServer,并从 WebServer 上接收到的用户输入再传递给应用 / 游戏,从而可以从浏览器上控制游戏。使用 UE 的 Program 方式编写。
- WebServer:PixelStreaming 设计的组织方式中,WebServer是由两个模块组成:SignalingWebServer与Matchmaker,使用的是 nodejs 编写。
- SignallingWebServer:启动一个 HTTP 服务,从 WebRTC 接收渲染帧和音频数据传递给浏览器客户端,并接收远程用户的输入 (键盘、鼠标等) 再传递给 WebRTC。
- MatchMakerServer:如果只是启动一个游戏实例和单个的 SignallingWebServer,那么使用浏览器访问的玩家操作的都是同一个游戏实例,他们的键盘和鼠标操作都会相互干扰。解决这个的问题的办法使用MatchMakerServer,但是这种方式也是需要启动多套 游戏实例 /WebRTCProxy 以及SignallingWebServer,供外部用户每个人访问不同的游戏实例,使每个浏览器访问的客户端具有不同的连接。
用户访问单个实例的流程如下图:
后续我会逐个分析一下它们各自的代码实现(上周末的简单分析了一下 PixelStreamingPlugin 的实现),这篇文章的目的是介绍基本概念和简单的 PixelStreamingDemo 上手。
本篇文章的参考资料主要是 UE 文档库中对于 PixelStreaming 的介绍,以及我读代码了解到的实现方式,目前官方文档页面的描述不是特别详细,有些细节和可以用的参数命令没有提及,还是看代码靠谱。
PixelStreamingDemo
基本概念介绍完毕,下面进入实际的上手环节。
Launch Game
首先创建一个 C++ 项目,我选择了一个第三人称模板:
创建完成之后,打开 Edit
-Plugins
搜索启用PixelStreaming
:
然后重启编辑器。
与 UE 的官网介绍 (Getting Started with Pixel Streaming) 的需要打包不同,只要使用 Standalone 模式启动项目就可以加载 PixelStreamingPlugin
,这样可以省去每次都要打包的麻烦。
为了方便添加启动参数,可以使用我之前写的一个工具:UE4 Launcher
并为其添加启动参数-game
/-log
/-AudioMixer
(PixelStreamingPlugin 需要这个参数):
注:PixelStreamingPlugin 支持启动时指定要连接的 WebRTCProxy 的地址与端口,可以在上面的启动参数列表中添加。
-PixelStreamingIP=<value>
:指定 WebRTCProxy 服务器的地址,默认为0.0.0.0
.-PixelStreamingPort=<value>
:指定 WebRTCProxy 服务器的端口,默认为8124
.
然后点击 Launch Configuration
即可以 Standalone 模式启动项目。
启动之后可以从 Log 窗口中看到 PixelStreaming 的 Log 输出:
WebRTCProxy
经过上面的操作游戏启动完成之后,可以启动 WebRTC 了,打开引擎目录:
1 | Engine\Source\Programs\PixelStreaming\WebRTCProxy\bin |
可以看到目录下有五个文件:
1 | 2019/07/29 01:21 110 Start_AWS_WebRTCProxy.bat |
需要做的只有双击 Start_WebRTCProxy.bat
启动(它里面也仅仅只是启动了WebRTCProxy.exe).
启动之后可以看到连接信息:
此时在打开游戏项目的 Log 窗口可以看到如下内容:
1 | [2019.07.30-08.18.49:324][758]PixelStreamingNet: Accepted connection from WebRTC Proxy: 127.0.0.1:2703 |
表明 PixelStreamingPlugin 与 WebRTCProxy 已经连接成功了。
WebRTCProxy也可以指定游戏内 PixelStreamingPlugin 设定的端口,以及 SignallingWebServer 的地址 / 端口,可以通过 -help
参数来查看 WebRTCProxy 支持的参数(这部分的实现代码在 Engine/Source/Programs/PixelStreaming/WebRTCProxy/src/WebRTCProxy.cpp 中):
1 | E:\UnrealEngine\Epic\UE_4.22\Engine\Source\Programs\PixelStreaming\WebRTCProxy\bin>WebRTCProxy.exe -help |
其中:
-Cirrus=<IP:Port>
用来指定与 SignallingWebServer 通信的端口(默认为127.0.0.1:8888
).-UEPort=<Port>
:用来指定与该 WebRTCProxy 关联的 UE 应用的端口(PixelStreamingPlugin 中的连接端口,默认为127.0.0.1:8124
)
SignallingWebServer
当游戏与 WebRTCProxy 都启动完毕之后,需要开始启动真正供浏览器可访问的 HTTP 服务器了。
首先需要安装 node,下载安装之后将其添加到系统的 PATH 路径,通过命令node -v
与npm -v
测试是否安装成功:
1 | C:\Users\imzlp\Desktop>node -v |
如上图则没有问题,可以启动 SignallingWebServer 了,打开引擎目录:
1 | Engine\Source\Programs\PixelStreaming\WebServers\SignallingWebServer |
里面有一堆的文件,需要启动的是 run.bat
或者 runNoSetup.bat
(他们两个唯一的区别为是否执行npm install
),如果你是第一次打开,则 以管理员权限 启动run.bat
,后续直接启动runNoSetup.bat 即可
。
经过一堆的 npm 包的下载与安装之后,启动成功:
此时打开 WebRTCProxy 的窗口界面,可以看到以下内容:
此时所有需要启动的服务都已启动完毕。
注:SignallingWebServer默认连接
127.0.0.1:8888
的 WebRTCProxy,并开启一个 80 端口的 HTTP 服务。
- 使用
--proxyPort <Port>
可以修改监听的 WebRTCProxy 端口,或者写在SignallingWebSerber/config.json
配置下。- 使用
--httpPort <Port>
可以修改启动的 HTTP 服务器的端口。
打开浏览器输入 http://127.0.0.1(使用的是默认端口 80,不然需要指定端口号https://127.0.0.1:xxxx) 就可以看到以下界面:
鼠标点击即可进入游戏画面:
其他的移动设备如果在同一个网段,也是可以直接连接的:
我也录了一个简单的视频(在 ipad 上操作):
MatchMakerServer
在文章的最开始,我简单说明了一下 MatchMakerServer 的用途,下面简单说一下如何做。
先来看 UE 对 MatchMakerServer 的职责图:
用法为:在启动单个的 SignallingWebServer 时,指定参数启用Matchmaker
:
1 | runNoSetup.bat --UseMatchmaker --matchmakeAddress 127.0.0.1 --matchmakerPort 9999 |
然后启动MatchmakerServer,找到以下路径:
1 | Engine\Source\Programs\PixelStreaming\WebServers\Matchmaker |
直接启动 run.bat
的默认 httpPort
为 90,matchmakerPort
为 9999,即上面运行 SignallingWebServer 时指定的--matchmakerPort 9999
,可以自己使用参数替换。
1 | run.bat --httpPort 88 --matchmakerPort 9988 |
下面使用的是默认的 httpPort
/matchmakePort
端口
然后访问 http:127.0.0.1:90,可以看到与单独启动的SignallingWebServer 一样,但是不允许其他的客户端再加入到当前的会话中来,会提示WARNING: No empty Cirrus servers are available
。
除非同时运行多套 游戏 /WebRTCProxy/SignallingWebServer,使每个玩家独占一套不相互干扰,这也是MatchmakerServer 的作用所在。
结语
Pixel Streaming 这种“云”游戏的思路很好,但是目前的硬件环境和带宽瓶颈还是很大的问题,在我测试体验的过程中,局域网连接比较流畅,在设定最高 60fps 的情况下可以跑到满帧,但是也是会出现偶尔掉帧的情况。
Google 也推出了云游戏平台Stadia,但是离真的可以落地还很远,但是目前做一些行业应用还是可以的(比如雪佛兰的汽车展示2020 CORVETTE STINGRAY)。