@webex/plugin-meetings 3.0.0-beta.1 → 3.0.0-beta.11

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 (281) hide show
  1. package/dist/common/browser-detection.js.map +1 -1
  2. package/dist/common/collection.js.map +1 -1
  3. package/dist/common/config.js.map +1 -1
  4. package/dist/common/errors/captcha-error.js +7 -0
  5. package/dist/common/errors/captcha-error.js.map +1 -1
  6. package/dist/common/errors/intent-to-join.js +8 -0
  7. package/dist/common/errors/intent-to-join.js.map +1 -1
  8. package/dist/common/errors/join-meeting.js +8 -0
  9. package/dist/common/errors/join-meeting.js.map +1 -1
  10. package/dist/common/errors/media.js +7 -0
  11. package/dist/common/errors/media.js.map +1 -1
  12. package/dist/common/errors/parameter.js.map +1 -1
  13. package/dist/common/errors/password-error.js +7 -0
  14. package/dist/common/errors/password-error.js.map +1 -1
  15. package/dist/common/errors/permission.js +7 -0
  16. package/dist/common/errors/permission.js.map +1 -1
  17. package/dist/common/errors/reconnection-in-progress.js.map +1 -1
  18. package/dist/common/errors/reconnection.js +7 -0
  19. package/dist/common/errors/reconnection.js.map +1 -1
  20. package/dist/common/errors/stats.js +7 -0
  21. package/dist/common/errors/stats.js.map +1 -1
  22. package/dist/common/errors/webex-errors.js +5 -29
  23. package/dist/common/errors/webex-errors.js.map +1 -1
  24. package/dist/common/errors/webex-meetings-error.js +5 -2
  25. package/dist/common/errors/webex-meetings-error.js.map +1 -1
  26. package/dist/common/events/events-scope.js.map +1 -1
  27. package/dist/common/events/events.js.map +1 -1
  28. package/dist/common/events/trigger-proxy.js.map +1 -1
  29. package/dist/common/events/util.js.map +1 -1
  30. package/dist/common/logs/logger-config.js.map +1 -1
  31. package/dist/common/logs/logger-proxy.js.map +1 -1
  32. package/dist/common/logs/request.js +3 -0
  33. package/dist/common/logs/request.js.map +1 -1
  34. package/dist/common/queue.js.map +1 -1
  35. package/dist/config.js +1 -0
  36. package/dist/config.js.map +1 -1
  37. package/dist/constants.js +15 -74
  38. package/dist/constants.js.map +1 -1
  39. package/dist/locus-info/controlsUtils.js.map +1 -1
  40. package/dist/locus-info/embeddedAppsUtils.js.map +1 -1
  41. package/dist/locus-info/fullState.js.map +1 -1
  42. package/dist/locus-info/hostUtils.js.map +1 -1
  43. package/dist/locus-info/index.js +43 -5
  44. package/dist/locus-info/index.js.map +1 -1
  45. package/dist/locus-info/infoUtils.js +4 -0
  46. package/dist/locus-info/infoUtils.js.map +1 -1
  47. package/dist/locus-info/mediaSharesUtils.js.map +1 -1
  48. package/dist/locus-info/parser.js +12 -3
  49. package/dist/locus-info/parser.js.map +1 -1
  50. package/dist/locus-info/selfUtils.js.map +1 -1
  51. package/dist/media/index.js +71 -210
  52. package/dist/media/index.js.map +1 -1
  53. package/dist/media/internal-media-core-wrapper.js +22 -0
  54. package/dist/media/internal-media-core-wrapper.js.map +1 -0
  55. package/dist/media/properties.js +32 -25
  56. package/dist/media/properties.js.map +1 -1
  57. package/dist/media/util.js +0 -27
  58. package/dist/media/util.js.map +1 -1
  59. package/dist/mediaQualityMetrics/config.js.map +1 -1
  60. package/dist/meeting/effectsState.js +8 -1
  61. package/dist/meeting/effectsState.js.map +1 -1
  62. package/dist/meeting/index.js +1146 -602
  63. package/dist/meeting/index.js.map +1 -1
  64. package/dist/meeting/muteState.js +6 -0
  65. package/dist/meeting/muteState.js.map +1 -1
  66. package/dist/meeting/request.js +83 -24
  67. package/dist/meeting/request.js.map +1 -1
  68. package/dist/meeting/state.js.map +1 -1
  69. package/dist/meeting/util.js +5 -44
  70. package/dist/meeting/util.js.map +1 -1
  71. package/dist/meeting-info/collection.js +4 -1
  72. package/dist/meeting-info/collection.js.map +1 -1
  73. package/dist/meeting-info/index.js +5 -0
  74. package/dist/meeting-info/index.js.map +1 -1
  75. package/dist/meeting-info/meeting-info-v2.js +14 -2
  76. package/dist/meeting-info/meeting-info-v2.js.map +1 -1
  77. package/dist/meeting-info/request.js +3 -0
  78. package/dist/meeting-info/request.js.map +1 -1
  79. package/dist/meeting-info/util.js.map +1 -1
  80. package/dist/meeting-info/utilv2.js.map +1 -1
  81. package/dist/meetings/collection.js +4 -1
  82. package/dist/meetings/collection.js.map +1 -1
  83. package/dist/meetings/index.js +136 -25
  84. package/dist/meetings/index.js.map +1 -1
  85. package/dist/meetings/request.js +4 -0
  86. package/dist/meetings/request.js.map +1 -1
  87. package/dist/meetings/util.js +24 -1
  88. package/dist/meetings/util.js.map +1 -1
  89. package/dist/member/index.js +30 -7
  90. package/dist/member/index.js.map +1 -1
  91. package/dist/member/util.js +2 -1
  92. package/dist/member/util.js.map +1 -1
  93. package/dist/members/collection.js +1 -0
  94. package/dist/members/collection.js.map +1 -1
  95. package/dist/members/index.js +82 -1
  96. package/dist/members/index.js.map +1 -1
  97. package/dist/members/request.js +19 -9
  98. package/dist/members/request.js.map +1 -1
  99. package/dist/members/util.js.map +1 -1
  100. package/dist/metrics/config.js.map +1 -1
  101. package/dist/metrics/constants.js.map +1 -1
  102. package/dist/metrics/index.js +8 -0
  103. package/dist/metrics/index.js.map +1 -1
  104. package/dist/multistream/mediaRequestManager.js +133 -0
  105. package/dist/multistream/mediaRequestManager.js.map +1 -0
  106. package/dist/multistream/multistreamMedia.js +116 -0
  107. package/dist/multistream/multistreamMedia.js.map +1 -0
  108. package/dist/multistream/receiveSlot.js +209 -0
  109. package/dist/multistream/receiveSlot.js.map +1 -0
  110. package/dist/multistream/receiveSlotManager.js +195 -0
  111. package/dist/multistream/receiveSlotManager.js.map +1 -0
  112. package/dist/multistream/remoteMedia.js +289 -0
  113. package/dist/multistream/remoteMedia.js.map +1 -0
  114. package/dist/multistream/remoteMediaGroup.js +243 -0
  115. package/dist/multistream/remoteMediaGroup.js.map +1 -0
  116. package/dist/multistream/remoteMediaManager.js +1113 -0
  117. package/dist/multistream/remoteMediaManager.js.map +1 -0
  118. package/dist/networkQualityMonitor/index.js +10 -2
  119. package/dist/networkQualityMonitor/index.js.map +1 -1
  120. package/dist/personal-meeting-room/index.js +11 -0
  121. package/dist/personal-meeting-room/index.js.map +1 -1
  122. package/dist/personal-meeting-room/request.js +2 -1
  123. package/dist/personal-meeting-room/request.js.map +1 -1
  124. package/dist/personal-meeting-room/util.js.map +1 -1
  125. package/dist/reachability/index.js +17 -7
  126. package/dist/reachability/index.js.map +1 -1
  127. package/dist/reachability/request.js +1 -0
  128. package/dist/reachability/request.js.map +1 -1
  129. package/dist/reactions/reactions.js +111 -0
  130. package/dist/reactions/reactions.js.map +1 -0
  131. package/dist/reactions/reactions.type.js +40 -0
  132. package/dist/reactions/reactions.type.js.map +1 -0
  133. package/dist/reconnection-manager/index.js +130 -132
  134. package/dist/reconnection-manager/index.js.map +1 -1
  135. package/dist/roap/index.js +58 -231
  136. package/dist/roap/index.js.map +1 -1
  137. package/dist/roap/request.js +7 -116
  138. package/dist/roap/request.js.map +1 -1
  139. package/dist/roap/turnDiscovery.js +20 -6
  140. package/dist/roap/turnDiscovery.js.map +1 -1
  141. package/dist/statsAnalyzer/global.js +2 -0
  142. package/dist/statsAnalyzer/global.js.map +1 -1
  143. package/dist/statsAnalyzer/index.js +58 -37
  144. package/dist/statsAnalyzer/index.js.map +1 -1
  145. package/dist/statsAnalyzer/mqaUtil.js +9 -3
  146. package/dist/statsAnalyzer/mqaUtil.js.map +1 -1
  147. package/dist/transcription/index.js +10 -3
  148. package/dist/transcription/index.js.map +1 -1
  149. package/package.json +21 -20
  150. package/src/common/{browser-detection.js → browser-detection.ts} +1 -1
  151. package/src/common/collection.ts +6 -6
  152. package/src/common/{config.js → config.ts} +1 -1
  153. package/src/common/errors/{captcha-error.js → captcha-error.ts} +5 -1
  154. package/src/common/errors/{intent-to-join.js → intent-to-join.ts} +6 -1
  155. package/src/common/errors/{join-meeting.js → join-meeting.ts} +6 -1
  156. package/src/common/errors/{media.js → media.ts} +5 -1
  157. package/src/common/errors/parameter.ts +3 -2
  158. package/src/common/errors/{password-error.js → password-error.ts} +5 -1
  159. package/src/common/errors/{permission.js → permission.ts} +5 -1
  160. package/src/common/errors/{reconnection-in-progress.js → reconnection-in-progress.ts} +0 -0
  161. package/src/common/errors/{reconnection.js → reconnection.ts} +5 -1
  162. package/src/common/errors/{stats.js → stats.ts} +5 -1
  163. package/src/common/errors/{webex-errors.js → webex-errors.ts} +1 -20
  164. package/src/common/errors/{webex-meetings-error.js → webex-meetings-error.ts} +3 -1
  165. package/src/common/events/{events-scope.js → events-scope.ts} +1 -1
  166. package/src/common/events/{events.js → events.ts} +0 -0
  167. package/src/common/events/{trigger-proxy.js → trigger-proxy.ts} +1 -2
  168. package/src/common/events/{util.js → util.ts} +1 -1
  169. package/src/common/logs/{logger-config.js → logger-config.ts} +1 -2
  170. package/src/common/logs/{logger-proxy.js → logger-proxy.ts} +1 -1
  171. package/src/common/logs/{request.js → request.ts} +12 -2
  172. package/src/common/queue.ts +1 -2
  173. package/src/{config.js → config.ts} +2 -0
  174. package/src/constants.ts +139 -179
  175. package/src/locus-info/{controlsUtils.js → controlsUtils.ts} +4 -4
  176. package/src/locus-info/{embeddedAppsUtils.js → embeddedAppsUtils.ts} +5 -6
  177. package/src/locus-info/{fullState.js → fullState.ts} +1 -1
  178. package/src/locus-info/{hostUtils.js → hostUtils.ts} +5 -5
  179. package/src/locus-info/{index.js → index.ts} +67 -32
  180. package/src/locus-info/{infoUtils.js → infoUtils.ts} +7 -4
  181. package/src/locus-info/{mediaSharesUtils.js → mediaSharesUtils.ts} +13 -13
  182. package/src/locus-info/{parser.js → parser.ts} +22 -12
  183. package/src/locus-info/{selfUtils.js → selfUtils.ts} +17 -19
  184. package/src/media/{index.js → index.ts} +130 -205
  185. package/src/media/internal-media-core-wrapper.ts +9 -0
  186. package/src/media/{properties.js → properties.ts} +35 -29
  187. package/src/media/util.ts +16 -0
  188. package/src/mediaQualityMetrics/{config.js → config.ts} +1 -1
  189. package/src/meeting/{effectsState.js → effectsState.ts} +12 -6
  190. package/src/meeting/{index.js → index.ts} +993 -474
  191. package/src/meeting/{muteState.js → muteState.ts} +16 -11
  192. package/src/meeting/{request.js → request.ts} +148 -36
  193. package/src/meeting/{state.js → state.ts} +6 -6
  194. package/src/meeting/{util.js → util.ts} +9 -51
  195. package/src/meeting-info/{collection.js → collection.ts} +4 -1
  196. package/src/meeting-info/{index.js → index.ts} +10 -6
  197. package/src/meeting-info/{meeting-info-v2.js → meeting-info-v2.ts} +28 -10
  198. package/src/meeting-info/{request.js → request.ts} +6 -2
  199. package/src/meeting-info/{util.js → util.ts} +6 -5
  200. package/src/meeting-info/{utilv2.js → utilv2.ts} +8 -7
  201. package/src/meetings/{collection.js → collection.ts} +5 -2
  202. package/src/meetings/{index.js → index.ts} +118 -22
  203. package/src/meetings/{request.js → request.ts} +6 -1
  204. package/src/meetings/{util.js → util.ts} +28 -5
  205. package/src/member/{index.js → index.ts} +46 -15
  206. package/src/member/{util.js → util.ts} +17 -16
  207. package/src/members/{collection.js → collection.ts} +2 -1
  208. package/src/members/{index.js → index.ts} +94 -26
  209. package/src/members/{request.js → request.ts} +16 -5
  210. package/src/members/{util.js → util.ts} +7 -7
  211. package/src/metrics/{config.js → config.ts} +0 -2
  212. package/src/metrics/{constants.js → constants.ts} +0 -0
  213. package/src/metrics/{index.js → index.ts} +27 -8
  214. package/src/multistream/mediaRequestManager.ts +166 -0
  215. package/src/multistream/multistreamMedia.ts +92 -0
  216. package/src/multistream/receiveSlot.ts +141 -0
  217. package/src/multistream/receiveSlotManager.ts +142 -0
  218. package/src/multistream/remoteMedia.ts +228 -0
  219. package/src/multistream/remoteMediaGroup.ts +224 -0
  220. package/src/multistream/remoteMediaManager.ts +911 -0
  221. package/src/networkQualityMonitor/{index.js → index.ts} +18 -3
  222. package/src/personal-meeting-room/{index.js → index.ts} +17 -4
  223. package/src/personal-meeting-room/{request.js → request.ts} +3 -1
  224. package/src/personal-meeting-room/{util.js → util.ts} +1 -1
  225. package/src/reachability/{index.js → index.ts} +28 -17
  226. package/src/reachability/request.ts +4 -2
  227. package/src/reactions/reactions.ts +104 -0
  228. package/src/reactions/reactions.type.ts +36 -0
  229. package/src/reconnection-manager/{index.js → index.ts} +81 -65
  230. package/src/roap/index.ts +229 -0
  231. package/src/roap/{request.js → request.ts} +15 -74
  232. package/src/roap/turnDiscovery.ts +26 -11
  233. package/src/statsAnalyzer/{global.js → global.ts} +2 -0
  234. package/src/statsAnalyzer/{index.js → index.ts} +66 -61
  235. package/src/statsAnalyzer/{mqaUtil.js → mqaUtil.ts} +6 -1
  236. package/src/transcription/{index.js → index.ts} +16 -11
  237. package/test/integration/spec/journey.js +1 -1
  238. package/test/integration/spec/space-meeting.js +1 -2
  239. package/test/unit/spec/locus-info/infoUtils.js +17 -1
  240. package/test/unit/spec/media/index.ts +207 -0
  241. package/test/unit/spec/media/properties.ts +73 -82
  242. package/test/unit/spec/meeting/effectsState.js +1 -3
  243. package/test/unit/spec/meeting/index.js +672 -245
  244. package/test/unit/spec/meeting/muteState.js +7 -0
  245. package/test/unit/spec/meeting/request.js +25 -1
  246. package/test/unit/spec/meeting/utils.js +63 -2
  247. package/test/unit/spec/meetings/index.js +0 -4
  248. package/test/unit/spec/members/index.js +164 -2
  249. package/test/unit/spec/multistream/mediaRequestManager.ts +515 -0
  250. package/test/unit/spec/multistream/receiveSlot.ts +104 -0
  251. package/test/unit/spec/multistream/receiveSlotManager.ts +173 -0
  252. package/test/unit/spec/multistream/remoteMedia.ts +225 -0
  253. package/test/unit/spec/multistream/remoteMediaGroup.ts +396 -0
  254. package/test/unit/spec/multistream/remoteMediaManager.ts +1309 -0
  255. package/test/unit/spec/reconnection-manager/index.js +68 -2
  256. package/test/unit/spec/roap/index.ts +63 -35
  257. package/test/unit/spec/stats-analyzer/index.js +19 -22
  258. package/dist/peer-connection-manager/index.js +0 -794
  259. package/dist/peer-connection-manager/index.js.map +0 -1
  260. package/dist/peer-connection-manager/util.js +0 -124
  261. package/dist/peer-connection-manager/util.js.map +0 -1
  262. package/dist/roap/collection.js +0 -73
  263. package/dist/roap/collection.js.map +0 -1
  264. package/dist/roap/handler.js +0 -337
  265. package/dist/roap/handler.js.map +0 -1
  266. package/dist/roap/state.js +0 -164
  267. package/dist/roap/state.js.map +0 -1
  268. package/dist/roap/util.js +0 -102
  269. package/dist/roap/util.js.map +0 -1
  270. package/src/media/util.js +0 -38
  271. package/src/peer-connection-manager/index.js +0 -723
  272. package/src/peer-connection-manager/util.ts +0 -117
  273. package/src/roap/collection.js +0 -63
  274. package/src/roap/handler.js +0 -252
  275. package/src/roap/index.js +0 -380
  276. package/src/roap/state.js +0 -149
  277. package/src/roap/util.js +0 -93
  278. package/test/unit/spec/peerconnection-manager/index.js +0 -188
  279. package/test/unit/spec/peerconnection-manager/utils.js +0 -48
  280. package/test/unit/spec/peerconnection-manager/utils.test-fixtures.ts +0 -389
  281. package/test/unit/spec/roap/util.js +0 -30
@@ -0,0 +1,515 @@
1
+ import {MediaRequestManager} from '@webex/plugin-meetings/src/multistream/mediaRequestManager';
2
+ import {ReceiveSlot} from '@webex/plugin-meetings/src/multistream/receiveSlot';
3
+ import sinon from 'sinon';
4
+ import {assert} from '@webex/test-helper-chai';
5
+
6
+ type ExpectedActiveSpeaker = {
7
+ policy: 'active-speaker';
8
+ priority: number;
9
+ receiveSlots: Array<ReceiveSlot>;
10
+ };
11
+ type ExpectedReceiverSelected = {
12
+ policy: 'receiver-selected';
13
+ csi: number;
14
+ receiveSlot: ReceiveSlot;
15
+ };
16
+ type ExpectedRequest = ExpectedActiveSpeaker | ExpectedReceiverSelected;
17
+
18
+ const maxPayloadBitsPerSecond = 10 * 1000 * 1000; // for now we always send this fixed constant
19
+
20
+ describe('MediaRequestManager', () => {
21
+ const CROSS_PRIORITY_DUPLICATION = true;
22
+ const CROSS_POLICY_DUPLICATION = true;
23
+ const PREFER_LIVE_VIDEO = true;
24
+ const ACTIVE_SPEAKER_MAX_FS = 3600;
25
+ const RECEIVER_SELECTED_MAX_FS = 8190;
26
+
27
+ const NUM_SLOTS = 10;
28
+
29
+ let mediaRequestManager: MediaRequestManager;
30
+ let sendMediaRequestsCallback;
31
+ let fakeWcmeSlots;
32
+ let fakeReceiveSlots;
33
+
34
+ beforeEach(() => {
35
+ sendMediaRequestsCallback = sinon.stub();
36
+ mediaRequestManager = new MediaRequestManager(sendMediaRequestsCallback);
37
+
38
+ // create some fake receive slots used by the tests
39
+ fakeWcmeSlots = Array(NUM_SLOTS)
40
+ .fill(null)
41
+ .map((_, index) => ({
42
+ id: `fake WCME slot ${index}`,
43
+ }));
44
+
45
+ fakeReceiveSlots = Array(NUM_SLOTS)
46
+ .fill(null)
47
+ .map(
48
+ (_, index) =>
49
+ ({
50
+ id: `fake receive slot ${index}`,
51
+ wcmeReceiveSlot: fakeWcmeSlots[index],
52
+ resetSourceState: sinon.stub(),
53
+ } as unknown as ReceiveSlot)
54
+ );
55
+ });
56
+
57
+ // helper function for adding an active speaker request
58
+ const addActiveSpeakerRequest = (priority, receiveSlots, commit = false) =>
59
+ mediaRequestManager.addRequest(
60
+ {
61
+ policyInfo: {
62
+ policy: 'active-speaker',
63
+ priority,
64
+ crossPriorityDuplication: CROSS_PRIORITY_DUPLICATION,
65
+ crossPolicyDuplication: CROSS_POLICY_DUPLICATION,
66
+ preferLiveVideo: PREFER_LIVE_VIDEO,
67
+ },
68
+ receiveSlots,
69
+ codecInfo: {
70
+ codec: 'h264',
71
+ maxFs: ACTIVE_SPEAKER_MAX_FS,
72
+ },
73
+ },
74
+ commit
75
+ );
76
+
77
+ // helper function for adding a receiver selected request
78
+ const addReceiverSelectedRequest = (csi, receiveSlot, commit = false) =>
79
+ mediaRequestManager.addRequest(
80
+ {
81
+ policyInfo: {
82
+ policy: 'receiver-selected',
83
+ csi,
84
+ },
85
+ receiveSlots: [receiveSlot],
86
+ codecInfo: {
87
+ codec: 'h264',
88
+ maxFs: RECEIVER_SELECTED_MAX_FS,
89
+ },
90
+ },
91
+ commit
92
+ );
93
+
94
+ // helper function for verifying that the right active speaker and receiver selected
95
+ // requests have been sent out
96
+ // It should be used only for verifying requests created with
97
+ // addActiveSpeakerRequest() or addReceiverSelectedRequest(), because of some
98
+ // hardcoded values used in them
99
+ const checkMediaRequestsSent = (expectedRequests: ExpectedRequest[]) => {
100
+ assert.calledOnce(sendMediaRequestsCallback);
101
+ assert.calledWith(
102
+ sendMediaRequestsCallback,
103
+ expectedRequests.map((expectedRequest) => {
104
+ if (expectedRequest.policy === 'active-speaker') {
105
+ return sinon.match({
106
+ policy: 'active-speaker',
107
+ policySpecificInfo: sinon.match({
108
+ priority: expectedRequest.priority,
109
+ crossPriorityDuplication: CROSS_PRIORITY_DUPLICATION,
110
+ crossPolicyDuplication: CROSS_POLICY_DUPLICATION,
111
+ preferLiveVideo: PREFER_LIVE_VIDEO,
112
+ }),
113
+ receiveSlots: expectedRequest.receiveSlots,
114
+ maxPayloadBitsPerSecond,
115
+ codecInfos: [
116
+ sinon.match({
117
+ payloadType: 0x80,
118
+ h264: sinon.match({
119
+ maxFs: ACTIVE_SPEAKER_MAX_FS,
120
+ }),
121
+ }),
122
+ ],
123
+ });
124
+ }
125
+ if (expectedRequest.policy === 'receiver-selected') {
126
+ return sinon.match({
127
+ policy: 'receiver-selected',
128
+ policySpecificInfo: sinon.match({
129
+ csi: expectedRequest.csi,
130
+ }),
131
+ receiveSlots: [expectedRequest.receiveSlot],
132
+ maxPayloadBitsPerSecond,
133
+ codecInfos: [
134
+ sinon.match({
135
+ payloadType: 0x80,
136
+ h264: sinon.match({
137
+ maxFs: RECEIVER_SELECTED_MAX_FS,
138
+ }),
139
+ }),
140
+ ],
141
+ });
142
+ }
143
+
144
+ return undefined;
145
+ })
146
+ );
147
+ sendMediaRequestsCallback.resetHistory();
148
+ };
149
+
150
+ it('starts with no requests', () => {
151
+ mediaRequestManager.commit();
152
+
153
+ assert.calledOnce(sendMediaRequestsCallback);
154
+ assert.calledWith(sendMediaRequestsCallback, []);
155
+ });
156
+
157
+ it('sends correct wcme media requests when addRequest() is called with commit=true', () => {
158
+ // this is the only test that doesn't use the helper addActiveSpeakerRequest(), addReceiverSelectedRequest() methods
159
+ // because it tests other values for some of the parameters that are otherwise always fixed by those helpers
160
+
161
+ // first call addRequest a couple of times with commit=false
162
+ mediaRequestManager.addRequest(
163
+ {
164
+ policyInfo: {
165
+ policy: 'active-speaker',
166
+ priority: 255,
167
+ crossPriorityDuplication: true,
168
+ crossPolicyDuplication: false,
169
+ preferLiveVideo: false,
170
+ },
171
+ receiveSlots: [fakeReceiveSlots[0], fakeReceiveSlots[1], fakeReceiveSlots[2]],
172
+ codecInfo: {
173
+ codec: 'h264',
174
+ maxFs: 1620,
175
+ maxFps: 1500,
176
+ },
177
+ },
178
+ false
179
+ );
180
+ mediaRequestManager.addRequest(
181
+ {
182
+ policyInfo: {
183
+ policy: 'receiver-selected',
184
+ csi: 123,
185
+ },
186
+ receiveSlots: [fakeReceiveSlots[3]],
187
+ codecInfo: {
188
+ codec: 'h264',
189
+ maxFs: 3600,
190
+ maxFps: 2500,
191
+ maxMbps: 90000,
192
+ },
193
+ },
194
+ false
195
+ );
196
+
197
+ // finally call it with commit=true
198
+ mediaRequestManager.addRequest(
199
+ {
200
+ policyInfo: {
201
+ policy: 'receiver-selected',
202
+ csi: 123,
203
+ },
204
+ receiveSlots: [fakeReceiveSlots[4]],
205
+ codecInfo: {
206
+ codec: 'h264',
207
+ maxFs: 8192,
208
+ maxFps: 2500,
209
+ maxMbps: 204800,
210
+ },
211
+ },
212
+ true
213
+ );
214
+
215
+ // all 3 requests should be sent out together
216
+ assert.calledOnce(sendMediaRequestsCallback);
217
+ assert.calledWith(sendMediaRequestsCallback, [
218
+ sinon.match({
219
+ policy: 'active-speaker',
220
+ policySpecificInfo: sinon.match({
221
+ priority: 255,
222
+ crossPriorityDuplication: true,
223
+ crossPolicyDuplication: false,
224
+ preferLiveVideo: false,
225
+ }),
226
+ receiveSlots: [fakeWcmeSlots[0], fakeWcmeSlots[1], fakeWcmeSlots[2]],
227
+ codecInfos: [
228
+ sinon.match({
229
+ payloadType: 0x80,
230
+ h264: sinon.match({
231
+ maxFs: 1620,
232
+ maxFps: 1500,
233
+ maxMbps: 245760,
234
+ }),
235
+ }),
236
+ ],
237
+ }),
238
+ sinon.match({
239
+ policy: 'receiver-selected',
240
+ policySpecificInfo: sinon.match({
241
+ csi: 123,
242
+ }),
243
+ receiveSlots: [fakeWcmeSlots[3]],
244
+ codecInfos: [
245
+ sinon.match({
246
+ payloadType: 0x80,
247
+ h264: sinon.match({
248
+ maxFs: 3600,
249
+ maxFps: 2500,
250
+ maxMbps: 90000,
251
+ }),
252
+ }),
253
+ ],
254
+ }),
255
+ sinon.match({
256
+ policy: 'receiver-selected',
257
+ policySpecificInfo: sinon.match({
258
+ csi: 123,
259
+ }),
260
+ receiveSlots: [fakeWcmeSlots[4]],
261
+ codecInfos: [
262
+ sinon.match({
263
+ payloadType: 0x80,
264
+ h264: sinon.match({
265
+ maxFs: 8192,
266
+ maxFps: 2500,
267
+ maxMbps: 204800,
268
+ }),
269
+ }),
270
+ ],
271
+ }),
272
+ ]);
273
+ });
274
+
275
+ it('keeps adding requests with every call to addRequest()', () => {
276
+ // start with 1 request
277
+ addReceiverSelectedRequest(100, fakeReceiveSlots[0], true);
278
+
279
+ checkMediaRequestsSent([
280
+ {policy: 'receiver-selected', csi: 100, receiveSlot: fakeWcmeSlots[0]},
281
+ ]);
282
+
283
+ // now add another one
284
+ addReceiverSelectedRequest(101, fakeReceiveSlots[1], true);
285
+
286
+ checkMediaRequestsSent([
287
+ {policy: 'receiver-selected', csi: 100, receiveSlot: fakeWcmeSlots[0]},
288
+ {policy: 'receiver-selected', csi: 101, receiveSlot: fakeWcmeSlots[1]},
289
+ ]);
290
+
291
+ // and one more
292
+ addActiveSpeakerRequest(
293
+ 1,
294
+ [fakeReceiveSlots[2], fakeReceiveSlots[3], fakeReceiveSlots[4]],
295
+ true
296
+ );
297
+
298
+ checkMediaRequestsSent([
299
+ {policy: 'receiver-selected', csi: 100, receiveSlot: fakeWcmeSlots[0]},
300
+ {policy: 'receiver-selected', csi: 101, receiveSlot: fakeWcmeSlots[1]},
301
+ {
302
+ policy: 'active-speaker',
303
+ priority: 1,
304
+ receiveSlots: [fakeWcmeSlots[2], fakeWcmeSlots[3], fakeWcmeSlots[4]],
305
+ },
306
+ ]);
307
+ });
308
+
309
+ it('cancels the requests correctly when cancelRequest() is called with commit=true', () => {
310
+ const requestIds = [
311
+ addActiveSpeakerRequest(255, [fakeReceiveSlots[0], fakeReceiveSlots[1]]),
312
+ addActiveSpeakerRequest(255, [fakeReceiveSlots[2], fakeReceiveSlots[3]]),
313
+ addReceiverSelectedRequest(100, fakeReceiveSlots[4]),
314
+ addReceiverSelectedRequest(200, fakeReceiveSlots[5]),
315
+ ];
316
+
317
+ // cancel one of the active speaker requests
318
+ mediaRequestManager.cancelRequest(requestIds[1], true);
319
+
320
+ // expect only the 3 remaining requests to be sent out
321
+ checkMediaRequestsSent([
322
+ {policy: 'active-speaker', priority: 255, receiveSlots: [fakeWcmeSlots[0], fakeWcmeSlots[1]]},
323
+ {policy: 'receiver-selected', csi: 100, receiveSlot: fakeWcmeSlots[4]},
324
+ {policy: 'receiver-selected', csi: 200, receiveSlot: fakeWcmeSlots[5]},
325
+ ]);
326
+
327
+ // cancel one of the receiver selected requests
328
+ mediaRequestManager.cancelRequest(requestIds[3], true);
329
+
330
+ // expect only the 2 remaining requests to be sent out
331
+ checkMediaRequestsSent([
332
+ {policy: 'active-speaker', priority: 255, receiveSlots: [fakeWcmeSlots[0], fakeWcmeSlots[1]]},
333
+ {policy: 'receiver-selected', csi: 100, receiveSlot: fakeWcmeSlots[4]},
334
+ ]);
335
+ });
336
+
337
+ it('does not send out anything if addRequest() is called with commit=false', () => {
338
+ addActiveSpeakerRequest(
339
+ 10,
340
+ [fakeReceiveSlots[0], fakeReceiveSlots[1], fakeReceiveSlots[2]],
341
+ false
342
+ );
343
+ addReceiverSelectedRequest(123, fakeReceiveSlots[3], false);
344
+
345
+ // nothing should be sent out as we didn't commit the requests
346
+ assert.notCalled(sendMediaRequestsCallback);
347
+
348
+ // now do the commit
349
+ mediaRequestManager.commit();
350
+
351
+ // check that the 2 requests have been sent out
352
+ checkMediaRequestsSent([
353
+ {
354
+ policy: 'active-speaker',
355
+ priority: 10,
356
+ receiveSlots: [fakeWcmeSlots[0], fakeWcmeSlots[1], fakeWcmeSlots[2]],
357
+ },
358
+ {policy: 'receiver-selected', csi: 123, receiveSlot: fakeWcmeSlots[3]},
359
+ ]);
360
+ });
361
+
362
+ it('does not send out anything if cancelRequest() is called with commit=false', () => {
363
+ // send 4 requests
364
+ const requestIds = [
365
+ addActiveSpeakerRequest(
366
+ 250,
367
+ [fakeReceiveSlots[0], fakeReceiveSlots[1], fakeReceiveSlots[2]],
368
+ false
369
+ ),
370
+ addReceiverSelectedRequest(98765, fakeReceiveSlots[3], false),
371
+ addReceiverSelectedRequest(99999, fakeReceiveSlots[4], false),
372
+ addReceiverSelectedRequest(88888, fakeReceiveSlots[5], true),
373
+ ];
374
+
375
+ checkMediaRequestsSent([
376
+ {
377
+ policy: 'active-speaker',
378
+ priority: 250,
379
+ receiveSlots: [fakeWcmeSlots[0], fakeWcmeSlots[1], fakeWcmeSlots[2]],
380
+ },
381
+ {policy: 'receiver-selected', csi: 98765, receiveSlot: fakeWcmeSlots[3]},
382
+ {policy: 'receiver-selected', csi: 99999, receiveSlot: fakeWcmeSlots[4]},
383
+ {policy: 'receiver-selected', csi: 88888, receiveSlot: fakeWcmeSlots[5]},
384
+ ]);
385
+
386
+ // now cancel 3 of them, but with commit=false => nothing should happen
387
+ mediaRequestManager.cancelRequest(requestIds[0], false);
388
+ mediaRequestManager.cancelRequest(requestIds[2], false);
389
+ mediaRequestManager.cancelRequest(requestIds[3], false);
390
+
391
+ assert.notCalled(sendMediaRequestsCallback);
392
+
393
+ // now do the commit
394
+ mediaRequestManager.commit();
395
+
396
+ checkMediaRequestsSent([
397
+ {policy: 'receiver-selected', csi: 98765, receiveSlot: fakeWcmeSlots[3]},
398
+ ]);
399
+ });
400
+
401
+ it('sends the wcme media requests when commit() is called', () => {
402
+ // send some requests, all of them with commit=false
403
+ addReceiverSelectedRequest(123000, fakeReceiveSlots[0], false);
404
+ addReceiverSelectedRequest(456000, fakeReceiveSlots[1], false);
405
+ addActiveSpeakerRequest(
406
+ 255,
407
+ [fakeReceiveSlots[2], fakeReceiveSlots[3], fakeReceiveSlots[4]],
408
+ false
409
+ );
410
+ addActiveSpeakerRequest(
411
+ 254,
412
+ [fakeReceiveSlots[5], fakeReceiveSlots[6], fakeReceiveSlots[7]],
413
+ false
414
+ );
415
+
416
+ // nothing should be sent out as we didn't commit the requests
417
+ assert.notCalled(sendMediaRequestsCallback);
418
+
419
+ // now do the commit
420
+ mediaRequestManager.commit();
421
+
422
+ // check that all requests have been sent out
423
+ checkMediaRequestsSent([
424
+ {policy: 'receiver-selected', csi: 123000, receiveSlot: fakeWcmeSlots[0]},
425
+ {policy: 'receiver-selected', csi: 456000, receiveSlot: fakeWcmeSlots[1]},
426
+ {
427
+ policy: 'active-speaker',
428
+ priority: 255,
429
+ receiveSlots: [fakeWcmeSlots[2], fakeWcmeSlots[3], fakeWcmeSlots[4]],
430
+ },
431
+ {
432
+ policy: 'active-speaker',
433
+ priority: 254,
434
+ receiveSlots: [fakeWcmeSlots[5], fakeWcmeSlots[6], fakeWcmeSlots[7]],
435
+ },
436
+ ]);
437
+ });
438
+
439
+ it('clears all the requests on reset()', () => {
440
+ // send some requests and commit them one by one
441
+ addReceiverSelectedRequest(1500, fakeReceiveSlots[0], true);
442
+ addReceiverSelectedRequest(1501, fakeReceiveSlots[1], true);
443
+ addActiveSpeakerRequest(
444
+ 255,
445
+ [fakeReceiveSlots[2], fakeReceiveSlots[3], fakeReceiveSlots[4]],
446
+ true
447
+ );
448
+ addActiveSpeakerRequest(
449
+ 254,
450
+ [fakeReceiveSlots[5], fakeReceiveSlots[6], fakeReceiveSlots[7]],
451
+ true
452
+ );
453
+
454
+ sendMediaRequestsCallback.resetHistory();
455
+
456
+ // check that when calling commit() all requests are re-sent again
457
+ mediaRequestManager.commit();
458
+
459
+ checkMediaRequestsSent([
460
+ {policy: 'receiver-selected', csi: 1500, receiveSlot: fakeWcmeSlots[0]},
461
+ {policy: 'receiver-selected', csi: 1501, receiveSlot: fakeWcmeSlots[1]},
462
+ {
463
+ policy: 'active-speaker',
464
+ priority: 255,
465
+ receiveSlots: [fakeWcmeSlots[2], fakeWcmeSlots[3], fakeWcmeSlots[4]],
466
+ },
467
+ {
468
+ policy: 'active-speaker',
469
+ priority: 254,
470
+ receiveSlots: [fakeWcmeSlots[5], fakeWcmeSlots[6], fakeWcmeSlots[7]],
471
+ },
472
+ ]);
473
+
474
+ // now reset everything
475
+ mediaRequestManager.reset();
476
+
477
+ // calling commit now should not cause any requests to be sent out
478
+ mediaRequestManager.commit();
479
+ checkMediaRequestsSent([]);
480
+ });
481
+
482
+ it('calls resetSourceState() on slots that are stopped being used', () => {
483
+ const requestIds = [
484
+ addActiveSpeakerRequest(255, [fakeReceiveSlots[0], fakeReceiveSlots[1]]),
485
+ addActiveSpeakerRequest(255, [fakeReceiveSlots[2], fakeReceiveSlots[3]]),
486
+ addReceiverSelectedRequest(100, fakeReceiveSlots[4]),
487
+ addReceiverSelectedRequest(200, fakeReceiveSlots[5]),
488
+ ];
489
+
490
+ mediaRequestManager.commit();
491
+ checkMediaRequestsSent([
492
+ {policy: 'active-speaker', priority: 255, receiveSlots: [fakeWcmeSlots[0], fakeWcmeSlots[1]]},
493
+ {policy: 'active-speaker', priority: 255, receiveSlots: [fakeWcmeSlots[2], fakeWcmeSlots[3]]},
494
+ {policy: 'receiver-selected', csi: 100, receiveSlot: fakeWcmeSlots[4]},
495
+ {policy: 'receiver-selected', csi: 200, receiveSlot: fakeWcmeSlots[5]},
496
+ ]);
497
+
498
+ // cancel 2 of the requests
499
+ mediaRequestManager.cancelRequest(requestIds[1], false);
500
+ mediaRequestManager.cancelRequest(requestIds[3], false);
501
+
502
+ mediaRequestManager.commit();
503
+
504
+ // expect only the 2 remaining requests to be sent out
505
+ checkMediaRequestsSent([
506
+ {policy: 'active-speaker', priority: 255, receiveSlots: [fakeWcmeSlots[0], fakeWcmeSlots[1]]},
507
+ {policy: 'receiver-selected', csi: 100, receiveSlot: fakeWcmeSlots[4]},
508
+ ]);
509
+
510
+ // and that the receive slots of the 2 cancelled ones had resetSourceState() called
511
+ assert.calledOnce(fakeReceiveSlots[2].resetSourceState);
512
+ assert.calledOnce(fakeReceiveSlots[3].resetSourceState);
513
+ assert.calledOnce(fakeReceiveSlots[5].resetSourceState);
514
+ });
515
+ });
@@ -0,0 +1,104 @@
1
+ /* eslint-disable require-jsdoc */
2
+ import EventEmitter from 'events';
3
+
4
+ import {MediaConnection as MC} from '@webex/internal-media-core';
5
+ import {ReceiveSlot, ReceiveSlotEvents} from '@webex/plugin-meetings/src/multistream/receiveSlot';
6
+ import sinon from 'sinon';
7
+ import {assert} from '@webex/test-helper-chai';
8
+
9
+ class FakeWcmeSlot extends EventEmitter {
10
+ public stream;
11
+
12
+ constructor(stream) {
13
+ super();
14
+ this.stream = stream;
15
+ }
16
+ }
17
+
18
+ describe('ReceiveSlot', () => {
19
+ let receiveSlot;
20
+ let fakeWcmeSlot;
21
+ let findMemberIdCallbackStub;
22
+ let fakeStream;
23
+
24
+ beforeEach(() => {
25
+ fakeStream = {id: 'fake stream'};
26
+ fakeWcmeSlot = new FakeWcmeSlot(fakeStream);
27
+ findMemberIdCallbackStub = sinon.stub();
28
+ receiveSlot = new ReceiveSlot(MC.MediaType.VideoMain, fakeWcmeSlot, findMemberIdCallbackStub);
29
+ });
30
+
31
+ describe('forwards events from underlying wcme receive slot', () => {
32
+ it('forwards SourceUpdate', () => {
33
+ let eventEmitted = false;
34
+ let eventData;
35
+
36
+ const csi = 10203040;
37
+ const fakeMemberId = '12345678-1234-5678-9012-345678901234';
38
+
39
+ findMemberIdCallbackStub.returns(fakeMemberId);
40
+
41
+ receiveSlot.on(ReceiveSlotEvents.SourceUpdate, (data) => {
42
+ eventEmitted = true;
43
+ eventData = data;
44
+ });
45
+
46
+ fakeWcmeSlot.emit(MC.ReceiveSlotEvents.SourceUpdate, 'live', csi);
47
+
48
+ assert.strictEqual(eventEmitted, true);
49
+ assert.deepEqual(eventData, {
50
+ state: 'live',
51
+ csi,
52
+ memberId: fakeMemberId,
53
+ });
54
+ assert.calledOnce(findMemberIdCallbackStub);
55
+ assert.calledWith(findMemberIdCallbackStub, csi);
56
+ });
57
+ });
58
+
59
+ it('has public properties', () => {
60
+ assert.strictEqual(receiveSlot.id, 'r1');
61
+ assert.strictEqual(receiveSlot.mediaType, MC.MediaType.VideoMain);
62
+ });
63
+
64
+ it("exposes underlying wcme receive slot's properties", () => {
65
+ assert.strictEqual(receiveSlot.stream, fakeStream);
66
+ assert.strictEqual(receiveSlot.wcmeReceiveSlot, fakeWcmeSlot);
67
+ });
68
+
69
+ it("caches some underlying wcme receive slot's properties", () => {
70
+ assert.strictEqual(receiveSlot.memberId, undefined);
71
+ assert.strictEqual(receiveSlot.csi, undefined);
72
+ assert.strictEqual(receiveSlot.sourceState, 'no source');
73
+
74
+ const csi = 987654321;
75
+ const fakeMemberId = '00000001-1234-5678-9012-345678901234';
76
+
77
+ findMemberIdCallbackStub.returns(fakeMemberId);
78
+
79
+ fakeWcmeSlot.emit(MC.ReceiveSlotEvents.SourceUpdate, 'live', csi);
80
+
81
+ assert.strictEqual(receiveSlot.memberId, fakeMemberId);
82
+ assert.strictEqual(receiveSlot.csi, csi);
83
+ assert.strictEqual(receiveSlot.sourceState, 'live');
84
+ });
85
+
86
+ it('resets source related properties when resetSourceState() is called', () => {
87
+ const csi = 123456;
88
+ const fakeMemberId = '00000001-5555-6666-9012-345678901234';
89
+
90
+ findMemberIdCallbackStub.returns(fakeMemberId);
91
+
92
+ fakeWcmeSlot.emit(MC.ReceiveSlotEvents.SourceUpdate, 'live', csi);
93
+
94
+ assert.strictEqual(receiveSlot.memberId, fakeMemberId);
95
+ assert.strictEqual(receiveSlot.csi, csi);
96
+ assert.strictEqual(receiveSlot.sourceState, 'live');
97
+
98
+ receiveSlot.resetSourceState();
99
+
100
+ assert.strictEqual(receiveSlot.memberId, undefined);
101
+ assert.strictEqual(receiveSlot.csi, undefined);
102
+ assert.strictEqual(receiveSlot.sourceState, 'no source');
103
+ });
104
+ });