@feige0629/unity-render-streaming 使用
本包只是React客户端,需要配合 定制的 webserver 服务端进行使用
Tips:需要React客户端源码+本客户端定制的服务端源码,可加微信,备注来意
微信:feige0629
说明
Unity Render Streaming是Unity官方推出的一套云渲染解决方案,可以实现将我们打包的.exe程序运行于服务器云端,在浏览器、移动端进行显示,该解决方案基于Google开发的WebRTC流技术,以及Unity官方推出的新的输入系统Input System来实现,主要用于三端通信,客户端(本React端为客户端)、服务器端、 unity.exe程序。
1、安装
npm install @feige0629/unity-render-streaming
yarn add @feige0629/unity-render-streaming
2、本包封装了2个React组件
// 1、这是从 Unity 接收视频/音频的示例。可以结合BroadcastUnity Render Streaming的场景使用。
<Receiver websocketUrl= 'ws://127.0.0.1:7000' autoPlay={true} style={{width:600, height:400}} />
// 2、这是一个示例,用于接收在 Unity 上渲染的相机图像。您可以通过浏览器在 Unity 中操作相机。可以结合WebBrowserInputUnity Render Streaming的场景使用。WebApp 必须在公共模式下运行。
<Videoplayer websocketUrl= 'ws://127.0.0.1:7000' autoPlay={true} style={{width:600, height:400}} />
3、Videoplayer Demo 使用方法
import { useRef, useState } from 'react';
import '../App.css'
import { Videoplayer, VideoplayerRef } from '../webserver';
function VideoDemo()
{
const receiverRef = useRef<VideoplayerRef>(null);
const [autoPlay, setAutoPlay] = useState<boolean>(true); //是否自动播放
// 播放视频
const playButton = ()=>{
receiverRef.current!.playVideo();
setAutoPlay(true);
}
// 加载完成
const onComplate = (videoRef: HTMLVideoElement, videoPlayer: any) => {
console.log('加载完成:',videoRef, videoPlayer);
}
return (
<div id="container">
<h1>VideoPlayer Sample</h1>
<div id="video-container">
<Videoplayer ref={receiverRef} websocketUrl= 'ws://127.0.0.1:5173/video' onComplate={onComplate} autoPlay={autoPlay} style={{width:600, height:400}} />
{
!autoPlay &&
<div id="player">
<button id="playButton" onClick={playButton}>播放</button>
</div>
}
</div>
</div>
);
}
export default VideoDemo;
4、Receiver Demo 使用方法
import { useRef, useState } from 'react';
import '../App.css'
import { Receiver, ReceiverRef } from '../webserver';
function ReceiverDemo()
{
const receiverRef = useRef<ReceiverRef>(null);
const [autoPlay, setAutoPlay] = useState<boolean>(true); //是否自动播放
const [show, setShow] = useState<boolean>(false);
const [websocketUrl, setWebsocketUrl] = useState<string>('ws://127.0.0.1:5173/ws');
// 播放视频
const playButton = ()=>{
receiverRef.current!.playVideo();
setAutoPlay(true);
}
// 发送消息
const sendMessageButton = ()=>{
receiverRef.current!.sendMessage(JSON.stringify({"MessageType":"1", "Content":"测试数据"}));
}
// 监听消息
const onMessage = (msg:MessageEvent) => {
console.log(`Receive Msg:`, msg.data, msg);
}
// 加载完成
const onComplate = (videoRef: HTMLVideoElement, videoPlayer: any, renderstreaming: any) => {
setShow(true);
console.log('加载完成:',videoRef, videoPlayer, renderstreaming);
}
// 结束链接
const onDisconnect = ()=>{
console.log('结束');
}
return (
<div id="container">
<h1>Receiver Sample - {show ? '加载成功' : '启动中...'}</h1>
<div id="video-container">
<Receiver ref={receiverRef} config={{
iceServers : [
{
urls: ['turn:xxx.xxx.xx.xx:3478?transport=udp'],
username: 'admin',
credential: '123456'
}
]
}} onMessage={onMessage} websocketUrl={websocketUrl} onDisconnect={onDisconnect} onComplate={onComplate} autoPlay={autoPlay} style={{width:600, height:400}} />
{
!autoPlay &&
<div id="player">
<button id="playButton" onClick={playButton}>播放</button>
</div>
}
</div>
{ autoPlay && <button id="sendButton" onClick={sendMessageButton}>发送数据</button> }
<button id="sendButton" onClick={()=>setWebsocketUrl('ws://127.0.0.1:5173/ws')}>本地websocketUrl</button>
<button id="sendButton" onClick={()=>setWebsocketUrl('ws://127.0.0.1:5173/fwq')}>服务器websocketUrl</button>
</div>
);
}
export default ReceiverDemo;
5、API
参数 | 说明 | 类型 | 默认值 | 适用组件 |
---|---|---|---|---|
autoPlay | 自动播放 | boolean | true | Receiver, Videoplayer |
style | 自定义样式 | CSSProperties | - | Receiver, Videoplayer |
className | className属性 | string | - | Receiver, Videoplayer |
config | 配置 | { logging?: string; startupMode?: string; useWebSocket?: boolean; sdpSemantics?: string; iceServers?: { [key:number]:{ urls: string[], username?: string, credential?: string } }[]; } | { logging: "dev", startupMode: "public", useWebSocket: true, sdpSemantics:'unified-pla', iceServers : [{ urls: ['stun:stun.l.google.com:19302'] }],username: 'admin', credential: '123456' } | Receiver, Videoplayer |
websocketUrl | websocket协议地址, config.useWebSocket为true启用 | string | location.protocol === "https:" ? "wss://" + location.host : "ws://" + location.host | Receiver, Videoplayer |
signalingOrigin | signaling协议地址, config.useWebSocket为false启用 | string | location.origin | Receiver, Videoplayer |
onMessage | 监听服务器端消息 | (msg: MessageEvent) => void | - | Receiver |
onStatsMessage | 监听video状态数据 | (msg: statsType[]) => void | - | Receiver |
onComplate | 加载完成,renderstreaming只在Receiver组件返回 | (videoRef: HTMLVideoElement, videoPlayer: any, renderstreaming: any) => void | - | Receiver, Videoplayer |
onDisconnect | 关闭回调 | - | - | Receiver, Videoplayer |
6、方法
名称 | 描述 | 适用组件 |
---|---|---|
sendMessage | 发送消息(message: string) | Receiver |
playVideo | 播放视频 | Receiver, Videoplayer |
disconnect | 调用关闭 | Receiver, Videoplayer |
7、外网服务器部署
对于大多数 WebRTC 应用,服务器都需要在对等设备之间中继流量,因为在客户端之间通常无法实现直接套接字(除非这些应用在同一个本地网络中)。解决此问题的常见方法是使用TURN 服务器。术语表示使用中继 NAT 的遍历,是一种中继网络流量的协议。
参考Unity文档中TURN 服务器设置
https://docs.unity3d.com/Packages/com.unity.renderstreaming@3.1/manual/turnserver.html
TURN服务器使用的端口需要公开,可设置最大最小值
协议 | 端口 |
---|---|
TCP | 32355-65535、3478-3479 |
UDP | 32355-65535、3478-3479 |