From 2c31b4774b475ce697631defafba7f15680b89ad Mon Sep 17 00:00:00 2001 From: Denis Phoenix <127062860+DenisTensorWorks@users.noreply.github.com> Date: Mon, 17 Jun 2024 14:28:51 +1000 Subject: [PATCH 01/13] Update LICENSE - Update license year --- LICENSE | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/LICENSE b/LICENSE index e1794fb6..ab9d9624 100644 --- a/LICENSE +++ b/LICENSE @@ -1,6 +1,6 @@ MIT License -Copyright (c) 2021 - 2022 TensorWorks Pty Ltd +Copyright (c) 2021 - 2024 TensorWorks Pty Ltd Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal From c23fd5c79b548290e61827b429036c76a6cbeccc Mon Sep 17 00:00:00 2001 From: Denis Phoenix <127062860+DenisTensorWorks@users.noreply.github.com> Date: Mon, 17 Jun 2024 14:41:12 +1000 Subject: [PATCH 02/13] Update README.md - First pass editing review --- README.md | 31 ++++++++++++++----------------- 1 file changed, 14 insertions(+), 17 deletions(-) diff --git a/README.md b/README.md index 3f5c3c02..28285080 100644 --- a/README.md +++ b/README.md @@ -1,36 +1,33 @@ -# Scalable Pixel Streaming Frontend +# Scalable Pixel Streaming frontend -This is the web frontend for [Scalable Pixel Streaming (SPS)](https://scalablestreaming.io). +This repository contains the web frontend for [Scalable Pixel Streaming (SPS)](https://scalablestreaming.io), which is a lightweight wrapper implementation of Epic Games [Pixel Streaming frontend](https://github.com/EpicGamesExt/PixelStreamingInfrastructure/tree/master/Frontend). -The SPS frontend is a lightweight implementation of Epic Games' [Pixel Streaming frontend](https://github.com/EpicGames/PixelStreamingInfrastructure/tree/master/Frontend). - -## Features of the SPS Frontend +## Features of the SPS frontend - [Extensions](./library/src/SignallingExtension.ts) to the default signalling messages to communicate with our custom signalling server. -- The sending of [streaming statistics](./library/src/SPSApplication.ts#L38) to our signalling server. +- [Streaming statistics](./library/src/SPSApplication.ts#L38) are being sent to our signalling server. ## Documentation ### Utilising the Scalable Pixel Streaming Frontend -Below is a comprehensive guide for accessing the Scalable Pixel Streaming Frontend. This guide includes where to download the library, how to consume it and how to customise it for usage in different projects. -- [Scalable Pixel Streaming Frontend utilisation guide](./docs/frontend_utilisation_guide.md) -### Migrating from Scalable Pixel Streaming Frontend -In general, the official Epic Games Pixel Streaming [Frontend docs](https://github.com/EpicGames/PixelStreamingInfrastructure/tree/master/Frontend) should cover most common usage cases (as our library is simply a thin wrapper on that). However, some Scalable Pixel Streaming Frontend specific docs are listed below: +Refer to our [Scalable Pixel Streaming frontend utilisation guide](./docs/frontend_utilisation_guide.md) for accessing the Scalable Pixel Streaming frontend, downloading the library, consuming it, and customising it for usage in different projects. + +### Migrating legacy Scalable Pixel Streaming frontend + +All SPS versions since `v 0.1.4` are using the current version of Epic Games Pixel Streaming frontend. Refer to [our migration guide](./docs/api_transition_guide.md) if your frontend predates this version. -- [Migrating from Scalable Pixel Streaming Frontend <=0.1.4](./docs/api_transition_guide.md) +### Scalable Pixel Streaming frontend reference -### Scalable Pixel Streaming Frontend Reference section -The Scalable Pixel Streaming Frontend is a part of a complex system which abstracts a lot of its complexities behind the library. Below is a useful collection of references which explain how the Scalable Pixel Streaming Frontend fits within Scalable Pixel Streaming as a whole. -- [Scalable Pixel Streaming Frontend Reference guide](./docs/sps_frontend_refrence_guide.md) +The Scalable Pixel Streaming frontend is a part of a complex system which abstracts a lot of its complexities behind the library. Refer to our [reference guide](./docs/sps_frontend_refrence_guide.md) to gain a deeper understanding of how the SPS frontend fits within Scalable Pixel Streaming as a whole. ## Issues -As the SPS frontend is a lightweight implementation of the Epic Games frontend, the majority of issues should be reported to the Epic Games frontend [here](https://github.com/EpicGames/PixelStreamingInfrastructure/issues). +As the SPS frontend is an implementation of the Epic Games Pixel Streaming frontend, the majority of issues will pertain to the Epic Games frontend and should be reported on [their repository](https://github.com/EpicGamesExt/PixelStreamingInfrastructure/issues). -However, in cases where you are certain it is an SPS specific frontend issue, please report your issue [here](https://github.com/ScalablePixelStreaming/Frontend/issues). +If you encounter an issues specific to the SPS implementation, please report your issue [here](https://github.com/ScalablePixelStreaming/Frontend/issues). ## Legal -Copyright © 2021 - 2023, TensorWorks Pty Ltd. Licensed under the MIT License, see the file [LICENSE](./LICENSE) for details. +Copyright © 2021 - 2024, TensorWorks Pty Ltd. Licensed under the MIT License, see the [license file](./LICENSE) for details. From 43fbb08b167d18829f42269c404d28c62edb1583 Mon Sep 17 00:00:00 2001 From: Denis Phoenix <127062860+DenisTensorWorks@users.noreply.github.com> Date: Mon, 17 Jun 2024 14:58:40 +1000 Subject: [PATCH 03/13] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 28285080..ce612cb7 100644 --- a/README.md +++ b/README.md @@ -15,7 +15,7 @@ Refer to our [Scalable Pixel Streaming frontend utilisation guide](./docs/fronte ### Migrating legacy Scalable Pixel Streaming frontend -All SPS versions since `v 0.1.4` are using the current version of Epic Games Pixel Streaming frontend. Refer to [our migration guide](./docs/api_transition_guide.md) if your frontend predates this version. +All SPS versions since `v0.1.4` are using the current version of Epic Games Pixel Streaming frontend. Refer to [our migration guide](./docs/api_transition_guide.md) if your frontend predates this version. ### Scalable Pixel Streaming frontend reference From bbd3eae542f858edff2c6a4b67b0b3d81357357d Mon Sep 17 00:00:00 2001 From: Denis Phoenix <127062860+DenisTensorWorks@users.noreply.github.com> Date: Mon, 17 Jun 2024 15:18:55 +1000 Subject: [PATCH 04/13] Update api_transition_guide.md - Facelift --- docs/api_transition_guide.md | 40 ++++++++++++++---------------------- 1 file changed, 15 insertions(+), 25 deletions(-) diff --git a/docs/api_transition_guide.md b/docs/api_transition_guide.md index d1d3d726..101e943a 100644 --- a/docs/api_transition_guide.md +++ b/docs/api_transition_guide.md @@ -1,23 +1,21 @@ -# Migrating from `libspsfrontend` <=0.1.4 +# Migrating from `libspsfrontend` predating `v0.1.4` -All SPS versions after `0.1.4` are now using the [Epic Games' Pixel Streaming frontend](https://github.com/EpicGames/PixelStreamingInfrastructure/tree/master/Frontend). This shift to the Epic frontend has caused us to change both our API and our NPM packages. +SPS frontend changed to use the [Epic Games Pixel Streaming frontend](https://github.com/EpicGames/PixelStreamingInfrastructure/tree/master/Frontend) since version `0.1.4`, which involed mdofications both to our API and NPM packages. ---- +Below aresome common usage of the SPS Frontend API that has changed. Note that this list is not exhaustive, if you encounter more differences, please open an issue on this repository to report them. -# API Usage +### Listening for UE messages -Below are common usage of SPS Frontend API that have now changed (this list is not exhaustive, if there are more you would like documented please open an issue). +Refer to [this PR](https://github.com/EpicGames/PixelStreamingInfrastructure/pull/132) for more details. -## Listening for UE messages - -**Before:** +Before: ```js iWebRtcController.dataChannelController.onResponse = (messageBuffer) => { /* whatever */ } ``` -**Now:** +Now: ```js pixelstreaming.addResponseEventListener(name, funct) @@ -26,38 +24,30 @@ pixelstreaming.addResponseEventListener(name, funct) pixelstreaming.removeResponseEventListener(name) ``` -(More details [here](https://github.com/EpicGames/PixelStreamingInfrastructure/pull/132)) - ---- +### Sending messages to UE -## Sending messages to UE +Refer to [this PR](https://github.com/EpicGames/PixelStreamingInfrastructure/pull/132) for more details. -**Before:** +Before: ```js iWebRtcController.sendUeUiDescriptor(JSON.stringify({ /* whatever */ } )) ``` -**Now:** +Now: ```js pixelstreaming.emitUIInteraction(data: object | string) ``` -(More details [here](https://github.com/EpicGames/PixelStreamingInfrastructure/pull/132)) - ---- +### Listening for WebRTC stream start -## Listen for WebRTC stream start? +Refer to [this PR](https://github.com/EpicGames/PixelStreamingInfrastructure/pull/110) for more details. -**Before:** +Before: ```js override onVideoInitialised() ``` -**Now:** +Now: ```js pixelStreaming.addEventListener("videoInitialized", ()=> { /* Do something */ }); ``` - -(More details [here](https://github.com/EpicGames/PixelStreamingInfrastructure/pull/110)) - ------- \ No newline at end of file From e681abe0bf0939051f4eebc9cb124a96137dca13 Mon Sep 17 00:00:00 2001 From: Denis Phoenix <127062860+DenisTensorWorks@users.noreply.github.com> Date: Mon, 17 Jun 2024 15:32:10 +1000 Subject: [PATCH 05/13] Update sps_frontend_refrence_guide.md - Facelift --- docs/sps_frontend_refrence_guide.md | 39 ++++++++++++++++------------- 1 file changed, 22 insertions(+), 17 deletions(-) diff --git a/docs/sps_frontend_refrence_guide.md b/docs/sps_frontend_refrence_guide.md index 719686bb..a76ea624 100644 --- a/docs/sps_frontend_refrence_guide.md +++ b/docs/sps_frontend_refrence_guide.md @@ -1,34 +1,39 @@ -# About the Scalable Pixel Streaming Frontend -## SPS lifecycle +# Scalable Pixel Streaming frontend reference + +There are several phases involved in the SPS lifecycle, described in detail below. + ### Authentication Phase + 1) The signalling server transmits a message to the frontend indicating that authentication is required. -2) The player controller responds with an authentication request containing either an empty authentication token (if we have not yet received a token from an identity provider) or with an authentication token that had been obtained by means of a redirect during a previous run of the event lifecycle. +2) The player controller responds with an authentication request containing either an empty authentication token (if we have not yet received a token from an identity provider), or with an authentication token that had been obtained by means of a redirect during a previous run of the event lifecycle. -3) The signalling server communicates with the authentication plugin to determine what to do next. +3) The signalling server communicates with the authentication plugin to determine what to do next: -- If the no-op authentication plugin is being used then the signalling server transmits a response indicating that authentication was successful. +- If the no-op authentication method is used, then the signalling server transmits a response indicating that authentication was successful. -- If any other authentication plugin is being used and we do not have an authentication token then the signalling server transmits a response indicating that the user should be redirected to the login page for the identity provider. +- If any other authentication plugin is used and we _do not_ have an authentication token, then the signalling server transmits a response indicating that the user should be redirected to the login page for the identity provider. -- If any other authentication plugin is being used and we do have an authentication token then the signalling server transmits a response indicating whether the token was accepted as valid by the authentication plugin. +- If any other authentication plugin is used and we _do_ have an authentication token, then the signalling server transmits a response indicating whether the token was accepted as valid by the authentication plugin. -Note that the path taken in Step 3 is largely transparent to the logic in the Frontend. +Note that the path taken in step three is largely transparent to the logic in the frontend. -4) If a redirect is required then the Scalable Pixel Streaming Frontend will trigger it immediately after it has finished notifying the Epic Games Pixel Streaming Frontend of the authentication status. After a redirect occurs and the identity provider's login page subsequently redirects back to the Scalable Pixel Streaming Frontend, the page is reset and the event lifecycle restarts from the beginning, except that there is now an authentication token specified in the page's URL parameters and we will follow a different path in Step 3. +4) If a redirect is required, then the Scalable Pixel Streaming frontend will trigger it immediately after it has finished notifying the Epic Games Pixel Streaming frontend of the authentication status. After a redirect occurs and the identity provider's login page subsequently redirects back to the Scalable Pixel Streaming frontend, the page is reset and the event lifecycle restarts from the beginning, except that there is now an authentication token specified in the page's URL parameters, which will lead down a different path in the previous step. -5) Once the user has been successfully authenticated, the signalling server will initiate the creation of an instance of the Pixel Streaming application, which represents the beginning of the Instance Startup Phase. +5) Once the user has been successfully authenticated, the signalling server will initiate the creation of an instance of the Pixel Streaming application, beginning the instance startup phase. -### Instance Startup Phase -As the Pixel Streaming application instance is created and starts, the signalling server transmits status update messages to the Epic Games Pixel Streaming Frontend. +### Instance startup phase -The Epic Games Pixel Streaming Frontend notifies the Scalable Pixel Streaming Frontend of the application instance status so it can inform the user through the page's UI. +1) As the Pixel Streaming application instance is created, the signalling server transmits status update messages to the Epic Games Pixel Streaming frontend. -Once the Pixel Streaming application instance has started, it will connect to the signalling server and initiate the WebRTC Connection Phase. +2) The Epic Games Pixel Streaming frontend notifies the SPS frontend of the application instance status, so it can inform the user through the page's UI. + +3) Once the Pixel Streaming application instance has started, it will connect to the signalling server and initiate the WebRTC connection phase. ### Determining the WebSocket endpoint URL -Prior to deploying the Scalable Pixel Streaming Frontend, you will need to determine the endpoint URL that will be used to establish WebSocket connections to the signalling server(s) for your Pixel Streaming application: -If you are deploying your Pixel Streaming application in a single geographic region on a single cloud platform, then this will be the signalling server endpoint URL reported by the Scalable Pixel Streaming REST API. +Prior to deploying the Scalable Pixel Streaming frontend, you will need to determine the endpoint URL that will be used to establish WebSocket connections to the signalling server/servers for your Pixel Streaming application: + +- If you are deploying your Pixel Streaming application in a single geographic region on a single cloud platform, this will be the signalling server endpoint URL reported by the Scalable Pixel Streaming REST API. -If you are deploying your Pixel Streaming application in multiple geographic regions or across multiple cloud platforms then this will be the URL of a load balancer that you have configured to distribute requests to the signalling servers in the various regions or platforms. \ No newline at end of file +- If you are deploying your Pixel Streaming application in multiple geographic regions or across multiple cloud platforms, this will be the URL of a load balancer that you have configured to distribute requests to the signalling servers in the various regions and/or platforms. From 1473a5fb2071d1af843f202b2eedce9f6c7b3443 Mon Sep 17 00:00:00 2001 From: Denis Phoenix <127062860+DenisTensorWorks@users.noreply.github.com> Date: Tue, 18 Jun 2024 09:30:19 +1000 Subject: [PATCH 06/13] Update frontend_utilisation_guide.md - Intermediate commit --- docs/frontend_utilisation_guide.md | 216 ++++++++++++++++------------- 1 file changed, 122 insertions(+), 94 deletions(-) diff --git a/docs/frontend_utilisation_guide.md b/docs/frontend_utilisation_guide.md index 04c9de8d..82be03a0 100644 --- a/docs/frontend_utilisation_guide.md +++ b/docs/frontend_utilisation_guide.md @@ -1,132 +1,142 @@ -# Utilising the Frontend +# Utilising the frontend + ## Overview -The Scalable Pixel Streaming Frontend is a library of HTML, CSS and TypeScript code that runs in client web browsers to help users connect to Scalable Pixel Streaming applications and interact with them. It is able to achieve this by consuming the Pixel Streaming Frontend and UI libraries and by extending their signalling server and WebSocket packages the Pixel Streaming Frontend can be configured to work with Scalable Pixel Streaming signalling severs. -## Epic Games Pixel Streaming Frontend and UI Frontend -For the base functionality for Pixel Streaming and its UI capabilities the Scalable Pixel Streaming Frontend consumes the Epic Games Pixel Streaming Frontend and UI Frontend: -- [Pixel Streaming Frontend](https://www.npmjs.com/package/@epicgames-ps/lib-pixelstreamingfrontend-ue5.4) +The Scalable Pixel Streaming (SPS) frontend is a library of HTML, CSS, and TypeScript code that runs in web browsers and allows users to connect and interact with Scalable Pixel Streaming applications. It consumes the Epic Games Pixel Streaming frontend and UI libraries, and extends their signalling server and WebSocket packages. Note that the Epic Games Pixel Streaming frontend can be configured to work with Scalable Pixel Streaming signalling severs. + +## Epic Games Pixel Streaming frontend and UI frontend NPM packages + +NPM packages consumed by SPS frontend are: + - [Pixel Streaming Frontend UI](https://www.npmjs.com/package/@epicgames-ps/lib-pixelstreamingfrontend-ui-ue5.4) -### Pixel Streaming Frontend -The Pixel Streaming Frontend contains all the base functionality: -- WebSocket handling -- Data channel handling -- UE message handling -- Mouse and keyboard interaction handling -- Video and audio stream handling -- Logic for: AFK, FreezeFrames, Mic, TURN, SDP +### Pixel Streaming Frontend + +NPM package for the Pixel Streaming frontend consumed by SPS is located [here](https://www.npmjs.com/package/@epicgames-ps/lib-pixelstreamingfrontend-ue5.4). + +It contains the following functionality: + +- WebSocket handling; +- Data channel handling; +- UE message handling; +- Mouse and keyboard interaction handling; +- Video and audio stream handling; +- Logic for: AFK, FreezeFrames, Mic, TURN, SDP. ### Pixel Streaming Frontend UI -The Pixel Streaming Frontend UI contains all the functionality for UI components: -- Text, Action and AFK Overlays -- CSS styling -- UI display settings; UE stream data + +NPM package for the Pixel Streaming UI frontend consumed by SPS is located [here](https://www.npmjs.com/package/@epicgames-ps/lib-pixelstreamingfrontend-ui-ue5.4). + +It contains the following functionality: + +- Text, Action, and AFK Overlays; +- CSS styling; +- UI display settings; +- UE stream data. --- -## Scalable Pixel Streaming Frontend packages -### The Scalable Pixel Streaming Frontend Library -The library is the part of the Scalable Pixel Streaming Frontend that consumes the Epic Games Pixel Streaming Frontend and UI Frontend. It includes all of the custom signalling server logic that Scalable Pixel Streaming signalling servers require to work. The library can be either obtained through [GitHub](https://github.com/ScalablePixelStreaming/Frontend) or [NPM](https://www.npmjs.com/package/@tensorworks/libspsfrontend). To make use of the library it must be initialised via HTML and Javascript. The library is written in TypeScript but configured to export as a UMD module and can be consumed by plain JavaScript and most JavaScript frameworks. +## SPS frontend packages + +### SPS frontend Library + +The library includes all of the custom signalling logic that Scalable Pixel Streaming signalling servers require to work. The library can be either obtained through [GitHub](https://github.com/ScalablePixelStreaming/Frontend) or [NPM](https://www.npmjs.com/package/@tensorworks/libspsfrontend). The library must be initialised via HTML and Javascript. It is written in TypeScript, but configured to export as a UMD module and can be consumed by plain JavaScript and most JavaScript frameworks. + +### SPS frontend TypeScript example + +Our [TypeScript example](https://github.com/ScalablePixelStreaming/Frontend/tree/main/examples/typescript) is a simple HTML, CSS, and TypeScript implementation that initializes the SPS frontend library by instantiating the library components and starting a connection to the signalling server. + +## Installing and consumping SPS packages + +Download the [SPS frontend source code from GitHub](https://github.com/ScalablePixelStreaming/Frontend). + +### Building for development and production + +SPS frontend packages contain several NPM scripts that can build the library and example implementation for either development or production. When building for development, source maps for debugging will be enabled. When building for production, source maps will be disabled, reducing console output and minifying the distributed JavaScript files. Below is a list of NPM scripts for both the library and example implementation with their respective commands. -### The Scalable Pixel Streaming Frontend TypeScript example -The [TypeScript example](https://github.com/ScalablePixelStreaming/Frontend/tree/main/examples/typescript) is a simple HTML, CSS and TypeScript implementation of what a user could create to initialize the Scalable Pixel Streaming Frontend Library. Its role is to instantiate the library's components and help start the Scalable Pixel Streaming connection to the signalling server. +#### Building library -## Getting Started; installation and consumption -### Building for Development vs Production -The Scalable Pixel Streaming Frontend packages contain several NPM scripts that can be used to build the library and example for either development or production. When building for development this will enable source maps for debugging. When building for production this will disable source maps, reduce console output and minify the distributed JavaScript files. Below are a list of npm scripts for both the library and example and what each command does: +First, install all required dependencies by running this command from the `library` directory: + +- `npm install`: Install the frontend library dependencies + +The following build scripts must be executed from the same directory: -#### library scripts -Please ensure that all library scripts are executed from the `library` directory and a user must first run `npm install` to install all the Libraries dependencies. - `npm run build-dev`: Build the library in development mode - `npm run build-prod`: Build the library in production mode -#### example scripts -Please ensure that all example scripts are executed from the `examples/typescript` directory. In general, it is recommended that a user installs the library first as the example requires the library. On the contrary, `build-all-dev` and `build-all-prod` do not require the library to be installed and built first, as these scripts will install and build the library, example and all dependencies. +#### Building example and linking the library + +The library must be installed before executing example scripts. All example scripts must be executed from the `examples/typescript` directory: + - `npm run build-dev`: Build the library in development mode - `npm run build-prod`: Build the library in production mode - `npm run serve-dev`: Serve the example locally using the library in development mode - `npm run serve-prod`: Serve the example locally using the library in production mode -- `npm run symlink`: Links the library to the example for consumption -- `npm run build-all-dev`: Build the library and the example in development mode and link the library to the example for consumption -- `npm run build-all-prod`: Build the library and the example in production mode and link the library to the example for consumption +- `npm run symlink`: Link the library to the example for consumption -### Installing the Scalable Pixel Streaming Frontend Library from GitHub -Please note the following installation will be done with `dev` NPM scripts however, it can also be done with `prod` build scripts. +#### Building and linking library and example with a single command -1) Download the [Scalable Pixel Streaming Frontend source code from GitHub](https://github.com/ScalablePixelStreaming/Frontend) +Alternatively, you can run the build all scripts from the `examples/typescript` directory to install and link the library and the example at the same time: -2) To build the library run the following commands in the `library` directory of the source tree: -```bash -# Install the Frontend library's dependencies -npm install +- `npm run build-all-dev`: Build the library and the example in development mode and link the library to the example for consumption +- `npm run build-all-prod`: Build the library and the example in production mode and link the library to the example for consumption -# Build the Frontend library -npm run build-dev -``` -These commands and scripts will install and build the library. +### Installing the Scalable Pixel Streaming Frontend through NPM -3) Run the following commands in the `examples/typescript` directory of the source tree: -```bash -# Install the examples' dependencies -npm npm install +1) If your project includes a `package.json` file, run the following command in the same directory: -# Symlink the library to the example -npm run symlink +- `npm i @tensorworks/libspsfrontend` -# Build the example -npm run build-dev -``` -These commands and scripts will install the example, link the library to the example and build the example. +2) Import your desired components from the library package `"@tensorworks/libspsfrontend"` -#### Installing and building with the build-all script -1) Download the [Scalable Pixel Streaming Frontend source code from GitHub](https://github.com/ScalablePixelStreaming/Frontend) +#### Initialising and consuming the library -2) Run the following script in the `examples/typescript` directory of the source tree: -```bash -# Install, link and build the example and library -npm run build-all-dev -``` -This will install, link and build the Scalable Pixel Streaming Frontend example and library all-in-one. +The following example for initialising the library is based on the TypeScript example provided on GitHub. -### Installing the Scalable Pixel Streaming Frontend through NPM -If your project includes a `package.json` file run the following command in the same directory -1) Run the following command: `npm i @tensorworks/libspsfrontend` +1) Import all the required objects, types, and packages from the SPS frontend library: -2) Import your desired components from the library package `"@tensorworks/libspsfrontend"` - -#### Basics to initialising and consuming the library -The following example for initialising the library is based on the TypeScript example Provided on GitHub. - -1) Import all the required objects, types and packages from the Scalable Pixel Streaming Frontend Library ```typescript import {Config, PixelStreaming, SPSApplication, TextParameters, PixelStreamingApplicationStyle} from "@tensorworks/libspsfrontend"; ``` -2) Apply default styling from Epic Games Pixel Streaming Frontend + +2) Apply default styling from Epic Games Pixel Streaming frontend: + ```typescript export const PixelStreamingApplicationStyles = new PixelStreamingApplicationStyle(); PixelStreamingApplicationStyles.applyStyleSheet(); ``` -3) Create a `webSocketAddress` variable so the WebSocket URL can be modified if a user wishes to inject their own WebSocket address at load time + +3) Create a `webSocketAddress` variable, so that the WebSocket URL could be modified if a user wishes to inject their own WebSocket address at load time: + ```typescript let webSocketAddress = ""; ``` -4) Create a `document.body.onload` function to automate the activation and creation of steps 5-8 + +4) Create a `document.body.onload` function to automate the activation and creation of the remaining steps: + ```typescript document.body.onload = function () { // steps 5-8 go in here } ``` -5) Create the Pixel Streaming `config` object and ensure that `useUrlParams` is true and `initialSettings` contains `{ OfferToReceive: true, TimeoutIfIdle: true }`. This is important as the Scalable Pixel Streaming signalling server can only receive the offer to connect. `TimeoutIfIdle` enables the AFK timeout by default so any unattended sessions close and do not consume extra cloud GPU resources. + +5) Create the Pixel Streaming `config` object and ensure that `useUrlParams` is true, and `initialSettings` contains `{ OfferToReceive: true, TimeoutIfIdle: true }`. This is important as the SPS signalling server can only receive the offer to connect. `TimeoutIfIdle` enables the AFK timeout by default, so that any unattended sessions close and stop consuming unnecessary cloud GPU resources: + ```typescript const config = new Config({ useUrlParams: true, initialSettings: { OfferToReceive: true, TimeoutIfIdle: true } }); ``` -6) Create an if statement that will make use of the `webSocketAddress` variable if one is included + +6) Create an if statement that will make use of the `webSocketAddress` variable if one is included: + ```typescript if(webSocketAddress != ""){ config.setTextSetting(TextParameters.SignallingServerUrl, webSocketAddress) } ``` -7) Create an instance of the `PixelStreaming` object called `stream` and an instance of the `SPSApplication` object called `spsApplication`. + +7) Create an instance of the `PixelStreaming` object called `stream` and an instance of the `SPSApplication` object called `spsApplication`: + ```typescript const stream = new PixelStreaming(config); const spsApplication = new SPSApplication({ @@ -134,14 +144,19 @@ const spsApplication = new SPSApplication({ onColorModeChanged: (isLightMode) => PixelStreamingApplicationStyles.setColorMode(isLightMode) /* Light/Dark mode support. */ }); ``` -8) Append the `spsApplication.rootElement` inside a DOM Element of your choice or inject directly into the body of the web page like in the TypeScript example + +8) Append the `spsApplication.rootElement` inside a DOM element of your choice or inject directly into the body of the web page like in the TypeScript example: + ```typescript document.body.appendChild(spsApplication.rootElement); //OR document.getElementById("myElementId").appendChild(spsApplication.rootElement); ``` -### Default Index Implementation +### Default index implementation + +A default index implementation would look like this: + ```typescript import {Config, PixelStreaming, SPSApplication, TextParameters, PixelStreamingApplicationStyle} from "@tensorworks/libspsfrontend"; export const PixelStreamingApplicationStyles = new PixelStreamingApplicationStyle(); @@ -163,36 +178,50 @@ document.body.onload = function () { ``` ### Customising the WebSocket connection + #### Using setTextSetting within Config to inject a custom WebSocket -When serving the Scalable Pixel Streaming Frontend it will build a default WebSocket address to connect to based on the address of the current window of the webpage. If the WebSocket address matches what is created by default then no further steps are required. Users can override the default by using the `setTextSetting` method on our `config` instance. See the section: [Basics to initialising and consuming the library](frontend_utilisation_guide.md#basics-to-initialising-and-consuming-the-library) steps 3 and 6. + +When serving the SPS frontend, it will build a default WebSocket address to connect to, based on the address of the current window of the webpage. If the WebSocket address matches what is created by default, then no further steps are required. Users can override the default by using the `setTextSetting` method on the `config` instance. Refer to [Basics to initialising and consuming the library](frontend_utilisation_guide.md#basics-to-initialising-and-consuming-the-library), steps 3 and 6. + #### The .env file for the TypeScript example -In the TypeScript example there is a `.env.example` file. inside this file there is a line called `WEBSOCKET_URL` containing a filler URL. This file can be used to hard code a WebSocket address that can be consumed by the example as shown above. This example is able to work with the help of the [dotenv NPM package](https://www.npmjs.com/package/dotenv) in the `webpack.common.js` file in the TypeScript example. To implement this example follow these steps: -1) Rename the `.env.example` to `.env` -2) Replace the place holder URL with the WebSocket URL you wish to consume -3) Rebuild the example with the `npm run build-dev` or `npm run build-prod` for the changes to take effect - -If you wish to include this functionality in your project you will need to include the following steps: -The TypeScript example makes use of these exact steps and is a good demonstration resource on this topic. -1) Install `dotenv` via NPM `npm i dotenv --save-dev` -2) Include `dotenv` in your webpack file and set your `.env` file path using `path:` + +In the TypeScript example there is a `.env.example` file containing a filler URL in the `WEBSOCKET_URL` line. This file can be used to hard code a WebSocket address that can be consumed by the example as shown above. This example is able to work with the help of the [dotenv NPM package](https://www.npmjs.com/package/dotenv) in the `webpack.common.js` file in the TypeScript example. To implement this example follow these steps: + +1) Rename the `.env.example` to `.env`. +2) Replace the placeholder URL with the WebSocket URL you wish to consume. +3) Rebuild the example with the `npm run build-dev` or `npm run build-prod` for the changes to take effect. + +If you wish to include this functionality in your project, you will need to include the following steps, which are also demonstrated in the TypeScript example: + +1) Install `dotenv` via NPM `npm i dotenv --save-dev`. +2) Include `dotenv` in your webpack file and set your `.env` file path using `path:`: + ```javascript require('dotenv').config({ path: './.env' }); ``` -3) Include a plugin in your webpack file with the environment variables' name. For this example the name will be set to `WEBSOCKET_URL` + +3) Include a plugin in your webpack file with the environment variable's name. For this example, the name will be set to `WEBSOCKET_URL`: + ```javascript new webpack.DefinePlugin({ WEBSOCKET_URL: JSON.stringify((process.env.WEBSOCKET_URL !== undefined) ? process.env.WEBSOCKET_URL : '') }), ``` -4) Create the `.env` file in the path you set in step 3 with the variable of your choice + +4) Create the `.env` file in the path you set in the rpevious step with the variable of your choice: + ```bash WEBSOCKET_URL=ws://example.com/your/ws ``` -5) Declare your environment variable where you instantiate your Scalable Pixel Streaming Frontend Library + +5) Declare your environment variable where you instantiate your SPS frontend library: + ```typescript declare var WEBSOCKET_URL: string; ``` -6) Make use of the `setTextSetting` method within the `config` instance to set the `TextParameters.SignallingServerUrl` to a variable that makes use of `WEBSOCKET_URL` + +6) Make use of the `setTextSetting` method within the `config` instance to set the `TextParameters.SignallingServerUrl` to a variable that makes use of `WEBSOCKET_URL`: + ```typescript let webSocketAddress = WEBSOCKET_URL; if(webSocketAddress != ""){ @@ -200,9 +229,8 @@ if(webSocketAddress != ""){ } ``` ---- ## Scalable Pixel Streaming Frontend customisation By default the Scalable Pixel Streaming Frontend Library contains all the requirements to connect to a Scalable Pixel Streaming signalling server making it an effective starting template for further customisation rather than starting from scratch. It is able to achieve this functionality through its consumption of the Epic Games Pixel Streaming Frontend. To learn more about further utilising the Epic Games Pixel Streaming Frontend documentation can be found [here](https://github.com/EpicGames/PixelStreamingInfrastructure#readme). ### Scalable Pixel Streaming Frontend UI element customisation -Further customisation of UI elements like overlays or visual elements can also be achieved by utilising the Pixel Streaming Frontend UI and extending its types. For further information on how to utilise the Epic Games Pixel Streaming Frontend UI refer to the [Pixel Streaming Frontend UI documentation](https://github.com/EpicGames/PixelStreamingInfrastructure#readme). \ No newline at end of file +Further customisation of UI elements like overlays or visual elements can also be achieved by utilising the Pixel Streaming Frontend UI and extending its types. For further information on how to utilise the Epic Games Pixel Streaming Frontend UI refer to the [Pixel Streaming Frontend UI documentation](https://github.com/EpicGames/PixelStreamingInfrastructure#readme). From d7a230831db00a9861942f68869deb3e95bfd00c Mon Sep 17 00:00:00 2001 From: Denis Phoenix <127062860+DenisTensorWorks@users.noreply.github.com> Date: Tue, 18 Jun 2024 09:36:00 +1000 Subject: [PATCH 07/13] Update frontend_utilisation_guide.md - Final changes. Facelift --- docs/frontend_utilisation_guide.md | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/docs/frontend_utilisation_guide.md b/docs/frontend_utilisation_guide.md index 82be03a0..33567f20 100644 --- a/docs/frontend_utilisation_guide.md +++ b/docs/frontend_utilisation_guide.md @@ -229,8 +229,6 @@ if(webSocketAddress != ""){ } ``` -## Scalable Pixel Streaming Frontend customisation -By default the Scalable Pixel Streaming Frontend Library contains all the requirements to connect to a Scalable Pixel Streaming signalling server making it an effective starting template for further customisation rather than starting from scratch. It is able to achieve this functionality through its consumption of the Epic Games Pixel Streaming Frontend. To learn more about further utilising the Epic Games Pixel Streaming Frontend documentation can be found [here](https://github.com/EpicGames/PixelStreamingInfrastructure#readme). +## SPS frontend and frontend UI customisation -### Scalable Pixel Streaming Frontend UI element customisation -Further customisation of UI elements like overlays or visual elements can also be achieved by utilising the Pixel Streaming Frontend UI and extending its types. For further information on how to utilise the Epic Games Pixel Streaming Frontend UI refer to the [Pixel Streaming Frontend UI documentation](https://github.com/EpicGames/PixelStreamingInfrastructure#readme). +Refer to [the official Pixel Streaming repository documentation](https://github.com/EpicGamesExt/PixelStreamingInfrastructure#readme) to learn more about further utilising the Epic Games Pixel Streaming frontend and frontend UI. Utilise the supplied SPS frontend library as a template for further customization, and leverage Pixel Streaming frontend UI types to further customise UI elements, such as overlays and visual elements. From e567e78ba7a723618e6db858d4a2cce720e27dc1 Mon Sep 17 00:00:00 2001 From: Denis Phoenix <127062860+DenisTensorWorks@users.noreply.github.com> Date: Tue, 18 Jun 2024 09:37:09 +1000 Subject: [PATCH 08/13] Update api_transition_guide.md - Spell check --- docs/api_transition_guide.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/api_transition_guide.md b/docs/api_transition_guide.md index 101e943a..9299d268 100644 --- a/docs/api_transition_guide.md +++ b/docs/api_transition_guide.md @@ -1,8 +1,8 @@ # Migrating from `libspsfrontend` predating `v0.1.4` -SPS frontend changed to use the [Epic Games Pixel Streaming frontend](https://github.com/EpicGames/PixelStreamingInfrastructure/tree/master/Frontend) since version `0.1.4`, which involed mdofications both to our API and NPM packages. +SPS frontend changed to use the [Epic Games Pixel Streaming frontend](https://github.com/EpicGames/PixelStreamingInfrastructure/tree/master/Frontend) since version `0.1.4`, which involved modifications both to our API and NPM packages. -Below aresome common usage of the SPS Frontend API that has changed. Note that this list is not exhaustive, if you encounter more differences, please open an issue on this repository to report them. +Below are some common usages of the SPS frontend API that have changed. Note that this list is not exhaustive, if you encounter more differences, please open an issue on this repository to report them. ### Listening for UE messages From 5bd39ed839968f2a623f3c044c5188fdd380f923 Mon Sep 17 00:00:00 2001 From: Denis Phoenix <127062860+DenisTensorWorks@users.noreply.github.com> Date: Tue, 18 Jun 2024 09:40:51 +1000 Subject: [PATCH 09/13] Update frontend_utilisation_guide.md - Spell check --- docs/frontend_utilisation_guide.md | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/docs/frontend_utilisation_guide.md b/docs/frontend_utilisation_guide.md index 33567f20..80ecbaf3 100644 --- a/docs/frontend_utilisation_guide.md +++ b/docs/frontend_utilisation_guide.md @@ -2,17 +2,17 @@ ## Overview -The Scalable Pixel Streaming (SPS) frontend is a library of HTML, CSS, and TypeScript code that runs in web browsers and allows users to connect and interact with Scalable Pixel Streaming applications. It consumes the Epic Games Pixel Streaming frontend and UI libraries, and extends their signalling server and WebSocket packages. Note that the Epic Games Pixel Streaming frontend can be configured to work with Scalable Pixel Streaming signalling severs. +The Scalable Pixel Streaming (SPS) frontend is a library of HTML, CSS, and TypeScript code that runs in web browsers and allows users to connect and interact with Scalable Pixel Streaming applications. It consumes the Epic Games Pixel Streaming frontend and UI libraries and extends their signalling server and WebSocket packages. Note that the Epic Games Pixel Streaming frontend can be configured to work with Scalable Pixel Streaming signalling servers. ## Epic Games Pixel Streaming frontend and UI frontend NPM packages -NPM packages consumed by SPS frontend are: +NPM packages consumed by the SPS frontend are: - [Pixel Streaming Frontend UI](https://www.npmjs.com/package/@epicgames-ps/lib-pixelstreamingfrontend-ui-ue5.4) -### Pixel Streaming Frontend +### Pixel Streaming frontend -NPM package for the Pixel Streaming frontend consumed by SPS is located [here](https://www.npmjs.com/package/@epicgames-ps/lib-pixelstreamingfrontend-ue5.4). +The NPM package for the Pixel Streaming frontend consumed by SPS is located [here](https://www.npmjs.com/package/@epicgames-ps/lib-pixelstreamingfrontend-ue5.4). It contains the following functionality: @@ -23,9 +23,9 @@ It contains the following functionality: - Video and audio stream handling; - Logic for: AFK, FreezeFrames, Mic, TURN, SDP. -### Pixel Streaming Frontend UI +### Pixel Streaming frontend UI -NPM package for the Pixel Streaming UI frontend consumed by SPS is located [here](https://www.npmjs.com/package/@epicgames-ps/lib-pixelstreamingfrontend-ui-ue5.4). +The NPM package for the Pixel Streaming UI frontend consumed by SPS is located [here](https://www.npmjs.com/package/@epicgames-ps/lib-pixelstreamingfrontend-ui-ue5.4). It contains the following functionality: @@ -38,15 +38,15 @@ It contains the following functionality: ## SPS frontend packages -### SPS frontend Library +### SPS frontend library -The library includes all of the custom signalling logic that Scalable Pixel Streaming signalling servers require to work. The library can be either obtained through [GitHub](https://github.com/ScalablePixelStreaming/Frontend) or [NPM](https://www.npmjs.com/package/@tensorworks/libspsfrontend). The library must be initialised via HTML and Javascript. It is written in TypeScript, but configured to export as a UMD module and can be consumed by plain JavaScript and most JavaScript frameworks. +The library includes all of the custom signalling logic that Scalable Pixel Streaming signalling servers require to work. The library can be obtained either through [GitHub](https://github.com/ScalablePixelStreaming/Frontend) or [NPM](https://www.npmjs.com/package/@tensorworks/libspsfrontend). The library must be initialised via HTML and Javascript. It is written in TypeScript, but configured to export as a UMD module and can be consumed by plain JavaScript and most JavaScript frameworks. ### SPS frontend TypeScript example -Our [TypeScript example](https://github.com/ScalablePixelStreaming/Frontend/tree/main/examples/typescript) is a simple HTML, CSS, and TypeScript implementation that initializes the SPS frontend library by instantiating the library components and starting a connection to the signalling server. +Our [TypeScript example](https://github.com/ScalablePixelStreaming/Frontend/tree/main/examples/typescript) is a simple HTML, CSS, and TypeScript implementation that initialises the SPS frontend library by instantiating the library components and starting a connection to the signalling server. -## Installing and consumping SPS packages +## Installing and consuming SPS packages Download the [SPS frontend source code from GitHub](https://github.com/ScalablePixelStreaming/Frontend). @@ -145,7 +145,7 @@ const spsApplication = new SPSApplication({ }); ``` -8) Append the `spsApplication.rootElement` inside a DOM element of your choice or inject directly into the body of the web page like in the TypeScript example: +8) Append the `spsApplication.rootElement` inside a DOM element of your choice or inject directly into the body of the web page, like in the TypeScript example: ```typescript document.body.appendChild(spsApplication.rootElement); @@ -185,7 +185,7 @@ When serving the SPS frontend, it will build a default WebSocket address to conn #### The .env file for the TypeScript example -In the TypeScript example there is a `.env.example` file containing a filler URL in the `WEBSOCKET_URL` line. This file can be used to hard code a WebSocket address that can be consumed by the example as shown above. This example is able to work with the help of the [dotenv NPM package](https://www.npmjs.com/package/dotenv) in the `webpack.common.js` file in the TypeScript example. To implement this example follow these steps: +In the TypeScript example, there is a `.env.example` file containing a filler URL in the `WEBSOCKET_URL` line. This file can be used to hard code a WebSocket address that can be consumed by the example as shown above. This example is able to work with the help of the [dotenv NPM package](https://www.npmjs.com/package/dotenv) in the `webpack.common.js` file in the TypeScript example. To implement this example, follow these steps: 1) Rename the `.env.example` to `.env`. 2) Replace the placeholder URL with the WebSocket URL you wish to consume. @@ -208,7 +208,7 @@ new webpack.DefinePlugin({ }), ``` -4) Create the `.env` file in the path you set in the rpevious step with the variable of your choice: +4) Create the `.env` file in the path you set in the previous step with the variable of your choice: ```bash WEBSOCKET_URL=ws://example.com/your/ws @@ -231,4 +231,4 @@ if(webSocketAddress != ""){ ## SPS frontend and frontend UI customisation -Refer to [the official Pixel Streaming repository documentation](https://github.com/EpicGamesExt/PixelStreamingInfrastructure#readme) to learn more about further utilising the Epic Games Pixel Streaming frontend and frontend UI. Utilise the supplied SPS frontend library as a template for further customization, and leverage Pixel Streaming frontend UI types to further customise UI elements, such as overlays and visual elements. +Refer to [the official Pixel Streaming repository documentation](https://github.com/EpicGamesExt/PixelStreamingInfrastructure#readme) to learn more about further utilising the Epic Games Pixel Streaming frontend and frontend UI. Utilise the supplied SPS frontend library as a template for further customisation, and leverage Pixel Streaming frontend UI types to further customise UI elements, such as overlays and visual elements. From 4cefc1a35e12445870e0c97aab55c88839a8e6c1 Mon Sep 17 00:00:00 2001 From: Denis Phoenix <127062860+DenisTensorWorks@users.noreply.github.com> Date: Tue, 18 Jun 2024 09:42:56 +1000 Subject: [PATCH 10/13] Update README.md - Spell check --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index ce612cb7..45da6489 100644 --- a/README.md +++ b/README.md @@ -19,13 +19,13 @@ All SPS versions since `v0.1.4` are using the current version of Epic Games Pixe ### Scalable Pixel Streaming frontend reference -The Scalable Pixel Streaming frontend is a part of a complex system which abstracts a lot of its complexities behind the library. Refer to our [reference guide](./docs/sps_frontend_refrence_guide.md) to gain a deeper understanding of how the SPS frontend fits within Scalable Pixel Streaming as a whole. +The Scalable Pixel Streaming frontend is part of a complex system that abstracts a lot of its complexities behind the library. Refer to our [reference guide](./docs/sps_frontend_refrence_guide.md) to gain a deeper understanding of how the SPS frontend fits within Scalable Pixel Streaming as a whole. ## Issues As the SPS frontend is an implementation of the Epic Games Pixel Streaming frontend, the majority of issues will pertain to the Epic Games frontend and should be reported on [their repository](https://github.com/EpicGamesExt/PixelStreamingInfrastructure/issues). -If you encounter an issues specific to the SPS implementation, please report your issue [here](https://github.com/ScalablePixelStreaming/Frontend/issues). +If you encounter an issue specific to the SPS implementation, please report it [here](https://github.com/ScalablePixelStreaming/Frontend/issues). ## Legal From 6fa75f26c043721f031ca4071d4d8c648bcd4180 Mon Sep 17 00:00:00 2001 From: Denis Phoenix <127062860+DenisTensorWorks@users.noreply.github.com> Date: Tue, 16 Jul 2024 10:36:43 +1000 Subject: [PATCH 11/13] Update frontend_utilisation_guide.md --- docs/frontend_utilisation_guide.md | 4 ---- 1 file changed, 4 deletions(-) diff --git a/docs/frontend_utilisation_guide.md b/docs/frontend_utilisation_guide.md index 80ecbaf3..f49e826b 100644 --- a/docs/frontend_utilisation_guide.md +++ b/docs/frontend_utilisation_guide.md @@ -6,10 +6,6 @@ The Scalable Pixel Streaming (SPS) frontend is a library of HTML, CSS, and TypeS ## Epic Games Pixel Streaming frontend and UI frontend NPM packages -NPM packages consumed by the SPS frontend are: - -- [Pixel Streaming Frontend UI](https://www.npmjs.com/package/@epicgames-ps/lib-pixelstreamingfrontend-ui-ue5.4) - ### Pixel Streaming frontend The NPM package for the Pixel Streaming frontend consumed by SPS is located [here](https://www.npmjs.com/package/@epicgames-ps/lib-pixelstreamingfrontend-ue5.4). From e59d787e38b8498f257b5d98d7c8105d7bf8be74 Mon Sep 17 00:00:00 2001 From: David MacPherson Date: Tue, 16 Jul 2024 13:39:42 +1000 Subject: [PATCH 12/13] Added better styling to code sample --- docs/frontend_utilisation_guide.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/docs/frontend_utilisation_guide.md b/docs/frontend_utilisation_guide.md index f49e826b..2ad38fbd 100644 --- a/docs/frontend_utilisation_guide.md +++ b/docs/frontend_utilisation_guide.md @@ -137,7 +137,8 @@ if(webSocketAddress != ""){ const stream = new PixelStreaming(config); const spsApplication = new SPSApplication({ stream, - onColorModeChanged: (isLightMode) => PixelStreamingApplicationStyles.setColorMode(isLightMode) /* Light/Dark mode support. */ + onColorModeChanged: (isLightMode) => + PixelStreamingApplicationStyles.setColorMode(isLightMode) /* Light/Dark mode support. */ }); ``` From 38e9b29ae370b3b6c44eafa6f00deb972b508f6b Mon Sep 17 00:00:00 2001 From: David MacPherson Date: Tue, 16 Jul 2024 14:17:11 +1000 Subject: [PATCH 13/13] Updated docs --- docs/frontend_utilisation_guide.md | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/docs/frontend_utilisation_guide.md b/docs/frontend_utilisation_guide.md index 2ad38fbd..33f19026 100644 --- a/docs/frontend_utilisation_guide.md +++ b/docs/frontend_utilisation_guide.md @@ -134,12 +134,19 @@ if(webSocketAddress != ""){ 7) Create an instance of the `PixelStreaming` object called `stream` and an instance of the `SPSApplication` object called `spsApplication`: ```typescript + +// Create stream and spsApplication instances that implement the Epic Games Pixel Streaming Frontend PixelStreaming and Application types const stream = new PixelStreaming(config); -const spsApplication = new SPSApplication({ - stream, - onColorModeChanged: (isLightMode) => - PixelStreamingApplicationStyles.setColorMode(isLightMode) /* Light/Dark mode support. */ -}); + +// Create our SPS application and pass it some UI configuration options. +// Note: There are more options than this if you need them (e.g. turning off certain UI elements). +const uiOptions: UIOptions = { + stream: stream, + onColorModeChanged: (isLightMode) => PixelStreamingApplicationStyles.setColorMode(isLightMode) /* Light/Dark mode support. */ +}; + +// Create our application +const spsApplication: SPSApplication = new SPSApplication(uiOptions); ``` 8) Append the `spsApplication.rootElement` inside a DOM element of your choice or inject directly into the body of the web page, like in the TypeScript example: