1
- import { ClientMessage , MediaConfig , ServerMessage } from "./sfu.ts" ;
1
+ import {
2
+ ClientMessage ,
3
+ MediaConfig ,
4
+ ParticipantStream ,
5
+ ParticipantSubscription ,
6
+ ServerMessage ,
7
+ VideoSubscription ,
8
+ } from "./sfu.ts" ;
2
9
3
10
const MAX_DOWNSTREAMS = 16 ;
4
11
const LAST_N_AUDIO = 3 ;
@@ -13,7 +20,8 @@ interface VideoSlot {
13
20
14
21
interface ParticipantMeta {
15
22
externalParticipantId : string ;
16
- media ?: MediaConfig ;
23
+ participantId : string ;
24
+ media : MediaConfig ;
17
25
}
18
26
19
27
export interface ClientCoreConfig {
@@ -28,6 +36,7 @@ export class ClientCore {
28
36
#videoSender: RTCRtpTransceiver ;
29
37
#audioSender: RTCRtpTransceiver ;
30
38
#closed: boolean ;
39
+ #sequence: number ;
31
40
32
41
#videoSlots: VideoSlot [ ] ;
33
42
#audioSlots: RTCRtpTransceiver [ ] ;
@@ -47,6 +56,7 @@ export class ClientCore {
47
56
this . #videoSlots = [ ] ;
48
57
this . #audioSlots = [ ] ;
49
58
this . #participants = { } ;
59
+ this . #sequence = 0 ;
50
60
51
61
this . #pc = new RTCPeerConnection ( ) ;
52
62
this . #pc. onconnectionstatechange = ( ) => {
@@ -81,27 +91,13 @@ export class ClientCore {
81
91
82
92
switch ( msgKind ) {
83
93
case "roomSnapshot" :
84
- for ( const participant of msg . roomSnapshot . participants ) {
85
- this . #participants[ participant . participantId ] = {
86
- externalParticipantId : participant . externalParticipantId ,
87
- media : participant . media ,
88
- } ;
89
- }
94
+ this . #handleParticipantUpdates( msg . roomSnapshot . participants ) ;
90
95
break ;
91
96
case "streamUpdate" :
92
97
if ( msg . streamUpdate . participantStream ) {
93
- const stream = msg . streamUpdate . participantStream ;
94
- if ( stream . participantId in this . #participants) {
95
- const participant = this . #participants[ stream . participantId ] ;
96
- participant . media = stream . media ;
97
- participant . externalParticipantId =
98
- stream . externalParticipantId ;
99
- } else {
100
- this . #participants[ stream . participantId ] = {
101
- externalParticipantId : stream . externalParticipantId ,
102
- media : stream . media ,
103
- } ;
104
- }
98
+ this . #handleParticipantUpdates( [
99
+ msg . streamUpdate . participantStream ,
100
+ ] ) ;
105
101
}
106
102
break ;
107
103
}
@@ -138,6 +134,59 @@ export class ClientCore {
138
134
}
139
135
}
140
136
137
+ #sendRpc( msg : ClientMessage [ "msg" ] ) {
138
+ this . #rpc. send ( ClientMessage . toBinary ( {
139
+ sequence : this . #sequence,
140
+ msg,
141
+ } ) ) ;
142
+ this . #sequence += 1 ;
143
+ }
144
+
145
+ #handleParticipantUpdates( streams : ParticipantStream [ ] ) {
146
+ const newParticipants : ParticipantMeta [ ] = [ ] ;
147
+
148
+ for ( const stream of streams ) {
149
+ if ( ! stream . media ) {
150
+ // participant has left
151
+ delete this . #participants[ stream . participantId ] ;
152
+ continue ;
153
+ }
154
+
155
+ if ( stream . participantId in this . #participants) {
156
+ const participant = this . #participants[ stream . participantId ] ;
157
+ participant . media = stream . media ;
158
+ participant . externalParticipantId = stream . externalParticipantId ;
159
+ participant . participantId = stream . participantId ;
160
+ } else {
161
+ const meta : ParticipantMeta = {
162
+ externalParticipantId : stream . externalParticipantId ,
163
+ participantId : stream . participantId ,
164
+ media : stream . media ,
165
+ } ;
166
+ this . #participants[ stream . participantId ] = meta ;
167
+ newParticipants . push ( meta ) ;
168
+ }
169
+ }
170
+
171
+ // TODO: should we bin pack the old participants first?
172
+ for ( const slot of this . #videoSlots) {
173
+ if ( slot . participantId ) {
174
+ if ( slot . participantId in this . #participants) {
175
+ continue ;
176
+ }
177
+
178
+ slot . participantId = undefined ;
179
+ }
180
+
181
+ const participant = newParticipants . pop ( ) ;
182
+ if ( ! participant ) {
183
+ continue ;
184
+ }
185
+
186
+ slot . participantId = participant . participantId ;
187
+ }
188
+ }
189
+
141
190
#close( error ?: string ) {
142
191
if ( this . #closed) return ;
143
192
0 commit comments