您最多选择25个主题 主题必须以字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符

MockClasses.js 11KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404
  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.getDesiredMediaDirection}.
  174. */
  175. getDesiredMediaDirection() {
  176. return 'sendrecv';
  177. }
  178. /**
  179. * {@link TraceablePeerConnection.isSpatialScalabilityOn}.
  180. *
  181. * @returns {boolean}
  182. */
  183. isSpatialScalabilityOn() {
  184. return this._simulcast;
  185. }
  186. /**
  187. * {@link TraceablePeerConnection.processLocalSdpForTransceiverInfo}.
  188. *
  189. * @returns {void}
  190. */
  191. processLocalSdpForTransceiverInfo() {
  192. }
  193. /**
  194. * {@link TraceablePeerConnection.setLocalDescription}.
  195. *
  196. * @returns {Promise<void>}
  197. */
  198. setLocalDescription() {
  199. return Promise.resolve();
  200. }
  201. /**
  202. * {@link TraceablePeerConnection.setRemoteDescription}.
  203. *
  204. * @returns {Promise<void>}
  205. */
  206. setRemoteDescription() {
  207. return Promise.resolve();
  208. }
  209. /**
  210. * {@link TraceablePeerConnection.setSenderVideoConstraints}.
  211. */
  212. setSenderVideoConstraints() {
  213. }
  214. /**
  215. * {@link TraceablePeerConnection.setVideoTransferActive}.
  216. */
  217. setVideoTransferActive() {
  218. return false;
  219. }
  220. /**
  221. * {@link TraceablePeerConnection.updateRemoteSources}.
  222. */
  223. updateRemoteSources() {
  224. }
  225. /**
  226. * {@link TraceablePeerConnection.usesUnifiedPlan}.
  227. */
  228. usesUnifiedPlan() {
  229. return this._usesUnifiedPlan;
  230. }
  231. /**
  232. * {@link TraceablePeerConnection.getLocalVideoTracks}.
  233. */
  234. getLocalVideoTracks() {
  235. return [];
  236. }
  237. }
  238. /**
  239. * Mock {@link RTC} - add things as needed, but only things useful for all tests.
  240. */
  241. export class MockRTC extends Listenable {
  242. /**
  243. * {@link RTC.createPeerConnection}.
  244. *
  245. * @returns {MockPeerConnection}
  246. */
  247. createPeerConnection() {
  248. this.pc = new MockPeerConnection();
  249. this.forwardedSources = [];
  250. return this.pc;
  251. }
  252. /**
  253. * Returns the list of sources that the bridge is forwarding to the client.
  254. * @returns {Array<string>}
  255. */
  256. getForwardedSources() {
  257. return this.forwardedSources;
  258. }
  259. }
  260. /**
  261. * MockSignalingLayerImpl
  262. */
  263. export class MockSignalingLayerImpl {
  264. /**
  265. * A constructor
  266. */
  267. constructor() {
  268. this._remoteSourceState = {};
  269. }
  270. /**
  271. * Returns the muted state, videoType and codec info received in presence.
  272. * @param {string} endpointId
  273. * @returns Object
  274. */
  275. getPeerMediaInfo(endpointId) {
  276. return this._remoteSourceState[endpointId];
  277. }
  278. /**
  279. * Updates the media info for peer on join/leave.
  280. * @param {boolean} isJoin - whether endpoint is joining or leaving the call
  281. * @param {string} endpointId - endpoint id
  282. * @param {Array<string>} codecList - new codec list published in presence
  283. * @param {string} codecType - legacy codec setting published in presence
  284. */
  285. setPeerMediaInfo(isJoin, endpointId, codecList, codecType) {
  286. if (isJoin) {
  287. this._remoteSourceState[endpointId] = {
  288. muted: true, // muted by default
  289. videoType: 'camera',
  290. codecList,
  291. codecType
  292. };
  293. } else {
  294. this._remoteSourceState[endpointId] = undefined;
  295. }
  296. }
  297. }
  298. /**
  299. * MockTrack
  300. */
  301. export class MockTrack {
  302. /**
  303. * A constructor
  304. */
  305. constructor(height) {
  306. this.height = height;
  307. }
  308. /**
  309. * Returns height.
  310. * @returns {number}
  311. */
  312. getSettings() {
  313. return {
  314. height: this.height
  315. };
  316. }
  317. }
  318. /**
  319. * MockJitsiLocalTrack
  320. */
  321. export class MockJitsiLocalTrack {
  322. /**
  323. * A constructor
  324. */
  325. constructor(height, mediaType, videoType) {
  326. this.resolution = height;
  327. this.track = new MockTrack(height);
  328. this.type = mediaType;
  329. this.videoType = videoType;
  330. }
  331. /**
  332. * Returns the height.
  333. * @returns {number}
  334. */
  335. getHeight() {
  336. return this.track.height;
  337. }
  338. /**
  339. * Returns the capture resolution.
  340. * @returns {number}
  341. */
  342. getCaptureResolution() {
  343. return this.getHeight();
  344. }
  345. /**
  346. * Returns track.
  347. * @returns {MockTrack}
  348. */
  349. getTrack() {
  350. return this.track;
  351. }
  352. /**
  353. * Returns media type.
  354. * @returns {MediaType}
  355. */
  356. getType() {
  357. return this.type;
  358. }
  359. /**
  360. * Returns video type.
  361. * @returns {VideoType}
  362. */
  363. getVideoType() {
  364. return this.videoType;
  365. }
  366. }