對於 WebRTC 串流,不是只能用在網頁對網頁撥話,也可以嘗試從不同的裝置或應用程式將串流與網頁的介面進行溝通及串流,本篇文章是它的其中一個應用。
從上一篇 WebRTC(1) 的文章中,我們已經具備 WebSocket 的 Signaling 的功能、網頁也有撥接功能,現在,希望從 Unity 中將攝影機串流出來。
直接打開 Unity Render Streaming 這個專案:
https://github.com/Unity-Technologies/UnityRenderStreaming
這個專案本身有提供自己的 WebRTC Server 跟網頁端互動的格式,不過因為我們在上一篇文章是自幹 WebRTC SDP/Candidate Sending, 所以對於這個專案,網頁上也需要調整一下格式符合這個專案的 Format。
Signaling: 就是 Client 端透過 WebSocket 或其他方式把 SDP/Candidate 傳給其他人的步驟,其他人收到對方的 Signaling,才能互相開啟 WebRTC 通訊。 (先前做 Signaling 都是網頁端用 WebSocket 互傳)
相較上一個專案,Unity Render Streaming 專案中的 Signaling 格式是 (網頁端要改):
{ from: "[我是誰]", to: "", type:"[offer / answer]", data:{原來的 sdp } }
這個格式是從原本官方對自己的 WebRTC Signaling Server 傳訊息,觀察到的結果:
1-1 網頁與 Unity 單邊通訊
網頁端只想接收,不想發送攝影機訊息,Unity 只需要傳送攝影機訊息,其他簡易溝通可以透過 WebSocket 實現。
撥號者預設是網頁端,也就是說,想看串流的時候,是從網頁端撥號, Unity 無條件接聽,把自己的訊號傳送出去。
必要的 Server 架設:
- WebSocket Server (上一篇文章有提到該 golang 程式,繼續使用)
- TURN Server
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> <script src="https://webrtc.github.io/adapter/adapter-latest.js" type="application/javascript"></script> </head> <body style="background-color: #e2e2e2; font-family: 微軟正黑體;"> <button id="call" style="font-size: 24px;padding: 5px 15px;">Call</button> <h1>Unity Scene</h1> <video id="remoteView" width="1280px" height="760px" autoplay muted style="position: absolute;z-index: -1;margin-top: -20px;"></video>
<script> let ws = new WebSocket('ws://192.168.50.152:8899/boradcast') const configuration = { sdpSemantics : 'unified-plan', //改用 unified-plan 格式 iceServers: [ //{urls: "stun:23.21.150.121"}, {urls: "stun:stun.l.google.com:19302"}, /*{ urls: "turn:192.168.50.152:3478?transport=tcp", username: "mac", credential:"123", } // TURN Server address*/ ] }; var pc; function start() { pc = new RTCPeerConnection(configuration); // send any ice candidates to the other peer pc.onicecandidate = function (evt) { //no need to send candidate data //ws.send(JSON.stringify({"candidate": evt.candidate})); }; // once remote stream arrives, show it in the remote video element pc.ontrack = function (evt) { console.log("add remote stream"); console.log(evt); remoteView.srcObject = evt.streams[0]; console.log("收到遠端串流") }; //不開攝影機,告知只想收視 //https://stackoverflow.com/questions/31259205/can-i-send-a-video-stream-even-if-the-user-does-not-have-a-webcam pc.createOffer( { offerToReceiveAudio: true, offerToReceiveVideo: true } ).then((desc)=>{ let wsobjectdata = {}; wsobjectdata.from = "WebBrowser_[NO_UUID]"; wsobjectdata.to = ""; wsobjectdata.type = "offer"; wsobjectdata.data = desc; pc.setLocalDescription(desc); ws.send(JSON.stringify(wsobjectdata)); }); } call.addEventListener('click', ()=> { console.log('webrtc start'); start(); }); sendInstruction.addEventListener('click', ()=>{ var sigCanvas = document.getElementById("canvasSignature"); var context = sigCanvas.getContext("2d"); ws.send(JSON.stringify({'type':'image_instruction', 'data' : { 'message' : document.getElementById("canvasSignature").toDataURL()} })); context.clearRect(0, 0, sigCanvas.width, sigCanvas.height); }) ws.onopen = () => { console.log('open connection') } ws.onclose = () => { console.log('close connection') ws = new WebSocket('ws://192.168.50.152:8899/boradcast') console.log('reconnect') } ws.onmessage = (event) => { console.log('event-data',event.data) let data = JSON.parse(event.data) if (data.data.sdp) pc.setRemoteDescription(new RTCSessionDescription(data.data)); else if (data.data.candidate) pc.addIceCandidate(new RTCIceCandidate(data.data)); }; </script> </body> </html>
Unity 上的設定,可以直接打開專案中的範例場景,找到 RenderStreaming 物件,把 websocket signal 打開, ice server 資訊填上跟網頁上一樣的。
注意事項:
- 如果是要用官方的 WebRTC Server 而且你要用 websocket signaling,那開啟 server 指令要用: webserver.exe -w (打開 websocket 模式)
- 這個東西無法放在手機,只能在 x86 平台,原因有下:
- RenderStreming 是用 HDRP
- Streaming Codec 還是需要硬體支援
Reference:
https://github.com/Unity-Technologies/UnityRenderStreaming/blob/develop/WebApp/src/index.ts
https://blogs.unity3d.com/2019/09/17/stream-high-quality-real-time-graphics-through-your-browser-with-our-new-webrtc-framework/
https://github.com/Unity-Technologies/UnityRenderStreaming/blob/97949e2bc469ef17eca5577f561a23cdd0efa7bb/WebApp/public/scripts/sendvideo.js#L97
https://github.com/Unity-Technologies/UnityRenderStreaming/blob/97949e2bc469ef17eca5577f561a23cdd0efa7bb/WebApp/public/scripts/signaling.js
https://github.com/Unity-Technologies/UnityRenderStreaming/blob/develop/WebApp/src/websocket.ts
https://docs.unity3d.com/Packages/[email protected]/manual/en/videostreaming.html
https://codertw.com/%E7%A8%8B%E5%BC%8F%E8%AA%9E%E8%A8%80/542995/
https://webrtc.org/getting-started/unified-plan-transition-guide
https://github.com/Unity-Technologies/UnityRenderStreaming/blob/97949e2bc469ef17eca5577f561a23cdd0efa7bb/WebApp/public/scripts/video-player.js
沒有留言:
張貼留言