mediasoup-client 3.7.1 → 3.7.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +85 -112
- package/lib/Consumer.d.ts +1 -1
- package/lib/Consumer.d.ts.map +1 -1
- package/lib/Consumer.js +1 -1
- package/lib/DataConsumer.d.ts +1 -1
- package/lib/DataConsumer.d.ts.map +1 -1
- package/lib/DataConsumer.js +1 -1
- package/lib/DataProducer.d.ts +1 -1
- package/lib/DataProducer.d.ts.map +1 -1
- package/lib/DataProducer.js +1 -1
- package/lib/Device.d.ts +3 -3
- package/lib/Device.d.ts.map +1 -1
- package/lib/Device.js +66 -89
- package/lib/EnhancedEventEmitter.d.ts.map +1 -1
- package/lib/Logger.d.ts.map +1 -1
- package/lib/Producer.d.ts +5 -15
- package/lib/Producer.d.ts.map +1 -1
- package/lib/Producer.js +2 -2
- package/lib/RtpParameters.d.ts.map +1 -1
- package/lib/SctpParameters.d.ts.map +1 -1
- package/lib/Transport.d.ts +21 -11
- package/lib/Transport.d.ts.map +1 -1
- package/lib/Transport.js +73 -55
- package/lib/errors.d.ts.map +1 -1
- package/lib/errors.js +6 -6
- package/lib/handlers/Chrome111.d.ts +4 -4
- package/lib/handlers/Chrome111.d.ts.map +1 -1
- package/lib/handlers/Chrome111.js +79 -78
- package/lib/handlers/Chrome55.d.ts +4 -4
- package/lib/handlers/Chrome55.d.ts.map +1 -1
- package/lib/handlers/Chrome55.js +88 -81
- package/lib/handlers/Chrome67.d.ts +4 -4
- package/lib/handlers/Chrome67.d.ts.map +1 -1
- package/lib/handlers/Chrome67.js +90 -84
- package/lib/handlers/Chrome70.d.ts +4 -4
- package/lib/handlers/Chrome70.d.ts.map +1 -1
- package/lib/handlers/Chrome70.js +81 -79
- package/lib/handlers/Chrome74.d.ts +4 -4
- package/lib/handlers/Chrome74.d.ts.map +1 -1
- package/lib/handlers/Chrome74.js +80 -79
- package/lib/handlers/Edge11.d.ts +1 -1
- package/lib/handlers/Edge11.d.ts.map +1 -1
- package/lib/handlers/Edge11.js +66 -78
- package/lib/handlers/FakeHandler.d.ts +3 -3
- package/lib/handlers/FakeHandler.d.ts.map +1 -1
- package/lib/handlers/FakeHandler.js +20 -22
- package/lib/handlers/Firefox60.d.ts +4 -4
- package/lib/handlers/Firefox60.d.ts.map +1 -1
- package/lib/handlers/Firefox60.js +80 -73
- package/lib/handlers/HandlerInterface.d.ts +1 -0
- package/lib/handlers/HandlerInterface.d.ts.map +1 -1
- package/lib/handlers/ReactNative.d.ts +4 -4
- package/lib/handlers/ReactNative.d.ts.map +1 -1
- package/lib/handlers/ReactNative.js +89 -83
- package/lib/handlers/ReactNativeUnifiedPlan.d.ts +4 -4
- package/lib/handlers/ReactNativeUnifiedPlan.d.ts.map +1 -1
- package/lib/handlers/ReactNativeUnifiedPlan.js +80 -79
- package/lib/handlers/Safari11.d.ts +4 -4
- package/lib/handlers/Safari11.d.ts.map +1 -1
- package/lib/handlers/Safari11.js +89 -82
- package/lib/handlers/Safari12.d.ts +4 -4
- package/lib/handlers/Safari12.d.ts.map +1 -1
- package/lib/handlers/Safari12.js +80 -78
- package/lib/handlers/ortc/edgeUtils.d.ts.map +1 -1
- package/lib/handlers/ortc/utils.d.ts.map +1 -1
- package/lib/handlers/ortc/utils.js +2 -2
- package/lib/handlers/sdp/MediaSection.d.ts +5 -5
- package/lib/handlers/sdp/MediaSection.d.ts.map +1 -1
- package/lib/handlers/sdp/MediaSection.js +296 -318
- package/lib/handlers/sdp/RemoteSdp.d.ts +5 -5
- package/lib/handlers/sdp/RemoteSdp.d.ts.map +1 -1
- package/lib/handlers/sdp/RemoteSdp.js +28 -30
- package/lib/handlers/sdp/commonUtils.d.ts +8 -5
- package/lib/handlers/sdp/commonUtils.d.ts.map +1 -1
- package/lib/handlers/sdp/commonUtils.js +71 -59
- package/lib/handlers/sdp/plainRtpUtils.d.ts +2 -2
- package/lib/handlers/sdp/plainRtpUtils.d.ts.map +1 -1
- package/lib/handlers/sdp/plainRtpUtils.js +5 -7
- package/lib/handlers/sdp/planBUtils.d.ts +2 -2
- package/lib/handlers/sdp/planBUtils.d.ts.map +1 -1
- package/lib/handlers/sdp/planBUtils.js +11 -14
- package/lib/handlers/sdp/unifiedPlanUtils.d.ts +2 -2
- package/lib/handlers/sdp/unifiedPlanUtils.d.ts.map +1 -1
- package/lib/handlers/sdp/unifiedPlanUtils.js +11 -14
- package/lib/index.d.ts +1 -1
- package/lib/index.js +1 -1
- package/lib/ortc.d.ts +4 -58
- package/lib/ortc.d.ts.map +1 -1
- package/lib/ortc.js +432 -478
- package/lib/scalabilityModes.d.ts.map +1 -1
- package/lib/scalabilityModes.js +2 -2
- package/lib/{tests → test}/fakeParameters.d.ts +3 -2
- package/lib/test/fakeParameters.d.ts.map +1 -0
- package/lib/test/fakeParameters.js +654 -0
- package/lib/{tests → test}/test.d.ts.map +1 -1
- package/lib/{tests → test}/test.js +469 -496
- package/lib/test/uaTestCases.d.ts.map +1 -0
- package/lib/{tests → test}/uaTestCases.js +17 -17
- package/lib/types.d.ts.map +1 -1
- package/lib/utils.d.ts.map +1 -1
- package/npm-scripts.mjs +75 -103
- package/package.json +93 -90
- package/lib/tests/fakeParameters.d.ts.map +0 -1
- package/lib/tests/fakeParameters.js +0 -662
- package/lib/tests/uaTestCases.d.ts.map +0 -1
- /package/lib/{tests → test}/test.d.ts +0 -0
- /package/lib/{tests → test}/uaTestCases.d.ts +0 -0
|
@@ -27,7 +27,7 @@ exports.OfferMediaSection = exports.AnswerMediaSection = exports.MediaSection =
|
|
|
27
27
|
const sdpTransform = __importStar(require("sdp-transform"));
|
|
28
28
|
const utils = __importStar(require("../../utils"));
|
|
29
29
|
class MediaSection {
|
|
30
|
-
constructor({ iceParameters, iceCandidates, dtlsParameters, planB = false }) {
|
|
30
|
+
constructor({ iceParameters, iceCandidates, dtlsParameters, planB = false, }) {
|
|
31
31
|
this._mediaObject = {};
|
|
32
32
|
this._planB = planB;
|
|
33
33
|
if (iceParameters) {
|
|
@@ -41,7 +41,9 @@ class MediaSection {
|
|
|
41
41
|
// RTP (1).
|
|
42
42
|
candidateObject.component = 1;
|
|
43
43
|
candidateObject.foundation = candidate.foundation;
|
|
44
|
-
|
|
44
|
+
// Be ready for new candidate.address field in mediasoup server side
|
|
45
|
+
// field and keep backward compatibility with deprecated candidate.ip.
|
|
46
|
+
candidateObject.ip = candidate.address ?? candidate.ip;
|
|
45
47
|
candidateObject.port = candidate.port;
|
|
46
48
|
candidateObject.priority = candidate.priority;
|
|
47
49
|
candidateObject.transport = candidate.protocol;
|
|
@@ -91,7 +93,7 @@ class MediaSection {
|
|
|
91
93
|
}
|
|
92
94
|
exports.MediaSection = MediaSection;
|
|
93
95
|
class AnswerMediaSection extends MediaSection {
|
|
94
|
-
constructor({ iceParameters, iceCandidates, dtlsParameters, sctpParameters, plainRtpParameters, planB = false, offerMediaObject, offerRtpParameters, answerRtpParameters, codecOptions, extmapAllowMixed = false }) {
|
|
96
|
+
constructor({ iceParameters, iceCandidates, dtlsParameters, sctpParameters, plainRtpParameters, planB = false, offerMediaObject, offerRtpParameters, answerRtpParameters, codecOptions, extmapAllowMixed = false, }) {
|
|
95
97
|
super({ iceParameters, iceCandidates, dtlsParameters, planB });
|
|
96
98
|
this._mediaObject.mid = String(offerMediaObject.mid);
|
|
97
99
|
this._mediaObject.type = offerMediaObject.type;
|
|
@@ -101,217 +103,204 @@ class AnswerMediaSection extends MediaSection {
|
|
|
101
103
|
this._mediaObject.port = 7;
|
|
102
104
|
}
|
|
103
105
|
else {
|
|
104
|
-
this._mediaObject.connection =
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
};
|
|
106
|
+
this._mediaObject.connection = {
|
|
107
|
+
ip: plainRtpParameters.ip,
|
|
108
|
+
version: plainRtpParameters.ipVersion,
|
|
109
|
+
};
|
|
109
110
|
this._mediaObject.port = plainRtpParameters.port;
|
|
110
111
|
}
|
|
111
112
|
switch (offerMediaObject.type) {
|
|
112
113
|
case 'audio':
|
|
113
|
-
case 'video':
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
.rtcpFeedback
|
|
167
|
-
.filter((fb) => fb.type !== 'nack' || fb.parameter);
|
|
168
|
-
codecRtcpFeedback = codecRtcpFeedback
|
|
169
|
-
.filter((fb) => fb.type !== 'nack' || fb.parameter);
|
|
170
|
-
}
|
|
171
|
-
break;
|
|
172
|
-
}
|
|
173
|
-
case 'video/vp8':
|
|
174
|
-
case 'video/vp9':
|
|
175
|
-
case 'video/h264':
|
|
176
|
-
case 'video/h265':
|
|
177
|
-
{
|
|
178
|
-
if (videoGoogleStartBitrate !== undefined) {
|
|
179
|
-
codecParameters['x-google-start-bitrate'] = videoGoogleStartBitrate;
|
|
180
|
-
}
|
|
181
|
-
if (videoGoogleMaxBitrate !== undefined) {
|
|
182
|
-
codecParameters['x-google-max-bitrate'] = videoGoogleMaxBitrate;
|
|
183
|
-
}
|
|
184
|
-
if (videoGoogleMinBitrate !== undefined) {
|
|
185
|
-
codecParameters['x-google-min-bitrate'] = videoGoogleMinBitrate;
|
|
186
|
-
}
|
|
187
|
-
break;
|
|
188
|
-
}
|
|
114
|
+
case 'video': {
|
|
115
|
+
this._mediaObject.direction = 'recvonly';
|
|
116
|
+
this._mediaObject.rtp = [];
|
|
117
|
+
this._mediaObject.rtcpFb = [];
|
|
118
|
+
this._mediaObject.fmtp = [];
|
|
119
|
+
for (const codec of answerRtpParameters.codecs) {
|
|
120
|
+
const rtp = {
|
|
121
|
+
payload: codec.payloadType,
|
|
122
|
+
codec: getCodecName(codec),
|
|
123
|
+
rate: codec.clockRate,
|
|
124
|
+
};
|
|
125
|
+
if (codec.channels > 1) {
|
|
126
|
+
rtp.encoding = codec.channels;
|
|
127
|
+
}
|
|
128
|
+
this._mediaObject.rtp.push(rtp);
|
|
129
|
+
const codecParameters = utils.clone(codec.parameters) ?? {};
|
|
130
|
+
let codecRtcpFeedback = utils.clone(codec.rtcpFeedback) ?? [];
|
|
131
|
+
if (codecOptions) {
|
|
132
|
+
const { opusStereo, opusFec, opusDtx, opusMaxPlaybackRate, opusMaxAverageBitrate, opusPtime, opusNack, videoGoogleStartBitrate, videoGoogleMaxBitrate, videoGoogleMinBitrate, } = codecOptions;
|
|
133
|
+
const offerCodec = offerRtpParameters.codecs.find((c) => c.payloadType === codec.payloadType);
|
|
134
|
+
switch (codec.mimeType.toLowerCase()) {
|
|
135
|
+
case 'audio/opus':
|
|
136
|
+
case 'audio/multiopus': {
|
|
137
|
+
if (opusStereo !== undefined) {
|
|
138
|
+
offerCodec.parameters['sprop-stereo'] = opusStereo ? 1 : 0;
|
|
139
|
+
codecParameters.stereo = opusStereo ? 1 : 0;
|
|
140
|
+
}
|
|
141
|
+
if (opusFec !== undefined) {
|
|
142
|
+
offerCodec.parameters.useinbandfec = opusFec ? 1 : 0;
|
|
143
|
+
codecParameters.useinbandfec = opusFec ? 1 : 0;
|
|
144
|
+
}
|
|
145
|
+
if (opusDtx !== undefined) {
|
|
146
|
+
offerCodec.parameters.usedtx = opusDtx ? 1 : 0;
|
|
147
|
+
codecParameters.usedtx = opusDtx ? 1 : 0;
|
|
148
|
+
}
|
|
149
|
+
if (opusMaxPlaybackRate !== undefined) {
|
|
150
|
+
codecParameters.maxplaybackrate = opusMaxPlaybackRate;
|
|
151
|
+
}
|
|
152
|
+
if (opusMaxAverageBitrate !== undefined) {
|
|
153
|
+
codecParameters.maxaveragebitrate = opusMaxAverageBitrate;
|
|
154
|
+
}
|
|
155
|
+
if (opusPtime !== undefined) {
|
|
156
|
+
offerCodec.parameters.ptime = opusPtime;
|
|
157
|
+
codecParameters.ptime = opusPtime;
|
|
158
|
+
}
|
|
159
|
+
// If opusNack is not set, we must remove NACK support for OPUS.
|
|
160
|
+
// Otherwise it would be enabled for those handlers that artificially
|
|
161
|
+
// announce it in their RTP capabilities.
|
|
162
|
+
if (!opusNack) {
|
|
163
|
+
offerCodec.rtcpFeedback = offerCodec.rtcpFeedback.filter(fb => fb.type !== 'nack' || fb.parameter);
|
|
164
|
+
codecRtcpFeedback = codecRtcpFeedback.filter(fb => fb.type !== 'nack' || fb.parameter);
|
|
165
|
+
}
|
|
166
|
+
break;
|
|
189
167
|
}
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
168
|
+
case 'video/vp8':
|
|
169
|
+
case 'video/vp9':
|
|
170
|
+
case 'video/h264':
|
|
171
|
+
case 'video/h265': {
|
|
172
|
+
if (videoGoogleStartBitrate !== undefined) {
|
|
173
|
+
codecParameters['x-google-start-bitrate'] =
|
|
174
|
+
videoGoogleStartBitrate;
|
|
175
|
+
}
|
|
176
|
+
if (videoGoogleMaxBitrate !== undefined) {
|
|
177
|
+
codecParameters['x-google-max-bitrate'] =
|
|
178
|
+
videoGoogleMaxBitrate;
|
|
179
|
+
}
|
|
180
|
+
if (videoGoogleMinBitrate !== undefined) {
|
|
181
|
+
codecParameters['x-google-min-bitrate'] =
|
|
182
|
+
videoGoogleMinBitrate;
|
|
183
|
+
}
|
|
184
|
+
break;
|
|
198
185
|
}
|
|
199
|
-
fmtp.config += `${key}=${codecParameters[key]}`;
|
|
200
186
|
}
|
|
187
|
+
}
|
|
188
|
+
const fmtp = {
|
|
189
|
+
payload: codec.payloadType,
|
|
190
|
+
config: '',
|
|
191
|
+
};
|
|
192
|
+
for (const key of Object.keys(codecParameters)) {
|
|
201
193
|
if (fmtp.config) {
|
|
202
|
-
|
|
203
|
-
}
|
|
204
|
-
for (const fb of codecRtcpFeedback) {
|
|
205
|
-
this._mediaObject.rtcpFb.push({
|
|
206
|
-
payload: codec.payloadType,
|
|
207
|
-
type: fb.type,
|
|
208
|
-
subtype: fb.parameter
|
|
209
|
-
});
|
|
194
|
+
fmtp.config += ';';
|
|
210
195
|
}
|
|
196
|
+
fmtp.config += `${key}=${codecParameters[key]}`;
|
|
211
197
|
}
|
|
212
|
-
|
|
213
|
-
.
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
if (!found) {
|
|
221
|
-
continue;
|
|
222
|
-
}
|
|
223
|
-
this._mediaObject.ext.push({
|
|
224
|
-
uri: ext.uri,
|
|
225
|
-
value: ext.id
|
|
198
|
+
if (fmtp.config) {
|
|
199
|
+
this._mediaObject.fmtp.push(fmtp);
|
|
200
|
+
}
|
|
201
|
+
for (const fb of codecRtcpFeedback) {
|
|
202
|
+
this._mediaObject.rtcpFb.push({
|
|
203
|
+
payload: codec.payloadType,
|
|
204
|
+
type: fb.type,
|
|
205
|
+
subtype: fb.parameter,
|
|
226
206
|
});
|
|
227
207
|
}
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
208
|
+
}
|
|
209
|
+
this._mediaObject.payloads = answerRtpParameters.codecs
|
|
210
|
+
.map((codec) => codec.payloadType)
|
|
211
|
+
.join(' ');
|
|
212
|
+
this._mediaObject.ext = [];
|
|
213
|
+
for (const ext of answerRtpParameters.headerExtensions) {
|
|
214
|
+
// Don't add a header extension if not present in the offer.
|
|
215
|
+
const found = (offerMediaObject.ext || []).some((localExt) => localExt.uri === ext.uri);
|
|
216
|
+
if (!found) {
|
|
217
|
+
continue;
|
|
232
218
|
}
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
219
|
+
this._mediaObject.ext.push({
|
|
220
|
+
uri: ext.uri,
|
|
221
|
+
value: ext.id,
|
|
222
|
+
});
|
|
223
|
+
}
|
|
224
|
+
// Allow both 1 byte and 2 bytes length header extensions.
|
|
225
|
+
if (extmapAllowMixed &&
|
|
226
|
+
offerMediaObject.extmapAllowMixed === 'extmap-allow-mixed') {
|
|
227
|
+
this._mediaObject.extmapAllowMixed = 'extmap-allow-mixed';
|
|
228
|
+
}
|
|
229
|
+
// Simulcast.
|
|
230
|
+
if (offerMediaObject.simulcast) {
|
|
231
|
+
this._mediaObject.simulcast = {
|
|
232
|
+
dir1: 'recv',
|
|
233
|
+
list1: offerMediaObject.simulcast.list1,
|
|
234
|
+
};
|
|
235
|
+
this._mediaObject.rids = [];
|
|
236
|
+
for (const rid of offerMediaObject.rids || []) {
|
|
237
|
+
if (rid.direction !== 'send') {
|
|
238
|
+
continue;
|
|
249
239
|
}
|
|
240
|
+
this._mediaObject.rids.push({
|
|
241
|
+
id: rid.id,
|
|
242
|
+
direction: 'recv',
|
|
243
|
+
});
|
|
250
244
|
}
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
}
|
|
263
|
-
this._mediaObject.rids.push({
|
|
264
|
-
id: rid.id,
|
|
265
|
-
direction: 'recv'
|
|
266
|
-
});
|
|
245
|
+
}
|
|
246
|
+
// Simulcast (draft version 03).
|
|
247
|
+
else if (offerMediaObject.simulcast_03) {
|
|
248
|
+
// eslint-disable-next-line camelcase
|
|
249
|
+
this._mediaObject.simulcast_03 = {
|
|
250
|
+
value: offerMediaObject.simulcast_03.value.replace(/send/g, 'recv'),
|
|
251
|
+
};
|
|
252
|
+
this._mediaObject.rids = [];
|
|
253
|
+
for (const rid of offerMediaObject.rids || []) {
|
|
254
|
+
if (rid.direction !== 'send') {
|
|
255
|
+
continue;
|
|
267
256
|
}
|
|
257
|
+
this._mediaObject.rids.push({
|
|
258
|
+
id: rid.id,
|
|
259
|
+
direction: 'recv',
|
|
260
|
+
});
|
|
268
261
|
}
|
|
269
|
-
this._mediaObject.rtcpMux = 'rtcp-mux';
|
|
270
|
-
this._mediaObject.rtcpRsize = 'rtcp-rsize';
|
|
271
|
-
if (this._planB && this._mediaObject.type === 'video') {
|
|
272
|
-
this._mediaObject.xGoogleFlag = 'conference';
|
|
273
|
-
}
|
|
274
|
-
break;
|
|
275
262
|
}
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
this._mediaObject.payloads = 'webrtc-datachannel';
|
|
281
|
-
this._mediaObject.sctpPort = sctpParameters.port;
|
|
282
|
-
this._mediaObject.maxMessageSize = sctpParameters.maxMessageSize;
|
|
283
|
-
}
|
|
284
|
-
// Old spec.
|
|
285
|
-
else if (offerMediaObject.sctpmap) {
|
|
286
|
-
this._mediaObject.payloads = sctpParameters.port;
|
|
287
|
-
this._mediaObject.sctpmap =
|
|
288
|
-
{
|
|
289
|
-
app: 'webrtc-datachannel',
|
|
290
|
-
sctpmapNumber: sctpParameters.port,
|
|
291
|
-
maxMessageSize: sctpParameters.maxMessageSize
|
|
292
|
-
};
|
|
293
|
-
}
|
|
294
|
-
break;
|
|
263
|
+
this._mediaObject.rtcpMux = 'rtcp-mux';
|
|
264
|
+
this._mediaObject.rtcpRsize = 'rtcp-rsize';
|
|
265
|
+
if (this._planB && this._mediaObject.type === 'video') {
|
|
266
|
+
this._mediaObject.xGoogleFlag = 'conference';
|
|
295
267
|
}
|
|
268
|
+
break;
|
|
269
|
+
}
|
|
270
|
+
case 'application': {
|
|
271
|
+
// New spec.
|
|
272
|
+
if (typeof offerMediaObject.sctpPort === 'number') {
|
|
273
|
+
this._mediaObject.payloads = 'webrtc-datachannel';
|
|
274
|
+
this._mediaObject.sctpPort = sctpParameters.port;
|
|
275
|
+
this._mediaObject.maxMessageSize = sctpParameters.maxMessageSize;
|
|
276
|
+
}
|
|
277
|
+
// Old spec.
|
|
278
|
+
else if (offerMediaObject.sctpmap) {
|
|
279
|
+
this._mediaObject.payloads = sctpParameters.port;
|
|
280
|
+
this._mediaObject.sctpmap = {
|
|
281
|
+
app: 'webrtc-datachannel',
|
|
282
|
+
sctpmapNumber: sctpParameters.port,
|
|
283
|
+
maxMessageSize: sctpParameters.maxMessageSize,
|
|
284
|
+
};
|
|
285
|
+
}
|
|
286
|
+
break;
|
|
287
|
+
}
|
|
296
288
|
}
|
|
297
289
|
}
|
|
298
290
|
setDtlsRole(role) {
|
|
299
291
|
switch (role) {
|
|
300
|
-
case 'client':
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
this._mediaObject.setup = 'actpass';
|
|
313
|
-
break;
|
|
314
|
-
}
|
|
292
|
+
case 'client': {
|
|
293
|
+
this._mediaObject.setup = 'active';
|
|
294
|
+
break;
|
|
295
|
+
}
|
|
296
|
+
case 'server': {
|
|
297
|
+
this._mediaObject.setup = 'passive';
|
|
298
|
+
break;
|
|
299
|
+
}
|
|
300
|
+
case 'auto': {
|
|
301
|
+
this._mediaObject.setup = 'actpass';
|
|
302
|
+
break;
|
|
303
|
+
}
|
|
315
304
|
}
|
|
316
305
|
}
|
|
317
306
|
resume() {
|
|
@@ -334,12 +323,14 @@ class AnswerMediaSection extends MediaSection {
|
|
|
334
323
|
simulcastFormat.paused = !layers[simulcastFormat.scid]?.active;
|
|
335
324
|
}
|
|
336
325
|
}
|
|
337
|
-
this._mediaObject.simulcast.list1 = simulcastStreams
|
|
326
|
+
this._mediaObject.simulcast.list1 = simulcastStreams
|
|
327
|
+
.map(simulcastFormats => simulcastFormats.map(f => `${f.paused ? '~' : ''}${f.scid}`).join(','))
|
|
328
|
+
.join(';');
|
|
338
329
|
}
|
|
339
330
|
}
|
|
340
331
|
exports.AnswerMediaSection = AnswerMediaSection;
|
|
341
332
|
class OfferMediaSection extends MediaSection {
|
|
342
|
-
constructor({ iceParameters, iceCandidates, dtlsParameters, sctpParameters, plainRtpParameters, planB = false, mid, kind, offerRtpParameters, streamId, trackId, oldDataChannelSpec = false }) {
|
|
333
|
+
constructor({ iceParameters, iceCandidates, dtlsParameters, sctpParameters, plainRtpParameters, planB = false, mid, kind, offerRtpParameters, streamId, trackId, oldDataChannelSpec = false, }) {
|
|
343
334
|
super({ iceParameters, iceCandidates, dtlsParameters, planB });
|
|
344
335
|
this._mediaObject.mid = String(mid);
|
|
345
336
|
this._mediaObject.type = kind;
|
|
@@ -354,132 +345,126 @@ class OfferMediaSection extends MediaSection {
|
|
|
354
345
|
this._mediaObject.port = 7;
|
|
355
346
|
}
|
|
356
347
|
else {
|
|
357
|
-
this._mediaObject.connection =
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
};
|
|
348
|
+
this._mediaObject.connection = {
|
|
349
|
+
ip: plainRtpParameters.ip,
|
|
350
|
+
version: plainRtpParameters.ipVersion,
|
|
351
|
+
};
|
|
362
352
|
this._mediaObject.protocol = 'RTP/AVP';
|
|
363
353
|
this._mediaObject.port = plainRtpParameters.port;
|
|
364
354
|
}
|
|
365
355
|
switch (kind) {
|
|
366
356
|
case 'audio':
|
|
367
|
-
case 'video':
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
357
|
+
case 'video': {
|
|
358
|
+
this._mediaObject.direction = 'sendonly';
|
|
359
|
+
this._mediaObject.rtp = [];
|
|
360
|
+
this._mediaObject.rtcpFb = [];
|
|
361
|
+
this._mediaObject.fmtp = [];
|
|
362
|
+
if (!this._planB) {
|
|
363
|
+
this._mediaObject.msid = `${streamId || '-'} ${trackId}`;
|
|
364
|
+
}
|
|
365
|
+
for (const codec of offerRtpParameters.codecs) {
|
|
366
|
+
const rtp = {
|
|
367
|
+
payload: codec.payloadType,
|
|
368
|
+
codec: getCodecName(codec),
|
|
369
|
+
rate: codec.clockRate,
|
|
370
|
+
};
|
|
371
|
+
if (codec.channels > 1) {
|
|
372
|
+
rtp.encoding = codec.channels;
|
|
375
373
|
}
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
if (codec.channels > 1) {
|
|
383
|
-
rtp.encoding = codec.channels;
|
|
384
|
-
}
|
|
385
|
-
this._mediaObject.rtp.push(rtp);
|
|
386
|
-
const fmtp = {
|
|
387
|
-
payload: codec.payloadType,
|
|
388
|
-
config: ''
|
|
389
|
-
};
|
|
390
|
-
for (const key of Object.keys(codec.parameters)) {
|
|
391
|
-
if (fmtp.config) {
|
|
392
|
-
fmtp.config += ';';
|
|
393
|
-
}
|
|
394
|
-
fmtp.config += `${key}=${codec.parameters[key]}`;
|
|
395
|
-
}
|
|
374
|
+
this._mediaObject.rtp.push(rtp);
|
|
375
|
+
const fmtp = {
|
|
376
|
+
payload: codec.payloadType,
|
|
377
|
+
config: '',
|
|
378
|
+
};
|
|
379
|
+
for (const key of Object.keys(codec.parameters)) {
|
|
396
380
|
if (fmtp.config) {
|
|
397
|
-
|
|
398
|
-
}
|
|
399
|
-
for (const fb of codec.rtcpFeedback) {
|
|
400
|
-
this._mediaObject.rtcpFb.push({
|
|
401
|
-
payload: codec.payloadType,
|
|
402
|
-
type: fb.type,
|
|
403
|
-
subtype: fb.parameter
|
|
404
|
-
});
|
|
381
|
+
fmtp.config += ';';
|
|
405
382
|
}
|
|
383
|
+
fmtp.config += `${key}=${codec.parameters[key]}`;
|
|
384
|
+
}
|
|
385
|
+
if (fmtp.config) {
|
|
386
|
+
this._mediaObject.fmtp.push(fmtp);
|
|
406
387
|
}
|
|
407
|
-
|
|
408
|
-
.
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
this._mediaObject.ext.push({
|
|
413
|
-
uri: ext.uri,
|
|
414
|
-
value: ext.id
|
|
388
|
+
for (const fb of codec.rtcpFeedback) {
|
|
389
|
+
this._mediaObject.rtcpFb.push({
|
|
390
|
+
payload: codec.payloadType,
|
|
391
|
+
type: fb.type,
|
|
392
|
+
subtype: fb.parameter,
|
|
415
393
|
});
|
|
416
394
|
}
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
395
|
+
}
|
|
396
|
+
this._mediaObject.payloads = offerRtpParameters.codecs
|
|
397
|
+
.map((codec) => codec.payloadType)
|
|
398
|
+
.join(' ');
|
|
399
|
+
this._mediaObject.ext = [];
|
|
400
|
+
for (const ext of offerRtpParameters.headerExtensions) {
|
|
401
|
+
this._mediaObject.ext.push({
|
|
402
|
+
uri: ext.uri,
|
|
403
|
+
value: ext.id,
|
|
404
|
+
});
|
|
405
|
+
}
|
|
406
|
+
this._mediaObject.rtcpMux = 'rtcp-mux';
|
|
407
|
+
this._mediaObject.rtcpRsize = 'rtcp-rsize';
|
|
408
|
+
const encoding = offerRtpParameters.encodings[0];
|
|
409
|
+
const ssrc = encoding.ssrc;
|
|
410
|
+
const rtxSsrc = encoding.rtx && encoding.rtx.ssrc ? encoding.rtx.ssrc : undefined;
|
|
411
|
+
this._mediaObject.ssrcs = [];
|
|
412
|
+
this._mediaObject.ssrcGroups = [];
|
|
413
|
+
if (offerRtpParameters.rtcp.cname) {
|
|
414
|
+
this._mediaObject.ssrcs.push({
|
|
415
|
+
id: ssrc,
|
|
416
|
+
attribute: 'cname',
|
|
417
|
+
value: offerRtpParameters.rtcp.cname,
|
|
418
|
+
});
|
|
419
|
+
}
|
|
420
|
+
if (this._planB) {
|
|
421
|
+
this._mediaObject.ssrcs.push({
|
|
422
|
+
id: ssrc,
|
|
423
|
+
attribute: 'msid',
|
|
424
|
+
value: `${streamId || '-'} ${trackId}`,
|
|
425
|
+
});
|
|
426
|
+
}
|
|
427
|
+
if (rtxSsrc) {
|
|
426
428
|
if (offerRtpParameters.rtcp.cname) {
|
|
427
429
|
this._mediaObject.ssrcs.push({
|
|
428
|
-
id:
|
|
430
|
+
id: rtxSsrc,
|
|
429
431
|
attribute: 'cname',
|
|
430
|
-
value: offerRtpParameters.rtcp.cname
|
|
432
|
+
value: offerRtpParameters.rtcp.cname,
|
|
431
433
|
});
|
|
432
434
|
}
|
|
433
435
|
if (this._planB) {
|
|
434
436
|
this._mediaObject.ssrcs.push({
|
|
435
|
-
id:
|
|
437
|
+
id: rtxSsrc,
|
|
436
438
|
attribute: 'msid',
|
|
437
|
-
value: `${streamId || '-'} ${trackId}
|
|
438
|
-
});
|
|
439
|
-
}
|
|
440
|
-
if (rtxSsrc) {
|
|
441
|
-
if (offerRtpParameters.rtcp.cname) {
|
|
442
|
-
this._mediaObject.ssrcs.push({
|
|
443
|
-
id: rtxSsrc,
|
|
444
|
-
attribute: 'cname',
|
|
445
|
-
value: offerRtpParameters.rtcp.cname
|
|
446
|
-
});
|
|
447
|
-
}
|
|
448
|
-
if (this._planB) {
|
|
449
|
-
this._mediaObject.ssrcs.push({
|
|
450
|
-
id: rtxSsrc,
|
|
451
|
-
attribute: 'msid',
|
|
452
|
-
value: `${streamId || '-'} ${trackId}`
|
|
453
|
-
});
|
|
454
|
-
}
|
|
455
|
-
// Associate original and retransmission SSRCs.
|
|
456
|
-
this._mediaObject.ssrcGroups.push({
|
|
457
|
-
semantics: 'FID',
|
|
458
|
-
ssrcs: `${ssrc} ${rtxSsrc}`
|
|
439
|
+
value: `${streamId || '-'} ${trackId}`,
|
|
459
440
|
});
|
|
460
441
|
}
|
|
461
|
-
|
|
442
|
+
// Associate original and retransmission SSRCs.
|
|
443
|
+
this._mediaObject.ssrcGroups.push({
|
|
444
|
+
semantics: 'FID',
|
|
445
|
+
ssrcs: `${ssrc} ${rtxSsrc}`,
|
|
446
|
+
});
|
|
462
447
|
}
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
}
|
|
481
|
-
break;
|
|
448
|
+
break;
|
|
449
|
+
}
|
|
450
|
+
case 'application': {
|
|
451
|
+
// New spec.
|
|
452
|
+
if (!oldDataChannelSpec) {
|
|
453
|
+
this._mediaObject.payloads = 'webrtc-datachannel';
|
|
454
|
+
this._mediaObject.sctpPort = sctpParameters.port;
|
|
455
|
+
this._mediaObject.maxMessageSize = sctpParameters.maxMessageSize;
|
|
456
|
+
}
|
|
457
|
+
// Old spec.
|
|
458
|
+
else {
|
|
459
|
+
this._mediaObject.payloads = sctpParameters.port;
|
|
460
|
+
this._mediaObject.sctpmap = {
|
|
461
|
+
app: 'webrtc-datachannel',
|
|
462
|
+
sctpmapNumber: sctpParameters.port,
|
|
463
|
+
maxMessageSize: sctpParameters.maxMessageSize,
|
|
464
|
+
};
|
|
482
465
|
}
|
|
466
|
+
break;
|
|
467
|
+
}
|
|
483
468
|
}
|
|
484
469
|
}
|
|
485
470
|
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
@@ -490,12 +475,10 @@ class OfferMediaSection extends MediaSection {
|
|
|
490
475
|
resume() {
|
|
491
476
|
this._mediaObject.direction = 'sendonly';
|
|
492
477
|
}
|
|
493
|
-
planBReceive({ offerRtpParameters, streamId, trackId }) {
|
|
478
|
+
planBReceive({ offerRtpParameters, streamId, trackId, }) {
|
|
494
479
|
const encoding = offerRtpParameters.encodings[0];
|
|
495
480
|
const ssrc = encoding.ssrc;
|
|
496
|
-
const rtxSsrc =
|
|
497
|
-
? encoding.rtx.ssrc
|
|
498
|
-
: undefined;
|
|
481
|
+
const rtxSsrc = encoding.rtx && encoding.rtx.ssrc ? encoding.rtx.ssrc : undefined;
|
|
499
482
|
const payloads = this._mediaObject.payloads.split(' ');
|
|
500
483
|
for (const codec of offerRtpParameters.codecs) {
|
|
501
484
|
if (payloads.includes(String(codec.payloadType))) {
|
|
@@ -504,7 +487,7 @@ class OfferMediaSection extends MediaSection {
|
|
|
504
487
|
const rtp = {
|
|
505
488
|
payload: codec.payloadType,
|
|
506
489
|
codec: getCodecName(codec),
|
|
507
|
-
rate: codec.clockRate
|
|
490
|
+
rate: codec.clockRate,
|
|
508
491
|
};
|
|
509
492
|
if (codec.channels > 1) {
|
|
510
493
|
rtp.encoding = codec.channels;
|
|
@@ -512,7 +495,7 @@ class OfferMediaSection extends MediaSection {
|
|
|
512
495
|
this._mediaObject.rtp.push(rtp);
|
|
513
496
|
const fmtp = {
|
|
514
497
|
payload: codec.payloadType,
|
|
515
|
-
config: ''
|
|
498
|
+
config: '',
|
|
516
499
|
};
|
|
517
500
|
for (const key of Object.keys(codec.parameters)) {
|
|
518
501
|
if (fmtp.config) {
|
|
@@ -527,12 +510,11 @@ class OfferMediaSection extends MediaSection {
|
|
|
527
510
|
this._mediaObject.rtcpFb.push({
|
|
528
511
|
payload: codec.payloadType,
|
|
529
512
|
type: fb.type,
|
|
530
|
-
subtype: fb.parameter
|
|
513
|
+
subtype: fb.parameter,
|
|
531
514
|
});
|
|
532
515
|
}
|
|
533
516
|
}
|
|
534
|
-
this._mediaObject.payloads += ` ${offerRtpParameters
|
|
535
|
-
.codecs
|
|
517
|
+
this._mediaObject.payloads += ` ${offerRtpParameters.codecs
|
|
536
518
|
.filter((codec) => !this._mediaObject.payloads.includes(codec.payloadType))
|
|
537
519
|
.map((codec) => codec.payloadType)
|
|
538
520
|
.join(' ')}`;
|
|
@@ -541,45 +523,41 @@ class OfferMediaSection extends MediaSection {
|
|
|
541
523
|
this._mediaObject.ssrcs.push({
|
|
542
524
|
id: ssrc,
|
|
543
525
|
attribute: 'cname',
|
|
544
|
-
value: offerRtpParameters.rtcp.cname
|
|
526
|
+
value: offerRtpParameters.rtcp.cname,
|
|
545
527
|
});
|
|
546
528
|
}
|
|
547
529
|
this._mediaObject.ssrcs.push({
|
|
548
530
|
id: ssrc,
|
|
549
531
|
attribute: 'msid',
|
|
550
|
-
value: `${streamId || '-'} ${trackId}
|
|
532
|
+
value: `${streamId || '-'} ${trackId}`,
|
|
551
533
|
});
|
|
552
534
|
if (rtxSsrc) {
|
|
553
535
|
if (offerRtpParameters.rtcp.cname) {
|
|
554
536
|
this._mediaObject.ssrcs.push({
|
|
555
537
|
id: rtxSsrc,
|
|
556
538
|
attribute: 'cname',
|
|
557
|
-
value: offerRtpParameters.rtcp.cname
|
|
539
|
+
value: offerRtpParameters.rtcp.cname,
|
|
558
540
|
});
|
|
559
541
|
}
|
|
560
542
|
this._mediaObject.ssrcs.push({
|
|
561
543
|
id: rtxSsrc,
|
|
562
544
|
attribute: 'msid',
|
|
563
|
-
value: `${streamId || '-'} ${trackId}
|
|
545
|
+
value: `${streamId || '-'} ${trackId}`,
|
|
564
546
|
});
|
|
565
547
|
// Associate original and retransmission SSRCs.
|
|
566
548
|
this._mediaObject.ssrcGroups.push({
|
|
567
549
|
semantics: 'FID',
|
|
568
|
-
ssrcs: `${ssrc} ${rtxSsrc}
|
|
550
|
+
ssrcs: `${ssrc} ${rtxSsrc}`,
|
|
569
551
|
});
|
|
570
552
|
}
|
|
571
553
|
}
|
|
572
|
-
planBStopReceiving({ offerRtpParameters }) {
|
|
554
|
+
planBStopReceiving({ offerRtpParameters, }) {
|
|
573
555
|
const encoding = offerRtpParameters.encodings[0];
|
|
574
556
|
const ssrc = encoding.ssrc;
|
|
575
|
-
const rtxSsrc =
|
|
576
|
-
|
|
577
|
-
: undefined;
|
|
578
|
-
this._mediaObject.ssrcs = this._mediaObject.ssrcs
|
|
579
|
-
.filter((s) => s.id !== ssrc && s.id !== rtxSsrc);
|
|
557
|
+
const rtxSsrc = encoding.rtx && encoding.rtx.ssrc ? encoding.rtx.ssrc : undefined;
|
|
558
|
+
this._mediaObject.ssrcs = this._mediaObject.ssrcs.filter((s) => s.id !== ssrc && s.id !== rtxSsrc);
|
|
580
559
|
if (rtxSsrc) {
|
|
581
|
-
this._mediaObject.ssrcGroups = this._mediaObject.ssrcGroups
|
|
582
|
-
.filter((group) => group.ssrcs !== `${ssrc} ${rtxSsrc}`);
|
|
560
|
+
this._mediaObject.ssrcGroups = this._mediaObject.ssrcGroups.filter((group) => group.ssrcs !== `${ssrc} ${rtxSsrc}`);
|
|
583
561
|
}
|
|
584
562
|
}
|
|
585
563
|
}
|