PixelStreaming数据通信

  • 简介
  • H5到UE4通信
    • H5发送
    • UE4接收
  • UE4到H5通信
    • UE4发送
    • H5接收
  • iframe + postMessage
    • 父页面
    • 子页面(改造UE4提供的像素流送H5)
  • UE4项目bat启动器
  • 问题
    • * UE4.26像素流送,使用Chrome94版崩溃问题
    • * UE4像素流送多个鼠标问题(Web启用了HoverMouse模式,UE4勾选了ShowMouseCursor)
    • * UE4.27 setup.ps1无法运行此脚本
    • * exe窗口与像素流送分别设置不同的分辨率
    • * UE4.27之后的版本默认无法动态更改VideoResolution (控制台命令SetRes导致VideoFrame拉伸)

简介

  1. 使用UE4.26像素流送方案,启动像素流送插件
  2. UE4编辑器设置中添加运行参数与打包后exe快捷方式添加命令行参数 -AudioMixer -RenderOffScreen -PixelStreamingIP=localhost -PixelStreamingPort=8888 -PixelStreamingHideCursor -Log
    r.setres超过屏幕分辨率无效:需加快捷方式最后处添加参数 NvEncH264ConfigLevel=NV_ENC_LEVEL_H264_52。
参数 描述
AllowPixelStreamingCommands 决定播放器网页是否能使用 emitCommand() 函数在虚幻引擎中远程执行控制台命令。注意这可能涉及安全问题,请谨慎处理。
-AudioMixer 强制虚幻引擎使用软件混合音频,以便像素流送插件采集音频。从应用程序采集音频并流送到浏览器需要用到此参数。
-PixelStreamingIP=< value > 必需
-PixelStreamingPort=< value > 必需
-PixelStreamingKeyFilter=“< value >” 像素流送插件应从播放器网页中继至虚幻引擎的输入中过滤掉的键盘键的列表,以逗号分隔。如果在浏览器中按下其中一个键,此事件将不会被中继至虚幻引擎的输入控制器。举例而言,-PixelStreamingKeyFilter=“F1…F12,W,A,S,D” 将过滤掉所有12个功能键和移动键。
-PixelStreamingReceiveStringMaxLength 设置虚幻引擎应用从信令和网页服务器接收的信息的最大长度,以字节为单位。默认值为 1024。
-RenderOffScreen 以headless模式运行虚幻引擎应用程序,本地机上不带任何可见的渲染。应用程序不会显示任何窗口,也不会以全屏渲染。可使用此参数结合 -ForceRes 使虚幻引擎停止基于主显示分辨率自动调整分辨率。如遗漏此参数,虚幻引擎应用程序窗口将正常渲染。如果此应用程序窗口被最小化,像素流送视频和输入采集将停止工作。因此我们推荐固定包含此参数,除非需要在运行时在同一台电脑上本地查看虚幻引擎应用程序的渲染输出。
-NvEncFrameRateNum=< value > 指定后,覆盖默认的编码器帧率。默认值设为匹配 t.MaxFPS。
-NvEncMaxEncodeWidth=< value > 编码器可编码的帧的最大宽度。默认值为 3840。
-NvEncMaxEncodeHeight=< value > 编码器可编码的帧的最大高度。默认值为 2160。
-NvEncAverageBitRate=< value > 指定后,覆盖编码器的默认平均比特率。
-NvEncH264ConfigLevel=< value > 决定H.264的压缩级别:5.2或5.1。如果不设置此参数,解码器将使用5.2级别,可以解码高清分辨率,如3840x2160(4K)。 如果要解码较低的分辨率,可以将此参数设置为 NV_ENC_LEVEL_H264_51 以切换到5.1级别,以节省带宽。 如需了解H.264等级的更多内容,请参阅此页面。如果虚幻引擎应用程序报告其 未能初始化NvEncoder,且正在处理高分辨率输出,则可能需要移除此选项,将压缩级别恢复到5.2。
  1. 复制出引擎目录下的WebServers文件夹
    E:\Program Files\Epic Games\UE_4.26\Engine\Source\Programs\PixelStreaming\WebServers
  2. 修改WebServers\player.htm内容
  3. 运行WebServers\SignallingWebServer\run.bat
  4. UE4编辑器独立运行游戏
  5. 测试像素流送

H5到UE4通信

H5发送

  1. emitCommand 可向游戏发送命令的预设列表、更改分辨率、执行控制台命令,或是降低编码器的码率。

    //显示fps
    let descriptor = {ConsoleCommand: 'stat fps'}//重置虚幻引擎程序的渲染分辨率
    let descriptor = {
    Resolution: {Width: 1024,Height: 768
    }}//控制媒体流的质量,此值默认为50%.如部署中出现延迟和视频瑕疵,可进一步降低该值
    let descriptor = {
    Encoder: {BitrateReduction: 20
    }}
    
  2. emitUIInteraction 可向游戏发送任意字符串或JavaScript对象。使用此功能将自定义命令从播放器UI处发射,用户可在gameplay逻辑中响应此类命令以在程序中产生所需效果。
    //传递单个字符串
    emitUIInteraction("MyCustomCommand");//传递JavaScript对象,emitUIInteraction 函数会在内部将其转换为JSON字符串
    let descriptor = {LoadLevel: "/Game/Maps/Level_2",PlayerCharacter: {Name: "Shinbi",Skin: "Dynasty"}}
    emitUIInteraction(descriptor);
    

UE4接收

在程序的gameplay逻辑中,使用 Bind Event to OnPixelStreamingInputEvent 节点绑定自定义事件来处理此类输入。

UE4到H5通信

UE4发送

要将事件发射到播放器页面时可使用 Pixel Streaming > Send Pixel Streaming Response 节点。将自定义字符串参数指定到节点,向播放器页面说明发生的事件内容。

H5接收

  1. JavaScript中编写自定义事件处理器函数,每当页面从虚幻引擎程序接收到响应事件时将调用该函数。

    //显示fps
    function myHandleResponseFunction(data) {
    console.warn("Response received!");switch (data) {case "MyCustomEvent":... // handle one type of eventcase "AnotherEvent":... // handle another event}
    }
    
  2. 调用 app.js 提供的 addResponseEventListener 函数来注册监听器函数。为事件监听器和函数向此函数传递一个独特命名。
      addResponseEventListener("handle_responses", myHandleResponseFunction);
    
  3. 如需移除事件监听器,可调用 removeResponseEventListener 并传递相同命名。
    removeResponseEventListener("handle_responses");
    

iframe + postMessage

  • 修改app.js(UE4提供的像素流送Web项目文件)
var isStart = false;webRtcPlayerObj.onDataChannelConnected = function () {if (ws && ws.readyState === WS_OPEN_STATE) {showTextOverlay('WebRTC connected, waiting for video');setTimeout(()=>{isStart = true;<!-- 其他代码省略 -->}, 500); }};

父页面

<!DOCTYPE html>
<html lang="zh-CN">
<head><meta charset="utf-8"><style type="text/css">iframe {width: 960px;height: 540px;}</style></head>
<body><button id="button">给子页面发消息</button><iframe id="iframe" src="http://127.0.0.1:81"></iframe><script>window.addEventListener('message', e=> {console.log(e.data)});var button = document.getElementById('button');let iframe = document.getElementById('iframe');button.onclick = function(){<!-- iframe.contentWindow.postMessage('hello from parent', 'http://127.0.0.1:80') -->iframe.contentWindow.postMessage('hello from parent', '*')}
</script>
</body>
</html>

子页面(改造UE4提供的像素流送H5)

<!DOCTYPE HTML>
<html>
<head><link rel="shortcut icon" href="/images/favicon.ico" type="image/x-icon"><link rel="icon" type="image/png" sizes="96x96" href="/images/favicon-96x96.png"><link rel="icon" type="image/png" sizes="32x32" href="/images/favicon-32x32.png"><link rel="icon" type="image/png" sizes="16x16" href="/images/favicon-16x16.png"><link type="text/css" rel="stylesheet" href="player.css"><script type="text/javascript" src="scripts/adapter-latest.js"></script><script type="text/javascript" src="scripts/webRtcPlayer.js"></script><script type="text/javascript" src="scripts/app.js"></script></head><body onload="load()"><div id="playerUI"><div id="player"></div><div id="overlay" class="overlay"><div><div id="qualityStatus" class="greyStatus">&#9679</div><div id="overlayButton">+</div></div><div id="overlaySettings"><div id="KickOthers"><div class="settings-text">Kick all other players</div><label class="btn-overlay"><input type="button" id="kick-other-players-button" class="overlay-button btn-flat" value="Kick"></label></div><div id="FillWindow"><div class="settings-text">Enlarge Display to Fill Window</div><label class="tgl-switch"><input type="checkbox" id="enlarge-display-to-fill-window-tgl" class="tgl tgl-flat" checked><div class="tgl-slider"></div></label></div><div id="QualityControlOwnership"><div class="settings-text">Quality control ownership</div><label class="tgl-switch"><input type="checkbox" id="quality-control-ownership-tgl" class="tgl tgl-flat"><div class="tgl-slider"></div></label></div><div id="statsSetting"> <div class="settings-text">Show Stats</div><label class="tgl-switch"><input type="checkbox" id="show-stats-tgl" class="tgl tgl-flat" checked><div class="tgl-slider"></div></label><div id="statsContainer"><div id="stats"></div></div></div></div></div></div>
<script>inputOptions.controlScheme = ControlSchemeType.HoveringMouse;<!-- inputOptions.fakeMouseWithTouches = true; -->styleAdditional = 'cursor: default; cursor: -moz-default; cursor: -webkit-default';function SendMessage(data){emitUIInteraction(data);};function SendJsonMessage(data){if(!isStart)return;let jsonStr = JSON.stringify(data); //.replace(/[\\]/g,'')console.log(jsonStr);emitUIInteraction(jsonStr);};function HandleResponse(data) {if(!isStart)return;console.log("-------------UE4_To_H5Parent-----------------");top.postMessage(data, '*');console.log(data);};addResponseEventListener("handle_responses", HandleResponse);window.addEventListener('message',function(event){if(!isStart)return;console.log("-------------H5Parent_To_UE4-----------------");console.log(event.data);emitUIInteraction(event.data);}, false);
</script>
</body>
</html>

UE4项目bat启动器

UE4项目打包目录下创建Run.bat代替创建exe快捷方式(以便其他电脑上运行也有效)
注:Demo.exe根据实际名修改

@echo off
cd %~dp0
start Demo.exe -AudioMixer -RenderOffScreen -PixelStreamingIP=localhost -PixelStreamingPort=8888 -Log
exit

问题

* UE4.26像素流送,使用Chrome94版崩溃问题

解决办法:添加一行代码

offer.sdp = offer.sdp.replace(/(a=extmap-allow-mixed)\r\n/gm, "");

* UE4像素流送多个鼠标问题(Web启用了HoverMouse模式,UE4勾选了ShowMouseCursor)

解决办法1:
快捷方式添加 -PixelStreamingHideCursor
解决办法2:
1.隐藏UE4像素流送模式下的光标:UE4的ProjectSettings -> PixelStreaming -> DefaultCursorClass使用HiddenCursor

2.SignallingWebServer鼠标模式设置
// player.htm内容设置鼠标模式 inputOptions.controlScheme = ControlSchemeType.HoveringMouse; styleAdditional = 'cursor: default; cursor: -moz-default; cursor: -webkit-default';

* UE4.27 setup.ps1无法运行此脚本

解决办法:
管理员运行Windows PowerShell执行命令,Y确认
set-ExecutionPolicy RemoteSigned //Y确认 ./setup.ps1 //回车安装

* exe窗口与像素流送分别设置不同的分辨率

解决办法:PlayerController的BeginPlayer中执行控制台命令

PixelStreaming.Capturer.UseBackBufferSize false
PixelStreaming.Capturer.CaptureSize 960x540

* UE4.27之后的版本默认无法动态更改VideoResolution (控制台命令SetRes导致VideoFrame拉伸)

解决办法:DRC 0

PixelStreaming数据通信相关推荐

  1. dac生成信号频率取决于_DAC和AOC,谁将是数据通信领域最终赢家?

    如今竞争激烈的通信行业,大家都期望获得竞争优势,无论是在性能方面.效率方面还是成本方面.虽然许多数据中心的整改侧重于网络适配器和交换机配置,但有一种极其基础.却同样有效的方法可以改进部署的数据中心,那 ...

  2. Node.js权威指南 (7) - 实现基于TCP与UDP的数据通信

    7.1 使用net模块实现基于TCP的数据通信 / 136 7.1.1 创建TCP服务器 / 136 7.1.2 socket端口对象 / 142 7.1.3 创建TCP客户端 / 151 7.1.4 ...

  3. 计算机网络——数据通信过程

    数据通信是指在两点或多点之间以二进制的形式进行信息交换.数据传输+通信控制. 数据通信的过程是把字符或符号转换成编码,产生与编码对应的信号,信号传送到目的地后被接受设备接收,按编码的规则将信号解码,再 ...

  4. 数据通信技术_华为数据通信创新峰会在长春圆满举行

    9月11日,以"激发联接的潜能"为主题的华为数据通信创新峰会2020在长春召开.会上,华为不仅分享了引领智能IP网络的的理念和实践进展,还展示了新基建新形势下,华为如何用技术能力适 ...

  5. Git命令家底儿及Git数据通信原理详解

    声明:本文为CSDN原创投稿文章,未经许可,禁止任何形式的转载. 作者:周立伟(花名:华序,ITeye博客),关注分布式.高并发和Java中间件的研究. 责编:钱曙光,关注架构和算法领域,寻求报道或者 ...

  6. 【计算机网络】物理层 : 数据通信 ( 数据通信模型 | 信源 | 信宿 | 信道 | 通信方式 | 单工 | 半双工 | 全双工 | 数据传输方式 | 串行 | 并行 )

    文章目录 一.数据通信模型示例 二.数据通信模型 三.数据通信模型 分类 四.数据通信 术语 五.三种通信方式 六.数据传输方式 一.数据通信模型示例 数据通信模型 示例 : ① 通信场景 : 两台计 ...

  7. 利用邮箱实现数据通信

    文章目录 1 利用邮箱实现数据通信 1 利用邮箱实现数据通信 问题分析: 解决方案: 使用邮箱完成数据传递和同步功能. 消息通信分析: 示例代码: /*** @brief tOS应用示例* @deta ...

  8. 利用全局数据实现数据通信

    文章目录 1 利用全局数据实现数据通信 1 利用全局数据实现数据通信 问题分析: 解决方案: 示例代码: /*** @brief tOS应用示例* @details* @author 01课堂 李述铜 ...

  9. 以太网数据帧的报尾封装字段是什么_利用TCP/IP模型理解数据通信过程

    回顾TCP/IP模型 TCP/IP模型是当今IP网络的基础(由OSI七层参考模型发展而来,也称为DoD模型). 分层参考模型的设计是非常经典的理念: 层次化的模型设计将网络的通信过程划分为更小.更简单 ...

最新文章

  1. 利用FLASH和XML做炫酷图片相册
  2. centos普通用户设置sudo权限
  3. Java 技术篇-使用poi开源jar包实现读取excel实例演示,poi-3.17.jar获取
  4. python常见异常
  5. 2020年下信息系统项目管理师合格分数线通知
  6. 让智能家居产品操控更简单 快捷键来了
  7. Idea+Maven+Jersey2+Tomcat配置Web服务
  8. mutex_lock
  9. P2012-拯救世界2【EGF】
  10. 【渝粤题库】陕西师范大学202321投资银行学 作业(专升本)
  11. mac 批量清空文件夹文件_【XSS 聚宝瓶】文件及文件夹批量改名工具
  12. java tostring格式_如何在Java中使用toString()获得数字的字符串表示形式?
  13. python 2.7和3.6区别_Windows Python 2.7 和 Python 3.6 共存方法
  14. git clone error port 443: Timed out
  15. 从零开始学ios开发(十三):Table Views(下)Grouped and Indexed Sections
  16. 23种设计模式-备忘录模式
  17. 《Google Go: A Primer》学习笔记
  18. mysql随机抽样方法_MySQL中随机抽样
  19. 【javaEE】——多线程进阶(锁策略:面试相关考点)04
  20. 智能音箱全国产化电子元件推荐方案

热门文章

  1. matlab 多通滤波,带通滤波 matlab
  2. HTTP状态码一共分5种类型
  3. Docker超详细基础教程
  4. JDBC学习笔记(六)
  5. Hibernate的clear(),flush(),evict()方法详解
  6. 彻底搞懂回溯法(本文真的很详细)
  7. caffe 以及caffe2 安装时portobuf库相关的编译问题
  8. django orm mysql_django指定mysql数据库 ORM查询
  9. 中国人最常说的‘中国式英语’
  10. 【Linux】find命令详解