Unreal Web DataStreams Guide
This guide was written as a quick reference step by step guide for setting up a simple Unreal Web datastream. For more in depth information on each step please check the documentation at https://www.genvidtech.com/for-developers/sdk-latest/
Download Web Assets
Download the folder containing the assets for this guide
Package the Project (UE5)
Package the unreal project. Note the exe file location in your project folder. For instance: “\\Archives\\Windows\\ClockTime\\Binaries\\Win64\\ClockTime.exe” (or any other folder just adjust the template file below accordingly)
Package the Project (UE4)
Package the unreal project. Note the exe file location in your project folder. For instance: “\\Archives\\WindowsNoEditor\\ClockTime\\Binaries\\Win64\\ClockTime.exe” (or any other folder just adjust the template file below accordingly)
Dealing with changes
If anything changes in the project - it will have to be repackaged. However there is a workaround. If the project is played in editor the local bastion (detailed in putting it all together) will pick up the project currently in play.
Prepare the Unreal config files
Navigate to your unreal project folder - then go up one
In this folder create a “config” folder
This will hold all the unreal related config files needed by genvid
In the new folder create a “game.hcl” file
version = "1.7.0" job "ue4" {} log "ue4" { job = "ue4" fileName = "ue4.log" logLevel = true } log "ue4_stderr" { job = "ue4" fileName = "stderr" logLevel = true } log "ue4_stdout" { job = "ue4" fileName = "stdout" logLevel = true } config { local { ue4 { appdir = "{ {env `PROJECTDIR` | js}}\\App" } } }
Change the version and appdir. Change all references of ue4 to ue5 if needed.
Check the documentation for an in depth explanation.
The Genvid SDK also contains examples in the samples folder
This file tells the local genvid bastion where the unreal project is
Create a “sample.hcl” file
version = "1.7.0" settings { encode { input { width = 1280 height = 720 } output { width = 1280 height = 720 } } info { description = "Genvid SDK Unreal Clock Time Sample" game = "ClockTime" name = "clock time" } }
Change the description, game, and name to match your game
Check the documentation for an in depth explanation.
The Genvid SDK also contains examples in the samples folders
This file sets the window size and some misc information about the game
Create an “events.json” file
This will be mostly empty as we do not have any events:
{ "version": "1.7.0", "event": { "game": { "maps": [ ] } } }
Change the version to be your version
Prepare the Unreal template files
In the directory above your Unreal project folder create the folders “templates/local”
This is why it was recommended to put your unreal project one extra folder deep
Create a file named “ue4.nomad.tmpl” or “ue5.nomad.tmpl”
job "ue4" { datacenters = [ # { {range $i, $dc := datacenters}} "{ {$dc}}", # { {end}} ] group "ue4" { network { port "sdkgui" {} } task "ue4" { driver = "raw_exec" config { command = "{ {key `local/ue4/appdir` | js}}\\Archives\\WindowsNoEditor\\ClockTime\\Binaries\\Win64\\ClockTime.exe" args = [ "-ResX={ {- keyOrDefault `genvid/encode/input/width` `1280` -}}", "-ResY={ {- keyOrDefault `genvid/encode/input/height` `720` -}}", "-Windowed", "-game", "-unattended", "-nosplash", "-nohomedir", "-forcelogflush", "-logtimes", "-ABSLOG=${NOMAD_ALLOC_DIR}/logs/ue4.log", "-nopause", ] } service { name = "sdkguiservice" port = "sdkgui" } env { GLOG_logtostderr = "true" GOOGLE_LOGTOSTDERR = "true" GENVID_LOGGER_PREFIX = "ue4" GLOG_minloglevel = "0" GLOG_flushloglevel = "-1" GLOG_logbufsecs = "5" } } } }
Change the end of the setting of the “command” value to point to your exe location. Change mentions of ue4 if needed
check the documentation for an in depth explanation
This tells the local genvid instance where the exe is located
Prepare the Unreal python file
In the directory above your unreal project folder copy the downloaded asset named “app.py”
We will use this python file later to load all the config and templates files.
You may need to install the genvid toolbox if not done already
You can install the genvid toolbox via the python file in the downloaded SDK files (py install-toolbox.py)
Check the documentation for an in depth explanation of what this script is doing. The function is named “load”
Prepare the web node_modules folder
In the directory above your Unreal project create a folder called “web” and move into it
Copy the downloaded asset named “package.json” here
Check the documentation for an in depth explanation of what this is doing
Run the command “npm install” in powershell in the “web” folder
A “node_modules” folder should be created
Prepare the web backend folder
Create a “backend” folder in the “web” folder and move into the new folder
Copy the following files: “www”, “streams.js”, “config.js”, “commands.js”, “auth.js”, “app.js”, “apiBase.js” from the downloaded assets here
See the documentation for a detailed description
Prepare the web config files
Create a “config” folder in the “web” folder
Create a “web.hcl” file
version = "1.7.0" job "web" {} log "web" { job = "web" task = "web" fileName = "stdout" } log "weberr" { job = "web" task = "web" fileName = "stderr" } link "web" { name = "Clock Time Sample" template = "http://${serviceEx `web` `` true}/" } link "admin" { name = "Clock Time Admin" template = "http://${serviceEx `web` `` true}/admin" } // { {with $url := env `SSLWEBENDPOINT`}} link "web" { name = "Clock Time Sample" template = "https://{ {$url}}:30000" } link "admin" { template = "https://{ {$url}}:30000/admin" } // { {end}} // Check if we are using a load balancer // { {with $url := env `WEBENDPOINT`}} link "web" { name = "Clock Time Sample" template = "https://{ {$url}}/" } link "admin" { name = "Clock Time Admin" template = "https://{ {$url}}/admin" } // { {end}} config { local { website { root = "{ {env `PROJECTDIR` | js}}" script = "{ {env `PROJECTDIR` | js}}\\backend\\www" } binary { node { path = "{ {plugin `where.exe` `node` | js}}" } } } embed_ssl { enabled = false } } // end of config
Change the various “name” variables to be your projects name
Change the version to be your version
Check the documentation for an in depth explanation.
The Genvid SDK also contains examples in the samples folders
This file informs the bastion instance where the various web related files are
Create a “stream.hcl” file
version = "1.7.0" secrets { disco { GENVID_DISCO_SECRET = "discosecret" } studio { GENVID_STUDIO_SECRET = "studiosecret" } webgateway { GENVID_WEBGATEWAY_SECRET = "webgatewaysecret" } } settings { encode { input { width = 1280 height = 720 } output { width = 1280 height = 720 framerate = 30 } } info { description = "Sample to demonstrate genvid" game = "ClockTime" name = "Clock Time" } } config { local { appdir = "{ {env `PROJECTDIR` | js}}\\ClockTime" } }
Change the appdir to be the folder your unreal project is in as well as the name, game, and description to be for your project
Change the version to be your version
Check the documentation for an in depth explanation.
The Genvid SDK also contains examples in the samples folders
This file informs the bastion instance of what streams to expect
Create an “events.json” file
This will be mostly empty as we do not have any events:
{ "version": "1.7.0", "event": { "game": { "maps": [ ] } } }
Change the version to be your version
Prepare the web template files
Create “templates/local” folders in your “web” folder
Create a file named “web.nomad.tmpl”
job "web" { datacenters = [ # { {range $i, $dc := datacenters}} "{ {$dc}}", # { {end}} ] group "web" { network { port "web" { static = 30000 } } task "web" { driver = "raw_exec" config { command = "{ {key `local/binary/node/path` | js}}" args = ["{ {key `local/website/script` | js}}"] } vault { policies = ["genvid"] } env { GENVID_LIVESERVICE = "{ {key `/genvid/encode/stream/service`}}" GENVID_LIVECHANNEL = "{ {key `/genvid/encode/stream/channel`}}" # { {with secret `secret/disco` }} GENVID_DISCO_SECRET = "{ { .Data.GENVID_DISCO_SECRET }}" # { {end}} # { {with secret `secret/studio` }} GENVID_STUDIO_SECRET = "{ { .Data.GENVID_STUDIO_SECRET }}" # { {end}} # { {with secret `secret/webgateway` }} GENVID_WEBGATEWAY_SECRET = "{ { .Data.GENVID_WEBGATEWAY_SECRET }}" # { {end}} # { {if keyExists `/twitch_extension/enabled`}} # { { if key `/twitch_extension/enabled` | parseBool }} # { {with secret `secret/twitch` }} TWITCH_EXT_CLIENT_SECRET = "{ { .Data.TWITCH_EXT_CLIENT_SECRET }}" # { { end }}{ { end }}{ {end}} // { {if keyExists `/embed_ssl/enabled`}} // { { if key `/embed_ssl/enabled` | parseBool }} SSL = true // { { end }}{ { end }} PORT = "${NOMAD_PORT_web}" } service { name = "web" tags = ["engage", "web"] port = "web" // { {if keyExists `/embed_ssl/enabled`}} // { { if key `/embed_ssl/enabled` | parseBool }} check { name = "HTTPS Check" type = "http" path = "/health" protocol = "https" tls_skip_verify = true interval = "5s" timeout = "2s" } // { { else }} check { name = "HTTP Check" type = "http" path = "/health" interval = "5s" timeout = "2s" } // { { end }}{ { end }} } } } }
Check the documentation for an in depth explanation.
The Genvid SDK also contains examples in the samples folders
This file informs the bastion instance of various web related information
Prepare the web public folder
Create a “public” folder in your “web folder” and move into the new folder
Copy the following files from the SDK into this folder
“Favicon.ico”, “genvid.umd”, “genvid-math.umd”, “lib/genvid.es5”, and “lib/genvid-math.es5”
Create a lib folder to put the two es5 files in
All the files minus the .ico file can be found in “<SDK root>\api\web\dist\”
The .ico file can be found in the root “logo_small.ico”. Copy and rename it
Create the overlay files for the clock datastream in the public folder (a index.html, overlay.js, and style.css file)
The html file will need to set up 3 divs to display the hour, minute, and second stream
<!doctype html> <html> <head> <title>Genvid Overlay</title> <link rel="stylesheet" href="style.css"> <script src="genvid.umd.js"></script> <script src="genvid-math.umd.js"></script> <script src="overlay.js"></script> </head> <body style="background:black"> <div id="video_player"></div> <div id="overlay"> <div class="child" id="hour"></div> <div class="child" id="minute"></div> <div class="child" id="second"></div> </div> </body> </html>
The js file will need to parse the stream and set the data in the divs
var genvidClient; fetch("/api/public/channels/join", { method: "post" }) .then(function (data) { return data.json() }) .then(function (response) { genvidClient = genvid.createGenvidClient(response.info, response.uri, response.token, "video_player"); genvidClient.onStreamsReceived(function (dataStreams) { for (let stream of [...dataStreams.streams, ...dataStreams.annotations]) { for (let frame of stream.frames) { try { frame.user = JSON.parse(frame.data); } catch (e) { console.log(e, frame.data); } } } }); genvidClient.onVideoPlayerReady(function () { console.log("Video Player is Ready"); }); genvidClient.onDraw(function (frame) { let gameDataFrame = frame.streams["ClockTime"]; if (gameDataFrame && gameDataFrame.user) { update(gameDataFrame.user, genvidClient.videoAspectRatio); } }); genvidClient.start(); }) .catch(function (e) { console.log(e) }); function update(data, videoAspectRatio) { document.getElementById("hour").innerHTML = "Hour: " + Math.round(data.hour); document.getElementById("minute").innerHTML = "Minute: " + Math.round(data.minute); document.getElementById("second").innerHTML = "Second: " + Math.round(data.second); }
The css file will need to set the styles for the various elements created above
.label { position: absolute; left:1vw; bottom:1vw; opacity: 0.7; border-radius: 8px; padding: 12px; background-color:rgb(255, 200, 47); } #overlay { position: absolute; left:1vw; top:1vw; margin : 0 auto; padding : 5px; display : flex; justify-content : space-between; } .child { opacity: 0.7; border-radius: 8px; padding: 12px; margin: 12px; width:128px; background-color:rgb(255, 200, 47); }
Prepare the web python file
In the “web” folder copy the downloaded assets “web.py” file
This python file will also eventually do what the previous one did but for the web config files. (calls set_config on the various config files)
See the documentation, or SDK samples for an example. The function is named “load”
Putting it all together
Return to the folder above your unreal project
Open a powershell instance here
Run “genvid-bastion install --bastionid localbastion --loadconfig” to install bastion
Run “genvid-sdk setup” to create the local cluster
Run “genvid-sdk clean-config” to remove any previously loaded sample configurations
Run “genvid-sdk load-config-sdk” to configure the basic services for the SDK
Run “py app.py load” to load the configuration files created earlier for unreal
Change directory to your “web folder”
Run “py web.py load” to load the configuration files created earlier for web
Run “genvid-sdk monitor”
Hit “Start All” in the top right
If you want to use the project as is in editor without having to package - stop the ue4/ue5 service. Then play in editor. The in editor version will automatically be picked up.
Once everything is started click on the non admin or studio link to open the web view
To stop run “genvid-sdk stop” and “genvid-bastion uninstall”
Example cluster
