11// Copyright Epic Games, Inc. All Rights Reserved.
22
3- import { Config , Flags , PixelStreaming } from '@epicgames-ps/lib-pixelstreamingfrontend-ue5.5' ;
4- import { Application , PixelStreamingApplicationStyle } from '@epicgames-ps/lib-pixelstreamingfrontend-ui-ue5.5' ;
5- const PixelStreamingApplicationStyles =
6- new PixelStreamingApplicationStyle ( ) ;
3+ import { Config , Flags , PixelStreaming , Logger , LogLevel } from '@epicgames-ps/lib-pixelstreamingfrontend-ue5.5' ;
4+ import {
5+ Application ,
6+ PixelStreamingApplicationStyle
7+ } from '@epicgames-ps/lib-pixelstreamingfrontend-ui-ue5.5' ;
8+ const PixelStreamingApplicationStyles = new PixelStreamingApplicationStyle ( ) ;
79PixelStreamingApplicationStyles . applyStyleSheet ( ) ;
810
911export class PixelStreamingFrame {
10- element : HTMLElement ;
11- pixelStreamingApp : Application ;
12+ element : HTMLElement ;
13+ pixelStreamingApp : Application ;
1214
13- constructor ( element : HTMLElement , pixelStreamingApp : Application ) {
14- this . element = element ;
15- this . pixelStreamingApp = pixelStreamingApp ;
16- }
15+ constructor ( element : HTMLElement , pixelStreamingApp : Application ) {
16+ this . element = element ;
17+ this . pixelStreamingApp = pixelStreamingApp ;
18+ }
1719}
1820
1921// This is the entrypoint to the stress test, all setup happens here
2022export class StressTester {
21- play : boolean ;
22- maxPeers : number ;
23- totalStreams : number ;
24- streamCreationIntervalMs : number ;
25- streamDeletionIntervalMs : number ;
26- pixelStreamingFrames : Array < PixelStreamingFrame > ;
27- creationIntervalHandle : number ;
28- deletionIntervalHandle : number ;
29- streamsContainer : HTMLElement ;
30-
31- constructor ( ) {
32- this . play = false ;
33- this . maxPeers = 3 ;
34- this . totalStreams = 0 ;
35- this . streamCreationIntervalMs = 1000 ;
36- this . streamDeletionIntervalMs = 4000 ;
37- this . pixelStreamingFrames = [ ] ;
38- this . creationIntervalHandle = null ;
39- this . deletionIntervalHandle = null ;
40- // Get a container to put the "Pixel Streaming" pages in.
41- this . streamsContainer = document . getElementById ( "streamsContainer" ) ;
42- }
43-
44- startStressTest ( ) : void {
45- this . setupNumPeersSlider ( ) ;
46- this . startStreamCreation ( ) ;
47- this . startStreamDeletion ( ) ;
48- this . setupPlayPause ( ) ;
49-
50- document . getElementById ( "creationIntervalInput" ) . onchange = ( event : Event ) => {
51- const inputElem = document . getElementById ( "creationIntervalInput" ) as HTMLInputElement ;
52- const parsedValue = Number . parseInt ( inputElem . value ) ;
53- if ( ! Number . isNaN ( parsedValue ) ) {
54- this . streamCreationIntervalMs = parsedValue * 1000.0 ;
55- this . startStreamCreation ( ) ;
56- }
57- }
58-
59- document . getElementById ( "deletionIntervalInput" ) . onchange = ( event : Event ) => {
60- const inputElem = document . getElementById ( "deletionIntervalInput" ) as HTMLInputElement ;
61- const parsedValue = Number . parseInt ( inputElem . value ) ;
62- if ( ! Number . isNaN ( parsedValue ) ) {
63- this . streamDeletionIntervalMs = parsedValue * 1000.0 ;
64- this . startStreamDeletion ( ) ;
65- }
66- }
67-
68- const creationIntervalInput = document . getElementById ( "creationIntervalInput" ) as HTMLInputElement ;
69- creationIntervalInput . value = ( this . streamCreationIntervalMs / 1000.0 ) . toString ( ) ;
70-
71- const deletionIntervalInput = document . getElementById ( "deletionIntervalInput" ) as HTMLInputElement ;
72- deletionIntervalInput . value = ( this . streamDeletionIntervalMs / 1000.0 ) . toString ( ) ;
73- }
74-
75-
76- private setupNumPeersSlider ( ) : void {
77- const nPeersSlider : HTMLInputElement = document . getElementById ( "nPeersSlider" ) as HTMLInputElement ;
78- nPeersSlider . value = this . maxPeers . toString ( ) ;
79-
80- const nPeersLabel : HTMLElement = document . getElementById ( "nPeerLabel" ) ;
81- nPeersLabel . innerHTML = this . maxPeers . toString ( ) ;
82-
83- nPeersSlider . onchange = ( event : Event ) => {
84- const inputElem = event . target as HTMLInputElement ;
85- const parsedValue = Number . parseInt ( inputElem . value ) ;
86-
87- if ( ! Number . isNaN ( parsedValue ) ) {
88- this . maxPeers = parsedValue ;
89- const nPeersLabel : HTMLElement = document . getElementById ( "nPeerLabel" ) ;
90- nPeersLabel . innerHTML = this . maxPeers . toString ( ) ;
91- }
92- }
93- }
94-
95- private startStreamCreation ( ) : void {
96- if ( this . creationIntervalHandle ) {
97- clearInterval ( this . creationIntervalHandle ) ;
98- }
99-
100- this . creationIntervalHandle = window . setInterval ( ( ) => {
101- if ( this . play ) {
102- const curNPeers = this . pixelStreamingFrames . length ;
103- if ( curNPeers >= this . maxPeers ) return ;
104-
105- const maxPeersToCreate = this . maxPeers - curNPeers ;
106- const nPeersToCreate = Math . ceil ( Math . random ( ) * maxPeersToCreate ) ;
107-
108- for ( let i = 0 ; i < nPeersToCreate ; i ++ ) {
109- const psFrame = this . createPixelStreamingFrame ( ) ;
110- const n = this . pixelStreamingFrames . length ;
111- psFrame . element . id = `PixelStreamingFrame_${ n + 1 } ` ;
112- this . streamsContainer . append ( psFrame . element ) ;
113- this . pixelStreamingFrames . push ( psFrame ) ;
114- this . totalStreams += 1 ;
115- this . updateTotalStreams ( ) ;
116- }
117- }
118- } , this . streamCreationIntervalMs ) ;
119- }
120-
121- private startStreamDeletion ( ) : void {
122- if ( this . deletionIntervalHandle ) {
123- clearInterval ( this . deletionIntervalHandle )
124- }
125-
126- this . deletionIntervalHandle = window . setInterval ( ( ) => {
127- if ( ! this . play ) return ;
128-
129- const curNPeers = this . pixelStreamingFrames . length ;
130- if ( curNPeers === 0 ) return ;
131-
132- const nPeersToDelete = Math . ceil ( Math . random ( ) * curNPeers ) ;
133- for ( let i = 0 ; i < nPeersToDelete ; i ++ ) {
134- const psFrame = this . pixelStreamingFrames . shift ( ) ;
135- // Remove HTML element from DOM
136- psFrame . element . parentNode . removeChild ( psFrame . element ) ;
137- // Disconnect Pixel Streaming application so we don't have orphaned WebRTC/WebSocket/PeerConnections
138- psFrame . pixelStreamingApp . stream . disconnect ( ) ;
139- }
140- } , this . streamDeletionIntervalMs ) ;
141- }
142-
143- private setupPlayPause ( ) : void {
144- const playPauseBtn = document . getElementById ( "playPause" ) ;
145- playPauseBtn . innerHTML = this . play ? "Pause" : "Play" ;
146-
147- playPauseBtn . onclick = ( event : Event ) => {
148- this . play = ! this . play ;
149- playPauseBtn . innerHTML = this . play ? "Pause" : "Play" ;
150- }
151- }
152-
153- private createPixelStreamingFrame ( ) : PixelStreamingFrame {
154- const streamFrame = document . createElement ( "div" ) ;
155-
156- const config = new Config ( ) ;
157- config . setFlagEnabled ( Flags . AutoConnect , true ) ;
158- config . setFlagEnabled ( Flags . AutoPlayVideo , true ) ;
159- config . setFlagEnabled ( Flags . StartVideoMuted , true ) ;
160-
161- // Create a Native DOM delegate instance that implements the Delegate interface class
162- const stream = new PixelStreaming ( config ) ;
163- const application = new Application ( {
164- stream,
165- onColorModeChanged : ( isLightMode : any ) => PixelStreamingApplicationStyles . setColorMode ( isLightMode )
166- } ) ;
167- streamFrame . appendChild ( application . rootElement ) ;
168-
169- return new PixelStreamingFrame ( streamFrame , application ) ;
170- }
171-
172- private updateTotalStreams ( ) : void {
173- const nStreamsLabel = document . getElementById ( "nStreamsLabel" ) ;
174- nStreamsLabel . innerHTML = this . totalStreams . toString ( ) ;
175- }
23+ play : boolean ;
24+ maxPeers : number ;
25+ totalStreams : number ;
26+ streamCreationIntervalMs : number ;
27+ streamDeletionIntervalMs : number ;
28+ pixelStreamingFrames : Array < PixelStreamingFrame > ;
29+ creationIntervalHandle : number ;
30+ deletionIntervalHandle : number ;
31+ streamsContainer : HTMLElement ;
32+
33+ constructor ( ) {
34+ this . play = false ;
35+ this . maxPeers = 3 ;
36+ this . totalStreams = 0 ;
37+ this . streamCreationIntervalMs = 1000 ;
38+ this . streamDeletionIntervalMs = 4000 ;
39+ this . pixelStreamingFrames = [ ] ;
40+ this . creationIntervalHandle = null ;
41+ this . deletionIntervalHandle = null ;
42+ // Get a container to put the "Pixel Streaming" pages in.
43+ this . streamsContainer = document . getElementById ( 'streamsContainer' ) ;
44+ Logger . InitLogging ( LogLevel . Warning , true ) ;
45+ }
46+
47+ startStressTest ( ) : void {
48+ this . setupNumPeersSlider ( ) ;
49+ this . startStreamCreation ( ) ;
50+ this . startStreamDeletion ( ) ;
51+ this . setupPlayPause ( ) ;
52+
53+ document . getElementById ( 'creationIntervalInput' ) . onchange = ( event : Event ) => {
54+ const inputElem = document . getElementById ( 'creationIntervalInput' ) as HTMLInputElement ;
55+ const parsedValue = Number . parseInt ( inputElem . value ) ;
56+ if ( ! Number . isNaN ( parsedValue ) ) {
57+ this . streamCreationIntervalMs = parsedValue * 1000.0 ;
58+ this . startStreamCreation ( ) ;
59+ }
60+ } ;
61+
62+ document . getElementById ( 'deletionIntervalInput' ) . onchange = ( event : Event ) => {
63+ const inputElem = document . getElementById ( 'deletionIntervalInput' ) as HTMLInputElement ;
64+ const parsedValue = Number . parseInt ( inputElem . value ) ;
65+ if ( ! Number . isNaN ( parsedValue ) ) {
66+ this . streamDeletionIntervalMs = parsedValue * 1000.0 ;
67+ this . startStreamDeletion ( ) ;
68+ }
69+ } ;
70+
71+ const creationIntervalInput = document . getElementById ( 'creationIntervalInput' ) as HTMLInputElement ;
72+ creationIntervalInput . value = ( this . streamCreationIntervalMs / 1000.0 ) . toString ( ) ;
73+
74+ const deletionIntervalInput = document . getElementById ( 'deletionIntervalInput' ) as HTMLInputElement ;
75+ deletionIntervalInput . value = ( this . streamDeletionIntervalMs / 1000.0 ) . toString ( ) ;
76+ }
77+
78+ private setupNumPeersSlider ( ) : void {
79+ const nPeersSlider : HTMLInputElement = document . getElementById ( 'nPeersSlider' ) as HTMLInputElement ;
80+ nPeersSlider . value = this . maxPeers . toString ( ) ;
81+
82+ const nPeersLabel : HTMLElement = document . getElementById ( 'nPeerLabel' ) ;
83+ nPeersLabel . innerHTML = this . maxPeers . toString ( ) ;
84+
85+ nPeersSlider . onchange = ( event : Event ) => {
86+ const inputElem = event . target as HTMLInputElement ;
87+ const parsedValue = Number . parseInt ( inputElem . value ) ;
88+
89+ if ( ! Number . isNaN ( parsedValue ) ) {
90+ this . maxPeers = parsedValue ;
91+ const nPeersLabel : HTMLElement = document . getElementById ( 'nPeerLabel' ) ;
92+ nPeersLabel . innerHTML = this . maxPeers . toString ( ) ;
93+ }
94+ } ;
95+ }
96+
97+ private startStreamCreation ( ) : void {
98+ if ( this . creationIntervalHandle ) {
99+ clearInterval ( this . creationIntervalHandle ) ;
100+ }
101+
102+ this . creationIntervalHandle = window . setInterval ( ( ) => {
103+ if ( this . play ) {
104+ const curNPeers = this . pixelStreamingFrames . length ;
105+ if ( curNPeers >= this . maxPeers ) return ;
106+
107+ const maxPeersToCreate = this . maxPeers - curNPeers ;
108+ const nPeersToCreate = Math . ceil ( Math . random ( ) * maxPeersToCreate ) ;
109+
110+ for ( let i = 0 ; i < nPeersToCreate ; i ++ ) {
111+ const psFrame = this . createPixelStreamingFrame ( ) ;
112+ const n = this . pixelStreamingFrames . length ;
113+ psFrame . element . id = `PixelStreamingFrame_${ n + 1 } ` ;
114+ this . streamsContainer . append ( psFrame . element ) ;
115+ this . pixelStreamingFrames . push ( psFrame ) ;
116+ this . totalStreams += 1 ;
117+ this . updateTotalStreams ( ) ;
118+ }
119+ }
120+ } , this . streamCreationIntervalMs ) ;
121+ }
122+
123+ private startStreamDeletion ( ) : void {
124+ if ( this . deletionIntervalHandle ) {
125+ clearInterval ( this . deletionIntervalHandle ) ;
126+ }
127+
128+ this . deletionIntervalHandle = window . setInterval ( ( ) => {
129+ if ( ! this . play ) return ;
130+
131+ const curNPeers = this . pixelStreamingFrames . length ;
132+ if ( curNPeers === 0 ) return ;
133+
134+ const nPeersToDelete = Math . ceil ( Math . random ( ) * curNPeers ) ;
135+ for ( let i = 0 ; i < nPeersToDelete ; i ++ ) {
136+ const psFrame = this . pixelStreamingFrames . shift ( ) ;
137+ // Remove HTML element from DOM
138+ psFrame . element . parentNode . removeChild ( psFrame . element ) ;
139+ // Disconnect Pixel Streaming application so we don't have orphaned WebRTC/WebSocket/PeerConnections
140+ psFrame . pixelStreamingApp . stream . disconnect ( ) ;
141+ psFrame ?. pixelStreamingApp . stream . webRtcController . destroyVideoPlayer ( ) ;
142+ }
143+ } , this . streamDeletionIntervalMs ) ;
144+ }
145+
146+ private setupPlayPause ( ) : void {
147+ const playPauseBtn = document . getElementById ( 'playPause' ) ;
148+ playPauseBtn . innerHTML = this . play ? 'Pause' : 'Play' ;
149+
150+ playPauseBtn . onclick = ( event : Event ) => {
151+ this . play = ! this . play ;
152+ playPauseBtn . innerHTML = this . play ? 'Pause' : 'Play' ;
153+ } ;
154+ }
155+
156+ private createPixelStreamingFrame ( ) : PixelStreamingFrame {
157+ const streamFrame = document . createElement ( 'div' ) ;
158+
159+ const config = new Config ( ) ;
160+ config . setFlagEnabled ( Flags . AutoConnect , true ) ;
161+ config . setFlagEnabled ( Flags . AutoPlayVideo , true ) ;
162+ config . setFlagEnabled ( Flags . StartVideoMuted , true ) ;
163+
164+ // Create a Native DOM delegate instance that implements the Delegate interface class
165+ const stream = new PixelStreaming ( config ) ;
166+ const application = new Application ( {
167+ stream,
168+ onColorModeChanged : ( isLightMode : any ) =>
169+ PixelStreamingApplicationStyles . setColorMode ( isLightMode )
170+ } ) ;
171+ streamFrame . appendChild ( application . rootElement ) ;
172+
173+ return new PixelStreamingFrame ( streamFrame , application ) ;
174+ }
175+
176+ private updateTotalStreams ( ) : void {
177+ const nStreamsLabel = document . getElementById ( 'nStreamsLabel' ) ;
178+ nStreamsLabel . innerHTML = this . totalStreams . toString ( ) ;
179+ }
176180}
177181
178182const tester = new StressTester ( ) ;
179- tester . startStressTest ( ) ;
183+ tester . startStressTest ( ) ;
184+
0 commit comments