react_hsbc_teller 2.0.6 → 2.0.8

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.
@@ -4,11 +4,13 @@
4
4
  import React, { Component, useState } from 'react';
5
5
  import QRCode from 'qrcode.react';
6
6
  import API from '../../api/api';
7
- import { initWebSocket, joinRoom, disconnect } from '../../common/websocket';
8
7
  import { BoardOperate } from '../../common/index.esm.js';
9
8
  import './video.less'
9
+ import { compressImage, isLight } from '../../utils/utils'
10
10
  import Header from '../header/header.jsx'
11
11
  import Foot from '../foot/foot.jsx'
12
+ import IconSuccess from '../../assets/img/icon_success.jpg'
13
+ import IconFail from '../../assets/img/icon_fail.jpg'
12
14
  import voiceImgOpen from '../../assets/img/icon_Mute.png'
13
15
  import voiceImgCloe from '../../assets/img/icon_MuteOne.png'
14
16
  import cameraImgOpen from '../../assets/img/icon_camera.png'
@@ -21,8 +23,9 @@ import recordErrorAudio from '../../assets/mp3/record_error.mp3'
21
23
  import internalJoin from '../../assets/mp3/internalJoin.mp3'
22
24
  import internalLeft from '../../assets/mp3/internalLeft.mp3'
23
25
  import leftMetting from '../../assets/mp3/leftmeeting.mp3'
26
+ import networkWeakAudio from '../../assets/mp3/networkweak.mp3'
27
+ import PIPictureClosedAudio from '../../assets/mp3/pip_close.mp3'
24
28
  import errorPng from '../../assets/img/tooltips2_fail.png'
25
- import { callNimIM } from '../../utils/cell.js'
26
29
  import Modal from "antd/lib/modal";
27
30
  import 'antd/lib/modal/style'
28
31
  import message from "antd/lib/message";
@@ -49,6 +52,8 @@ import SignMy from '../sign/signMy.jsx'
49
52
  import Step from '../components/step/step.jsx'
50
53
  import axios from 'axios';
51
54
  import CryptoJS from "crypto-js";
55
+
56
+ const SDK_VERISON = '2.0.8'
52
57
  const IDtypeFront = '请客户在其设备后置摄像头下展示证件正面(如:身份证照片页面)'
53
58
  const IDtypeBack = '请在后置摄像头下展示证件反面(如:身份证国徽页)'
54
59
  const { Option } = Select;
@@ -56,6 +61,18 @@ const LEAVE_TYPE = {
56
61
  TELLER_EXIT: 1, // 坐席退出
57
62
  ROOM_DESTROYED: -1, // 房间异常
58
63
  }
64
+ const POINT_TYPE = {
65
+ tts: '文字转语音',
66
+ asr: '语音转文字',
67
+ ffd: "人脸出框检测",
68
+ env: "环境检测",
69
+ pipd: "画中画显示、关闭",
70
+ pwd: "违禁词检测",
71
+ wnd: "弱网",
72
+ mute: "静音"
73
+ }
74
+ const RECORD_DEVICE_NAME = 'screen-capture-recorder'
75
+ // const RECORD_DEVICE_NAME = 'Full HD webcam'
59
76
  let media_status = 0
60
77
  let pictureInPictureVideo
61
78
  let mix_stream
@@ -75,6 +92,8 @@ let isSuccuseHs = false
75
92
  let isGraffiti = false
76
93
  let strokeColor = '#333'
77
94
  let clearTime
95
+ let beautyMode = 'none'
96
+ let hsMode = 'none'
78
97
  let CanvasHome = styled.div`
79
98
  position: fixed;
80
99
  z-index: ${props => props.zIndexNum};
@@ -120,7 +139,7 @@ function clearStreamRemain() {
120
139
  };
121
140
  async function startBeauty(stream) {
122
141
  await beautyInit();
123
- beautyStart(stream, "none");
142
+ beautyStart(stream, beautyMode);
124
143
  }
125
144
  async function startMix(stream, onState) {
126
145
  var drawCanvas = document.getElementById('canvas');
@@ -136,21 +155,25 @@ async function startHs(stream) {
136
155
 
137
156
  await hsInit();
138
157
 
139
- hsStart(stream, 'none');
158
+ hsStart(stream, hsMode);
140
159
 
141
160
  }
142
161
 
143
162
  async function stopHs() {
144
- var stop_stream = true;//控制是否内部来进行关闭流
145
- var stream = hsStop(stop_stream);
146
- if (stream != null && stream != undefined) {
147
- stream.getTracks().forEach((track) => {
148
- track.stop();
149
- });
150
- stream = null;
163
+ try {
164
+ var stop_stream = true;//控制是否内部来进行关闭流
165
+ var stream = hsStop(stop_stream);
166
+ if (stream != null && stream != undefined) {
167
+ stream.getTracks().forEach((track) => {
168
+ track.stop();
169
+ });
170
+ stream = null;
171
+ }
172
+ isSuccuseHs = false
173
+ } catch (err) {
174
+ console.log('stopHs Error')
175
+ console.log(err)
151
176
  }
152
- isSuccuseHs = false
153
-
154
177
  }
155
178
  async function mixStopClick() {
156
179
  var stop_stream = true;//控制是否内部来进行关闭流
@@ -175,6 +198,7 @@ class Video extends Component {
175
198
  }
176
199
  cancel = axios.CancelToken.source()
177
200
  state = {
201
+ ablePlayNetweakAudio: true,
178
202
  beautyType: false,
179
203
  beautyName: '开启美颜',
180
204
  signNoClick: false,
@@ -207,6 +231,7 @@ class Video extends Component {
207
231
  isModalVisibleFacial: false,
208
232
  isModalVisibleEnd: false,
209
233
  isModalVisible: false,
234
+ isPictureConfirmModalVisible:false,
210
235
  screenName: '共享模式',
211
236
  suspendName: '暂停',
212
237
  cameraImg: cameraImgOpen,
@@ -251,11 +276,9 @@ class Video extends Component {
251
276
  cameraValue: '',
252
277
  microphoneValue: '',
253
278
  imStatus: false,
254
- imJoinRoom: false,
255
279
  analyserData: new Map(),
256
280
  analyserHeight: new Map(),
257
281
  OnVolumeAnalyserMap: new Map(),
258
- manualClose: false,
259
282
  defaultValue: '1',
260
283
  customOcrSid: '',
261
284
  shareMaskState: false,
@@ -296,6 +319,8 @@ class Video extends Component {
296
319
  cardFailReason: '',
297
320
  videoType: '',
298
321
  certificateValidityType: true,
322
+ drawCanvasInterval: null,
323
+ faceDetectionTimer: null, // 人脸检测定时器
299
324
  };
300
325
  // eslint-disable-next-line no-undef
301
326
  test_controller = '';
@@ -303,7 +328,7 @@ class Video extends Component {
303
328
  saveLog = (val) => {
304
329
  axios({
305
330
  method: 'get',
306
- baseURL: this.props.logUrl + '&message=' + encodeURIComponent(val) + '&react_hsbc_teller=2.0.6&logTime=' + Date.now() + '&mtoken=' + encodeURIComponent(this.state.rtoken) + '&roomId=' + encodeURIComponent(this.state.channelId) + '&sessionId=' + encodeURIComponent(this.state.sessionId) + '&appointmentID=' + this.props.businessNumber,
331
+ baseURL: this.props.logUrl + '&message=' + encodeURIComponent(val) + '&react_hsbc_teller='+ SDK_VERISON +'&logTime=' + Date.now() + '&mtoken=' + encodeURIComponent(this.state.rtoken) + '&roomId=' + encodeURIComponent(this.state.channelId) + '&sessionId=' + encodeURIComponent(this.state.sessionId) + '&appointmentID=' + this.props.businessNumber,
307
332
 
308
333
  }).then(res => {
309
334
 
@@ -349,16 +374,9 @@ class Video extends Component {
349
374
  this.test_controller.Publish(publish_config)
350
375
  })
351
376
  // this.publishAllScreen();
352
-
353
- // eslint-disable-next-line no-undef
354
- setTimeout(() => {
355
- if (this.state.imStatus && !this.state.imJoinRoom) {
356
- joinRoom((this.props.tellerAccount + '@' + JSON.parse(window.sessionStorage.getItem('sigData')).hostname), this.state.imRoomId)
357
- this.state.imJoinRoom = true
358
- this.saveLog('Join im room')
359
- console.log('加入IM房间')
360
- }
361
- })
377
+ // 单独发布录制屏幕设备的流
378
+ this.publishRecorderDevice()
379
+
362
380
  this.props.createRoomCallback({
363
381
  type: 1,
364
382
  errorManage: '',
@@ -468,11 +486,6 @@ class Video extends Component {
468
486
  handleEdit = () => {
469
487
  console.log(JSON.parse(window.sessionStorage.getItem('sigData')));
470
488
  // eslint-disable-next-line no-undef
471
- // initWebSocket('wss://im.uat.dsp.hsbcfts.com.cn:443/wealth/im/ws/')
472
- if (!this.state.imStatus) {
473
- this.state.manualClose = false
474
- initWebSocket('wss://' + JSON.parse(window.sessionStorage.getItem('sigData')).hostname + ':' + JSON.parse(window.sessionStorage.getItem('sigData')).webPort + '/ws/');
475
- }
476
489
  const config_param = {};
477
490
  config_param.workspaceId = this.state.workSpaceId;
478
491
  config_param.uid = this.props.tellerAccount;
@@ -567,7 +580,7 @@ class Video extends Component {
567
580
  }
568
581
  }
569
582
  // 开启录制
570
- enableServerRecording = () => {
583
+ enableServerRecording = (record_business_id) => {
571
584
  const that = this
572
585
  this.rateAll().then((res) => {
573
586
  console.log('退出房间者', res)
@@ -643,7 +656,7 @@ class Video extends Component {
643
656
  height: 175
644
657
  },
645
658
  {
646
- tag: 'RM_ALL_SCREEN',
659
+ tag: 'sharedScreen', // 一期暂时不需要录制
647
660
  xPosition: 960,
648
661
  yPosition: 180,
649
662
  width: 320,
@@ -684,12 +697,23 @@ class Video extends Component {
684
697
  recordParam.endType = 1;
685
698
  recordParam.crf = 26
686
699
  recordParam.overlaps = [
700
+ {
701
+ tag: '', // 流 tag,如果不设置或为空,则为全局⽔印
702
+ type: 2, // 1 为时间戳⽔印;2 为⽂字⽔印;3 为图⽚⽔印
703
+ id: 2, // ⽔印 ID
704
+ enable: true,
705
+ xPosition: 640, // x 轴位置
706
+ yPosition: 10, // y 轴位置
707
+ text: `${this.props.recordMode ==1 ?'远程录制' :'网点录制'} ${this.props.salesBranchCode || ''} ${this.props.financialOffice || ''}`,
708
+ fontSize: 16, // 字体⼤⼩
709
+ url: '' // ⽔印图⽚ HTTP 地址
710
+ },
687
711
  {
688
712
  tag: '', // 流 tag,如果不设置或为空,则为全局⽔印
689
713
  type: 1, // 1 为时间戳⽔印;2 为⽂字⽔印;3 为图⽚⽔印
690
714
  id: 1, // ⽔印 ID
691
715
  enable: true,
692
- xPosition: 1000, // x 轴位置
716
+ xPosition: 1080, // x 轴位置
693
717
  yPosition: 10, // y 轴位置
694
718
  text: '', // ⽔印⽂字
695
719
  fontSize: 16, // 字体⼤⼩
@@ -698,7 +722,7 @@ class Video extends Component {
698
722
  ];
699
723
  recordParam.tagPositions = list
700
724
  console.log('recordParam', recordParam);
701
- that.test_controller.StartRemoteRecord(filePath, recordParam, '')
725
+ that.test_controller.StartRemoteRecord(filePath, recordParam, record_business_id)
702
726
 
703
727
  })
704
728
 
@@ -714,6 +738,15 @@ class Video extends Component {
714
738
  })
715
739
  }
716
740
  };
741
+ sendMessage = (msg) => {
742
+ try {
743
+ console.log('发送消息', JSON.stringify(msg))
744
+ this.test_controller.SendTextMsg(JSON.stringify(msg))
745
+ } catch (err) {
746
+ console.error(`内部错误, msg = ${JSON.stringify(msg)} `)
747
+ console.error(err)
748
+ }
749
+ }
717
750
  errorCodeClick=(type,value)=>{
718
751
  if(type == 'ocr'){
719
752
  if(value == -1007 || value == -100701 || value == -100702 || value == -200001 || value == -300901 || value == -300902 || value == -400001) {
@@ -955,6 +988,100 @@ class Video extends Component {
955
988
  this.selectCustomer('facial')
956
989
  }
957
990
  };
991
+ generateMediaInfo = (sid) => {
992
+ let that = this
993
+ console.log(that.test_controller, sid)
994
+ console.log(that.test_controller.GetMediaInfo(sid))
995
+ let originalMediaInfo = that.test_controller.GetMediaInfo(sid);
996
+ let mediaInfo = {
997
+ peer_connection_: originalMediaInfo.peer_connection_,
998
+ local_video_width: originalMediaInfo.local_video_width,
999
+ local_video_height: originalMediaInfo.local_video_height,
1000
+ local_video_frame: originalMediaInfo.local_video_frame,
1001
+ local_video_bitrate: originalMediaInfo.local_video_bitrate,
1002
+ stream_type: originalMediaInfo.stream_type,
1003
+ stat_interval_: 3,
1004
+ video_send_packets_base_: 0,
1005
+ video_recv_packets_base_: 0,
1006
+ video_send_lost_pack_base_: 0,
1007
+ video_recv_lost_pack_base_: 0,
1008
+ audio_send_packets_base_: 0,
1009
+ audio_recv_packets_base_: 0,
1010
+ audio_send_lost_pack_base_: 0,
1011
+ audio_recv_lost_pack_base_: 0,
1012
+ video_send_qpsum_base: 0,
1013
+ video_send_frame_encoded_base: 0,
1014
+ video_recv_qpsum_base: 0,
1015
+ video_recv_frame_decoded_base: 0,
1016
+ video_send_bitrate_base_: 0,
1017
+ video_recv_bitrate_base_: 0,
1018
+ audio_send_bitrate_base_: 0,
1019
+ audio_recv_bitrate_base_: 0,
1020
+ };
1021
+ return mediaInfo;
1022
+ }
1023
+ detectNetworkWeak = () => {
1024
+ return new Promise((resolve, reject) => {
1025
+ let detectionsNumber = 3
1026
+ let finalResult = true
1027
+ let setTimer = () => {
1028
+ setTimeout(() => {
1029
+ this.test_controller.GetStats(this.mediaInfo).then(media_stat => {
1030
+ if (detectionsNumber>2) {
1031
+ // 不考虑第一次的评估结果,重新计算码率
1032
+ detectionsNumber--;
1033
+ setTimer()
1034
+ return
1035
+ }
1036
+ console.log('media_stat:')
1037
+ console.log(media_stat)
1038
+ // 分辨率、帧率
1039
+ let googAvailableSendBandwidth = (media_stat["VideoBwe"]["googAvailableSendBandwidth"] / 1000).toFixed(2);
1040
+ let googTransmitBitrate = (media_stat["VideoBwe"]["googTransmitBitrate"] / 1000).toFixed(2);
1041
+ let ssrcVideoSendLostRate = media_stat["ssrcVideoSend"]["lostRate"];
1042
+ let ssrcAudioSendLostRate = media_stat["ssrcAudioSend"]["lostRate"];
1043
+ let weak_googAvailableSendBandwidth = 200;
1044
+ let weak_ssrcVideoSendLostRate = 20;
1045
+ let weak_ssrcAudioSendLostRate = 20;
1046
+ let weak_str = "网络正常";
1047
+ if (googAvailableSendBandwidth < weak_googAvailableSendBandwidth) {
1048
+ weak_str = "当前网络不佳";
1049
+ }
1050
+ let bpsSend = (media_stat.ssrcVideoSend["bpsSend"] / 1000).toFixed(2)
1051
+ let fps = media_stat["ssrcVideoSend"].googFrameRateSent
1052
+ let str =
1053
+ "带宽评估:" + (googAvailableSendBandwidth == undefined ? "none" : googAvailableSendBandwidth + "kbps") + "; "
1054
+ + "视频码率:" + bpsSend + "kb" + "; "
1055
+ + "音频码率:" + (media_stat.ssrcAudioSend["bpsSend"] / 1000).toFixed(2) + "kb" + "; "
1056
+ + "视频丢包率:" + (ssrcVideoSendLostRate == undefined ? "none" : ssrcVideoSendLostRate + "%") + "; "
1057
+ + "音频丢包率:" + (ssrcAudioSendLostRate == undefined ? "none" : ssrcAudioSendLostRate + "%") + "; "
1058
+ + weak_str + "; "
1059
+ + "当前编码格式:" + media_stat["ssrcVideoSend"].googCodecName + "; "
1060
+ + "分辨率:" + media_stat["ssrcVideoSend"].resolution + "; "
1061
+ + "帧率:" + media_stat["ssrcVideoSend"].googFrameRateSent;
1062
+ console.log('弱网', str)
1063
+ // document.getElementById("publish_media_stat1").innerText = str;
1064
+ let result = (bpsSend < 200 ) && googAvailableSendBandwidth < weak_googAvailableSendBandwidth
1065
+ if (result) {
1066
+ console.log('[!]弱网单次评估' + result);
1067
+ } else {
1068
+ finalResult = false
1069
+ console.log('弱网单次评估' + result);
1070
+ }
1071
+ if (detectionsNumber > 0 && finalResult) {
1072
+ detectionsNumber -= 1
1073
+ setTimer();
1074
+ } else {
1075
+ console.log('弱网综合检测结果:' + finalResult)
1076
+ resolve(finalResult)
1077
+ }
1078
+ });
1079
+
1080
+ }, 3000)
1081
+ }
1082
+ setTimer()
1083
+ })
1084
+ }
958
1085
  ocrClick = () => {
959
1086
  if (this.isFileSuccuse()) {
960
1087
  this.state.faceCustomerType = 2
@@ -1022,14 +1149,14 @@ class Video extends Component {
1022
1149
  return a.order - b.order;
1023
1150
  })
1024
1151
  for (let i =1;i<=12;i++){
1025
- if(document.getElementById('video'+i).name){
1152
+ if(sortedlist[i-1].videoName){
1026
1153
  list.push({
1027
- name: 'video' + i,
1028
- title: sortedlist[i-1].videoName,
1029
- mute: sortedlist[i-1].mute,
1030
- noVideo: sortedlist[i-1].noVideo
1031
- })
1032
- }
1154
+ name: 'video' + sortedlist[i-1].idIndex,
1155
+ title: sortedlist[i-1].videoName,
1156
+ mute: sortedlist[i-1].mute,
1157
+ noVideo: sortedlist[i-1].noVideo
1158
+ })
1159
+ }
1033
1160
  }
1034
1161
  console.log(list)
1035
1162
  this.state.listVideoPicture = list
@@ -1234,17 +1361,33 @@ class Video extends Component {
1234
1361
 
1235
1362
  pictureInPictureVideo.addEventListener('enterpictureinpicture', (event) => {
1236
1363
  //可获取画中画窗口的一些数据,如宽高等
1364
+ console.log('开启画中画')
1237
1365
  pictureInPictureVideo.style.display = 'block';
1238
1366
  pictureInPictureVideo.play();
1239
1367
  this.state.isPictureInPicture = true
1240
1368
  });
1241
1369
 
1242
1370
  pictureInPictureVideo.addEventListener('leavepictureinpicture', (event) => {
1371
+ console.log('关闭画中画')
1243
1372
  pictureInPictureVideo.srcObject = null;
1244
1373
  pictureInPictureVideo.style.display = "none";
1245
1374
  this.state.listVideoPicture = []
1246
1375
  worker.postMessage(false);
1247
1376
  this.state.isPictureInPicture = false
1377
+
1378
+ // 画中画循环播放逻辑
1379
+ this.setState({
1380
+ isPictureConfirmModalVisible: true
1381
+ })
1382
+ const loopPlay = () => {
1383
+ console.log('loopPlay status', this.state.isPictureInPicture);
1384
+ if(!this.state.isPictureInPicture && document.getElementById("publish_video1")){
1385
+ let audio = new Audio(PIPictureClosedAudio)
1386
+ audio.play()
1387
+ setTimeout(loopPlay, 3000);
1388
+ }
1389
+ }
1390
+ setTimeout(loopPlay, 0);
1248
1391
  });
1249
1392
 
1250
1393
  }
@@ -1312,9 +1455,8 @@ class Video extends Component {
1312
1455
  })
1313
1456
  }
1314
1457
  }
1315
- mountClick = () => {
1316
- window.IMEvt = msg => {
1317
- console.log(JSON.parse(msg));
1458
+ handleReceiveMsg = (msg) => {
1459
+ console.log(JSON.parse(msg));
1318
1460
  const Mival = JSON.parse(msg);
1319
1461
  if (Mival.typeId == 1210) {
1320
1462
  // 进行初始化操作
@@ -1347,6 +1489,7 @@ class Video extends Component {
1347
1489
  }, ()=>{
1348
1490
  this.pictureInPicture('Refresh')
1349
1491
  })
1492
+ this.messageClick('客户人脸已离框', 'error')
1350
1493
  }
1351
1494
  }
1352
1495
  else if (Mival.typeId == 3003) { // app进入前台
@@ -1363,6 +1506,18 @@ class Video extends Component {
1363
1506
  })
1364
1507
  }
1365
1508
  }
1509
+ else if (Mival.typeId == 5001) { // 客户端离框
1510
+ this.messageClick('客户人脸已离框', 'error')
1511
+ // this.saveVideoPoint('ffd', '客户人脸离框');
1512
+ }
1513
+ else if (Mival.typeId == 5002) { // 客户端
1514
+ this.messageClick('客户背光、曝光过度', 'error')
1515
+ // this.saveVideoPoint('env', '客户端背光、曝光过度');
1516
+ }
1517
+ else if (Mival.typeId == 5003) { // 客户端弱网
1518
+ this.messageClick('客户当前网络较弱', 'error')
1519
+ // this.saveVideoPoint('wnd', '客户端弱网');
1520
+ }
1366
1521
  else if (Mival.typeId == 1220) {
1367
1522
  // 一炒多的图片 1214
1368
1523
  if (Mival.sessionId == this.state.sessionId) {
@@ -1393,6 +1548,9 @@ class Video extends Component {
1393
1548
  if (Mival.type == 1) {
1394
1549
  this.switchExternal()
1395
1550
  this.saveLog('whiteboard start, typeId=1218,')
1551
+ if (typeof this.props.sfpCallback === 'function'){
1552
+ this.props.sfpCallback()
1553
+ }
1396
1554
  } else if (Mival.type == 2) {
1397
1555
  if (streamShare) {
1398
1556
  streamShare.getTracks().forEach(track => track.stop());
@@ -1406,6 +1564,7 @@ class Video extends Component {
1406
1564
  } else {
1407
1565
  if (document.getElementById('video20').name) {
1408
1566
  this.test_controller.UnPublish(document.getElementById('video20').name)
1567
+ if(this.state.drawCanvasInterval) clearInterval(this.state.drawCanvasInterval)
1409
1568
  }
1410
1569
  this.setState({
1411
1570
  isWhiteboard: false
@@ -1436,6 +1595,9 @@ class Video extends Component {
1436
1595
 
1437
1596
  }
1438
1597
  }
1598
+ if (this.state.isPictureInPicture) {
1599
+ this.pictureInPicture('Refresh')
1600
+ }
1439
1601
  }
1440
1602
  } else if (Mival.typeId == 121305) {
1441
1603
  if (Mival.sessionId == this.state.sessionId) {
@@ -1471,33 +1633,25 @@ class Video extends Component {
1471
1633
  });
1472
1634
  let sid = document.getElementById('publish_video1').name || document.getElementById('publish_streamId1').name;
1473
1635
  this.test_controller.SetLocalAudioEnable(0, parseInt(sid, 10));
1474
- callNimIM('sendCustomCmdMsg', {
1475
- customId: this.state.imRoomId,
1476
- content: JSON.stringify({
1636
+ this.sendMessage({
1477
1637
  'typeId': 1013,
1478
1638
  'muteStatus': 1,
1479
1639
  'data': {
1480
1640
  'sessionId': this.state.sessionId,
1481
1641
  'userId': this.props.tellerAccount
1482
1642
  }
1483
- })
1484
- }, function (code, message, data) {
1485
- // console.log(data)
1486
1643
  })
1487
1644
  }
1488
1645
  document.getElementById('audio1').muted = true
1489
1646
  console.log('音频流静音')
1490
1647
  console.log(document.getElementById('audio1').muted)
1491
1648
  setTimeout(() => {
1492
- callNimIM('sendCustomCmdMsg', {
1493
- customId: this.state.imRoomId,
1494
- content: JSON.stringify({
1495
- 'typeId': 1223,
1496
- 'state': 1, // app解除静音
1497
- 'sessionId': this.state.sessionId,
1498
- 'userId': Mival.data.userId //this.seeList(this.state.roomCustomerList, 'feedId', document.getElementById('feedId1').innerText).uid
1499
- })
1500
- });
1649
+ this.sendMessage({
1650
+ 'typeId': 1223,
1651
+ 'state': 1, // app解除静音
1652
+ 'sessionId': this.state.sessionId,
1653
+ 'userId': Mival.data.userId //this.seeList(this.state.roomCustomerList, 'feedId', document.getElementById('feedId1').innerText).uid
1654
+ })
1501
1655
  }, 1000);
1502
1656
  }
1503
1657
  } else if (Mival.typeId == 1401) {
@@ -1511,42 +1665,166 @@ class Video extends Component {
1511
1665
  this.setState({
1512
1666
  videoList: this.state.videoList
1513
1667
  })
1668
+ if (this.state.isPictureInPicture) {
1669
+ this.pictureInPicture('Refresh')
1670
+ }
1514
1671
  }
1515
1672
  } else if (Mival.typeId == 10020) {
1516
- // 录制服务异常中断,请重试
1673
+ // 录制中断
1517
1674
  this.messageClick('录制服务异常中断,请重试', 'error')
1518
- let audio = new Audio(recordErrorAudio)
1519
- audio.play()
1520
- }
1521
- };
1522
- window.IMOpenfire = msg => {
1523
- console.log('im登录', msg)
1524
- if (msg.status == 'error') {
1525
- this.state.imStatus = false
1526
- this.saveLog('Im connection establishment failed')
1527
- this.roomCallBack(2, 'im建立连接失败', 5)
1528
- } else if (msg.status == 'success') {
1529
- this.state.imStatus = true
1530
- setTimeout(() => {
1531
- if (this.state.imRoomId && !this.state.imJoinRoom) {
1532
- joinRoom((this.props.tellerAccount + '@' + JSON.parse(window.sessionStorage.getItem('sigData')).hostname), this.state.imRoomId)
1533
- this.state.imJoinRoom = true
1534
- console.log('IMOpenfire 加入im房间')
1675
+ this.saveLog('recording error')
1676
+ this.setState({
1677
+ isRecordingeErrorModalVisible: true,
1678
+ recordId: ''
1679
+ })
1680
+ // 循环播放录制中断语音
1681
+ const loopPlay = () => {
1682
+ if(!this.state.recordId && document.getElementById("publish_video1")){
1683
+ let audio = new Audio(recordErrorAudio)
1684
+ audio.play()
1685
+ setTimeout(loopPlay, 3000);
1535
1686
  }
1536
- }, 200);
1537
- } else if (msg.status == 'close') {
1538
- if (!this.state.manualClose) {
1539
- this.timer && clearInterval(this.timer);
1540
- this.state.imStatus = false
1541
- console.log('IMOpenfireclose')
1542
- this.saveLog('Repeated login of account')
1543
- this.roomCallBack(2, '账号重复登录', 9)
1687
+ }
1688
+ setTimeout(loopPlay, 0);
1544
1689
 
1690
+ } else if (Mival.typeId == 33001 && this.state.sessionId == Mival.data.sessionId) {
1691
+ if (Mival.type == 1) {
1692
+ this.saveAuthorize(Mival.data.userId)
1693
+ this.customerFaceClick(this.state.customerList[this.state.customerSelect - 1])
1545
1694
  }
1695
+ console.log('33001 done')
1696
+ } else if (Mival.typeId == 2210 && this.state.sessionId == Mival.sessionId) {
1697
+ if (Mival.status == 1) {
1698
+ // 开启了业务录制
1699
+ console.log('业务录制开启')
1700
+ this.state.businessId = Mival.id;
1701
+ this.saveLog('Start business recording')
1702
+ this.enableServerRecording( Mival.id)
1703
+
1704
+ this.startFaceDetection();
1705
+ this.startImageDetection();
1706
+ } else if (Mival.status == 2) {
1707
+ // 关闭了业务录制
1708
+ console.log('业务录制关闭')
1709
+ this.saveLog('Stop business recording')
1710
+ this.test_controller.StopRemoteRecord(this.state.businessRecordId)
1711
+ this.state.businessId = '';
1712
+ clearInterval(this.state.faceDetectionTimer);
1713
+ clearInterval(this.state.imageDetectionTimer);
1714
+ }
1715
+ } else if (Mival.typeId == 2002 && this.state.sessionId == Mival.sessionId) {
1716
+ // 会议到时间
1717
+ console.log('会议超过时间限制')
1718
+ this.endSessionValue();
1719
+ }
1720
+ }
1721
+ startFaceDetection = () => {
1722
+ console.log('startFaceDetection!!!!')
1723
+ clearInterval(this.state.faceDetectionTimer);
1724
+ const timer = setInterval( async () => {
1725
+ const path = this.test_controller.TakePicture(0, 0, 0, document.getElementById("publish_video1").name, 'png')
1726
+ try {
1727
+ let result = await API.faceDetection({
1728
+ activityId: this.props.businessNumber,
1729
+ sessionId: `${this.props.tellerAccount}_${Date.now()}`,
1730
+ // sessionId: this.state.sessionId,
1731
+ roomId: this.state.channelId + '',
1732
+ appId: this.state.appId,
1733
+ recordId: this.state.recordId,
1734
+ base64Image: path.replace('data:image/png;base64,', '')
1735
+ });
1736
+ if (result.faceNum == 0) {
1737
+ // 人脸出框
1738
+ this.messageClick('检测到您的人脸已出框', 'error')
1739
+ // 打点
1740
+ this.saveVideoPoint('ffd', 'RM端人脸离框');
1741
+ }
1742
+ } catch (err) {
1743
+ console.error(err);
1744
+ if (err.status == 502 || err.status == 404) {
1745
+ }
1746
+ }
1747
+ }, 5000);
1546
1748
 
1749
+ this.state.faceDetectionTimer = timer;
1750
+ }
1751
+ startImageDetection = () => {
1752
+ console.log('startImageDetection!!!!')
1753
+ clearInterval(this.state.imageDetectionTimer);
1754
+ const timer = setInterval( async () => {
1755
+ const path = this.test_controller.TakePicture(0, 0, 0, document.getElementById("publish_video1").name, 'png')
1756
+ const img = new Image()
1757
+ img.src = path;
1758
+ img.width = 300 //
1759
+ img.onload = () => {
1760
+ const origin = cv.imread(img)
1761
+ // let start = new Date().getTime()
1762
+ const res = isLight(origin)
1763
+ if (res==1 || res== -1){
1764
+ // 背景曝光过度
1765
+ this.messageClick('检测到当前背光、曝光过度', 'error')
1766
+ this.saveVideoPoint('env', 'RM端背光、曝光过度');
1767
+ }
1768
+ origin.delete()
1769
+ // let end = new Date().getTime()
1770
+ // console.log('执行时间(s) ', (end - start)/1000 )
1547
1771
  }
1772
+ }, 3000);
1548
1773
 
1774
+ this.state.imageDetectionTimer = timer;
1775
+ }
1776
+ lightDetect() {
1777
+ try {
1778
+ if (document.getElementById("publish_video1").name) {
1779
+ const path = this.test_controller.TakePicture(0, 0, 0, document.getElementById("publish_video1").name, 'png')
1780
+ console.log('检测图像长度',path.length)
1781
+ const img = new Image()
1782
+ img.src = path;
1783
+ img.width = 300 //
1784
+ img.onload = () => {
1785
+ const origin = cv.imread(img)
1786
+ // let start = new Date().getTime()
1787
+ const res = isLight(origin)
1788
+ if (res==1 || res==-1){
1789
+ // 背景曝光过度
1790
+ this.state.envInfo.lightResult = '不合格'
1791
+ } else {
1792
+ this.state.envInfo.lightResult = '合格'
1793
+ }
1794
+ this.setState({
1795
+ envInfo: this.state.envInfo
1796
+ })
1797
+ origin.delete()
1798
+ }
1799
+ }
1800
+ // else {
1801
+ // setTimeout(() => {
1802
+ // this.lightDetect()
1803
+ // }, 1000);
1804
+ // }
1805
+ }catch(err){
1806
+ console.error(err)
1549
1807
  }
1808
+ }
1809
+ saveVideoPoint = async (code, content) => {
1810
+ try {
1811
+ let result = await API.saveVideoPoint({
1812
+ title: POINT_TYPE[code],
1813
+ content: [content],
1814
+ code,
1815
+ activityId: this.props.businessNumber,
1816
+ sessionId: this.state.sessionId,
1817
+ roomId: this.state.channelId + '',
1818
+ appId: this.state.appId,
1819
+ recordId: this.state.recordId,
1820
+ });
1821
+ } catch (err) {
1822
+ console.error(err);
1823
+ if (err.status == 502 || err.status == 404) {
1824
+ }
1825
+ }
1826
+ }
1827
+ mountClick = () => {
1550
1828
  let data = {
1551
1829
  account: this.props.tellerAccount,
1552
1830
  type: '2',
@@ -1642,26 +1920,38 @@ class Video extends Component {
1642
1920
  }
1643
1921
  }
1644
1922
  console.log(objList, objList1, objList2)
1923
+ const cameraList = objList.filter(el => !el.actionname.includes(RECORD_DEVICE_NAME))
1924
+ const recorderDevice = objList.find(el => el.actionname.includes(RECORD_DEVICE_NAME))
1645
1925
  this.setState({
1646
- cameraList: objList,
1926
+ cameraList: cameraList,
1927
+ recorderDevice: recorderDevice,
1647
1928
  microphoneList: objList1,
1648
1929
  speakerList: objList2.length > 0 ? [objList2[0]] : []
1649
1930
  })
1650
1931
  let indexId = 0
1651
- objList.map((item, index) => {
1652
- if (item.actionname.indexOf('Integrated Camera') != -1) {
1932
+ let microId = 0
1933
+ // 摄像头设置默认
1934
+ objList.forEach((item, index) => {
1935
+ if (item.actionname.indexOf('HP Full-HD Camera') != -1) {
1936
+ indexId = index
1937
+ } else if (item.actionname.indexOf('Integrated Camera') != -1) {
1653
1938
  indexId = index
1654
1939
  }
1655
1940
  })
1656
- console.log(indexId)
1941
+ // 麦克风设置默认
1942
+ objList1.forEach((item, index) => {
1943
+ if (item.actionname.indexOf('Microphone Array (Realtek High Definition Audio(SST))') != -1) {
1944
+ microId = index
1945
+ }
1946
+ })
1947
+ console.log(indexId, microId)
1657
1948
  this.setState({
1658
1949
  cameraValue: objList[indexId].actionid,
1659
- microphoneValue: objList1[0].actionid
1950
+ microphoneValue: objList1[microId].actionid
1660
1951
  })
1661
1952
  if (!this.state.appId && !this.state.sessionType) {
1662
1953
  console.log('cameraValue', this.state.cameraValue)
1663
1954
  this.mpaasSig(data);
1664
- this.showEnvDetection()
1665
1955
  } else {
1666
1956
  console.log('cameraValue', this.state.cameraValue)
1667
1957
  this.setState({
@@ -1726,6 +2016,10 @@ class Video extends Component {
1726
2016
  this.state.rtoken = rtoken
1727
2017
  this.createRoom()
1728
2018
  this.saveLog('RM mrtc create room successfully, room_id=' + room_id)
2019
+
2020
+ this.state.imStatus = true
2021
+ this.saveLog('Join im room')
2022
+ console.log('加入IM房间')
1729
2023
  };
1730
2024
  // 创建房间失败
1731
2025
  this.test_controller.OnCreateRoomFailed = (err_code, err_msg) => {
@@ -1776,9 +2070,15 @@ class Video extends Component {
1776
2070
  this.test_controller.Publish(publish_config)
1777
2071
  })
1778
2072
  // this.publishAllScreen();
2073
+ // 单独发布录制屏幕设备的流
2074
+ this.publishRecorderDevice()
1779
2075
 
1780
2076
  this.roomCallBack(1, '', 0)
1781
2077
  this.saveLog('mrtc join room success')
2078
+
2079
+ this.state.imStatus = true
2080
+ this.saveLog('Join im room')
2081
+ console.log('加入IM房间')
1782
2082
  };
1783
2083
  // 加入房间失败
1784
2084
  this.test_controller.OnJoinRoomFailed = (err_code, err_msg) => {
@@ -1793,12 +2093,9 @@ class Video extends Component {
1793
2093
  this.state.rtoken = '',
1794
2094
  this.state.sessionId = '',
1795
2095
  this.state.imRoomId = ''
1796
- this.state.imJoinRoom = false
1797
2096
  if (this.state.imStatus) {
1798
2097
  console.log('disconnect断开连接')
1799
- this.state.manualClose = true
1800
2098
  this.state.imStatus = false
1801
- disconnect();
1802
2099
  }
1803
2100
  this.test_controller.Disconnect()
1804
2101
  let data = {
@@ -1809,71 +2106,24 @@ class Video extends Component {
1809
2106
  this.mpaasSig(data);
1810
2107
  };
1811
2108
  this.test_controller.OnSendTextMsgSucc = (msgId) => {
1812
- console.log('发送成功', msgId)
1813
- this.setState({
1814
- documentError: '',
1815
- isModalVisibleCustomer: false,
1816
- })
1817
- this.saveLog('mrtc OnSendTextMsgSucc:' + msgId)
2109
+ // console.log('发送成功', msgId)
2110
+ // this.saveLog('mrtc OnSendTextMsgSucc:' + msgId)
1818
2111
  }
1819
2112
  this.test_controller.OnSendTextMsgFailed = (msgId, code, msg) => {
1820
2113
  console.log('发送失败', msgId, code, msg)
1821
- this.setState({
1822
- documentError: '推送授权白板失败,请重试'
1823
- })
2114
+ const Mival = JSON.parse(msg)
2115
+ // 失败处理
2116
+ if (Mival.typeId == '3300') {
2117
+ this.setState({
2118
+ documentError: '推送授权白板失败,请重试'
2119
+ })
2120
+ }
1824
2121
  this.saveLog('mrtc OnSendTextMsgFail:' + msgId +', code=' + code + ',msg=' + msg)
1825
2122
  }
1826
2123
  this.test_controller.OnReceiveTextMsg = (uid, msg) => {
1827
- console.log('收到手机端消息', uid, msg, JSON.parse(msg).typeId, JSON.parse(msg).data.sessionId, this.state.sessionId)
1828
- if (JSON.parse(msg).typeId == 33001 && this.state.sessionId == JSON.parse(msg).data.sessionId) {
1829
- if (JSON.parse(msg).type == 1) {
1830
- this.saveAuthorize(JSON.parse(msg).data.userId)
1831
- this.customerFaceClick(this.state.customerList[this.state.customerSelect - 1])
1832
- }
1833
- }
1834
- // 线下demo静音处理
1835
- if (JSON.parse(msg).typeId == 4004 && this.state.sessionId == JSON.parse(msg).data.sessionId) {
1836
- if (this.isFileSuccuse()) {
1837
- if (!this.state.voiceStatue) {
1838
- // 静音本地
1839
- this.setState({
1840
- voiceStatue: true,
1841
- voiceImg: voiceImgCloe,
1842
- voiceName: '解除静音'
1843
- });
1844
- let sid = document.getElementById('publish_video1').name || document.getElementById('publish_streamId1').name;
1845
- this.test_controller.SetLocalAudioEnable(0, parseInt(sid, 10));
1846
- callNimIM('sendCustomCmdMsg', {
1847
- customId: this.state.imRoomId,
1848
- content: JSON.stringify({
1849
- 'typeId': 1013,
1850
- 'muteStatus': 1,
1851
- 'data': {
1852
- 'sessionId': this.state.sessionId,
1853
- 'userId': this.props.tellerAccount
1854
- }
1855
- })
1856
- }, function (code, message, data) {
1857
- // console.log(data)
1858
- })
1859
- }
1860
- document.getElementById('audio1').muted = true
1861
- console.log('音频流静音')
1862
- console.log(document.getElementById('audio1').muted)
1863
- setTimeout(() => {
1864
- callNimIM('sendCustomCmdMsg', {
1865
- customId: this.state.imRoomId,
1866
- content: JSON.stringify({
1867
- 'typeId': 1223,
1868
- 'state': 1, // app解除静音
1869
- 'sessionId': this.state.sessionId,
1870
- 'userId': uid //this.seeList(this.state.roomCustomerList, 'feedId', document.getElementById('feedId1').innerText).uid
1871
- })
1872
- });
1873
- }, 1000);
1874
- }
1875
- }
1876
- this.saveLog('mrtc OnReceiveTextMsg info:' + msg)
2124
+ console.log('收到手机端消息',uid, msg, JSON.parse(msg))
2125
+ // this.saveLog('mrtc OnReceiveTextMsg info:' + msg)
2126
+ this.handleReceiveMsg(msg)
1877
2127
  }
1878
2128
  this.test_controller.StreamFilterHandler = async (publish_tag, stream, stream_type, publish_device, media_type) => {
1879
2129
  console.log(`stream processed by client, publish_device=${publish_device}, media_type=${media_type}, publish_tag=${publish_tag},stream_type=${stream_type}`);
@@ -1889,12 +2139,13 @@ class Video extends Component {
1889
2139
  if (publish_tag == 'tag1') {
1890
2140
  console.log('tag1', stream)
1891
2141
  let newStream = stream;
1892
-
1893
2142
  if (stream.getVideoTracks()[0]) {
1894
- await startBeauty(newStream);
1895
- newStream = beautyCaptureStream();
1896
- await startHs(newStream);
1897
- newStream = hsCaptureStream();
2143
+ if (this.state.beautyType || isSuccuseHs){
2144
+ await startBeauty(newStream);
2145
+ newStream = beautyCaptureStream();
2146
+ await startHs(newStream);
2147
+ newStream = hsCaptureStream();
2148
+ }
1898
2149
  // 清理原始流
1899
2150
  newStream.oninactive = function () {
1900
2151
  clearOriginStream(stream);
@@ -1916,9 +2167,26 @@ class Video extends Component {
1916
2167
  }
1917
2168
 
1918
2169
  if (publish_tag == 'projectionWhiteboard' && publish_device == 2) {
1919
-
1920
2170
  let newStream1 = stream;
1921
2171
  if (stream.getVideoTracks()[0]) {
2172
+ try {
2173
+ console.log('共享')
2174
+ console.log(stream.getVideoTracks()[0])
2175
+ if ( stream.getVideoTracks()[0] instanceof BrowserCaptureMediaStreamTrack) {
2176
+ console.log('tab共享')
2177
+ this.saveLog('Share type = tab')
2178
+ } else if (stream.getVideoTracks()[0] instanceof MediaStreamTrack && stream.getVideoTracks()[0].label.includes('screen')) {
2179
+ console.log('屏幕共享')
2180
+ this.saveLog('Share type = screen')
2181
+ } else if (stream.getVideoTracks()[0].label.includes('window')){
2182
+ console.log('窗口共享')
2183
+ this.saveLog('Share type = window')
2184
+ }
2185
+ } catch (err) {
2186
+ console.log('不支持此浏览器记录投屏类型日志')
2187
+ console.log(navigator.userAgent)
2188
+ console.log(err)
2189
+ }
1922
2190
  if (this.state.operateShow) {
1923
2191
  await startMix(newStream1, 'mix');
1924
2192
 
@@ -1930,6 +2198,7 @@ class Video extends Component {
1930
2198
  canvas.width = this.state.widthVideo
1931
2199
  } else {
1932
2200
  await startMix(newStream1, 'none');
2201
+ isGraffiti = false
1933
2202
  }
1934
2203
 
1935
2204
  newStream1 = mixCaptureStream();
@@ -1950,27 +2219,25 @@ class Video extends Component {
1950
2219
  stream = null;
1951
2220
  }
1952
2221
  }
2222
+ if (stream.getAudioTracks()[0] && newStream1.addTrack) {
2223
+ newStream1.addTrack(stream.getAudioTracks()[0])
2224
+ }
1953
2225
  return newStream1
1954
- } else {
1955
- return stream
1956
2226
  }
1957
-
2227
+ return stream
1958
2228
  }
1959
2229
  // 发布媒体流成功
1960
2230
  this.test_controller.OnPublishSucc = (sid) => {
1961
2231
  console.log('发布媒体流成功', sid)
1962
2232
  this.state.sessionType = true
1963
2233
  if (sid == document.getElementById('video20').name) {
1964
- callNimIM('sendCustomCmdMsg', {
1965
- customId: this.state.imRoomId,
1966
- content: JSON.stringify({
1967
- 'typeId': 2030,
1968
- 'sessionId': this.state.sessionId,
1969
- 'sharedScreen': 1,
1970
- 'tellerId': this.props.tellerAccount
1971
- })
1972
- });
1973
- if (this.state.screenName == '切换共享') {
2234
+ this.sendMessage({
2235
+ 'typeId': 2030,
2236
+ 'sessionId': this.state.sessionId,
2237
+ 'sharedScreen': 1,
2238
+ 'tellerId': this.props.tellerAccount
2239
+ })
2240
+ if (this.state.screenName == '共享屏幕') {
1974
2241
  this.state.isSharedScreen = true
1975
2242
  this.state.isScreenSwitching = false
1976
2243
  }
@@ -1981,29 +2248,31 @@ class Video extends Component {
1981
2248
 
1982
2249
  loading: false,
1983
2250
  });
2251
+ setTimeout(() => {
2252
+ this.showEnvDetection()
2253
+ }, 1500);
2254
+
1984
2255
 
1985
2256
  this.enterRoom()
1986
2257
  this.updateMeetingInfo()
1987
2258
  this.timer = setInterval(
1988
2259
  () => {
1989
2260
  if (!this.state.voiceStatue && this.state.analyserHeight.get(sid).toFixed(2) > 0.1) {
1990
- callNimIM('sendCustomCmdMsg', {
1991
- customId: this.state.imRoomId,
1992
- content: JSON.stringify({
1993
- 'typeId': 3200,
1994
- 'decibelValue': this.state.analyserHeight.get(sid).toFixed(2),
1995
- "data": {
1996
- 'sessionId': this.state.sessionId,
1997
- 'userId': this.props.tellerAccount,
1998
- 'data': (new Date()).valueOf()
1999
- }
2000
-
2001
- })
2002
- });
2261
+ this.sendMessage({
2262
+ 'typeId': 3200,
2263
+ 'decibelValue': this.state.analyserHeight.get(sid).toFixed(2),
2264
+ "data": {
2265
+ 'sessionId': this.state.sessionId,
2266
+ 'userId': this.props.tellerAccount,
2267
+ 'data': (new Date()).valueOf()
2268
+ }
2269
+ })
2003
2270
  }
2004
2271
  },
2005
2272
  1000
2006
2273
  );
2274
+ this.mediaInfo = this.generateMediaInfo(document.getElementById("publish_video1").name);
2275
+
2007
2276
  } else {
2008
2277
  var box = document.getElementById("whiteboardDIV");
2009
2278
  var box1 = document.getElementById("operate")
@@ -2078,6 +2347,10 @@ class Video extends Component {
2078
2347
  participants.map((item, index) => {
2079
2348
  if (item.uid != this.state.tellerAccount) {
2080
2349
  item.publish.map((itemOne, indexOne) => {
2350
+ if (itemOne.tag && itemOne.tag.includes('UnSubscribe_RM')) {
2351
+ console.log('过滤订阅的tag:', itemOne.tag)
2352
+ return
2353
+ }
2081
2354
  let array = this.state.roomCustomerList;
2082
2355
  let newArray = [...array];
2083
2356
  newArray.push({
@@ -2138,6 +2411,7 @@ class Video extends Component {
2138
2411
  console.log(config_param)
2139
2412
  console.log('发起订阅')
2140
2413
  this.test_controller.Subscribe(config_param)
2414
+ document.getElementById(config_param.subscribe_video_id).name = 'temp'
2141
2415
 
2142
2416
  }
2143
2417
  })
@@ -2155,22 +2429,19 @@ class Video extends Component {
2155
2429
  this.test_controller.OnNewPublish = (feed) => {
2156
2430
  console.log('有新发布者', feed);
2157
2431
  console.log(new Date())
2158
- callNimIM('sendCustomCmdMsg', {
2159
- customId: this.state.imRoomId,
2160
- content: JSON.stringify({
2432
+ if (feed.tag && feed.tag.includes('UnSubscribe_RM')) {
2433
+ console.log('过滤订阅的tag:', feed.tag)
2434
+ return
2435
+ }
2436
+ this.sendMessage({
2161
2437
  'typeId': 1013,
2162
2438
  'muteStatus': this.state.voiceStatue ? 1 : 0,
2163
2439
  'data': {
2164
2440
  'sessionId': this.state.sessionId,
2165
2441
  'userId': this.props.tellerAccount
2166
2442
  }
2167
- })
2168
- }, function (code, message, data) {
2169
- console.log(data)
2170
2443
  })
2171
- callNimIM('sendCustomCmdMsg', {
2172
- customId: this.state.imRoomId,
2173
- content: JSON.stringify({
2444
+ this.sendMessage({
2174
2445
  'typeId': 1014,
2175
2446
  'sessionId': this.state.sessionId,
2176
2447
  'meetingInfo': {
@@ -2179,9 +2450,6 @@ class Video extends Component {
2179
2450
  'customers': this.props.meetingInfo.customers,
2180
2451
  'otherAttendees': this.props.meetingInfo.otherAttendees
2181
2452
  }
2182
-
2183
- })
2184
- }, function (code, message, data) {
2185
2453
  })
2186
2454
  this.sendNotification()
2187
2455
  let array = this.state.roomCustomerList;
@@ -2268,14 +2536,11 @@ class Video extends Component {
2268
2536
  this.test_controller.OnUnPublishSucc = (sid) => {
2269
2537
  console.log('取消发布成功', sid, document.getElementById('publish_video1').name)
2270
2538
  if (document.getElementById('publish_video1').name && sid != document.getElementById('publish_video1').name) {
2271
- callNimIM('sendCustomCmdMsg', {
2272
- customId: this.state.imRoomId,
2273
- content: JSON.stringify({
2539
+ this.sendMessage({
2274
2540
  'typeId': 2030,
2275
2541
  'sessionId': this.state.sessionId,
2276
2542
  'sharedScreen': 0,
2277
2543
  'tellerId': this.props.tellerAccount
2278
- })
2279
2544
  })
2280
2545
  this.state.isSharedScreen = false
2281
2546
  this.setState({
@@ -2374,6 +2639,10 @@ class Video extends Component {
2374
2639
  // let audio = new Audio(src)
2375
2640
  // audio.play()
2376
2641
  // }
2642
+ if (participant.includes('UnHint')){
2643
+ console.log('过滤掉的uid', participant)
2644
+ return
2645
+ }
2377
2646
 
2378
2647
 
2379
2648
  this.appGetUsernameClick(participant).then((res) => {
@@ -2411,44 +2680,97 @@ class Video extends Component {
2411
2680
  this.test_controller.OnNetworkWeak = (bpsSend, bpsRecv, sid) => {
2412
2681
  console.log('弱网回调', bpsSend, bpsRecv, sid)
2413
2682
  if (sid == document.getElementById('publish_video1').name) {
2414
- this.messageClick('当前网络环境较差', 'error')
2415
- this.saveLog('mrtc OnNetworkWeak')
2683
+
2684
+ this.detectNetworkWeak().then((isWeak) => {
2685
+ console.log('弱网结果:' + isWeak)
2686
+ if (isWeak) {
2687
+ this.messageClick('当前网络环境较差', 'error')
2688
+ this.saveLog('mrtc OnNetworkWeak')
2689
+ this.saveVideoPoint('wnd', 'RM端弱网');
2690
+ if (this.props.isWeakSound && this.state.ablePlayNetweakAudio) {
2691
+ this.state.ablePlayNetweakAudio = false;
2692
+ let src = networkWeakAudio
2693
+ let audio = new Audio(src)
2694
+ audio.play()
2695
+ setTimeout(() => {
2696
+ this.state.ablePlayNetweakAudio = true;
2697
+ }, 30000);
2698
+ }
2699
+ if (this.props.OnNetworkWeak) {
2700
+ this.props.OnNetworkWeak(bpsSend, bpsRecv, sid)
2701
+ }
2702
+ }
2703
+ })
2704
+
2416
2705
  }
2417
2706
  };
2418
2707
  // 开始服务端录制成功
2419
- this.test_controller.OnStartRemoteRecordSucc = (record_id) => {
2420
- console.log('开始服务端录制成功', record_id);
2421
- this.state.recordId = record_id
2422
- this.videoRecordCallback('1', true)
2423
- this.saveLog('mrtc OnStartRemoteRecordSucc')
2708
+ this.test_controller.OnStartRemoteRecordSucc = (record_id, record_third_id) => {
2709
+ console.log('开始服务端录制成功', record_id, record_third_id);
2710
+ if (!record_third_id) {
2711
+ // 全局录制
2712
+ this.state.recordId = record_id
2713
+ this.videoRecordCallback('1', true)
2714
+ this.saveLog('mrtc OnStartRemoteRecordSucc')
2715
+ } else {
2716
+ // 业务录制
2717
+ this.state.businessRecordId = record_id
2718
+ this.businessRecordCallback('1', true, record_third_id)
2719
+ this.saveLog('mrtc OnStartRemoteBusinessRecordSucc, businessId=' + record_third_id)
2720
+ }
2721
+
2722
+ if (this.state.isRecordingeErrorModalVisible) {
2723
+ this.setState({
2724
+ isRecordingeErrorModalVisible: false
2725
+ })
2726
+ }
2424
2727
  };
2425
2728
  // 开始服务端录制失败
2426
2729
  this.test_controller.OnStartRemoteRecordFailed = (
2427
2730
  record_id,
2428
2731
  err_code,
2429
- err_msg
2732
+ err_msg,
2733
+ record_third_id
2430
2734
  ) => {
2431
- this.videoRecordCallback('1', false)
2432
- console.log('开始服务端录制失败', record_id, err_code, err_msg)
2433
- this.saveLog('mrtc OnStartRemoteRecordFailed, code='+err_code)
2735
+ console.log('开始服务端录制失败', record_id, err_code, err_msg, record_third_id)
2736
+ if (!record_third_id) {
2737
+ this.videoRecordCallback('1', false)
2738
+ this.saveLog('mrtc OnStartRemoteRecordFailed, code='+err_code)
2739
+ } else {
2740
+ this.businessRecordCallback('1', false, record_third_id)
2741
+ this.saveLog('mrtc OnStartRemoteBusinessRecordFailed, code='+err_code + ',businessId=' + record_third_id)
2742
+ }
2434
2743
  };
2435
2744
  // 结束服务端录制成功
2436
- this.test_controller.OnStopRemoteRecordSucc = (recordId) => {
2437
- console.log('结束服务端录制成功', recordId);
2438
- this.videoRecordCallback('2', true)
2439
- this.saveLog('mrtc OnStopRemoteRecordSucc, recordId='+recordId)
2440
- // this.endSessionValue()
2745
+ this.test_controller.OnStopRemoteRecordSucc = (recordId, record_third_id) => {
2746
+ console.log('结束服务端录制成功', recordId, record_third_id);
2747
+ if (!record_third_id) {
2748
+ this.videoRecordCallback('2', true)
2749
+ this.saveLog('mrtc OnStopRemoteRecordSucc, recordId='+recordId)
2750
+ this.state.recordId = '';
2751
+ } else {
2752
+ this.businessRecordCallback('2', true, record_third_id)
2753
+ this.saveLog('mrtc OnStopRemoteBusinessRecordSucc, recordId='+recordId + ',businessId=' + record_third_id)
2754
+ this.state.businessRecordId = '';
2755
+ }
2441
2756
  // 获取服务端录制结果
2442
2757
  };
2443
2758
  // 结束服务端录制失败
2444
2759
  this.test_controller.OnStopRemoteRecordFailed = (
2445
2760
  recordId,
2446
2761
  err_code,
2447
- err_msg
2762
+ err_msg,
2763
+ record_third_id
2448
2764
  ) => {
2449
- this.videoRecordCallback('2', false)
2450
- console.log('结束服务端录制失败', recordId, err_code, err_msg)
2451
- this.saveLog('mrtc OnStopRemoteRecordFailed, err_code='+err_code)
2765
+ console.log('结束服务端录制失败', recordId, err_code, err_msg, record_third_id)
2766
+ if (!record_third_id) {
2767
+ this.videoRecordCallback('2', false)
2768
+ this.saveLog('mrtc OnStopRemoteRecordFailed, err_code='+err_code)
2769
+ } else {
2770
+ this.businessRecordCallback('2', false, record_third_id)
2771
+ this.saveLog('mrtc OnStopRemoteBusinessRecordFailed, err_code='+err_code+',businessId=' + record_third_id)
2772
+ }
2773
+
2452
2774
  };
2453
2775
  // 开启浏览器录制成功
2454
2776
  this.test_controller.OnClientStartRecordSuccess = (
@@ -2571,6 +2893,23 @@ class Video extends Component {
2571
2893
  ) => {
2572
2894
  console.log('下载失败', clientRecordId, code, msg)
2573
2895
  };
2896
+ // 日志上传成功
2897
+ this.test_controller.OnUploadLogSucc = (filePath) => {
2898
+ // const filePath = 'https://mpaas.oss-cn-hk-hsbc-d01-a.ali-ops.cloud.cn.hsbc/log/0E6C7637D9A53DF38D4CFC614EC8915C_41B8EEB302057/wmzTeller_681269134338102_1681269140267_1.log?Expires=1681269740&OSSAccessKeyId=Cq0vGDNN7WQeyn8n&Signature=avYEdwRSdblKIY7LhB6FzwpPAD8%3D'
2899
+
2900
+ console.info('OnUploadLogSucc', filePath)
2901
+ this.saveLog('mrtc OnUploadLogSucc, filePath=' + filePath)
2902
+
2903
+ // const exp1 = /.+\.log/g
2904
+ // const url = filePath.match(exp1)[0]
2905
+ // console.log(url)
2906
+ this.uploadLogCallback(filePath)
2907
+ };
2908
+ this.test_controller.OnUploadLogFail = (code, err_msg) => {
2909
+ // test_controller.trace(`upload log failed, err_code=${code}, err_msg=${JSON.stringify(err_msg)}`);
2910
+ console.info('OnUploadLogFail', code, err_msg)
2911
+ this.saveLog('mrtc OnUploadLogFail, code=' + code, ',msg=' + err_msg)
2912
+ };
2574
2913
  // 切流成功通知
2575
2914
  this.test_controller.OnChangeMediaStreamSuccess = (sid) => {
2576
2915
  console.log('切流成功通知', sid);
@@ -2731,7 +3070,7 @@ class Video extends Component {
2731
3070
  }
2732
3071
  // 停止共享
2733
3072
  this.test_controller.OnDesktopDisplayClosed = () => {
2734
- console.log('OnDesktopDisplayClosed', this.state.isSharedScreen, this.state.laveRoomSharedScreen)
3073
+ console.log('OnDesktopDisplayClosed', this.state.isSharedScreen, this.state.laveRoomSharedScreen, streamShare)
2735
3074
 
2736
3075
  if (this.state.isScreenSwitching) {
2737
3076
  this.state.isScreenSwitching = false
@@ -2890,12 +3229,54 @@ class Video extends Component {
2890
3229
  // duration: 10
2891
3230
  })
2892
3231
  }
3232
+ // 全局录制
2893
3233
  videoRecordCallback = async (type, status) => {
3234
+ if (status) {
3235
+ // 全局录制且开启成功,通知app
3236
+ this.sendMessage({
3237
+ 'typeId': 1030,
3238
+ 'type': type,
3239
+ 'sessionId': this.state.sessionId,
3240
+ 'recordId': this.state.recordId
3241
+ })
3242
+ }
3243
+ try {
3244
+ let result = await API.videoRecordCallback({
3245
+ activityId: this.props.businessNumber,
3246
+ sessionId: this.state.sessionId,
3247
+ roomId: this.state.channelId + '',
3248
+ appId: this.state.appId,
3249
+ recordId: this.state.recordId,
3250
+ type: type,
3251
+ status: status
3252
+ });
3253
+ console.log(result);
3254
+ } catch (err) {
3255
+ console.error(err);
3256
+ if (err.status == 502 || err.status == 404) {
3257
+ }
3258
+ }
3259
+ }
3260
+ // 业务录制回调
3261
+ businessRecordCallback = async (type, status, businessId) => {
3262
+ if (status) {
3263
+ this.sendMessage({
3264
+ 'typeId': 1031,
3265
+ 'type': type,
3266
+ 'id': businessId,
3267
+ 'sessionId': this.state.sessionId,
3268
+ 'recordId': this.state.recordId,
3269
+ 'businessRecordId': this.state.businessRecordId
3270
+ })
3271
+ }
2894
3272
  try {
2895
3273
  let result = await API.videoRecordCallback({
2896
3274
  activityId: this.props.businessNumber,
2897
3275
  sessionId: this.state.sessionId,
2898
3276
  roomId: this.state.channelId + '',
3277
+ id: businessId,
3278
+ appId: this.state.appId,
3279
+ recordId: this.state.businessRecordId,
2899
3280
  type: type,
2900
3281
  status: status
2901
3282
  });
@@ -2906,6 +3287,21 @@ class Video extends Component {
2906
3287
  }
2907
3288
  }
2908
3289
  }
3290
+ uploadLogCallback = async (url) => {
3291
+ try {
3292
+ let result = await API.uploadLogCallback({
3293
+ activityId: this.props.businessNumber,
3294
+ sessionId: this.state.sessionId,
3295
+ roomId: this.state.channelId + '',
3296
+ tellerAccount: this.props.tellerAccount,
3297
+ fileUrl: url
3298
+ });
3299
+ } catch (err) {
3300
+ // console.error(err);
3301
+ if (err.status == 502 || err.status == 404) {
3302
+ }
3303
+ }
3304
+ }
2909
3305
  // 保存mettingInfo
2910
3306
  updateMeetingInfo = async () => {
2911
3307
  let customers
@@ -2938,9 +3334,7 @@ class Video extends Component {
2938
3334
  });
2939
3335
  console.log(result);
2940
3336
  this.appGetUsername(document.getElementById('publish_video1').name)
2941
- callNimIM('sendCustomCmdMsg', {
2942
- customId: this.state.imRoomId,
2943
- content: JSON.stringify({
3337
+ this.sendMessage({
2944
3338
  'typeId': 1014,
2945
3339
  'sessionId': this.state.sessionId,
2946
3340
  'meetingInfo': {
@@ -2949,9 +3343,6 @@ class Video extends Component {
2949
3343
  'customers': this.props.meetingInfo.customers,
2950
3344
  'otherAttendees': this.props.meetingInfo.otherAttendees
2951
3345
  }
2952
-
2953
- })
2954
- }, function (code, message, data) {
2955
3346
  })
2956
3347
  } catch (err) {
2957
3348
  console.error(err);
@@ -2978,12 +3369,10 @@ class Video extends Component {
2978
3369
  this.stopASR()
2979
3370
  this.asr_controller.Disconnect()
2980
3371
  }
2981
- if (this.state.imStatus) {
2982
- console.log('disconnect断开连接')
2983
- this.state.manualClose = true
2984
- disconnect();
2985
- }
2986
3372
  message.destroy()
3373
+ clearInterval(this.state.drawCanvasInterval)
3374
+ clearInterval(this.state.faceDetectionTimer);
3375
+ clearInterval(this.state.imageDetectionTimer);
2987
3376
  }
2988
3377
  finishSession = () => {
2989
3378
  // clearInterval(this.state.OnVolumeAnalyserMap.get(sid))
@@ -3101,42 +3490,50 @@ class Video extends Component {
3101
3490
 
3102
3491
  }
3103
3492
  addToScriptClick = () => {
3493
+ let params = `?v=${SDK_VERISON}`
3104
3494
  const _dependScripts = [
3105
- // 'http://121.196.19.70/download/asr_api.js',
3106
- // 'http://121.196.19.70/download/reconnecting-websocket.min.js',
3107
- // 'http://121.196.19.70/download/resampler.js',
3108
- this.props.resourcePath + "/asr_api.js",
3109
- this.props.resourcePath + "/reconnecting-websocket.min.js",
3110
- this.props.resourcePath + "/resampler.js",
3111
- this.props.resourcePath + "/beauty/beauty_frame_pkg.js",
3112
- this.props.resourcePath + "/adapter.js",
3113
- this.props.resourcePath + "/getMediaInfo.js",
3114
- this.props.resourcePath + "/EBML.js",
3115
- this.props.resourcePath + "/mcu.js",
3116
- this.props.resourcePath + "/meeting_desk_stream.js",
3117
- this.props.resourcePath + "/meeting_html_stream.js",
3118
- this.props.resourcePath + "/meeting_file_stream.js",
3119
- this.props.resourcePath + "/meeting_im.js",
3120
- this.props.resourcePath + "/meeting_vod.js",
3121
- this.props.resourcePath + "/meeting_invite.js",
3122
- this.props.resourcePath + "/client_record.js",
3123
- this.props.resourcePath + "/remote_record.js",
3124
- this.props.resourcePath + "/meeting_camera_stream.js",
3125
- this.props.resourcePath + "/meeting_api.js",
3126
-
3127
- this.props.resourcePath + "/eruda.js",
3128
- this.props.resourcePath + "/iconfont.js",
3129
- this.props.resourcePath + "/html2canvas.js",
3130
- this.props.resourcePath + "/dom-to-image.js",
3131
-
3132
- this.props.resourcePath + "/hs/hs_human_segmentation_wrapper.js",
3133
- this.props.resourcePath + "/hs/hs_human_segmentation.js",
3134
- this.props.resourcePath + "/hs/hs_human_segmentation.wasm",
3135
-
3136
- this.props.resourcePath + "/mix/mix_frame.js",
3137
- this.props.resourcePath + "/mix/pageBoard.js"
3495
+ // this.props.resourcePath + "/opencv.js" + params,
3496
+ this.props.resourcePath + "/asr_api.js" + params,
3497
+ this.props.resourcePath + "/reconnecting-websocket.min.js" + params,
3498
+ this.props.resourcePath + "/resampler.js" + params,
3499
+ this.props.resourcePath + "/beauty/beauty_frame_pkg.js" + params,
3500
+ this.props.resourcePath + "/adapter.js" + params,
3501
+ this.props.resourcePath + "/getMediaInfo.js" + params,
3502
+ this.props.resourcePath + "/EBML.js" + params,
3503
+ this.props.resourcePath + "/mcu.js" + params,
3504
+ this.props.resourcePath + "/meeting_desk_stream.js" + params,
3505
+ this.props.resourcePath + "/meeting_html_stream.js" + params,
3506
+ this.props.resourcePath + "/meeting_file_stream.js" + params,
3507
+ this.props.resourcePath + "/meeting_im.js" + params,
3508
+ this.props.resourcePath + "/meeting_vod.js" + params,
3509
+ this.props.resourcePath + "/meeting_invite.js" + params,
3510
+ this.props.resourcePath + "/client_record.js" + params,
3511
+ this.props.resourcePath + "/remote_record.js" + params,
3512
+ this.props.resourcePath + "/meeting_camera_stream.js" + params,
3513
+ this.props.resourcePath + "/meeting_api.js" + params,
3514
+
3515
+ this.props.resourcePath + "/eruda.js" + params,
3516
+ this.props.resourcePath + "/iconfont.js" + params,
3517
+ this.props.resourcePath + "/html2canvas.js" + params,
3518
+ this.props.resourcePath + "/dom-to-image.js" + params,
3519
+
3520
+ this.props.resourcePath + "/hs/hs_human_segmentation_wrapper.js" + params,
3521
+ this.props.resourcePath + "/hs/hs_human_segmentation.js" + params,
3522
+ this.props.resourcePath + "/hs/hs_human_segmentation.wasm" + params,
3523
+
3524
+ this.props.resourcePath + "/mix/mix_frame.js" + params,
3525
+ this.props.resourcePath + "/mix/pageBoard.js" + params,
3138
3526
 
3139
3527
  ]
3528
+ try{
3529
+ if (!cv){
3530
+ _dependScripts.unshift(this.props.resourcePath + "/opencv.js" + params)
3531
+ }
3532
+ } catch(err) {
3533
+ console.log(err)
3534
+ _dependScripts.unshift(this.props.resourcePath + "/opencv.js" + params)
3535
+ }
3536
+
3140
3537
  const that = this
3141
3538
  let i = 0
3142
3539
  scriptAdd()
@@ -3151,14 +3548,14 @@ class Video extends Component {
3151
3548
  if (document.all) { //如果是IE
3152
3549
  script.onreadystatechange = () => {
3153
3550
  if (script.readyState == 'loaded' || script.readyState == 'complete') {
3154
- that.test_controller = new McuController();
3551
+ that.test_controller = new MeetingController();
3155
3552
  that.asr_controller = new AsrController()
3156
3553
  that.mountClick()
3157
3554
  }
3158
3555
  }
3159
3556
  } else {
3160
3557
  script.onload = () => {
3161
- that.test_controller = new McuController();
3558
+ that.test_controller = new MeetingController();
3162
3559
  that.asr_controller = new AsrController()
3163
3560
  that.mountClick()
3164
3561
  }
@@ -3182,7 +3579,17 @@ class Video extends Component {
3182
3579
  }
3183
3580
  }
3184
3581
  componentWillMount() {
3185
- console.log('hsbc_teller_sdk', '2.0.6')
3582
+ console.log('hsbc_teller_sdk', SDK_VERISON)
3583
+ // window.document.startRecord = () => {
3584
+ // this.enableServerRecording();
3585
+ // }
3586
+ // window.document.stopRecord = (recordId) => {
3587
+ // this.test_controller.StopRemoteRecord(recordId || this.state.recordId)
3588
+ // }
3589
+ // window.document.detectNetworkWeak = () => {
3590
+ // console.log('detectNetworkWeak')
3591
+ // this.test_controller.detectNetworkWeak()
3592
+ // }
3186
3593
  let arr = []
3187
3594
  for(let i=1;i<=12;i++){
3188
3595
  arr.push({
@@ -3196,6 +3603,18 @@ class Video extends Component {
3196
3603
  }
3197
3604
  this.setState({
3198
3605
  videoList: arr
3606
+ }, () => {
3607
+ // 设置播放回调
3608
+ for(let i=1;i<=12;i++){
3609
+ let dom = document.getElementById('video'+ i)
3610
+ dom.addEventListener("loadedmetadata", (event) => {
3611
+ console.log('video'+ i +' loadedmetadata:' + dom.srcObject.id)
3612
+ this.saveLog('video'+ i +' loadedmetadata, id=' + dom.srcObject.id)
3613
+ // let arrItem = this.state.videoList.find(el => el.idIndex == i) || {}
3614
+ // console.log(arrItem.videoName)
3615
+
3616
+ });
3617
+ }
3199
3618
  })
3200
3619
  if (this.props.sessionId) {
3201
3620
  this.getRoomStatus({
@@ -3221,20 +3640,15 @@ class Video extends Component {
3221
3640
  sid = document.getElementById('publish_streamId1').name
3222
3641
  }
3223
3642
  this.test_controller.SetLocalAudioEnable(0, parseInt(sid, 10));
3224
- callNimIM('sendCustomCmdMsg', {
3225
- customId: this.state.imRoomId,
3226
- content: JSON.stringify({
3643
+ this.saveVideoPoint('mute', 'RM端静音')
3644
+ this.sendMessage({
3227
3645
  'typeId': 1013,
3228
3646
  'muteStatus': 1,
3229
3647
  'data': {
3230
3648
  'sessionId': this.state.sessionId,
3231
3649
  'userId': this.props.tellerAccount
3232
3650
  }
3233
- })
3234
- }, function (code, message, data) {
3235
- console.log(data)
3236
3651
  })
3237
-
3238
3652
  } else if (this.state.voiceStatue) {
3239
3653
  // 打开本地
3240
3654
  this.setState({
@@ -3248,20 +3662,21 @@ class Video extends Component {
3248
3662
  sid = document.getElementById('publish_streamId1').name
3249
3663
  }
3250
3664
  this.test_controller.SetLocalAudioEnable(1, parseInt(sid, 10));
3251
- callNimIM('sendCustomCmdMsg', {
3252
- customId: this.state.imRoomId,
3253
- content: JSON.stringify({
3665
+ this.saveVideoPoint('mute', 'RM端解除静音')
3666
+ this.sendMessage({
3254
3667
  'typeId': 1013,
3255
3668
  'muteStatus': 0,
3256
3669
  'data': {
3257
3670
  'sessionId': this.state.sessionId,
3258
3671
  'userId': this.props.tellerAccount
3259
3672
  }
3260
- })
3261
- }, function (code, message, data) {
3262
- console.log(data)
3263
3673
  })
3264
3674
  }
3675
+ if (this.state.isPictureInPicture) {
3676
+ setTimeout(() => {
3677
+ this.pictureInPicture('Refresh')
3678
+ }, 0);
3679
+ }
3265
3680
  }
3266
3681
  };
3267
3682
  isFileSuccuse = () => {
@@ -3286,17 +3701,12 @@ class Video extends Component {
3286
3701
  sid = document.getElementById('publish_streamId1').name
3287
3702
  }
3288
3703
  this.test_controller.SetLocalVideoEnable(0, parseInt(sid, 10));
3289
- callNimIM('sendCustomCmdMsg', {
3290
- customId: this.state.imRoomId,
3291
- content: JSON.stringify({
3704
+ this.sendMessage({
3292
3705
  'typeId': 1012,
3293
3706
  'state': 0,
3294
3707
  'sessionId': this.state.sessionId,
3295
3708
  'userId': this.props.tellerAccount
3296
- })
3297
- }, function (code, message, data) {
3298
- console.log(data)
3299
- })
3709
+ })
3300
3710
  } else if (this.state.audioed) {
3301
3711
  this.state.audioed = false,
3302
3712
  this.setState({
@@ -3308,16 +3718,11 @@ class Video extends Component {
3308
3718
  sid = document.getElementById('publish_streamId1').name
3309
3719
  }
3310
3720
  this.test_controller.SetLocalVideoEnable(1, parseInt(sid, 10));
3311
- callNimIM('sendCustomCmdMsg', {
3312
- customId: this.state.imRoomId,
3313
- content: JSON.stringify({
3314
- 'typeId': 1012,
3315
- 'state': 1,
3316
- 'sessionId': this.state.sessionId,
3317
- 'userId': this.props.tellerAccount
3318
- })
3319
- }, function (code, message, data) {
3320
- console.log(data)
3721
+ this.sendMessage({
3722
+ 'typeId': 1012,
3723
+ 'state': 1,
3724
+ 'sessionId': this.state.sessionId,
3725
+ 'userId': this.props.tellerAccount
3321
3726
  })
3322
3727
  }
3323
3728
  }
@@ -3332,30 +3737,58 @@ class Video extends Component {
3332
3737
  streamShare = ''
3333
3738
  }
3334
3739
  if (this.state.isSharedScreen) {
3335
- const publish_config = {}
3740
+ this.test_controller.UnPublish(document.getElementById('video20').name)
3741
+ setTimeout(() => {
3336
3742
  publish_config.media_type = 1
3337
3743
  publish_config.publish_device = 2
3744
+ publish_config.need_volume_analyser = true
3338
3745
  publish_config.video_profile_type = 1
3339
- // publish_config.video_profile_type=100
3340
- // publish_config.video_profile_diy={width:1280, height:720, frameRate:8, bitrate:1500}
3746
+ publish_config.desktopStreamToCanvas = false
3341
3747
  publish_config.enableDesktopAudio = true
3342
3748
  publish_config.degradationType = 2
3343
- publish_config.desktopStreamToCanvas = false
3344
- publish_config.sid = document.getElementById('video20').name
3345
- this.test_controller.ChangeMediaStream(publish_config)
3346
- this.state.isScreenSwitching = true
3749
+ publish_config.publish_video_id = 'video20'
3750
+ publish_config.publish_streamId_id = 'subscribe_streamId20'
3751
+ publish_config.publish_tag = 'projectionWhiteboard'
3752
+ this.test_controller.Publish(publish_config)
3753
+ }, 300);
3754
+ // const publish_config = {}
3755
+ // publish_config.media_type = 1
3756
+ // publish_config.publish_device = 2
3757
+ // publish_config.video_profile_type = 1
3758
+ // // publish_config.video_profile_type=100
3759
+ // // publish_config.video_profile_diy={width:1280, height:720, frameRate:8, bitrate:1500}
3760
+ // publish_config.enableDesktopAudio = true
3761
+ // publish_config.degradationType = 2
3762
+ // publish_config.desktopStreamToCanvas = false
3763
+ // publish_config.sid = document.getElementById('video20').name
3764
+ // this.test_controller.ChangeMediaStream(publish_config)
3765
+ // this.state.isScreenSwitching = true
3347
3766
  } else {
3348
3767
  if (document.getElementById('video20').name) {
3349
- publish_config.media_type = 1;
3350
- publish_config.publish_device = 2;
3351
- publish_config.video_profile_type = 1
3352
- // publish_config.video_profile_type=100
3353
- // publish_config.video_profile_diy={width:1280, height:720, frameRate:8, bitrate:1500}
3354
- publish_config.enableDesktopAudio = true
3355
- publish_config.desktopStreamToCanvas = false
3356
- publish_config.degradationType = 2
3357
- publish_config.sid = document.getElementById('video20').name;
3358
- this.test_controller.ChangeMediaStream(publish_config);
3768
+ this.test_controller.UnPublish(document.getElementById('video20').name)
3769
+ setTimeout(() => {
3770
+ publish_config.media_type = 1
3771
+ publish_config.publish_device = 2
3772
+ publish_config.need_volume_analyser = true
3773
+ publish_config.video_profile_type = 1
3774
+ publish_config.desktopStreamToCanvas = false
3775
+ publish_config.enableDesktopAudio = true
3776
+ publish_config.degradationType = 2
3777
+ publish_config.publish_video_id = 'video20'
3778
+ publish_config.publish_streamId_id = 'subscribe_streamId20'
3779
+ publish_config.publish_tag = 'projectionWhiteboard'
3780
+ this.test_controller.Publish(publish_config)
3781
+ }, 300);
3782
+ // publish_config.media_type = 1;
3783
+ // publish_config.publish_device = 2;
3784
+ // publish_config.video_profile_type = 1
3785
+ // // publish_config.video_profile_type=100
3786
+ // // publish_config.video_profile_diy={width:1280, height:720, frameRate:8, bitrate:1500}
3787
+ // publish_config.enableDesktopAudio = true
3788
+ // publish_config.desktopStreamToCanvas = false
3789
+ // publish_config.degradationType = 2
3790
+ // publish_config.sid = document.getElementById('video20').name;
3791
+ // this.test_controller.ChangeMediaStream(publish_config);
3359
3792
  } else {
3360
3793
  publish_config.media_type = 1
3361
3794
  publish_config.publish_device = 2
@@ -3434,23 +3867,21 @@ class Video extends Component {
3434
3867
  sid = document.getElementById('publish_streamId1').name
3435
3868
  }
3436
3869
  this.test_controller.SetLocalAudioEnable(0, parseInt(sid, 10))
3870
+ this.saveVideoPoint('mute', 'RM端静音')
3437
3871
  } else {
3438
3872
  // 当前是
3439
3873
  this.test_controller.SetLocalAudioEnable(1, parseInt(sid, 10));
3874
+ this.saveVideoPoint('mute', 'RM端解除静音')
3440
3875
  this.setState({
3441
3876
  voiceImg: voiceImgOpen,
3442
3877
  voiceName: '静音'
3443
3878
  })
3444
3879
  }
3445
- callNimIM('sendCustomCmdMsg', {
3446
- customId: this.state.imRoomId,
3447
- content: JSON.stringify({
3448
- 'typeId': 1011,
3449
- 'state': 1,
3450
- 'sessionId': this.state.sessionId,
3451
- 'userId': this.props.tellerAccount
3452
- })
3453
- }, function (code, message, data) {
3880
+ this.sendMessage({
3881
+ 'typeId': 1011,
3882
+ 'state': 1,
3883
+ 'sessionId': this.state.sessionId,
3884
+ 'userId': this.props.tellerAccount
3454
3885
  })
3455
3886
  } else {
3456
3887
  this.setState({
@@ -3459,41 +3890,42 @@ class Video extends Component {
3459
3890
  }
3460
3891
 
3461
3892
  };
3893
+ handleOkPictureConfirm = () => {
3894
+ this.pictureInPictureClick('add')
3895
+ this.setState({isPictureConfirmModalVisible: false})
3896
+ }
3897
+ handleOkRecordConfirm = () => {
3898
+ if (!this.state.isPictureInPicture) {
3899
+ this.pictureInPicture()
3900
+ }
3901
+ this.saveLog('Start recording')
3902
+ this.enableServerRecording()
3903
+ }
3462
3904
  handleOk = () => {
3463
3905
  // 代表此时按钮是暂停会话,把isSuspend改成true变成恢复会话
3464
- callNimIM('sendCustomCmdMsg', {
3465
- customId: this.state.imRoomId,
3466
- content: JSON.stringify({
3467
- 'typeId': 1012,
3468
- 'state': 1,
3469
- 'sessionId': this.state.sessionId,
3470
- 'userId': this.props.tellerAccount
3471
- })
3472
- }, function (code, message, data) {
3473
- console.log(data)
3474
- });
3906
+ this.sendMessage({
3907
+ 'typeId': 1012,
3908
+ 'state': 1,
3909
+ 'sessionId': this.state.sessionId,
3910
+ 'userId': this.props.tellerAccount
3911
+ })
3475
3912
  this.setState({
3476
3913
  isSuspend: true,
3477
3914
  suspendName: '恢复'
3478
3915
  });
3479
- callNimIM('sendCustomCmdMsg', {
3480
- customId: this.state.imRoomId,
3481
- content: JSON.stringify({
3482
- 'typeId': 1011,
3483
- 'state': 0,
3484
- 'sessionId': this.state.sessionId,
3485
- 'userId': this.props.tellerAccount
3486
- })
3487
- }, function (code, message, data) {
3488
- console.log(data)
3489
- });
3916
+ this.sendMessage({
3917
+ 'typeId': 1011,
3918
+ 'state': 0,
3919
+ 'sessionId': this.state.sessionId,
3920
+ 'userId': this.props.tellerAccount
3921
+ })
3490
3922
  let sid = document.getElementById('publish_video1').name;
3491
3923
  if (!sid) {
3492
3924
  // 纯音频的时候sid在publish_streamId标签中
3493
3925
  sid = document.getElementById('publish_streamId1').name
3494
3926
  }
3495
3927
  this.test_controller.SetLocalAudioEnable(0, parseInt(sid, 10));
3496
- this.test_controller.SetLocalVideoEnable(0, parseInt(sid, 10));
3928
+ this.saveVideoPoint('mute', 'RM端静音')
3497
3929
  this.setState({
3498
3930
  isModalVisible: false
3499
3931
  })
@@ -3673,6 +4105,9 @@ class Video extends Component {
3673
4105
  // videoList: this.state.videoList
3674
4106
  // })
3675
4107
  this.videoListSort();
4108
+ if (this.state.isPictureInPicture) {
4109
+ this.pictureInPicture('Refresh')
4110
+ }
3676
4111
  } else {
3677
4112
  console.log('1')
3678
4113
  this.messageClick('保持信息失败', 'error')
@@ -3697,15 +4132,12 @@ class Video extends Component {
3697
4132
  console.log('ocrCallback', result.data,val)
3698
4133
  // this.messageClick('姓名:' + result.data.idCardName + ',身份证号:' + result.data.idCardNumber,'success')
3699
4134
  // this.messageClick('识别成功','success')
3700
- callNimIM('sendCustomCmdMsg', {
3701
- customId: this.state.imRoomId,
3702
- content: JSON.stringify({
3703
- 'typeId': 1020,
3704
- 'sessionId': this.state.sessionId,
3705
- 'cameraState': 1,
3706
- "userId": this.state.faceCustomerUid
3707
- })
3708
- });
4135
+ this.sendMessage({
4136
+ 'typeId': 1020,
4137
+ 'sessionId': this.state.sessionId,
4138
+ 'cameraState': 1,
4139
+ "userId": this.state.faceCustomerUid
4140
+ })
3709
4141
  if(this.state.documentType == 'ID_CARD') {
3710
4142
  if (result.data.side == 'front' && val == 1) {
3711
4143
  if(this.state.certificateValidity) {
@@ -3865,6 +4297,7 @@ class Video extends Component {
3865
4297
  })
3866
4298
  // this.messageClick('识别失败', 'error')
3867
4299
  this.errorCodeClick('ocr',result.code)
4300
+ this.saveLog('OCR failed, error code=' + result.code)
3868
4301
  }
3869
4302
  } catch (err) {
3870
4303
  this.setState({
@@ -3963,6 +4396,9 @@ class Video extends Component {
3963
4396
  // videoList: this.state.videoList
3964
4397
  // })
3965
4398
  this.videoListSort();
4399
+ if (this.state.isPictureInPicture) {
4400
+ this.pictureInPicture('Refresh')
4401
+ }
3966
4402
  } else {
3967
4403
  console.log('1')
3968
4404
  this.messageClick('保持信息失败', 'error')
@@ -3973,15 +4409,12 @@ class Video extends Component {
3973
4409
  }
3974
4410
  };
3975
4411
  handleCancelFacial = () => {
3976
- callNimIM('sendCustomCmdMsg', {
3977
- customId: this.state.imRoomId,
3978
- content: JSON.stringify({
3979
- 'typeId': 1020,
3980
- 'sessionId': this.state.sessionId,
3981
- 'cameraState': 1, // 1--打开前置 2--打开后置
3982
- "userId": this.state.faceCustomerUid
3983
- })
3984
- });
4412
+ this.sendMessage({
4413
+ 'typeId': 1020,
4414
+ 'sessionId': this.state.sessionId,
4415
+ 'cameraState': 1, // 1--打开前置 2--打开后置
4416
+ "userId": this.state.faceCustomerUid
4417
+ })
3985
4418
  this.setState({
3986
4419
  isModalVisibleFacial: false
3987
4420
  })
@@ -4006,15 +4439,12 @@ class Video extends Component {
4006
4439
  }
4007
4440
  }
4008
4441
  newFaceClick=()=>{
4009
- callNimIM('sendCustomCmdMsg', {
4010
- customId: this.state.imRoomId,
4011
- content: JSON.stringify({
4012
- 'typeId': 1020,
4013
- 'sessionId': this.state.sessionId,
4014
- 'cameraState': 2, // 1--打开前置 2--打开后置
4015
- "userId": this.state.faceCustomerUid
4016
- })
4017
- });
4442
+ this.sendMessage({
4443
+ 'typeId': 1020,
4444
+ 'sessionId': this.state.sessionId,
4445
+ 'cameraState': 2, // 1--打开前置 2--打开后置
4446
+ "userId": this.state.faceCustomerUid
4447
+ })
4018
4448
  this.setState({
4019
4449
  clickedFacial: false,
4020
4450
  clickedOcr: false,
@@ -4125,15 +4555,12 @@ class Video extends Component {
4125
4555
  } else {
4126
4556
  if (this.state.faceCustomerType == 2) {
4127
4557
  // ocr
4128
- callNimIM('sendCustomCmdMsg', {
4129
- customId: this.state.imRoomId,
4130
- content: JSON.stringify({
4131
- 'typeId': 1020,
4132
- 'sessionId': this.state.sessionId,
4133
- 'cameraState': 2, // 1--打开前置 2--打开后置
4134
- "userId": item.customId
4135
- })
4136
- });
4558
+ this.sendMessage({
4559
+ 'typeId': 1020,
4560
+ 'sessionId': this.state.sessionId,
4561
+ 'cameraState': 2, // 1--打开前置 2--打开后置
4562
+ "userId": item.customId
4563
+ })
4137
4564
  }
4138
4565
  var sid
4139
4566
  if (item.feedId == document.getElementById("feedId1").innerText) {
@@ -4204,19 +4631,25 @@ class Video extends Component {
4204
4631
  }
4205
4632
  }
4206
4633
  sgsinImage = () => {
4207
- if (this.state.IDtypeFrontOrBack == IDtypeFront) {
4208
- this.setState({
4209
- facialImg: this.test_controller.TakePicture(1, undefined, undefined, this.state.customOcrSid, 'png'),
4210
- isFaceImage: true,
4211
- facialImgFront: this.test_controller.TakePicture(1, undefined, undefined, this.state.customOcrSid, 'png'),
4212
- })
4213
- } else if (this.state.IDtypeFrontOrBack == IDtypeBack) {
4214
- this.setState({
4215
- facialImg: this.test_controller.TakePicture(1, undefined, undefined, this.state.customOcrSid, 'png'),
4216
- isFaceImage: true,
4217
- facialImgBack: this.test_controller.TakePicture(1, undefined, undefined, this.state.customOcrSid, 'png'),
4218
- })
4219
- }
4634
+ const imgBase64 = this.test_controller.TakePicture(1, undefined, undefined, this.state.customOcrSid, 'png')
4635
+ // console.log(imgBase64)
4636
+
4637
+ compressImage(imgBase64, (compressedImg)=>{
4638
+ // console.log(compressedImg)
4639
+ if (this.state.IDtypeFrontOrBack == IDtypeFront) {
4640
+ this.setState({
4641
+ facialImg: compressedImg,
4642
+ isFaceImage: true,
4643
+ facialImgFront: compressedImg,
4644
+ })
4645
+ } else if (this.state.IDtypeFrontOrBack == IDtypeBack) {
4646
+ this.setState({
4647
+ facialImg: compressedImg,
4648
+ isFaceImage: true,
4649
+ facialImgBack: compressedImg,
4650
+ })
4651
+ }
4652
+ })
4220
4653
 
4221
4654
  }
4222
4655
  handleChangeOcr = (val) => {
@@ -4228,10 +4661,10 @@ class Video extends Component {
4228
4661
  })
4229
4662
  }
4230
4663
  componentWillReceiveProps(props) {
4231
- this.state.channelId = props.roomId,
4232
- this.state.rtoken = props.mtoken,
4233
- this.state.sessionId = props.sessionId,
4234
- this.state.imRoomId = props.imRoomId
4664
+ this.state.channelId = props.roomId || this.state.channelId
4665
+ this.state.rtoken = props.mtoken || this.state.rtoken
4666
+ this.state.sessionId = props.sessionId || this.state.sessionId
4667
+ this.state.imRoomId = props.imRoomId || this.state.imRoomId
4235
4668
  }
4236
4669
  appGetUsernameClick = async (userId) => {
4237
4670
  let data = ''
@@ -4379,6 +4812,21 @@ class Video extends Component {
4379
4812
  })
4380
4813
  }
4381
4814
  }
4815
+ changePdfRendering = () => {
4816
+ if (this.props.pdfRendering) {
4817
+ // 暂停绘制
4818
+ clearInterval(this.state.drawCanvasInterval)
4819
+ } else {
4820
+ // 继续绘制
4821
+ if (!this.drawFunction) {
4822
+ console.log('未开始远程签署')
4823
+ return
4824
+ }
4825
+ clearInterval(this.state.drawCanvasInterval)
4826
+ this.state.drawCanvasInterval = setInterval(this.drawFunction, 1000 / 20);
4827
+ }
4828
+
4829
+ }
4382
4830
  navigatorClick = () => {
4383
4831
  const that = this
4384
4832
  const publish_config = {};
@@ -4408,8 +4856,10 @@ class Video extends Component {
4408
4856
  canvas.width = 960;
4409
4857
  canvas.height = 540;
4410
4858
 
4411
-
4412
- videoMedia.addEventListener('play', (event) => {
4859
+ if (this.state.whiteboardPlayEvent) {
4860
+ videoMedia.removeEventListener('play', this.state.whiteboardPlayEvent)
4861
+ }
4862
+ this.state.whiteboardPlayEvent = (event) => {
4413
4863
  var $this = this; //cache
4414
4864
  if ($this.state.operateShow) {
4415
4865
  isGraffiti = false
@@ -4420,20 +4870,21 @@ class Video extends Component {
4420
4870
  canvas.width = this.state.whiteboardWidth
4421
4871
  }
4422
4872
  console.log('addEventListener', !$this.paused, !$this.ended, x, y, width, height)
4423
- loop()
4424
- function loop() {
4425
- if (!$this.paused && !$this.ended) {
4426
- // if(!that.state.tabTitles.find(el=>el.value == 'customerScreen')) {
4427
- cobj.drawImage(videoMedia, x, y, width, height, 0, 0, 960, 540);
4428
- // } else {
4429
- // cobj.fillStyle = 'rgb(0 0 0)'
4430
- // cobj.fillRect(0,0,960,540)
4431
- // }
4432
4873
 
4433
- setTimeout(loop, 1000 / 20); // drawing at 30fps
4434
- }
4874
+ if (this.state.drawCanvasInterval) clearInterval(this.state.drawCanvasInterval)
4875
+ $this.drawFunction = () => {
4876
+ if (!$this.paused && !$this.ended) {
4877
+ // if(!that.state.tabTitles.find(el=>el.value == 'customerScreen')) {
4878
+ cobj.drawImage(videoMedia, x, y, width, height, 0, 0, 960, 540);
4879
+ // } else {
4880
+ // cobj.fillStyle = 'rgb(0 0 0)'
4881
+ // cobj.fillRect(0,0,960,540)
4882
+ // }
4883
+ }
4435
4884
  }
4436
4885
 
4886
+ this.state.drawCanvasInterval = setInterval($this.drawFunction , 1000/ 20);
4887
+
4437
4888
  if (document.getElementById('video20').name) {
4438
4889
  // 代表已经有了进行切流
4439
4890
  publish_config.publish_device = 5
@@ -4456,7 +4907,8 @@ class Video extends Component {
4456
4907
  publish_config.publish_tag = 'projectionWhiteboard'
4457
4908
  this.test_controller.Publish(publish_config)
4458
4909
  }
4459
- }, 0);
4910
+ }
4911
+ videoMedia.addEventListener('play', this.state.whiteboardPlayEvent);
4460
4912
  navigator.mediaDevices.getDisplayMedia({
4461
4913
  video: true,
4462
4914
  preferCurrentTab: true,
@@ -4488,13 +4940,34 @@ class Video extends Component {
4488
4940
  that.test_controller.UnPublish(document.getElementById('video20').name)
4489
4941
  }
4490
4942
  }
4943
+
4944
+ // 关闭当前共享屏幕
4945
+ document.getElementById('video20') && document.getElementById('video20').name ? this.test_controller.UnPublish(document.getElementById('video20').name) : ''
4946
+ that.state.isSharedScreen = false
4947
+ that.state.isScreenSwitching = false
4948
+ that.setState({
4949
+ screenName: '共享模式'
4950
+ });
4951
+ that.tabTitlesClick('RMScreen', 'delect')
4952
+
4491
4953
  }, error => {
4492
4954
  console.log("Unable to acquire screen capture", error);
4493
4955
  });
4494
4956
  }
4495
- // publishAllScreen = () => {
4496
-
4497
- // }
4957
+ publishRecorderDevice = () => {
4958
+ if (this.state.recorderDevice){
4959
+ let publish_config = {}
4960
+ publish_config.media_type = 3
4961
+ publish_config.publish_device = 1
4962
+ publish_config.videoSource = this.state.recorderDevice.actionid
4963
+ publish_config.video_profile_type = 100
4964
+ publish_config.video_profile_diy = { width: 640, height: 360, frameRate: 15, bitrate: 400 }
4965
+ publish_config.publish_video_id = 'publish_video_record_device'
4966
+ publish_config.publish_streamId_id = 'publish_streamId_record_device'
4967
+ publish_config.publish_tag = 'sharedScreen'
4968
+ this.test_controller.Publish(publish_config)
4969
+ }
4970
+ }
4498
4971
  publishAllScreen = () => {
4499
4972
  const that = this
4500
4973
  const publish_config = {};
@@ -4767,6 +5240,7 @@ class Video extends Component {
4767
5240
  jsHeapSizeLimit: '未知', // 上下文内可用堆的最大体积
4768
5241
  totalJSHeapSize: '未知', // 已分配的堆体积
4769
5242
  usedJSHeapSize: '未知', // 当前 JS 堆活跃段(segment)的体积
5243
+ lightResult: this.state.envInfo? this.state.envInfo.lightResult : '未知'
4770
5244
  }
4771
5245
 
4772
5246
  if (navigator) {
@@ -4800,8 +5274,12 @@ class Video extends Component {
4800
5274
  // console.log(`有效网络连接类型: ${effectiveType}`);
4801
5275
  // console.log(`估算的下行速度/带宽: ${downlink}Mb/s`);
4802
5276
  // console.log(`估算的往返时间: ${rtt}ms`);
4803
- if (!window.navigator.onLine) {envInfo.networkInfo = ''}
4804
- else envInfo.networkInfo = `等效网络类型:${effectiveType};预估下行速度/带宽:${downlink}Mb/s;预估往返延时:${rtt}ms`
5277
+ if (!window.navigator.onLine) {
5278
+ envInfo.networkInfo = ''}
5279
+ else {
5280
+ envInfo.networkInfo = `等效网络类型:${effectiveType};预估下行速度/带宽:${downlink}Mb/s;预估往返延时:${rtt}ms`
5281
+ envInfo.networkResult = downlink > 0.2? '合格': '不合格'
5282
+ }
4805
5283
  }
4806
5284
  setNetworkInfo()
4807
5285
  navigator.connection.removeEventListener('change', self.envDetection);
@@ -4831,7 +5309,8 @@ class Video extends Component {
4831
5309
  // console.log('当前 JS 堆活跃段(segment)的体积', envInfo.usedJSHeapSize)
4832
5310
  envInfo.memoryResult = '合格'
4833
5311
  }
4834
-
5312
+ // 背景曝光环境检测
5313
+ this.lightDetect()
4835
5314
 
4836
5315
  this.setState({
4837
5316
  // isModalVisibleEnvironment: true,
@@ -4842,6 +5321,9 @@ class Video extends Component {
4842
5321
  this.setState({
4843
5322
  isModalVisibleEnvironment: false,
4844
5323
  })
5324
+ if (!this.state.isPictureInPicture) {
5325
+ this.pictureInPicture()
5326
+ }
4845
5327
  }
4846
5328
  // handleCancelEnvDetection = () => {
4847
5329
  // this.setState({
@@ -4893,16 +5375,39 @@ class Video extends Component {
4893
5375
  this.setState({
4894
5376
  beautyName: '开启美颜'
4895
5377
  })
5378
+ beautyMode = 'none'
4896
5379
  beautySetMode('none')
5380
+ beautyStop()
5381
+ if(!isSuccuseHs) {
5382
+ stopHs()
5383
+ }
4897
5384
  } else {
4898
5385
  this.state.beautyType = true
5386
+ beautyMode = 'beauty'
4899
5387
  beautySetMode('beauty')
4900
5388
  this.setState({
4901
5389
  beautyName: '关闭美颜'
4902
5390
  })
4903
5391
  }
5392
+ this.changeMediaStream();
4904
5393
 
4905
5394
  }
5395
+ changeMediaStream = () => {
5396
+ let publish_config = {}
5397
+ publish_config.sid = document.getElementById('publish_video1').name
5398
+ publish_config.media_type = 1
5399
+ publish_config.publish_device = 1
5400
+ // publish_config.videoSource = this.state.cameraValue
5401
+ // publish_config.audioSource = this.state.microphoneValue
5402
+ publish_config.need_volume_analyser = true
5403
+ publish_config.video_profile_type = 100
5404
+ publish_config.video_profile_diy = { width: 640, height: 360, frameRate: 15, bitrate: 400 }
5405
+ // publish_config.publish_video_id = 'publish_video1'
5406
+ // publish_config.publish_streamId_id = 'publish_streamId1'
5407
+ // publish_config.publish_tag = 'tag1'
5408
+ this.test_controller.ChangeMediaStream(publish_config)
5409
+ }
5410
+
4906
5411
  componentDidMount() {
4907
5412
  var box = document.getElementById("whiteboardDIV");
4908
5413
  var box1 = document.getElementById("operate")
@@ -4920,117 +5425,81 @@ class Video extends Component {
4920
5425
  muteOpposite = (value) => {
4921
5426
  console.log(value);
4922
5427
  if (value == 'video1') {
4923
- callNimIM('sendCustomCmdMsg', {
4924
- customId: this.state.imRoomId,
4925
- content: JSON.stringify({
4926
- 'typeId': 1223,
4927
- 'sessionId': this.state.sessionId,
4928
- 'userId': this.seeList(this.state.roomCustomerList, 'feedId', document.getElementById('feedId1').innerText).uid
4929
- })
4930
- });
5428
+ this.sendMessage({
5429
+ 'typeId': 1223,
5430
+ 'sessionId': this.state.sessionId,
5431
+ 'userId': this.seeList(this.state.roomCustomerList, 'feedId', document.getElementById('feedId1').innerText).uid
5432
+ })
4931
5433
  }
4932
5434
  if (value == 'video2') {
4933
- callNimIM('sendCustomCmdMsg', {
4934
- customId: this.state.imRoomId,
4935
- content: JSON.stringify({
4936
- 'typeId': 1223,
4937
- 'sessionId': this.state.sessionId,
4938
- 'userId': this.seeList(this.state.roomCustomerList, 'feedId', document.getElementById('feedId2').innerText).uid
4939
- })
4940
- });
5435
+ this.sendMessage({
5436
+ 'typeId': 1223,
5437
+ 'sessionId': this.state.sessionId,
5438
+ 'userId': this.seeList(this.state.roomCustomerList, 'feedId', document.getElementById('feedId2').innerText).uid
5439
+ })
4941
5440
  } if (value == 'video3') {
4942
- callNimIM('sendCustomCmdMsg', {
4943
- customId: this.state.imRoomId,
4944
- content: JSON.stringify({
4945
- 'typeId': 1223,
4946
- 'sessionId': this.state.sessionId,
4947
- 'userId': this.seeList(this.state.roomCustomerList, 'feedId', document.getElementById('feedId3').innerText).uid
4948
- })
4949
- });
5441
+ this.sendMessage({
5442
+ 'typeId': 1223,
5443
+ 'sessionId': this.state.sessionId,
5444
+ 'userId': this.seeList(this.state.roomCustomerList, 'feedId', document.getElementById('feedId3').innerText).uid
5445
+ })
4950
5446
  } if (value == 'video4') {
4951
- callNimIM('sendCustomCmdMsg', {
4952
- customId: this.state.imRoomId,
4953
- content: JSON.stringify({
4954
- 'typeId': 1223,
4955
- 'sessionId': this.state.sessionId,
4956
- 'userId': this.seeList(this.state.roomCustomerList, 'feedId', document.getElementById('feedId4').innerText).uid
4957
- })
4958
- });
5447
+ this.sendMessage({
5448
+ 'typeId': 1223,
5449
+ 'sessionId': this.state.sessionId,
5450
+ 'userId': this.seeList(this.state.roomCustomerList, 'feedId', document.getElementById('feedId4').innerText).uid
5451
+ })
4959
5452
  } if (value == 'video5') {
4960
- callNimIM('sendCustomCmdMsg', {
4961
- customId: this.state.imRoomId,
4962
- content: JSON.stringify({
4963
- 'typeId': 1223,
4964
- 'sessionId': this.state.sessionId,
4965
- 'userId': this.seeList(this.state.roomCustomerList, 'feedId', document.getElementById('feedId5').innerText).uid
4966
- })
4967
- });
5453
+ this.sendMessage({
5454
+ 'typeId': 1223,
5455
+ 'sessionId': this.state.sessionId,
5456
+ 'userId': this.seeList(this.state.roomCustomerList, 'feedId', document.getElementById('feedId5').innerText).uid
5457
+ })
4968
5458
  } if (value == 'video6') {
4969
- callNimIM('sendCustomCmdMsg', {
4970
- customId: this.state.imRoomId,
4971
- content: JSON.stringify({
4972
- 'typeId': 1223,
4973
- 'sessionId': this.state.sessionId,
4974
- 'userId': this.seeList(this.state.roomCustomerList, 'feedId', document.getElementById('feedId6').innerText).uid
4975
- })
4976
- });
5459
+ this.sendMessage({
5460
+ 'typeId': 1223,
5461
+ 'sessionId': this.state.sessionId,
5462
+ 'userId': this.seeList(this.state.roomCustomerList, 'feedId', document.getElementById('feedId6').innerText).uid
5463
+ })
4977
5464
  } if (value == 'video7') {
4978
- callNimIM('sendCustomCmdMsg', {
4979
- customId: this.state.imRoomId,
4980
- content: JSON.stringify({
4981
- 'typeId': 1223,
4982
- 'sessionId': this.state.sessionId,
4983
- 'userId': this.seeList(this.state.roomCustomerList, 'feedId', document.getElementById('feedId7').innerText).uid
4984
- })
4985
- });
5465
+ this.sendMessage({
5466
+ 'typeId': 1223,
5467
+ 'sessionId': this.state.sessionId,
5468
+ 'userId': this.seeList(this.state.roomCustomerList, 'feedId', document.getElementById('feedId7').innerText).uid
5469
+ })
4986
5470
  } if (value == 'video8') {
4987
- callNimIM('sendCustomCmdMsg', {
4988
- customId: this.state.imRoomId,
4989
- content: JSON.stringify({
4990
- 'typeId': 1223,
4991
- 'sessionId': this.state.sessionId,
4992
- 'userId': this.seeList(this.state.roomCustomerList, 'feedId', document.getElementById('feedId8').innerText).uid
4993
- })
4994
- });
5471
+ this.sendMessage({
5472
+ 'typeId': 1223,
5473
+ 'sessionId': this.state.sessionId,
5474
+ 'userId': this.seeList(this.state.roomCustomerList, 'feedId', document.getElementById('feedId8').innerText).uid
5475
+ })
4995
5476
  } if (value == 'video9') {
4996
- callNimIM('sendCustomCmdMsg', {
4997
- customId: this.state.imRoomId,
4998
- content: JSON.stringify({
4999
- 'typeId': 1223,
5000
- 'sessionId': this.state.sessionId,
5001
- 'userId': this.seeList(this.state.roomCustomerList, 'feedId', document.getElementById('feedId9').innerText).uid
5002
- })
5003
- });
5477
+ this.sendMessage({
5478
+ 'typeId': 1223,
5479
+ 'sessionId': this.state.sessionId,
5480
+ 'userId': this.seeList(this.state.roomCustomerList, 'feedId', document.getElementById('feedId9').innerText).uid
5481
+ })
5004
5482
  }
5005
5483
  if (value == 'video10') {
5006
- callNimIM('sendCustomCmdMsg', {
5007
- customId: this.state.imRoomId,
5008
- content: JSON.stringify({
5009
- 'typeId': 1223,
5010
- 'sessionId': this.state.sessionId,
5011
- 'userId': this.seeList(this.state.roomCustomerList, 'feedId', document.getElementById('feedId10').innerText).uid
5012
- })
5013
- });
5484
+ this.sendMessage({
5485
+ 'typeId': 1223,
5486
+ 'sessionId': this.state.sessionId,
5487
+ 'userId': this.seeList(this.state.roomCustomerList, 'feedId', document.getElementById('feedId10').innerText).uid
5488
+ })
5014
5489
  }
5015
5490
  if (value == 'video11') {
5016
- callNimIM('sendCustomCmdMsg', {
5017
- customId: this.state.imRoomId,
5018
- content: JSON.stringify({
5019
- 'typeId': 1223,
5020
- 'sessionId': this.state.sessionId,
5021
- 'userId': this.seeList(this.state.roomCustomerList, 'feedId', document.getElementById('feedId11').innerText).uid
5022
- })
5023
- });
5491
+ this.sendMessage({
5492
+ 'typeId': 1223,
5493
+ 'sessionId': this.state.sessionId,
5494
+ 'userId': this.seeList(this.state.roomCustomerList, 'feedId', document.getElementById('feedId11').innerText).uid
5495
+ })
5024
5496
  }
5025
5497
  if (value == 'video12') {
5026
- callNimIM('sendCustomCmdMsg', {
5027
- customId: this.state.imRoomId,
5028
- content: JSON.stringify({
5029
- 'typeId': 1223,
5030
- 'sessionId': this.state.sessionId,
5031
- 'userId': this.seeList(this.state.roomCustomerList, 'feedId', document.getElementById('feedId12').innerText).uid
5032
- })
5033
- });
5498
+ this.sendMessage({
5499
+ 'typeId': 1223,
5500
+ 'sessionId': this.state.sessionId,
5501
+ 'userId': this.seeList(this.state.roomCustomerList, 'feedId', document.getElementById('feedId12').innerText).uid
5502
+ })
5034
5503
  }
5035
5504
 
5036
5505
  }
@@ -5039,14 +5508,11 @@ class Video extends Component {
5039
5508
  this.state.shareMaskState = this.props.shareMask
5040
5509
  // 加延迟是因为在关闭的时候可以看到部分rm的操作
5041
5510
  setTimeout(() => {
5042
- callNimIM('sendCustomCmdMsg', {
5043
- customId: this.state.imRoomId,
5044
- content: JSON.stringify({
5045
- 'typeId': 1230,
5046
- 'sessionId': this.state.sessionId,
5047
- 'type': this.state.shareMaskState ? 1 : 2
5048
- })
5049
- });
5511
+ this.sendMessage({
5512
+ 'typeId': 1230,
5513
+ 'sessionId': this.state.sessionId,
5514
+ 'type': this.state.shareMaskState ? 1 : 2
5515
+ })
5050
5516
  }, 100)
5051
5517
 
5052
5518
  }
@@ -5054,11 +5520,18 @@ class Video extends Component {
5054
5520
  if (!isSuccuseHs) {
5055
5521
 
5056
5522
  hsSetMode('blur')
5523
+ hsMode = 'blur'
5057
5524
  isSuccuseHs = true
5058
5525
  } else {
5059
5526
  hsSetMode('none')
5527
+ hsMode = 'none'
5060
5528
  isSuccuseHs = false
5529
+ stopHs()
5530
+ if(!this.state.beautyType) {
5531
+ beautyStop()
5532
+ }
5061
5533
  }
5534
+ this.changeMediaStream();
5062
5535
  }
5063
5536
  virtualization = () => {
5064
5537
  this.virtualizationClick()
@@ -5085,6 +5558,17 @@ class Video extends Component {
5085
5558
  return false;
5086
5559
  }
5087
5560
  }
5561
+ isHKPassValidTime=(value)=>{
5562
+ if (!value.split('.') || value.split('.').length < 3 || value.split('.').some(el => el == '')) return false;
5563
+ let start = new Date('2020.01.01').valueOf();
5564
+ let end = new Date('2023.12.31').valueOf();
5565
+ var time = new Date(value).valueOf();
5566
+ if(start<=time && end >= time ){
5567
+ return true;
5568
+ }else{
5569
+ return false;
5570
+ }
5571
+ }
5088
5572
  handleChangeCertificateValidity = (event) => {
5089
5573
  // 护照只有起始日期,单独处理
5090
5574
  if (this.state.documentType == 'PASSPORT_CARD' && event.target.value.split('.').length >2) {
@@ -5105,6 +5589,12 @@ class Video extends Component {
5105
5589
  certificateValidity: event.target.value,
5106
5590
  certificateValidityType: true
5107
5591
  });
5592
+ } else if (this.state.documentType == 'HK_MO_PASS_CARD' && this.isHKPassValidTime(event.target.value.split('-')[1])){
5593
+ // 疫情政策对港澳来往通行证放宽限制,有效期限从2020.1.1到2023.12.31都算有效
5594
+ this.setState({
5595
+ certificateValidity: event.target.value,
5596
+ certificateValidityType: true
5597
+ });
5108
5598
  } else {
5109
5599
  this.setState({
5110
5600
  certificateValidity: event.target.value,
@@ -5119,6 +5609,9 @@ class Video extends Component {
5119
5609
  if (this.props.shareMask != prevProps.shareMask) {
5120
5610
  this.sendNotification()
5121
5611
  }
5612
+ if (this.props.pdfRendering != prevProps.pdfRendering) {
5613
+ this.changePdfRendering()
5614
+ }
5122
5615
  }
5123
5616
  onChangeOCRCustomer = (e) => {
5124
5617
  console.log(e)
@@ -5219,8 +5712,10 @@ class Video extends Component {
5219
5712
 
5220
5713
  }))
5221
5714
  }
5222
-
5223
-
5715
+ this.setState({
5716
+ documentError: '',
5717
+ isModalVisibleCustomer: false,
5718
+ })
5224
5719
  }
5225
5720
  })
5226
5721
  // this.customerFaceClick(this.state.customerList[this.state.customerSelect])
@@ -5669,7 +6164,7 @@ class Video extends Component {
5669
6164
  <audio id={'audio'+(item.idIndex)} autoPlay />
5670
6165
  <label style={{ display: 'none' }} id={'feedId'+(item.idIndex)} type="text" />
5671
6166
 
5672
- <div style={{ display: (item.videoName) ? '' : 'none'}} className={`customerTitle titleSamlle`}>
6167
+ <div onClick={this.muteOpposite.bind(this, 'video'+(item.idIndex))} style={{ display: (item.videoName) ? '' : 'none'}} className={`customerTitle titleSamlle`}>
5673
6168
  {
5674
6169
  item.mute && <img
5675
6170
  alt=""
@@ -5736,6 +6231,23 @@ class Video extends Component {
5736
6231
  !this.state.isSuspend && <span>确定是否暂停会话?</span>
5737
6232
  }
5738
6233
  </Modal>
6234
+ {/* 画中画重新开启确认 */}
6235
+ <Modal closable={false} centered={true} visible={this.state.isPictureConfirmModalVisible} maskClosable={false} footer={[
6236
+ <div key='end'>
6237
+ {/* <Button className="modelButtonCancel" onClick={()=> {this.setState({isPictureConfirmModalVisible: false})}}>取消</Button> */}
6238
+ <Button className="modelButtonOk" type="primary" danger onClick={this.handleOkPictureConfirm}>确定</Button>
6239
+ </div>
6240
+ ]}>
6241
+ <div className='endModal'>画中画已关闭,请重新开启</div>
6242
+ </Modal>
6243
+ {/* 双录中断重新开启确认 */}
6244
+ <Modal closable={false} centered={true} visible={this.state.isRecordingeErrorModalVisible} maskClosable={false} footer={[
6245
+ <div key='end'>
6246
+ <Button className="modelButtonOk" type="primary" danger onClick={this.handleOkRecordConfirm}>确定</Button>
6247
+ </div>
6248
+ ]}>
6249
+ <div className='endModal'>双录异常中断,请重新开启</div>
6250
+ </Modal>
5739
6251
  {/* 是否退出会议*/}
5740
6252
  <Modal closable={false} centered={true} visible={this.state.isModalVisibleEnd} maskClosable={false} footer={[
5741
6253
  <div key='end'>
@@ -5743,7 +6255,7 @@ class Video extends Component {
5743
6255
  <Button className="modelButtonOk" type="primary" danger onClick={this.handleOkEnd}>确定</Button>
5744
6256
  </div>
5745
6257
  ]}>
5746
- <div className='endModal'>是否要结束并退出会议?</div>
6258
+ <div className='endModal'>{this.state.businessId? '正在进行业务录制,是否确认结束并退出会议?': '是否要结束并退出会议?'}</div>
5747
6259
  </Modal>
5748
6260
  {/* ocr及人脸 */}
5749
6261
  <Modal title={this.state.titleModal} width={800} closable={true} maskClosable={false} onCancel={this.handleCancelFacial} centered={true} visible={this.state.isModalVisibleFacial} footer={[
@@ -6086,22 +6598,26 @@ class Video extends Component {
6086
6598
  <Modal title="环境检测" maskClosable={false} width={650} closable={false} centered={true} visible={this.state.isModalVisibleEnvironment} footer={[
6087
6599
  <div key='env'>
6088
6600
  {/* <Button className="modelButtonCancel" onClick={this.handleCancelEnvDetection}>取消</Button> */}
6089
- <Button className="modelButtonOk" type="primary" danger onClick={this.handleOkEnvDetection}>确定</Button>
6601
+ <Button className="modelButtonOk" type="primary" disabled={this.state.loading} danger onClick={this.handleOkEnvDetection}>确定</Button>
6090
6602
  </div>
6091
6603
  ]}>
6092
- <Collapse defaultActiveKey={['1', '2', '3', '4', '5']} ghost>
6604
+ <Collapse defaultActiveKey={['1', '2', '3', '4', '5', '6']} ghost>
6093
6605
 
6094
- <Panel header={'网络检测 - ' +this.state.envInfo.networkResult} key="5" className={this.state.envInfo.networkResult=='不合格'? 'panel-error':''} >
6606
+ <Panel header={<span>网络检测 - {this.state.envInfo.networkResult } {this.state.envInfo.networkResult=='不合格'? <img src={IconFail} />: <img src={IconSuccess} />}</span>}
6607
+ key="5" className={this.state.envInfo.networkResult=='不合格'? 'panel-error':''} >
6095
6608
  <p className='envClass'>网络状态:{this.state.envInfo.networkStatus}</p>
6096
6609
  {this.state.envInfo.networkInfo?<p className='envClass'>{this.state.envInfo.networkInfo}</p>:null}
6097
6610
  </Panel>
6098
- <Panel header={'设备电量 - ' +this.state.envInfo.batteryResult} key="2" className={this.state.envInfo.batteryResult=='不合格'? 'panel-error':''}>
6611
+ <Panel header={<span>设备电量 - {this.state.envInfo.batteryResult} {this.state.envInfo.batteryResult=='不合格'? <img src={IconFail} />: <img src={IconSuccess} />} </span>}
6612
+ key="2" className={this.state.envInfo.batteryResult=='不合格'? 'panel-error':''}>
6099
6613
  <p className='envClass'>电量:{this.state.envInfo.batteryLevel}({this.state.envInfo.batteryCharging})</p>
6100
6614
  </Panel>
6101
- <Panel header={'内存检测 - ' +this.state.envInfo.memoryResult} key="1" className={this.state.envInfo.memoryResult=='不合格'? 'panel-error':''}>
6615
+ <Panel header={<span>内存检测 - {this.state.envInfo.memoryResult} {this.state.envInfo.memoryResult=='不合格'? <img src={IconFail} />: <img src={IconSuccess} />}</span>}
6616
+ key="1" className={this.state.envInfo.memoryResult=='不合格'? 'panel-error':''}>
6102
6617
  <p className='envClass'>最大可用内存:{this.state.envInfo.jsHeapSizeLimit} ;当前已使用:{this.state.envInfo.usedJSHeapSize} </p>
6103
6618
  </Panel>
6104
- <Panel header={'摄像头设备 - ' +this.state.envInfo.cameraResult} key="3" className={this.state.envInfo.cameraResult=='不合格'? 'panel-error':''}>
6619
+ <Panel header={<span>摄像头设备 - {this.state.envInfo.cameraResult}{this.state.envInfo.cameraResult=='不合格'? <img src={IconFail} />: <img src={IconSuccess} />}</span>}
6620
+ key="3" className={this.state.envInfo.cameraResult=='不合格'? 'panel-error':''}>
6105
6621
  <div >
6106
6622
  {
6107
6623
  this.state.cameraList.map((item, index) => {
@@ -6114,7 +6630,7 @@ class Video extends Component {
6114
6630
  {this.state.cameraList.length == 0 ? <p className="envClass">获取不到摄像头设备,请检查</p> : null}
6115
6631
  </div>
6116
6632
  </Panel>
6117
- <Panel header={'麦克风设备 - ' +this.state.envInfo.microResult} key="4" className={this.state.envInfo.microResult=='不合格'? 'panel-error':''}>
6633
+ <Panel header={<span>麦克风设备 - {this.state.envInfo.microResult} {this.state.envInfo.microResult=='不合格'? <img src={IconFail} />: <img src={IconSuccess} />}</span>} key="4" className={this.state.envInfo.microResult=='不合格'? 'panel-error':''}>
6118
6634
  <div>
6119
6635
  {
6120
6636
  this.state.microphoneList.map((item, index) => {
@@ -6126,6 +6642,9 @@ class Video extends Component {
6126
6642
  {this.state.cameraList.length == 0 ? <p className="envClass">获取不到麦克风设备,请检查</p> : null}
6127
6643
  </div>
6128
6644
  </Panel>
6645
+ <Panel header={<span>背光、曝光 - {this.state.envInfo.lightResult} {this.state.envInfo.lightResult=='合格'? <img src={IconSuccess} />: <img src={IconFail} />}</span>} key="6" className={this.state.envInfo.lightResult=='合格'? '':'panel-error'}>
6646
+ <p className="envClass">{this.state.envInfo.lightResult=='合格'? '无过度背光、曝光':'过度背光、曝光'}</p>
6647
+ </Panel>
6129
6648
  </Collapse>
6130
6649
  </Modal>
6131
6650
  <video className="mixedvideo" id="mixedvideo" autoPlay muted={true} width="0" height="0"></video>
@@ -6134,6 +6653,7 @@ class Video extends Component {
6134
6653
 
6135
6654
  <video className="mixedvideo" id="recordvideo" autoPlay width="0" height="0"></video>
6136
6655
  <video className="mixedvideo" id="record_video" muted autoPlay></video>
6656
+ <video className="mixedvideo" id="publish_video_record_device" muted autoPlay></video>
6137
6657
 
6138
6658
  </Spin>
6139
6659
  </div>);
@@ -6168,10 +6688,18 @@ Video.defaultProps = {
6168
6688
  customers: ['--'],
6169
6689
  otherAttendees: undefined
6170
6690
  },
6691
+ pdfRendering: false,
6171
6692
  isTranscribing: false,
6172
6693
  shareMask: false,
6173
6694
  isOpenSound: false, // true开启进出音效 false不开启
6695
+ isWeakSound: false,
6174
6696
  userSide: 2,
6697
+ meetingDuration: null, // 会议时长,单位小时
6698
+ recordMode: 1, // 录制模式 1远程录制 2网点录制
6699
+ defaultBranchCode: "",// 员工网点缩写
6700
+ customerId: "", //客户号
6701
+ salesBranchCode: "", //网点编号(分行号)
6702
+ financialOffice: "", // 理财室
6175
6703
  logUrl: 'http://hsbc.cn-shanghai.log.aliyuncs.com/logstores/hsbc/track?APIVersion=0.6.0&app=meeting-ui',
6176
6704
  internalUrl: 'https://wp-staff-gateway.wealth-platform.uat.ali.cloud.cn.hsbc/meeting-ui/OHB/CN/HSBC?chnlID=OHB&locale=zh_CN&chnlCC=CN&chnlGMC=HSBC&targetFunc=supervisorMeeting&sourceFunc=rmMeeting'
6177
6705
  }