@webex/plugin-meetings 3.0.0-beta.17 → 3.0.0-beta.171

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 (427) hide show
  1. package/README.md +45 -7
  2. package/dist/annotation/annotation.types.js +7 -0
  3. package/dist/annotation/annotation.types.js.map +1 -0
  4. package/dist/annotation/constants.js +49 -0
  5. package/dist/annotation/constants.js.map +1 -0
  6. package/dist/annotation/index.js +359 -0
  7. package/dist/annotation/index.js.map +1 -0
  8. package/dist/breakouts/breakout.js +216 -0
  9. package/dist/breakouts/breakout.js.map +1 -0
  10. package/dist/breakouts/collection.js +23 -0
  11. package/dist/breakouts/collection.js.map +1 -0
  12. package/dist/breakouts/edit-lock-error.js +52 -0
  13. package/dist/breakouts/edit-lock-error.js.map +1 -0
  14. package/dist/breakouts/events.js +45 -0
  15. package/dist/breakouts/events.js.map +1 -0
  16. package/dist/breakouts/index.js +1048 -0
  17. package/dist/breakouts/index.js.map +1 -0
  18. package/dist/breakouts/request.js +78 -0
  19. package/dist/breakouts/request.js.map +1 -0
  20. package/dist/breakouts/utils.js +67 -0
  21. package/dist/breakouts/utils.js.map +1 -0
  22. package/dist/common/errors/webex-errors.js +3 -2
  23. package/dist/common/errors/webex-errors.js.map +1 -1
  24. package/dist/common/logs/logger-proxy.js +1 -1
  25. package/dist/common/logs/logger-proxy.js.map +1 -1
  26. package/dist/config.js +6 -8
  27. package/dist/config.js.map +1 -1
  28. package/dist/constants.js +194 -28
  29. package/dist/constants.js.map +1 -1
  30. package/dist/controls-options-manager/constants.js +14 -0
  31. package/dist/controls-options-manager/constants.js.map +1 -0
  32. package/dist/controls-options-manager/enums.js +27 -0
  33. package/dist/controls-options-manager/enums.js.map +1 -0
  34. package/dist/controls-options-manager/index.js +297 -0
  35. package/dist/controls-options-manager/index.js.map +1 -0
  36. package/dist/controls-options-manager/types.js +7 -0
  37. package/dist/controls-options-manager/types.js.map +1 -0
  38. package/dist/controls-options-manager/util.js +300 -0
  39. package/dist/controls-options-manager/util.js.map +1 -0
  40. package/dist/index.js +107 -0
  41. package/dist/index.js.map +1 -1
  42. package/dist/interpretation/collection.js +23 -0
  43. package/dist/interpretation/collection.js.map +1 -0
  44. package/dist/interpretation/index.js +214 -0
  45. package/dist/interpretation/index.js.map +1 -0
  46. package/dist/interpretation/siLanguage.js +25 -0
  47. package/dist/interpretation/siLanguage.js.map +1 -0
  48. package/dist/locus-info/controlsUtils.js +92 -2
  49. package/dist/locus-info/controlsUtils.js.map +1 -1
  50. package/dist/locus-info/index.js +350 -41
  51. package/dist/locus-info/index.js.map +1 -1
  52. package/dist/locus-info/mediaSharesUtils.js +43 -1
  53. package/dist/locus-info/mediaSharesUtils.js.map +1 -1
  54. package/dist/locus-info/parser.js +2 -1
  55. package/dist/locus-info/parser.js.map +1 -1
  56. package/dist/locus-info/selfUtils.js +97 -14
  57. package/dist/locus-info/selfUtils.js.map +1 -1
  58. package/dist/media/index.js +41 -136
  59. package/dist/media/index.js.map +1 -1
  60. package/dist/media/properties.js +33 -94
  61. package/dist/media/properties.js.map +1 -1
  62. package/dist/mediaQualityMetrics/config.js +505 -493
  63. package/dist/mediaQualityMetrics/config.js.map +1 -1
  64. package/dist/meeting/in-meeting-actions.js +76 -2
  65. package/dist/meeting/in-meeting-actions.js.map +1 -1
  66. package/dist/meeting/index.js +2757 -2439
  67. package/dist/meeting/index.js.map +1 -1
  68. package/dist/meeting/locusMediaRequest.js +291 -0
  69. package/dist/meeting/locusMediaRequest.js.map +1 -0
  70. package/dist/meeting/muteState.js +229 -124
  71. package/dist/meeting/muteState.js.map +1 -1
  72. package/dist/meeting/request.js +191 -167
  73. package/dist/meeting/request.js.map +1 -1
  74. package/dist/meeting/request.type.js.map +1 -1
  75. package/dist/meeting/util.js +477 -466
  76. package/dist/meeting/util.js.map +1 -1
  77. package/dist/meeting-info/index.js +48 -7
  78. package/dist/meeting-info/index.js.map +1 -1
  79. package/dist/meeting-info/meeting-info-v2.js +172 -50
  80. package/dist/meeting-info/meeting-info-v2.js.map +1 -1
  81. package/dist/meeting-info/utilv2.js +20 -5
  82. package/dist/meeting-info/utilv2.js.map +1 -1
  83. package/dist/meetings/collection.js +22 -0
  84. package/dist/meetings/collection.js.map +1 -1
  85. package/dist/meetings/index.js +377 -82
  86. package/dist/meetings/index.js.map +1 -1
  87. package/dist/meetings/meetings.types.js +7 -0
  88. package/dist/meetings/meetings.types.js.map +1 -0
  89. package/dist/meetings/request.js +16 -12
  90. package/dist/meetings/request.js.map +1 -1
  91. package/dist/meetings/util.js +88 -1
  92. package/dist/meetings/util.js.map +1 -1
  93. package/dist/member/index.js +43 -0
  94. package/dist/member/index.js.map +1 -1
  95. package/dist/member/types.js +15 -0
  96. package/dist/member/types.js.map +1 -0
  97. package/dist/member/util.js +97 -3
  98. package/dist/member/util.js.map +1 -1
  99. package/dist/members/collection.js +10 -0
  100. package/dist/members/collection.js.map +1 -1
  101. package/dist/members/index.js +94 -11
  102. package/dist/members/index.js.map +1 -1
  103. package/dist/members/request.js +109 -39
  104. package/dist/members/request.js.map +1 -1
  105. package/dist/members/types.js +15 -0
  106. package/dist/members/types.js.map +1 -0
  107. package/dist/members/util.js +316 -233
  108. package/dist/members/util.js.map +1 -1
  109. package/dist/metrics/constants.js +3 -5
  110. package/dist/metrics/constants.js.map +1 -1
  111. package/dist/metrics/index.js +1 -468
  112. package/dist/metrics/index.js.map +1 -1
  113. package/dist/multistream/mediaRequestManager.js +265 -36
  114. package/dist/multistream/mediaRequestManager.js.map +1 -1
  115. package/dist/multistream/receiveSlot.js +52 -19
  116. package/dist/multistream/receiveSlot.js.map +1 -1
  117. package/dist/multistream/receiveSlotManager.js +53 -33
  118. package/dist/multistream/receiveSlotManager.js.map +1 -1
  119. package/dist/multistream/remoteMedia.js +44 -18
  120. package/dist/multistream/remoteMedia.js.map +1 -1
  121. package/dist/multistream/remoteMediaGroup.js +60 -3
  122. package/dist/multistream/remoteMediaGroup.js.map +1 -1
  123. package/dist/multistream/remoteMediaManager.js +322 -103
  124. package/dist/multistream/remoteMediaManager.js.map +1 -1
  125. package/dist/networkQualityMonitor/index.js +4 -2
  126. package/dist/networkQualityMonitor/index.js.map +1 -1
  127. package/dist/reachability/index.js +117 -60
  128. package/dist/reachability/index.js.map +1 -1
  129. package/dist/reachability/request.js +12 -5
  130. package/dist/reachability/request.js.map +1 -1
  131. package/dist/reactions/constants.js +13 -0
  132. package/dist/reactions/constants.js.map +1 -0
  133. package/dist/reactions/reactions.js +2 -2
  134. package/dist/reactions/reactions.js.map +1 -1
  135. package/dist/reactions/reactions.type.js +18 -18
  136. package/dist/reactions/reactions.type.js.map +1 -1
  137. package/dist/reconnection-manager/index.js +216 -162
  138. package/dist/reconnection-manager/index.js.map +1 -1
  139. package/dist/recording-controller/enums.js +17 -0
  140. package/dist/recording-controller/enums.js.map +1 -0
  141. package/dist/recording-controller/index.js +363 -0
  142. package/dist/recording-controller/index.js.map +1 -0
  143. package/dist/recording-controller/util.js +64 -0
  144. package/dist/recording-controller/util.js.map +1 -0
  145. package/dist/roap/index.js +21 -29
  146. package/dist/roap/index.js.map +1 -1
  147. package/dist/roap/request.js +135 -94
  148. package/dist/roap/request.js.map +1 -1
  149. package/dist/roap/turnDiscovery.js +135 -53
  150. package/dist/roap/turnDiscovery.js.map +1 -1
  151. package/dist/statsAnalyzer/global.js +1 -93
  152. package/dist/statsAnalyzer/global.js.map +1 -1
  153. package/dist/statsAnalyzer/index.js +329 -314
  154. package/dist/statsAnalyzer/index.js.map +1 -1
  155. package/dist/statsAnalyzer/mqaUtil.js +103 -54
  156. package/dist/statsAnalyzer/mqaUtil.js.map +1 -1
  157. package/dist/types/annotation/annotation.types.d.ts +43 -0
  158. package/dist/types/annotation/constants.d.ts +31 -0
  159. package/dist/types/annotation/index.d.ts +124 -0
  160. package/dist/types/breakouts/breakout.d.ts +8 -0
  161. package/dist/types/breakouts/collection.d.ts +5 -0
  162. package/dist/types/breakouts/edit-lock-error.d.ts +15 -0
  163. package/dist/types/breakouts/events.d.ts +8 -0
  164. package/dist/types/breakouts/index.d.ts +5 -0
  165. package/dist/types/breakouts/request.d.ts +22 -0
  166. package/dist/types/breakouts/utils.d.ts +15 -0
  167. package/dist/types/common/browser-detection.d.ts +9 -0
  168. package/dist/types/common/collection.d.ts +48 -0
  169. package/dist/types/common/config.d.ts +2 -0
  170. package/dist/types/common/errors/captcha-error.d.ts +15 -0
  171. package/dist/types/common/errors/intent-to-join.d.ts +16 -0
  172. package/dist/types/common/errors/join-meeting.d.ts +17 -0
  173. package/dist/types/common/errors/media.d.ts +15 -0
  174. package/dist/types/common/errors/parameter.d.ts +15 -0
  175. package/dist/types/common/errors/password-error.d.ts +15 -0
  176. package/dist/types/common/errors/permission.d.ts +14 -0
  177. package/dist/types/common/errors/reconnection-in-progress.d.ts +9 -0
  178. package/dist/types/common/errors/reconnection.d.ts +15 -0
  179. package/dist/types/common/errors/stats.d.ts +15 -0
  180. package/dist/types/common/errors/webex-errors.d.ts +69 -0
  181. package/dist/types/common/errors/webex-meetings-error.d.ts +20 -0
  182. package/dist/types/common/events/events-scope.d.ts +17 -0
  183. package/dist/types/common/events/events.d.ts +12 -0
  184. package/dist/types/common/events/trigger-proxy.d.ts +2 -0
  185. package/dist/types/common/events/util.d.ts +2 -0
  186. package/dist/types/common/logs/logger-config.d.ts +2 -0
  187. package/dist/types/common/logs/logger-proxy.d.ts +2 -0
  188. package/dist/types/common/logs/request.d.ts +34 -0
  189. package/dist/types/common/queue.d.ts +32 -0
  190. package/dist/types/config.d.ts +72 -0
  191. package/dist/types/constants.d.ts +1007 -0
  192. package/dist/types/controls-options-manager/constants.d.ts +4 -0
  193. package/dist/types/controls-options-manager/enums.d.ts +15 -0
  194. package/dist/types/controls-options-manager/index.d.ts +136 -0
  195. package/dist/types/controls-options-manager/types.d.ts +43 -0
  196. package/dist/types/controls-options-manager/util.d.ts +1 -0
  197. package/dist/types/index.d.ts +7 -0
  198. package/dist/types/interpretation/collection.d.ts +5 -0
  199. package/dist/types/interpretation/index.d.ts +5 -0
  200. package/dist/types/interpretation/siLanguage.d.ts +5 -0
  201. package/dist/types/locus-info/controlsUtils.d.ts +2 -0
  202. package/dist/types/locus-info/embeddedAppsUtils.d.ts +2 -0
  203. package/dist/types/locus-info/fullState.d.ts +2 -0
  204. package/dist/types/locus-info/hostUtils.d.ts +2 -0
  205. package/dist/types/locus-info/index.d.ts +315 -0
  206. package/dist/types/locus-info/infoUtils.d.ts +2 -0
  207. package/dist/types/locus-info/mediaSharesUtils.d.ts +2 -0
  208. package/dist/types/locus-info/parser.d.ts +212 -0
  209. package/dist/types/locus-info/selfUtils.d.ts +2 -0
  210. package/dist/types/media/index.d.ts +34 -0
  211. package/dist/types/media/properties.d.ts +93 -0
  212. package/dist/types/media/util.d.ts +2 -0
  213. package/dist/types/mediaQualityMetrics/config.d.ts +365 -0
  214. package/dist/types/meeting/in-meeting-actions.d.ts +149 -0
  215. package/dist/types/meeting/index.d.ts +1462 -0
  216. package/dist/types/meeting/locusMediaRequest.d.ts +70 -0
  217. package/dist/types/meeting/muteState.d.ts +184 -0
  218. package/dist/types/meeting/request.d.ts +270 -0
  219. package/dist/types/meeting/request.type.d.ts +11 -0
  220. package/dist/types/meeting/state.d.ts +9 -0
  221. package/dist/types/meeting/util.d.ts +77 -0
  222. package/dist/types/meeting-info/collection.d.ts +20 -0
  223. package/dist/types/meeting-info/index.d.ts +62 -0
  224. package/dist/types/meeting-info/meeting-info-v2.d.ts +122 -0
  225. package/dist/types/meeting-info/request.d.ts +22 -0
  226. package/dist/types/meeting-info/util.d.ts +2 -0
  227. package/dist/types/meeting-info/utilv2.d.ts +2 -0
  228. package/dist/types/meetings/collection.d.ts +31 -0
  229. package/dist/types/meetings/index.d.ts +365 -0
  230. package/dist/types/meetings/meetings.types.d.ts +4 -0
  231. package/dist/types/meetings/request.d.ts +27 -0
  232. package/dist/types/meetings/util.d.ts +18 -0
  233. package/dist/types/member/index.d.ts +158 -0
  234. package/dist/types/member/types.d.ts +21 -0
  235. package/dist/types/member/util.d.ts +2 -0
  236. package/dist/types/members/collection.d.ts +29 -0
  237. package/dist/types/members/index.d.ts +353 -0
  238. package/dist/types/members/request.d.ts +114 -0
  239. package/dist/types/members/types.d.ts +24 -0
  240. package/dist/types/members/util.d.ts +210 -0
  241. package/dist/types/metrics/constants.d.ts +55 -0
  242. package/dist/types/metrics/index.d.ts +45 -0
  243. package/dist/types/multistream/mediaRequestManager.d.ts +118 -0
  244. package/dist/types/multistream/receiveSlot.d.ts +68 -0
  245. package/dist/types/multistream/receiveSlotManager.d.ts +56 -0
  246. package/dist/types/multistream/remoteMedia.d.ts +72 -0
  247. package/dist/types/multistream/remoteMediaGroup.d.ts +47 -0
  248. package/dist/types/multistream/remoteMediaManager.d.ts +277 -0
  249. package/dist/types/networkQualityMonitor/index.d.ts +70 -0
  250. package/dist/types/personal-meeting-room/index.d.ts +47 -0
  251. package/dist/types/personal-meeting-room/request.d.ts +14 -0
  252. package/dist/types/personal-meeting-room/util.d.ts +2 -0
  253. package/dist/types/reachability/index.d.ts +152 -0
  254. package/dist/types/reachability/request.d.ts +37 -0
  255. package/dist/types/reactions/constants.d.ts +3 -0
  256. package/dist/types/reactions/reactions.d.ts +4 -0
  257. package/dist/types/reactions/reactions.type.d.ts +52 -0
  258. package/dist/types/reconnection-manager/index.d.ts +126 -0
  259. package/dist/types/recording-controller/enums.d.ts +7 -0
  260. package/dist/types/recording-controller/index.d.ts +208 -0
  261. package/dist/types/recording-controller/util.d.ts +14 -0
  262. package/dist/types/roap/index.d.ts +77 -0
  263. package/dist/types/roap/request.d.ts +36 -0
  264. package/dist/types/roap/turnDiscovery.d.ts +91 -0
  265. package/dist/types/statsAnalyzer/global.d.ts +36 -0
  266. package/dist/types/statsAnalyzer/index.d.ts +200 -0
  267. package/dist/types/statsAnalyzer/mqaUtil.d.ts +24 -0
  268. package/dist/types/transcription/index.d.ts +64 -0
  269. package/package.json +29 -21
  270. package/src/annotation/annotation.types.ts +52 -0
  271. package/src/annotation/constants.ts +36 -0
  272. package/src/annotation/index.ts +343 -0
  273. package/src/breakouts/README.md +220 -0
  274. package/src/breakouts/breakout.ts +188 -0
  275. package/src/breakouts/collection.ts +19 -0
  276. package/src/breakouts/edit-lock-error.ts +25 -0
  277. package/src/breakouts/events.ts +56 -0
  278. package/src/breakouts/index.ts +925 -0
  279. package/src/breakouts/request.ts +55 -0
  280. package/src/breakouts/utils.ts +57 -0
  281. package/src/common/errors/webex-errors.ts +6 -2
  282. package/src/common/logs/logger-proxy.ts +1 -1
  283. package/src/config.ts +5 -7
  284. package/src/constants.ts +183 -22
  285. package/src/controls-options-manager/constants.ts +5 -0
  286. package/src/controls-options-manager/enums.ts +18 -0
  287. package/src/controls-options-manager/index.ts +278 -0
  288. package/src/controls-options-manager/types.ts +59 -0
  289. package/src/controls-options-manager/util.ts +286 -0
  290. package/src/index.ts +39 -0
  291. package/src/interpretation/README.md +51 -0
  292. package/src/interpretation/collection.ts +19 -0
  293. package/src/interpretation/index.ts +182 -0
  294. package/src/interpretation/siLanguage.ts +18 -0
  295. package/src/locus-info/controlsUtils.ts +110 -0
  296. package/src/locus-info/index.ts +374 -38
  297. package/src/locus-info/mediaSharesUtils.ts +48 -0
  298. package/src/locus-info/parser.ts +2 -1
  299. package/src/locus-info/selfUtils.ts +86 -2
  300. package/src/media/index.ts +78 -144
  301. package/src/media/properties.ts +55 -99
  302. package/src/mediaQualityMetrics/config.ts +379 -377
  303. package/src/meeting/in-meeting-actions.ts +151 -3
  304. package/src/meeting/index.ts +2181 -2052
  305. package/src/meeting/locusMediaRequest.ts +309 -0
  306. package/src/meeting/muteState.ts +228 -132
  307. package/src/meeting/request.ts +100 -91
  308. package/src/meeting/request.type.ts +2 -0
  309. package/src/meeting/util.ts +450 -439
  310. package/src/meeting-info/index.ts +54 -8
  311. package/src/meeting-info/meeting-info-v2.ts +150 -14
  312. package/src/meeting-info/utilv2.ts +13 -3
  313. package/src/meetings/collection.ts +20 -0
  314. package/src/meetings/index.ts +396 -89
  315. package/src/meetings/meetings.types.ts +12 -0
  316. package/src/meetings/request.ts +3 -1
  317. package/src/meetings/util.ts +103 -4
  318. package/src/member/index.ts +42 -0
  319. package/src/member/types.ts +24 -0
  320. package/src/member/util.ts +95 -1
  321. package/src/members/collection.ts +8 -0
  322. package/src/members/index.ts +108 -6
  323. package/src/members/request.ts +98 -17
  324. package/src/members/types.ts +28 -0
  325. package/src/members/util.ts +319 -240
  326. package/src/metrics/constants.ts +2 -4
  327. package/src/metrics/index.ts +1 -490
  328. package/src/multistream/mediaRequestManager.ts +337 -63
  329. package/src/multistream/receiveSlot.ts +68 -26
  330. package/src/multistream/receiveSlotManager.ts +61 -38
  331. package/src/multistream/remoteMedia.ts +29 -3
  332. package/src/multistream/remoteMediaGroup.ts +61 -2
  333. package/src/multistream/remoteMediaManager.ts +260 -66
  334. package/src/networkQualityMonitor/index.ts +6 -6
  335. package/src/reachability/index.ts +75 -25
  336. package/src/reachability/request.ts +10 -5
  337. package/src/reactions/constants.ts +4 -0
  338. package/src/reactions/reactions.ts +4 -4
  339. package/src/reactions/reactions.type.ts +28 -3
  340. package/src/reconnection-manager/index.ts +83 -49
  341. package/src/recording-controller/enums.ts +8 -0
  342. package/src/recording-controller/index.ts +333 -0
  343. package/src/recording-controller/util.ts +75 -0
  344. package/src/roap/index.ts +21 -30
  345. package/src/roap/request.ts +72 -61
  346. package/src/roap/turnDiscovery.ts +51 -27
  347. package/src/statsAnalyzer/global.ts +1 -94
  348. package/src/statsAnalyzer/index.ts +380 -390
  349. package/src/statsAnalyzer/mqaUtil.ts +106 -99
  350. package/test/integration/spec/converged-space-meetings.js +233 -0
  351. package/test/integration/spec/journey.js +336 -259
  352. package/test/integration/spec/space-meeting.js +77 -4
  353. package/test/unit/spec/annotation/index.ts +436 -0
  354. package/test/unit/spec/breakouts/breakout.ts +237 -0
  355. package/test/unit/spec/breakouts/collection.ts +15 -0
  356. package/test/unit/spec/breakouts/edit-lock-error.ts +30 -0
  357. package/test/unit/spec/breakouts/events.ts +89 -0
  358. package/test/unit/spec/breakouts/index.ts +1790 -0
  359. package/test/unit/spec/breakouts/request.ts +104 -0
  360. package/test/unit/spec/breakouts/utils.js +72 -0
  361. package/test/unit/spec/controls-options-manager/index.js +287 -0
  362. package/test/unit/spec/controls-options-manager/util.js +518 -0
  363. package/test/unit/spec/fixture/locus.js +1 -0
  364. package/test/unit/spec/interpretation/collection.ts +15 -0
  365. package/test/unit/spec/interpretation/index.ts +329 -0
  366. package/test/unit/spec/interpretation/siLanguage.ts +26 -0
  367. package/test/unit/spec/locus-info/controlsUtils.js +323 -30
  368. package/test/unit/spec/locus-info/index.js +792 -4
  369. package/test/unit/spec/locus-info/mediaSharesUtils.ts +22 -0
  370. package/test/unit/spec/locus-info/selfConstant.js +48 -0
  371. package/test/unit/spec/locus-info/selfUtils.js +275 -0
  372. package/test/unit/spec/media/index.ts +130 -24
  373. package/test/unit/spec/media/properties.ts +9 -9
  374. package/test/unit/spec/meeting/in-meeting-actions.ts +75 -3
  375. package/test/unit/spec/meeting/index.js +2834 -1442
  376. package/test/unit/spec/meeting/locusMediaRequest.ts +436 -0
  377. package/test/unit/spec/meeting/muteState.js +370 -208
  378. package/test/unit/spec/meeting/request.js +354 -42
  379. package/test/unit/spec/meeting/utils.js +384 -170
  380. package/test/unit/spec/meeting-info/index.js +181 -0
  381. package/test/unit/spec/meeting-info/meetinginfov2.js +383 -5
  382. package/test/unit/spec/meeting-info/utilv2.js +21 -0
  383. package/test/unit/spec/meetings/collection.js +14 -0
  384. package/test/unit/spec/meetings/index.js +847 -121
  385. package/test/unit/spec/meetings/utils.js +206 -2
  386. package/test/unit/spec/member/index.js +31 -0
  387. package/test/unit/spec/member/util.js +408 -32
  388. package/test/unit/spec/members/index.js +320 -1
  389. package/test/unit/spec/members/request.js +206 -27
  390. package/test/unit/spec/members/utils.js +184 -0
  391. package/test/unit/spec/metrics/index.js +1 -50
  392. package/test/unit/spec/multistream/mediaRequestManager.ts +1012 -109
  393. package/test/unit/spec/multistream/receiveSlot.ts +77 -18
  394. package/test/unit/spec/multistream/receiveSlotManager.ts +69 -39
  395. package/test/unit/spec/multistream/remoteMedia.ts +32 -2
  396. package/test/unit/spec/multistream/remoteMediaGroup.ts +271 -5
  397. package/test/unit/spec/multistream/remoteMediaManager.ts +672 -65
  398. package/test/unit/spec/networkQualityMonitor/index.js +4 -4
  399. package/test/unit/spec/reachability/index.ts +176 -25
  400. package/test/unit/spec/reachability/request.js +66 -0
  401. package/test/unit/spec/reconnection-manager/index.js +95 -13
  402. package/test/unit/spec/recording-controller/index.js +307 -0
  403. package/test/unit/spec/recording-controller/util.js +229 -0
  404. package/test/unit/spec/roap/index.ts +28 -52
  405. package/test/unit/spec/roap/request.ts +225 -0
  406. package/test/unit/spec/roap/turnDiscovery.ts +73 -34
  407. package/test/unit/spec/stats-analyzer/index.js +94 -43
  408. package/test/utils/constants.js +9 -0
  409. package/test/utils/integrationTestUtils.js +46 -0
  410. package/test/utils/testUtils.js +0 -45
  411. package/test/utils/webex-config.js +4 -0
  412. package/test/utils/webex-test-users.js +7 -3
  413. package/tsconfig.json +6 -0
  414. package/dist/media/internal-media-core-wrapper.js +0 -18
  415. package/dist/media/internal-media-core-wrapper.js.map +0 -1
  416. package/dist/meeting/effectsState.js +0 -262
  417. package/dist/meeting/effectsState.js.map +0 -1
  418. package/dist/metrics/config.js +0 -299
  419. package/dist/metrics/config.js.map +0 -1
  420. package/dist/multistream/multistreamMedia.js +0 -106
  421. package/dist/multistream/multistreamMedia.js.map +0 -1
  422. package/src/index.js +0 -15
  423. package/src/media/internal-media-core-wrapper.ts +0 -9
  424. package/src/meeting/effectsState.ts +0 -211
  425. package/src/metrics/config.ts +0 -495
  426. package/src/multistream/multistreamMedia.ts +0 -93
  427. package/test/unit/spec/meeting/effectsState.js +0 -281
@@ -2,29 +2,48 @@ import {MediaRequestManager} from '@webex/plugin-meetings/src/multistream/mediaR
2
2
  import {ReceiveSlot} from '@webex/plugin-meetings/src/multistream/receiveSlot';
3
3
  import sinon from 'sinon';
4
4
  import {assert} from '@webex/test-helper-chai';
5
+ import {getMaxFs} from '@webex/plugin-meetings/src/multistream/remoteMedia';
6
+ import FakeTimers from '@sinonjs/fake-timers';
7
+ import * as mediaCore from '@webex/internal-media-core';
8
+ import { expect } from 'chai';
5
9
 
6
10
  type ExpectedActiveSpeaker = {
7
11
  policy: 'active-speaker';
12
+ maxPayloadBitsPerSecond?: number;
8
13
  priority: number;
9
14
  receiveSlots: Array<ReceiveSlot>;
15
+ maxFs?: number;
16
+ maxMbps?: number;
10
17
  };
11
18
  type ExpectedReceiverSelected = {
12
19
  policy: 'receiver-selected';
20
+ maxPayloadBitsPerSecond?: number;
13
21
  csi: number;
14
22
  receiveSlot: ReceiveSlot;
23
+ maxFs?: number;
24
+ maxMbps?: number;
15
25
  };
16
26
  type ExpectedRequest = ExpectedActiveSpeaker | ExpectedReceiverSelected;
17
27
 
18
- const maxPayloadBitsPerSecond = 10 * 1000 * 1000; // for now we always send this fixed constant
28
+ const degradationPreferences = {
29
+ maxMacroblocksLimit: Infinity, // no limit
30
+ };
19
31
 
20
32
  describe('MediaRequestManager', () => {
21
33
  const CROSS_PRIORITY_DUPLICATION = true;
22
34
  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;
35
+ const MAX_FPS = 3000;
36
+ const MAX_FS_360p = 920;
37
+ const MAX_FS_720p = 3600;
38
+ const MAX_FS_1080p = 8192;
39
+ const MAX_MBPS_360p = 27600;
40
+ const MAX_MBPS_720p = 108000;
41
+ const MAX_MBPS_1080p = 245760;
42
+ const MAX_PAYLOADBITSPS_360p = 640000;
43
+ const MAX_PAYLOADBITSPS_720p = 2500000;
44
+ const MAX_PAYLOADBITSPS_1080p = 4000000;
26
45
 
27
- const NUM_SLOTS = 10;
46
+ const NUM_SLOTS = 15;
28
47
 
29
48
  let mediaRequestManager: MediaRequestManager;
30
49
  let sendMediaRequestsCallback;
@@ -33,7 +52,11 @@ describe('MediaRequestManager', () => {
33
52
 
34
53
  beforeEach(() => {
35
54
  sendMediaRequestsCallback = sinon.stub();
36
- mediaRequestManager = new MediaRequestManager(sendMediaRequestsCallback);
55
+ mediaRequestManager = new MediaRequestManager(sendMediaRequestsCallback, {
56
+ degradationPreferences,
57
+ kind: 'video',
58
+ trimRequestsToNumOfSources: false,
59
+ });
37
60
 
38
61
  // create some fake receive slots used by the tests
39
62
  fakeWcmeSlots = Array(NUM_SLOTS)
@@ -48,14 +71,16 @@ describe('MediaRequestManager', () => {
48
71
  (_, index) =>
49
72
  ({
50
73
  id: `fake receive slot ${index}`,
74
+ on: sinon.stub(),
75
+ off: sinon.stub(),
76
+ sourceState: 'live',
51
77
  wcmeReceiveSlot: fakeWcmeSlots[index],
52
- resetSourceState: sinon.stub(),
53
78
  } as unknown as ReceiveSlot)
54
79
  );
55
80
  });
56
81
 
57
82
  // helper function for adding an active speaker request
58
- const addActiveSpeakerRequest = (priority, receiveSlots, commit = false) =>
83
+ const addActiveSpeakerRequest = (priority, receiveSlots, maxFs, commit = false, preferLiveVideo = true) =>
59
84
  mediaRequestManager.addRequest(
60
85
  {
61
86
  policyInfo: {
@@ -63,19 +88,19 @@ describe('MediaRequestManager', () => {
63
88
  priority,
64
89
  crossPriorityDuplication: CROSS_PRIORITY_DUPLICATION,
65
90
  crossPolicyDuplication: CROSS_POLICY_DUPLICATION,
66
- preferLiveVideo: PREFER_LIVE_VIDEO,
91
+ preferLiveVideo,
67
92
  },
68
93
  receiveSlots,
69
94
  codecInfo: {
70
95
  codec: 'h264',
71
- maxFs: ACTIVE_SPEAKER_MAX_FS,
96
+ maxFs: maxFs,
72
97
  },
73
98
  },
74
99
  commit
75
100
  );
76
101
 
77
102
  // helper function for adding a receiver selected request
78
- const addReceiverSelectedRequest = (csi, receiveSlot, commit = false) =>
103
+ const addReceiverSelectedRequest = (csi, receiveSlot, maxFs, commit = false) =>
79
104
  mediaRequestManager.addRequest(
80
105
  {
81
106
  policyInfo: {
@@ -85,7 +110,7 @@ describe('MediaRequestManager', () => {
85
110
  receiveSlots: [receiveSlot],
86
111
  codecInfo: {
87
112
  codec: 'h264',
88
- maxFs: RECEIVER_SELECTED_MAX_FS,
113
+ maxFs: maxFs,
89
114
  },
90
115
  },
91
116
  commit
@@ -96,7 +121,12 @@ describe('MediaRequestManager', () => {
96
121
  // It should be used only for verifying requests created with
97
122
  // addActiveSpeakerRequest() or addReceiverSelectedRequest(), because of some
98
123
  // hardcoded values used in them
99
- const checkMediaRequestsSent = (expectedRequests: ExpectedRequest[]) => {
124
+ const checkMediaRequestsSent = (
125
+ expectedRequests: ExpectedRequest[], {
126
+ isCodecInfoDefined = true,
127
+ preferLiveVideo = true,
128
+ } = {}
129
+ ) => {
100
130
  assert.calledOnce(sendMediaRequestsCallback);
101
131
  assert.calledWith(
102
132
  sendMediaRequestsCallback,
@@ -108,18 +138,21 @@ describe('MediaRequestManager', () => {
108
138
  priority: expectedRequest.priority,
109
139
  crossPriorityDuplication: CROSS_PRIORITY_DUPLICATION,
110
140
  crossPolicyDuplication: CROSS_POLICY_DUPLICATION,
111
- preferLiveVideo: PREFER_LIVE_VIDEO,
141
+ preferLiveVideo,
112
142
  }),
113
143
  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
- ],
144
+ maxPayloadBitsPerSecond: expectedRequest.maxPayloadBitsPerSecond,
145
+ codecInfos: isCodecInfoDefined
146
+ ? [
147
+ sinon.match({
148
+ payloadType: 0x80,
149
+ h264: sinon.match({
150
+ maxMbps: expectedRequest.maxMbps,
151
+ maxFs: expectedRequest.maxFs,
152
+ }),
153
+ }),
154
+ ]
155
+ : [],
123
156
  });
124
157
  }
125
158
  if (expectedRequest.policy === 'receiver-selected') {
@@ -129,15 +162,18 @@ describe('MediaRequestManager', () => {
129
162
  csi: expectedRequest.csi,
130
163
  }),
131
164
  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
- ],
165
+ maxPayloadBitsPerSecond: expectedRequest.maxPayloadBitsPerSecond,
166
+ codecInfos: isCodecInfoDefined
167
+ ? [
168
+ sinon.match({
169
+ payloadType: 0x80,
170
+ h264: sinon.match({
171
+ maxMbps: expectedRequest.maxMbps,
172
+ maxFs: expectedRequest.maxFs,
173
+ }),
174
+ }),
175
+ ]
176
+ : [],
141
177
  });
142
178
  }
143
179
 
@@ -171,8 +207,8 @@ describe('MediaRequestManager', () => {
171
207
  receiveSlots: [fakeReceiveSlots[0], fakeReceiveSlots[1], fakeReceiveSlots[2]],
172
208
  codecInfo: {
173
209
  codec: 'h264',
174
- maxFs: 1620,
175
- maxFps: 1500,
210
+ maxFs: MAX_FS_360p,
211
+ maxFps: MAX_FPS,
176
212
  },
177
213
  },
178
214
  false
@@ -186,9 +222,9 @@ describe('MediaRequestManager', () => {
186
222
  receiveSlots: [fakeReceiveSlots[3]],
187
223
  codecInfo: {
188
224
  codec: 'h264',
189
- maxFs: 3600,
190
- maxFps: 2500,
191
- maxMbps: 90000,
225
+ maxFs: MAX_FS_720p,
226
+ maxFps: MAX_FPS,
227
+ maxMbps: MAX_MBPS_720p,
192
228
  },
193
229
  },
194
230
  false
@@ -204,9 +240,9 @@ describe('MediaRequestManager', () => {
204
240
  receiveSlots: [fakeReceiveSlots[4]],
205
241
  codecInfo: {
206
242
  codec: 'h264',
207
- maxFs: 8192,
208
- maxFps: 2500,
209
- maxMbps: 204800,
243
+ maxFs: MAX_FS_1080p,
244
+ maxFps: MAX_FPS,
245
+ maxMbps: MAX_MBPS_1080p,
210
246
  },
211
247
  },
212
248
  true
@@ -224,13 +260,14 @@ describe('MediaRequestManager', () => {
224
260
  preferLiveVideo: false,
225
261
  }),
226
262
  receiveSlots: [fakeWcmeSlots[0], fakeWcmeSlots[1], fakeWcmeSlots[2]],
263
+ maxPayloadBitsPerSecond: MAX_PAYLOADBITSPS_360p,
227
264
  codecInfos: [
228
265
  sinon.match({
229
266
  payloadType: 0x80,
230
267
  h264: sinon.match({
231
- maxFs: 1620,
232
- maxFps: 1500,
233
- maxMbps: 245760,
268
+ maxFs: MAX_FS_360p,
269
+ maxFps: MAX_FPS,
270
+ maxMbps: MAX_MBPS_360p,
234
271
  }),
235
272
  }),
236
273
  ],
@@ -241,13 +278,14 @@ describe('MediaRequestManager', () => {
241
278
  csi: 123,
242
279
  }),
243
280
  receiveSlots: [fakeWcmeSlots[3]],
281
+ maxPayloadBitsPerSecond: MAX_PAYLOADBITSPS_720p,
244
282
  codecInfos: [
245
283
  sinon.match({
246
284
  payloadType: 0x80,
247
285
  h264: sinon.match({
248
- maxFs: 3600,
249
- maxFps: 2500,
250
- maxMbps: 90000,
286
+ maxFs: MAX_FS_720p,
287
+ maxFps: MAX_FPS,
288
+ maxMbps: MAX_MBPS_720p,
251
289
  }),
252
290
  }),
253
291
  ],
@@ -258,13 +296,14 @@ describe('MediaRequestManager', () => {
258
296
  csi: 123,
259
297
  }),
260
298
  receiveSlots: [fakeWcmeSlots[4]],
299
+ maxPayloadBitsPerSecond: MAX_PAYLOADBITSPS_1080p,
261
300
  codecInfos: [
262
301
  sinon.match({
263
302
  payloadType: 0x80,
264
303
  h264: sinon.match({
265
- maxFs: 8192,
266
- maxFps: 2500,
267
- maxMbps: 204800,
304
+ maxFs: MAX_FS_1080p,
305
+ maxFps: MAX_FPS,
306
+ maxMbps: MAX_MBPS_1080p,
268
307
  }),
269
308
  }),
270
309
  ],
@@ -274,44 +313,103 @@ describe('MediaRequestManager', () => {
274
313
 
275
314
  it('keeps adding requests with every call to addRequest()', () => {
276
315
  // start with 1 request
277
- addReceiverSelectedRequest(100, fakeReceiveSlots[0], true);
316
+ addReceiverSelectedRequest(100, fakeReceiveSlots[0], MAX_FS_1080p, true);
278
317
 
279
318
  checkMediaRequestsSent([
280
- {policy: 'receiver-selected', csi: 100, receiveSlot: fakeWcmeSlots[0]},
319
+ {
320
+ policy: 'receiver-selected',
321
+ csi: 100,
322
+ receiveSlot: fakeWcmeSlots[0],
323
+ maxPayloadBitsPerSecond: MAX_PAYLOADBITSPS_1080p,
324
+ maxFs: MAX_FS_1080p,
325
+ maxMbps: MAX_MBPS_1080p,
326
+ },
281
327
  ]);
282
328
 
283
329
  // now add another one
284
- addReceiverSelectedRequest(101, fakeReceiveSlots[1], true);
330
+ addReceiverSelectedRequest(101, fakeReceiveSlots[1], MAX_FS_1080p, true);
285
331
 
286
332
  checkMediaRequestsSent([
287
- {policy: 'receiver-selected', csi: 100, receiveSlot: fakeWcmeSlots[0]},
288
- {policy: 'receiver-selected', csi: 101, receiveSlot: fakeWcmeSlots[1]},
333
+ {
334
+ policy: 'receiver-selected',
335
+ csi: 100,
336
+ receiveSlot: fakeWcmeSlots[0],
337
+ maxPayloadBitsPerSecond: MAX_PAYLOADBITSPS_1080p,
338
+ maxFs: MAX_FS_1080p,
339
+ maxMbps: MAX_MBPS_1080p,
340
+ },
341
+ {
342
+ policy: 'receiver-selected',
343
+ csi: 101,
344
+ receiveSlot: fakeWcmeSlots[1],
345
+ maxPayloadBitsPerSecond: MAX_PAYLOADBITSPS_1080p,
346
+ maxFs: MAX_FS_1080p,
347
+ maxMbps: MAX_MBPS_1080p,
348
+ },
289
349
  ]);
290
350
 
291
351
  // and one more
292
352
  addActiveSpeakerRequest(
293
353
  1,
294
354
  [fakeReceiveSlots[2], fakeReceiveSlots[3], fakeReceiveSlots[4]],
355
+ MAX_FS_720p,
295
356
  true
296
357
  );
297
358
 
298
359
  checkMediaRequestsSent([
299
- {policy: 'receiver-selected', csi: 100, receiveSlot: fakeWcmeSlots[0]},
300
- {policy: 'receiver-selected', csi: 101, receiveSlot: fakeWcmeSlots[1]},
360
+ {
361
+ policy: 'receiver-selected',
362
+ csi: 100,
363
+ receiveSlot: fakeWcmeSlots[0],
364
+ maxPayloadBitsPerSecond: MAX_PAYLOADBITSPS_1080p,
365
+ maxFs: MAX_FS_1080p,
366
+ maxMbps: MAX_MBPS_1080p,
367
+ },
368
+ {
369
+ policy: 'receiver-selected',
370
+ csi: 101,
371
+ receiveSlot: fakeWcmeSlots[1],
372
+ maxPayloadBitsPerSecond: MAX_PAYLOADBITSPS_1080p,
373
+ maxFs: MAX_FS_1080p,
374
+ maxMbps: MAX_MBPS_1080p,
375
+ },
301
376
  {
302
377
  policy: 'active-speaker',
303
378
  priority: 1,
304
379
  receiveSlots: [fakeWcmeSlots[2], fakeWcmeSlots[3], fakeWcmeSlots[4]],
380
+ maxPayloadBitsPerSecond: MAX_PAYLOADBITSPS_720p,
381
+ maxFs: MAX_FS_720p,
382
+ maxMbps: MAX_MBPS_720p,
305
383
  },
306
384
  ]);
307
385
  });
308
386
 
387
+ it('removes the events maxFsUpdate and sourceUpdate when cancelRequest() is called', async () => {
388
+
389
+ const requestId = addActiveSpeakerRequest(255, [fakeReceiveSlots[2], fakeReceiveSlots[3]], MAX_FS_720p);
390
+
391
+ mediaRequestManager.cancelRequest(requestId, true);
392
+
393
+ const sourceUpdateHandler = fakeReceiveSlots[2].off.getCall(0);
394
+
395
+ const maxFsHandlerCall = fakeReceiveSlots[2].off.getCall(1);
396
+
397
+ const maxFsEventName = maxFsHandlerCall.args[0];
398
+ const sourceUpdateEventName = sourceUpdateHandler.args[0];
399
+
400
+ expect(sourceUpdateHandler.args[1]).to.be.a('function');
401
+ expect(maxFsHandlerCall.args[1]).to.be.a('function');
402
+
403
+ assert.equal(maxFsEventName, 'maxFsUpdate')
404
+ assert.equal(sourceUpdateEventName, 'sourceUpdate')
405
+ });
406
+
309
407
  it('cancels the requests correctly when cancelRequest() is called with commit=true', () => {
310
408
  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]),
409
+ addActiveSpeakerRequest(255, [fakeReceiveSlots[0], fakeReceiveSlots[1]], MAX_FS_720p),
410
+ addActiveSpeakerRequest(255, [fakeReceiveSlots[2], fakeReceiveSlots[3]], MAX_FS_720p),
411
+ addReceiverSelectedRequest(100, fakeReceiveSlots[4], MAX_FS_1080p),
412
+ addReceiverSelectedRequest(200, fakeReceiveSlots[5], MAX_FS_1080p),
315
413
  ];
316
414
 
317
415
  // cancel one of the active speaker requests
@@ -319,9 +417,30 @@ describe('MediaRequestManager', () => {
319
417
 
320
418
  // expect only the 3 remaining requests to be sent out
321
419
  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]},
420
+ {
421
+ policy: 'active-speaker',
422
+ priority: 255,
423
+ receiveSlots: [fakeWcmeSlots[0], fakeWcmeSlots[1]],
424
+ maxPayloadBitsPerSecond: MAX_PAYLOADBITSPS_720p,
425
+ maxFs: MAX_FS_720p,
426
+ maxMbps: MAX_MBPS_720p,
427
+ },
428
+ {
429
+ policy: 'receiver-selected',
430
+ csi: 100,
431
+ receiveSlot: fakeWcmeSlots[4],
432
+ maxPayloadBitsPerSecond: MAX_PAYLOADBITSPS_1080p,
433
+ maxFs: MAX_FS_1080p,
434
+ maxMbps: MAX_MBPS_1080p,
435
+ },
436
+ {
437
+ policy: 'receiver-selected',
438
+ csi: 200,
439
+ receiveSlot: fakeWcmeSlots[5],
440
+ maxPayloadBitsPerSecond: MAX_PAYLOADBITSPS_1080p,
441
+ maxFs: MAX_FS_1080p,
442
+ maxMbps: MAX_MBPS_1080p,
443
+ },
325
444
  ]);
326
445
 
327
446
  // cancel one of the receiver selected requests
@@ -329,8 +448,22 @@ describe('MediaRequestManager', () => {
329
448
 
330
449
  // expect only the 2 remaining requests to be sent out
331
450
  checkMediaRequestsSent([
332
- {policy: 'active-speaker', priority: 255, receiveSlots: [fakeWcmeSlots[0], fakeWcmeSlots[1]]},
333
- {policy: 'receiver-selected', csi: 100, receiveSlot: fakeWcmeSlots[4]},
451
+ {
452
+ policy: 'active-speaker',
453
+ priority: 255,
454
+ receiveSlots: [fakeWcmeSlots[0], fakeWcmeSlots[1]],
455
+ maxPayloadBitsPerSecond: MAX_PAYLOADBITSPS_720p,
456
+ maxFs: MAX_FS_720p,
457
+ maxMbps: MAX_MBPS_720p,
458
+ },
459
+ {
460
+ policy: 'receiver-selected',
461
+ csi: 100,
462
+ receiveSlot: fakeWcmeSlots[4],
463
+ maxPayloadBitsPerSecond: MAX_PAYLOADBITSPS_1080p,
464
+ maxFs: MAX_FS_1080p,
465
+ maxMbps: MAX_MBPS_1080p,
466
+ },
334
467
  ]);
335
468
  });
336
469
 
@@ -338,9 +471,10 @@ describe('MediaRequestManager', () => {
338
471
  addActiveSpeakerRequest(
339
472
  10,
340
473
  [fakeReceiveSlots[0], fakeReceiveSlots[1], fakeReceiveSlots[2]],
474
+ MAX_FS_720p,
341
475
  false
342
476
  );
343
- addReceiverSelectedRequest(123, fakeReceiveSlots[3], false);
477
+ addReceiverSelectedRequest(123, fakeReceiveSlots[3], MAX_FS_1080p, false);
344
478
 
345
479
  // nothing should be sent out as we didn't commit the requests
346
480
  assert.notCalled(sendMediaRequestsCallback);
@@ -354,8 +488,18 @@ describe('MediaRequestManager', () => {
354
488
  policy: 'active-speaker',
355
489
  priority: 10,
356
490
  receiveSlots: [fakeWcmeSlots[0], fakeWcmeSlots[1], fakeWcmeSlots[2]],
491
+ maxPayloadBitsPerSecond: MAX_PAYLOADBITSPS_720p,
492
+ maxFs: MAX_FS_720p,
493
+ maxMbps: MAX_MBPS_720p,
494
+ },
495
+ {
496
+ policy: 'receiver-selected',
497
+ csi: 123,
498
+ receiveSlot: fakeWcmeSlots[3],
499
+ maxPayloadBitsPerSecond: MAX_PAYLOADBITSPS_1080p,
500
+ maxFs: MAX_FS_1080p,
501
+ maxMbps: MAX_MBPS_1080p,
357
502
  },
358
- {policy: 'receiver-selected', csi: 123, receiveSlot: fakeWcmeSlots[3]},
359
503
  ]);
360
504
  });
361
505
 
@@ -365,11 +509,12 @@ describe('MediaRequestManager', () => {
365
509
  addActiveSpeakerRequest(
366
510
  250,
367
511
  [fakeReceiveSlots[0], fakeReceiveSlots[1], fakeReceiveSlots[2]],
512
+ MAX_FS_720p,
368
513
  false
369
514
  ),
370
- addReceiverSelectedRequest(98765, fakeReceiveSlots[3], false),
371
- addReceiverSelectedRequest(99999, fakeReceiveSlots[4], false),
372
- addReceiverSelectedRequest(88888, fakeReceiveSlots[5], true),
515
+ addReceiverSelectedRequest(98765, fakeReceiveSlots[3], MAX_FS_1080p, false),
516
+ addReceiverSelectedRequest(99999, fakeReceiveSlots[4], MAX_FS_1080p, false),
517
+ addReceiverSelectedRequest(88888, fakeReceiveSlots[5], MAX_FS_1080p, true),
373
518
  ];
374
519
 
375
520
  checkMediaRequestsSent([
@@ -377,10 +522,34 @@ describe('MediaRequestManager', () => {
377
522
  policy: 'active-speaker',
378
523
  priority: 250,
379
524
  receiveSlots: [fakeWcmeSlots[0], fakeWcmeSlots[1], fakeWcmeSlots[2]],
525
+ maxPayloadBitsPerSecond: MAX_PAYLOADBITSPS_720p,
526
+ maxFs: MAX_FS_720p,
527
+ maxMbps: MAX_MBPS_720p,
528
+ },
529
+ {
530
+ policy: 'receiver-selected',
531
+ csi: 98765,
532
+ receiveSlot: fakeWcmeSlots[3],
533
+ maxPayloadBitsPerSecond: MAX_PAYLOADBITSPS_1080p,
534
+ maxFs: MAX_FS_1080p,
535
+ maxMbps: MAX_MBPS_1080p,
536
+ },
537
+ {
538
+ policy: 'receiver-selected',
539
+ csi: 99999,
540
+ receiveSlot: fakeWcmeSlots[4],
541
+ maxPayloadBitsPerSecond: MAX_PAYLOADBITSPS_1080p,
542
+ maxFs: MAX_FS_1080p,
543
+ maxMbps: MAX_MBPS_1080p,
544
+ },
545
+ {
546
+ policy: 'receiver-selected',
547
+ csi: 88888,
548
+ receiveSlot: fakeWcmeSlots[5],
549
+ maxPayloadBitsPerSecond: MAX_PAYLOADBITSPS_1080p,
550
+ maxFs: MAX_FS_1080p,
551
+ maxMbps: MAX_MBPS_1080p,
380
552
  },
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
553
  ]);
385
554
 
386
555
  // now cancel 3 of them, but with commit=false => nothing should happen
@@ -394,22 +563,31 @@ describe('MediaRequestManager', () => {
394
563
  mediaRequestManager.commit();
395
564
 
396
565
  checkMediaRequestsSent([
397
- {policy: 'receiver-selected', csi: 98765, receiveSlot: fakeWcmeSlots[3]},
566
+ {
567
+ policy: 'receiver-selected',
568
+ csi: 98765,
569
+ receiveSlot: fakeWcmeSlots[3],
570
+ maxPayloadBitsPerSecond: MAX_PAYLOADBITSPS_1080p,
571
+ maxFs: MAX_FS_1080p,
572
+ maxMbps: MAX_MBPS_1080p,
573
+ },
398
574
  ]);
399
575
  });
400
576
 
401
577
  it('sends the wcme media requests when commit() is called', () => {
402
578
  // send some requests, all of them with commit=false
403
- addReceiverSelectedRequest(123000, fakeReceiveSlots[0], false);
404
- addReceiverSelectedRequest(456000, fakeReceiveSlots[1], false);
579
+ addReceiverSelectedRequest(123000, fakeReceiveSlots[0], MAX_FS_1080p, false);
580
+ addReceiverSelectedRequest(456000, fakeReceiveSlots[1], MAX_FS_1080p, false);
405
581
  addActiveSpeakerRequest(
406
582
  255,
407
583
  [fakeReceiveSlots[2], fakeReceiveSlots[3], fakeReceiveSlots[4]],
584
+ MAX_FS_720p,
408
585
  false
409
586
  );
410
587
  addActiveSpeakerRequest(
411
588
  254,
412
589
  [fakeReceiveSlots[5], fakeReceiveSlots[6], fakeReceiveSlots[7]],
590
+ MAX_FS_720p,
413
591
  false
414
592
  );
415
593
 
@@ -421,56 +599,103 @@ describe('MediaRequestManager', () => {
421
599
 
422
600
  // check that all requests have been sent out
423
601
  checkMediaRequestsSent([
424
- {policy: 'receiver-selected', csi: 123000, receiveSlot: fakeWcmeSlots[0]},
425
- {policy: 'receiver-selected', csi: 456000, receiveSlot: fakeWcmeSlots[1]},
602
+ {
603
+ policy: 'receiver-selected',
604
+ csi: 123000,
605
+ receiveSlot: fakeWcmeSlots[0],
606
+ maxPayloadBitsPerSecond: MAX_PAYLOADBITSPS_1080p,
607
+ maxFs: MAX_FS_1080p,
608
+ maxMbps: MAX_MBPS_1080p,
609
+ },
610
+ {
611
+ policy: 'receiver-selected',
612
+ csi: 456000,
613
+ receiveSlot: fakeWcmeSlots[1],
614
+ maxPayloadBitsPerSecond: MAX_PAYLOADBITSPS_1080p,
615
+ maxFs: MAX_FS_1080p,
616
+ maxMbps: MAX_MBPS_1080p,
617
+ },
426
618
  {
427
619
  policy: 'active-speaker',
428
620
  priority: 255,
429
621
  receiveSlots: [fakeWcmeSlots[2], fakeWcmeSlots[3], fakeWcmeSlots[4]],
622
+ maxPayloadBitsPerSecond: MAX_PAYLOADBITSPS_720p,
623
+ maxFs: MAX_FS_720p,
624
+ maxMbps: MAX_MBPS_720p,
430
625
  },
431
626
  {
432
627
  policy: 'active-speaker',
433
628
  priority: 254,
434
629
  receiveSlots: [fakeWcmeSlots[5], fakeWcmeSlots[6], fakeWcmeSlots[7]],
630
+ maxPayloadBitsPerSecond: MAX_PAYLOADBITSPS_720p,
631
+ maxFs: MAX_FS_720p,
632
+ maxMbps: MAX_MBPS_720p,
435
633
  },
436
634
  ]);
437
635
  });
438
636
 
439
- it('clears all the requests on reset()', () => {
637
+ it('avoids sending duplicate requests and clears all the requests on reset()', () => {
440
638
  // send some requests and commit them one by one
441
- addReceiverSelectedRequest(1500, fakeReceiveSlots[0], true);
442
- addReceiverSelectedRequest(1501, fakeReceiveSlots[1], true);
639
+ addReceiverSelectedRequest(1500, fakeReceiveSlots[0], MAX_FS_1080p, false);
640
+ addReceiverSelectedRequest(1501, fakeReceiveSlots[1], MAX_FS_1080p, false);
443
641
  addActiveSpeakerRequest(
444
642
  255,
445
643
  [fakeReceiveSlots[2], fakeReceiveSlots[3], fakeReceiveSlots[4]],
446
- true
644
+ MAX_FS_720p,
645
+ false
447
646
  );
448
647
  addActiveSpeakerRequest(
449
648
  254,
450
649
  [fakeReceiveSlots[5], fakeReceiveSlots[6], fakeReceiveSlots[7]],
451
- true
650
+ MAX_FS_720p,
651
+ false
452
652
  );
453
653
 
454
- sendMediaRequestsCallback.resetHistory();
654
+ // nothing should be sent out as we didn't commit the requests
655
+ assert.notCalled(sendMediaRequestsCallback);
455
656
 
456
- // check that when calling commit() all requests are re-sent again
457
657
  mediaRequestManager.commit();
458
-
459
658
  checkMediaRequestsSent([
460
- {policy: 'receiver-selected', csi: 1500, receiveSlot: fakeWcmeSlots[0]},
461
- {policy: 'receiver-selected', csi: 1501, receiveSlot: fakeWcmeSlots[1]},
659
+ {
660
+ policy: 'receiver-selected',
661
+ csi: 1500,
662
+ receiveSlot: fakeWcmeSlots[0],
663
+ maxPayloadBitsPerSecond: MAX_PAYLOADBITSPS_1080p,
664
+ maxFs: MAX_FS_1080p,
665
+ maxMbps: MAX_MBPS_1080p,
666
+ },
667
+ {
668
+ policy: 'receiver-selected',
669
+ csi: 1501,
670
+ receiveSlot: fakeWcmeSlots[1],
671
+ maxPayloadBitsPerSecond: MAX_PAYLOADBITSPS_1080p,
672
+ maxFs: MAX_FS_1080p,
673
+ maxMbps: MAX_MBPS_1080p,
674
+ },
462
675
  {
463
676
  policy: 'active-speaker',
464
677
  priority: 255,
465
678
  receiveSlots: [fakeWcmeSlots[2], fakeWcmeSlots[3], fakeWcmeSlots[4]],
679
+ maxPayloadBitsPerSecond: MAX_PAYLOADBITSPS_720p,
680
+ maxFs: MAX_FS_720p,
681
+ maxMbps: MAX_MBPS_720p,
466
682
  },
467
683
  {
468
684
  policy: 'active-speaker',
469
685
  priority: 254,
470
686
  receiveSlots: [fakeWcmeSlots[5], fakeWcmeSlots[6], fakeWcmeSlots[7]],
687
+ maxPayloadBitsPerSecond: MAX_PAYLOADBITSPS_720p,
688
+ maxFs: MAX_FS_720p,
689
+ maxMbps: MAX_MBPS_720p,
471
690
  },
472
691
  ]);
473
692
 
693
+ // check that when calling commit()
694
+ // all requests are not re-sent again (avoid duplicate requests)
695
+ mediaRequestManager.commit();
696
+
697
+ assert.notCalled(sendMediaRequestsCallback);
698
+
474
699
  // now reset everything
475
700
  mediaRequestManager.reset();
476
701
 
@@ -479,37 +704,715 @@ describe('MediaRequestManager', () => {
479
704
  checkMediaRequestsSent([]);
480
705
  });
481
706
 
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
- ];
707
+ it('makes sure to call requests correctly after reset was called and another request was added', () => {
708
+ addReceiverSelectedRequest(1500, fakeReceiveSlots[0], MAX_FS_1080p, false);
709
+
710
+ assert.notCalled(sendMediaRequestsCallback);
489
711
 
490
712
  mediaRequestManager.commit();
491
713
  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]},
714
+ {
715
+ policy: 'receiver-selected',
716
+ csi: 1500,
717
+ receiveSlot: fakeWcmeSlots[0],
718
+ maxPayloadBitsPerSecond: MAX_PAYLOADBITSPS_1080p,
719
+ maxFs: MAX_FS_1080p,
720
+ maxMbps: MAX_MBPS_1080p,
721
+ },
496
722
  ]);
497
723
 
498
- // cancel 2 of the requests
499
- mediaRequestManager.cancelRequest(requestIds[1], false);
500
- mediaRequestManager.cancelRequest(requestIds[3], false);
724
+ // now reset everything
725
+ mediaRequestManager.reset();
501
726
 
727
+ // calling commit now should not cause any requests to be sent out
502
728
  mediaRequestManager.commit();
729
+ checkMediaRequestsSent([]);
503
730
 
504
- // expect only the 2 remaining requests to be sent out
731
+ //add new request
732
+ addReceiverSelectedRequest(1501, fakeReceiveSlots[1], MAX_FS_1080p, false);
733
+
734
+ // commit
735
+ mediaRequestManager.commit();
736
+
737
+ // check the new request was sent
505
738
  checkMediaRequestsSent([
506
- {policy: 'active-speaker', priority: 255, receiveSlots: [fakeWcmeSlots[0], fakeWcmeSlots[1]]},
507
- {policy: 'receiver-selected', csi: 100, receiveSlot: fakeWcmeSlots[4]},
739
+ {
740
+ policy: 'receiver-selected',
741
+ csi: 1501,
742
+ receiveSlot: fakeWcmeSlots[1],
743
+ maxPayloadBitsPerSecond: MAX_PAYLOADBITSPS_1080p,
744
+ maxFs: MAX_FS_1080p,
745
+ maxMbps: MAX_MBPS_1080p,
746
+ },
508
747
  ]);
748
+ });
509
749
 
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);
750
+ it('can send same media request after previous requests have been cleared', () => {
751
+ // add a request and commit
752
+ addReceiverSelectedRequest(1500, fakeReceiveSlots[0], MAX_FS_1080p, false);
753
+ mediaRequestManager.commit();
754
+ checkMediaRequestsSent([
755
+ {
756
+ policy: 'receiver-selected',
757
+ csi: 1500,
758
+ maxPayloadBitsPerSecond: MAX_PAYLOADBITSPS_1080p,
759
+ receiveSlot: fakeWcmeSlots[0],
760
+ maxFs: MAX_FS_1080p,
761
+ maxMbps: MAX_MBPS_1080p,
762
+ },
763
+ ]);
764
+
765
+ // clear previous requests
766
+ mediaRequestManager.clearPreviousRequests();
767
+
768
+ // commit same request
769
+ mediaRequestManager.commit();
770
+
771
+ // check the request was sent
772
+ checkMediaRequestsSent([
773
+ {
774
+ policy: 'receiver-selected',
775
+ csi: 1500,
776
+ maxPayloadBitsPerSecond: MAX_PAYLOADBITSPS_1080p,
777
+ receiveSlot: fakeWcmeSlots[0],
778
+ maxFs: MAX_FS_1080p,
779
+ maxMbps: MAX_MBPS_1080p,
780
+ },
781
+ ]);
782
+ });
783
+
784
+ it('re-sends media requests after degradation preferences are set', () => {
785
+ // set max macroblocks limit
786
+ mediaRequestManager.setDegradationPreferences({maxMacroblocksLimit: 32400});
787
+ assert.calledOnce(sendMediaRequestsCallback);
788
+ });
789
+
790
+ it('should not degrade max-fs if receive slot sources are not live', () => {
791
+ // set receive slot source states to "no source"
792
+ fakeReceiveSlots.forEach((slot) => {
793
+ slot.sourceState = 'no source';
794
+ });
795
+
796
+ // set max macroblocks limit
797
+ mediaRequestManager.setDegradationPreferences({maxMacroblocksLimit: 32400});
798
+ sendMediaRequestsCallback.resetHistory();
799
+
800
+ // request 4 "large" 1080p streams, which should degrade to 720p if live
801
+ addActiveSpeakerRequest(255, fakeReceiveSlots.slice(0, 4), getMaxFs('large'), true);
802
+
803
+ // check that resulting requests are 4 "large" 1080p streams
804
+ checkMediaRequestsSent([
805
+ {
806
+ policy: 'active-speaker',
807
+ priority: 255,
808
+ receiveSlots: fakeWcmeSlots.slice(0, 4),
809
+ maxPayloadBitsPerSecond: MAX_PAYLOADBITSPS_1080p,
810
+ maxFs: getMaxFs('large'),
811
+ maxMbps: MAX_MBPS_1080p,
812
+ },
813
+ ]);
514
814
  });
815
+
816
+ it('can degrade max-fs once when request exceeds max macroblocks limit', () => {
817
+ // set max macroblocks limit
818
+ mediaRequestManager.setDegradationPreferences({maxMacroblocksLimit: 32400});
819
+ sendMediaRequestsCallback.resetHistory();
820
+
821
+ // request 3 "large" 1080p streams
822
+ addActiveSpeakerRequest(255, fakeReceiveSlots.slice(0, 3), getMaxFs('large'), false);
823
+
824
+ // request additional "large" 1080p stream to exceed max macroblocks limit
825
+ const additionalRequestId = addReceiverSelectedRequest(
826
+ 123,
827
+ fakeReceiveSlots[3],
828
+ getMaxFs('large'),
829
+ true
830
+ );
831
+
832
+ // check that resulting requests are 4 "medium" 720p streams
833
+ checkMediaRequestsSent([
834
+ {
835
+ policy: 'active-speaker',
836
+ priority: 255,
837
+ receiveSlots: fakeWcmeSlots.slice(0, 3),
838
+ maxPayloadBitsPerSecond: MAX_PAYLOADBITSPS_720p,
839
+ maxFs: getMaxFs('medium'),
840
+ maxMbps: MAX_MBPS_720p,
841
+ },
842
+ {
843
+ policy: 'receiver-selected',
844
+ csi: 123,
845
+ receiveSlot: fakeWcmeSlots[3],
846
+ maxPayloadBitsPerSecond: MAX_PAYLOADBITSPS_720p,
847
+ maxFs: getMaxFs('medium'),
848
+ maxMbps: MAX_MBPS_720p,
849
+ },
850
+ ]);
851
+
852
+ // cancel additional request
853
+ mediaRequestManager.cancelRequest(additionalRequestId);
854
+
855
+ // check that resulting requests are 3 "large" 1080p streams
856
+ checkMediaRequestsSent([
857
+ {
858
+ policy: 'active-speaker',
859
+ priority: 255,
860
+ receiveSlots: fakeWcmeSlots.slice(0, 3),
861
+ maxPayloadBitsPerSecond: MAX_PAYLOADBITSPS_1080p,
862
+ maxFs: getMaxFs('large'),
863
+ maxMbps: MAX_MBPS_1080p,
864
+ },
865
+ ]);
866
+ });
867
+
868
+ it('can degrade max-fs multiple times when request exceeds max macroblocks limit', () => {
869
+ // set max macroblocks limit
870
+ mediaRequestManager.setDegradationPreferences({maxMacroblocksLimit: 32400});
871
+ sendMediaRequestsCallback.resetHistory();
872
+
873
+ // request 10 "large" 1080p streams
874
+ addActiveSpeakerRequest(255, fakeReceiveSlots.slice(0, 10), getMaxFs('large'), true);
875
+
876
+ // check that resulting requests are 10 "small" 360p streams
877
+ checkMediaRequestsSent([
878
+ {
879
+ policy: 'active-speaker',
880
+ priority: 255,
881
+ receiveSlots: fakeWcmeSlots.slice(0, 10),
882
+ maxPayloadBitsPerSecond: MAX_PAYLOADBITSPS_360p,
883
+ maxFs: getMaxFs('small'),
884
+ maxMbps: MAX_MBPS_360p,
885
+ },
886
+ ]);
887
+ });
888
+
889
+ it('can degrade only the largest max-fs when request exceeds max macroblocks limit', () => {
890
+ // set max macroblocks limit
891
+ mediaRequestManager.setDegradationPreferences({maxMacroblocksLimit: 32400});
892
+ sendMediaRequestsCallback.resetHistory();
893
+
894
+ // request 5 "large" 1080p streams and 5 "small" 360p streams
895
+ addActiveSpeakerRequest(255, fakeReceiveSlots.slice(0, 5), getMaxFs('large'), false);
896
+ addActiveSpeakerRequest(254, fakeReceiveSlots.slice(5, 10), getMaxFs('small'), true);
897
+
898
+ // check that resulting requests are 5 "medium" 720p streams and 5 "small" 360p streams
899
+ checkMediaRequestsSent([
900
+ {
901
+ policy: 'active-speaker',
902
+ priority: 255,
903
+ receiveSlots: fakeWcmeSlots.slice(0, 5),
904
+ maxPayloadBitsPerSecond: MAX_PAYLOADBITSPS_720p,
905
+ maxFs: getMaxFs('medium'),
906
+ maxMbps: MAX_MBPS_720p,
907
+ },
908
+ {
909
+ policy: 'active-speaker',
910
+ priority: 254,
911
+ receiveSlots: fakeWcmeSlots.slice(5, 10),
912
+ maxPayloadBitsPerSecond: MAX_PAYLOADBITSPS_360p,
913
+ maxFs: getMaxFs('small'),
914
+ maxMbps: MAX_MBPS_360p,
915
+ },
916
+ ]);
917
+ });
918
+
919
+ it('respects the preferredMaxFs if set', () => {
920
+ sendMediaRequestsCallback.resetHistory();
921
+ const clock = FakeTimers.install({now: Date.now()});
922
+
923
+ addActiveSpeakerRequest(255, fakeReceiveSlots.slice(0, 10), getMaxFs('large'), true);
924
+
925
+ sendMediaRequestsCallback.resetHistory();
926
+
927
+ const maxFsHandlerCall = fakeReceiveSlots[0].on.getCall(1);
928
+
929
+ const maxFsHandler = maxFsHandlerCall.args[1];
930
+ const eventName = maxFsHandlerCall.args[0];
931
+
932
+ assert.equal(eventName, 'maxFsUpdate');
933
+
934
+ const preferredFrameSize = 100;
935
+
936
+ maxFsHandler({maxFs: preferredFrameSize});
937
+
938
+ clock.tick(999);
939
+
940
+ assert.notCalled(sendMediaRequestsCallback);
941
+
942
+ clock.tick(1);
943
+
944
+ checkMediaRequestsSent([
945
+ {
946
+ policy: 'active-speaker',
947
+ priority: 255,
948
+ receiveSlots: fakeWcmeSlots.slice(0, 10),
949
+ maxFs: preferredFrameSize,
950
+ maxPayloadBitsPerSecond: 99000,
951
+ maxMbps: 3000,
952
+ },
953
+ ]);
954
+ });
955
+
956
+ describe('maxPayloadBitsPerSecond', () => {
957
+ let getRecommendedMaxBitrateForFrameSizeSpy;
958
+
959
+ beforeEach(() => {
960
+ sendMediaRequestsCallback.resetHistory();
961
+ getRecommendedMaxBitrateForFrameSizeSpy = sinon.spy(
962
+ mediaCore,
963
+ 'getRecommendedMaxBitrateForFrameSize'
964
+ );
965
+ });
966
+
967
+ afterEach(() => {
968
+ getRecommendedMaxBitrateForFrameSizeSpy.restore();
969
+ });
970
+
971
+ it('returns the default maxPayloadBitsPerSecond if kind is "audio"', () => {
972
+ const mediaRequestManagerAudio = new MediaRequestManager(sendMediaRequestsCallback, {
973
+ degradationPreferences,
974
+ kind: 'audio',
975
+ trimRequestsToNumOfSources: false,
976
+ });
977
+ mediaRequestManagerAudio.setNumCurrentSources(100, 100);
978
+ sendMediaRequestsCallback.resetHistory();
979
+
980
+ mediaRequestManagerAudio.addRequest(
981
+ {
982
+ policyInfo: {
983
+ policy: 'receiver-selected',
984
+ csi: 123,
985
+ },
986
+ receiveSlots: [fakeReceiveSlots[0]],
987
+ codecInfo: undefined,
988
+ },
989
+ false
990
+ );
991
+
992
+ mediaRequestManagerAudio.commit();
993
+
994
+ checkMediaRequestsSent(
995
+ [
996
+ {
997
+ policy: 'receiver-selected',
998
+ csi: 123,
999
+ receiveSlot: fakeWcmeSlots[0],
1000
+ // returns RecommendedOpusBitrates.FB_MONO_MUSIC as expected:
1001
+ maxPayloadBitsPerSecond: 64000,
1002
+ },
1003
+ // set isCodecInfoDefined to false, since we don't pass in a codec info when audio:
1004
+ ],
1005
+ {isCodecInfoDefined: false}
1006
+ );
1007
+
1008
+ assert.notCalled(getRecommendedMaxBitrateForFrameSizeSpy);
1009
+ });
1010
+
1011
+ it('returns the recommended maxPayloadBitsPerSecond if kind is "video"', () => {
1012
+ mediaRequestManager.addRequest(
1013
+ {
1014
+ policyInfo: {
1015
+ policy: 'receiver-selected',
1016
+ csi: 123,
1017
+ },
1018
+ receiveSlots: [fakeReceiveSlots[0]],
1019
+ codecInfo: {
1020
+ codec: 'h264',
1021
+ maxFs: MAX_FS_1080p,
1022
+ maxFps: MAX_FPS,
1023
+ maxMbps: MAX_MBPS_1080p,
1024
+ },
1025
+ },
1026
+ false
1027
+ );
1028
+
1029
+ mediaRequestManager.commit();
1030
+
1031
+ checkMediaRequestsSent([
1032
+ {
1033
+ policy: 'receiver-selected',
1034
+ csi: 123,
1035
+ receiveSlot: fakeWcmeSlots[0],
1036
+ maxPayloadBitsPerSecond: MAX_PAYLOADBITSPS_1080p,
1037
+ maxFs: MAX_FS_1080p,
1038
+ maxMbps: MAX_MBPS_1080p,
1039
+ },
1040
+ ]);
1041
+
1042
+ // calls the utility function as expected with maxFs passed in (no need to do
1043
+ // further tests here, since the util function itself should be tested for different inputs)
1044
+ assert.calledWith(getRecommendedMaxBitrateForFrameSizeSpy, MAX_FS_1080p);
1045
+ });
1046
+ });
1047
+
1048
+ describe('maxMbps', () => {
1049
+ beforeEach(() => {
1050
+ sendMediaRequestsCallback.resetHistory();
1051
+ });
1052
+
1053
+ it('returns the correct maxMbps value', () => {
1054
+ mediaRequestManager.addRequest(
1055
+ {
1056
+ policyInfo: {
1057
+ policy: 'receiver-selected',
1058
+ csi: 123,
1059
+ },
1060
+ receiveSlots: [fakeReceiveSlots[0]],
1061
+ codecInfo: {
1062
+ codec: 'h264',
1063
+ maxFs: MAX_FS_1080p,
1064
+ maxFps: MAX_FPS,
1065
+ // random value to pass in, to show that the output (below) is calculated
1066
+ // from the maxFs and maxFps values only:
1067
+ maxMbps: 123,
1068
+ },
1069
+ },
1070
+ false
1071
+ );
1072
+
1073
+ mediaRequestManager.commit();
1074
+
1075
+ checkMediaRequestsSent([
1076
+ {
1077
+ policy: 'receiver-selected',
1078
+ csi: 123,
1079
+ receiveSlot: fakeWcmeSlots[0],
1080
+ maxPayloadBitsPerSecond: MAX_PAYLOADBITSPS_1080p,
1081
+ maxFs: MAX_FS_1080p,
1082
+ maxMbps: MAX_MBPS_1080p,
1083
+ },
1084
+ ]);
1085
+ });
1086
+ });
1087
+
1088
+ describe('trimming of requested receive slots', () => {
1089
+ beforeEach(() => {
1090
+ mediaRequestManager = new MediaRequestManager(sendMediaRequestsCallback, {
1091
+ degradationPreferences,
1092
+ kind: 'video',
1093
+ trimRequestsToNumOfSources: true,
1094
+ });
1095
+ });
1096
+
1097
+ const limitNumAvailableStreams = (preferLiveVideo, limit) => {
1098
+ if (preferLiveVideo) {
1099
+ mediaRequestManager.setNumCurrentSources(100, limit);
1100
+ } else {
1101
+ mediaRequestManager.setNumCurrentSources(limit, 1);
1102
+ }
1103
+ };
1104
+
1105
+ [true, false].forEach((preferLiveVideo) =>
1106
+ describe(`preferLiveVideo=${preferLiveVideo}`, () => {
1107
+ it(`trims the active speaker request with lowest priority first and maintains slot order`, () => {
1108
+ // add some receiver-selected and active-speaker requests, in a mixed up order
1109
+ addReceiverSelectedRequest(100, fakeReceiveSlots[0], MAX_FS_360p, false);
1110
+ addActiveSpeakerRequest( // AS request 1 - it will get 1 slot trimmed
1111
+ 254,
1112
+ [fakeReceiveSlots[1], fakeReceiveSlots[2], fakeReceiveSlots[3]],
1113
+ MAX_FS_360p,
1114
+ false,
1115
+ preferLiveVideo
1116
+ );
1117
+ addActiveSpeakerRequest( // AS request 2 - lowest priority, it will have all slots trimmed
1118
+ 253,
1119
+ [fakeReceiveSlots[7], fakeReceiveSlots[8], fakeReceiveSlots[9]],
1120
+ MAX_FS_360p,
1121
+ false,
1122
+ preferLiveVideo
1123
+ );
1124
+ addActiveSpeakerRequest( // AS request 3 - highest priority, nothing will be trimmed
1125
+ 255,
1126
+ [fakeReceiveSlots[4], fakeReceiveSlots[5], fakeReceiveSlots[6]],
1127
+ MAX_FS_360p,
1128
+ false,
1129
+ preferLiveVideo
1130
+ );
1131
+ addReceiverSelectedRequest(101, fakeReceiveSlots[10], MAX_FS_360p, false);
1132
+
1133
+ /* Set number of available streams to 7 so that there will be enough sources only for
1134
+ the 2 RS requests and 2 of the 3 AS requests. The lowest priority AS request will
1135
+ have all the slots trimmed, the second lowest priority AS request will have 1 slot trimmed */
1136
+ limitNumAvailableStreams(preferLiveVideo, 7);
1137
+
1138
+ // check what got trimmed
1139
+ checkMediaRequestsSent([
1140
+ {
1141
+ policy: 'receiver-selected',
1142
+ csi: 100,
1143
+ receiveSlot: fakeWcmeSlots[0],
1144
+ maxPayloadBitsPerSecond: MAX_PAYLOADBITSPS_360p,
1145
+ maxFs: MAX_FS_360p,
1146
+ maxMbps: MAX_MBPS_360p,
1147
+ },
1148
+ {
1149
+ policy: 'active-speaker',
1150
+ priority: 254,
1151
+ receiveSlots: [fakeWcmeSlots[1], fakeWcmeSlots[2]], // fakeWcmeSlots[3] got trimmed
1152
+ maxPayloadBitsPerSecond: MAX_PAYLOADBITSPS_360p,
1153
+ maxFs: MAX_FS_360p,
1154
+ maxMbps: MAX_MBPS_360p,
1155
+ },
1156
+ // AS request with priority 253 is missing, because all of its slots got trimmed
1157
+ {
1158
+ policy: 'active-speaker',
1159
+ priority: 255,
1160
+ receiveSlots: [fakeWcmeSlots[4], fakeWcmeSlots[5], fakeWcmeSlots[6]],
1161
+ maxPayloadBitsPerSecond: MAX_PAYLOADBITSPS_360p,
1162
+ maxFs: MAX_FS_360p,
1163
+ maxMbps: MAX_MBPS_360p,
1164
+ },
1165
+ {
1166
+ policy: 'receiver-selected',
1167
+ csi: 101,
1168
+ receiveSlot: fakeWcmeSlots[10],
1169
+ maxPayloadBitsPerSecond: MAX_PAYLOADBITSPS_360p,
1170
+ maxFs: MAX_FS_360p,
1171
+ maxMbps: MAX_MBPS_360p,
1172
+ },
1173
+ ], {preferLiveVideo});
1174
+
1175
+ // now increase the number of available streams so only the last AS request is trimmed by 1
1176
+ limitNumAvailableStreams(preferLiveVideo, 10);
1177
+
1178
+ checkMediaRequestsSent([
1179
+ {
1180
+ policy: 'receiver-selected',
1181
+ csi: 100,
1182
+ receiveSlot: fakeWcmeSlots[0],
1183
+ maxPayloadBitsPerSecond: MAX_PAYLOADBITSPS_360p,
1184
+ maxFs: MAX_FS_360p,
1185
+ maxMbps: MAX_MBPS_360p,
1186
+ },
1187
+ {
1188
+ policy: 'active-speaker',
1189
+ priority: 254,
1190
+ receiveSlots: [fakeWcmeSlots[1], fakeWcmeSlots[2], fakeWcmeSlots[3]], // all slots are used, nothing trimmed
1191
+ maxPayloadBitsPerSecond: MAX_PAYLOADBITSPS_360p,
1192
+ maxFs: MAX_FS_360p,
1193
+ maxMbps: MAX_MBPS_360p,
1194
+ },
1195
+ {
1196
+ policy: 'active-speaker',
1197
+ priority: 253,
1198
+ receiveSlots: [fakeWcmeSlots[7], fakeWcmeSlots[8]], // only 1 slot is trimmed
1199
+ maxPayloadBitsPerSecond: MAX_PAYLOADBITSPS_360p,
1200
+ maxFs: MAX_FS_360p,
1201
+ maxMbps: MAX_MBPS_360p,
1202
+ },
1203
+ {
1204
+ policy: 'active-speaker',
1205
+ priority: 255,
1206
+ receiveSlots: [fakeWcmeSlots[4], fakeWcmeSlots[5], fakeWcmeSlots[6]], // all slots are used, nothing trimmed
1207
+ maxPayloadBitsPerSecond: MAX_PAYLOADBITSPS_360p,
1208
+ maxFs: MAX_FS_360p,
1209
+ maxMbps: MAX_MBPS_360p,
1210
+ },
1211
+ {
1212
+ policy: 'receiver-selected',
1213
+ csi: 101,
1214
+ receiveSlot: fakeWcmeSlots[10],
1215
+ maxPayloadBitsPerSecond: MAX_PAYLOADBITSPS_360p,
1216
+ maxFs: MAX_FS_360p,
1217
+ maxMbps: MAX_MBPS_360p,
1218
+ },
1219
+ ], {preferLiveVideo});
1220
+ })
1221
+
1222
+ it('does not trim the receiver selected requests', async () => {
1223
+ // add some receiver-selected and active-speaker requests, in a mixed up order
1224
+ addReceiverSelectedRequest(200, fakeReceiveSlots[0], MAX_FS_360p, false);
1225
+ addActiveSpeakerRequest(
1226
+ 255,
1227
+ [fakeReceiveSlots[1], fakeReceiveSlots[2], fakeReceiveSlots[3]],
1228
+ MAX_FS_360p,
1229
+ false,
1230
+ preferLiveVideo
1231
+ );
1232
+ addReceiverSelectedRequest(201, fakeReceiveSlots[4], MAX_FS_720p, false);
1233
+ addActiveSpeakerRequest(
1234
+ 254,
1235
+ [fakeReceiveSlots[5], fakeReceiveSlots[6], fakeReceiveSlots[7]],
1236
+ MAX_FS_720p,
1237
+ false,
1238
+ preferLiveVideo
1239
+ );
1240
+
1241
+ /* Set number of available streams to 1, which is lower than the number of RS requests,
1242
+ so all AS requests will be trimmed to 0 but RS requests should be unaltered */
1243
+ limitNumAvailableStreams(preferLiveVideo, 1);
1244
+
1245
+ // check what got trimmed - only RS requests should remain
1246
+ checkMediaRequestsSent([
1247
+ {
1248
+ policy: 'receiver-selected',
1249
+ csi: 200,
1250
+ receiveSlot: fakeWcmeSlots[0],
1251
+ maxPayloadBitsPerSecond: MAX_PAYLOADBITSPS_360p,
1252
+ maxFs: MAX_FS_360p,
1253
+ maxMbps: MAX_MBPS_360p,
1254
+ },
1255
+ {
1256
+ policy: 'receiver-selected',
1257
+ csi: 201,
1258
+ receiveSlot: fakeWcmeSlots[4],
1259
+ maxPayloadBitsPerSecond: MAX_PAYLOADBITSPS_720p,
1260
+ maxFs: MAX_FS_720p,
1261
+ maxMbps: MAX_MBPS_720p,
1262
+ },
1263
+ ], {preferLiveVideo});
1264
+ });
1265
+
1266
+ it('does trimming first and applies degradationPreferences after that', async () => {
1267
+ // add some receiver-selected and active-speaker requests
1268
+ addReceiverSelectedRequest(200, fakeReceiveSlots[0], MAX_FS_360p, false);
1269
+ addActiveSpeakerRequest(
1270
+ 255,
1271
+ [fakeReceiveSlots[1], fakeReceiveSlots[2], fakeReceiveSlots[3]],
1272
+ MAX_FS_360p,
1273
+ false,
1274
+ preferLiveVideo
1275
+ );
1276
+ addReceiverSelectedRequest(201, fakeReceiveSlots[4], MAX_FS_720p, false);
1277
+ addActiveSpeakerRequest(
1278
+ 254,
1279
+ [fakeReceiveSlots[5], fakeReceiveSlots[6], fakeReceiveSlots[7]],
1280
+ MAX_FS_720p,
1281
+ false,
1282
+ preferLiveVideo
1283
+ );
1284
+
1285
+ // Set maxMacroblocksLimit to a value that's big enough just for the 2 RS requests and 1 AS with 1 slot of 360p.
1286
+ // but not big enough for all of the RS and AS requests. If maxMacroblocksLimit
1287
+ // was applied first, the resolution of all requests (including RS ones) would be degraded
1288
+ // This test verifies that it's not happening and the resolutions are not affected.
1289
+ mediaRequestManager.setDegradationPreferences({maxMacroblocksLimit: MAX_FS_360p + MAX_FS_720p + MAX_FS_360p});
1290
+ sendMediaRequestsCallback.resetHistory();
1291
+
1292
+ /* Limit the num of streams so that only 2 RS requests and 1 AS with 1 slot can be sent out */
1293
+ limitNumAvailableStreams(preferLiveVideo, 3);
1294
+
1295
+ // check what got trimmed - the remaining requests should have unchanged resolutions
1296
+ checkMediaRequestsSent([
1297
+ {
1298
+ policy: 'receiver-selected',
1299
+ csi: 200,
1300
+ receiveSlot: fakeWcmeSlots[0],
1301
+ maxPayloadBitsPerSecond: MAX_PAYLOADBITSPS_360p,
1302
+ maxFs: MAX_FS_360p,
1303
+ maxMbps: MAX_MBPS_360p,
1304
+ },
1305
+ {
1306
+ policy: 'active-speaker',
1307
+ priority: 255,
1308
+ receiveSlots: [fakeWcmeSlots[1]],
1309
+ maxPayloadBitsPerSecond: MAX_PAYLOADBITSPS_360p,
1310
+ maxFs: MAX_FS_360p,
1311
+ maxMbps: MAX_MBPS_360p,
1312
+ },
1313
+ {
1314
+ policy: 'receiver-selected',
1315
+ csi: 201,
1316
+ receiveSlot: fakeWcmeSlots[4],
1317
+ maxPayloadBitsPerSecond: MAX_PAYLOADBITSPS_720p,
1318
+ maxFs: MAX_FS_720p,
1319
+ maxMbps: MAX_MBPS_720p,
1320
+ },
1321
+ ], {preferLiveVideo});
1322
+ });
1323
+
1324
+ it('trims all AS requests completely until setNumCurrentSources() is called with non-zero values', async () => {
1325
+ // add some receiver-selected and active-speaker requests
1326
+ addReceiverSelectedRequest(200, fakeReceiveSlots[0], MAX_FS_360p, false);
1327
+ addActiveSpeakerRequest(
1328
+ 255,
1329
+ [fakeReceiveSlots[1], fakeReceiveSlots[2], fakeReceiveSlots[3]],
1330
+ MAX_FS_360p,
1331
+ false,
1332
+ preferLiveVideo
1333
+ );
1334
+ addActiveSpeakerRequest(
1335
+ 254,
1336
+ [fakeReceiveSlots[5]],
1337
+ MAX_FS_360p,
1338
+ false,
1339
+ preferLiveVideo
1340
+ );
1341
+
1342
+ mediaRequestManager.commit();
1343
+
1344
+ // we're not calling setNumCurrentSources(), so it should use the initial values of 0 for sources count
1345
+ // and completely trim all AS requests to 0
1346
+ checkMediaRequestsSent([
1347
+ {
1348
+ policy: 'receiver-selected',
1349
+ csi: 200,
1350
+ receiveSlot: fakeWcmeSlots[0],
1351
+ maxPayloadBitsPerSecond: MAX_PAYLOADBITSPS_360p,
1352
+ maxFs: MAX_FS_360p,
1353
+ maxMbps: MAX_MBPS_360p,
1354
+ },
1355
+ ], {preferLiveVideo});
1356
+ });
1357
+
1358
+ it('resets num of sources to 0 when reset() is called', async () => {
1359
+ // set available streams to non-zero value
1360
+ limitNumAvailableStreams(preferLiveVideo, 4);
1361
+ sendMediaRequestsCallback.resetHistory();
1362
+
1363
+ // do the reset
1364
+ mediaRequestManager.reset();
1365
+
1366
+ // add some receiver-selected and active-speaker requests
1367
+ addReceiverSelectedRequest(200, fakeReceiveSlots[0], MAX_FS_360p, false);
1368
+ addActiveSpeakerRequest(
1369
+ 255,
1370
+ [fakeReceiveSlots[1], fakeReceiveSlots[2], fakeReceiveSlots[3]],
1371
+ MAX_FS_360p,
1372
+ false,
1373
+ preferLiveVideo
1374
+ );
1375
+
1376
+ mediaRequestManager.commit();
1377
+
1378
+ // verify that AS request was trimmed to 0, because we've reset mediaRequestManager so available streams count is 0 now
1379
+ checkMediaRequestsSent([
1380
+ {
1381
+ policy: 'receiver-selected',
1382
+ csi: 200,
1383
+ receiveSlot: fakeWcmeSlots[0],
1384
+ maxPayloadBitsPerSecond: MAX_PAYLOADBITSPS_360p,
1385
+ maxFs: MAX_FS_360p,
1386
+ maxMbps: MAX_MBPS_360p,
1387
+ },
1388
+ ], {preferLiveVideo});
1389
+ });
1390
+ })
1391
+ );
1392
+
1393
+
1394
+ it('throws if there are 2 active-speaker requests with different preferLiveVideo values', () => {
1395
+ addActiveSpeakerRequest(
1396
+ 255,
1397
+ [fakeReceiveSlots[0]],
1398
+ MAX_FS_360p,
1399
+ false,
1400
+ true
1401
+ );
1402
+ addReceiverSelectedRequest(201, fakeReceiveSlots[4], MAX_FS_720p, false);
1403
+ addActiveSpeakerRequest(
1404
+ 254,
1405
+ [fakeReceiveSlots[2]],
1406
+ MAX_FS_360p,
1407
+ false,
1408
+ false
1409
+ );
1410
+
1411
+ assert.throws(() => mediaRequestManager.commit(), 'a mix of active-speaker groups with different values for preferLiveVideo is not supported');
1412
+ })
1413
+ })
515
1414
  });
1415
+ function assertEqual(arg0: any, arg1: string) {
1416
+ throw new Error('Function not implemented.');
1417
+ }
1418
+