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.

MockClasses.js 11KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391
  1. import transform from 'sdp-transform';
  2. import Listenable from '../util/Listenable';
  3. /* eslint-disable no-empty-function */
  4. /* eslint-disable max-len */
  5. /**
  6. * MockRTCPeerConnection that return the local description sdp.
  7. */
  8. class MockRTCPeerConnection {
  9. /**
  10. * local description SDP.
  11. */
  12. get localDescription() {
  13. return { sdp: [
  14. 'v=0\r\n',
  15. 'o=- 2074571967553371465 5 IN IP4 127.0.0.1\r\n',
  16. 's=-\r\n',
  17. 't=0 0\r\n',
  18. 'a=msid-semantic: WMS 2a9e4328-59f4-4af5-883f-4b265ac854d6\r\n',
  19. 'a=group:BUNDLE 0 1\r\n',
  20. 'a=extmap-allow-mixed\r\n',
  21. 'm=audio 9 UDP/TLS/RTP/SAVPF 111 126\r\n',
  22. 'c=IN IP4 0.0.0.0\r\n',
  23. 'a=rtpmap:111 opus/48000/2\r\n',
  24. 'a=rtpmap:126 telephone-event/8000\r\n',
  25. 'a=fmtp:126 0-15\r\n',
  26. 'a=fmtp:111 minptime=10;useinbandfec=1\r\n',
  27. 'a=rtcp:9 IN IP4 0.0.0.0\r\n',
  28. 'a=setup:active\r\n',
  29. 'a=mid:0\r\n',
  30. 'a=msid:26D16D51-503A-420B-8274-3DD1174E498F 8205D1FC-50B4-407C-87D5-9C45F1B779F0\r\n',
  31. 'a=sendrecv\r\n',
  32. 'a=ice-ufrag:tOQd\r\n',
  33. 'a=ice-pwd:3sAozs7hw6+2O6DBp2pt9fvY\r\n',
  34. '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',
  35. 'a=ssrc:2002 msid:26D16D51-503A-420B-8274-3DD1174E498F 8205D1FC-50B4-407C-87D5-9C45F1B779F0\r\n',
  36. 'a=ssrc:2002 cname:juejgy8a01\r\n',
  37. 'a=ssrc:2002 name:a8f7g30-a0\r\n',
  38. 'a=rtcp-mux\r\n',
  39. 'a=extmap-allow-mixed\r\n',
  40. 'm=video 9 UDP/TLS/RTP/SAVPF 100 98 96 45\r\n',
  41. 'c=IN IP4 0.0.0.0\r\n',
  42. 'a=rtpmap:100 VP9/90000\r\n',
  43. 'a=rtpmap:98 VP9/90000\r\n',
  44. 'a=rtpmap:96 VP8/90000\r\n',
  45. 'a=rtpmap:45 AV1/90000\r\n',
  46. 'a=fmtp:100 profile-id=2\r\n',
  47. 'a=fmtp:98 profile-id=0\r\n',
  48. 'a=rtcp:9 IN IP4 0.0.0.0\r\n',
  49. 'a=rtcp-fb:100 goog-remb\r\n',
  50. 'a=rtcp-fb:100 transport-cc\r\n',
  51. 'a=rtcp-fb:100 ccm fir\r\n',
  52. 'a=rtcp-fb:100 nack\r\n',
  53. 'a=rtcp-fb:100 nack pli\r\n',
  54. 'a=rtcp-fb:98 goog-remb\r\n',
  55. 'a=rtcp-fb:98 transport-cc\r\n',
  56. 'a=rtcp-fb:98 ccm fir\r\n',
  57. 'a=rtcp-fb:98 nack\r\n',
  58. 'a=rtcp-fb:98 nack pli\r\n',
  59. 'a=rtcp-fb:96 goog-remb\r\n',
  60. 'a=rtcp-fb:96 transport-cc\r\n',
  61. 'a=rtcp-fb:96 ccm fir\r\n',
  62. 'a=rtcp-fb:96 nack\r\n',
  63. 'a=rtcp-fb:96 nack pli\r\n',
  64. 'a=rtcp-fb:45 goog-remb\r\n',
  65. 'a=rtcp-fb:45 transport-cc\r\n',
  66. 'a=rtcp-fb:45 ccm fir\r\n',
  67. 'a=rtcp-fb:45 nack\r\n',
  68. 'a=rtcp-fb:45 nack pli\r\n',
  69. 'a=extmap:14 urn:ietf:params:rtp-hdrext:toffset\r\n',
  70. 'a=extmap:2 http://www.webrtc.org/experiments/rtp-hdrext/abs-send-time\r\n',
  71. 'a=extmap:13 urn:3gpp:video-orientation\r\n',
  72. 'a=extmap:3 http://www.ietf.org/id/draft-holmer-rmcat-transport-wide-cc-extensions-01\r\n',
  73. 'a=extmap:5 http://www.webrtc.org/experiments/rtp-hdrext/playout-delay\r\n',
  74. 'a=extmap:6 http://www.webrtc.org/experiments/rtp-hdrext/video-content-type\r\n',
  75. 'a=extmap:7 http://www.webrtc.org/experiments/rtp-hdrext/video-timing\r\n',
  76. 'a=extmap:8 http://www.webrtc.org/experiments/rtp-hdrext/color-space\r\n',
  77. 'a=extmap:4 urn:ietf:params:rtp-hdrext:sdes:mid\r\n',
  78. 'a=extmap:10 urn:ietf:params:rtp-hdrext:sdes:rtp-stream-id\r\n',
  79. 'a=extmap:11 urn:ietf:params:rtp-hdrext:sdes:repaired-rtp-stream-id\r\n',
  80. 'a=setup:actpass\r\n',
  81. 'a=mid:1\r\n',
  82. 'a=msid:7C0035E5-2DA1-4AEA-804A-9E75BF9B3768 225E9CDA-0384-4C92-92DD-E74C1153EC68\r\n',
  83. 'a=sendrecv\r\n',
  84. 'a=ice-ufrag:tOQd\r\n',
  85. 'a=ice-pwd:3sAozs7hw6+2O6DBp2pt9fvY\r\n',
  86. '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',
  87. 'a=ssrc:4004 msid:7C0035E5-2DA1-4AEA-804A-9E75BF9B3768 225E9CDA-0384-4C92-92DD-E74C1153EC68\r\n',
  88. 'a=ssrc:4005 msid:7C0035E5-2DA1-4AEA-804A-9E75BF9B3768 225E9CDA-0384-4C92-92DD-E74C1153EC68\r\n',
  89. 'a=ssrc:4004 cname:juejgy8a01\r\n',
  90. 'a=ssrc:4005 cname:juejgy8a01\r\n',
  91. 'a=ssrc:4004 name:a8f7g30-v0\r\n',
  92. 'a=ssrc:4005 name:a8f7g30-v0\r\n',
  93. 'a=ssrc-group:FID 4004 4005\r\n',
  94. 'a=rtcp-mux\r\n'
  95. ].join('') };
  96. }
  97. }
  98. /**
  99. * Mock {@link TraceablePeerConnection} - add things as needed, but only things useful for all tests.
  100. */
  101. export class MockPeerConnection {
  102. /**
  103. * Constructor.
  104. *
  105. * @param {string} id RTC id
  106. * @param {boolean} usesUnifiedPlan
  107. * @param {boolean} simulcast
  108. */
  109. constructor(id, usesUnifiedPlan, simulcast) {
  110. this.id = id;
  111. this._usesUnifiedPlan = usesUnifiedPlan;
  112. this.peerconnection = new MockRTCPeerConnection();
  113. this._simulcast = simulcast;
  114. }
  115. /**
  116. * {@link TraceablePeerConnection.localDescription}.
  117. *
  118. * @returns {Object}
  119. */
  120. get localDescription() {
  121. return {
  122. sdp: ''
  123. };
  124. }
  125. /**
  126. * {@link TraceablePeerConnection.remoteDescription}.
  127. *
  128. * @returns {Object}
  129. */
  130. get remoteDescription() {
  131. return {
  132. sdp: ''
  133. };
  134. }
  135. /**
  136. * {@link TracablePeerConnection.calculateExpectedSendResolution}.
  137. * @param {JitsiLocalTrack} localTrack
  138. * @returns {number}
  139. */
  140. calculateExpectedSendResolution(localTrack) {
  141. return localTrack.getCaptureResolution();
  142. }
  143. /**
  144. * {@link TraceablePeerConnection.createAnswer}.
  145. *
  146. * @returns {Promise<Object>}
  147. */
  148. createAnswer() {
  149. return Promise.resolve(/* answer */{});
  150. }
  151. /**
  152. * {@link TraceablePeerConnection.doesTrueSimulcast}.
  153. * @returns {boolean}
  154. */
  155. doesTrueSimulcast() {
  156. return false;
  157. }
  158. /**
  159. * Returns the list of the codecs negotiated.
  160. * @returns {Array<string>}
  161. */
  162. getConfiguredVideoCodecs() {
  163. const sdp = this.peerconnection.localDescription?.sdp;
  164. if (!sdp) {
  165. return [];
  166. }
  167. const parsedSdp = transform.parse(sdp);
  168. const mLine = parsedSdp.media.find(m => m.type === 'video');
  169. const codecs = new Set(mLine.rtp.map(pt => pt.codec.toLowerCase()));
  170. return Array.from(codecs);
  171. }
  172. /**
  173. * {@link TraceablePeerConnection.isSpatialScalabilityOn}.
  174. *
  175. * @returns {boolean}
  176. */
  177. isSpatialScalabilityOn() {
  178. return this._simulcast;
  179. }
  180. /**
  181. * {@link TraceablePeerConnection.processLocalSdpForTransceiverInfo}.
  182. *
  183. * @returns {void}
  184. */
  185. processLocalSdpForTransceiverInfo() {
  186. }
  187. /**
  188. * {@link TraceablePeerConnection.setLocalDescription}.
  189. *
  190. * @returns {Promise<void>}
  191. */
  192. setLocalDescription() {
  193. return Promise.resolve();
  194. }
  195. /**
  196. * {@link TraceablePeerConnection.setRemoteDescription}.
  197. *
  198. * @returns {Promise<void>}
  199. */
  200. setRemoteDescription() {
  201. return Promise.resolve();
  202. }
  203. /**
  204. * {@link TraceablePeerConnection.setSenderVideoConstraints}.
  205. */
  206. setSenderVideoConstraints() {
  207. }
  208. /**
  209. * {@link TraceablePeerConnection.setVideoTransferActive}.
  210. */
  211. setVideoTransferActive() {
  212. return false;
  213. }
  214. /**
  215. * {@link TraceablePeerConnection.usesUnifiedPlan}.
  216. */
  217. usesUnifiedPlan() {
  218. return this._usesUnifiedPlan;
  219. }
  220. /**
  221. * {@link TraceablePeerConnection.getLocalVideoTracks}.
  222. */
  223. getLocalVideoTracks() {
  224. return [];
  225. }
  226. }
  227. /**
  228. * Mock {@link RTC} - add things as needed, but only things useful for all tests.
  229. */
  230. export class MockRTC extends Listenable {
  231. /**
  232. * {@link RTC.createPeerConnection}.
  233. *
  234. * @returns {MockPeerConnection}
  235. */
  236. createPeerConnection() {
  237. this.pc = new MockPeerConnection();
  238. this.forwardedSources = [];
  239. return this.pc;
  240. }
  241. /**
  242. * Returns the list of sources that the bridge is forwarding to the client.
  243. * @returns {Array<string>}
  244. */
  245. getForwardedSources() {
  246. return this.forwardedSources;
  247. }
  248. }
  249. /**
  250. * MockSignalingLayerImpl
  251. */
  252. export class MockSignalingLayerImpl {
  253. /**
  254. * A constructor
  255. */
  256. constructor() {
  257. this._remoteSourceState = {};
  258. }
  259. /**
  260. * Returns the muted state, videoType and codec info received in presence.
  261. * @param {string} endpointId
  262. * @returns Object
  263. */
  264. getPeerMediaInfo(endpointId) {
  265. return this._remoteSourceState[endpointId];
  266. }
  267. /**
  268. * Updates the media info for peer on join/leave.
  269. * @param {boolean} isJoin - whether endpoint is joining or leaving the call
  270. * @param {string} endpointId - endpoint id
  271. * @param {Array<string>} codecList - new codec list published in presence
  272. * @param {string} codecType - legacy codec setting published in presence
  273. */
  274. setPeerMediaInfo(isJoin, endpointId, codecList, codecType) {
  275. if (isJoin) {
  276. this._remoteSourceState[endpointId] = {
  277. muted: true, // muted by default
  278. videoType: 'camera',
  279. codecList,
  280. codecType
  281. };
  282. } else {
  283. this._remoteSourceState[endpointId] = undefined;
  284. }
  285. }
  286. }
  287. /**
  288. * MockTrack
  289. */
  290. export class MockTrack {
  291. /**
  292. * A constructor
  293. */
  294. constructor(height) {
  295. this.height = height;
  296. }
  297. /**
  298. * Returns height.
  299. * @returns {number}
  300. */
  301. getSettings() {
  302. return {
  303. height: this.height
  304. };
  305. }
  306. }
  307. /**
  308. * MockJitsiLocalTrack
  309. */
  310. export class MockJitsiLocalTrack {
  311. /**
  312. * A constructor
  313. */
  314. constructor(height, mediaType, videoType) {
  315. this.resolution = height;
  316. this.track = new MockTrack(height);
  317. this.type = mediaType;
  318. this.videoType = videoType;
  319. }
  320. /**
  321. * Returns the height.
  322. * @returns {number}
  323. */
  324. getHeight() {
  325. return this.track.height;
  326. }
  327. /**
  328. * Returns the capture resolution.
  329. * @returns {number}
  330. */
  331. getCaptureResolution() {
  332. return this.getHeight();
  333. }
  334. /**
  335. * Returns track.
  336. * @returns {MockTrack}
  337. */
  338. getTrack() {
  339. return this.track;
  340. }
  341. /**
  342. * Returns media type.
  343. * @returns {MediaType}
  344. */
  345. getType() {
  346. return this.type;
  347. }
  348. /**
  349. * Returns video type.
  350. * @returns {VideoType}
  351. */
  352. getVideoType() {
  353. return this.videoType;
  354. }
  355. }