@@ -43,6 +43,7 @@ export const Game = {
43
43
init ( { addSource, removeSource, updateSource, getSource } ) {
44
44
// Updated by engine socket events
45
45
let gameSourceStreams : { [ id : string ] : MediaStream } = { }
46
+ let previousTracks : SDK . Track [ ] = [ ]
46
47
// Updated by corecontext events
47
48
let previousGameSources : SDK . Source [ ] = [ ]
48
49
@@ -86,6 +87,125 @@ export const Game = {
86
87
} )
87
88
}
88
89
90
+ CoreContext . on ( 'RoomJoined' , ( { projectId, room } ) => {
91
+ const project = toBaseProject ( getProject ( projectId ) )
92
+ if ( project . role !== SDK . Role . ROLE_RENDERER ) {
93
+ const updatePreviewStreams = ( ) => {
94
+ previousTracks
95
+ . filter ( ( p ) => p ?. type === 'screen_share' && p ?. isExternal === true )
96
+ . forEach ( ( track ) => {
97
+ if ( track . type === 'screen_share' ) {
98
+ const srcObject = gameSourceStreams [ track . participantId ]
99
+ const participant = room . getParticipant ( track . participantId )
100
+ // only do anything if it is for an Game source
101
+ const isGameSource = previousGameSources . some (
102
+ ( source ) => source . id === participant . id ,
103
+ )
104
+ if ( isGameSource ) {
105
+ const videoTrack = room . getTrack ( track . id )
106
+ const source = getSource ( `game-${ participant ?. id } ` )
107
+ if ( source ) {
108
+ const audioTrack = room . getTracks ( ) . find ( ( track ) => {
109
+ return (
110
+ track . participantId === participant . id &&
111
+ track . mediaStreamTrack . kind === 'audio'
112
+ )
113
+ } )
114
+ updateMediaStreamTracks ( srcObject , {
115
+ video : videoTrack ?. mediaStreamTrack ,
116
+ audio : audioTrack ?. mediaStreamTrack ,
117
+ } )
118
+
119
+ updateSource ( `game-${ participant ?. id } ` , {
120
+ videoEnabled : Boolean (
121
+ videoTrack ?. mediaStreamTrack && ! videoTrack . isMuted ,
122
+ ) ,
123
+ audioEnabled : Boolean ( audioTrack && ! audioTrack . isMuted ) ,
124
+ mirrored : participant ?. meta [ track . id ] ?. isMirrored ,
125
+ external : track ?. isExternal ,
126
+ } )
127
+ }
128
+ }
129
+ }
130
+ } )
131
+ }
132
+
133
+ // listen for changes to available tracks
134
+ room . useTracks ( ( tracks ) => {
135
+ // Filter for those that are game-source
136
+ const gameSourceTracks = tracks
137
+ . filter ( ( t ) =>
138
+ previousGameSources . some ( ( s ) => s . id === t . participantId ) ,
139
+ )
140
+ . filter ( ( t ) => [ 'screen_share' ] . includes ( t . type ) )
141
+
142
+ // get tracks not contained in previous tracks
143
+ const newTracks = gameSourceTracks . filter (
144
+ ( track ) =>
145
+ ! previousTracks . some ( ( x ) => x . id === track . id ) &&
146
+ Boolean ( track ?. mediaStreamTrack ) ,
147
+ )
148
+
149
+ // get previous tracks not contained in current tracks
150
+ const removedTracks = previousTracks . filter (
151
+ ( t ) => ! gameSourceTracks . some ( ( x ) => x . id === t . id ) ,
152
+ )
153
+
154
+ // Filter out racks that have a mediaStreamTrack
155
+ previousTracks = gameSourceTracks . filter ( ( t ) =>
156
+ Boolean ( t ?. mediaStreamTrack ) ,
157
+ )
158
+
159
+ removedTracks . forEach ( ( track ) => {
160
+ const { participantId } = track
161
+ const srcObject = gameSourceStreams [ participantId ]
162
+
163
+ if ( track . mediaStreamTrack . kind === 'video' ) {
164
+ updateMediaStreamTracks ( srcObject , {
165
+ video : null ,
166
+ } )
167
+ updateSource ( `game-${ participantId } ` , {
168
+ videoEnabled : false ,
169
+ } )
170
+ }
171
+ if ( track . mediaStreamTrack . kind === 'audio' ) {
172
+ updateMediaStreamTracks ( srcObject , {
173
+ audio : null ,
174
+ } )
175
+ updateSource ( `game-${ participantId } ` , {
176
+ audioEnabled : false ,
177
+ } )
178
+ }
179
+ } )
180
+
181
+ newTracks . forEach ( ( track ) => {
182
+ if (
183
+ track . type === 'screen_share' &&
184
+ track . mediaStreamTrack . kind === 'video'
185
+ ) {
186
+ const srcObject = gameSourceStreams [ track . participantId ]
187
+ const audioTrack = previousTracks . find ( ( t ) => {
188
+ return (
189
+ t . participantId === track . participantId &&
190
+ t . mediaStreamTrack ?. kind === 'audio'
191
+ )
192
+ } )
193
+ updateMediaStreamTracks ( srcObject , {
194
+ video : track ?. mediaStreamTrack ,
195
+ audio : audioTrack ?. mediaStreamTrack ,
196
+ } )
197
+ updateSource ( `game-${ track . participantId } ` , {
198
+ videoEnabled : Boolean ( track && ! track ?. isMuted ) ,
199
+ audioEnabled : Boolean ( audioTrack && ! audioTrack ?. isMuted ) ,
200
+ } )
201
+ }
202
+ } )
203
+
204
+ updatePreviewStreams ( )
205
+ } )
206
+ }
207
+ } )
208
+
89
209
CoreContext . on ( 'ActiveProjectChanged' , ( { projectId } ) => {
90
210
const project = toBaseProject ( getProject ( projectId ) )
91
211
const sources = project . sources . filter (
0 commit comments