Starting everything up
What actually runs
A streamed kiosk runs three processes. Knowing their names helps, because when something fails, it is almost always obvious which one is responsible:
-
Unreal — your packaged application. It renders the avatar and sends video out.
-
The signalling server — a small Node application. It introduces the browser and Unreal. Once introduced, video flows directly between them instead of going through the server. This same server also serves the page the big screen displays.
-
A tunnel, only if the kiosk has no public address of its own. We use ngrok.
The operator tablet is not in this list. Unreal serves the tablet page itself, on its own port, so nothing extra runs for it.
On-site deployments run none of this. If Unreal is on the machine driving the screen, it renders straight to the display and there is no server, no tunnel and no relay. This page is for streamed layouts.
Where the servers are
The signalling server is not part of the plugin — Epic’s PixelStreaming2 ships no servers at all.
A known-good copy is included with this plugin at
PromethistLinkPixelStreaming/Samples/WebServers, and it runs from wherever you put it.
There are two steps the first time:
-
Run
SignallingWebServer\platform_scripts\cmd\setup.bat. It downloads a private copy of Node and coturn. They are deliberately omitted from the repository, so nothing starts until you do this. -
Start the server with
SignallingWebServer\platform_scripts\cmd\start_with_stun.bat.
This provides a running server with Epic’s defaults. It is enough to prove the pieces can talk to each other, but it is not what you want on a real kiosk.
The flags that matter
Everything a kiosk needs is a command-line flag on that same script. Rather than describe them
twice, we ship the launcher we use ourselves:
PromethistLinkPixelStreaming/Samples/Examples/signalling_server.bat.
It consists almost entirely of comments, which explain why each flag is there:
-
--peer_options_file turn.json— points both the browser and Unreal at your TURN relay. See Do you need a TURN relay? before assuming you need one. -
--turn_secret_file— mints fresh TURN credentials per connection instead of a shared password. -
--player_token_file— refuses viewers who do not present a token. See Locking the control channel. -
--max_players 1— a kiosk has one screen. -
--media_proxy— serves the agent’s images through the server, resized and paced. Without it, the first seconds of a session can arrive with the video lagging the audio. -
--homepage— which page the server serves.
Start from that file rather than Epic’s defaults, and delete what you do not need.
What order, and how to tell it worked
Start the signalling server first, then Unreal. Unreal retries, so the reverse order also works, but this way the logs read in the order things happened.
The server prints its listening ports as soon as it starts — one for the Unreal streamer, one for viewers. When Unreal connects, the server logs the streamer arriving. If you never see that line, the fault lies between Unreal and the server, and no amount of browser reloading will fix it.
If a browser connects and gets audio but no picture, or a picture that never arrives, the introduction worked but the media path failed. That is the TURN relay question, not a signalling problem.
Two files you create yourself, and never commit
The launcher looks for both files beside itself, quietly skipping the feature if either is missing. This silence is deliberate, but it means a missing file looks like a fault:
-
turn_secret.txt— the shared secret, matchingstatic-auth-secreton your TURN server. Without it, the relay refuses every allocation, and behind symmetric NAT you get signalling that connects and video that never arrives. -
player_token.txt— who may open the stream at all. Leave it out for a public demo.
Keep both files out of source control. Create them per machine.