@@ -83,6 +83,13 @@ export class ConferencePeerConnectionChannel extends EventDispatcher {
8383 if ( typeof options !== 'object' ) {
8484 return Promise . reject ( new TypeError ( 'Options should be an object.' ) ) ;
8585 }
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+ }
8693 if ( options . audio === undefined ) {
8794 options . audio = ! ! stream . mediaStream . getAudioTracks ( ) . length ;
8895 }
@@ -115,18 +122,20 @@ export class ConferencePeerConnectionChannel extends EventDispatcher {
115122 }
116123 }
117124 }
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 ) ) {
123130 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' ) ) {
128137 return Promise . reject ( new TypeError (
129- 'options.video has incorrect parameters.' ) ) ;
138+ 'options.video has incorrect parameters.' ) ) ;
130139 }
131140 }
132141 }
@@ -149,9 +158,6 @@ export class ConferencePeerConnectionChannel extends EventDispatcher {
149158 }
150159 mediaOptions . audio = { } ;
151160 mediaOptions . audio . source = stream . source . audio ;
152- for ( const track of stream . mediaStream . getAudioTracks ( ) ) {
153- this . _pc . addTrack ( track , stream . mediaStream ) ;
154- }
155161 } else {
156162 mediaOptions . audio = false ;
157163 }
@@ -174,9 +180,6 @@ export class ConferencePeerConnectionChannel extends EventDispatcher {
174180 } ,
175181 framerate : trackSettings . frameRate ,
176182 } ;
177- for ( const track of stream . mediaStream . getVideoTracks ( ) ) {
178- this . _pc . addTrack ( track , stream . mediaStream ) ;
179- }
180183 } else {
181184 mediaOptions . video = false ;
182185 }
@@ -197,15 +200,31 @@ export class ConferencePeerConnectionChannel extends EventDispatcher {
197200 } ;
198201 if ( typeof this . _pc . addTransceiver === 'function' ) {
199202 // |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 ) ;
202213 }
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 ) ;
205224 }
206225 }
207226 let localDesc ;
208- this . _pc . createOffer ( offerOptions ) . then ( ( desc ) => {
227+ this . _pc . createOffer ( ) . then ( ( desc ) => {
209228 if ( options ) {
210229 desc . sdp = this . _setRtpReceiverOptions ( desc . sdp , options ) ;
211230 }
@@ -332,7 +351,7 @@ export class ConferencePeerConnectionChannel extends EventDispatcher {
332351 this . _pc . addTransceiver ( 'video' , { direction : 'recvonly' } ) ;
333352 }
334353 }
335- this . _pc . createOffer ( offerOptions ) . then ( ( desc ) => {
354+ this . _pc . createOffer ( ) . then ( ( desc ) => {
336355 if ( options ) {
337356 desc . sdp = this . _setRtpReceiverOptions ( desc . sdp , options ) ;
338357 }
@@ -645,11 +664,20 @@ export class ConferencePeerConnectionChannel extends EventDispatcher {
645664 }
646665
647666 _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+ }
648672 sdp = this . _setMaxBitrate ( sdp , options ) ;
649673 return sdp ;
650674 }
651675
652676 _setRtpReceiverOptions ( sdp , options ) {
677+ if ( this . _isRtpEncodingParameters ( options . audio ) ||
678+ this . _isRtpEncodingParameters ( options . video ) ) {
679+ return sdp ;
680+ }
653681 sdp = this . _setCodecOrder ( sdp , options ) ;
654682 return sdp ;
655683 }
@@ -683,4 +711,23 @@ export class ConferencePeerConnectionChannel extends EventDispatcher {
683711 Logger . warning ( 'Invalid data value for stream update info.' ) ;
684712 }
685713 }
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+ }
686733}
0 commit comments