@webex/plugin-meetings 2.59.3-next.1 → 2.59.4-next.1

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 (420) hide show
  1. package/.eslintrc.js +6 -6
  2. package/LICENSE +1 -1
  3. package/README.md +1204 -1204
  4. package/UPGRADING.md +287 -287
  5. package/babel.config.js +3 -3
  6. package/browsers.js +108 -108
  7. package/dist/common/browser-detection.js +2 -2
  8. package/dist/common/browser-detection.js.map +1 -1
  9. package/dist/common/collection.js +45 -45
  10. package/dist/common/collection.js.map +1 -1
  11. package/dist/common/config.js.map +1 -1
  12. package/dist/common/errors/captcha-error.js +7 -7
  13. package/dist/common/errors/captcha-error.js.map +1 -1
  14. package/dist/common/errors/intent-to-join.js +7 -7
  15. package/dist/common/errors/intent-to-join.js.map +1 -1
  16. package/dist/common/errors/join-meeting.js +8 -8
  17. package/dist/common/errors/join-meeting.js.map +1 -1
  18. package/dist/common/errors/media.js +7 -7
  19. package/dist/common/errors/media.js.map +1 -1
  20. package/dist/common/errors/parameter.js +7 -7
  21. package/dist/common/errors/parameter.js.map +1 -1
  22. package/dist/common/errors/password-error.js +7 -7
  23. package/dist/common/errors/password-error.js.map +1 -1
  24. package/dist/common/errors/permission.js +6 -6
  25. package/dist/common/errors/permission.js.map +1 -1
  26. package/dist/common/errors/reconnection-in-progress.js +6 -6
  27. package/dist/common/errors/reconnection-in-progress.js.map +1 -1
  28. package/dist/common/errors/reconnection.js +7 -7
  29. package/dist/common/errors/reconnection.js.map +1 -1
  30. package/dist/common/errors/stats.js +7 -7
  31. package/dist/common/errors/stats.js.map +1 -1
  32. package/dist/common/errors/webex-errors.js +42 -42
  33. package/dist/common/errors/webex-errors.js.map +1 -1
  34. package/dist/common/errors/webex-meetings-error.js +12 -12
  35. package/dist/common/errors/webex-meetings-error.js.map +1 -1
  36. package/dist/common/events/events-scope.js +10 -10
  37. package/dist/common/events/events-scope.js.map +1 -1
  38. package/dist/common/events/events.js +4 -4
  39. package/dist/common/events/events.js.map +1 -1
  40. package/dist/common/events/trigger-proxy.js.map +1 -1
  41. package/dist/common/events/util.js.map +1 -1
  42. package/dist/common/logs/logger-config.js.map +1 -1
  43. package/dist/common/logs/logger-proxy.js.map +1 -1
  44. package/dist/common/logs/request.js +18 -18
  45. package/dist/common/logs/request.js.map +1 -1
  46. package/dist/common/queue.js +18 -18
  47. package/dist/common/queue.js.map +1 -1
  48. package/dist/config.js.map +1 -1
  49. package/dist/constants.js +9 -9
  50. package/dist/constants.js.map +1 -1
  51. package/dist/controls-options-manager/constants.js.map +1 -1
  52. package/dist/controls-options-manager/enums.js.map +1 -1
  53. package/dist/controls-options-manager/index.js +83 -83
  54. package/dist/controls-options-manager/index.js.map +1 -1
  55. package/dist/controls-options-manager/util.js.map +1 -1
  56. package/dist/index.js.map +1 -1
  57. package/dist/locus-info/controlsUtils.js +27 -27
  58. package/dist/locus-info/controlsUtils.js.map +1 -1
  59. package/dist/locus-info/embeddedAppsUtils.js +14 -14
  60. package/dist/locus-info/embeddedAppsUtils.js.map +1 -1
  61. package/dist/locus-info/fullState.js.map +1 -1
  62. package/dist/locus-info/hostUtils.js +19 -19
  63. package/dist/locus-info/hostUtils.js.map +1 -1
  64. package/dist/locus-info/index.js +198 -198
  65. package/dist/locus-info/index.js.map +1 -1
  66. package/dist/locus-info/infoUtils.js.map +1 -1
  67. package/dist/locus-info/mediaSharesUtils.js +50 -50
  68. package/dist/locus-info/mediaSharesUtils.js.map +1 -1
  69. package/dist/locus-info/parser.js +138 -138
  70. package/dist/locus-info/parser.js.map +1 -1
  71. package/dist/locus-info/selfUtils.js +52 -52
  72. package/dist/locus-info/selfUtils.js.map +1 -1
  73. package/dist/media/index.js +145 -145
  74. package/dist/media/index.js.map +1 -1
  75. package/dist/media/properties.js +49 -49
  76. package/dist/media/properties.js.map +1 -1
  77. package/dist/media/util.js.map +1 -1
  78. package/dist/mediaQualityMetrics/config.js.map +1 -1
  79. package/dist/meeting/effectsState.js +24 -24
  80. package/dist/meeting/effectsState.js.map +1 -1
  81. package/dist/meeting/in-meeting-actions.js +11 -11
  82. package/dist/meeting/in-meeting-actions.js.map +1 -1
  83. package/dist/meeting/index.js +1505 -1508
  84. package/dist/meeting/index.js.map +1 -1
  85. package/dist/meeting/muteState.js +85 -85
  86. package/dist/meeting/muteState.js.map +1 -1
  87. package/dist/meeting/request.js +143 -143
  88. package/dist/meeting/request.js.map +1 -1
  89. package/dist/meeting/state.js +30 -30
  90. package/dist/meeting/state.js.map +1 -1
  91. package/dist/meeting/util.js +4 -4
  92. package/dist/meeting/util.js.map +1 -1
  93. package/dist/meeting-info/collection.js +13 -13
  94. package/dist/meeting-info/collection.js.map +1 -1
  95. package/dist/meeting-info/index.js +50 -50
  96. package/dist/meeting-info/index.js.map +1 -1
  97. package/dist/meeting-info/meeting-info-v2.js +52 -52
  98. package/dist/meeting-info/meeting-info-v2.js.map +1 -1
  99. package/dist/meeting-info/request.js +14 -14
  100. package/dist/meeting-info/request.js.map +1 -1
  101. package/dist/meeting-info/util.js +9 -9
  102. package/dist/meeting-info/util.js.map +1 -1
  103. package/dist/meeting-info/utilv2.js +20 -20
  104. package/dist/meeting-info/utilv2.js.map +1 -1
  105. package/dist/meetings/collection.js +16 -16
  106. package/dist/meetings/collection.js.map +1 -1
  107. package/dist/meetings/index.js +259 -259
  108. package/dist/meetings/index.js.map +1 -1
  109. package/dist/meetings/request.js +15 -15
  110. package/dist/meetings/request.js.map +1 -1
  111. package/dist/meetings/util.js +29 -29
  112. package/dist/meetings/util.js.map +1 -1
  113. package/dist/member/index.js +214 -214
  114. package/dist/member/index.js.map +1 -1
  115. package/dist/member/member.types.js.map +1 -1
  116. package/dist/member/util.js +60 -60
  117. package/dist/member/util.js.map +1 -1
  118. package/dist/members/collection.js +11 -11
  119. package/dist/members/collection.js.map +1 -1
  120. package/dist/members/index.js +277 -277
  121. package/dist/members/index.js.map +1 -1
  122. package/dist/members/request.js +27 -27
  123. package/dist/members/request.js.map +1 -1
  124. package/dist/members/util.js +21 -21
  125. package/dist/members/util.js.map +1 -1
  126. package/dist/metrics/config.js.map +1 -1
  127. package/dist/metrics/constants.js.map +1 -1
  128. package/dist/metrics/index.js +92 -92
  129. package/dist/metrics/index.js.map +1 -1
  130. package/dist/networkQualityMonitor/index.js +65 -65
  131. package/dist/networkQualityMonitor/index.js.map +1 -1
  132. package/dist/peer-connection-manager/index.js +87 -87
  133. package/dist/peer-connection-manager/index.js.map +1 -1
  134. package/dist/peer-connection-manager/util.js +9 -9
  135. package/dist/peer-connection-manager/util.js.map +1 -1
  136. package/dist/personal-meeting-room/index.js +67 -67
  137. package/dist/personal-meeting-room/index.js.map +1 -1
  138. package/dist/personal-meeting-room/request.js +7 -7
  139. package/dist/personal-meeting-room/request.js.map +1 -1
  140. package/dist/personal-meeting-room/util.js.map +1 -1
  141. package/dist/reachability/index.js +119 -112
  142. package/dist/reachability/index.js.map +1 -1
  143. package/dist/reachability/request.js +15 -15
  144. package/dist/reachability/request.js.map +1 -1
  145. package/dist/reactions/reactions.js.map +1 -1
  146. package/dist/reactions/reactions.type.js.map +1 -1
  147. package/dist/reconnection-manager/index.js +112 -112
  148. package/dist/reconnection-manager/index.js.map +1 -1
  149. package/dist/recording-controller/enums.js.map +1 -1
  150. package/dist/recording-controller/index.js +127 -127
  151. package/dist/recording-controller/index.js.map +1 -1
  152. package/dist/recording-controller/util.js.map +1 -1
  153. package/dist/roap/collection.js.map +1 -1
  154. package/dist/roap/handler.js +27 -27
  155. package/dist/roap/handler.js.map +1 -1
  156. package/dist/roap/index.js +111 -111
  157. package/dist/roap/index.js.map +1 -1
  158. package/dist/roap/request.js +17 -17
  159. package/dist/roap/request.js.map +1 -1
  160. package/dist/roap/state.js +14 -14
  161. package/dist/roap/state.js.map +1 -1
  162. package/dist/roap/turnDiscovery.js +46 -46
  163. package/dist/roap/turnDiscovery.js.map +1 -1
  164. package/dist/roap/util.js.map +1 -1
  165. package/dist/statsAnalyzer/global.js.map +1 -1
  166. package/dist/statsAnalyzer/index.js +130 -130
  167. package/dist/statsAnalyzer/index.js.map +1 -1
  168. package/dist/statsAnalyzer/mqaUtil.js +15 -15
  169. package/dist/statsAnalyzer/mqaUtil.js.map +1 -1
  170. package/dist/transcription/index.js +42 -42
  171. package/dist/transcription/index.js.map +1 -1
  172. package/internal-README.md +172 -172
  173. package/jest.config.js +3 -3
  174. package/package.json +15 -15
  175. package/process +1 -1
  176. package/src/common/browser-detection.ts +39 -39
  177. package/src/common/collection.ts +94 -94
  178. package/src/common/config.ts +9 -9
  179. package/src/common/errors/captcha-error.ts +25 -25
  180. package/src/common/errors/intent-to-join.ts +27 -27
  181. package/src/common/errors/join-meeting.ts +32 -32
  182. package/src/common/errors/media.ts +25 -25
  183. package/src/common/errors/parameter.ts +33 -33
  184. package/src/common/errors/password-error.ts +25 -25
  185. package/src/common/errors/permission.ts +24 -24
  186. package/src/common/errors/reconnection-in-progress.ts +8 -8
  187. package/src/common/errors/reconnection.ts +25 -25
  188. package/src/common/errors/stats.ts +25 -25
  189. package/src/common/errors/webex-errors.ts +140 -140
  190. package/src/common/errors/webex-meetings-error.ts +35 -35
  191. package/src/common/events/events-scope.ts +30 -30
  192. package/src/common/events/events.ts +25 -25
  193. package/src/common/events/trigger-proxy.ts +25 -25
  194. package/src/common/events/util.ts +39 -39
  195. package/src/common/logs/logger-config.ts +8 -8
  196. package/src/common/logs/logger-proxy.ts +44 -44
  197. package/src/common/logs/request.ts +65 -65
  198. package/src/common/queue.ts +50 -50
  199. package/src/config.ts +96 -96
  200. package/src/constants.ts +1121 -1121
  201. package/src/controls-options-manager/constants.ts +5 -5
  202. package/src/controls-options-manager/enums.ts +6 -6
  203. package/src/controls-options-manager/index.ts +183 -183
  204. package/src/controls-options-manager/util.ts +20 -20
  205. package/src/index.js +15 -15
  206. package/src/locus-info/controlsUtils.ts +112 -112
  207. package/src/locus-info/embeddedAppsUtils.ts +57 -57
  208. package/src/locus-info/fullState.ts +69 -69
  209. package/src/locus-info/hostUtils.ts +60 -60
  210. package/src/locus-info/index.ts +1303 -1303
  211. package/src/locus-info/infoUtils.ts +101 -101
  212. package/src/locus-info/mediaSharesUtils.ts +173 -173
  213. package/src/locus-info/parser.ts +680 -680
  214. package/src/locus-info/selfUtils.ts +428 -428
  215. package/src/media/index.ts +675 -675
  216. package/src/media/properties.ts +313 -313
  217. package/src/media/util.ts +37 -37
  218. package/src/mediaQualityMetrics/config.ts +382 -382
  219. package/src/meeting/effectsState.ts +209 -209
  220. package/src/meeting/in-meeting-actions.ts +153 -153
  221. package/src/meeting/index.ts +6537 -6537
  222. package/src/meeting/muteState.ts +365 -365
  223. package/src/meeting/request.ts +810 -810
  224. package/src/meeting/state.ts +194 -194
  225. package/src/meeting/util.ts +530 -530
  226. package/src/meeting-info/collection.ts +41 -41
  227. package/src/meeting-info/index.ts +137 -137
  228. package/src/meeting-info/meeting-info-v2.ts +273 -273
  229. package/src/meeting-info/request.ts +46 -46
  230. package/src/meeting-info/util.ts +314 -314
  231. package/src/meeting-info/utilv2.ts +324 -324
  232. package/src/meetings/collection.ts +43 -43
  233. package/src/meetings/index.ts +1128 -1128
  234. package/src/meetings/request.ts +81 -81
  235. package/src/meetings/util.ts +181 -181
  236. package/src/member/index.ts +446 -446
  237. package/src/member/member.types.ts +13 -13
  238. package/src/member/util.ts +286 -286
  239. package/src/members/collection.ts +40 -40
  240. package/src/members/index.ts +900 -900
  241. package/src/members/request.ts +175 -175
  242. package/src/members/util.ts +260 -260
  243. package/src/metrics/config.ts +485 -485
  244. package/src/metrics/constants.ts +61 -61
  245. package/src/metrics/index.ts +543 -543
  246. package/src/networkQualityMonitor/index.ts +211 -211
  247. package/src/peer-connection-manager/index.ts +847 -847
  248. package/src/peer-connection-manager/util.ts +119 -119
  249. package/src/personal-meeting-room/index.ts +157 -157
  250. package/src/personal-meeting-room/request.ts +48 -48
  251. package/src/personal-meeting-room/util.ts +49 -49
  252. package/src/reachability/index.ts +478 -478
  253. package/src/reachability/request.ts +81 -81
  254. package/src/reactions/reactions.ts +104 -104
  255. package/src/reactions/reactions.type.ts +36 -36
  256. package/src/reconnection-manager/index.ts +622 -622
  257. package/src/recording-controller/enums.ts +8 -8
  258. package/src/recording-controller/index.ts +315 -315
  259. package/src/recording-controller/util.ts +58 -58
  260. package/src/roap/collection.ts +62 -62
  261. package/src/roap/handler.ts +294 -294
  262. package/src/roap/index.ts +413 -413
  263. package/src/roap/request.ts +229 -229
  264. package/src/roap/state.ts +156 -156
  265. package/src/roap/turnDiscovery.ts +283 -283
  266. package/src/roap/util.ts +100 -100
  267. package/src/statsAnalyzer/global.ts +128 -128
  268. package/src/statsAnalyzer/index.ts +1266 -1266
  269. package/src/statsAnalyzer/mqaUtil.ts +290 -290
  270. package/src/transcription/index.ts +154 -154
  271. package/test/integration/spec/journey.js +941 -941
  272. package/test/integration/spec/space-meeting.js +457 -457
  273. package/test/integration/spec/transcription.js +55 -55
  274. package/test/unit/spec/common/browser-detection.js +119 -119
  275. package/test/unit/spec/common/queue.js +69 -69
  276. package/test/unit/spec/controls-options-manager/index.js +123 -123
  277. package/test/unit/spec/controls-options-manager/util.js +65 -65
  278. package/test/unit/spec/fixture/locus.js +406 -406
  279. package/test/unit/spec/locus-info/controlsUtils.js +82 -82
  280. package/test/unit/spec/locus-info/embeddedAppsUtils.js +104 -104
  281. package/test/unit/spec/locus-info/index.js +1272 -1272
  282. package/test/unit/spec/locus-info/infoUtils.js +138 -138
  283. package/test/unit/spec/locus-info/lib/BasicSeqCmp.json +975 -975
  284. package/test/unit/spec/locus-info/lib/SeqCmp.json +522 -522
  285. package/test/unit/spec/locus-info/lib/selfConstant.js +286 -286
  286. package/test/unit/spec/locus-info/parser.js +298 -298
  287. package/test/unit/spec/locus-info/selfUtils.js +185 -185
  288. package/test/unit/spec/media/properties.ts +305 -305
  289. package/test/unit/spec/meeting/effectsState.js +281 -281
  290. package/test/unit/spec/meeting/in-meeting-actions.ts +90 -90
  291. package/test/unit/spec/meeting/index.js +5227 -5227
  292. package/test/unit/spec/meeting/muteState.js +430 -430
  293. package/test/unit/spec/meeting/request.js +317 -317
  294. package/test/unit/spec/meeting/utils.js +319 -319
  295. package/test/unit/spec/meeting-info/meetinginfov2.js +376 -376
  296. package/test/unit/spec/meeting-info/request.js +64 -64
  297. package/test/unit/spec/meeting-info/util.js +37 -37
  298. package/test/unit/spec/meeting-info/utilv2.js +330 -330
  299. package/test/unit/spec/meetings/collection.js +52 -52
  300. package/test/unit/spec/meetings/index.js +1375 -1375
  301. package/test/unit/spec/meetings/utils.js +66 -66
  302. package/test/unit/spec/member/index.js +47 -47
  303. package/test/unit/spec/member/util.js +80 -80
  304. package/test/unit/spec/members/index.js +364 -364
  305. package/test/unit/spec/members/request.js +200 -200
  306. package/test/unit/spec/members/utils.js +42 -42
  307. package/test/unit/spec/metrics/index.js +111 -111
  308. package/test/unit/spec/networkQualityMonitor/index.js +99 -99
  309. package/test/unit/spec/peerconnection-manager/index.js +218 -218
  310. package/test/unit/spec/peerconnection-manager/utils.js +49 -49
  311. package/test/unit/spec/peerconnection-manager/utils.test-fixtures.ts +388 -388
  312. package/test/unit/spec/personal-meeting-room/personal-meeting-room.js +29 -29
  313. package/test/unit/spec/reachability/index.ts +50 -50
  314. package/test/unit/spec/reconnection-manager/index.js +206 -206
  315. package/test/unit/spec/recording-controller/index.js +230 -230
  316. package/test/unit/spec/recording-controller/util.js +101 -101
  317. package/test/unit/spec/roap/index.ts +128 -128
  318. package/test/unit/spec/roap/turnDiscovery.ts +372 -372
  319. package/test/unit/spec/roap/util.js +30 -30
  320. package/test/unit/spec/stats-analyzer/index.js +287 -287
  321. package/test/utils/cmr.js +104 -104
  322. package/test/utils/testUtils.js +287 -287
  323. package/test/utils/webex-config.js +77 -77
  324. package/test/utils/webex-test-users.js +82 -82
  325. package/tsconfig.json +5 -5
  326. package/dist/common/browser-detection.d.ts +0 -9
  327. package/dist/common/collection.d.ts +0 -48
  328. package/dist/common/config.d.ts +0 -2
  329. package/dist/common/errors/captcha-error.d.ts +0 -15
  330. package/dist/common/errors/intent-to-join.d.ts +0 -16
  331. package/dist/common/errors/join-meeting.d.ts +0 -17
  332. package/dist/common/errors/media.d.ts +0 -15
  333. package/dist/common/errors/parameter.d.ts +0 -15
  334. package/dist/common/errors/password-error.d.ts +0 -15
  335. package/dist/common/errors/permission.d.ts +0 -14
  336. package/dist/common/errors/reconnection-in-progress.d.ts +0 -9
  337. package/dist/common/errors/reconnection.d.ts +0 -15
  338. package/dist/common/errors/stats.d.ts +0 -15
  339. package/dist/common/errors/webex-errors.d.ts +0 -81
  340. package/dist/common/errors/webex-meetings-error.d.ts +0 -20
  341. package/dist/common/events/events-scope.d.ts +0 -17
  342. package/dist/common/events/events.d.ts +0 -12
  343. package/dist/common/events/trigger-proxy.d.ts +0 -2
  344. package/dist/common/events/util.d.ts +0 -2
  345. package/dist/common/logs/logger-config.d.ts +0 -2
  346. package/dist/common/logs/logger-proxy.d.ts +0 -2
  347. package/dist/common/logs/request.d.ts +0 -34
  348. package/dist/common/queue.d.ts +0 -32
  349. package/dist/config.d.ts +0 -73
  350. package/dist/constants.d.ts +0 -924
  351. package/dist/controls-options-manager/constants.d.ts +0 -4
  352. package/dist/controls-options-manager/enums.d.ts +0 -5
  353. package/dist/controls-options-manager/index.d.ts +0 -120
  354. package/dist/controls-options-manager/util.d.ts +0 -7
  355. package/dist/index.d.ts +0 -4
  356. package/dist/locus-info/controlsUtils.d.ts +0 -2
  357. package/dist/locus-info/embeddedAppsUtils.d.ts +0 -2
  358. package/dist/locus-info/fullState.d.ts +0 -2
  359. package/dist/locus-info/hostUtils.d.ts +0 -2
  360. package/dist/locus-info/index.d.ts +0 -269
  361. package/dist/locus-info/infoUtils.d.ts +0 -2
  362. package/dist/locus-info/mediaSharesUtils.d.ts +0 -2
  363. package/dist/locus-info/parser.d.ts +0 -212
  364. package/dist/locus-info/selfUtils.d.ts +0 -2
  365. package/dist/media/index.d.ts +0 -32
  366. package/dist/media/properties.d.ts +0 -108
  367. package/dist/media/util.d.ts +0 -2
  368. package/dist/mediaQualityMetrics/config.d.ts +0 -233
  369. package/dist/meeting/effectsState.d.ts +0 -42
  370. package/dist/meeting/in-meeting-actions.d.ts +0 -79
  371. package/dist/meeting/index.d.ts +0 -1621
  372. package/dist/meeting/muteState.d.ts +0 -116
  373. package/dist/meeting/request.d.ts +0 -255
  374. package/dist/meeting/state.d.ts +0 -9
  375. package/dist/meeting/util.d.ts +0 -2
  376. package/dist/meeting-info/collection.d.ts +0 -20
  377. package/dist/meeting-info/index.d.ts +0 -57
  378. package/dist/meeting-info/meeting-info-v2.d.ts +0 -93
  379. package/dist/meeting-info/request.d.ts +0 -22
  380. package/dist/meeting-info/util.d.ts +0 -2
  381. package/dist/meeting-info/utilv2.d.ts +0 -2
  382. package/dist/meetings/collection.d.ts +0 -23
  383. package/dist/meetings/index.d.ts +0 -296
  384. package/dist/meetings/request.d.ts +0 -27
  385. package/dist/meetings/util.d.ts +0 -18
  386. package/dist/member/index.d.ts +0 -147
  387. package/dist/member/member.types.d.ts +0 -11
  388. package/dist/member/util.d.ts +0 -2
  389. package/dist/members/collection.d.ts +0 -24
  390. package/dist/members/index.d.ts +0 -298
  391. package/dist/members/request.d.ts +0 -50
  392. package/dist/members/util.d.ts +0 -2
  393. package/dist/metrics/config.d.ts +0 -169
  394. package/dist/metrics/constants.d.ts +0 -57
  395. package/dist/metrics/index.d.ts +0 -152
  396. package/dist/networkQualityMonitor/index.d.ts +0 -70
  397. package/dist/peer-connection-manager/index.d.ts +0 -6
  398. package/dist/peer-connection-manager/util.d.ts +0 -6
  399. package/dist/personal-meeting-room/index.d.ts +0 -47
  400. package/dist/personal-meeting-room/request.d.ts +0 -14
  401. package/dist/personal-meeting-room/util.d.ts +0 -2
  402. package/dist/reachability/index.d.ts +0 -139
  403. package/dist/reachability/request.d.ts +0 -35
  404. package/dist/reactions/reactions.d.ts +0 -4
  405. package/dist/reactions/reactions.type.d.ts +0 -32
  406. package/dist/reconnection-manager/index.d.ts +0 -112
  407. package/dist/recording-controller/enums.d.ts +0 -7
  408. package/dist/recording-controller/index.d.ts +0 -193
  409. package/dist/recording-controller/util.d.ts +0 -13
  410. package/dist/roap/collection.d.ts +0 -10
  411. package/dist/roap/handler.d.ts +0 -47
  412. package/dist/roap/index.d.ts +0 -116
  413. package/dist/roap/request.d.ts +0 -35
  414. package/dist/roap/state.d.ts +0 -9
  415. package/dist/roap/turnDiscovery.d.ts +0 -67
  416. package/dist/roap/util.d.ts +0 -2
  417. package/dist/statsAnalyzer/global.d.ts +0 -126
  418. package/dist/statsAnalyzer/index.d.ts +0 -190
  419. package/dist/statsAnalyzer/mqaUtil.d.ts +0 -22
  420. package/dist/transcription/index.d.ts +0 -64
package/README.md CHANGED
@@ -1,1204 +1,1204 @@
1
- # @webex/plugin-meetings
2
-
3
- [![standard-readme compliant](https://img.shields.io/badge/readme%20style-standard-brightgreen.svg?style=flat-square)](https://github.com/RichardLitt/standard-readme)
4
-
5
- > Meetings plugin for the Cisco Webex JS SDK.
6
-
7
- - [Install](#install)
8
- - [Usage](#usage)
9
- - [Important Changes](#important-changes)
10
- - [Development](#development)
11
- - [Contribute](#contribute)
12
- - [Maintainers](#maintainers)
13
- - [License](#license)
14
-
15
- # WARNING: This plugin is currently under active development
16
-
17
- ## Install
18
-
19
- ```bash
20
- npm install --save @webex/plugin-meetings
21
- ```
22
-
23
- ## Usage
24
-
25
- This is a plugin for the Cisco Webex JS SDK . Please see our [developer portal](https://developer.webex.com/) and the [API docs](https://webex.github.io/webex-js-sdk/api/) for full details.
26
-
27
- ## Important Changes
28
-
29
- - Version `0.109.0` - Participant email has been removed to reduce PII. Please use participant identity (`members.membersCollection.members[id].participant.identity`) to lookup participant details via the [/people](https://developer.webex.com/docs/api/v1/people/get-person-details) endpoint.
30
-
31
- ## API Docs and Sample App
32
-
33
- API Docs: https://webex.github.io/webex-js-sdk/api/
34
- Hosted Sample App: https://webex.github.io/webex-js-sdk/samples/browser-plugin-meetings/
35
- See https://github.com/webex/webex-js-sdk/tree/master/docs/samples/browser-plugin-meetings for the sample app code vs the readme
36
-
37
- #### Device Registration
38
-
39
- The meetings plugin relies on websocket data to function. The user's device needs to register and connect to the web socket server.
40
-
41
- These setup actions are handled with the `register` function.
42
-
43
- This function registers the device, connects web sockets, and listens for meeting events.
44
-
45
- ```js
46
- webex.meetings.register();
47
- ```
48
-
49
- #### Device Unregistration
50
-
51
- The inverse of the `register()` function is available as well.
52
- This function stops listening for meeting events, disconnects from web sockets and unregisters the device.
53
-
54
- ```js
55
- webex.meetings.unregister();
56
- ```
57
-
58
- #### Creating a basic meeting
59
-
60
- ##### Via [developer portal room id](https://developer.webex.com/docs/api/v1/rooms)
61
-
62
- ```javascript
63
- let roomId = `Y2lzY29zcGFyazovL3VzL1JPT00vNWZhMWUzODAtZTkzZS0xMWU5LTgyZTEtOGRmYTg5ZTgzMjJm `;
64
- return webex.meetings.create(roomId).then((meeting) ==> {...});
65
- ```
66
-
67
- ##### Via [developer portal people id](https://developer.webex.com/docs/api/v1/people)
68
-
69
- ```javascript
70
- let peopleId = `Y2lzY29zcGFyazovL3VzL1BFT1BMRS8wMDAwMDAwMC0wMDAwLTAwMDAtMDAwMC0wMDAwMDAwMDAwMDAw `;
71
- return webex.meetings.create(peopleId).then((meeting) ==> {...});
72
- ```
73
-
74
- ##### Via conversation url
75
-
76
- ```javascript
77
- let conversationUrl = `https://conv-a.wbx2.com/conversation/api/v1/ObiwanAnnouncementsConversationUUID`;
78
- return webex.meetings.create(conversationUrl).then((meeting) ==> {...});
79
- ```
80
-
81
- ##### Via SIP URI
82
-
83
- ```javascript
84
- let sipUri = `obiwan@example.com`;
85
- return webex.meetings.create(sipUri).then((meeting) ==> {...});
86
- ```
87
-
88
- ##### Via Locus Object
89
-
90
- ```javascript
91
- // unlikely to be used
92
- return webex.meetings.create(locusObj, 'LOCUS_ID').then((meeting) ==> {...});
93
- ```
94
-
95
- #### Meetings
96
-
97
- ##### List Active Meetings
98
-
99
- We want to sync our meetings collection with the server.
100
-
101
- ```js
102
- let existingMeetings;
103
- // Sync Meetings From Server
104
- webex.meetings.syncMeetings().then(() => {
105
- // Existing meetings live in the meeting collection
106
- existingMeetings = webex.meetings.getAllMeetings();
107
- });
108
- ```
109
-
110
- ##### Get a Meeting
111
-
112
- ```js
113
- webex.meetings.getMeetingByType('SIP_URI', sipUri);
114
- ```
115
-
116
- ##### Properties
117
-
118
- ```js
119
- webex.meetings.personalMeetingRoom; // the personal meeting room instance
120
- webex.meetings.reachability; // the reachability instance, not initialized until after setReachability is called
121
- webex.meetings.meetingCollection; // the collection of meetings instance
122
- webex.meetings.meetingInfo; // the meeting info instance
123
- ```
124
-
125
- ##### Media
126
-
127
- After a meeting is created and joined, the media from the meeting needs to be connected.
128
-
129
- ###### Local Media
130
-
131
- To get the local device media we use the function on the meeting object `getMediaStreams`. This takes an options object of which media streams to enable:
132
-
133
- ```js
134
- const mediaSettings = {
135
- receiveVideo: true,
136
- receiveAudio: true,
137
- receiveShare: true,
138
- sendVideo: true,
139
- sendAudio: true,
140
- sendShare: false,
141
- };
142
-
143
- const myStreams = {};
144
- meeting
145
- .getMediaStreams(mediaSettings)
146
- .then(([localStream, localShare]) => {
147
- return {localStream, localShare};
148
- })
149
- .then((streams) => {
150
- myStreams.localStream = streams.localStream;
151
- myStreams.localShare = streams.localShare;
152
- });
153
- ```
154
-
155
- This local stream is now ready to be added to the DOM for a self preview via:
156
-
157
- ```html
158
- <video id="localvideo" muted="true" autoplay playsinline></video>
159
- ```
160
-
161
- ```js
162
- document.getElementById('localvideo').srcObject = myStreams.localStream;
163
- ```
164
-
165
- ##### Add Media
166
-
167
- Once you have your local streams and shares, you need to add the media to the meeting with the `addMedia` function.
168
-
169
- ```js
170
- meeting
171
- .addMedia({
172
- localShare,
173
- localStream,
174
- mediaSettings,
175
- })
176
- .then((mediaResponse) => {
177
- // do something once you know media has been completed
178
- });
179
- ```
180
-
181
- #### Join a meeting
182
-
183
- ##### Basic Join
184
-
185
- One can join a meeting without adding a media to just be present in the meeting without send/receive
186
- Once a meeting object has been created, to start it, simply `join` it.
187
-
188
- ```javascript
189
- let destination = `obiwan@example.com`; // email example
190
- return webex.meetings.create(destination).then((meeting) => {
191
- activeMeeting = meeting;
192
- // attach listeners or other actions
193
- activeMeeting.join().then(() => {
194
- // now the meeting is joined!
195
- // now you can addMedia
196
- });
197
- });
198
- ```
199
-
200
- ##### Full Example
201
-
202
- ```javascript
203
- let activeMeeting;
204
-
205
- const mediaSettings = {
206
- receiveVideo: true,
207
- receiveAudio: true,
208
- receiveShare: true,
209
- sendVideo: true,
210
- sendAudio: true,
211
- sendShare: false
212
- };
213
-
214
- const myStreams = {}
215
-
216
- function setMedia(media){
217
- if (media.type === 'local') {
218
- document.getElementById('<videoId>').srcObject = media.stream;
219
- } else if (media.type === 'remote') {
220
- document.getElementById('<videoId>').srcObject = media.stream;
221
- }
222
- }
223
-
224
- function handleAudioChange(audio){
225
- // perform some actions after audio has been muted/unmuted
226
- }
227
-
228
- function handleVideoChange(video) {
229
- // perform some action after video has been muted/unmuted
230
- }
231
-
232
- return webex.meetings
233
- .create(destination)
234
- .then((meeting) => {
235
- activeMeeting = meeting;
236
- activeMeeting.getMediaStreams(mediaSettings).then(([localStream, localShare]) => {
237
- return {localStream, localShare};
238
- }).then((streams) => {
239
- myStreams.localStream = streams.localStream
240
- myStreams.localShare = streams.localShare
241
- });
242
- activeMeeting.on('media:ready', () => setMedia));
243
- activeMeeting.on('media:audioChanged', handleAudioChange);
244
- activeMeeting.on('media:videoChanged', handleVideoChange);
245
- // join a meeting using resourceId as the destination, i.e., paired to a device and using the device for the call
246
- activeMeeting.join({resourceId: <DeviceId>}).then((joinResponse) => {
247
- activeMeeting.addMedia({
248
- localShare,
249
- localStream,
250
- mediaSettings
251
- }).then((mediaResponse) => {
252
- // do something once you know media has been completed
253
- });
254
- });
255
- });
256
- ```
257
-
258
- ##### Join a PMR
259
-
260
- From above, we build off of the join...
261
-
262
- ##### Join your own claimed PMR
263
-
264
- ```javascript
265
- ...
266
- meeting.join().then((res) => {
267
- // backend services determine you are the owner, so no pin, or moderator flag is required
268
- // now you are in the meeting
269
- });
270
- ...
271
- ```
272
-
273
- ##### Join someone elses claimed PMR
274
-
275
- ```javascript
276
- ...
277
- // join as host (in place of them)
278
- meeting.join({pin: <WebexHostPin>, moderator: true}).then((res) => {
279
- // now you are in the meeting
280
- });
281
- ```
282
-
283
- ```javascript
284
- ...
285
- // join as attendee
286
- meeting.join({pin: <WebexMeetingPin>}).then((res) => {
287
- // if host hasn't started the meeting, now you are in the lobby, else if host has started the meeting, you are in the meeting
288
- });
289
- ```
290
-
291
- ##### Join an unclaimed PMR
292
-
293
- ```javascript
294
- // join as host automatically
295
- meeting.join({pin: <WebexHostPin>, moderator: true}).then((res) => {
296
- // now you are in the meeting
297
- });
298
- ```
299
-
300
- ```javascript
301
- // join as host with ask user option
302
- // join as attendee
303
- meeting.join().then((res) => {
304
- }).catch((err) => {
305
- if (err.joinIntentRequired) {
306
- // at this point you can ask the user to join as host or join as guest
307
- // if join as host, requires a pin
308
- ...
309
- // join as host simply makes the join call again with the proper pin/moderator parameters
310
- meeting.join({pin: <WebexHostPin>, moderator: true}).then(() => {
311
- // you are now in the meeting
312
- });
313
- ...
314
- // join as guest simply makes the call again with moderator parameter
315
- meeting.join(({moderator: false})).then(() => {
316
- // if host hasn't started the meeting, now you are in the lobby, else if host has started the meeting, you are in the meeting
317
- });
318
- }
319
- });
320
- ```
321
-
322
- ##### Join an incoming meeting
323
-
324
- When listening to an added meeting, to determine if it is an "incoming" meeting, check the type property of the meeting:
325
-
326
- ```js
327
- webex.meetings.on('meeting:added', (addedMeeting) => {
328
- if (addedMeeting.type === 'INCOMING') {
329
- // Handle incoming meeting
330
- addedMeeting.acknowledge();
331
- addedMeeting.join().then(() => {});
332
- }
333
- ```
334
-
335
- ##### Reject an incoming meeting
336
-
337
- When listening to an added meeting, to determine if it is an "incoming" meeting, check the type property of the meeting:
338
-
339
- ```js
340
- webex.meetings.on('meeting:added', (addedMeeting) => {
341
- if (addedMeeting.type === 'INCOMING') {
342
- // Handle incoming meeting
343
- addedMeeting.decline();
344
- }
345
- ```
346
-
347
- #### Enable receiving meeting real-time transcripts
348
-
349
- In order to receive meeting transcripts, Webex assistant must be enabled for the meeting.
350
-
351
- ```javascript
352
- ...
353
- // Subscribe to transcription events
354
- meeting.on('meeting:receiveTranscription:started', (payload) => {
355
- console.log(payload);
356
- });
357
-
358
- meeting.on('meeting:receiveTranscription:stopped', () => {});
359
-
360
- await meeting.join({receiveTranscription: true});
361
- ```
362
-
363
- ##### Microphone, Speaker and Camera
364
-
365
- Select a different device than the default:
366
-
367
- ```js
368
- const audioInputSelect = document.querySelector('select#audioSource');
369
- const audioOutputSelect = document.querySelector('select#audioOutput');
370
- const videoSelect = document.querySelector('select#videoSource');
371
- ```
372
-
373
- ```js
374
- const audio = {};
375
- const video = {};
376
- const media = {
377
- receiveVideo: boolean,
378
- receiveAudio: boolean,
379
- receiveShare: boolean,
380
- sendShare: boolean,
381
- sendVideo: boolean,
382
- sendAudio: boolean
383
- };
384
-
385
- // setting up the devices
386
- const selectors = [audioInputSelect, audioOutputSelect, videoSelect];
387
-
388
- meeting.getDevices().then((deviceInfos) => {
389
- const values = selectors.map((select) => select.value);
390
-
391
- selectors.forEach((select) => {
392
- while (select.firstChild) {
393
- select.removeChild(select.firstChild);
394
- }
395
- });
396
- for (let i = 0; i !== deviceInfos.length; i += 1) {
397
- const deviceInfo = deviceInfos[i];
398
- const option = document.createElement('option');
399
-
400
- option.value = deviceInfo.deviceId;
401
- if (deviceInfo.kind === 'audioinput') {
402
- option.text = deviceInfo.label || `microphone ${audioInputSelect.length + 1}`;
403
- audioInputSelect.appendChild(option);
404
- }
405
- else if (deviceInfo.kind === 'audiooutput') {
406
- option.text = deviceInfo.label || `speaker ${audioOutputSelect.length + 1}`;
407
- audioOutputSelect.appendChild(option);
408
- }
409
- else if (deviceInfo.kind === 'videoinput') {
410
- option.text = deviceInfo.label || `camera ${videoSelect.length + 1}`;
411
- videoSelect.appendChild(option);
412
- }
413
- else {
414
- console.log('Some other kind of source/device: ', deviceInfo);
415
- }
416
- }
417
- selectors.forEach((select, selectorIndex) => {
418
- if (Array.prototype.slice.call(select.childNodes).some((n) => n.value === values[selectorIndex])) {
419
- select.value = values[selectorIndex];
420
- }
421
- });
422
-
423
- // attaching before the request
424
-
425
- audio.deviceId = {exact: audioInputSelect.value}
426
- video.deviceId = {exact: videoSelect.value}
427
- meeting.getMediaStreams(media, {audio, video}).then(...)
428
- ```
429
-
430
- ###### Changing remote audio output
431
-
432
- ```js
433
- // Attach audio output device to video element using device/sink ID.
434
- function attachSinkId(element, sinkId) {
435
- if (typeof element.sinkId !== 'undefined') {
436
- element
437
- .setSinkId(sinkId)
438
- .then(() => {
439
- console.log(`Success, audio output device attached: ${sinkId}`);
440
- })
441
- .catch((error) => {
442
- let errorMessage = error;
443
-
444
- if (error.name === 'SecurityError') {
445
- errorMessage = `You need to use HTTPS for selecting audio output device: ${error}`;
446
- }
447
- console.error(errorMessage);
448
- // Jump back to first output device in the list as it's the default.
449
- audioOutputSelect.selectedIndex = 0;
450
- });
451
- } else {
452
- console.warn('Browser does not support output device selection.');
453
- }
454
- }
455
-
456
- audioOutputSelect.onchange = function () {
457
- attachSinkId(document.getElementById('remoteaudio'), audioOutputSelect.value);
458
- };
459
- ```
460
-
461
- ##### Record
462
-
463
- ```js
464
- // you can only pause if recording
465
- // you can only start recording if not recording
466
- // you can only resume recording if paused
467
- // you can only pause recording if started
468
- meeting.startRecording();
469
- meeting.pauseRecording();
470
- meeting.resumeRecording();
471
- meeting.stopRecording();
472
- // note, all recording is done in the cloud
473
- // local recording is not yet available for this package
474
- // but is technically possible
475
- // please submit a feature request if desired :)
476
- // https://github.com/webex/webex-js-sdk/blob/master/CONTRIBUTING.md
477
- ```
478
-
479
- ##### Mute Audio or Video
480
-
481
- ```js
482
- meeting.muteAudio();
483
- meeting.muteVideo();
484
- ```
485
-
486
- ##### Unmute Audio or Video
487
-
488
- ```js
489
- meeting.unmuteAudio();
490
- meeting.unmuteVideo();
491
- ```
492
-
493
- ##### Start Sending a Share
494
-
495
- ```js
496
- meeting.shareScreen();
497
- ```
498
-
499
- ##### Stop Sending a Share
500
-
501
- ```js
502
- meeting.stopShare();
503
- ```
504
-
505
- ##### Update Audio/Video Streams
506
-
507
- Use this if you want to change the actual streams send and receive for audio or video component separately; `updateAudio` and `updateVideo` is for the developer to add and remove the streams completely.
508
-
509
- ```js
510
- //video
511
- if (media.sendVideo) {
512
- meeting
513
- .getMediaStreams(
514
- {sendVideo: true},
515
- {video: videoSelect.value ? {deviceId: {exact: videoSelect.value}} : media.sendVideo}
516
- )
517
- .then(([localStream]) =>
518
- meeting.updateVideo({
519
- stream: localStream,
520
- sendVideo: media.sendVideo,
521
- receiveVideo: media.receiveVideo,
522
- })
523
- );
524
- } else {
525
- meeting.updateVideo({
526
- sendVideo: media.sendVideo,
527
- receiveVideo: media.receiveVideo,
528
- });
529
- }
530
- //audio
531
- if (media.sendAudio) {
532
- meeting
533
- .getMediaStreams(media, {
534
- audio: audioInputSelect.value ? {deviceId: {exact: audioInputSelect.value}} : media.sendAudio,
535
- })
536
- .then(([localStream]) =>
537
- meeting.updateAudio({
538
- stream: localStream,
539
- sendAudio: media.sendAudio,
540
- receiveAudio: media.receiveAudio,
541
- })
542
- );
543
- } else {
544
- meeting.updateAudio({
545
- sendAudio: media.sendAudio,
546
- receiveAudio: media.receiveAudio,
547
- });
548
- }
549
- //all in one
550
- meeting.getMediaStreams(media, {audio, video}).then(([localStream, localShare]) =>
551
- meeting.updateMedia({
552
- mediaSettings: media,
553
- localStream,
554
- localShare,
555
- })
556
- );
557
- ```
558
-
559
- ##### Accessing media directly (outside of a meeting)
560
-
561
- You can also directly access the following media properties that are not on a meeting instance
562
-
563
- ```
564
- this.media.getUserMedia(mediaSetting, audioVideo, sharePreferences, config)
565
- ```
566
-
567
- See the [Media](https://github.com/webex/webex-js-sdk/blob/master/packages/node_modules/%40webex/plugin-meetings/src/media/index.js) util file for method signatures.
568
-
569
- ##### Leave a Meeting
570
-
571
- To leave a meeting, simply call leave
572
-
573
- ```js
574
- myMeeting.leave();
575
- ```
576
-
577
- ##### Lock/Unlock a Meeting
578
-
579
- ```js
580
- meeting.lockMeeting();
581
- meeting.unlockMeeting();
582
- ```
583
-
584
- ##### Transfer Host
585
-
586
- ```js
587
- const hostMemberId = ...;
588
- meeting.transfer(hostMemberId);
589
- ```
590
-
591
- ##### Check User Actions
592
-
593
- ```js
594
- meeting.inMeetingActions.get();
595
- {
596
- canInviteNewParticipants: boolean,
597
- canAdmitParticipant: boolean,
598
- canLock: boolean,
599
- canUnlock: boolean,
600
- canAssignHost: boolean,
601
- canStartRecording: boolean,
602
- canPauseRecording: boolean,
603
- canResumeRecording: boolean,
604
- canStopRecording: boolean,
605
- canRaiseHand: boolean,
606
- canLowerAllHands: boolean,
607
- canLowerSomeoneElsesHand: boolean,
608
- bothLeaveAndEndMeetingAvailable: boolean,
609
- }
610
- ```
611
-
612
- #### Personal Meeting Room
613
-
614
- ##### Edit Personal Meeting Room
615
-
616
- ```javascript
617
- const link = ...; // a valid pmr link
618
- const pin = ...; // a valid host pin assoicated to the link
619
- // claiming a pmr, and updating the cached values for the stored PMR
620
- webex.meetings.personalMeetingRoom.claim(link, pin).then((pmr) => {
621
- console.log(pmr); // do something else with the pmr
622
- });
623
- ```
624
-
625
- ##### Get Personal Meeting Room
626
-
627
- ```javascript
628
- webex.meetings.personalMeetingRoom.get().then((pmr) => {
629
- // do some stuff with the pmr values
630
- console.log(`PMR INFO:
631
- link-${webex.meetings.personalMeetingRoom.meetingLink}-
632
- uri-${webex.meetings.personalMeetingRoom.sipUri}-
633
- tollFree-${webex.meetings.personalMeetingRoom.pmr.callInNumbersInfo.callInTollFreeNumber.number}-
634
- toll-${webex.meetings.personalMeetingRoom.pmr.callInNumbersInfo.callInTollNumber.number}-
635
- accessCode-${webex.meetings.personalMeetingRoom.pmr.meetingNumber}
636
- `);
637
- });
638
- ```
639
-
640
- #### Usage of Webex Devices
641
-
642
- For details on how to use the devices see https://github.com/webex/webex-js-sdk/tree/master/packages/node_modules/%40webex/plugin-device-manager
643
-
644
- ##### Leave a Meeting Using a Device
645
-
646
- ```js
647
- const resourceId = ...;
648
-
649
- meeting.leave({resourceId}).then((res) => {
650
- console.log(`successful leave with device, ${res}`);
651
- });
652
- ```
653
-
654
- ##### Leave a Meeting While Paired to the Device, Keep Device in Meeting
655
-
656
- ```js
657
- meeting.leave().then((res) => {
658
- console.log(`successful leave, ${res}`);
659
- });
660
- ```
661
-
662
- ##### Move Meeting To Paired Device
663
-
664
- ```js
665
- const resourceId = ...
666
-
667
- meeting.moveTo(resourceId).then((res) => {
668
- console.log(`successful move to ${res}`);
669
- });
670
- }
671
- ```
672
-
673
- ##### Move Meeting from Paired Device
674
-
675
- ```js
676
- const resourceId = ...
677
-
678
- meeting.moveFrom(resourceId).then((res) => {
679
- console.log(`successful move from ${res}`);
680
- });
681
- ```
682
-
683
- ##### Start Wireless Share
684
-
685
- ```js
686
- const deviceId = ...
687
- // create the meeting
688
- webex.meetings.create(deviceId).then((m) => {
689
- // attach listeners
690
- // then join the meeting
691
- meeting.getMediaStreams({
692
- sendAudio: false,
693
- sendVideo: false,
694
- sendShare: true
695
- }))
696
- .then(([localStream, localShare]) =>
697
- meeting.addMedia({
698
- mediaSettings: {
699
- sendAudio: false,
700
- sendVideo: false,
701
- sendShare: true,
702
- receiveShare: false,
703
- receiveAudio: false,
704
- receiveVideo: false
705
- },
706
- localShare,
707
- localStream
708
- }))
709
- .catch((e) => {
710
- meeting.leave();
711
- console.error('Error wireless screen sharing', e);
712
- });
713
- }
714
- ```
715
-
716
- ##### End Wireless Share
717
-
718
- ```js
719
- meeting.leave();
720
- ```
721
-
722
- ##### Reconnect a Meeting Media
723
-
724
- Warning: not necessary to use manually, internally the sdk listens to mercury reconnect events to determine for a reconnection
725
-
726
- ```js
727
- meeting.reconnect();
728
- ```
729
-
730
- #### Scheduled Meetings
731
-
732
- For scheduled meetings see https://github.com/webex/webex-js-sdk/tree/master/packages/node_modules/%40webex/internal-plugin-calendar
733
-
734
- #### Member
735
-
736
- ##### Properties
737
-
738
- ```javascript
739
- member.participant ... // Object server participant object, advanced use only
740
- member.id ... // String key for storing
741
- member.name ... // String plain text name
742
- member.isAudioMuted ... // Boolean
743
- member.isVideoMuted ... // Boolean
744
- member.isHandRaised ... //Boolean
745
- member.isSelf ... // Boolean is this member YOUR user?
746
- member.isHost ... // Boolean
747
- member.isGuest ... // Boolean
748
- member.isInLobby ... // Boolean
749
- member.isInMeeting ... // Boolean
750
- member.isNotAdmitted ... // Boolean -- waiting to be admitted to the meeting, will also have isInLobby true
751
- member.isContentSharing ... // Boolean
752
- member.status ... // String -- advanced use only
753
- member.isDevice ... // Boolean
754
- member.isUser ... // Boolean
755
- member.associatedUser ... // String -- member.id if isDevice is true
756
- member.isRecording ... // Boolean
757
- member.isMutable ... // Boolean
758
- member.isRemovable ... // Boolean
759
- member.type ... // String
760
- member.isModerator ... // Boolean
761
- member.isModeratorAssignmentProhibited ... // Boolean
762
- ```
763
-
764
- #### Members
765
-
766
- You can access the members object on each individual meeting instance. It has some key events to listen to, and maintains what happens for members of a meeting with some key properties.
767
-
768
- ##### Properties
769
-
770
- ```javascript
771
- meeting.members.membersCollection.members ... // the members collection, object {id0: member0, ... idN: memberN}
772
- meeting.members.locusUrl ... // current locusUrl being used
773
- meeting.members.hostId ... // active host id for the meeting
774
- meeting.members.selfId ... // active self id for the meeting
775
- meeting.members.mediaShareContentId ... // active content sharer id for the meeting
776
- ```
777
-
778
- ##### Functions
779
-
780
- ```javascript
781
- // You can add a guest to the meeting by inviting them, this is proxied by meeting.invite
782
- // use an emailAddress and a boolean value alertIfActive to notify server side (usually true)
783
- meeting.members.addMember(emailAddress, alertIfActive);
784
-
785
- // You can admit the guest to the meeting once they are waiting in the lobby, you can do this in bulk, proxied by meeting.admit
786
- // use member ids, can be singular, but has to be put into an array
787
- meeting.members.admitMembers([memberIds]);
788
-
789
- // You can remove a member from the meeting by booting them, this is proxied by meeting.remove
790
- // use a memberId string
791
- meeting.members.removeMember(memberId);
792
-
793
- // You can audio mute a member from the meeting by calling to mute them, this is proxied by meeting.mute
794
- // use a memberId string and a boolean to mute or not, default to true
795
- // mute them
796
- meeting.members.muteMember(memberId);
797
-
798
- // You can raise or lower the hand of a member from the meeting
799
- // use a memberId string and a "raise" boolean to raise or lower, default to true ("raise the hand")
800
- meeting.members.raiseOrLowerHand(memberId);
801
-
802
- // You can lower all hands in a meeting
803
- // use a memberId string to indicate who is requesting lowering all hands
804
- meeting.members.lowerAllHands(requestingMemberId);
805
-
806
- // You can transfer the host role to another member in the meeting, this is proxied by meeting.transfer
807
- // use a memberId string and a moderator boolean to transfer or not, default to true
808
- meeting.members.transferHostToMember(memberId);
809
- ```
810
-
811
- ##### Events
812
-
813
- ```javascript
814
- // members collection updated
815
- meeting.members.on('members:update', (payload) => {
816
- const delta = payload.delta; // the changes to the members list
817
- const full = payload.full; // the full members collection
818
- const updated = delta.updated; // only the updates, includes removals, as they will have updated status and member properties
819
- const added = delta.added; // added members to the meeting
820
- Object.keys(full).forEach((key) => {
821
- const member = full[key];
822
- console.log(`Member: ... ${member.x}`);
823
- });
824
- Object.keys(updated).forEach((key) => {
825
- const member = updated[key];
826
- console.log(`Member Updated: ... ${member.x}`);
827
- });
828
- Object.keys(added).forEach((key) => {
829
- const member = added[key];
830
- console.log(`Member Added: ... ${member.x}`);
831
- });
832
- });
833
- // content updates
834
- meeting.members.on('members:content:update', (payload) => {
835
- console.log(`who started sharing: ${payload.activeContentSharingId};`);
836
- console.log(`who stopped sharing: ${payload.endedContentSharingId};`);
837
- });
838
- // host updates
839
- meeting.members.on('members:host:update', (payload) => {
840
- console.log(`who started hosting: ${payload.activeHostId};`);
841
- console.log(`who stopped hosting: ${payload.endedHostId};`);
842
- });
843
- // self updates, not typically used
844
- meeting.members.on('members:self:update', (payload) => {
845
- console.log(`active self id: ${payload.activeSelfId};`);
846
- console.log(`ended self Id: ${payload.endedSelfId};`);
847
- });
848
- ```
849
-
850
- ## Events
851
-
852
- ### Meetings Events
853
-
854
- ```js
855
- webex.meetings.on(...)
856
- ```
857
-
858
- | Event Name | Description |
859
- | --------------------- | -------------------------------------------------------------------------------------------------- |
860
- | `meetings:ready` | Fired when the plugin has been instantiated and is ready for action! |
861
- | `meeting:added` | Fired when a meeting has been added to the collection, either incoming, or outgoing, can be joined |
862
- | `meeting:removed` | Fired when a meeting has been deleted from the collection, this meeting cannot be rejoined |
863
- | `media:codec:loaded` | Fired when H.264 media codec has been loaded in the browser. Does not have a payload. |
864
- | `media:codec:missing` | Fired when H.264 media codec appears to be missing from the browser. Does not have a payload. |
865
- | --- | --- |
866
-
867
- `meetings:ready` does not have a payload
868
-
869
- `meeting:added` has the following payload
870
-
871
- ```js
872
- {
873
- meetingId; // the uuid of the meeting removed
874
- type; // string type can be INCOMING, JOIN, or MEETING
875
- }
876
- ```
877
-
878
- `meeting:removed` has the following payload
879
-
880
- ```js
881
- {
882
- meetingId; // the uuid of the meeting removed
883
- response; // a propagated server response
884
- }
885
- ```
886
-
887
- ### Meeting Events
888
-
889
- ```js
890
- meeting.on(...)
891
- ```
892
-
893
- | Event Name | Description |
894
- | -------------------------------------- | ------------------------------------------------------------------------------------------------- |
895
- | `meetings:ready` | Fired when the meetings plugin has been successfully initialized |
896
- | `meetings:registered` | Fired when the meetings plugin has registered the device and is listening to websocket events |
897
- | `meetings:unregistered` | Fired when the meetings plugin has been disconnected from websockets and unregistered as a device |
898
- | `media:ready` | Fired when remote or local media has been acquired |
899
- | `media:stopped` | Fired when remote or local media has been torn down |
900
- | `meeting:media:local:start` | Fired when local media has started sending bytes |
901
- | `meeting:media:remote:start` | Fired when local media has started receiving bytes from the remote audio or video streams |
902
- | `meeting:alerted` | Fired when locus was notified that user received meeting |
903
- | `meeting:ringing` | Fired when meeting should have a ringing sound on repeat |
904
- | `meeting:ringingStop` | Fired when meeting should stop a ringing sound |
905
- | `meeting:startedSharingLocal` | Fired when local screen sharing was started |
906
- | `meeting:stoppedSharingLocal` | Fired when local screen sharing ends |
907
- | `meeting:startedSharingRemote` | Fired when remote screen sharing was started |
908
- | `meeting:stoppedSharingRemote` | Fired when remote screen sharing ends |
909
- | `meeting:self:lobbyWaiting` | Fired when user has entered the lobby for a PMR or the like |
910
- | `meeting:self:guestAdmitted` | Fired when user has entered the meeting after waiting to be admitted from join |
911
- | `meeting:self:mutedByOthers` | Fired when user has been audio muted by another in the muting |
912
- | `meeting:reconnectionStarting` | Fired when a reconnect begins |
913
- | `meeting:reconnectionSuccess` | Fired when the media was reconnected successfully |
914
- | `meeting:reconnectionFailure` | Fired when the media failed to reconnect, user will have to rejoin and connect |
915
- | `meeting:unlocked` | Fired when the meeting was unlocked by the host, for webex type meetings only |
916
- | `meeting:locked` | Fired when the meeting was locked by the host, for webex type meetings only |
917
- | `meeting:actionsUpdate` | Fired when the user has new actions they can take, such as lock, unlock, transferHost |
918
- | `meeting:logUpload:success` | Fired when the meeting logs were successfully uploaded |
919
- | `meeting:logUpload:failure` | Fired when the meeting logs failed to upload |
920
- | `meeting:recording:started` | Fired when member starts recording |
921
- | `meeting:recording:stopped` | Fired when member stops recording |
922
- | `meeting:recording:paused` | Fired when member pauses recording |
923
- | `meeting:recording:resumed` | Fired when member resumes recording |
924
- | `meeting:receiveTranscription:started` | Fired when transcription is received |
925
- | `meeting:receiveTranscription:stopped` | Fired when transcription has stopped from being received |
926
- | `meeting:meetingContainer:update` | Fired when the meetingContainerUrl is updated |
927
- | --- | --- |
928
-
929
- `meetings:ready` does not have a payload
930
-
931
- `meetings:registered` does not have a payload
932
-
933
- `meetings:unregistered` does not have a payload
934
-
935
- `media:ready` has the following payload
936
-
937
- ```javascript
938
- {
939
- type, // local or remote
940
- stream; // the MediaStream
941
- }
942
- // usage
943
- meeting.on('media:ready', (media) => {
944
- if (!media) {
945
- return;
946
- }
947
- if (media.type === 'local') {
948
- document.getElementById('localvideo').srcObject = media.stream;
949
- }
950
- if (media.type === 'remoteVideo') {
951
- document.getElementById('remotevideo').srcObject = media.stream;
952
- }
953
- if (media.type === 'remoteAudio') {
954
- document.getElementById('remoteaudio').srcObject = media.stream;
955
- }
956
- if (media.type === 'remoteShare') {
957
- document.getElementById('sharevideo').srcObject = media.stream;
958
- }
959
- if (media.type === 'localShare') {
960
- document.getElementById('localshare').srcObject = media.stream;
961
- }
962
- });
963
- ```
964
-
965
- `media:stopped` has the following payload
966
-
967
- ```javascript
968
- {
969
- type, // local or remote
970
- }
971
- // usage
972
- meeting.on('media:stopped', (media) => {
973
- if (media.type === 'local') {
974
- document.getElementById('localvideo').srcObject = null;
975
- }
976
- if (media.type === 'remoteVideo') {
977
- document.getElementById('remotevideo').srcObject = null;
978
- }
979
- if (media.type === 'remoteAudio') {
980
- document.getElementById('remoteaudio').srcObject = null;
981
- }
982
- if (media.type === 'localShare') {
983
- document.getElementById('localshare').srcObject = null;
984
- }
985
- if (media.type === 'remoteShare') {
986
- document.getElementById('sharevideo').srcObject = null;
987
- }
988
- });
989
- ```
990
-
991
- `meeting:alerted` does not have a payload
992
-
993
- `meeting:ringing` has the following payload
994
-
995
- ```js
996
- {
997
- type // INCOMING or JOIN
998
- id // the meeting id
999
- }
1000
- ```
1001
-
1002
- `meeting:ringingStop` has the following payload
1003
-
1004
- ```js
1005
- {
1006
- type // Object {remoteAnswered: boolean, remoteDeclined: boolean}
1007
- id // the meeting id
1008
- }
1009
- ```
1010
-
1011
- `meeting:startedSharingLocal` does not have a payload
1012
-
1013
- `meeting:stoppedSharingLocal` does not have a payload
1014
-
1015
- `meeting:self:lobbyWaiting` has the following payload
1016
-
1017
- ```js
1018
- {
1019
- payload; // self object
1020
- }
1021
- ```
1022
-
1023
- `meeting:self:guestAdmitted` has the following payload
1024
-
1025
- ```js
1026
- {
1027
- payload; // self object
1028
- }
1029
- ```
1030
-
1031
- `meeting:self:mutedByOthers` has the following payload
1032
-
1033
- ```js
1034
- {
1035
- payload; // self object
1036
- }
1037
- ```
1038
-
1039
- `meeting:reconnectionStarting` does not have a payload
1040
-
1041
- `meeting:reconnectionSuccess` has the following payload
1042
-
1043
- ```js
1044
- {
1045
- reconnect; // the media promise resolution
1046
- }
1047
- ```
1048
-
1049
- `meeting:reconnectionFailure` has the following payload
1050
-
1051
- ```js
1052
- {
1053
- error; // the forwarded error from media
1054
- }
1055
- ```
1056
-
1057
- `meeting:unlocked` has the following payload
1058
-
1059
- ```js
1060
- {
1061
- info; // info object
1062
- }
1063
- ```
1064
-
1065
- `meeting:locked` has the following payload
1066
-
1067
- ```js
1068
- {
1069
- info; // info object
1070
- }
1071
- ```
1072
-
1073
- `meeting:actionsUpdate` has the following payload
1074
-
1075
- ```js
1076
- {
1077
- canInviteNewParticipants, // boolean
1078
- canAdmitParticipant, // boolean
1079
- canLock, // boolean
1080
- canUnlock, // boolean
1081
- canAssignHost, // boolean
1082
- canStartRecording, // boolean
1083
- canPauseRecording, // boolean
1084
- canResumeRecording, // boolean
1085
- canStopRecording, // boolean
1086
- canRaiseHand, //boolean
1087
- canLowerAllHands, //boolean
1088
- canLowerSomeoneElsesHand, //boolean
1089
- bothLeaveAndEndMeetingAvailable, //boolean
1090
- }
1091
- ```
1092
-
1093
- `meeting:recording:started`
1094
- `meeting:recording:stopped`
1095
- `meeting:recording:paused`
1096
- `meeting:recording:resumed` have the following payload
1097
-
1098
- ```js
1099
- {
1100
- state; // could be etiher `recording`, `idle` or `paused`
1101
- modifiedBy; // user's decrypted ID who made an action
1102
- lastModified; // when the action was made
1103
- }
1104
- ```
1105
-
1106
- ### Event Caveats
1107
-
1108
- ##### Remote screen share is not displayed if started before participant joins
1109
-
1110
- If you notice that the remote screen share is not being displayed to a participant when they join
1111
- after a screen has already been shared, double-check that you are following the standard plugin-meeting workflow.
1112
-
1113
- Standard plugin-meeting workflow is as follows:
1114
-
1115
- 1. Set event listener for `media:ready`
1116
- 2. Call `join()`
1117
- 3. Call `addMedia()` with `options.mediaSettings.receiveShare=true`
1118
- 4. Wait to receive an event from `media:ready` with payload `type=remoteShare` that contains the remote share media stream
1119
- 5. Set `srcObject` of a `video` element in the application to the previously obtained media stream
1120
- (e.g. `document.getElementById('remote-screen').srcObject = media.stream`)
1121
-
1122
- In most cases this will resolve the issue though an extra step could be to
1123
- use `meeting.shareStatus` to control whether to show the video element or not.
1124
-
1125
- This may be necessary as you can only register for events like `meeting:startedSharingRemote` on the
1126
- meeting object, however, you can only do that after you've received the `meeting:added` event notification
1127
- with the meeting payload. In the case when a host has already begun sharing before a participant joins,
1128
- the registration for `meeting:startedSharingRemote` happens too late (after the SDK code that would send
1129
- that event is already executed). Thus, you can check the value of `meeting.shareStatus` when you join the meeting
1130
- to control whether to show that video element (the one that has srcObject set to the remote share stream) on the screen or not.
1131
-
1132
- ### Members Events
1133
-
1134
- ```js
1135
- meeting.members.on(...)
1136
- ```
1137
-
1138
- There are several events submitted by this package that you can subscribe to.
1139
- | Event Name | Description |
1140
- |---|---|
1141
- | `members:update` | Fired when a member in the collection has been updated |
1142
- | `members:content:update` | Fired when a member in the collection has a changed content stream (share screen) |
1143
- | `members:host:update` | Fired when a member in the collection has a changed host value |
1144
- | `members:self:update` | Fired when a member in the collection has a changed self value |
1145
- |---|---|
1146
-
1147
- `members:update` has the following payload
1148
-
1149
- ```js
1150
- {
1151
- delta: { // the changes to the members list
1152
- updated // array only the updates, includes removals, as they will have updated status and member properties
1153
- added // array added members to the meeting
1154
- }
1155
- full: // array the full members collection
1156
- }
1157
- ```
1158
-
1159
- `members:content:update` has the following payload
1160
-
1161
- ```js
1162
- {
1163
- activeContentSharingId; // the member id
1164
- endedContentSharingId; // the member id
1165
- }
1166
- ```
1167
-
1168
- `members:host:update` has the following payload
1169
-
1170
- ```js
1171
- {
1172
- activeHostId; // the member id
1173
- endedHostId; // the member id
1174
- }
1175
- ```
1176
-
1177
- `members:self:update` has the following payload
1178
-
1179
- ```js
1180
- {
1181
- activeSelfId; // the member id
1182
- endedSelfId; // the member id
1183
- }
1184
- ```
1185
-
1186
- ## Development
1187
-
1188
- To use `webpack-dev-server` to load this package, run `yarn run samples:serve`.
1189
-
1190
- Files placed in the `docs/samples/browser-plugin-meetings` folder will be served statically.
1191
-
1192
- Files in the `src` folder will be compiled, bundled, and served as a static asset at `bundle.js` inside that directory.
1193
-
1194
- ## Maintainers
1195
-
1196
- This package is maintained by [Cisco Webex for Developers](https://developer.webex.com/).
1197
-
1198
- ## Contribute
1199
-
1200
- Pull requests welcome. Please see [CONTRIBUTING.md](https://github.com/webex/webex-js-sdk/blob/master/CONTRIBUTING.md) for more details.
1201
-
1202
- ## License
1203
-
1204
- © 2016-2020 Cisco and/or its affiliates. All Rights Reserved.
1
+ # @webex/plugin-meetings
2
+
3
+ [![standard-readme compliant](https://img.shields.io/badge/readme%20style-standard-brightgreen.svg?style=flat-square)](https://github.com/RichardLitt/standard-readme)
4
+
5
+ > Meetings plugin for the Cisco Webex JS SDK.
6
+
7
+ - [Install](#install)
8
+ - [Usage](#usage)
9
+ - [Important Changes](#important-changes)
10
+ - [Development](#development)
11
+ - [Contribute](#contribute)
12
+ - [Maintainers](#maintainers)
13
+ - [License](#license)
14
+
15
+ # WARNING: This plugin is currently under active development
16
+
17
+ ## Install
18
+
19
+ ```bash
20
+ npm install --save @webex/plugin-meetings
21
+ ```
22
+
23
+ ## Usage
24
+
25
+ This is a plugin for the Cisco Webex JS SDK . Please see our [developer portal](https://developer.webex.com/) and the [API docs](https://webex.github.io/webex-js-sdk/api/) for full details.
26
+
27
+ ## Important Changes
28
+
29
+ - Version `0.109.0` - Participant email has been removed to reduce PII. Please use participant identity (`members.membersCollection.members[id].participant.identity`) to lookup participant details via the [/people](https://developer.webex.com/docs/api/v1/people/get-person-details) endpoint.
30
+
31
+ ## API Docs and Sample App
32
+
33
+ API Docs: https://webex.github.io/webex-js-sdk/api/
34
+ Hosted Sample App: https://webex.github.io/webex-js-sdk/samples/browser-plugin-meetings/
35
+ See https://github.com/webex/webex-js-sdk/tree/master/docs/samples/browser-plugin-meetings for the sample app code vs the readme
36
+
37
+ #### Device Registration
38
+
39
+ The meetings plugin relies on websocket data to function. The user's device needs to register and connect to the web socket server.
40
+
41
+ These setup actions are handled with the `register` function.
42
+
43
+ This function registers the device, connects web sockets, and listens for meeting events.
44
+
45
+ ```js
46
+ webex.meetings.register();
47
+ ```
48
+
49
+ #### Device Unregistration
50
+
51
+ The inverse of the `register()` function is available as well.
52
+ This function stops listening for meeting events, disconnects from web sockets and unregisters the device.
53
+
54
+ ```js
55
+ webex.meetings.unregister();
56
+ ```
57
+
58
+ #### Creating a basic meeting
59
+
60
+ ##### Via [developer portal room id](https://developer.webex.com/docs/api/v1/rooms)
61
+
62
+ ```javascript
63
+ let roomId = `Y2lzY29zcGFyazovL3VzL1JPT00vNWZhMWUzODAtZTkzZS0xMWU5LTgyZTEtOGRmYTg5ZTgzMjJm `;
64
+ return webex.meetings.create(roomId).then((meeting) ==> {...});
65
+ ```
66
+
67
+ ##### Via [developer portal people id](https://developer.webex.com/docs/api/v1/people)
68
+
69
+ ```javascript
70
+ let peopleId = `Y2lzY29zcGFyazovL3VzL1BFT1BMRS8wMDAwMDAwMC0wMDAwLTAwMDAtMDAwMC0wMDAwMDAwMDAwMDAw `;
71
+ return webex.meetings.create(peopleId).then((meeting) ==> {...});
72
+ ```
73
+
74
+ ##### Via conversation url
75
+
76
+ ```javascript
77
+ let conversationUrl = `https://conv-a.wbx2.com/conversation/api/v1/ObiwanAnnouncementsConversationUUID`;
78
+ return webex.meetings.create(conversationUrl).then((meeting) ==> {...});
79
+ ```
80
+
81
+ ##### Via SIP URI
82
+
83
+ ```javascript
84
+ let sipUri = `obiwan@example.com`;
85
+ return webex.meetings.create(sipUri).then((meeting) ==> {...});
86
+ ```
87
+
88
+ ##### Via Locus Object
89
+
90
+ ```javascript
91
+ // unlikely to be used
92
+ return webex.meetings.create(locusObj, 'LOCUS_ID').then((meeting) ==> {...});
93
+ ```
94
+
95
+ #### Meetings
96
+
97
+ ##### List Active Meetings
98
+
99
+ We want to sync our meetings collection with the server.
100
+
101
+ ```js
102
+ let existingMeetings;
103
+ // Sync Meetings From Server
104
+ webex.meetings.syncMeetings().then(() => {
105
+ // Existing meetings live in the meeting collection
106
+ existingMeetings = webex.meetings.getAllMeetings();
107
+ });
108
+ ```
109
+
110
+ ##### Get a Meeting
111
+
112
+ ```js
113
+ webex.meetings.getMeetingByType('SIP_URI', sipUri);
114
+ ```
115
+
116
+ ##### Properties
117
+
118
+ ```js
119
+ webex.meetings.personalMeetingRoom; // the personal meeting room instance
120
+ webex.meetings.reachability; // the reachability instance, not initialized until after setReachability is called
121
+ webex.meetings.meetingCollection; // the collection of meetings instance
122
+ webex.meetings.meetingInfo; // the meeting info instance
123
+ ```
124
+
125
+ ##### Media
126
+
127
+ After a meeting is created and joined, the media from the meeting needs to be connected.
128
+
129
+ ###### Local Media
130
+
131
+ To get the local device media we use the function on the meeting object `getMediaStreams`. This takes an options object of which media streams to enable:
132
+
133
+ ```js
134
+ const mediaSettings = {
135
+ receiveVideo: true,
136
+ receiveAudio: true,
137
+ receiveShare: true,
138
+ sendVideo: true,
139
+ sendAudio: true,
140
+ sendShare: false,
141
+ };
142
+
143
+ const myStreams = {};
144
+ meeting
145
+ .getMediaStreams(mediaSettings)
146
+ .then(([localStream, localShare]) => {
147
+ return {localStream, localShare};
148
+ })
149
+ .then((streams) => {
150
+ myStreams.localStream = streams.localStream;
151
+ myStreams.localShare = streams.localShare;
152
+ });
153
+ ```
154
+
155
+ This local stream is now ready to be added to the DOM for a self preview via:
156
+
157
+ ```html
158
+ <video id="localvideo" muted="true" autoplay playsinline></video>
159
+ ```
160
+
161
+ ```js
162
+ document.getElementById('localvideo').srcObject = myStreams.localStream;
163
+ ```
164
+
165
+ ##### Add Media
166
+
167
+ Once you have your local streams and shares, you need to add the media to the meeting with the `addMedia` function.
168
+
169
+ ```js
170
+ meeting
171
+ .addMedia({
172
+ localShare,
173
+ localStream,
174
+ mediaSettings,
175
+ })
176
+ .then((mediaResponse) => {
177
+ // do something once you know media has been completed
178
+ });
179
+ ```
180
+
181
+ #### Join a meeting
182
+
183
+ ##### Basic Join
184
+
185
+ One can join a meeting without adding a media to just be present in the meeting without send/receive
186
+ Once a meeting object has been created, to start it, simply `join` it.
187
+
188
+ ```javascript
189
+ let destination = `obiwan@example.com`; // email example
190
+ return webex.meetings.create(destination).then((meeting) => {
191
+ activeMeeting = meeting;
192
+ // attach listeners or other actions
193
+ activeMeeting.join().then(() => {
194
+ // now the meeting is joined!
195
+ // now you can addMedia
196
+ });
197
+ });
198
+ ```
199
+
200
+ ##### Full Example
201
+
202
+ ```javascript
203
+ let activeMeeting;
204
+
205
+ const mediaSettings = {
206
+ receiveVideo: true,
207
+ receiveAudio: true,
208
+ receiveShare: true,
209
+ sendVideo: true,
210
+ sendAudio: true,
211
+ sendShare: false
212
+ };
213
+
214
+ const myStreams = {}
215
+
216
+ function setMedia(media){
217
+ if (media.type === 'local') {
218
+ document.getElementById('<videoId>').srcObject = media.stream;
219
+ } else if (media.type === 'remote') {
220
+ document.getElementById('<videoId>').srcObject = media.stream;
221
+ }
222
+ }
223
+
224
+ function handleAudioChange(audio){
225
+ // perform some actions after audio has been muted/unmuted
226
+ }
227
+
228
+ function handleVideoChange(video) {
229
+ // perform some action after video has been muted/unmuted
230
+ }
231
+
232
+ return webex.meetings
233
+ .create(destination)
234
+ .then((meeting) => {
235
+ activeMeeting = meeting;
236
+ activeMeeting.getMediaStreams(mediaSettings).then(([localStream, localShare]) => {
237
+ return {localStream, localShare};
238
+ }).then((streams) => {
239
+ myStreams.localStream = streams.localStream
240
+ myStreams.localShare = streams.localShare
241
+ });
242
+ activeMeeting.on('media:ready', () => setMedia));
243
+ activeMeeting.on('media:audioChanged', handleAudioChange);
244
+ activeMeeting.on('media:videoChanged', handleVideoChange);
245
+ // join a meeting using resourceId as the destination, i.e., paired to a device and using the device for the call
246
+ activeMeeting.join({resourceId: <DeviceId>}).then((joinResponse) => {
247
+ activeMeeting.addMedia({
248
+ localShare,
249
+ localStream,
250
+ mediaSettings
251
+ }).then((mediaResponse) => {
252
+ // do something once you know media has been completed
253
+ });
254
+ });
255
+ });
256
+ ```
257
+
258
+ ##### Join a PMR
259
+
260
+ From above, we build off of the join...
261
+
262
+ ##### Join your own claimed PMR
263
+
264
+ ```javascript
265
+ ...
266
+ meeting.join().then((res) => {
267
+ // backend services determine you are the owner, so no pin, or moderator flag is required
268
+ // now you are in the meeting
269
+ });
270
+ ...
271
+ ```
272
+
273
+ ##### Join someone elses claimed PMR
274
+
275
+ ```javascript
276
+ ...
277
+ // join as host (in place of them)
278
+ meeting.join({pin: <WebexHostPin>, moderator: true}).then((res) => {
279
+ // now you are in the meeting
280
+ });
281
+ ```
282
+
283
+ ```javascript
284
+ ...
285
+ // join as attendee
286
+ meeting.join({pin: <WebexMeetingPin>}).then((res) => {
287
+ // if host hasn't started the meeting, now you are in the lobby, else if host has started the meeting, you are in the meeting
288
+ });
289
+ ```
290
+
291
+ ##### Join an unclaimed PMR
292
+
293
+ ```javascript
294
+ // join as host automatically
295
+ meeting.join({pin: <WebexHostPin>, moderator: true}).then((res) => {
296
+ // now you are in the meeting
297
+ });
298
+ ```
299
+
300
+ ```javascript
301
+ // join as host with ask user option
302
+ // join as attendee
303
+ meeting.join().then((res) => {
304
+ }).catch((err) => {
305
+ if (err.joinIntentRequired) {
306
+ // at this point you can ask the user to join as host or join as guest
307
+ // if join as host, requires a pin
308
+ ...
309
+ // join as host simply makes the join call again with the proper pin/moderator parameters
310
+ meeting.join({pin: <WebexHostPin>, moderator: true}).then(() => {
311
+ // you are now in the meeting
312
+ });
313
+ ...
314
+ // join as guest simply makes the call again with moderator parameter
315
+ meeting.join(({moderator: false})).then(() => {
316
+ // if host hasn't started the meeting, now you are in the lobby, else if host has started the meeting, you are in the meeting
317
+ });
318
+ }
319
+ });
320
+ ```
321
+
322
+ ##### Join an incoming meeting
323
+
324
+ When listening to an added meeting, to determine if it is an "incoming" meeting, check the type property of the meeting:
325
+
326
+ ```js
327
+ webex.meetings.on('meeting:added', (addedMeeting) => {
328
+ if (addedMeeting.type === 'INCOMING') {
329
+ // Handle incoming meeting
330
+ addedMeeting.acknowledge();
331
+ addedMeeting.join().then(() => {});
332
+ }
333
+ ```
334
+
335
+ ##### Reject an incoming meeting
336
+
337
+ When listening to an added meeting, to determine if it is an "incoming" meeting, check the type property of the meeting:
338
+
339
+ ```js
340
+ webex.meetings.on('meeting:added', (addedMeeting) => {
341
+ if (addedMeeting.type === 'INCOMING') {
342
+ // Handle incoming meeting
343
+ addedMeeting.decline();
344
+ }
345
+ ```
346
+
347
+ #### Enable receiving meeting real-time transcripts
348
+
349
+ In order to receive meeting transcripts, Webex assistant must be enabled for the meeting.
350
+
351
+ ```javascript
352
+ ...
353
+ // Subscribe to transcription events
354
+ meeting.on('meeting:receiveTranscription:started', (payload) => {
355
+ console.log(payload);
356
+ });
357
+
358
+ meeting.on('meeting:receiveTranscription:stopped', () => {});
359
+
360
+ await meeting.join({receiveTranscription: true});
361
+ ```
362
+
363
+ ##### Microphone, Speaker and Camera
364
+
365
+ Select a different device than the default:
366
+
367
+ ```js
368
+ const audioInputSelect = document.querySelector('select#audioSource');
369
+ const audioOutputSelect = document.querySelector('select#audioOutput');
370
+ const videoSelect = document.querySelector('select#videoSource');
371
+ ```
372
+
373
+ ```js
374
+ const audio = {};
375
+ const video = {};
376
+ const media = {
377
+ receiveVideo: boolean,
378
+ receiveAudio: boolean,
379
+ receiveShare: boolean,
380
+ sendShare: boolean,
381
+ sendVideo: boolean,
382
+ sendAudio: boolean
383
+ };
384
+
385
+ // setting up the devices
386
+ const selectors = [audioInputSelect, audioOutputSelect, videoSelect];
387
+
388
+ meeting.getDevices().then((deviceInfos) => {
389
+ const values = selectors.map((select) => select.value);
390
+
391
+ selectors.forEach((select) => {
392
+ while (select.firstChild) {
393
+ select.removeChild(select.firstChild);
394
+ }
395
+ });
396
+ for (let i = 0; i !== deviceInfos.length; i += 1) {
397
+ const deviceInfo = deviceInfos[i];
398
+ const option = document.createElement('option');
399
+
400
+ option.value = deviceInfo.deviceId;
401
+ if (deviceInfo.kind === 'audioinput') {
402
+ option.text = deviceInfo.label || `microphone ${audioInputSelect.length + 1}`;
403
+ audioInputSelect.appendChild(option);
404
+ }
405
+ else if (deviceInfo.kind === 'audiooutput') {
406
+ option.text = deviceInfo.label || `speaker ${audioOutputSelect.length + 1}`;
407
+ audioOutputSelect.appendChild(option);
408
+ }
409
+ else if (deviceInfo.kind === 'videoinput') {
410
+ option.text = deviceInfo.label || `camera ${videoSelect.length + 1}`;
411
+ videoSelect.appendChild(option);
412
+ }
413
+ else {
414
+ console.log('Some other kind of source/device: ', deviceInfo);
415
+ }
416
+ }
417
+ selectors.forEach((select, selectorIndex) => {
418
+ if (Array.prototype.slice.call(select.childNodes).some((n) => n.value === values[selectorIndex])) {
419
+ select.value = values[selectorIndex];
420
+ }
421
+ });
422
+
423
+ // attaching before the request
424
+
425
+ audio.deviceId = {exact: audioInputSelect.value}
426
+ video.deviceId = {exact: videoSelect.value}
427
+ meeting.getMediaStreams(media, {audio, video}).then(...)
428
+ ```
429
+
430
+ ###### Changing remote audio output
431
+
432
+ ```js
433
+ // Attach audio output device to video element using device/sink ID.
434
+ function attachSinkId(element, sinkId) {
435
+ if (typeof element.sinkId !== 'undefined') {
436
+ element
437
+ .setSinkId(sinkId)
438
+ .then(() => {
439
+ console.log(`Success, audio output device attached: ${sinkId}`);
440
+ })
441
+ .catch((error) => {
442
+ let errorMessage = error;
443
+
444
+ if (error.name === 'SecurityError') {
445
+ errorMessage = `You need to use HTTPS for selecting audio output device: ${error}`;
446
+ }
447
+ console.error(errorMessage);
448
+ // Jump back to first output device in the list as it's the default.
449
+ audioOutputSelect.selectedIndex = 0;
450
+ });
451
+ } else {
452
+ console.warn('Browser does not support output device selection.');
453
+ }
454
+ }
455
+
456
+ audioOutputSelect.onchange = function () {
457
+ attachSinkId(document.getElementById('remoteaudio'), audioOutputSelect.value);
458
+ };
459
+ ```
460
+
461
+ ##### Record
462
+
463
+ ```js
464
+ // you can only pause if recording
465
+ // you can only start recording if not recording
466
+ // you can only resume recording if paused
467
+ // you can only pause recording if started
468
+ meeting.startRecording();
469
+ meeting.pauseRecording();
470
+ meeting.resumeRecording();
471
+ meeting.stopRecording();
472
+ // note, all recording is done in the cloud
473
+ // local recording is not yet available for this package
474
+ // but is technically possible
475
+ // please submit a feature request if desired :)
476
+ // https://github.com/webex/webex-js-sdk/blob/master/CONTRIBUTING.md
477
+ ```
478
+
479
+ ##### Mute Audio or Video
480
+
481
+ ```js
482
+ meeting.muteAudio();
483
+ meeting.muteVideo();
484
+ ```
485
+
486
+ ##### Unmute Audio or Video
487
+
488
+ ```js
489
+ meeting.unmuteAudio();
490
+ meeting.unmuteVideo();
491
+ ```
492
+
493
+ ##### Start Sending a Share
494
+
495
+ ```js
496
+ meeting.shareScreen();
497
+ ```
498
+
499
+ ##### Stop Sending a Share
500
+
501
+ ```js
502
+ meeting.stopShare();
503
+ ```
504
+
505
+ ##### Update Audio/Video Streams
506
+
507
+ Use this if you want to change the actual streams send and receive for audio or video component separately; `updateAudio` and `updateVideo` is for the developer to add and remove the streams completely.
508
+
509
+ ```js
510
+ //video
511
+ if (media.sendVideo) {
512
+ meeting
513
+ .getMediaStreams(
514
+ {sendVideo: true},
515
+ {video: videoSelect.value ? {deviceId: {exact: videoSelect.value}} : media.sendVideo}
516
+ )
517
+ .then(([localStream]) =>
518
+ meeting.updateVideo({
519
+ stream: localStream,
520
+ sendVideo: media.sendVideo,
521
+ receiveVideo: media.receiveVideo,
522
+ })
523
+ );
524
+ } else {
525
+ meeting.updateVideo({
526
+ sendVideo: media.sendVideo,
527
+ receiveVideo: media.receiveVideo,
528
+ });
529
+ }
530
+ //audio
531
+ if (media.sendAudio) {
532
+ meeting
533
+ .getMediaStreams(media, {
534
+ audio: audioInputSelect.value ? {deviceId: {exact: audioInputSelect.value}} : media.sendAudio,
535
+ })
536
+ .then(([localStream]) =>
537
+ meeting.updateAudio({
538
+ stream: localStream,
539
+ sendAudio: media.sendAudio,
540
+ receiveAudio: media.receiveAudio,
541
+ })
542
+ );
543
+ } else {
544
+ meeting.updateAudio({
545
+ sendAudio: media.sendAudio,
546
+ receiveAudio: media.receiveAudio,
547
+ });
548
+ }
549
+ //all in one
550
+ meeting.getMediaStreams(media, {audio, video}).then(([localStream, localShare]) =>
551
+ meeting.updateMedia({
552
+ mediaSettings: media,
553
+ localStream,
554
+ localShare,
555
+ })
556
+ );
557
+ ```
558
+
559
+ ##### Accessing media directly (outside of a meeting)
560
+
561
+ You can also directly access the following media properties that are not on a meeting instance
562
+
563
+ ```
564
+ this.media.getUserMedia(mediaSetting, audioVideo, sharePreferences, config)
565
+ ```
566
+
567
+ See the [Media](https://github.com/webex/webex-js-sdk/blob/master/packages/node_modules/%40webex/plugin-meetings/src/media/index.js) util file for method signatures.
568
+
569
+ ##### Leave a Meeting
570
+
571
+ To leave a meeting, simply call leave
572
+
573
+ ```js
574
+ myMeeting.leave();
575
+ ```
576
+
577
+ ##### Lock/Unlock a Meeting
578
+
579
+ ```js
580
+ meeting.lockMeeting();
581
+ meeting.unlockMeeting();
582
+ ```
583
+
584
+ ##### Transfer Host
585
+
586
+ ```js
587
+ const hostMemberId = ...;
588
+ meeting.transfer(hostMemberId);
589
+ ```
590
+
591
+ ##### Check User Actions
592
+
593
+ ```js
594
+ meeting.inMeetingActions.get();
595
+ {
596
+ canInviteNewParticipants: boolean,
597
+ canAdmitParticipant: boolean,
598
+ canLock: boolean,
599
+ canUnlock: boolean,
600
+ canAssignHost: boolean,
601
+ canStartRecording: boolean,
602
+ canPauseRecording: boolean,
603
+ canResumeRecording: boolean,
604
+ canStopRecording: boolean,
605
+ canRaiseHand: boolean,
606
+ canLowerAllHands: boolean,
607
+ canLowerSomeoneElsesHand: boolean,
608
+ bothLeaveAndEndMeetingAvailable: boolean,
609
+ }
610
+ ```
611
+
612
+ #### Personal Meeting Room
613
+
614
+ ##### Edit Personal Meeting Room
615
+
616
+ ```javascript
617
+ const link = ...; // a valid pmr link
618
+ const pin = ...; // a valid host pin assoicated to the link
619
+ // claiming a pmr, and updating the cached values for the stored PMR
620
+ webex.meetings.personalMeetingRoom.claim(link, pin).then((pmr) => {
621
+ console.log(pmr); // do something else with the pmr
622
+ });
623
+ ```
624
+
625
+ ##### Get Personal Meeting Room
626
+
627
+ ```javascript
628
+ webex.meetings.personalMeetingRoom.get().then((pmr) => {
629
+ // do some stuff with the pmr values
630
+ console.log(`PMR INFO:
631
+ link-${webex.meetings.personalMeetingRoom.meetingLink}-
632
+ uri-${webex.meetings.personalMeetingRoom.sipUri}-
633
+ tollFree-${webex.meetings.personalMeetingRoom.pmr.callInNumbersInfo.callInTollFreeNumber.number}-
634
+ toll-${webex.meetings.personalMeetingRoom.pmr.callInNumbersInfo.callInTollNumber.number}-
635
+ accessCode-${webex.meetings.personalMeetingRoom.pmr.meetingNumber}
636
+ `);
637
+ });
638
+ ```
639
+
640
+ #### Usage of Webex Devices
641
+
642
+ For details on how to use the devices see https://github.com/webex/webex-js-sdk/tree/master/packages/node_modules/%40webex/plugin-device-manager
643
+
644
+ ##### Leave a Meeting Using a Device
645
+
646
+ ```js
647
+ const resourceId = ...;
648
+
649
+ meeting.leave({resourceId}).then((res) => {
650
+ console.log(`successful leave with device, ${res}`);
651
+ });
652
+ ```
653
+
654
+ ##### Leave a Meeting While Paired to the Device, Keep Device in Meeting
655
+
656
+ ```js
657
+ meeting.leave().then((res) => {
658
+ console.log(`successful leave, ${res}`);
659
+ });
660
+ ```
661
+
662
+ ##### Move Meeting To Paired Device
663
+
664
+ ```js
665
+ const resourceId = ...
666
+
667
+ meeting.moveTo(resourceId).then((res) => {
668
+ console.log(`successful move to ${res}`);
669
+ });
670
+ }
671
+ ```
672
+
673
+ ##### Move Meeting from Paired Device
674
+
675
+ ```js
676
+ const resourceId = ...
677
+
678
+ meeting.moveFrom(resourceId).then((res) => {
679
+ console.log(`successful move from ${res}`);
680
+ });
681
+ ```
682
+
683
+ ##### Start Wireless Share
684
+
685
+ ```js
686
+ const deviceId = ...
687
+ // create the meeting
688
+ webex.meetings.create(deviceId).then((m) => {
689
+ // attach listeners
690
+ // then join the meeting
691
+ meeting.getMediaStreams({
692
+ sendAudio: false,
693
+ sendVideo: false,
694
+ sendShare: true
695
+ }))
696
+ .then(([localStream, localShare]) =>
697
+ meeting.addMedia({
698
+ mediaSettings: {
699
+ sendAudio: false,
700
+ sendVideo: false,
701
+ sendShare: true,
702
+ receiveShare: false,
703
+ receiveAudio: false,
704
+ receiveVideo: false
705
+ },
706
+ localShare,
707
+ localStream
708
+ }))
709
+ .catch((e) => {
710
+ meeting.leave();
711
+ console.error('Error wireless screen sharing', e);
712
+ });
713
+ }
714
+ ```
715
+
716
+ ##### End Wireless Share
717
+
718
+ ```js
719
+ meeting.leave();
720
+ ```
721
+
722
+ ##### Reconnect a Meeting Media
723
+
724
+ Warning: not necessary to use manually, internally the sdk listens to mercury reconnect events to determine for a reconnection
725
+
726
+ ```js
727
+ meeting.reconnect();
728
+ ```
729
+
730
+ #### Scheduled Meetings
731
+
732
+ For scheduled meetings see https://github.com/webex/webex-js-sdk/tree/master/packages/node_modules/%40webex/internal-plugin-calendar
733
+
734
+ #### Member
735
+
736
+ ##### Properties
737
+
738
+ ```javascript
739
+ member.participant ... // Object server participant object, advanced use only
740
+ member.id ... // String key for storing
741
+ member.name ... // String plain text name
742
+ member.isAudioMuted ... // Boolean
743
+ member.isVideoMuted ... // Boolean
744
+ member.isHandRaised ... //Boolean
745
+ member.isSelf ... // Boolean is this member YOUR user?
746
+ member.isHost ... // Boolean
747
+ member.isGuest ... // Boolean
748
+ member.isInLobby ... // Boolean
749
+ member.isInMeeting ... // Boolean
750
+ member.isNotAdmitted ... // Boolean -- waiting to be admitted to the meeting, will also have isInLobby true
751
+ member.isContentSharing ... // Boolean
752
+ member.status ... // String -- advanced use only
753
+ member.isDevice ... // Boolean
754
+ member.isUser ... // Boolean
755
+ member.associatedUser ... // String -- member.id if isDevice is true
756
+ member.isRecording ... // Boolean
757
+ member.isMutable ... // Boolean
758
+ member.isRemovable ... // Boolean
759
+ member.type ... // String
760
+ member.isModerator ... // Boolean
761
+ member.isModeratorAssignmentProhibited ... // Boolean
762
+ ```
763
+
764
+ #### Members
765
+
766
+ You can access the members object on each individual meeting instance. It has some key events to listen to, and maintains what happens for members of a meeting with some key properties.
767
+
768
+ ##### Properties
769
+
770
+ ```javascript
771
+ meeting.members.membersCollection.members ... // the members collection, object {id0: member0, ... idN: memberN}
772
+ meeting.members.locusUrl ... // current locusUrl being used
773
+ meeting.members.hostId ... // active host id for the meeting
774
+ meeting.members.selfId ... // active self id for the meeting
775
+ meeting.members.mediaShareContentId ... // active content sharer id for the meeting
776
+ ```
777
+
778
+ ##### Functions
779
+
780
+ ```javascript
781
+ // You can add a guest to the meeting by inviting them, this is proxied by meeting.invite
782
+ // use an emailAddress and a boolean value alertIfActive to notify server side (usually true)
783
+ meeting.members.addMember(emailAddress, alertIfActive);
784
+
785
+ // You can admit the guest to the meeting once they are waiting in the lobby, you can do this in bulk, proxied by meeting.admit
786
+ // use member ids, can be singular, but has to be put into an array
787
+ meeting.members.admitMembers([memberIds]);
788
+
789
+ // You can remove a member from the meeting by booting them, this is proxied by meeting.remove
790
+ // use a memberId string
791
+ meeting.members.removeMember(memberId);
792
+
793
+ // You can audio mute a member from the meeting by calling to mute them, this is proxied by meeting.mute
794
+ // use a memberId string and a boolean to mute or not, default to true
795
+ // mute them
796
+ meeting.members.muteMember(memberId);
797
+
798
+ // You can raise or lower the hand of a member from the meeting
799
+ // use a memberId string and a "raise" boolean to raise or lower, default to true ("raise the hand")
800
+ meeting.members.raiseOrLowerHand(memberId);
801
+
802
+ // You can lower all hands in a meeting
803
+ // use a memberId string to indicate who is requesting lowering all hands
804
+ meeting.members.lowerAllHands(requestingMemberId);
805
+
806
+ // You can transfer the host role to another member in the meeting, this is proxied by meeting.transfer
807
+ // use a memberId string and a moderator boolean to transfer or not, default to true
808
+ meeting.members.transferHostToMember(memberId);
809
+ ```
810
+
811
+ ##### Events
812
+
813
+ ```javascript
814
+ // members collection updated
815
+ meeting.members.on('members:update', (payload) => {
816
+ const delta = payload.delta; // the changes to the members list
817
+ const full = payload.full; // the full members collection
818
+ const updated = delta.updated; // only the updates, includes removals, as they will have updated status and member properties
819
+ const added = delta.added; // added members to the meeting
820
+ Object.keys(full).forEach((key) => {
821
+ const member = full[key];
822
+ console.log(`Member: ... ${member.x}`);
823
+ });
824
+ Object.keys(updated).forEach((key) => {
825
+ const member = updated[key];
826
+ console.log(`Member Updated: ... ${member.x}`);
827
+ });
828
+ Object.keys(added).forEach((key) => {
829
+ const member = added[key];
830
+ console.log(`Member Added: ... ${member.x}`);
831
+ });
832
+ });
833
+ // content updates
834
+ meeting.members.on('members:content:update', (payload) => {
835
+ console.log(`who started sharing: ${payload.activeContentSharingId};`);
836
+ console.log(`who stopped sharing: ${payload.endedContentSharingId};`);
837
+ });
838
+ // host updates
839
+ meeting.members.on('members:host:update', (payload) => {
840
+ console.log(`who started hosting: ${payload.activeHostId};`);
841
+ console.log(`who stopped hosting: ${payload.endedHostId};`);
842
+ });
843
+ // self updates, not typically used
844
+ meeting.members.on('members:self:update', (payload) => {
845
+ console.log(`active self id: ${payload.activeSelfId};`);
846
+ console.log(`ended self Id: ${payload.endedSelfId};`);
847
+ });
848
+ ```
849
+
850
+ ## Events
851
+
852
+ ### Meetings Events
853
+
854
+ ```js
855
+ webex.meetings.on(...)
856
+ ```
857
+
858
+ | Event Name | Description |
859
+ | --------------------- | -------------------------------------------------------------------------------------------------- |
860
+ | `meetings:ready` | Fired when the plugin has been instantiated and is ready for action! |
861
+ | `meeting:added` | Fired when a meeting has been added to the collection, either incoming, or outgoing, can be joined |
862
+ | `meeting:removed` | Fired when a meeting has been deleted from the collection, this meeting cannot be rejoined |
863
+ | `media:codec:loaded` | Fired when H.264 media codec has been loaded in the browser. Does not have a payload. |
864
+ | `media:codec:missing` | Fired when H.264 media codec appears to be missing from the browser. Does not have a payload. |
865
+ | --- | --- |
866
+
867
+ `meetings:ready` does not have a payload
868
+
869
+ `meeting:added` has the following payload
870
+
871
+ ```js
872
+ {
873
+ meetingId; // the uuid of the meeting removed
874
+ type; // string type can be INCOMING, JOIN, or MEETING
875
+ }
876
+ ```
877
+
878
+ `meeting:removed` has the following payload
879
+
880
+ ```js
881
+ {
882
+ meetingId; // the uuid of the meeting removed
883
+ response; // a propagated server response
884
+ }
885
+ ```
886
+
887
+ ### Meeting Events
888
+
889
+ ```js
890
+ meeting.on(...)
891
+ ```
892
+
893
+ | Event Name | Description |
894
+ | -------------------------------------- | ------------------------------------------------------------------------------------------------- |
895
+ | `meetings:ready` | Fired when the meetings plugin has been successfully initialized |
896
+ | `meetings:registered` | Fired when the meetings plugin has registered the device and is listening to websocket events |
897
+ | `meetings:unregistered` | Fired when the meetings plugin has been disconnected from websockets and unregistered as a device |
898
+ | `media:ready` | Fired when remote or local media has been acquired |
899
+ | `media:stopped` | Fired when remote or local media has been torn down |
900
+ | `meeting:media:local:start` | Fired when local media has started sending bytes |
901
+ | `meeting:media:remote:start` | Fired when local media has started receiving bytes from the remote audio or video streams |
902
+ | `meeting:alerted` | Fired when locus was notified that user received meeting |
903
+ | `meeting:ringing` | Fired when meeting should have a ringing sound on repeat |
904
+ | `meeting:ringingStop` | Fired when meeting should stop a ringing sound |
905
+ | `meeting:startedSharingLocal` | Fired when local screen sharing was started |
906
+ | `meeting:stoppedSharingLocal` | Fired when local screen sharing ends |
907
+ | `meeting:startedSharingRemote` | Fired when remote screen sharing was started |
908
+ | `meeting:stoppedSharingRemote` | Fired when remote screen sharing ends |
909
+ | `meeting:self:lobbyWaiting` | Fired when user has entered the lobby for a PMR or the like |
910
+ | `meeting:self:guestAdmitted` | Fired when user has entered the meeting after waiting to be admitted from join |
911
+ | `meeting:self:mutedByOthers` | Fired when user has been audio muted by another in the muting |
912
+ | `meeting:reconnectionStarting` | Fired when a reconnect begins |
913
+ | `meeting:reconnectionSuccess` | Fired when the media was reconnected successfully |
914
+ | `meeting:reconnectionFailure` | Fired when the media failed to reconnect, user will have to rejoin and connect |
915
+ | `meeting:unlocked` | Fired when the meeting was unlocked by the host, for webex type meetings only |
916
+ | `meeting:locked` | Fired when the meeting was locked by the host, for webex type meetings only |
917
+ | `meeting:actionsUpdate` | Fired when the user has new actions they can take, such as lock, unlock, transferHost |
918
+ | `meeting:logUpload:success` | Fired when the meeting logs were successfully uploaded |
919
+ | `meeting:logUpload:failure` | Fired when the meeting logs failed to upload |
920
+ | `meeting:recording:started` | Fired when member starts recording |
921
+ | `meeting:recording:stopped` | Fired when member stops recording |
922
+ | `meeting:recording:paused` | Fired when member pauses recording |
923
+ | `meeting:recording:resumed` | Fired when member resumes recording |
924
+ | `meeting:receiveTranscription:started` | Fired when transcription is received |
925
+ | `meeting:receiveTranscription:stopped` | Fired when transcription has stopped from being received |
926
+ | `meeting:meetingContainer:update` | Fired when the meetingContainerUrl is updated |
927
+ | --- | --- |
928
+
929
+ `meetings:ready` does not have a payload
930
+
931
+ `meetings:registered` does not have a payload
932
+
933
+ `meetings:unregistered` does not have a payload
934
+
935
+ `media:ready` has the following payload
936
+
937
+ ```javascript
938
+ {
939
+ type, // local or remote
940
+ stream; // the MediaStream
941
+ }
942
+ // usage
943
+ meeting.on('media:ready', (media) => {
944
+ if (!media) {
945
+ return;
946
+ }
947
+ if (media.type === 'local') {
948
+ document.getElementById('localvideo').srcObject = media.stream;
949
+ }
950
+ if (media.type === 'remoteVideo') {
951
+ document.getElementById('remotevideo').srcObject = media.stream;
952
+ }
953
+ if (media.type === 'remoteAudio') {
954
+ document.getElementById('remoteaudio').srcObject = media.stream;
955
+ }
956
+ if (media.type === 'remoteShare') {
957
+ document.getElementById('sharevideo').srcObject = media.stream;
958
+ }
959
+ if (media.type === 'localShare') {
960
+ document.getElementById('localshare').srcObject = media.stream;
961
+ }
962
+ });
963
+ ```
964
+
965
+ `media:stopped` has the following payload
966
+
967
+ ```javascript
968
+ {
969
+ type, // local or remote
970
+ }
971
+ // usage
972
+ meeting.on('media:stopped', (media) => {
973
+ if (media.type === 'local') {
974
+ document.getElementById('localvideo').srcObject = null;
975
+ }
976
+ if (media.type === 'remoteVideo') {
977
+ document.getElementById('remotevideo').srcObject = null;
978
+ }
979
+ if (media.type === 'remoteAudio') {
980
+ document.getElementById('remoteaudio').srcObject = null;
981
+ }
982
+ if (media.type === 'localShare') {
983
+ document.getElementById('localshare').srcObject = null;
984
+ }
985
+ if (media.type === 'remoteShare') {
986
+ document.getElementById('sharevideo').srcObject = null;
987
+ }
988
+ });
989
+ ```
990
+
991
+ `meeting:alerted` does not have a payload
992
+
993
+ `meeting:ringing` has the following payload
994
+
995
+ ```js
996
+ {
997
+ type // INCOMING or JOIN
998
+ id // the meeting id
999
+ }
1000
+ ```
1001
+
1002
+ `meeting:ringingStop` has the following payload
1003
+
1004
+ ```js
1005
+ {
1006
+ type // Object {remoteAnswered: boolean, remoteDeclined: boolean}
1007
+ id // the meeting id
1008
+ }
1009
+ ```
1010
+
1011
+ `meeting:startedSharingLocal` does not have a payload
1012
+
1013
+ `meeting:stoppedSharingLocal` does not have a payload
1014
+
1015
+ `meeting:self:lobbyWaiting` has the following payload
1016
+
1017
+ ```js
1018
+ {
1019
+ payload; // self object
1020
+ }
1021
+ ```
1022
+
1023
+ `meeting:self:guestAdmitted` has the following payload
1024
+
1025
+ ```js
1026
+ {
1027
+ payload; // self object
1028
+ }
1029
+ ```
1030
+
1031
+ `meeting:self:mutedByOthers` has the following payload
1032
+
1033
+ ```js
1034
+ {
1035
+ payload; // self object
1036
+ }
1037
+ ```
1038
+
1039
+ `meeting:reconnectionStarting` does not have a payload
1040
+
1041
+ `meeting:reconnectionSuccess` has the following payload
1042
+
1043
+ ```js
1044
+ {
1045
+ reconnect; // the media promise resolution
1046
+ }
1047
+ ```
1048
+
1049
+ `meeting:reconnectionFailure` has the following payload
1050
+
1051
+ ```js
1052
+ {
1053
+ error; // the forwarded error from media
1054
+ }
1055
+ ```
1056
+
1057
+ `meeting:unlocked` has the following payload
1058
+
1059
+ ```js
1060
+ {
1061
+ info; // info object
1062
+ }
1063
+ ```
1064
+
1065
+ `meeting:locked` has the following payload
1066
+
1067
+ ```js
1068
+ {
1069
+ info; // info object
1070
+ }
1071
+ ```
1072
+
1073
+ `meeting:actionsUpdate` has the following payload
1074
+
1075
+ ```js
1076
+ {
1077
+ canInviteNewParticipants, // boolean
1078
+ canAdmitParticipant, // boolean
1079
+ canLock, // boolean
1080
+ canUnlock, // boolean
1081
+ canAssignHost, // boolean
1082
+ canStartRecording, // boolean
1083
+ canPauseRecording, // boolean
1084
+ canResumeRecording, // boolean
1085
+ canStopRecording, // boolean
1086
+ canRaiseHand, //boolean
1087
+ canLowerAllHands, //boolean
1088
+ canLowerSomeoneElsesHand, //boolean
1089
+ bothLeaveAndEndMeetingAvailable, //boolean
1090
+ }
1091
+ ```
1092
+
1093
+ `meeting:recording:started`
1094
+ `meeting:recording:stopped`
1095
+ `meeting:recording:paused`
1096
+ `meeting:recording:resumed` have the following payload
1097
+
1098
+ ```js
1099
+ {
1100
+ state; // could be etiher `recording`, `idle` or `paused`
1101
+ modifiedBy; // user's decrypted ID who made an action
1102
+ lastModified; // when the action was made
1103
+ }
1104
+ ```
1105
+
1106
+ ### Event Caveats
1107
+
1108
+ ##### Remote screen share is not displayed if started before participant joins
1109
+
1110
+ If you notice that the remote screen share is not being displayed to a participant when they join
1111
+ after a screen has already been shared, double-check that you are following the standard plugin-meeting workflow.
1112
+
1113
+ Standard plugin-meeting workflow is as follows:
1114
+
1115
+ 1. Set event listener for `media:ready`
1116
+ 2. Call `join()`
1117
+ 3. Call `addMedia()` with `options.mediaSettings.receiveShare=true`
1118
+ 4. Wait to receive an event from `media:ready` with payload `type=remoteShare` that contains the remote share media stream
1119
+ 5. Set `srcObject` of a `video` element in the application to the previously obtained media stream
1120
+ (e.g. `document.getElementById('remote-screen').srcObject = media.stream`)
1121
+
1122
+ In most cases this will resolve the issue though an extra step could be to
1123
+ use `meeting.shareStatus` to control whether to show the video element or not.
1124
+
1125
+ This may be necessary as you can only register for events like `meeting:startedSharingRemote` on the
1126
+ meeting object, however, you can only do that after you've received the `meeting:added` event notification
1127
+ with the meeting payload. In the case when a host has already begun sharing before a participant joins,
1128
+ the registration for `meeting:startedSharingRemote` happens too late (after the SDK code that would send
1129
+ that event is already executed). Thus, you can check the value of `meeting.shareStatus` when you join the meeting
1130
+ to control whether to show that video element (the one that has srcObject set to the remote share stream) on the screen or not.
1131
+
1132
+ ### Members Events
1133
+
1134
+ ```js
1135
+ meeting.members.on(...)
1136
+ ```
1137
+
1138
+ There are several events submitted by this package that you can subscribe to.
1139
+ | Event Name | Description |
1140
+ |---|---|
1141
+ | `members:update` | Fired when a member in the collection has been updated |
1142
+ | `members:content:update` | Fired when a member in the collection has a changed content stream (share screen) |
1143
+ | `members:host:update` | Fired when a member in the collection has a changed host value |
1144
+ | `members:self:update` | Fired when a member in the collection has a changed self value |
1145
+ |---|---|
1146
+
1147
+ `members:update` has the following payload
1148
+
1149
+ ```js
1150
+ {
1151
+ delta: { // the changes to the members list
1152
+ updated // array only the updates, includes removals, as they will have updated status and member properties
1153
+ added // array added members to the meeting
1154
+ }
1155
+ full: // array the full members collection
1156
+ }
1157
+ ```
1158
+
1159
+ `members:content:update` has the following payload
1160
+
1161
+ ```js
1162
+ {
1163
+ activeContentSharingId; // the member id
1164
+ endedContentSharingId; // the member id
1165
+ }
1166
+ ```
1167
+
1168
+ `members:host:update` has the following payload
1169
+
1170
+ ```js
1171
+ {
1172
+ activeHostId; // the member id
1173
+ endedHostId; // the member id
1174
+ }
1175
+ ```
1176
+
1177
+ `members:self:update` has the following payload
1178
+
1179
+ ```js
1180
+ {
1181
+ activeSelfId; // the member id
1182
+ endedSelfId; // the member id
1183
+ }
1184
+ ```
1185
+
1186
+ ## Development
1187
+
1188
+ To use `webpack-dev-server` to load this package, run `yarn run samples:serve`.
1189
+
1190
+ Files placed in the `docs/samples/browser-plugin-meetings` folder will be served statically.
1191
+
1192
+ Files in the `src` folder will be compiled, bundled, and served as a static asset at `bundle.js` inside that directory.
1193
+
1194
+ ## Maintainers
1195
+
1196
+ This package is maintained by [Cisco Webex for Developers](https://developer.webex.com/).
1197
+
1198
+ ## Contribute
1199
+
1200
+ Pull requests welcome. Please see [CONTRIBUTING.md](https://github.com/webex/webex-js-sdk/blob/master/CONTRIBUTING.md) for more details.
1201
+
1202
+ ## License
1203
+
1204
+ © 2016-2020 Cisco and/or its affiliates. All Rights Reserved.