Skip to content
This repository was archived by the owner on Oct 25, 2024. It is now read-only.

Commit 120f9ae

Browse files
committed
Publish method accepts RTCRtpEncodingParameters as options.
This change makes simulcast possibile.
1 parent b1c1122 commit 120f9ae

File tree

3 files changed

+76
-24
lines changed

3 files changed

+76
-24
lines changed

docs/mdfiles/changelog.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
11
Change Log
22
==========
3+
# 4.3
4+
* The type of `conferenceClient.publish` method's option is changed from `AudioEncodingParameters` and `VideoEncodingParameters` to `RTCRtpSendParameters`.
5+
36
# 4.0.2
47
* Fix a compatibility issue for Chrome 69 beta.
58

src/sdk/base/publication.js

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -171,15 +171,17 @@ export class PublishOptions {
171171
// eslint-disable-next-line require-jsdoc
172172
constructor(audio, video) {
173173
/**
174-
* @member {?Array<Owt.Base.AudioEncodingParameters>} audio
174+
* @member {?Array<Owt.Base.AudioEncodingParameters> | ?Array<RTCRtpEncodingParameters>} audio
175175
* @instance
176176
* @memberof Owt.Base.PublishOptions
177+
* @desc Parameters for audio RtpSender.
177178
*/
178179
this.audio = audio;
179180
/**
180-
* @member {?Array<Owt.Base.VideoEncodingParameters>} video
181+
* @member {?Array<Owt.Base.VideoEncodingParameters> | ?Array<RTCRtpEncodingParameters>} video
181182
* @instance
182183
* @memberof Owt.Base.PublishOptions
184+
* @desc Parameters for video RtpSender.
183185
*/
184186
this.video = video;
185187
}

src/sdk/conference/channel.js

Lines changed: 69 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -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

Comments
 (0)