mediasoup-client 3.6.46 → 3.6.50

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.
Files changed (54) hide show
  1. package/.vimrc +21 -0
  2. package/NO_GIT/Notes.txt +18 -0
  3. package/lib/Transport.d.ts +3 -0
  4. package/lib/Transport.d.ts.map +1 -1
  5. package/lib/Transport.js +110 -39
  6. package/lib/handlers/Chrome55.d.ts +1 -1
  7. package/lib/handlers/Chrome55.d.ts.map +1 -1
  8. package/lib/handlers/Chrome55.js +42 -28
  9. package/lib/handlers/Chrome67.d.ts +1 -1
  10. package/lib/handlers/Chrome67.d.ts.map +1 -1
  11. package/lib/handlers/Chrome67.js +45 -30
  12. package/lib/handlers/Chrome70.d.ts +1 -1
  13. package/lib/handlers/Chrome70.d.ts.map +1 -1
  14. package/lib/handlers/Chrome70.js +44 -29
  15. package/lib/handlers/Chrome74.d.ts +1 -1
  16. package/lib/handlers/Chrome74.d.ts.map +1 -1
  17. package/lib/handlers/Chrome74.js +47 -29
  18. package/lib/handlers/Edge11.d.ts +1 -1
  19. package/lib/handlers/Edge11.d.ts.map +1 -1
  20. package/lib/handlers/Edge11.js +28 -20
  21. package/lib/handlers/FakeHandler.d.ts +1 -1
  22. package/lib/handlers/FakeHandler.d.ts.map +1 -1
  23. package/lib/handlers/FakeHandler.js +13 -10
  24. package/lib/handlers/Firefox60.d.ts +1 -1
  25. package/lib/handlers/Firefox60.d.ts.map +1 -1
  26. package/lib/handlers/Firefox60.js +47 -30
  27. package/lib/handlers/HandlerInterface.d.ts +1 -1
  28. package/lib/handlers/HandlerInterface.d.ts.map +1 -1
  29. package/lib/handlers/ReactNative.d.ts +1 -1
  30. package/lib/handlers/ReactNative.d.ts.map +1 -1
  31. package/lib/handlers/ReactNative.js +50 -34
  32. package/lib/handlers/Safari11.d.ts +1 -1
  33. package/lib/handlers/Safari11.d.ts.map +1 -1
  34. package/lib/handlers/Safari11.js +43 -30
  35. package/lib/handlers/Safari12.d.ts +1 -1
  36. package/lib/handlers/Safari12.d.ts.map +1 -1
  37. package/lib/handlers/Safari12.js +44 -29
  38. package/lib/index.d.ts +1 -1
  39. package/lib/index.js +1 -1
  40. package/lib/ortc.js +4 -6
  41. package/package.json +10 -10
  42. package/src/Transport.ts +162 -58
  43. package/src/handlers/Chrome55.ts +52 -31
  44. package/src/handlers/Chrome67.ts +54 -33
  45. package/src/handlers/Chrome70.ts +55 -32
  46. package/src/handlers/Chrome74.ts +59 -32
  47. package/src/handlers/Edge11.ts +39 -25
  48. package/src/handlers/FakeHandler.ts +18 -10
  49. package/src/handlers/Firefox60.ts +57 -33
  50. package/src/handlers/HandlerInterface.ts +2 -2
  51. package/src/handlers/ReactNative.ts +62 -38
  52. package/src/handlers/Safari11.ts +54 -33
  53. package/src/handlers/Safari12.ts +55 -32
  54. package/src/ortc.ts +6 -8
@@ -580,25 +580,31 @@ export class Chrome55 extends HandlerInterface
580
580
  }
581
581
 
582
582
  async receive(
583
- { trackId, kind, rtpParameters }: HandlerReceiveOptions
584
- ): Promise<HandlerReceiveResult>
583
+ optionsList: HandlerReceiveOptions[]
584
+ ) : Promise<HandlerReceiveResult[]>
585
585
  {
586
586
  this._assertRecvDirection();
587
587
 
588
- logger.debug('receive() [trackId:%s, kind:%s]', trackId, kind);
588
+ const results: HandlerReceiveResult[] = [];
589
589
 
590
- const localId = trackId;
591
- const mid = kind;
592
- const streamId = rtpParameters.rtcp!.cname!;
590
+ for (const options of optionsList)
591
+ {
592
+ const { trackId, kind, rtpParameters } = options;
593
593
 
594
- this._remoteSdp!.receive(
595
- {
596
- mid,
597
- kind,
598
- offerRtpParameters : rtpParameters,
599
- streamId,
600
- trackId
601
- });
594
+ logger.debug('receive() [trackId:%s, kind:%s]', trackId, kind);
595
+
596
+ const mid = kind;
597
+ const streamId = rtpParameters.rtcp!.cname!;
598
+
599
+ this._remoteSdp!.receive(
600
+ {
601
+ mid,
602
+ kind,
603
+ offerRtpParameters : rtpParameters,
604
+ streamId,
605
+ trackId
606
+ });
607
+ }
602
608
 
603
609
  const offer = { type: 'offer', sdp: this._remoteSdp!.getSdp() };
604
610
 
@@ -610,16 +616,22 @@ export class Chrome55 extends HandlerInterface
610
616
 
611
617
  let answer = await this._pc.createAnswer();
612
618
  const localSdpObject = sdpTransform.parse(answer.sdp);
613
- const answerMediaObject = localSdpObject.media
614
- .find((m: any) => String(m.mid) === mid);
615
619
 
616
- // May need to modify codec parameters in the answer based on codec
617
- // parameters in the offer.
618
- sdpCommonUtils.applyCodecParameters(
619
- {
620
- offerRtpParameters : rtpParameters,
621
- answerMediaObject
622
- });
620
+ for (const options of optionsList)
621
+ {
622
+ const { kind, rtpParameters } = options;
623
+ const mid = kind;
624
+ const answerMediaObject = localSdpObject.media
625
+ .find((m: any) => String(m.mid) === mid);
626
+
627
+ // May need to modify codec parameters in the answer based on codec
628
+ // parameters in the offer.
629
+ sdpCommonUtils.applyCodecParameters(
630
+ {
631
+ offerRtpParameters : rtpParameters,
632
+ answerMediaObject
633
+ });
634
+ }
623
635
 
624
636
  answer = { type: 'answer', sdp: sdpTransform.write(localSdpObject) };
625
637
 
@@ -638,17 +650,26 @@ export class Chrome55 extends HandlerInterface
638
650
 
639
651
  await this._pc.setLocalDescription(answer);
640
652
 
641
- const stream = this._pc.getRemoteStreams()
642
- .find((s: any) => s.id === streamId);
643
- const track = stream.getTrackById(localId);
653
+ for (const options of optionsList)
654
+ {
655
+ const { kind, trackId, rtpParameters } = options;
656
+ const mid = kind;
657
+ const localId = trackId;
658
+ const streamId = rtpParameters.rtcp!.cname!;
659
+ const stream = this._pc.getRemoteStreams()
660
+ .find((s: any) => s.id === streamId);
661
+ const track = stream.getTrackById(localId);
644
662
 
645
- if (!track)
646
- throw new Error('remote track not found');
663
+ if (!track)
664
+ throw new Error('remote track not found');
647
665
 
648
- // Insert into the map.
649
- this._mapRecvLocalIdInfo.set(localId, { mid, rtpParameters });
666
+ // Insert into the map.
667
+ this._mapRecvLocalIdInfo.set(localId, { mid, rtpParameters });
668
+
669
+ results.push({ localId, track });
670
+ }
650
671
 
651
- return { localId, track };
672
+ return results;
652
673
  }
653
674
 
654
675
  async stopReceiving(localId: string): Promise<void>
@@ -657,24 +657,31 @@ export class Chrome67 extends HandlerInterface
657
657
  }
658
658
 
659
659
  async receive(
660
- { trackId, kind, rtpParameters }: HandlerReceiveOptions
661
- ): Promise<HandlerReceiveResult>
660
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
661
+ optionsList: HandlerReceiveOptions[]
662
+ ) : Promise<HandlerReceiveResult[]>
662
663
  {
663
664
  this._assertRecvDirection();
664
665
 
665
- logger.debug('receive() [trackId:%s, kind:%s]', trackId, kind);
666
+ const results: HandlerReceiveResult[] = [];
666
667
 
667
- const localId = trackId;
668
- const mid = kind;
668
+ for (const options of optionsList)
669
+ {
670
+ const { trackId, kind, rtpParameters } = options;
669
671
 
670
- this._remoteSdp!.receive(
671
- {
672
- mid,
673
- kind,
674
- offerRtpParameters : rtpParameters,
675
- streamId : rtpParameters.rtcp!.cname!,
676
- trackId
677
- });
672
+ logger.debug('receive() [trackId:%s, kind:%s]', trackId, kind);
673
+
674
+ const mid = kind;
675
+
676
+ this._remoteSdp!.receive(
677
+ {
678
+ mid,
679
+ kind,
680
+ offerRtpParameters : rtpParameters,
681
+ streamId : rtpParameters.rtcp!.cname!,
682
+ trackId
683
+ });
684
+ }
678
685
 
679
686
  const offer = { type: 'offer', sdp: this._remoteSdp!.getSdp() };
680
687
 
@@ -686,16 +693,22 @@ export class Chrome67 extends HandlerInterface
686
693
 
687
694
  let answer = await this._pc.createAnswer();
688
695
  const localSdpObject = sdpTransform.parse(answer.sdp);
689
- const answerMediaObject = localSdpObject.media
690
- .find((m: any) => String(m.mid) === mid);
691
696
 
692
- // May need to modify codec parameters in the answer based on codec
693
- // parameters in the offer.
694
- sdpCommonUtils.applyCodecParameters(
695
- {
696
- offerRtpParameters : rtpParameters,
697
- answerMediaObject
698
- });
697
+ for (const options of optionsList)
698
+ {
699
+ const { kind, rtpParameters } = options;
700
+ const mid = kind;
701
+ const answerMediaObject = localSdpObject.media
702
+ .find((m: any) => String(m.mid) === mid);
703
+
704
+ // May need to modify codec parameters in the answer based on codec
705
+ // parameters in the offer.
706
+ sdpCommonUtils.applyCodecParameters(
707
+ {
708
+ offerRtpParameters : rtpParameters,
709
+ answerMediaObject
710
+ });
711
+ }
699
712
 
700
713
  answer = { type: 'answer', sdp: sdpTransform.write(localSdpObject) };
701
714
 
@@ -714,20 +727,28 @@ export class Chrome67 extends HandlerInterface
714
727
 
715
728
  await this._pc.setLocalDescription(answer);
716
729
 
717
- const rtpReceiver = this._pc.getReceivers()
718
- .find((r: RTCRtpReceiver) => r.track && r.track.id === localId);
730
+ for (const options of optionsList)
731
+ {
732
+ const { kind, trackId, rtpParameters } = options;
733
+ const localId = trackId;
734
+ const mid = kind;
735
+ const rtpReceiver = this._pc.getReceivers()
736
+ .find((r: RTCRtpReceiver) => r.track && r.track.id === localId);
719
737
 
720
- if (!rtpReceiver)
721
- throw new Error('new RTCRtpReceiver not');
738
+ if (!rtpReceiver)
739
+ throw new Error('new RTCRtpReceiver not');
722
740
 
723
- // Insert into the map.
724
- this._mapRecvLocalIdInfo.set(localId, { mid, rtpParameters, rtpReceiver });
741
+ // Insert into the map.
742
+ this._mapRecvLocalIdInfo.set(localId, { mid, rtpParameters, rtpReceiver });
725
743
 
726
- return {
727
- localId,
728
- track : rtpReceiver.track,
729
- rtpReceiver
730
- };
744
+ results.push({
745
+ localId,
746
+ track : rtpReceiver.track,
747
+ rtpReceiver
748
+ });
749
+ }
750
+
751
+ return results;
731
752
  }
732
753
 
733
754
  async stopReceiving(localId: string): Promise<void>
@@ -663,23 +663,33 @@ export class Chrome70 extends HandlerInterface
663
663
  }
664
664
 
665
665
  async receive(
666
- { trackId, kind, rtpParameters }: HandlerReceiveOptions
667
- ): Promise<HandlerReceiveResult>
666
+ optionsList: HandlerReceiveOptions[]
667
+ ) : Promise<HandlerReceiveResult[]>
668
668
  {
669
669
  this._assertRecvDirection();
670
670
 
671
- logger.debug('receive() [trackId:%s, kind:%s]', trackId, kind);
671
+ const results: HandlerReceiveResult[] = [];
672
+ const mapLocalId: Map<string, string> = new Map();
672
673
 
673
- const localId = rtpParameters.mid || String(this._mapMidTransceiver.size);
674
+ for (const options of optionsList)
675
+ {
676
+ const { trackId, kind, rtpParameters } = options;
674
677
 
675
- this._remoteSdp!.receive(
676
- {
677
- mid : localId,
678
- kind,
679
- offerRtpParameters : rtpParameters,
680
- streamId : rtpParameters.rtcp!.cname!,
681
- trackId
682
- });
678
+ logger.debug('receive() [trackId:%s, kind:%s]', trackId, kind);
679
+
680
+ const localId = rtpParameters.mid || String(this._mapMidTransceiver.size);
681
+
682
+ mapLocalId.set(trackId, localId);
683
+
684
+ this._remoteSdp!.receive(
685
+ {
686
+ mid : localId,
687
+ kind,
688
+ offerRtpParameters : rtpParameters,
689
+ streamId : rtpParameters.rtcp!.cname!,
690
+ trackId
691
+ });
692
+ }
683
693
 
684
694
  const offer = { type: 'offer', sdp: this._remoteSdp!.getSdp() };
685
695
 
@@ -691,16 +701,22 @@ export class Chrome70 extends HandlerInterface
691
701
 
692
702
  let answer = await this._pc.createAnswer();
693
703
  const localSdpObject = sdpTransform.parse(answer.sdp);
694
- const answerMediaObject = localSdpObject.media
695
- .find((m: any) => String(m.mid) === localId);
696
704
 
697
- // May need to modify codec parameters in the answer based on codec
698
- // parameters in the offer.
699
- sdpCommonUtils.applyCodecParameters(
700
- {
701
- offerRtpParameters : rtpParameters,
702
- answerMediaObject
703
- });
705
+ for (const options of optionsList)
706
+ {
707
+ const { trackId, rtpParameters } = options;
708
+ const localId = mapLocalId.get(trackId);
709
+ const answerMediaObject = localSdpObject.media
710
+ .find((m: any) => String(m.mid) === localId);
711
+
712
+ // May need to modify codec parameters in the answer based on codec
713
+ // parameters in the offer.
714
+ sdpCommonUtils.applyCodecParameters(
715
+ {
716
+ offerRtpParameters : rtpParameters,
717
+ answerMediaObject
718
+ });
719
+ }
704
720
 
705
721
  answer = { type: 'answer', sdp: sdpTransform.write(localSdpObject) };
706
722
 
@@ -719,20 +735,27 @@ export class Chrome70 extends HandlerInterface
719
735
 
720
736
  await this._pc.setLocalDescription(answer);
721
737
 
722
- const transceiver = this._pc.getTransceivers()
723
- .find((t: RTCRtpTransceiver) => t.mid === localId);
738
+ for (const options of optionsList)
739
+ {
740
+ const { trackId } = options;
741
+ const localId = mapLocalId.get(trackId)!;
742
+ const transceiver = this._pc.getTransceivers()
743
+ .find((t: RTCRtpTransceiver) => t.mid === localId);
724
744
 
725
- if (!transceiver)
726
- throw new Error('new RTCRtpTransceiver not found');
745
+ if (!transceiver)
746
+ throw new Error('new RTCRtpTransceiver not found');
727
747
 
728
- // Store in the map.
729
- this._mapMidTransceiver.set(localId, transceiver);
748
+ // Store in the map.
749
+ this._mapMidTransceiver.set(localId, transceiver);
730
750
 
731
- return {
732
- localId,
733
- track : transceiver.receiver.track,
734
- rtpReceiver : transceiver.receiver
735
- };
751
+ results.push({
752
+ localId,
753
+ track : transceiver.receiver.track,
754
+ rtpReceiver : transceiver.receiver
755
+ });
756
+ }
757
+
758
+ return results;
736
759
  }
737
760
 
738
761
  async stopReceiving(localId: string): Promise<void>
@@ -649,23 +649,33 @@ export class Chrome74 extends HandlerInterface
649
649
  }
650
650
 
651
651
  async receive(
652
- { trackId, kind, rtpParameters }: HandlerReceiveOptions
653
- ): Promise<HandlerReceiveResult>
652
+ optionsList: HandlerReceiveOptions[]
653
+ ) : Promise<HandlerReceiveResult[]>
654
654
  {
655
655
  this._assertRecvDirection();
656
656
 
657
- logger.debug('receive() [trackId:%s, kind:%s]', trackId, kind);
657
+ const results: HandlerReceiveResult[] = [];
658
+ const mapLocalId: Map<string, string> = new Map();
658
659
 
659
- const localId = rtpParameters.mid || String(this._mapMidTransceiver.size);
660
+ for (const options of optionsList)
661
+ {
662
+ const { trackId, kind, rtpParameters } = options;
660
663
 
661
- this._remoteSdp!.receive(
662
- {
663
- mid : localId,
664
- kind,
665
- offerRtpParameters : rtpParameters,
666
- streamId : rtpParameters.rtcp!.cname!,
667
- trackId
668
- });
664
+ logger.debug('receive() [trackId:%s, kind:%s]', trackId, kind);
665
+
666
+ const localId = rtpParameters.mid || String(this._mapMidTransceiver.size);
667
+
668
+ mapLocalId.set(trackId, localId);
669
+
670
+ this._remoteSdp!.receive(
671
+ {
672
+ mid : localId,
673
+ kind,
674
+ offerRtpParameters : rtpParameters,
675
+ streamId : rtpParameters.rtcp!.cname!,
676
+ trackId
677
+ });
678
+ }
669
679
 
670
680
  const offer = { type: 'offer', sdp: this._remoteSdp!.getSdp() };
671
681
 
@@ -677,16 +687,22 @@ export class Chrome74 extends HandlerInterface
677
687
 
678
688
  let answer = await this._pc.createAnswer();
679
689
  const localSdpObject = sdpTransform.parse(answer.sdp);
680
- const answerMediaObject = localSdpObject.media
681
- .find((m: any) => String(m.mid) === localId);
682
690
 
683
- // May need to modify codec parameters in the answer based on codec
684
- // parameters in the offer.
685
- sdpCommonUtils.applyCodecParameters(
686
- {
687
- offerRtpParameters : rtpParameters,
688
- answerMediaObject
689
- });
691
+ for (const options of optionsList)
692
+ {
693
+ const { trackId, rtpParameters } = options;
694
+ const localId = mapLocalId.get(trackId);
695
+ const answerMediaObject = localSdpObject.media
696
+ .find((m: any) => String(m.mid) === localId);
697
+
698
+ // May need to modify codec parameters in the answer based on codec
699
+ // parameters in the offer.
700
+ sdpCommonUtils.applyCodecParameters(
701
+ {
702
+ offerRtpParameters : rtpParameters,
703
+ answerMediaObject
704
+ });
705
+ }
690
706
 
691
707
  answer = { type: 'answer', sdp: sdpTransform.write(localSdpObject) };
692
708
 
@@ -705,20 +721,31 @@ export class Chrome74 extends HandlerInterface
705
721
 
706
722
  await this._pc.setLocalDescription(answer);
707
723
 
708
- const transceiver = this._pc.getTransceivers()
709
- .find((t: RTCRtpTransceiver) => t.mid === localId);
724
+ for (const options of optionsList)
725
+ {
726
+ const { trackId } = options;
727
+ const localId = mapLocalId.get(trackId)!;
728
+ const transceiver = this._pc.getTransceivers()
729
+ .find((t: RTCRtpTransceiver) => t.mid === localId);
710
730
 
711
- if (!transceiver)
712
- throw new Error('new RTCRtpTransceiver not found');
731
+ if (!transceiver)
732
+ {
733
+ throw new Error('new RTCRtpTransceiver not found');
734
+ }
735
+ else
736
+ {
737
+ // Store in the map.
738
+ this._mapMidTransceiver.set(localId, transceiver);
713
739
 
714
- // Store in the map.
715
- this._mapMidTransceiver.set(localId, transceiver);
740
+ results.push({
741
+ localId,
742
+ track : transceiver.receiver.track,
743
+ rtpReceiver : transceiver.receiver
744
+ });
745
+ }
746
+ }
716
747
 
717
- return {
718
- localId,
719
- track : transceiver.receiver.track,
720
- rtpReceiver : transceiver.receiver
721
- };
748
+ return results;
722
749
  }
723
750
 
724
751
  async stopReceiving(localId: string): Promise<void>
@@ -361,44 +361,58 @@ export class Edge11 extends HandlerInterface
361
361
  }
362
362
 
363
363
  async receive(
364
- { trackId, kind, rtpParameters }: HandlerReceiveOptions
365
- ): Promise<HandlerReceiveResult>
364
+ optionsList: HandlerReceiveOptions[]
365
+ ) : Promise<HandlerReceiveResult[]>
366
366
  {
367
- logger.debug('receive() [trackId:%s, kind:%s]', trackId, kind);
367
+ const results: HandlerReceiveResult[] = [];
368
+
369
+ for (const options of optionsList)
370
+ {
371
+ const { trackId, kind } = options;
372
+
373
+ logger.debug('receive() [trackId:%s, kind:%s]', trackId, kind);
374
+ }
368
375
 
369
376
  if (!this._transportReady)
370
377
  await this._setupTransport({ localDtlsRole: 'server' });
371
378
 
372
- logger.debug('receive() | calling new RTCRtpReceiver()');
379
+ for (const options of optionsList)
380
+ {
381
+ const { trackId, kind, rtpParameters } = options;
373
382
 
374
- const rtpReceiver = new (RTCRtpReceiver as any)(this._dtlsTransport, kind);
383
+ logger.debug('receive() | calling new RTCRtpReceiver()');
375
384
 
376
- rtpReceiver.addEventListener('error', (event: any) =>
377
- {
378
- logger.error('rtpReceiver "error" event [event:%o]', event);
379
- });
385
+ const rtpReceiver = new (RTCRtpReceiver as any)(this._dtlsTransport, kind);
380
386
 
381
- // NOTE: Convert our standard RTCRtpParameters into those that Edge
382
- // expects.
383
- const edgeRtpParameters =
384
- edgeUtils.mangleRtpParameters(rtpParameters);
387
+ rtpReceiver.addEventListener('error', (event: any) =>
388
+ {
389
+ logger.error('rtpReceiver "error" event [event:%o]', event);
390
+ });
385
391
 
386
- logger.debug(
387
- 'receive() | calling rtpReceiver.receive() [params:%o]',
388
- edgeRtpParameters);
392
+ // NOTE: Convert our standard RTCRtpParameters into those that Edge
393
+ // expects.
394
+ const edgeRtpParameters =
395
+ edgeUtils.mangleRtpParameters(rtpParameters);
389
396
 
390
- await rtpReceiver.receive(edgeRtpParameters);
397
+ logger.debug(
398
+ 'receive() | calling rtpReceiver.receive() [params:%o]',
399
+ edgeRtpParameters);
391
400
 
392
- const localId = trackId;
401
+ await rtpReceiver.receive(edgeRtpParameters);
393
402
 
394
- // Store it.
395
- this._rtpReceivers.set(localId, rtpReceiver);
403
+ const localId = trackId;
396
404
 
397
- return {
398
- localId,
399
- track : rtpReceiver.track,
400
- rtpReceiver
401
- };
405
+ // Store it.
406
+ this._rtpReceivers.set(localId, rtpReceiver);
407
+
408
+ results.push({
409
+ localId,
410
+ track : rtpReceiver.track,
411
+ rtpReceiver
412
+ });
413
+ }
414
+
415
+ return results;
402
416
  }
403
417
 
404
418
  async stopReceiving(localId: string): Promise<void>
@@ -324,21 +324,29 @@ export class FakeHandler extends HandlerInterface
324
324
  }
325
325
 
326
326
  async receive(
327
- // eslint-disable-next-line @typescript-eslint/no-unused-vars
328
- { trackId, kind, rtpParameters }: HandlerReceiveOptions
329
- ): Promise<HandlerReceiveResult>
327
+ optionsList: HandlerReceiveOptions[]
328
+ ) : Promise<HandlerReceiveResult[]>
330
329
  {
331
- if (!this._transportReady)
332
- await this._setupTransport({ localDtlsRole: 'client' });
330
+ const results: HandlerReceiveResult[] = [];
333
331
 
334
- logger.debug('receive() [trackId:%s, kind:%s]', trackId, kind);
332
+ for (const options of optionsList)
333
+ {
334
+ const { trackId, kind } = options;
335
335
 
336
- const localId = this._nextLocalId++;
337
- const track = new FakeMediaStreamTrack({ kind });
336
+ if (!this._transportReady)
337
+ await this._setupTransport({ localDtlsRole: 'client' });
338
338
 
339
- this._tracks.set(localId, track);
339
+ logger.debug('receive() [trackId:%s, kind:%s]', trackId, kind);
340
+
341
+ const localId = this._nextLocalId++;
342
+ const track = new FakeMediaStreamTrack({ kind });
343
+
344
+ this._tracks.set(localId, track);
345
+
346
+ results.push({ localId: String(localId), track });
347
+ }
340
348
 
341
- return { localId: String(localId), track };
349
+ return results;
342
350
  }
343
351
 
344
352
  async stopReceiving(localId: string): Promise<void>