|
@@ -161,6 +161,48 @@ export default class LocalSdpMunger {
|
161
|
161
|
return modified;
|
162
|
162
|
}
|
163
|
163
|
|
|
164
|
+ /**
|
|
165
|
+ * Modifies 'cname', 'msid', 'label' and 'mslabel' by appending
|
|
166
|
+ * the id of {@link LocalSdpMunger#tpc} at the end, preceding by a dash
|
|
167
|
+ * sign.
|
|
168
|
+ *
|
|
169
|
+ * @param {MLineWrap} mediaSection - The media part (audio or video) of the
|
|
170
|
+ * session description which will be modified in place.
|
|
171
|
+ * @returns {void}
|
|
172
|
+ * @private
|
|
173
|
+ */
|
|
174
|
+ _transformMediaIdentifiers(mediaSection) {
|
|
175
|
+ const pcId = this.tpc.id;
|
|
176
|
+
|
|
177
|
+ for (const ssrcLine of mediaSection.ssrcs) {
|
|
178
|
+ switch (ssrcLine.attribute) {
|
|
179
|
+ case 'cname':
|
|
180
|
+ case 'label':
|
|
181
|
+ case 'mslabel':
|
|
182
|
+ ssrcLine.value = ssrcLine.value && `${ssrcLine.value}-${pcId}`;
|
|
183
|
+ break;
|
|
184
|
+ case 'msid': {
|
|
185
|
+ if (ssrcLine.value) {
|
|
186
|
+ const streamAndTrackIDs = ssrcLine.value.split(' ');
|
|
187
|
+
|
|
188
|
+ if (streamAndTrackIDs.length === 2) {
|
|
189
|
+ const streamId = streamAndTrackIDs[0];
|
|
190
|
+ const trackId = streamAndTrackIDs[1];
|
|
191
|
+
|
|
192
|
+ ssrcLine.value
|
|
193
|
+ = `${streamId}-${pcId} ${trackId}-${pcId}`;
|
|
194
|
+ } else {
|
|
195
|
+ logger.warn(
|
|
196
|
+ 'Unable to munge local MSID'
|
|
197
|
+ + `- weird format detected: ${ssrcLine.value}`);
|
|
198
|
+ }
|
|
199
|
+ }
|
|
200
|
+ break;
|
|
201
|
+ }
|
|
202
|
+ }
|
|
203
|
+ }
|
|
204
|
+ }
|
|
205
|
+
|
164
|
206
|
/**
|
165
|
207
|
* Maybe modifies local description to fake local video tracks SDP when
|
166
|
208
|
* those are muted.
|
|
@@ -185,4 +227,44 @@ export default class LocalSdpMunger {
|
185
|
227
|
|
186
|
228
|
return desc;
|
187
|
229
|
}
|
|
230
|
+
|
|
231
|
+ /**
|
|
232
|
+ * This transformation will make sure that stream identifiers are unique
|
|
233
|
+ * across all of the local PeerConnections even if the same stream is used
|
|
234
|
+ * by multiple instances at the same time.
|
|
235
|
+ * Each PeerConnection assigns different SSRCs to the same local
|
|
236
|
+ * MediaStream, but the MSID remains the same as it's used to identify
|
|
237
|
+ * the stream by the WebRTC backend. The transformation will append
|
|
238
|
+ * {@link TraceablePeerConnection#id} at the end of each stream's identifier
|
|
239
|
+ * ("cname", "msid", "label" and "mslabel").
|
|
240
|
+ *
|
|
241
|
+ * @param {RTCSessionDescription} sessionDesc - The local session
|
|
242
|
+ * description (this instance remains unchanged).
|
|
243
|
+ * @return {RTCSessionDescription} - Transformed local session description
|
|
244
|
+ * (a modified copy of the one given as the input).
|
|
245
|
+ */
|
|
246
|
+ transformStreamIdentifiers(sessionDesc) {
|
|
247
|
+ // FIXME similar check is probably duplicated in all other transformers
|
|
248
|
+ if (!sessionDesc || !sessionDesc.sdp || !sessionDesc.type) {
|
|
249
|
+ return sessionDesc;
|
|
250
|
+ }
|
|
251
|
+
|
|
252
|
+ const transformer = new SdpTransformWrap(sessionDesc.sdp);
|
|
253
|
+ const audioMLine = transformer.selectMedia('audio');
|
|
254
|
+
|
|
255
|
+ if (audioMLine) {
|
|
256
|
+ this._transformMediaIdentifiers(audioMLine);
|
|
257
|
+ }
|
|
258
|
+
|
|
259
|
+ const videoMLine = transformer.selectMedia('video');
|
|
260
|
+
|
|
261
|
+ if (videoMLine) {
|
|
262
|
+ this._transformMediaIdentifiers(videoMLine);
|
|
263
|
+ }
|
|
264
|
+
|
|
265
|
+ return new RTCSessionDescription({
|
|
266
|
+ type: sessionDesc.type,
|
|
267
|
+ sdp: transformer.toRawSDP()
|
|
268
|
+ });
|
|
269
|
+ }
|
188
|
270
|
}
|