Du kan inte välja fler än 25 ämnen Ämnen måste starta med en bokstav eller siffra, kan innehålla bindestreck ('-') och vara max 35 tecken långa.

LocalSdpMunger.spec.js 7.9KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218
  1. import * as transform from 'sdp-transform';
  2. import { MockPeerConnection } from '../RTC/MockClasses';
  3. import FeatureFlags from '../flags/FeatureFlags';
  4. import LocalSdpMunger from './LocalSdpMunger';
  5. import { default as SampleSdpStrings } from './SampleSdpStrings.js';
  6. /**
  7. * Returns the associated ssrc lines for a given media type.
  8. *
  9. * @param {RTCSessionDescription} desc
  10. * @param {string} mediaType
  11. * @returns
  12. */
  13. function getSsrcLines(desc, mediaType) {
  14. const mline = desc.media.find(m => m.type === mediaType);
  15. return mline.ssrcs ?? [];
  16. }
  17. describe('TransformSdpsForUnifiedPlan', () => {
  18. let localSdpMunger;
  19. const tpc = new MockPeerConnection('1', true);
  20. const localEndpointId = 'sRdpsdg';
  21. beforeEach(() => {
  22. FeatureFlags.init({ });
  23. localSdpMunger = new LocalSdpMunger(tpc, localEndpointId);
  24. });
  25. describe('dontStripSsrcs', () => {
  26. it('shouldn\'t strip ssrcs from an sdp with no msid', () => {
  27. localSdpMunger.tpc.isP2P = false;
  28. const sdpStr = transform.write(SampleSdpStrings.recvOnlySdp);
  29. const desc = new RTCSessionDescription({
  30. type: 'offer',
  31. sdp: sdpStr
  32. });
  33. const transformedDesc = localSdpMunger.transformStreamIdentifiers(desc);
  34. const newSdp = transform.parse(transformedDesc.sdp);
  35. const audioSsrcs = getSsrcLines(newSdp, 'audio');
  36. const videoSsrcs = getSsrcLines(newSdp, 'video');
  37. expect(audioSsrcs.length).toEqual(2);
  38. expect(videoSsrcs.length).toEqual(2);
  39. });
  40. describe('should do nothing to an sdp with msid', () => {
  41. let audioSsrcs, videoSsrcs;
  42. const transformStreamIdentifiers = () => {
  43. const sdpStr = transform.write(SampleSdpStrings.simulcastSdp);
  44. const desc = new RTCSessionDescription({
  45. type: 'offer',
  46. sdp: sdpStr
  47. });
  48. const transformedDesc = localSdpMunger.transformStreamIdentifiers(desc);
  49. const newSdp = transform.parse(transformedDesc.sdp);
  50. audioSsrcs = getSsrcLines(newSdp, 'audio');
  51. videoSsrcs = getSsrcLines(newSdp, 'video');
  52. };
  53. it('with source name signaling enabled (injected source name)', () => {
  54. transformStreamIdentifiers();
  55. expect(audioSsrcs.length).toEqual(4 + 1 /* injected source name */);
  56. expect(videoSsrcs.length).toEqual(6 + 3 /* injected source name into each ssrc */);
  57. });
  58. });
  59. });
  60. describe('addMsids', () => {
  61. it('should add endpointId to msid', () => {
  62. const sdpStr = transform.write(SampleSdpStrings.firefoxSdp);
  63. const desc = new RTCSessionDescription({
  64. type: 'offer',
  65. sdp: sdpStr
  66. });
  67. const transformedDesc = localSdpMunger.transformStreamIdentifiers(desc);
  68. const newSdp = transform.parse(transformedDesc.sdp);
  69. const videoSsrcs = getSsrcLines(newSdp, 'video');
  70. for (const ssrcLine of videoSsrcs) {
  71. if (ssrcLine.attribute === 'msid') {
  72. const msid = ssrcLine.value.split(' ')[0];
  73. expect(msid).toBe(`${localEndpointId}-video-0-${tpc.id}`);
  74. }
  75. }
  76. });
  77. it('should add missing msid', () => {
  78. // P2P case only.
  79. localSdpMunger.tpc.isP2P = true;
  80. const sdpStr = transform.write(SampleSdpStrings.firefoxP2pSdp);
  81. const desc = new RTCSessionDescription({
  82. type: 'offer',
  83. sdp: sdpStr
  84. });
  85. const transformedDesc = localSdpMunger.transformStreamIdentifiers(desc);
  86. const newSdp = transform.parse(transformedDesc.sdp);
  87. const videoSsrcs = getSsrcLines(newSdp, 'video');
  88. const msidExists = videoSsrcs.find(s => s.attribute === 'msid');
  89. expect(msidExists).toBeDefined();
  90. });
  91. });
  92. });
  93. describe('DoNotTransformSdpForPlanB', () => {
  94. let localSdpMunger;
  95. const tpc = new MockPeerConnection('1', false);
  96. const localEndpointId = 'sRdpsdg';
  97. beforeEach(() => {
  98. localSdpMunger = new LocalSdpMunger(tpc, localEndpointId);
  99. });
  100. describe('stripSsrcs', () => {
  101. describe('should not strip ssrcs from an sdp with no msid', () => {
  102. let audioSsrcs, videoSsrcs;
  103. const transformStreamIdentifiers = () => {
  104. localSdpMunger.tpc.isP2P = false;
  105. const sdpStr = transform.write(SampleSdpStrings.recvOnlySdp);
  106. const desc = new RTCSessionDescription({
  107. type: 'offer',
  108. sdp: sdpStr
  109. });
  110. const transformedDesc = localSdpMunger.transformStreamIdentifiers(desc);
  111. const newSdp = transform.parse(transformedDesc.sdp);
  112. audioSsrcs = getSsrcLines(newSdp, 'audio');
  113. videoSsrcs = getSsrcLines(newSdp, 'video');
  114. };
  115. it('with source name signaling', () => {
  116. FeatureFlags.init({ });
  117. transformStreamIdentifiers();
  118. expect(audioSsrcs.length).toEqual(1 + 1 /* injected source name */);
  119. expect(videoSsrcs.length).toEqual(1 + 1 /* injected source name */);
  120. });
  121. });
  122. });
  123. });
  124. describe('Transform msids for source-name signaling', () => {
  125. const tpc = new MockPeerConnection('1', false);
  126. const localEndpointId = 'sRdpsdg';
  127. const localSdpMunger = new LocalSdpMunger(tpc, localEndpointId);
  128. let audioMsid, audioMsidLine, videoMsid, videoMsidLine;
  129. const transformStreamIdentifiers = () => {
  130. const sdpStr = transform.write(SampleSdpStrings.simulcastRtxSdp);
  131. const desc = new RTCSessionDescription({
  132. type: 'offer',
  133. sdp: sdpStr
  134. });
  135. const transformedDesc = localSdpMunger.transformStreamIdentifiers(desc);
  136. const newSdp = transform.parse(transformedDesc.sdp);
  137. audioMsidLine = getSsrcLines(newSdp, 'audio').find(ssrc => ssrc.attribute === 'msid')?.value;
  138. audioMsid = audioMsidLine.split(' ')[0];
  139. videoMsidLine = getSsrcLines(newSdp, 'video').find(ssrc => ssrc.attribute === 'msid')?.value;
  140. videoMsid = videoMsidLine.split(' ')[0];
  141. };
  142. it('should transform', () => {
  143. FeatureFlags.init({ });
  144. transformStreamIdentifiers();
  145. expect(audioMsid).toBe('sRdpsdg-audio-0-1');
  146. expect(videoMsid).toBe('sRdpsdg-video-0-1');
  147. });
  148. });
  149. describe('Track replace operations in plan-b', () => {
  150. const tpc = new MockPeerConnection('1', false);
  151. const localEndpointId = 'sRdpsdg';
  152. let desc, newSdp, sdpStr, transformedDesc, videoMsid, videoMsidLine;
  153. const localSdpMunger = new LocalSdpMunger(tpc, localEndpointId);
  154. it('should not increment track index for new tracks', () => {
  155. FeatureFlags.init({ });
  156. sdpStr = transform.write(SampleSdpStrings.simulcastRtxSdp);
  157. desc = new RTCSessionDescription({
  158. type: 'offer',
  159. sdp: sdpStr
  160. });
  161. transformedDesc = localSdpMunger.transformStreamIdentifiers(desc);
  162. newSdp = transform.parse(transformedDesc.sdp);
  163. videoMsidLine = getSsrcLines(newSdp, 'video').find(ssrc => ssrc.attribute === 'msid')?.value;
  164. videoMsid = videoMsidLine.split(' ')[0];
  165. expect(videoMsid).toBe('sRdpsdg-video-0-1');
  166. sdpStr = transform.write(SampleSdpStrings.simulcastRtxSdpReplacedTrack);
  167. desc = new RTCSessionDescription({
  168. type: 'offer',
  169. sdp: sdpStr
  170. });
  171. transformedDesc = localSdpMunger.transformStreamIdentifiers(desc);
  172. newSdp = transform.parse(transformedDesc.sdp);
  173. videoMsidLine = getSsrcLines(newSdp, 'video').find(ssrc => ssrc.attribute === 'msid')?.value;
  174. videoMsid = videoMsidLine.split(' ')[0];
  175. expect(videoMsid).toBe('sRdpsdg-video-0-1');
  176. });
  177. });