You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

SDP.spec.js 24KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443
  1. import $ from 'jquery';
  2. import { $iq } from 'strophe.js';
  3. import FeatureFlags from '../flags/FeatureFlags';
  4. import { expandSourcesFromJson } from '../xmpp/JingleHelperFunctions';
  5. import SDP from './SDP';
  6. /**
  7. * @param {string} xml - raw xml of the stanza
  8. */
  9. function createStanzaElement(xml) {
  10. return new DOMParser().parseFromString(xml, 'text/xml').documentElement;
  11. }
  12. describe('SDP', () => {
  13. afterEach(() => {
  14. FeatureFlags.init({ });
  15. });
  16. describe('toJingle', () => {
  17. /* eslint-disable max-len*/
  18. const testSdp = [
  19. 'v=0\r\n',
  20. 'o=thisisadapterortc 2719486166053431 0 IN IP4 127.0.0.1\r\n',
  21. 's=-\r\n',
  22. 't=0 0\r\n',
  23. 'a=group:BUNDLE audio video\r\n',
  24. 'm=audio 9 UDP/TLS/RTP/SAVPF 111 126\r\n',
  25. 'c=IN IP4 0.0.0.0\r\n',
  26. 'a=rtpmap:111 opus/48000/2\r\n',
  27. 'a=rtpmap:126 telephone-event/8000\r\n',
  28. 'a=fmtp:126 0-15\r\n',
  29. 'a=fmtp:111 minptime=10;useinbandfec=1\r\n',
  30. 'a=rtcp:9 IN IP4 0.0.0.0\r\n',
  31. 'a=setup:active\r\n',
  32. 'a=mid:audio\r\n',
  33. 'a=msid:26D16D51-503A-420B-8274-3DD1174E498F 8205D1FC-50B4-407C-87D5-9C45F1B779F0\r\n',
  34. 'a=sendrecv\r\n',
  35. 'a=ice-ufrag:tOQd\r\n',
  36. 'a=ice-pwd:3sAozs7hw6+2O6DBp2pt9fvY\r\n',
  37. 'a=fingerprint:sha-256 A9:00:CC:F9:81:33:EA:E9:E3:B4:01:E9:9E:18:B3:9B:F8:49:25:A0:5D:12:20:70:D5:6F:34:5A:2A:39:19:0A\r\n',
  38. 'a=ssrc:2002 msid:26D16D51-503A-420B-8274-3DD1174E498F 8205D1FC-50B4-407C-87D5-9C45F1B779F0\r\n',
  39. 'a=ssrc:2002 cname:juejgy8a01\r\n',
  40. 'a=ssrc:2002 name:a8f7g30-a0\r\n',
  41. 'a=rtcp-mux\r\n',
  42. 'a=extmap-allow-mixed\r\n',
  43. 'm=video 9 UDP/TLS/RTP/SAVPF 107 100 99 96\r\n',
  44. 'c=IN IP4 0.0.0.0\r\n',
  45. 'a=rtpmap:107 h264/90000\r\n',
  46. 'a=rtpmap:100 VP8/90000\r\n',
  47. 'a=rtpmap:99 rtx/90000\r\n',
  48. 'a=rtpmap:96 rtx/90000\r\n',
  49. 'a=fmtp:107 x-google-start-bitrate=800\r\n',
  50. 'a=fmtp:100 x-google-start-bitrate=800\r\n',
  51. 'a=fmtp:99 apt=107\r\n',
  52. 'a=fmtp:96 apt=100\r\n',
  53. 'a=rtcp:9 IN IP4 0.0.0.0\r\n',
  54. 'a=rtcp-fb:107 nack\r\n',
  55. 'a=rtcp-fb:107 nack pli\r\n',
  56. 'a=rtcp-fb:107 goog-remb\r\n',
  57. 'a=rtcp-fb:100 nack\r\n',
  58. 'a=rtcp-fb:100 nack pli\r\n',
  59. 'a=rtcp-fb:100 goog-remb\r\n',
  60. 'a=extmap:3 http://www.webrtc.org/experiments/rtp-hdrext/abs-send-time\r\n',
  61. 'a=extmap-allow-mixed\r\n',
  62. 'a=setup:active\r\n',
  63. 'a=mid:video\r\n',
  64. 'a=msid:7C0035E5-2DA1-4AEA-804A-9E75BF9B3768 225E9CDA-0384-4C92-92DD-E74C1153EC68\r\n',
  65. 'a=sendrecv\r\n',
  66. 'a=ice-ufrag:tOQd\r\n',
  67. 'a=ice-pwd:3sAozs7hw6+2O6DBp2pt9fvY\r\n',
  68. 'a=fingerprint:sha-256 A9:00:CC:F9:81:33:EA:E9:E3:B4:01:E9:9E:18:B3:9B:F8:49:25:A0:5D:12:20:70:D5:6F:34:5A:2A:39:19:0A\r\n',
  69. 'a=ssrc:4004 msid:7C0035E5-2DA1-4AEA-804A-9E75BF9B3768 225E9CDA-0384-4C92-92DD-E74C1153EC68\r\n',
  70. 'a=ssrc:4005 msid:7C0035E5-2DA1-4AEA-804A-9E75BF9B3768 225E9CDA-0384-4C92-92DD-E74C1153EC68\r\n',
  71. 'a=ssrc:4004 cname:juejgy8a01\r\n',
  72. 'a=ssrc:4005 cname:juejgy8a01\r\n',
  73. 'a=ssrc:4004 name:a8f7g30-v0\r\n',
  74. 'a=ssrc:4005 name:a8f7g30-v0\r\n',
  75. 'a=ssrc-group:FID 4004 4005\r\n',
  76. 'a=rtcp-mux\r\n'
  77. ].join('');
  78. /* eslint-enable max-len*/
  79. it('correctly groups ssrcs lines that are not in order', () => {
  80. const sdp = new SDP(testSdp);
  81. const accept = $iq({
  82. to: 'peerjid',
  83. type: 'set'
  84. })
  85. .c('jingle', {
  86. xmlns: 'urn:xmpp:jingle:1',
  87. action: 'session-accept',
  88. initiator: false,
  89. responder: true,
  90. sid: 'temp-sid'
  91. });
  92. sdp.toJingle(accept, false);
  93. const { nodeTree } = accept;
  94. const videoSources = nodeTree.querySelectorAll('description[media=\'video\']>source');
  95. expect(videoSources.length).toBe(2);
  96. });
  97. it('put source names as source element attributes', () => {
  98. FeatureFlags.init({ });
  99. const sdp = new SDP(testSdp);
  100. const accept = $iq({
  101. to: 'peerjid',
  102. type: 'set'
  103. })
  104. .c('jingle', {
  105. xmlns: 'urn:xmpp:jingle:1',
  106. action: 'session-accept',
  107. initiator: false,
  108. responder: true,
  109. sid: 'temp-sid'
  110. });
  111. sdp.toJingle(accept, false);
  112. const { nodeTree } = accept;
  113. const audioSources = nodeTree.querySelectorAll('description[media=\'audio\']>source');
  114. const videoSources = nodeTree.querySelectorAll('description[media=\'video\']>source');
  115. for (const source of audioSources) {
  116. expect(source.getAttribute('name')).toBe('a8f7g30-a0');
  117. }
  118. for (const source of videoSources) {
  119. expect(source.getAttribute('name')).toBe('a8f7g30-v0');
  120. }
  121. });
  122. });
  123. describe('fromJingle', () => {
  124. /* eslint-disable max-len*/
  125. const stanza = `<iq>
  126. <jingle action='session-initiate' initiator='focus' sid='123' xmlns='urn:xmpp:jingle:1'>
  127. <content creator='initiator' name='audio' senders='both'>
  128. <description media='audio' maxptime='60' xmlns='urn:xmpp:jingle:apps:rtp:1'>
  129. <payload-type channels='2' clockrate='48000' name='opus' id='111'>
  130. <parameter name='minptime' value='10'/>
  131. <parameter name='useinbandfec' value='1'/>
  132. <rtcp-fb type='transport-cc' xmlns='urn:xmpp:jingle:apps:rtp:rtcp-fb:0'/>
  133. </payload-type>
  134. <payload-type clockrate='16000' name='ISAC' id='103'/>
  135. <payload-type clockrate='32000' name='ISAC' id='104'/>
  136. <payload-type clockrate='8000' name='telephone-event' id='126'>
  137. <parameter name="" value="0-15"/>
  138. </payload-type>
  139. <rtp-hdrext uri='urn:ietf:params:rtp-hdrext:ssrc-audio-level' id='1' xmlns='urn:xmpp:jingle:apps:rtp:rtp-hdrext:0'/>
  140. <rtp-hdrext uri='http://www.ietf.org/id/draft-holmer-rmcat-transport-wide-cc-extensions-01' id='5' xmlns='urn:xmpp:jingle:apps:rtp:rtp-hdrext:0'/>
  141. <extmap-allow-mixed xmlns='urn:xmpp:jingle:apps:rtp:rtp-hdrext:0'/>
  142. <rtcp-mux/>
  143. <source ssrc='4039389863' xmlns='urn:xmpp:jingle:apps:rtp:ssma:0'>
  144. <parameter name='cname' value='mixed'/>
  145. <parameter name='label' value='mixedlabelaudio0'/>
  146. <parameter name='msid' value='mixedmslabel mixedlabelaudio0'/>
  147. <parameter name='mslabel' value='mixedmslabel'/>
  148. </source>
  149. </description>
  150. <transport ufrag='someufrag' pwd='somepwd' xmlns='urn:xmpp:jingle:transports:ice-udp:1'>
  151. <fingerprint hash='sha-256' required='false' setup='actpass' xmlns='urn:xmpp:jingle:apps:dtls:0'>09:B1:51:0F:85:4C:80:19:A1:AF:81:73:47:EE:ED:3D:00:3A:84:C7:76:C1:4E:34:BE:56:F6:42:AD:15:D5:D7</fingerprint>
  152. <candidate foundation='1' id='3cbe5aea5bde0c1401a60bbc2' network='0' protocol='udp' generation='0' port='10000' priority='2130706431' type='host' ip='10.0.0.1' component='1'/>
  153. <candidate rel-addr='10.0.0.1' network='0' foundation='2' id='dfcfd075bde0c140ffffffff927646ba' port='10000' protocol='udp' generation='0' rel-port='10000' priority='1694498815' type='srflx' ip='10.0.0.2' component='1'/>
  154. </transport>
  155. </content>
  156. <content creator='initiator' name='video' senders='both'>
  157. <description media='video' xmlns='urn:xmpp:jingle:apps:rtp:1'>
  158. <payload-type clockrate='90000' name='VP8' id='100'>
  159. <rtcp-fb subtype='fir' type='ccm' xmlns='urn:xmpp:jingle:apps:rtp:rtcp-fb:0'/>
  160. <rtcp-fb type='nack' xmlns='urn:xmpp:jingle:apps:rtp:rtcp-fb:0'/>
  161. <rtcp-fb subtype='pli' type='nack' xmlns='urn:xmpp:jingle:apps:rtp:rtcp-fb:0'/>
  162. <rtcp-fb type='goog-remb' xmlns='urn:xmpp:jingle:apps:rtp:rtcp-fb:0'/>
  163. <rtcp-fb type='transport-cc' xmlns='urn:xmpp:jingle:apps:rtp:rtcp-fb:0'/>
  164. <parameter name='x-google-start-bitrate' value='800'/>
  165. </payload-type>
  166. <payload-type clockrate='90000' name='rtx' id='96'>
  167. <rtcp-fb subtype='fir' type='ccm' xmlns='urn:xmpp:jingle:apps:rtp:rtcp-fb:0'/>
  168. <rtcp-fb type='nack' xmlns='urn:xmpp:jingle:apps:rtp:rtcp-fb:0'/>
  169. <rtcp-fb subtype='pli' type='nack' xmlns='urn:xmpp:jingle:apps:rtp:rtcp-fb:0'/>
  170. <parameter name='apt' value='100'/>
  171. </payload-type>
  172. <rtp-hdrext uri='http://www.webrtc.org/experiments/rtp-hdrext/abs-send-time' id='3' xmlns='urn:xmpp:jingle:apps:rtp:rtp-hdrext:0'/>
  173. <rtp-hdrext uri='http://www.ietf.org/id/draft-holmer-rmcat-transport-wide-cc-extensions-01' id='5' xmlns='urn:xmpp:jingle:apps:rtp:rtp-hdrext:0'/>
  174. <extmap-allow-mixed xmlns='urn:xmpp:jingle:apps:rtp:rtp-hdrext:0'/>
  175. <rtcp-mux/>
  176. <source ssrc='3758540092' xmlns='urn:xmpp:jingle:apps:rtp:ssma:0'>
  177. <parameter name='cname' value='mixed'/>
  178. <parameter name='label' value='mixedlabelvideo0'/>
  179. <parameter name='msid' value='mixedmslabel mixedlabelvideo0'/>
  180. <parameter name='mslabel' value='mixedmslabel'/>
  181. </source>
  182. </description>
  183. <transport ufrag='someufrag' pwd='somepwd' xmlns='urn:xmpp:jingle:transports:ice-udp:1'>
  184. <fingerprint hash='sha-256' required='false' setup='actpass' xmlns='urn:xmpp:jingle:apps:dtls:0'>09:B1:51:0F:85:4C:80:19:A1:AF:81:73:47:EE:ED:3D:00:3A:84:C7:76:C1:4E:34:BE:56:F6:42:AD:15:D5:D7</fingerprint>
  185. <candidate foundation='1' id='3cbe5aea5bde0c1401a60bbc2' network='0' protocol='udp' generation='0' port='10000' priority='2130706431' type='host' ip='10.0.0.1' component='1'/>
  186. <candidate rel-addr='10.0.0.1' network='0' foundation='2' id='dfcfd075bde0c140ffffffff927646ba' port='10000' protocol='udp' generation='0' rel-port='10000' priority='1694498815' type='srflx' ip='10.0.0.2' component='1'/>
  187. </transport>
  188. </content>
  189. <group semantics='BUNDLE' xmlns='urn:xmpp:jingle:apps:grouping:0'>
  190. <content name='audio'/>
  191. <content name='video'/>
  192. </group>
  193. </jingle></iq>`;
  194. const expectedSDP = `v=0
  195. o=- 123 2 IN IP4 0.0.0.0
  196. s=-
  197. t=0 0
  198. a=group:BUNDLE audio video
  199. m=audio 9 UDP/TLS/RTP/SAVPF 111 103 104 126
  200. c=IN IP4 0.0.0.0
  201. a=rtcp:1 IN IP4 0.0.0.0
  202. a=ice-ufrag:someufrag
  203. a=ice-pwd:somepwd
  204. a=fingerprint:sha-256 09:B1:51:0F:85:4C:80:19:A1:AF:81:73:47:EE:ED:3D:00:3A:84:C7:76:C1:4E:34:BE:56:F6:42:AD:15:D5:D7
  205. a=setup:actpass
  206. a=candidate:1 1 udp 2130706431 10.0.0.1 10000 typ host generation 0
  207. a=candidate:2 1 udp 1694498815 10.0.0.2 10000 typ srflx raddr 10.0.0.1 rport 10000 generation 0
  208. a=sendrecv
  209. a=mid:audio
  210. a=rtcp-mux
  211. a=rtpmap:111 opus/48000/2
  212. a=fmtp:111 minptime=10;useinbandfec=1
  213. a=rtcp-fb:111 transport-cc
  214. a=rtpmap:103 ISAC/16000
  215. a=rtpmap:104 ISAC/32000
  216. a=rtpmap:126 telephone-event/8000
  217. a=fmtp:126 0-15
  218. a=extmap:1 urn:ietf:params:rtp-hdrext:ssrc-audio-level
  219. a=extmap:5 http://www.ietf.org/id/draft-holmer-rmcat-transport-wide-cc-extensions-01
  220. a=extmap-allow-mixed
  221. a=ssrc:4039389863 cname:mixed
  222. a=ssrc:4039389863 label:mixedlabelaudio0
  223. a=ssrc:4039389863 msid:mixedmslabel mixedlabelaudio0
  224. a=ssrc:4039389863 mslabel:mixedmslabel
  225. m=video 9 UDP/TLS/RTP/SAVPF 100 96
  226. c=IN IP4 0.0.0.0
  227. a=rtcp:1 IN IP4 0.0.0.0
  228. a=ice-ufrag:someufrag
  229. a=ice-pwd:somepwd
  230. a=fingerprint:sha-256 09:B1:51:0F:85:4C:80:19:A1:AF:81:73:47:EE:ED:3D:00:3A:84:C7:76:C1:4E:34:BE:56:F6:42:AD:15:D5:D7
  231. a=setup:actpass
  232. a=candidate:1 1 udp 2130706431 10.0.0.1 10000 typ host generation 0
  233. a=candidate:2 1 udp 1694498815 10.0.0.2 10000 typ srflx raddr 10.0.0.1 rport 10000 generation 0
  234. a=sendrecv
  235. a=mid:video
  236. a=rtcp-mux
  237. a=rtpmap:100 VP8/90000
  238. a=fmtp:100 x-google-start-bitrate=800
  239. a=rtcp-fb:100 ccm fir
  240. a=rtcp-fb:100 nack
  241. a=rtcp-fb:100 nack pli
  242. a=rtcp-fb:100 goog-remb
  243. a=rtcp-fb:100 transport-cc
  244. a=rtpmap:96 rtx/90000
  245. a=fmtp:96 apt=100
  246. a=rtcp-fb:96 ccm fir
  247. a=rtcp-fb:96 nack
  248. a=rtcp-fb:96 nack pli
  249. a=extmap:3 http://www.webrtc.org/experiments/rtp-hdrext/abs-send-time
  250. a=extmap:5 http://www.ietf.org/id/draft-holmer-rmcat-transport-wide-cc-extensions-01
  251. a=extmap-allow-mixed
  252. a=ssrc:3758540092 cname:mixed
  253. a=ssrc:3758540092 label:mixedlabelvideo0
  254. a=ssrc:3758540092 msid:mixedmslabel mixedlabelvideo0
  255. a=ssrc:3758540092 mslabel:mixedmslabel
  256. `.split('\n').join('\r\n');
  257. /* eslint-enable max-len*/
  258. it('gets converted to SDP', () => {
  259. const offer = createStanzaElement(stanza);
  260. const sdp = new SDP('');
  261. sdp.fromJingle($(offer).find('>jingle'));
  262. const rawSDP = sdp.raw.replace(/o=- \d+/, 'o=- 123'); // replace generated o= timestamp.
  263. expect(rawSDP).toEqual(expectedSDP);
  264. });
  265. });
  266. describe('fromJingleWithJSONFormat', () => {
  267. /* eslint-disable max-len*/
  268. const stanza = `
  269. <iq>
  270. <jingle xmlns="urn:xmpp:jingle:1" action="session-initiate" initiator="focus" sid="123">
  271. <content name="audio" creator="initiator" senders="both">
  272. <description xmlns="urn:xmpp:jingle:apps:rtp:1" maxptime="60" media="audio">
  273. <payload-type name="opus" clockrate="48000" id="111" channels="2">
  274. <parameter value="10" name="minptime"/>
  275. <parameter value="1" name="useinbandfec"/>
  276. <rtcp-fb xmlns="urn:xmpp:jingle:apps:rtp:rtcp-fb:0" type="transport-cc"/>
  277. </payload-type>
  278. <payload-type name="ISAC" clockrate="16000" id="103"/>
  279. <payload-type name="ISAC" clockrate="32000" id="104"/>
  280. <payload-type name="telephone-event" clockrate="8000" id="126"/>
  281. <rtp-hdrext xmlns="urn:xmpp:jingle:apps:rtp:rtp-hdrext:0" id="1" uri="urn:ietf:params:rtp-hdrext:ssrc-audio-level"/>
  282. <rtp-hdrext xmlns="urn:xmpp:jingle:apps:rtp:rtp-hdrext:0" id="5" uri="http://www.ietf.org/id/draft-holmer-rmcat-transport-wide-cc-extensions-01"/>
  283. <rtcp-mux/>
  284. </description>
  285. <transport ufrag='someufrag' pwd='somepwd' xmlns='urn:xmpp:jingle:transports:ice-udp:1'>
  286. <fingerprint hash='sha-256' required='false' setup='actpass' xmlns='urn:xmpp:jingle:apps:dtls:0'>09:B1:51:0F:85:4C:80:19:A1:AF:81:73:47:EE:ED:3D:00:3A:84:C7:76:C1:4E:34:BE:56:F6:42:AD:15:D5:D7</fingerprint>
  287. <candidate foundation='1' id='3cbe5aea5bde0c1401a60bbc2' network='0' protocol='udp' generation='0' port='10000' priority='2130706431' type='host' ip='10.0.0.1' component='1'/>
  288. <candidate rel-addr='10.0.0.1' network='0' foundation='2' id='dfcfd075bde0c140ffffffff927646ba' port='10000' protocol='udp' generation='0' rel-port='10000' priority='1694498815' type='srflx' ip='10.0.0.2' component='1'/>
  289. </transport>
  290. </content>
  291. <content name="video" creator="initiator" senders="both">
  292. <description xmlns="urn:xmpp:jingle:apps:rtp:1" media="video">
  293. <payload-type name="VP8" clockrate="90000" id="100">
  294. <rtcp-fb xmlns="urn:xmpp:jingle:apps:rtp:rtcp-fb:0" subtype="fir" type="ccm"/>
  295. <rtcp-fb xmlns="urn:xmpp:jingle:apps:rtp:rtcp-fb:0" type="nack"/>
  296. <rtcp-fb xmlns="urn:xmpp:jingle:apps:rtp:rtcp-fb:0" subtype="pli" type="nack"/>
  297. <parameter value="800" name="x-google-start-bitrate"/>
  298. <rtcp-fb xmlns="urn:xmpp:jingle:apps:rtp:rtcp-fb:0" type="transport-cc"/>
  299. </payload-type>
  300. <payload-type name="rtx" clockrate="90000" id="96">
  301. <parameter value="100" name="apt"/>
  302. <rtcp-fb xmlns="urn:xmpp:jingle:apps:rtp:rtcp-fb:0" subtype="fir" type="ccm"/>
  303. <rtcp-fb xmlns="urn:xmpp:jingle:apps:rtp:rtcp-fb:0" type="nack"/>
  304. <rtcp-fb xmlns="urn:xmpp:jingle:apps:rtp:rtcp-fb:0" subtype="pli" type="nack"/>
  305. </payload-type>
  306. <rtp-hdrext xmlns="urn:xmpp:jingle:apps:rtp:rtp-hdrext:0" id="3" uri="http://www.webrtc.org/experiments/rtp-hdrext/abs-send-time"/>
  307. <rtp-hdrext xmlns="urn:xmpp:jingle:apps:rtp:rtp-hdrext:0" id="5" uri="http://www.ietf.org/id/draft-holmer-rmcat-transport-wide-cc-extensions-01"/>
  308. <rtcp-mux/>
  309. </description>
  310. <transport ufrag='someufrag' pwd='somepwd' xmlns='urn:xmpp:jingle:transports:ice-udp:1'>
  311. <fingerprint hash='sha-256' required='false' setup='actpass' xmlns='urn:xmpp:jingle:apps:dtls:0'>09:B1:51:0F:85:4C:80:19:A1:AF:81:73:47:EE:ED:3D:00:3A:84:C7:76:C1:4E:34:BE:56:F6:42:AD:15:D5:D7</fingerprint>
  312. <candidate foundation='1' id='3cbe5aea5bde0c1401a60bbc2' network='0' protocol='udp' generation='0' port='10000' priority='2130706431' type='host' ip='10.0.0.1' component='1'/>
  313. <candidate rel-addr='10.0.0.1' network='0' foundation='2' id='dfcfd075bde0c140ffffffff927646ba' port='10000' protocol='udp' generation='0' rel-port='10000' priority='1694498815' type='srflx' ip='10.0.0.2' component='1'/>
  314. </transport>
  315. </content>
  316. <group xmlns="urn:xmpp:jingle:apps:grouping:0" semantics="BUNDLE">
  317. <content name="audio"/>
  318. <content name="video"/>
  319. </group>
  320. <json-message xmlns="http://jitsi.org/jitmeet">{"sources":{"831de82b":[[{"s":257838819,"m":"831de82b-video-1 9bb949d4-5abd-4498-98e9-2be1222b8d3e-1"},{"s":865670341,"m":"831de82b-video-1 9bb949d4-5abd-4498-98e9-2be1222b8d3e-1"},{"s":3041289080,"m":"831de82b-video-1 9bb949d4-5abd-4498-98e9-2be1222b8d3e-1"},{"s":6437989,"m":"831de82b-video-1 9bb949d4-5abd-4498-98e9-2be1222b8d3e-1"},{"s":2417192010,"m":"831de82b-video-1 9bb949d4-5abd-4498-98e9-2be1222b8d3e-1"},{"s":3368859313,"m":"831de82b-video-1 9bb949d4-5abd-4498-98e9-2be1222b8d3e-1"}],[["f",257838819,865670341],["s",257838819,3041289080,6437989],["f",3041289080,2417192010],["f",6437989,3368859313]],[]],"07af8d49":[[{"s":110279275,"m":"07af8d49-video-2 f685aa25-0318-442e-bd00-cd2a911236da-2"},{"s":527738645,"m":"07af8d49-video-2 f685aa25-0318-442e-bd00-cd2a911236da-2"},{"s":1201074111,"m":"07af8d49-video-2 f685aa25-0318-442e-bd00-cd2a911236da-2"},{"s":1635907749,"m":"07af8d49-video-2 f685aa25-0318-442e-bd00-cd2a911236da-2"},{"s":3873826414,"m":"07af8d49-video-2 f685aa25-0318-442e-bd00-cd2a911236da-2"},{"s":4101906340,"m":"07af8d49-video-2 f685aa25-0318-442e-bd00-cd2a911236da-2"}],[["f",3873826414,110279275],["s",3873826414,1201074111,1635907749],["f",1201074111,4101906340],["f",1635907749,527738645]],[]],"95edea8d":[[{"s":620660772,"m":"95edea8d-video-1 0c5d94d1-1902-4fb7-bf6a-76517d065d02-1"},{"s":2212130687,"m":"95edea8d-video-1 0c5d94d1-1902-4fb7-bf6a-76517d065d02-1"},{"s":2306112481,"m":"95edea8d-video-1 0c5d94d1-1902-4fb7-bf6a-76517d065d02-1"},{"s":3334993162,"m":"95edea8d-video-1 0c5d94d1-1902-4fb7-bf6a-76517d065d02-1"},{"s":3473290740,"m":"95edea8d-video-1 0c5d94d1-1902-4fb7-bf6a-76517d065d02-1"},{"s":4085804879,"m":"95edea8d-video-1 0c5d94d1-1902-4fb7-bf6a-76517d065d02-1"}],[["f",2306112481,620660772],["s",2306112481,3334993162,4085804879],["f",3334993162,3473290740],["f",4085804879,2212130687]],[]],"jvb":[[{"s":1427774514,"m":"mixedmslabel mixedlabelvideo0","c":"mixed"}],[],[{"s":3659539811,"m":"mixedmslabel mixedlabelaudio0","c":"mixed"}]]}}</json-message>
  321. </jingle>
  322. </iq>`;
  323. const expectedSDP = `v=0
  324. o=- 123 2 IN IP4 0.0.0.0
  325. s=-
  326. t=0 0
  327. a=group:BUNDLE audio video
  328. m=audio 9 UDP/TLS/RTP/SAVPF 111 103 104 126
  329. c=IN IP4 0.0.0.0
  330. a=rtcp:1 IN IP4 0.0.0.0
  331. a=ice-ufrag:someufrag
  332. a=ice-pwd:somepwd
  333. a=fingerprint:sha-256 09:B1:51:0F:85:4C:80:19:A1:AF:81:73:47:EE:ED:3D:00:3A:84:C7:76:C1:4E:34:BE:56:F6:42:AD:15:D5:D7
  334. a=setup:actpass
  335. a=candidate:1 1 udp 2130706431 10.0.0.1 10000 typ host generation 0
  336. a=candidate:2 1 udp 1694498815 10.0.0.2 10000 typ srflx raddr 10.0.0.1 rport 10000 generation 0
  337. a=sendrecv
  338. a=mid:audio
  339. a=rtcp-mux
  340. a=rtpmap:111 opus/48000/2
  341. a=fmtp:111 minptime=10;useinbandfec=1
  342. a=rtcp-fb:111 transport-cc
  343. a=rtpmap:103 ISAC/16000
  344. a=rtpmap:104 ISAC/32000
  345. a=rtpmap:126 telephone-event/8000
  346. a=extmap:1 urn:ietf:params:rtp-hdrext:ssrc-audio-level
  347. a=extmap:5 http://www.ietf.org/id/draft-holmer-rmcat-transport-wide-cc-extensions-01
  348. a=ssrc:3659539811 msid:mixedmslabel mixedlabelaudio0
  349. m=video 9 UDP/TLS/RTP/SAVPF 100 96
  350. c=IN IP4 0.0.0.0
  351. a=rtcp:1 IN IP4 0.0.0.0
  352. a=ice-ufrag:someufrag
  353. a=ice-pwd:somepwd
  354. a=fingerprint:sha-256 09:B1:51:0F:85:4C:80:19:A1:AF:81:73:47:EE:ED:3D:00:3A:84:C7:76:C1:4E:34:BE:56:F6:42:AD:15:D5:D7
  355. a=setup:actpass
  356. a=candidate:1 1 udp 2130706431 10.0.0.1 10000 typ host generation 0
  357. a=candidate:2 1 udp 1694498815 10.0.0.2 10000 typ srflx raddr 10.0.0.1 rport 10000 generation 0
  358. a=sendrecv
  359. a=mid:video
  360. a=rtcp-mux
  361. a=rtpmap:100 VP8/90000
  362. a=fmtp:100 x-google-start-bitrate=800
  363. a=rtcp-fb:100 ccm fir
  364. a=rtcp-fb:100 nack
  365. a=rtcp-fb:100 nack pli
  366. a=rtcp-fb:100 transport-cc
  367. a=rtpmap:96 rtx/90000
  368. a=fmtp:96 apt=100
  369. a=rtcp-fb:96 ccm fir
  370. a=rtcp-fb:96 nack
  371. a=rtcp-fb:96 nack pli
  372. a=extmap:3 http://www.webrtc.org/experiments/rtp-hdrext/abs-send-time
  373. a=extmap:5 http://www.ietf.org/id/draft-holmer-rmcat-transport-wide-cc-extensions-01
  374. a=ssrc-group:FID 257838819 865670341
  375. a=ssrc-group:SIM 257838819 3041289080 6437989
  376. a=ssrc-group:FID 3041289080 2417192010
  377. a=ssrc-group:FID 6437989 3368859313
  378. a=ssrc-group:FID 3873826414 110279275
  379. a=ssrc-group:SIM 3873826414 1201074111 1635907749
  380. a=ssrc-group:FID 1201074111 4101906340
  381. a=ssrc-group:FID 1635907749 527738645
  382. a=ssrc-group:FID 2306112481 620660772
  383. a=ssrc-group:SIM 2306112481 3334993162 4085804879
  384. a=ssrc-group:FID 3334993162 3473290740
  385. a=ssrc-group:FID 4085804879 2212130687
  386. a=ssrc:1427774514 msid:mixedmslabel mixedlabelvideo0
  387. a=ssrc:257838819 msid:831de82b-video-1 9bb949d4-5abd-4498-98e9-2be1222b8d3e-1
  388. a=ssrc:865670341 msid:831de82b-video-1 9bb949d4-5abd-4498-98e9-2be1222b8d3e-1
  389. a=ssrc:3041289080 msid:831de82b-video-1 9bb949d4-5abd-4498-98e9-2be1222b8d3e-1
  390. a=ssrc:6437989 msid:831de82b-video-1 9bb949d4-5abd-4498-98e9-2be1222b8d3e-1
  391. a=ssrc:2417192010 msid:831de82b-video-1 9bb949d4-5abd-4498-98e9-2be1222b8d3e-1
  392. a=ssrc:3368859313 msid:831de82b-video-1 9bb949d4-5abd-4498-98e9-2be1222b8d3e-1
  393. a=ssrc:110279275 msid:07af8d49-video-2 f685aa25-0318-442e-bd00-cd2a911236da-2
  394. a=ssrc:527738645 msid:07af8d49-video-2 f685aa25-0318-442e-bd00-cd2a911236da-2
  395. a=ssrc:1201074111 msid:07af8d49-video-2 f685aa25-0318-442e-bd00-cd2a911236da-2
  396. a=ssrc:1635907749 msid:07af8d49-video-2 f685aa25-0318-442e-bd00-cd2a911236da-2
  397. a=ssrc:3873826414 msid:07af8d49-video-2 f685aa25-0318-442e-bd00-cd2a911236da-2
  398. a=ssrc:4101906340 msid:07af8d49-video-2 f685aa25-0318-442e-bd00-cd2a911236da-2
  399. a=ssrc:620660772 msid:95edea8d-video-1 0c5d94d1-1902-4fb7-bf6a-76517d065d02-1
  400. a=ssrc:2212130687 msid:95edea8d-video-1 0c5d94d1-1902-4fb7-bf6a-76517d065d02-1
  401. a=ssrc:2306112481 msid:95edea8d-video-1 0c5d94d1-1902-4fb7-bf6a-76517d065d02-1
  402. a=ssrc:3334993162 msid:95edea8d-video-1 0c5d94d1-1902-4fb7-bf6a-76517d065d02-1
  403. a=ssrc:3473290740 msid:95edea8d-video-1 0c5d94d1-1902-4fb7-bf6a-76517d065d02-1
  404. a=ssrc:4085804879 msid:95edea8d-video-1 0c5d94d1-1902-4fb7-bf6a-76517d065d02-1
  405. `.split('\n').join('\r\n');
  406. /* eslint-enable max-len*/
  407. it('gets converted to SDP', () => {
  408. const offer = createStanzaElement(stanza);
  409. const jsonMessages = $(offer).find('jingle>json-message');
  410. for (let i = 0; i < jsonMessages.length; i++) {
  411. expandSourcesFromJson(offer, jsonMessages[i]);
  412. }
  413. const sdp = new SDP('');
  414. sdp.fromJingle($(offer).find('>jingle'));
  415. const rawSDP = sdp.raw.replace(/o=- \d+/, 'o=- 123'); // replace generated o= timestamp.
  416. expect(rawSDP).toEqual(expectedSDP);
  417. });
  418. });
  419. });