@@ -83,6 +83,13 @@ export class ConferencePeerConnectionChannel extends EventDispatcher {
83
83
if ( typeof options !== 'object' ) {
84
84
return Promise . reject ( new TypeError ( 'Options should be an object.' ) ) ;
85
85
}
86
+ if ( ( this . _isRtpEncodingParameters ( options . audio ) &&
87
+ this . _isOwtEncodingParameters ( options . video ) ) ||
88
+ ( this . _isOwtEncodingParameters ( options . audio ) &&
89
+ this . _isRtpEncodingParameters ( options . video ) ) ) {
90
+ return Promise . reject ( new ConferenceError (
91
+ 'Mixing RTCRtpEncodingParameters and AudioEncodingParameters/VideoEncodingParameters is not allowed.' ) )
92
+ }
86
93
if ( options . audio === undefined ) {
87
94
options . audio = ! ! stream . mediaStream . getAudioTracks ( ) . length ;
88
95
}
@@ -115,18 +122,20 @@ export class ConferencePeerConnectionChannel extends EventDispatcher {
115
122
}
116
123
}
117
124
}
118
- if ( typeof options . video === 'object' ) {
119
- if ( ! Array . isArray ( options . video ) ) {
120
- return Promise . reject ( new TypeError (
121
- 'options.video should be a boolean or an array.' ) ) ;
122
- }
125
+ if ( typeof options . video === 'object' && ! Array . isArray ( options . video ) ) {
126
+ return Promise . reject ( new TypeError (
127
+ 'options.video should be a boolean or an array.' ) ) ;
128
+ }
129
+ if ( this . _isOwtEncodingParameters ( options . video ) ) {
123
130
for ( const parameters of options . video ) {
124
- if ( ! parameters . codec || typeof parameters . codec . name !== 'string' || (
125
- parameters . maxBitrate !== undefined && typeof parameters . maxBitrate
126
- !== 'number' ) || ( parameters . codec . profile !== undefined
127
- && typeof parameters . codec . profile !== 'string' ) ) {
131
+ if ( ! parameters . codec || typeof parameters . codec . name !== 'string' ||
132
+ (
133
+ parameters . maxBitrate !== undefined && typeof parameters
134
+ . maxBitrate !==
135
+ 'number' ) || ( parameters . codec . profile !== undefined &&
136
+ typeof parameters . codec . profile !== 'string' ) ) {
128
137
return Promise . reject ( new TypeError (
129
- 'options.video has incorrect parameters.' ) ) ;
138
+ 'options.video has incorrect parameters.' ) ) ;
130
139
}
131
140
}
132
141
}
@@ -149,9 +158,6 @@ export class ConferencePeerConnectionChannel extends EventDispatcher {
149
158
}
150
159
mediaOptions . audio = { } ;
151
160
mediaOptions . audio . source = stream . source . audio ;
152
- for ( const track of stream . mediaStream . getAudioTracks ( ) ) {
153
- this . _pc . addTrack ( track , stream . mediaStream ) ;
154
- }
155
161
} else {
156
162
mediaOptions . audio = false ;
157
163
}
@@ -174,9 +180,6 @@ export class ConferencePeerConnectionChannel extends EventDispatcher {
174
180
} ,
175
181
framerate : trackSettings . frameRate ,
176
182
} ;
177
- for ( const track of stream . mediaStream . getVideoTracks ( ) ) {
178
- this . _pc . addTrack ( track , stream . mediaStream ) ;
179
- }
180
183
} else {
181
184
mediaOptions . video = false ;
182
185
}
@@ -197,15 +200,31 @@ export class ConferencePeerConnectionChannel extends EventDispatcher {
197
200
} ;
198
201
if ( typeof this . _pc . addTransceiver === 'function' ) {
199
202
// |direction| seems not working on Safari.
200
- if ( mediaOptions . audio && stream . mediaStream . getAudioTracks ( ) > 0 ) {
201
- this . _pc . addTransceiver ( 'audio' , { direction : 'sendonly' } ) ;
203
+ if ( mediaOptions . audio && stream . mediaStream . getAudioTracks ( ) . length >
204
+ 0 ) {
205
+ const transceiverInit = {
206
+ direction : 'sendonly'
207
+ } ;
208
+ if ( this . _isRtpEncodingParameters ( options . audio ) ) {
209
+ transceiverInit . sendEncodings = options . audio ;
210
+ }
211
+ this . _pc . addTransceiver ( stream . mediaStream . getAudioTracks ( ) [ 0 ] ,
212
+ transceiverInit ) ;
202
213
}
203
- if ( mediaOptions . video && stream . mediaStream . getVideoTracks ( ) > 0 ) {
204
- this . _pc . addTransceiver ( 'video' , { direction : 'sendonly' } ) ;
214
+ if ( mediaOptions . video && stream . mediaStream . getVideoTracks ( ) . length >
215
+ 0 ) {
216
+ const transceiverInit = {
217
+ direction : 'sendonly'
218
+ } ;
219
+ if ( this . _isRtpEncodingParameters ( options . video ) ) {
220
+ transceiverInit . sendEncodings = options . video ;
221
+ }
222
+ this . _pc . addTransceiver ( stream . mediaStream . getVideoTracks ( ) [ 0 ] ,
223
+ transceiverInit ) ;
205
224
}
206
225
}
207
226
let localDesc ;
208
- this . _pc . createOffer ( offerOptions ) . then ( ( desc ) => {
227
+ this . _pc . createOffer ( ) . then ( ( desc ) => {
209
228
if ( options ) {
210
229
desc . sdp = this . _setRtpReceiverOptions ( desc . sdp , options ) ;
211
230
}
@@ -332,7 +351,7 @@ export class ConferencePeerConnectionChannel extends EventDispatcher {
332
351
this . _pc . addTransceiver ( 'video' , { direction : 'recvonly' } ) ;
333
352
}
334
353
}
335
- this . _pc . createOffer ( offerOptions ) . then ( ( desc ) => {
354
+ this . _pc . createOffer ( ) . then ( ( desc ) => {
336
355
if ( options ) {
337
356
desc . sdp = this . _setRtpReceiverOptions ( desc . sdp , options ) ;
338
357
}
@@ -645,11 +664,20 @@ export class ConferencePeerConnectionChannel extends EventDispatcher {
645
664
}
646
665
647
666
_setRtpSenderOptions ( sdp , options ) {
667
+ // SDP mugling is deprecated, moving to `setParameters`.
668
+ if ( this . _isRtpEncodingParameters ( options . audio ) ||
669
+ this . _isRtpEncodingParameters ( options . video ) ) {
670
+ return sdp ;
671
+ }
648
672
sdp = this . _setMaxBitrate ( sdp , options ) ;
649
673
return sdp ;
650
674
}
651
675
652
676
_setRtpReceiverOptions ( sdp , options ) {
677
+ if ( this . _isRtpEncodingParameters ( options . audio ) ||
678
+ this . _isRtpEncodingParameters ( options . video ) ) {
679
+ return sdp ;
680
+ }
653
681
sdp = this . _setCodecOrder ( sdp , options ) ;
654
682
return sdp ;
655
683
}
@@ -683,4 +711,23 @@ export class ConferencePeerConnectionChannel extends EventDispatcher {
683
711
Logger . warning ( 'Invalid data value for stream update info.' ) ;
684
712
}
685
713
}
714
+
715
+ _isRtpEncodingParameters ( obj ) {
716
+ if ( ! Array . isArray ( obj ) ) {
717
+ return false ;
718
+ }
719
+ // Only check the first one.
720
+ const param = obj [ 0 ] ;
721
+ return param . codecPayloadType || param . dtx || param . active || param
722
+ . ptime || param . maxFramerate || param . scaleResolutionDownBy || param . rid ;
723
+ }
724
+
725
+ _isOwtEncodingParameters ( obj ) {
726
+ if ( ! Array . isArray ( obj ) ) {
727
+ return false ;
728
+ }
729
+ // Only check the first one.
730
+ const param = obj [ 0 ] ;
731
+ return ! ! param . codec ;
732
+ }
686
733
}
0 commit comments