PixelStreaming:基本概念与上手初探

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平台(依赖于模块D3DX11NvVideoEncoder库)。

UE提供的PixelStreaming展示案例的代码分成了几个部分:

  • PixelStreamingPlugin:提供渲染帧与音频数据的捕获与编码,并创建一个链接将音频和渲染帧的数据传递给WebRTC服务器,使用的是UE的插件方式编写和使用。
  • WebRTCProxy:应用/游戏与WebServer交流的中间层,作用是将游戏内编码好的渲染帧数据(.h264)与音频数据传递给WebServer,并从WebServer上接收到的用户输入再传递给应用/游戏,从而可以从浏览器上控制游戏。使用UE的Program方式编写。
  • WebServer:PixelStreaming设计的组织方式中,WebServer是由两个模块组成:SignalingWebServerMatchmaker,使用的是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
2
3
4
5
2019/07/29  01:21               110 Start_AWS_WebRTCProxy.bat
2019/07/29 01:21 473 Start_AWS_WebRTCProxy.ps1
2019/07/29 01:21 38 Start_WebRTCProxy.bat
2019/07/29 01:21 18,032,016 WebRTCProxy.exe
2019/07/29 01:21 15,511,552 WebRTCProxy.pdb

需要做的只有双击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
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
E:\UnrealEngine\Epic\UE_4.22\Engine\Source\Programs\PixelStreaming\WebRTCProxy\bin>WebRTCProxy.exe -help
WebRTCProxy
Copyright 1998-2019 Epic Games, Inc. All Rights Reserved.

Parameters:

-help
Shows this help

-Cirrus=<IP:Port>
The Cirrus server to connect to. If not specified. it defaults to 127.0.0.1:8888

-StunServer=<IP:Port>
Stun server to use.

-UE4Port=<Port>
The port UE4 is listening on

-AutoSetBitrate
If specified, it forcibly sends a bitrate request to UE4 once a client gets
quality control ownership

-PlanB
If specified, it will use PlanB sdp semantics. Default is UnifiedPlan.

-dbgwindow=[Proxy|WebRTC|All|None]
If running under the debugger (e.g: Visual Studio), it specifies what logs to
send to the Output Window.
Proxy - Only logs from WebRTCProxy itself will be displayed.
WebRTC - Only logs from WebRTC internals will be displayed.
All - (Default) Both WebRTCProxy and WebRTC internal logs are displayed.
None - No logs sent to the Output Window

-LocalTime
If specified, it will use local time in logging, instead of UTC.

其中:

  • -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 -vnpm -v测试是否安装成功:

1
2
3
4
C:\Users\imzlp\Desktop>node -v
v10.16.0
C:\Users\imzlp\Desktop>npm -v
6.9.0

如上图则没有问题,可以启动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)。

全文完,若有不足之处请评论指正。

扫描二维码,分享此文章

本文标题:PixelStreaming:基本概念与上手初探
文章作者:ZhaLiPeng
发布时间:2019年07月30日 17时48分
本文字数:本文一共有2.2k字
原始链接:https://imzlp.me/posts/9455/
许可协议: CC BY-NC-SA 4.0
转载请保留原文链接及作者信息,谢谢!
您的捐赠将鼓励我继续创作!