@@ -20,10 +20,12 @@ import LocalVideoTrack, {
20
20
videoLayersFromEncodings ,
21
21
} from '../track/LocalVideoTrack' ;
22
22
import {
23
+ AudioCaptureOptions ,
23
24
CreateLocalTracksOptions ,
24
25
ScreenShareCaptureOptions ,
25
26
ScreenSharePresets ,
26
27
TrackPublishOptions ,
28
+ VideoCaptureOptions ,
27
29
VideoCodec ,
28
30
} from '../track/options' ;
29
31
import { Track } from '../track/Track' ;
@@ -117,8 +119,11 @@ export default class LocalParticipant extends Participant {
117
119
* If a track has already published, it'll mute or unmute the track.
118
120
* Resolves with a `LocalTrackPublication` instance if successful and `undefined` otherwise
119
121
*/
120
- setCameraEnabled ( enabled : boolean ) : Promise < LocalTrackPublication | undefined > {
121
- return this . setTrackEnabled ( Track . Source . Camera , enabled ) ;
122
+ setCameraEnabled (
123
+ enabled : boolean ,
124
+ options ?: VideoCaptureOptions ,
125
+ ) : Promise < LocalTrackPublication | undefined > {
126
+ return this . setTrackEnabled ( Track . Source . Camera , enabled , options ) ;
122
127
}
123
128
124
129
/**
@@ -127,16 +132,22 @@ export default class LocalParticipant extends Participant {
127
132
* If a track has already published, it'll mute or unmute the track.
128
133
* Resolves with a `LocalTrackPublication` instance if successful and `undefined` otherwise
129
134
*/
130
- setMicrophoneEnabled ( enabled : boolean ) : Promise < LocalTrackPublication | undefined > {
131
- return this . setTrackEnabled ( Track . Source . Microphone , enabled ) ;
135
+ setMicrophoneEnabled (
136
+ enabled : boolean ,
137
+ options ?: AudioCaptureOptions ,
138
+ ) : Promise < LocalTrackPublication | undefined > {
139
+ return this . setTrackEnabled ( Track . Source . Microphone , enabled , options ) ;
132
140
}
133
141
134
142
/**
135
143
* Start or stop sharing a participant's screen
136
144
* Resolves with a `LocalTrackPublication` instance if successful and `undefined` otherwise
137
145
*/
138
- setScreenShareEnabled ( enabled : boolean ) : Promise < LocalTrackPublication | undefined > {
139
- return this . setTrackEnabled ( Track . Source . ScreenShare , enabled ) ;
146
+ setScreenShareEnabled (
147
+ enabled : boolean ,
148
+ options ?: ScreenShareCaptureOptions ,
149
+ ) : Promise < LocalTrackPublication | undefined > {
150
+ return this . setTrackEnabled ( Track . Source . ScreenShare , enabled , options ) ;
140
151
}
141
152
142
153
/** @internal */
@@ -155,16 +166,32 @@ export default class LocalParticipant extends Participant {
155
166
* Resolves with LocalTrackPublication if successful and void otherwise
156
167
*/
157
168
private async setTrackEnabled (
158
- source : Track . Source ,
169
+ source : Extract < Track . Source , Track . Source . Camera > ,
159
170
enabled : boolean ,
160
- ) : Promise < LocalTrackPublication | undefined > {
171
+ options ?: VideoCaptureOptions ,
172
+ ) : Promise < LocalTrackPublication | undefined > ;
173
+ private async setTrackEnabled (
174
+ source : Extract < Track . Source , Track . Source . Microphone > ,
175
+ enabled : boolean ,
176
+ options ?: AudioCaptureOptions ,
177
+ ) : Promise < LocalTrackPublication | undefined > ;
178
+ private async setTrackEnabled (
179
+ source : Extract < Track . Source , Track . Source . ScreenShare > ,
180
+ enabled : boolean ,
181
+ options ?: ScreenShareCaptureOptions ,
182
+ ) : Promise < LocalTrackPublication | undefined > ;
183
+ private async setTrackEnabled (
184
+ source : Track . Source ,
185
+ enabled : true ,
186
+ options ?: VideoCaptureOptions | AudioCaptureOptions | ScreenShareCaptureOptions ,
187
+ ) {
161
188
log . debug ( 'setTrackEnabled' , { source, enabled } ) ;
162
189
let track = this . getTrack ( source ) ;
163
190
if ( enabled ) {
164
191
if ( track ) {
165
192
await track . unmute ( ) ;
166
193
} else {
167
- let localTrack : LocalTrack | undefined ;
194
+ let localTracks : Array < LocalTrack > | undefined ;
168
195
if ( this . pendingPublishing . has ( source ) ) {
169
196
log . info ( 'skipping duplicate published source' , { source } ) ;
170
197
// no-op it's already been requested
@@ -174,23 +201,32 @@ export default class LocalParticipant extends Participant {
174
201
try {
175
202
switch ( source ) {
176
203
case Track . Source . Camera :
177
- [ localTrack ] = await this . createTracks ( {
178
- video : true ,
204
+ localTracks = await this . createTracks ( {
205
+ video : ( options as VideoCaptureOptions | undefined ) ?? true ,
179
206
} ) ;
207
+
180
208
break ;
181
209
case Track . Source . Microphone :
182
- [ localTrack ] = await this . createTracks ( {
183
- audio : true ,
210
+ localTracks = await this . createTracks ( {
211
+ audio : ( options as AudioCaptureOptions | undefined ) ?? true ,
184
212
} ) ;
185
213
break ;
186
214
case Track . Source . ScreenShare :
187
- [ localTrack ] = await this . createScreenTracks ( { audio : false } ) ;
215
+ localTracks = await this . createScreenTracks ( {
216
+ ...( options as ScreenShareCaptureOptions | undefined ) ,
217
+ } ) ;
188
218
break ;
189
219
default :
190
220
throw new TrackInvalidError ( source ) ;
191
221
}
192
-
193
- track = await this . publishTrack ( localTrack ) ;
222
+ const publishPromises : Array < Promise < LocalTrackPublication > > = [ ] ;
223
+ for ( const localTrack of localTracks ) {
224
+ publishPromises . push ( this . publishTrack ( localTrack ) ) ;
225
+ }
226
+ const publishedTracks = await Promise . all ( publishPromises ) ;
227
+ // for screen share publications including audio, this will only return the screen share publication, not the screen share audio one
228
+ // revisit if we want to return an array of tracks instead for v2
229
+ [ track ] = publishedTracks ;
194
230
} catch ( e ) {
195
231
if ( e instanceof Error && ! ( e instanceof TrackInvalidError ) ) {
196
232
this . emit ( ParticipantEvent . MediaDevicesError , e ) ;
@@ -204,6 +240,10 @@ export default class LocalParticipant extends Participant {
204
240
// screenshare cannot be muted, unpublish instead
205
241
if ( source === Track . Source . ScreenShare ) {
206
242
track = this . unpublishTrack ( track . track ) ;
243
+ const screenAudioTrack = this . getTrack ( Track . Source . ScreenShareAudio ) ;
244
+ if ( screenAudioTrack && screenAudioTrack . track ) {
245
+ this . unpublishTrack ( screenAudioTrack . track ) ;
246
+ }
207
247
} else {
208
248
await track . mute ( ) ;
209
249
}
0 commit comments