This repository has been archived by the owner on Mar 1, 2024. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 258
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Minimal sample React implementation (#159)
* Minimal sample React implementation * Added step-by-step comments explaining how PixelStreamingWrapper works
- Loading branch information
Showing
19 changed files
with
4,622 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
dist/ | ||
docs/ | ||
node_modules/ | ||
types/ | ||
package-lock.json | ||
package.json | ||
.cspell.json | ||
tsconfig.json | ||
webpack.config.js | ||
.eslintrc.js | ||
.vscode |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
{ | ||
"trailingComma": "none", | ||
"tabWidth": 4, | ||
"semi": true, | ||
"singleQuote": true | ||
} |
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
{ | ||
"name": "@epicgames-ps/reference-pixelstreamingfrontend-react-ue5.2", | ||
"version": "0.0.1", | ||
"description": "", | ||
"main": "./src/index.tsx", | ||
"scripts": { | ||
"build": "npx webpack --config webpack.prod.js", | ||
"build-dev": "npx webpack --config webpack.dev.js", | ||
"watch": "npx webpack --watch", | ||
"serve": "webpack serve --config webpack.dev.js", | ||
"serve-prod": "webpack serve --config webpack.prod.js", | ||
"build-all": "npm link ../../library && cd ../../library && npm run build && cd ../implementations/react && npm run build", | ||
"build-dev-all": "npm link ../../library && cd ../../library && npm run build-dev && cd ../implementations/react && npm run build-dev" | ||
}, | ||
"devDependencies": { | ||
"@types/react": "^18.0.28", | ||
"@types/react-dom": "^18.0.11", | ||
"css-loader": "^6.7.3", | ||
"html-loader": "^4.2.0", | ||
"html-webpack-plugin": "^5.5.0", | ||
"path": "^0.12.7", | ||
"ts-loader": "^9.4.2", | ||
"typescript": "^4.9.4", | ||
"webpack": "^5.76.0", | ||
"webpack-cli": "^5.0.1", | ||
"webpack-dev-server": "^4.11.1" | ||
}, | ||
"dependencies": { | ||
"react": "^18.2.0", | ||
"react-dom": "^18.2.0" | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
## Pixel Streaming sample React application | ||
|
||
A minimal sample application that uses the Pixel Streaming library in React. | ||
|
||
### Key features | ||
- A minimal React application with a Pixel Streaming wrapper component | ||
- Starts a Pixel Streaming session on wrapper component mount | ||
- Disconnects the session on wrapper component unmount e.g. if navigating to another view in a single page app | ||
- Hooks to `playStreamRejected` event and displays a `Click to play` overlay if the browser rejects video stream auto-play | ||
|
||
### Developing | ||
|
||
To build and run the React application, run: | ||
|
||
- `npm install` | ||
- `npm run build-all` | ||
- `npm run serve` |
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file not shown.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
// Copyright Epic Games, Inc. All Rights Reserved. | ||
|
||
import React from 'react'; | ||
import { PixelStreamingWrapper } from './PixelStreamingWrapper'; | ||
|
||
export const App = () => { | ||
return ( | ||
<div | ||
style={{ | ||
height: '100%', | ||
width: '100%' | ||
}} | ||
> | ||
<PixelStreamingWrapper | ||
initialSettings={{ | ||
AutoPlayVideo: true, | ||
AutoConnect: true, | ||
ss: 'ws://localhost:80', | ||
StartVideoMuted: true, | ||
HoveringMouse: true | ||
}} | ||
/> | ||
</div> | ||
); | ||
}; |
90 changes: 90 additions & 0 deletions
90
Frontend/implementations/react/src/components/PixelStreamingWrapper.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,90 @@ | ||
// Copyright Epic Games, Inc. All Rights Reserved. | ||
|
||
import React, { useEffect, useRef, useState } from 'react'; | ||
import { | ||
Config, | ||
AllSettings, | ||
PixelStreaming | ||
} from '@epicgames-ps/lib-pixelstreamingfrontend-ue5.2'; | ||
|
||
export interface PixelStreamingWrapperProps { | ||
initialSettings?: Partial<AllSettings>; | ||
} | ||
|
||
export const PixelStreamingWrapper = ({ | ||
initialSettings | ||
}: PixelStreamingWrapperProps) => { | ||
// A reference to parent div element that the Pixel Streaming library attaches into: | ||
const videoParent = useRef<HTMLDivElement>(null); | ||
|
||
// Pixel streaming library instance is stored into this state variable after initialization: | ||
const [pixelStreaming, setPixelStreaming] = useState<PixelStreaming>(); | ||
|
||
// A boolean state variable that determines if the Click to play overlay is shown: | ||
const [clickToPlayVisible, setClickToPlayVisible] = useState(false); | ||
|
||
// Run on component mount: | ||
useEffect(() => { | ||
if (videoParent.current) { | ||
// Attach Pixel Streaming library to videoParent element: | ||
const config = new Config({ initialSettings }); | ||
const streaming = new PixelStreaming(config, { | ||
videoElementParent: videoParent.current | ||
}); | ||
|
||
// register a playStreamRejected handler to show Click to play overlay if needed: | ||
streaming.addEventListener('playStreamRejected', () => { | ||
setClickToPlayVisible(true); | ||
}); | ||
|
||
// Save the library instance into component state so that it can be accessed later: | ||
setPixelStreaming(streaming); | ||
|
||
// Clean up on component unmount: | ||
return () => { | ||
try { | ||
streaming.disconnect(); | ||
} catch {} | ||
}; | ||
} | ||
}, []); | ||
|
||
return ( | ||
<div | ||
style={{ | ||
width: '100%', | ||
height: '100%', | ||
position: 'relative' | ||
}} | ||
> | ||
<div | ||
style={{ | ||
width: '100%', | ||
height: '100%' | ||
}} | ||
ref={videoParent} | ||
/> | ||
{clickToPlayVisible && ( | ||
<div | ||
style={{ | ||
position: 'absolute', | ||
top: 0, | ||
left: 0, | ||
width: '100%', | ||
height: '100%', | ||
display: 'flex', | ||
alignItems: 'center', | ||
justifyContent: 'center', | ||
cursor: 'pointer' | ||
}} | ||
onClick={() => { | ||
pixelStreaming?.play(); | ||
setClickToPlayVisible(false); | ||
}} | ||
> | ||
<div>Click to play</div> | ||
</div> | ||
)} | ||
</div> | ||
); | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
<!-- Copyright Epic Games, Inc. All Rights Reserved. --> | ||
<!DOCTYPE HTML> | ||
<html style="width: 100%; height: 100%"> | ||
<head> | ||
<meta charset="utf-8"> | ||
<meta name="viewport" content="width=device-width, initial-scale=1"> | ||
|
||
<!-- Optional: apply a font --> | ||
<link rel="preconnect" href="https://fonts.googleapis.com"> | ||
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin> | ||
<link href="https://fonts.googleapis.com/css2?family=Michroma&family=Montserrat:wght@600&display=swap" rel="stylesheet"> | ||
|
||
<!-- Optional: set some favicons --> | ||
<link rel="shortcut icon" href="./assets/images/favicon.ico" type="image/x-icon"> | ||
<link rel="icon" type="image/png" sizes="96x96" href="./assets/images/favicon-96x96.png"> | ||
<link rel="icon" type="image/png" sizes="32x32" href="./assets/images/favicon-32x32.png"> | ||
<link rel="icon" type="image/png" sizes="16x16" href="./assets/images/favicon-16x16.png"> | ||
|
||
<!-- Optional: set a title for your page --> | ||
<title>Pixel Streaming</title> | ||
</head> | ||
|
||
<!-- The Pixel Streaming player fills 100% of its parent element but body has a 0px height unless filled with content. As such, we explicitly force the body to be 100% of the viewport height --> | ||
<body style="width: 100vw; height: 100vh; min-height: -webkit-fill-available; font-family: 'Montserrat'; margin: 0px"> | ||
|
||
</body> | ||
|
||
</html> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
// Copyright Epic Games, Inc. All Rights Reserved. | ||
import React from 'react'; | ||
import { createRoot } from 'react-dom/client'; | ||
import { App } from './components/App'; | ||
|
||
document.body.onload = function () { | ||
// Attach the React app root component to document.body | ||
createRoot(document.body).render(<App />); | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
{ | ||
"compilerOptions": { | ||
"outDir": "./dist", | ||
"noImplicitAny": true, | ||
"module": "es6", | ||
"esModuleInterop": true, | ||
"target": "es5", | ||
"moduleResolution": "node", | ||
"sourceMap": false, | ||
"allowJs": true, | ||
"declaration": false, | ||
"jsx": "react-jsx" | ||
}, | ||
"lib": ["es2015"], | ||
"include": ["./src/*.tsx"], | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,75 @@ | ||
// Copyright Epic Games, Inc. All Rights Reserved. | ||
|
||
const path = require('path'); | ||
const HtmlWebpackPlugin = require('html-webpack-plugin'); | ||
const webpack = require('webpack'); | ||
const fs = require('fs'); | ||
|
||
const pages = fs.readdirSync('./src', { withFileTypes: true }) | ||
.filter(item => !item.isDirectory()) | ||
.filter(item => path.parse(item.name).ext === '.html') | ||
.map(htmlFile => path.parse(htmlFile.name).name); | ||
|
||
module.exports = { | ||
entry: pages.reduce((config, page) => { | ||
config[page] = `./src/${page}.tsx`; | ||
return config; | ||
}, {}), | ||
|
||
plugins: [].concat(pages.map((page) => new HtmlWebpackPlugin({ | ||
title: `${page}`, | ||
template: `./src/${page}.html`, | ||
filename: `${page}.html`, | ||
chunks: [page], | ||
}), )), | ||
|
||
module: { | ||
rules: [ | ||
{ | ||
test: /\.tsx?$/, | ||
loader: 'ts-loader', | ||
exclude: [ | ||
/node_modules/, | ||
], | ||
}, | ||
{ | ||
test: /\.html$/i, | ||
use: 'html-loader' | ||
}, | ||
{ | ||
test: /\.css$/, | ||
type: 'asset/resource', | ||
generator: { | ||
filename: 'css/[name][ext]' | ||
} | ||
}, | ||
{ | ||
test: /\.(png|svg)$/i, | ||
type: 'asset/resource', | ||
generator: { | ||
filename: 'images/[name][ext]' | ||
} | ||
}, | ||
], | ||
}, | ||
resolve: { | ||
extensions: ['.tsx', '.ts', '.js', '.svg', '.json'], | ||
}, | ||
output: { | ||
filename: '[name].js', | ||
library: 'epicgames-react-frontend', | ||
libraryTarget: 'umd', | ||
path: path.resolve(__dirname, '../../../SignallingWebServer/Public'), | ||
clean: true, | ||
globalObject: 'this', | ||
hashFunction: 'xxhash64', | ||
}, | ||
experiments: { | ||
futureDefaults: true | ||
}, | ||
devServer: { | ||
static: { | ||
directory: path.join(__dirname, '../../../SignallingWebServer/Public'), | ||
}, | ||
}, | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
// Copyright Epic Games, Inc. All Rights Reserved. | ||
|
||
const { merge } = require('webpack-merge'); | ||
const common = require('./webpack.common.js'); | ||
const path = require('path'); | ||
|
||
module.exports = merge(common, { | ||
mode: 'development', | ||
devtool: 'inline-source-map' | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
// Copyright Epic Games, Inc. All Rights Reserved. | ||
|
||
const { merge } = require('webpack-merge'); | ||
const common = require('./webpack.common.js'); | ||
|
||
module.exports = merge(common, { | ||
mode: 'production', | ||
optimization: { | ||
usedExports: true, | ||
minimize: true | ||
}, | ||
stats: 'errors-only', | ||
performance: { | ||
hints: false | ||
} | ||
}); |