meeting.js 25 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645
  1. var Meeting = function Meeting() {
  2. this.localUserInfo = {
  3. //创建会议的参数对象
  4. name: "", //会议名称
  5. masterId: "", //主持人用户ID
  6. masterName: "", //主持人名字
  7. masterNumber: "", //主持人号码
  8. region: "", //号码对应的PAAS域ID
  9. record: true, //是否录像录音true:录像录音 false:不录
  10. type: "video", //会议类型“audio”: 音频会议 “video”: 音视频会议
  11. mode: "group", //会议模式“p2p”:点对点“group”:群聊
  12. };
  13. this.InvitedMembers = {
  14. //邀请会议的参数对象
  15. id: "", //会议id
  16. inviteId: "", //邀请人ID
  17. inviteName: "", //邀请人名字
  18. inviteNumber: "", //邀请人号码
  19. member: [],
  20. };
  21. this.InvitedMembersSingle = {
  22. //单兵
  23. id: "", //会议id
  24. inviteId: "", //邀请人ID
  25. inviteName: "", //邀请人名字
  26. inviteNumber: "", //邀请人号码
  27. member: [],
  28. };
  29. this.InvitedMembersVehicle = {
  30. //车载
  31. id: "", //会议id
  32. inviteId: "", //邀请人ID
  33. inviteName: "", //邀请人名字
  34. inviteNumber: "", //邀请人号码
  35. member: [],
  36. };
  37. this.InvitedMembersUav = {
  38. //无人机
  39. id: "", //会议id
  40. inviteId: "", //邀请人ID
  41. inviteName: "", //邀请人名字
  42. inviteNumber: "", //邀请人号码
  43. member: [],
  44. };
  45. this.InvitedMembersTalkie = {
  46. //对讲机
  47. id: "", //会议id
  48. inviteId: "", //邀请人ID
  49. inviteName: "", //邀请人名字
  50. inviteNumber: "", //邀请人号码
  51. member: [],
  52. };
  53. this.inviteSelf = {
  54. userName: "",
  55. department: "",
  56. userId: "",
  57. region: "",
  58. number: "",
  59. type: "client",
  60. };
  61. this.meetingInfoback = ""; //各个接口返回信息
  62. this.$Message = {
  63. warning: (data) => {
  64. console.log(data);
  65. // alert(data)
  66. }
  67. };
  68. this.targetid = "vPlayArea"
  69. };
  70. Meeting.prototype = {
  71. initSocket(userCode, callback) {
  72. const self = this;
  73. //初始websocket实例,保存在window中方便调用。一个浏览器tab页面只能初始化一次。所有的控件窗口,通过该websocket实例去生成不同的窗口实例,不同的控件窗口通过自己的窗口实例去调用初始化、关闭、隐藏等
  74. window.theSocket = this.theSocket = new InitWebSocketClass(
  75. userCode,
  76. localStorage.getItem("token"), {
  77. //客户端登陆成功通知;
  78. loginSuccess: (v) => {
  79. console.log("loginSuccess-->", v);
  80. // self.initWnd();
  81. },
  82. //客户端窗口被拉起通知
  83. onCreateVideoSuccess: (v) => {
  84. console.log("客户端onCreateVideoSuccess-----", v);
  85. },
  86. //重点:统一分发客户端ws消息;vue 可以统一用$bus分发.第三方消息分发自定
  87. onSocketBackInfos: (data) => {
  88. //视频窗口创建成功通知
  89. if (
  90. data &&
  91. data.method === "createVideoDialogReuslt" &&
  92. data.params.result === 0
  93. ) {
  94. if (data.params.handleName === "#" + this.targetid) {
  95. //客户端窗口创建好后,界面显示窗口;
  96. callback && callback()
  97. self[self.targetid].resize();
  98. this.$Message.warning("视频窗口创建成功!");
  99. }
  100. }
  101. },
  102. }
  103. );
  104. //socket实例初始化websocket回调方法;
  105. window.theSocket
  106. .initWebSocket()
  107. .then((v) => {
  108. if (v) {
  109. this.$Message.warning("视频插件登陆完成!");
  110. }
  111. callback();
  112. })
  113. .catch((v) => {
  114. this.$Message.warning("若要观看实时视频,请先安装视频插件大华应急指挥调度实战平台客户端打开失败, 请尝试刷新页面重试");
  115. });
  116. },
  117. //初始化视频窗口实例,先获取自己用户code,再初始化窗口,严格按照封装参数传,别漏了
  118. getUserCode(callback) {
  119. let self = this;
  120. $.ajax({
  121. type: "GET",
  122. url: setting.URL + "/ras/user/info",
  123. contentType: "application/json", //如果提交的是json数据类型,则必须有此参数,表示提交的数据类型
  124. dateType: "json",
  125. beforeSend: (xhr) => {
  126. xhr.setRequestHeader("X-Subject-Token", localStorage.getItem("token"));
  127. xhr.setRequestHeader("Content-Type", "application/json;charset=UTF-8");
  128. },
  129. success: (res) => {
  130. if(typeof res === 'string'){
  131. res=JSON.parse(res);
  132. }
  133. console.log(res && res.userCode)
  134. //obj
  135. if (res && res.userCode) {
  136. let {
  137. userCode
  138. } = res;
  139. //初始化websocket;
  140. return self.initSocket(userCode, callback);
  141. }
  142. },
  143. });
  144. },
  145. //初始化视频窗口-dom
  146. initWnd() {
  147. //左边窗口类型参数 分割 2行2列
  148. const typeObj = {
  149. rows: 1,
  150. cols: 1,
  151. wndSpaceing: 0,
  152. embedVideoMode: true,
  153. playerCtrlBarEnable: false,
  154. displayMode: 3,
  155. playMode: 0,
  156. playParams: {},
  157. webControlExpend: true
  158. };
  159. //左边窗口实例
  160. window[this.targetid] = this[this.targetid] = new VideoPlay(
  161. "#" + this.targetid,
  162. window.theSocket.websocket, //一个浏览器tab页面公用一个
  163. window.theSocket.socketCode, //一个浏览器tab页面公用一个
  164. typeObj
  165. );
  166. //左边窗口初始化
  167. this[this.targetid].init();
  168. },
  169. //播放视频
  170. playVideo(item) {
  171. if (!window.theSocket.websocket) {
  172. this.$Message.warning("请先打开视频插件");
  173. return;
  174. }
  175. if (item.type == "client") {
  176. this.slectOptionmini(item.userId).then((arr) => {
  177. if (arr) {
  178. this[this.targetid].openAppVideo(arr);
  179. }
  180. });
  181. } else if (item.type == "single") {
  182. //播放单兵视频
  183. this.pullFlow(item.channelId);
  184. } else if (item.type == "vehicle") {
  185. //播放车载视频
  186. this.pullFlow(item.channelId);
  187. } else if (item.type == "uav_dev") {
  188. //播放无人机视频
  189. this.pullFlow(item.channelId);
  190. }
  191. },
  192. // setDesignDivision(rows, cols) {
  193. // // console.log(this.localUserInfo);
  194. // const params = JSON.stringify({
  195. // loginIp: setting.URL,
  196. // method: "SetDesignDivision",
  197. // userCode: this.localUserInfo.masterId,
  198. // params: {
  199. // handleName:'#vPlayArea',
  200. // rows: Number(rows),
  201. // cols: Number(cols)
  202. // },
  203. // socketCode: window.theSocket.socketCode
  204. // });
  205. // console.log(params);
  206. // this.webSocketSend(params);
  207. // },
  208. //设备视频拉流
  209. pullFlow(chinnelId) {
  210. if (chinnelId) {
  211. this[this.targetid].showBrower(true);
  212. this[this.targetid].dragResize(0, 0, 0, 0);
  213. window[this.targetid] && window[this.targetid].realTimeVideo && window[this.targetid].realTimeVideo([{
  214. "channelId": chinnelId
  215. }]);
  216. }
  217. },
  218. /* 创建会商 */
  219. async creatMeeting() {
  220. let _this = this;
  221. if (!_this.localUserInfo.name) {
  222. _this.$Message.warning("请创建会商名称");
  223. return;
  224. }
  225. await $.ajax({
  226. type: "POST",
  227. url: setting.URL + "/mcu/meeting",
  228. contentType: "application/json", //如果提交的是json数据类型,则必须有此参数,表示提交的数据类型
  229. dateType: "json",
  230. data: JSON.stringify(_this.localUserInfo),
  231. beforeSend: function(xhr) {
  232. xhr.setRequestHeader("X-Subject-Token", localStorage.getItem("token"));
  233. xhr.setRequestHeader("Content-Type", "application/json;charset=UTF-8");
  234. //xhr.setRequestHeader("Origin",null);
  235. },
  236. success: function(res) {
  237. //obj
  238. _this.InvitedMembers.id = res.id; //创建了会议id,保存起来,为了邀请成员;
  239. _this.InvitedMembersSingle.id = res.id; //单兵;
  240. _this.InvitedMembersVehicle.id = res.id; //车载;
  241. _this.InvitedMembersUav.id = res.id; //无人机;
  242. _this.InvitedMembersTalkie.id = res.id; //单兵;
  243. _this.meetingId = res.id;
  244. localStorage.setItem("meetingId", res.id);
  245. _this._debug("创建会商返回的信息", res);
  246. // _this.searchMeetingMember(); //add创建会商然后,开始查会议成员显示在列表中;
  247. },
  248. error: function(data) {},
  249. });
  250. },
  251. /* 邀请会商成员 */
  252. startInvite(member) {
  253. let _this = this;
  254. _this.InvitedMembers.member = [
  255. _this.inviteSelf,
  256. ...([member] || []),
  257. // {
  258. // type: "tandemPhone",
  259. // number: _this.outLinenum,
  260. // userName: _this.outLinenum,
  261. // region: _this.paasId,
  262. // },
  263. ];
  264. $.ajax({
  265. type: "POST",
  266. url: setting.URL + "/mcu/meeting/member",
  267. contentType: "application/json", //如果提交的是json数据类型,则必须有此参数,表示提交的数据类型
  268. dateType: "json",
  269. data: JSON.stringify(_this.InvitedMembers),
  270. beforeSend: function(xhr) {
  271. xhr.setRequestHeader("X-Subject-Token", localStorage.getItem("token"));
  272. xhr.setRequestHeader("Content-Type", "application/json;charset=UTF-8");
  273. },
  274. success: function(res) {
  275. //obj
  276. _this._debug("邀请会商成后的信息", res);
  277. //_this.searchMeetingMember(); //add创建会商然后,开始查会议成员显示在列表中;
  278. },
  279. error: function(data) {
  280. if (data.responseJSON.code == "mcuIdNotExist") {
  281. _this.$Message.warning("未创建会商");
  282. } else if (data.responseJSON.code == "mcuIdInvalid") {
  283. _this.$Message.warning("会议ID无效");
  284. } else if (data.responseJSON.code == "mcuMeetingMemMax") {
  285. _this.$Message.warning("会议用户数满");
  286. }
  287. },
  288. });
  289. },
  290. /* 关闭会商操作 */
  291. deleteMeeting() {
  292. try {
  293. let _this = this;
  294. let deleteMeetingId = _this.meetingId;
  295. if (!deleteMeetingId) {
  296. _this.$Message.warning("未创建会商");
  297. _this._debug("未创建会商", "");
  298. return;
  299. }
  300. $.ajax({
  301. type: "DELETE",
  302. url: setting.URL + "/mcu/meeting/" + deleteMeetingId,
  303. contentType: "application/json", //如果提交的是json数据类型,则必须有此参数,表示提交的数据类型
  304. dateType: "json",
  305. data: JSON.stringify(_this.localUserInfo),
  306. beforeSend: function(xhr) {
  307. xhr.setRequestHeader("X-Subject-Token", localStorage.getItem("token"));
  308. xhr.setRequestHeader("Content-Type", "application/json;charset=UTF-8");
  309. },
  310. success: function(res) {
  311. //obj
  312. _this._debug("关闭会议成功", res);
  313. localStorage.removeItem("meetingId");
  314. _this.meetingId = ""; //置空
  315. _this.meetMemberList = []; //置空
  316. _this.meetMemberList2 = []; //置空
  317. },
  318. error: function(data) {
  319. //obj
  320. _this._debug("关闭会议错误提示", data);
  321. if (data.responseJSON.code === "mcuIdNotExist") {
  322. _this.$Message.warning("未创建会商");
  323. }
  324. },
  325. });
  326. } catch (E) {}
  327. },
  328. deleteAllMeeting(callback) {
  329. let _this = this;
  330. let s = "?";
  331. var index = 0;
  332. var doindex = 0;
  333. let searchParams = {
  334. "userDomain": "",
  335. "userId": _this.localUserInfo.userId,
  336. "local": "0"
  337. };
  338. for (let k in searchParams) {
  339. s = s + k + "=" + searchParams[k] + "&"
  340. }
  341. s = s.substr(0, s.length - 1);
  342. //console.log(s);
  343. $.ajax({
  344. type: 'GET',
  345. url: setting.URL + "/imu/group/list" + s,
  346. contentType: "application/json", //如果提交的是json数据类型,则必须有此参数,表示提交的数据类型
  347. dateType: 'json',
  348. beforeSend: function(xhr) {
  349. xhr.setRequestHeader("X-Subject-Token", localStorage.getItem("token"));
  350. xhr.setRequestHeader("Content-Type", "application/json;charset=UTF-8");
  351. //xhr.setRequestHeader("Origin",null);
  352. },
  353. success: function(res) { //string
  354. if (res) {
  355. _this.allGroupColumnsData = JSON.parse(res).results;
  356. _this._debug("查询所有该用户参与的群组信息success", res);
  357. //所有与我有关的会商;
  358. let allRelateMeeting = [];
  359. if (JSON.parse(res).results !== null) {
  360. JSON.parse(res).results.forEach((item) => {
  361. if (item.meetId) {
  362. index++;
  363. allRelateMeeting.push(item);
  364. $.ajax({
  365. type: "DELETE",
  366. url: setting.URL + "/mcu/meeting/" + item.meetId,
  367. contentType: "application/json", //如果提交的是json数据类型,则必须有此参数,表示提交的数据类型
  368. dateType: "json",
  369. data: JSON.stringify(_this.localUserInfo),
  370. beforeSend: function(xhr) {
  371. xhr.setRequestHeader("X-Subject-Token", localStorage.getItem("token"));
  372. xhr.setRequestHeader("Content-Type", "application/json;charset=UTF-8");
  373. },
  374. success: function(res) {
  375. //obj
  376. doindex++;
  377. if (doindex == index) {
  378. callback();
  379. }
  380. },
  381. error: function(data) {
  382. //obj
  383. doindex++;
  384. if (doindex == index) {
  385. callback();
  386. }
  387. },
  388. });
  389. }
  390. });
  391. } else {
  392. callback();
  393. }
  394. _this._debug("查询所有该用户参与的会商success", allRelateMeeting);
  395. }
  396. },
  397. error: function(data) {
  398. callback();
  399. }
  400. });
  401. },
  402. /* 通过deviceCode查询设备channelId */
  403. searchChinnelId(deviceCode, deviceType) {
  404. let _this = this;
  405. return new Promise((resolve) => {
  406. $.ajax({
  407. type: "GET",
  408. url: setting.URL + "/videoService/devicesManager/devices/" + deviceCode,
  409. contentType: "application/json", //如果提交的是json数据类型,则必须有此参数,表示提交的数据类型
  410. dateType: "json",
  411. beforeSend: function(xhr) {
  412. xhr.setRequestHeader(
  413. "X-Subject-Token",
  414. localStorage.getItem("token")
  415. );
  416. xhr.setRequestHeader(
  417. "Content-Type",
  418. "application/json;charset=UTF-8"
  419. );
  420. //xhr.setRequestHeader("Origin",null);
  421. },
  422. success: function(res) {
  423. //obj
  424. if (res) {
  425. if (deviceType == "single") {
  426. //单兵
  427. _this.channelId = res.encoderUnit.channels[0].channelId;
  428. resolve(res.encoderUnit.channels[0].channelId);
  429. _this._debug(
  430. "单兵channelId",
  431. res.encoderUnit.channels[0].channelId
  432. );
  433. } else if (deviceType == "vehicle") {
  434. //车载
  435. _this.channelId = res.encoderUnit.channels[0].channelId;
  436. resolve(res.encoderUnit.channels[0].channelId);
  437. _this._debug(
  438. "车载channelId",
  439. res.encoderUnit.channels[0].channelId
  440. );
  441. } else if (deviceType == "uav") {
  442. //无人机
  443. _this.channelId = res.encoderUnit.channels[0].channelId;
  444. resolve(res.encoderUnit.channels[0].channelId);
  445. _this._debug(
  446. "无人机channelId",
  447. res.encoderUnit.channels[0].channelId
  448. );
  449. } else if (deviceType == "talkie") {
  450. //对讲机
  451. if (res.encoderUnit.channels[0].channelId) {
  452. _this.channelId = res.encoderUnit.channels[0].channelId;
  453. resolve(res.encoderUnit.channels[0].channelId);
  454. }
  455. _this._debug(
  456. "对讲机channelId",
  457. res.devAudioUnit.channels[0].channelId
  458. );
  459. }
  460. }
  461. },
  462. error: function(data) {
  463. //
  464. },
  465. });
  466. });
  467. },
  468. queryUser(userCode) {
  469. let _this = this;
  470. return new Promise((resolve) => {
  471. $.ajax({
  472. type: "GET",
  473. url: setting.URL + "/ras/user/" + userCode,
  474. contentType: "application/json", //如果提交的是json数据类型,则必须有此参数,表示提交的数据类型
  475. dateType: "json",
  476. beforeSend: function(xhr) {
  477. xhr.setRequestHeader(
  478. "X-Subject-Token",
  479. localStorage.getItem("token")
  480. );
  481. xhr.setRequestHeader(
  482. "Content-Type",
  483. "application/json;charset=UTF-8"
  484. );
  485. },
  486. success: function(res) {
  487. //obj
  488. if (res && res.chnId) {
  489. resolve(res);
  490. }
  491. },
  492. error: function(data) {},
  493. });
  494. });
  495. },
  496. /* app拉流 */
  497. slectOptionmini(userCode) {
  498. let _this = this;
  499. return new Promise((resolve) => {
  500. $.ajax({
  501. type: "GET",
  502. url: setting.URL + "/ras/user/" + userCode,
  503. contentType: "application/json", //如果提交的是json数据类型,则必须有此参数,表示提交的数据类型
  504. dateType: "json",
  505. beforeSend: function(xhr) {
  506. xhr.setRequestHeader(
  507. "X-Subject-Token",
  508. localStorage.getItem("token")
  509. );
  510. xhr.setRequestHeader(
  511. "Content-Type",
  512. "application/json;charset=UTF-8"
  513. );
  514. },
  515. success: function(res) {
  516. //obj
  517. if (res && res.chnId) {
  518. let arr = [{
  519. channelId: res.chnId,
  520. userCode: res.userCode,
  521. regionId: res.paasId,
  522. domainId: "",
  523. }, ];
  524. resolve(arr);
  525. }
  526. },
  527. error: function(data) {},
  528. });
  529. });
  530. },
  531. /* 打开客户端 */
  532. async openClient(callback) {
  533. return this.getUserCode(callback);
  534. },
  535. closeClient() {
  536. try {
  537. this.theSocket &&
  538. this.theSocket.closeClient &&
  539. this.theSocket.closeClient();
  540. } catch (E) {}
  541. },
  542. closeVideo() {
  543. try {
  544. // this.theSocket.closeAllVideo && this.theSocket.closeAllVideo();
  545. this[this.targetid].closeAllVideo();
  546. this[this.targetid].showBrower(false);
  547. setTimeout(() => {
  548. this[this.targetid].showBrower(false);
  549. }, 100);
  550. } catch (E) {}
  551. },
  552. /* 获取群聊fromName */
  553. async getLocalUserInfo() {
  554. let _this = this;
  555. await $.ajax({
  556. type: "GET",
  557. url: setting.URL + "/ras/user/info",
  558. contentType: "application/json", //如果提交的是json数据类型,则必须有此参数,表示提交的数据类型
  559. dateType: "json",
  560. beforeSend: function(xhr) {
  561. xhr.setRequestHeader("X-Subject-Token", localStorage.getItem("token"));
  562. xhr.setRequestHeader("Content-Type", "application/json;charset=UTF-8");
  563. },
  564. success: function(res) {
  565. //obj
  566. _this.loginPassword = res.loginPassword; //获取登录为密码.为登录用户话机注册做准备(需要res解密)
  567. _this.localUserInfo.masterName = res.userName;
  568. _this.localUserInfo.masterId = res.userCode;
  569. _this.localUserInfo.masterNumber = res.userPhone;
  570. _this.localUserInfo.region = res.paasId;
  571. _this.InvitedMembers.inviteId = res.userCode;
  572. _this.InvitedMembers.inviteName = res.userName;
  573. _this.InvitedMembers.inviteNumber = res.userPhone;
  574. _this.inviteSelf = {
  575. userName: res.userName + "(系统APP接入)",
  576. department: res.deptName,
  577. userId: res.userCode,
  578. region: res.paasId,
  579. number: res.userPhone,
  580. type: "client",
  581. };
  582. //单兵
  583. _this.InvitedMembersSingle.inviteId = res.userCode;
  584. _this.InvitedMembersSingle.inviteName = res.userName;
  585. _this.InvitedMembersSingle.inviteNumber = res.userPhone;
  586. //车载
  587. _this.InvitedMembersVehicle.inviteId = res.userCode;
  588. _this.InvitedMembersVehicle.inviteName = res.userName;
  589. _this.InvitedMembersVehicle.inviteNumber = res.userPhone;
  590. //无人机
  591. _this.InvitedMembersUav.inviteId = res.userCode;
  592. _this.InvitedMembersUav.inviteName = res.userName;
  593. _this.InvitedMembersUav.inviteNumber = res.userPhone;
  594. //对讲机
  595. _this.InvitedMembersTalkie.inviteId = res.userCode;
  596. _this.InvitedMembersTalkie.inviteName = res.userName;
  597. _this.InvitedMembersTalkie.inviteNumber = res.userPhone;
  598. },
  599. error: function (data) {
  600. _this.$Message.error('获取视屏用户失败');
  601. },
  602. });
  603. },
  604. _debug(tip, res) {
  605. let _this = this;
  606. _this.meetingInfoback += tip + "--》 " + JSON.stringify(res) + "\n\n";
  607. // let container = _this.$el.querySelector("#meetResBack textarea");
  608. // container.scrollTop = container.scrollHeight;
  609. },
  610. settargetId(id) {
  611. let _this = this;
  612. if (id != "") {
  613. _this.targetid = id;
  614. }
  615. _this.initWnd();
  616. }
  617. };