1
1
// Copyright Epic Games, Inc. All Rights Reserved.
2
2
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 ( ) ;
7
9
PixelStreamingApplicationStyles . applyStyleSheet ( ) ;
8
10
9
11
export class PixelStreamingFrame {
10
- element : HTMLElement ;
11
- pixelStreamingApp : Application ;
12
+ element : HTMLElement ;
13
+ pixelStreamingApp : Application ;
12
14
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
+ }
17
19
}
18
20
19
21
// This is the entrypoint to the stress test, all setup happens here
20
22
export 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
+ }
176
180
}
177
181
178
182
const tester = new StressTester ( ) ;
179
- tester . startStressTest ( ) ;
183
+ tester . startStressTest ( ) ;
184
+
0 commit comments