本文介绍在虚幻引擎上实现像素流送的各种可能方案并给出对比报告。
自 2018 年底以来1,虚幻引擎包含了一个称为像素流送(Pixel Streaming)的系统,通过该系统,来自远程虚幻引擎实例的音频和视觉图像被流式传输到 WebRTC 对端(通常是网络浏览器),而键盘、鼠标和触屏输入则可以从 WebRTC 对端传回,以促进与此 Pixel Streaming Unreal Engine 实例的交互。2
Unreal Engine 的 Pixel Streaming 系统是建立在 WebRTC 之上的,现代 Web 浏览器很好地支持它。3 WebRTC 专门设计为通过公共互联网进行双向、低延迟实时通信的整体解决方案。然而,有许多流媒体场景要么是单向的、非实时的,要么在不受数据包丢失或公共互联网变化的网络条件影响的受控网络环境中运行。此类流式传输场景的示例包括:直播、模拟软件、遗留硬件,或在完全受控的专用网络中运行的简单流式传输场景。这些场景不一定需要也不支持 WebRTC 的技术组合。
如果上述这些场景无法支持 WebRTC 连接,则意味着无法直接使用 Unreal Engine Pixel Streaming 系统。这是不幸的,因为我们认为在这些用例中虚幻引擎的音频、视觉和输入的流式传输是非常可取的。幸运的是,许多这些流式传输用例,尤其是黑盒硬件和仿真软件,已经支持使用现有的流式传输协议(例如 RTP 或 RTMP)接收流式传输数据。在这些用例中对非 WebRTC 流协议的支持提供了两个潜在的选择:
本报告的目的是调查每个可选项。具体来说,我们将确定这些选项的候选方法,然后根据其优势、局限性和一般可行性评估每种方法。我们以我们对这些非 WebRTC 接收器的像素流式传输的建议来结束本报告。
在本节中,我们将概述相关的流协议、以及与之相关的各种用户体验品质的技术,并回顾一些 WebRTC 网关服务器和转发器。本概述提供了相关背景信息,为我们对第 3 节中每种潜在解决方案的优势、局限性和可行性的调查提供信息。
实时数据流传输,例如视频、音频和控制输入,是过去多次尝试和改进的任务。作为本报告的一部分,我们对之前的一些工作进行了分析,我们认为这些工作与我们的目的相关的潜在流协议。下面的概述表提供了有关协议的简要说明和关键细节。
名称 | 描述 | 运输 | 典型用途 | 年 |
---|---|---|---|---|
RTP - 实时传输协议 | 一种用于实时数据端到端传输的协议。RTP 包括序列号/时序数据,以帮助无序数据重组。4 | UDP | 视频/音频 | 2003年 |
RTCP - RTP 控制协议 | “监控服务质量并……在正在进行的 [RTP] 会话中传达有关参与者的信息”。5 RTCP 是 RTP 的姊妹协议,用于为 RTP 会话发送 QoS 控制消息。 | UDP | QoS 控制消息 | 2003年 |
RTSP - 实时流媒体协议 | “RTSP 提供了一个可扩展的框架,以实现受控的按需交付实时数据,例如音频和视频……[RTSP] 通常不交付连续流本身……换句话说,RTSP 仅充当‘网络远程多媒体服务器的控制”。6通常,RTSP 控制的流将使用 RTP 作为其底层协议。RTSP 采用客户端-服务器架构。 | UDP/TCP | 创建和控制流的消息。 | 1998 |
RTMP - 实时消息传递协议 | “RTMP 通过可靠的流传输(例如 TCP)提供双向消息多路复用服务,旨在在一对通信对等点之间传输视频、音频和数据消息的并行流以及相关的时间信息”。7 RTMP 是 Adobe 在 2005 年收购 Macromedia 时获得的。该规范于 2009 年公开发布。8它被媒体服务器广泛支持;但是,浏览器/移动设备支持一直在下降。9它有一些延迟,例如,5s 是典型的。9 | TCP | 视频/音频 | 2009 |
SRT - 安全可靠的运输 | “SRT 是一种视频流传输协议和技术栈(在概念上类似于可靠的 UDP)。SRT 连接两个端点,以便通过有损网络传输低延迟视频和其他媒体流”。10除了处理有损网络,在协议级别 SRT 还支持端到端加密。SRT 主要在直播行业中得到采用,因此在该行业之外的协议支持可能会受到关注;但是,它是开源的。11 | UDP | 视频/音频 | 2013 |
RIST - 可靠的互联网流传输 | RIST 与 SRT 类似,因为它是一个开源12协议,旨在解决有损网络(如互联网)中可靠、低延迟的媒体传输。然而,与 SRT 不同的是,RIST 建立在 RTP 和 RTSP 之上,以最大限度地提高互操作性,因为已经有大量资源支持 RTP 和 RTSP。13 | UDP | 视频/音频 | 2018 |
WebRTC - Web 的实时通信 | WebRTC 是许多现有技术的组合,旨在通过公共互联网实现低延迟(特别是亚秒级)通信。14它对恶劣的网络条件具有弹性,并且可以优雅地适应数据包丢失。14与本报告中讨论的所有其他协议不同,WebRTC 本身是实时通信的整体解决方案,可处理:对等网络、会话管理、数据流以及适应网络条件的变化。此外,它在所有主要的 Web 浏览器中得到广泛支持。14 | TCP/UDP | 视频/音频/数据 | 2011 |
我们认为 RTP 可能是表 1 中列出的任何协议中实现最简单的协议。但是,与 SRT、RIST、RTMP 和 WebRTC 不同,RTP 协议没有内置机制来处理数据包丢失或网络抖动——这些挑战被推迟了给应用程序开发者。因此,如果要在虚幻引擎内部实施纯 RTP 流解决方案,讨论如何解决这些挑战似乎是明智的。
对于开发人员来说幸运的是,存在许多众所周知的有效技术来解决流数据的丢包和网络抖动问题。我们将这种方法称为“体验质量”(QoE)技术。一些已知的 QoE 技术包括前向纠错 (FEC)、自动重复请求 (ARQ)、抖动缓冲和数据包丢失隐藏。我们在下面简要介绍和解释这些 QoE 技术。此外,我们强调所有适当的 WebRTC 实现都将隐含地包括 FEC 和抖动缓冲 QoE 技术。15此外,Google 的 WebRTC(虚幻引擎的像素流系统使用的实现)还包括许多自定义丢包隐藏技术。16
前向纠错 (FEC)
前向纠错 (FEC) 是将冗余信息与流数据一起传输的过程,以便当数据包丢失时,此冗余信息可用作纠错码以恢复丢失的信息。17在实践中,这需要保留接收数据包的缓冲区,以便在检测到丢失数据包时,可以使用未来数据包来重建丢失的信息,而无需重新传输旧数据。18权衡是这些冗余纠错码增加了总传输大小。但是,应该注意的是,添加的冗余越多,FEC 在实践中的效果就越好。18可接受的冗余量很大程度上取决于底层网络的带宽能力。作为人们可以预期的那种丢失恢复的指标,一项真实世界的研究18表明,在 50% 的带宽开销下,基于 RTP 的 FEC 实施可以在丢包率约为 5-10% 的情况下恢复流数据。
自动重复请求 (ARQ)
自动重复请求 (ARQ) 是一种技术,其中接收方请求发送方在数据包丢失时重新传输数据包。19 ARQ 需要在接收端引入一个缓冲区来确定数据包是真的丢失还是只是乱序。19与 FEC 相比,ARQ 有两个主要缺点:
然而,与 FEC 不同,ARQ 不需要大量的额外传输带宽。此外,ARQ 能够从大量、连续的丢失数据包中恢复,这是 FEC 难以应对的情况。20我们强调,SRT 的创建者 Haivision 在其流式传输协议中使用 ARQ,因为“与其他纠错方法相比,它需要的带宽更少……并且仅在传输中引入了很小程度的延迟”。21
抖动缓冲
抖动缓冲只是在接收端维护一个缓冲区以存储传入数据包的过程。22用于在数据包乱序到达时对数据包进行重新排序,并提供接收端的恒定播放流。22抖动缓冲的缺点是延迟会直接增加缓冲区的大小。虽然固定大小的缓冲区更易于实现,但也可以(并且希望)根据最近的网络状况动态调整抖动缓冲区的大小。动态抖动缓冲区可以使用来自 RTCP 等协议的流统计信息来决定何时调整缓冲区大小。我们强调 FEC 和 ARQ 都包含抖动缓冲作为其实际实现的一部分。
丢包隐藏
数据包丢失隐藏实际上是一系列技术,其目的是决定在存在丢失数据包的情况下如何进行。与 FEC、ARQ 和抖动缓冲(它们是任何流数据的通用 QoE 技术)不同,数据包隐藏技术通常旨在通过利用音频和视频数据的属性来专门处理丢失的音频或视频数据包。例如,在一些音频流中,当数据包丢失时,使用了一种称为波形替换的技术,其中一些已经接收到的音频数据包被仔细地重复使用并拼接到接收到的音频中,以扩展当前的语音声音,直到接收到新的数据。23另一个例子是 Google Duo,它使用 WaveNetEQ 生成模型来插入由于数据包丢失而丢失的部分语音。24
正如我们在第 1 节中提到的,除了在虚幻引擎内部实现替代流传输协议之外,另一个选项是使用虚幻引擎现有的基于 WebRTC 的像素流传输到 WebRTC 网关/转发服务器。然后,该网关/转发服务器将 WebRTC 流转换为接收端可以理解的协议,例如 RTP,最后,网关/转发服务器将流传输到接收端。幸运的是,由于 WebRTC 的广泛采用,现有的网关/转发服务器可能适合此目的。我们在下面介绍了一些相关选项。
Janus
Janus 是一个用 C 语言编写的通用 WebRTC 服务器。它的设计使得基本的 Janus 应用程序占用空间小,并且大多数额外的功能是通过插件实现的。25为了通过其他协议转发 WebRTC 媒体,Janus 提供了一个“NoSIP”插件,充当“RTP 桥”,将媒体从 WebRTC 对等体中继到使用 RTP/RTCP 的接收器。26还有 Janus 插件“Videoroom” 27和“Janus-RTP-Forward-Plugin” 28由社区编写,这似乎也是可行的选择。我们强调 Janus 是开源的,并在 GPL 3.0 下获得许可。虽然 GPL 3.0 不兼容链接到虚幻引擎,但这可能不是问题,因为 Janus WebRTC 转发服务器将完全位于虚幻引擎之外。
Pion
Pion 是用 Go 编写的 WebRTC 实现,与 Google 的 WebRTC 不同,Pion 专门设计用于快速构建和定制。29虽然 Pion 并不是专门的 WebRTC 网关或服务器,但它确实包含一个“RTP-Forwarder”示例,说明如何将其用作将 RTP 数据包转发到其他地方的 WebRTC 对等体。30在实现方面,我们认识到 Go 不是可以从 Unreal Engine C++ 轻松调用的;但是,这应该不是问题,因为 Pion 将部署在 Unreal Engine 之外,并作为标准 WebRTC 对等体与 Pixel Streaming 进行通信。
其他选项
我们还研究了 GStreamer WebRTC 31和 Kurento WebRTC server 32,两者似乎都很合适,但在 WebRTC 到非 WebRTC 流转发方面的文档记录不如 Janus 或 Pion 少。此外,使用 Google 的 WebRTC 实现 WebRTC 转发服务器似乎也是可能的;但是,我们不建议采取这种做法,因为根据我们的经验,Google 的 WebRTC 很复杂,构建起来很耗时,而且更新也很重要。
在本节中,我们评估各种流解决方案在虚幻引擎中的实施的可行性、它们的一般优势和局限性,然后我们简要介绍我们对每种解决方案在不可靠网络中的表现的猜想。
具体来说,我们将通过讨论以下每个标准来探索每个协议的可行性:
虚幻引擎中的 UDP
UDP 流式传输可能是在虚幻引擎内部实现的最简单的选项;然而,它有几个限制,我们认为,这使它成为一个站不住脚的选择。使用 UDP 在虚幻引擎中实现视频和音频流不需要实现任何特定的协议或库,因为虚幻引擎已经支持 UDP 数据包的传输。33此外,使用 UDP 传输数据将缺乏其他传输协议所需的数据包开销。但是,纯UDP,是非常有限的;它不支持丢包、乱序交付或抖动。例如,即使在私有的、可靠的网络中,UDP 也可能会丢弃数据包或出现一些乱序传送。34例如,当我们考虑 H.264 编码视频在不可靠网络中的 UDP 传输时,丢包很可能导致视频流变得不可恢复。35我们认为,这些限制使纯 UDP 成为站不住脚的选择。然而,还有一些额外的技术可以在 UDP 流解决方案之上实现,例如 FEC 和抖动缓冲,这将在一定程度上缓解这些限制。但是,我们认为,如果使用缓解技术来克服 UDP 的内在属性,那么其他协议(例如 RTP)已经存在,并且由于它们的广泛采用,应该是首选。
虚幻引擎中的 RTP
RTP 是一种轻量级协议,可以使用内置的 UDP 传输 API 在虚幻引擎中实现。如果需要参考实现,我们建议学习 uvgRTP 36 37和Live555 38. 与纯 UDP 相比,RTP 的主要特点是 RTP 在其数据包中传输序列信息,以在发生乱序交付时帮助重建。但是,RTP 本身没有内置的 QoE 技术来实际解决乱序交付,这意味着如果需要诸如抖动缓冲或 FEC 之类的 QoE 技术,则必须由开发人员实施这些 QoE 技术。在没有实施额外 QoE 技术的可靠网络中,我们预计 RTP 的有效性与 UDP 大致相似。然而,随着 QoE 技术的实施,我们希望 RTP 在可靠的网络中有效运行。此外,在可靠的网络中,抖动缓冲区可以保持相对较小,从而最大限度地减少延迟。但是,在不可靠的网络中,RTP 需要 QoE 技术来提供功能性的实时流媒体体验。然而,我们强调,当在不可靠的网络中运行时,通常与 RTP、FEC 和抖动缓冲区配对的 QoE 技术将分别引入带宽和延迟的权衡。
虚幻引擎中的 RTP + RTCP
RTCP 旨在监控实时流并计算统计数据,然后用于动态修改 QoE 技术或动态调整源流。如果要在虚幻引擎中实现 RTCP,我们建议研究 Live555 中现有的 RTCP 库。38 39我们强调,要充分利用 RTCP,它也必须在接收端实现,这在某些黑盒系统中可能是不可能的。然而,假设 RTCP 在两端都实现并且 RTP 使用抖动缓冲,我们预计 RTCP 将通过允许抖动缓冲区根据网络条件动态调整大小来极大地提高不可靠网络的体验质量。与必须假定固定大小的纯 RTP 抖动缓冲区相比,我们希望 RTP + RTCP 解决方案随着网络条件的恢复而减少延迟。此外,即使不使用抖动缓冲,我们仍然希望 RTP + RTCP 在不可靠网络中产生比纯 RTP 更好的体验,因为可以使用来自 RTCP 的信息动态调整流的源质量。
虚幻引擎中的 RTSP
RTSP 是一种用于控制流媒体服务器的协议。6在实践中,它通常是一种瘦协议,将 RTP 和 RTCP 用于底层媒体流和控制消息。因此,我们认为在虚幻引擎中实现 RTSP 的实际优缺点与 RTP + RTCP 解决方案大致相同。因此,我们向读者推荐我们上面关于 RTP + RTCP 的评论。此外,在寻求 RTSP 的参考实现时,我们建议研究 Live555 38。
虚幻引擎中的 RTMP
RTMP 是广泛支持的基于 TCP 的协议,由 Macromedia/Adobe 7开发。就在虚幻引擎中实现 RTMP 而言,来自虚幻引擎的像素流系统的音频和视频流必须使用虚幻引擎的 TCP API 33以 RTMP 数据包格式进行分块和传输。我们建议研究 iReader 的媒体服务器以了解现有的 RTMP 实施。40 RTMP 的主要缺点是它使用 TCP 作为其底层传输,在不可靠的网络中,当重新传递尝试发生时,它会导致延迟膨胀。41
虚幻引擎中的 SRT
SRT 是由 Haivision 创建的基于 UDP 的低延迟流协议。10 SRT 是开源的,Haivision 为开发人员提供了一个生产就绪的 SRT 库。11要在虚幻引擎的像素流送系统中实现 SRT,我们建议将 Haivision 的 SRT 库合并到它自己的插件中,或者修改现有的像素流送插件以包含 SRT 库。SRT 的优势在于它专为跨不可靠网络的低延迟流式传输而设计,与其他基于 UDP 的协议(例如 RTP)不同,SRT 本身包含一种通过 ARQ 处理数据包丢失的机制。我们预见到使用 SRT 的解决方案的主要缺点是 SRT 相对较新,接收端的许多设备不太可能支持。
虚幻引擎中的 RIST
RIST 与 SRT 非常相似,它也是一个基于 UDP 的低延迟流协议。13与由私营公司创建的 SRT 不同,RIST 由视频服务集团创建,这是一个非营利组织,“由致力于媒体网络技术的互操作性、质量指标和教育的服务提供商、用户和制造商组成”。42要实施 RIST,我们建议将官方 RIST 库librist 12合并到其自己的插件中,或将其包含在现有的 Pixel Streaming 插件中。与 SRT 非常相似,实施使用 RIST 的解决方案的主要缺点是它相对较新,不太可能被接收端的许多设备支持。
虚幻引擎 → WebRTC 桥 → 非 WebRTC 接收器
此解决方案涉及利用虚幻引擎中现有的像素流式传输系统流式传输到自定义 WebRTC 桥接器,然后使用广泛支持的流式传输协议(例如 RTP、RTSP)将从虚幻引擎接收到的视频和音频转发到某个任意非 WebRTC 接收器, 或 RTMP。现有的 WebRTC 流媒体服务器包括 Janus 25和 Wowza 流引擎43;但是,如果除了简单地转发流之外还有特定要求,基于 Go 的 WebRTC 库 Pion 29也是一种选择。
该解决方案的优势在于它不需要对虚幻引擎或像素流式处理插件进行修改,并将流式传输的需求转移到虚幻引擎之外的其他协议。此外,WebRTC 桥接器的部署,尤其是在其自己的硬件上,比直接从虚幻引擎流式传输更具可扩展性,同时还消除了与虚幻引擎像素流式传输应用程序进行资源竞争的可能性。此外,由于 WebRTC 是底层流技术,如果配置正确,这种方法继承了 WebRTC 的所有低延迟、高弹性和属性。
相反,此解决方案的缺点是它需要另一个组件,可能在其自己的硬件上运行。此外,当流通过 WebRTC 桥转发时,这种方法可能会引入一些延迟。此外,如果 WebRTC 桥接器与接收器不在同一个本地网络中,则此方法将继承与选择从 WebRTC 桥接器流式传输到非 WebRTC 接收器的任何协议相同的质量。
根据第 3 节,有一些解决方案可以忽略我们的建议,因为它们不能满足我们确保与旧版和/或黑盒流客户端兼容的目标。具体来说,应该忽略 SRT 和 RIST,因为它们可能与大多数传统流接收器不兼容。此外,还不清楚 RTSP 是否比在 Unreal Engine Pixel Streaming 场景中简单地实现 RTP 和 RTCP 有任何好处;因此,它也可以忽略不计。最后,纯 UDP 流解决方案可能会出现丢包问题,即使在专用网络中也是如此,因此我们也将忽略它。
因此,我们认为 RTP、RTP + RTCP、RTMP 或 WebRTC 转发桥是支持从虚幻引擎的像素流系统到非 WebRTC 接收器的流式传输的最可行的解决方案。然而,在这四个选项中,WebRTC 转发桥是我们推荐的解决方案。
我们认为,与 WebRTC 转发桥相比,RTP、RTP + RTCP 和 RTMP 解决方案都有一个主要缺点。也就是说,如果需要在较差或变化的网络条件下保持稳定性,那么这些协议本身并不能提供解决方案。RTP和RTP+RTCP可以通过FEC、丢包隐藏、抖动缓冲来解决这些问题;但是,这在某种程度上必须在两端实现,这是一项不平凡的任务,如果接收端是黑盒或不可修改的遗留系统,这可能是一项不可行的任务。然而,WebRTC 转发桥获得了 WebRTC 固有的所有低延迟和较差的网络弹性。我们强调,为了最大限度地利用 WebRTC 的这些优势,我们建议在与非 WebRTC 接收器相同的本地网络中安装 WebRTC 转发桥。如果 WebRTC 转发桥与非 WebRTC 接收器不在同一个网络中,那么该解决方案将面临与底层转发协议(例如 RTP、RTMP)相同的缺点。
此外,即使在不关心网络条件差或变化的稳定性的情况下,我们仍然建议使用 WebRTC 转发桥。WebRTC 转发桥是唯一不需要对虚幻引擎进行任何修改的解决方案。这缓解了几个问题,包括:随着虚幻引擎源代码发生变化而更新解决方案的维护成本、与虚幻引擎的许可冲突以及在虚幻引擎中集成第三方库的复杂性。此外,它是唯一完全在虚幻引擎之外运行的解决方案,因此更具可扩展性。
为了证明该解决方案的可行性,我们提供了一个概念验证,使用 Pion WebRTC 将 RTP 流从虚幻引擎的像素流系统转发到非 WebRTC 接收器(在本例中为 FFplay)。此概念证明可在这个网址找到。
原文链接:虚幻引擎流送方案调查报告 — BimAnt