react_hsbc_teller 2.0.24 → 2.0.26

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (27) hide show
  1. package/lib/hsbc.js +1 -1
  2. package/lib/hsbc.js.LICENSE.txt +11 -0
  3. package/package.json +2 -1
  4. package/packages/api/api.js +91 -0
  5. package/packages/assets/mp3/ipad_leave_error.mp3 +0 -0
  6. package/packages/assets/mp3/ipad_low_power.mp3 +0 -0
  7. package/packages/demo/demo.js +3 -1
  8. package/packages/pages/foot/foot.jsx +2 -2
  9. package/packages/pages/multiModule/components/copy/agree.jsx +115 -0
  10. package/packages/pages/multiModule/components/copy/agree.less +105 -0
  11. package/packages/pages/multiModule/components/copy/copyTwo.jsx +663 -0
  12. package/packages/pages/multiModule/components/copy/copyTwo.less +180 -0
  13. package/packages/pages/multiModule/components/copy/copy_en.jsx +365 -0
  14. package/packages/pages/multiModule/components/copy/copy_en.less +145 -0
  15. package/packages/pages/multiModule/components/copy/copylist.jsx +291 -0
  16. package/packages/pages/multiModule/components/copy/copylist.less +83 -0
  17. package/packages/pages/multiModule/components/copy/risk.jsx +294 -0
  18. package/packages/pages/multiModule/components/copy/risk.less +123 -0
  19. package/packages/pages/multiModule/components/sign/signMy.jsx +306 -0
  20. package/packages/pages/multiModule/components/sign/signMy.less +128 -0
  21. package/packages/pages/multiModule/components/subscribe/subscribe.jsx +113 -0
  22. package/packages/pages/multiModule/components/subscribe/subscribe.less +82 -0
  23. package/packages/pages/multiModule/multiModule.jsx +26 -0
  24. package/packages/pages/multiModule/multiModule.less +20 -0
  25. package/packages/pages/video/video.jsx +473 -162
  26. package/packages/utils/asrController.js +241 -0
  27. package/packages/utils/utils.js +10 -2
@@ -7,6 +7,8 @@ import API from '../../api/api';
7
7
  import { BoardOperate } from '../../common/index.esm.js';
8
8
  import './video.less'
9
9
  import { compressImage, isLight } from '../../utils/utils'
10
+ import Recorder from "js-audio-recorder";
11
+ import MyAsrController from '../../utils/asrController'
10
12
  import Header from '../header/header.jsx'
11
13
  import Foot from '../foot/foot.jsx'
12
14
  import IconSuccess from '../../assets/img/icon_success.jpg'
@@ -20,6 +22,8 @@ import ocrImage from '../../assets/img/jietu.png'
20
22
  import faceImage from '../../assets/img/jietu_face.png'
21
23
  import autod from '../../assets/mp3/joinmeeting.mp3'
22
24
  import recordErrorAudio from '../../assets/mp3/record_error.mp3'
25
+ import IpadLeaveAudio from '../../assets/mp3/ipad_leave_error.mp3';
26
+ import IpadLowPowerAudio from '../../assets/mp3/ipad_low_power.mp3';
23
27
  import internalJoin from '../../assets/mp3/internalJoin.mp3'
24
28
  import internalLeft from '../../assets/mp3/internalLeft.mp3'
25
29
  import leftMetting from '../../assets/mp3/leftmeeting.mp3'
@@ -50,10 +54,11 @@ import styled from 'styled-components';
50
54
  import { Button } from '../../../node_modules/antd/lib/index';
51
55
  import SignMy from '../sign/signMy.jsx'
52
56
  import Step from '../components/step/step.jsx'
57
+ import MultiModule from '../multiModule/multiModule'//签字、抄录
53
58
  import axios from 'axios';
54
59
  import CryptoJS from "crypto-js";
55
60
 
56
- const SDK_VERISON = '2.0.24'
61
+ const SDK_VERISON = '2.0.26'
57
62
  const IDtypeFront = '请客户在其设备后置摄像头下展示证件正面(如:身份证照片页面)'
58
63
  const IDtypeBack = '请在后置摄像头下展示证件反面(如:身份证国徽页)'
59
64
  const { Option } = Select;
@@ -75,6 +80,7 @@ const POINT_TYPE = {
75
80
  }
76
81
  const RECORD_DEVICE_NAME = 'screen-capture-recorder'
77
82
  // const RECORD_DEVICE_NAME = 'Full HD webcam'
83
+ const IPAD_SUFFIX = '_ipad'
78
84
  let media_status = 0
79
85
  let pictureInPictureVideo
80
86
  let mix_stream
@@ -87,6 +93,7 @@ let muteJson = new Map()
87
93
  // let dateTime = 0
88
94
  let messageValue = ''
89
95
  let messageValueMap = new Map()
96
+ let videoMessageMap = new Map() // 画中画消息数据
90
97
  let third_id_Map = new Map()
91
98
  // let beautyType = false
92
99
  // let beautyNum = 0 // 0-关闭 1--弱 2--中 5---高
@@ -370,6 +377,7 @@ class Video extends Component {
370
377
  console.log(result);
371
378
  this.state.imRoomId = result.imRoomId,
372
379
  this.state.sessionId = result.sessionId;
380
+ window.imRoom.sessionId = result.sessionId;
373
381
 
374
382
  let publish_config = {}
375
383
  publish_config.media_type = 1
@@ -383,6 +391,11 @@ class Video extends Component {
383
391
  publish_config.publish_video_id = 'publish_video1'
384
392
  publish_config.publish_streamId_id = 'publish_streamId1'
385
393
  publish_config.publish_tag = 'tag1'
394
+ if (this.props.recordMode == 2) {
395
+ // 分行模式,只收音 不发布摄像头
396
+ publish_config.media_type = 2
397
+ // publish_config.publish_streamId_id = 'publish_video1'
398
+ }
386
399
  this.test_controller.Publish(publish_config)
387
400
 
388
401
  // this.publishAllScreen();
@@ -477,9 +490,16 @@ class Video extends Component {
477
490
  // let result = await API.mpaasSig({account: data.account, type: data.type});
478
491
  console.log('mpaasSig', result, result.mpsSig);
479
492
  window.sessionStorage.setItem('alimpassSig', result.mpsSig);
480
- this.state.workSpaceId = result.workspaceId,
481
- this.state.appId = result.appId,
493
+ this.state.workSpaceId = result.workspaceId
494
+ this.state.appId = result.appId
482
495
  this.state.bizName = result.bizName
496
+
497
+ //asr初始化
498
+ this.state.asrAppKey = this.props.asrAppKey || result.asrAppKey
499
+ this.state.asrServerUrl = this.props.asrServerUrl || result.asrServerUrl
500
+ this.state.asrToken = this.props.asrToken || result.asrToken
501
+ this.initAsrRecorder()
502
+
483
503
  window.sessionStorage.setItem('sigData', JSON.stringify(result));
484
504
  if (data.sigType == 1) {
485
505
  this.handleEdit()
@@ -571,6 +591,8 @@ class Video extends Component {
571
591
  this.test_controller.InitRoomConfig(config_param)
572
592
  this.saveLog('mrtc InitRoomConfig start')
573
593
  // 预热摄像头
594
+ config_param.videoSource = this.state.cameraValue
595
+ config_param.audioSource = this.state.microphoneValue
574
596
  this.test_controller.PreOpenLocalMedia(config_param)
575
597
  };
576
598
  rateAll = async () => {
@@ -735,6 +757,47 @@ class Video extends Component {
735
757
  })
736
758
 
737
759
  };
760
+ // 开启ipad录制
761
+ enableIpadRecording = (record_business_id) => {
762
+ const that = this
763
+ const filePath = 'recordId_' + new Date().valueOf() + '_ipad';
764
+ const recordParam = {};
765
+ recordParam.width = 1280;
766
+ recordParam.height = 720;
767
+ recordParam.recordTotalStream = 0;
768
+ recordParam.startTimeout = 10;
769
+ recordParam.splitType = 0;
770
+ recordParam.endType = 1;
771
+ recordParam.crf = 26
772
+ recordParam.overlaps = [
773
+ {
774
+ tag: '', // 流 tag,如果不设置或为空,则为全局⽔印
775
+ type: 2, // 1 为时间戳⽔印;2 为⽂字⽔印;3 为图⽚⽔印
776
+ id: 2, // ⽔印 ID
777
+ enable: true,
778
+ xPosition: 640, // x 轴位置
779
+ yPosition: 10, // y 轴位置
780
+ text: `${this.props.recordMode ==1 ?'远程录制' :'网点录制'} ${this.props.salesBranchCode || ''} ${this.state.branchName || ''} ${this.props.financialOffice || ''}`,
781
+ fontSize: 16, // 字体⼤⼩
782
+ url: '' // ⽔印图⽚ HTTP 地址
783
+ },
784
+ {
785
+ tag: '', // 流 tag,如果不设置或为空,则为全局⽔印
786
+ type: 1, // 1 为时间戳⽔印;2 为⽂字⽔印;3 为图⽚⽔印
787
+ id: 1, // ⽔印 ID
788
+ enable: true,
789
+ xPosition: 1080, // x 轴位置
790
+ yPosition: 10, // y 轴位置
791
+ text: '', // ⽔印⽂字
792
+ fontSize: 16, // 字体⼤⼩
793
+ url: '' // ⽔印图⽚ HTTP 地址
794
+ },
795
+ ];
796
+ recordParam.tagPositions = []
797
+ recordParam.tagFilter = that.state.ipadTag
798
+ console.log('recordParam', recordParam);
799
+ that.test_controller.StartRemoteRecord(filePath, recordParam, record_business_id+'_ipad')
800
+ };
738
801
  // 结束会话
739
802
  endSession = value => {
740
803
  if (value == 'customerHangUp') {
@@ -942,13 +1005,17 @@ class Video extends Component {
942
1005
  this.messageClick('当前暂无客户', 'error')
943
1006
  }
944
1007
  }
945
- messageClick = (value, tipType) => {
1008
+ messageClick = (value, tipType, userId) => {
946
1009
  console.log('messageClick', value, tipType)
1010
+
1011
+ if (userId) {
1012
+ // 画中画实时消息
1013
+ this.addPictureMessage(value, userId)
1014
+ }
947
1015
  const intervalSec = 5 // 相同提示触发间隔
948
1016
  const durationSec = 4.5 // 提示持续时间
949
1017
  if (messageValueMap.get(value) == undefined) {
950
1018
  // map中没有相同消息
951
- messageValue = value
952
1019
  messageValueMap.set(value, setTimeout(() => {
953
1020
  messageValueMap.delete(value)
954
1021
  }, intervalSec * 1000))
@@ -970,12 +1037,45 @@ class Video extends Component {
970
1037
  duration: durationSec
971
1038
  })
972
1039
  }
973
- clearTimeout(this.messageClearTimer)
974
- this.messageClearTimer = setTimeout(() => {
975
- messageValue = ''
976
- }, durationSec * 1000);
1040
+ if (!userId) {
1041
+ // 坐席消息
1042
+ messageValue = value
1043
+
1044
+ clearTimeout(this.messageClearTimer)
1045
+ this.messageClearTimer = setTimeout(() => {
1046
+ messageValue = ''
1047
+ }, durationSec * 1000);
1048
+ }
1049
+ }
1050
+ }
1051
+ // 画中画内消息
1052
+ addPictureMessage = (value, userId) => {
1053
+ console.log('addPictureMessage', value, userId)
1054
+
1055
+ const intervalSec = 5 // 相同提示触发间隔
1056
+ const durationSec = 4.5 // 提示持续时间
1057
+ let mapItem = videoMessageMap.get(userId)
1058
+ if (!mapItem) {
1059
+ mapItem = {
1060
+ messageValue: value,
1061
+ clearTimer: null,
1062
+ valueMap: new Map()
1063
+ }
977
1064
  }
1065
+ const valueMap = mapItem.valueMap
1066
+ if (valueMap.get(value) == undefined) {
1067
+ // map中没有相同消息
1068
+ valueMap.set(value, setTimeout(() => {
1069
+ valueMap.delete(value)
1070
+ }, intervalSec * 1000))
978
1071
 
1072
+ mapItem.messageValue = value
1073
+ clearTimeout(mapItem.clearTimer)
1074
+ mapItem.clearTimer = setTimeout(() => {
1075
+ mapItem.messageValue = ''
1076
+ }, durationSec * 1000)
1077
+ videoMessageMap.set(userId, mapItem)
1078
+ }
979
1079
  }
980
1080
  // 人脸识别
981
1081
  facialRecognition = () => {
@@ -1141,7 +1241,8 @@ class Video extends Component {
1141
1241
  name: 'video' + sortedlist[i-1].idIndex,
1142
1242
  title: sortedlist[i-1].videoName,
1143
1243
  mute: sortedlist[i-1].mute,
1144
- noVideo: sortedlist[i-1].noVideo
1244
+ noVideo: sortedlist[i-1].noVideo,
1245
+ userId: sortedlist[i-1].userId,
1145
1246
  })
1146
1247
  }
1147
1248
  }
@@ -1183,6 +1284,10 @@ class Video extends Component {
1183
1284
  cobj.clearRect(0, 0, 640, 360 * this.state.listVideoPicture.length + baseStartHeight);
1184
1285
  canvas.width = 640;
1185
1286
  canvas.height = 360 * this.state.listVideoPicture.length + baseStartHeight;
1287
+ if (this.state.listVideoPicture.length == 0) {
1288
+ // 画中画设置最小高度,避免没有人时 宽度被拉得很大
1289
+ canvas.height = 360 + baseStartHeight
1290
+ }
1186
1291
  for (let i = 0; i < this.state.listVideoPicture.length; i++) {
1187
1292
 
1188
1293
  let videoId = this.state.listVideoPicture[i].name;
@@ -1318,6 +1423,23 @@ class Video extends Component {
1318
1423
 
1319
1424
  }
1320
1425
 
1426
+ // 绘制消息
1427
+ if (videoMessageMap.get(this.state.listVideoPicture[i].userId)) {
1428
+ let str = videoMessageMap.get(this.state.listVideoPicture[i].userId).messageValue
1429
+ if (str) {
1430
+ cobj.fillStyle = '#F8F2F3';
1431
+ cobj.font = "normal lighter 30px sans-serif";
1432
+ // const textWidth = Math.min(cobj.measureText(str).width, 610)
1433
+ const startY = 360 * i + baseStartHeight
1434
+ cobj.fillRect(0, startY, 640, messageBoxHeight)
1435
+ cobj.textAlign = 'center';
1436
+ cobj.strokeStyle = 'black';
1437
+ cobj.lineWidth = 2
1438
+ cobj.strokeText(str, 320, startY + messageBoxHeight - 15);
1439
+ cobj.stroke();
1440
+ }
1441
+ }
1442
+
1321
1443
  }
1322
1444
  cobj.fillStyle = '#333333';
1323
1445
  cobj.fillRect(0, 0, 640, baseStartHeight)
@@ -1401,7 +1523,7 @@ class Video extends Component {
1401
1523
  })
1402
1524
  this.loopPlay = () => {
1403
1525
  console.log('loopPlay status', this.state.isPictureInPicture);
1404
- if(!this.state.isPictureInPicture && document.getElementById("publish_video1")){
1526
+ if(!this.state.isPictureInPicture && document.getElementById("publish_streamId1")){
1405
1527
  let audio = new Audio(PIPictureClosedAudio)
1406
1528
  audio.play()
1407
1529
  setTimeout(this.loopPlay, 3000);
@@ -1510,7 +1632,7 @@ class Video extends Component {
1510
1632
  }, ()=>{
1511
1633
  this.pictureInPicture('Refresh')
1512
1634
  })
1513
- this.messageClick('客户切换其他软件', 'error')
1635
+ this.messageClick('客户切换其他软件', 'error', Mival.data.userId)
1514
1636
  }
1515
1637
  }
1516
1638
  else if (Mival.typeId == 3003) { // app进入前台
@@ -1532,7 +1654,7 @@ class Video extends Component {
1532
1654
  if (Mival.data && Mival.data.userId) {
1533
1655
  TITLE = this.getUserTitle(Mival.data.userId)
1534
1656
  }
1535
- this.messageClick(TITLE+'人脸已离框', 'error')
1657
+ this.messageClick(TITLE+'人脸已离框', 'error', Mival.data.userId)
1536
1658
  // this.saveVideoPoint('ffd', '客户人脸离框');
1537
1659
  }
1538
1660
  else if (Mival.typeId == 5002) { // 客户端背光
@@ -1540,7 +1662,7 @@ class Video extends Component {
1540
1662
  if (Mival.data && Mival.data.userId) {
1541
1663
  TITLE = this.getUserTitle(Mival.data.userId)
1542
1664
  }
1543
- this.messageClick(TITLE+'背光、曝光过度', 'error')
1665
+ this.messageClick(TITLE+'背光、曝光过度', 'error', Mival.data.userId)
1544
1666
  // this.saveVideoPoint('env', '客户端背光、曝光过度');
1545
1667
  }
1546
1668
  else if (Mival.typeId == 5003) { // 客户端弱网
@@ -1548,9 +1670,33 @@ class Video extends Component {
1548
1670
  if (Mival.data && Mival.data.userId) {
1549
1671
  TITLE = this.getUserTitle(Mival.data.userId)
1550
1672
  }
1551
- this.messageClick(TITLE+'当前网络较弱', 'error')
1673
+ this.messageClick(TITLE+'当前网络较弱', 'error', Mival.data.userId)
1552
1674
  // this.saveVideoPoint('wnd', '客户端弱网');
1553
1675
  }
1676
+ else if (Mival.typeId == 5004) { // ipad低电量
1677
+ this.messageClick('IPAD电量过低', 'error', Mival.data.userId)
1678
+
1679
+ this.setState({
1680
+ ipadLowPowerErrorModalVisible: true,
1681
+ })
1682
+ // 循环播放ipad低电量
1683
+ clearTimeout(this.ipadLowPowerPlay)
1684
+ this.ipadLowPowerPlay = () => {
1685
+ if(this.state.ipadLowPowerErrorModalVisible){
1686
+ let audio = new Audio(IpadLowPowerAudio)
1687
+ audio.play()
1688
+ setTimeout(this.ipadLowPowerPlay, 3000);
1689
+ }
1690
+ }
1691
+ setTimeout(this.ipadLowPowerPlay, 0);
1692
+ }
1693
+ else if (Mival.typeId == 5005) { // 客户端人脸数量变化
1694
+ let TITLE = '客户'
1695
+ if (Mival.data && Mival.data.userId) {
1696
+ TITLE = this.getUserTitle(Mival.data.userId)
1697
+ }
1698
+ this.messageClick(TITLE+'人脸数量发生变化', 'error', Mival.data.userId)
1699
+ }
1554
1700
  else if (Mival.typeId == 1220) {
1555
1701
  // 一炒多的图片 1214
1556
1702
  if (Mival.sessionId == this.state.sessionId) {
@@ -1632,6 +1778,24 @@ class Video extends Component {
1632
1778
  this.pictureInPicture('Refresh')
1633
1779
  }
1634
1780
  }
1781
+ } else if (Mival.typeId == 1214) {
1782
+ if (Mival.sessionId == this.state.sessionId) {
1783
+ this.setState({
1784
+ moduleData: Mival,
1785
+ isBackdrop: false
1786
+ }, ()=>{
1787
+ this.showModal('copy')
1788
+ })
1789
+ }
1790
+ } else if (Mival.typeId == 1213) {
1791
+ if (Mival.sessionId == this.state.sessionId) {
1792
+ this.setState({
1793
+ moduleData: Mival,
1794
+ isBackdrop: false
1795
+ }, ()=>{
1796
+ this.showModal('subscribe')
1797
+ })
1798
+ }
1635
1799
  } else if (Mival.typeId == 121305) {
1636
1800
  if (Mival.sessionId == this.state.sessionId) {
1637
1801
  this.saveLog('signatureCallback fail, typeId=121305, ')
@@ -1734,21 +1898,28 @@ class Video extends Component {
1734
1898
  this.state.businessId = Mival.id;
1735
1899
  this.saveLog('Start business recording')
1736
1900
  this.enableServerRecording( Mival.id)
1901
+ if (this.state.ipadTag) this.enableIpadRecording(Mival.id)
1737
1902
 
1738
- if (this.props.whetherDetectFace){
1903
+ if (this.props.whetherDetectFace && this.props.recordMode != 2){
1739
1904
  this.startFaceDetection();
1740
1905
  }
1741
- if (this.props.whetherDetectLight){
1906
+ if (this.props.whetherDetectLight && this.props.recordMode != 2){
1742
1907
  this.startImageDetection();
1743
1908
  }
1909
+ if (this.props.whetherNeedAsr) {
1910
+ this.startASR();
1911
+ }
1744
1912
  } else if (Mival.status == 2) {
1745
1913
  // 关闭了业务录制
1746
1914
  console.log('业务录制关闭', this.state.businessRecordId)
1747
1915
  this.saveLog('Stop business recording')
1748
1916
  this.test_controller.StopRemoteRecord(this.state.businessRecordId)
1917
+ if (this.state.ipadRecordId) this.test_controller.StopRemoteRecord(this.state.ipadRecordId)
1918
+
1749
1919
  this.state.businessId = '';
1750
1920
  clearInterval(this.state.faceDetectionTimer);
1751
1921
  clearInterval(this.state.imageDetectionTimer);
1922
+ if(this.state.isAsrStart) this.stopASR();
1752
1923
  }
1753
1924
  } else if (Mival.typeId == 2002 && this.state.sessionId == Mival.sessionId) {
1754
1925
  // 会议到时间
@@ -1810,7 +1981,7 @@ class Video extends Component {
1810
1981
  img.onload = () => {
1811
1982
  const origin = cv.imread(img)
1812
1983
  // let start = new Date().getTime()
1813
- const res = isLight(origin)
1984
+ const res = isLight(origin, this.props.lightSensitivity)
1814
1985
  if (res==1 || res== -1){
1815
1986
  // 背景曝光过度
1816
1987
  this.messageClick('检测到当前背光、曝光过度', 'error')
@@ -1835,7 +2006,7 @@ class Video extends Component {
1835
2006
  img.onload = () => {
1836
2007
  const origin = cv.imread(img)
1837
2008
  // let start = new Date().getTime()
1838
- const res = isLight(origin)
2009
+ const res = isLight(origin, this.props.lightSensitivity)
1839
2010
  if (res==1 || res==-1){
1840
2011
  // 背景曝光过度
1841
2012
  this.state.envInfo.lightResult = '不合格'
@@ -2095,7 +2266,7 @@ class Video extends Component {
2095
2266
  this.test_controller.OnMediaClose = (code, sid) => {
2096
2267
  console.log(code, sid)
2097
2268
  if (code == 5003 || code == 5004 || code == 5005 || code == 5007 || code == 5009 || code == 5010 || code == 5011 || code == 5012) {
2098
- if (sid == document.getElementById('publish_video1').name) {
2269
+ if (sid == document.getElementById('publish_streamId1').name) {
2099
2270
  this.saveLog('Audio and video close notification,' + code)
2100
2271
  this.roomCallBack(2, '音视频异常关闭', 8)
2101
2272
  } else {
@@ -2119,6 +2290,11 @@ class Video extends Component {
2119
2290
  publish_config.publish_video_id = 'publish_video1'
2120
2291
  publish_config.publish_streamId_id = 'publish_streamId1'
2121
2292
  publish_config.publish_tag = 'tag1'
2293
+ if (this.props.recordMode == 2) {
2294
+ // 分行模式,只收音 不发布摄像头
2295
+ publish_config.media_type = 2
2296
+ // publish_config.publish_streamId_id = 'publish_video1'
2297
+ }
2122
2298
  this.test_controller.Publish(publish_config)
2123
2299
 
2124
2300
  // this.publishAllScreen();
@@ -2294,7 +2470,7 @@ class Video extends Component {
2294
2470
  this.state.isScreenSwitching = false
2295
2471
  }
2296
2472
  }
2297
- if (sid == document.getElementById('publish_video1').name) {
2473
+ if (sid == document.getElementById('publish_streamId1').name) {
2298
2474
 
2299
2475
  this.setState({
2300
2476
 
@@ -2323,7 +2499,7 @@ class Video extends Component {
2323
2499
  },
2324
2500
  1000
2325
2501
  );
2326
- this.mediaInfo = this.generateMediaInfo(document.getElementById("publish_video1").name);
2502
+ this.mediaInfo = this.generateMediaInfo(document.getElementById("publish_streamId1").name);
2327
2503
 
2328
2504
  } else {
2329
2505
  var box = document.getElementById("whiteboardDIV");
@@ -2346,7 +2522,7 @@ class Video extends Component {
2346
2522
  this.test_controller.OnPublishFailed = (sid, err_code, err_msg) => {
2347
2523
  this.saveLog('mrtc OnPublishFailed 发布失败, code=' + err_code)
2348
2524
  console.log('Publishing media stream failed,', sid, err_code, err_msg)
2349
- if (sid == document.getElementById('publish_video1').name) {
2525
+ if (sid == document.getElementById('publish_streamId1').name) {
2350
2526
  this.state.sessionType = false
2351
2527
  this.roomCallBack(2, '发布失败', 4)
2352
2528
  } else {
@@ -2569,6 +2745,11 @@ class Video extends Component {
2569
2745
  }
2570
2746
 
2571
2747
  }
2748
+
2749
+ // 记录ipad摄像头流,需要单独开启录制
2750
+ if (feed.mediaSource == 'VIDEO_SOURCE_CAMERA' && feed.uid.includes(IPAD_SUFFIX)) {
2751
+ this.state.ipadTag = feed.tag;
2752
+ }
2572
2753
  };
2573
2754
  // 推送“有新订阅”给与会者
2574
2755
  this.test_controller.OnNewSubscribe = (subscriber, feed) => {
@@ -2576,8 +2757,8 @@ class Video extends Component {
2576
2757
  };
2577
2758
  // 取消发布成功
2578
2759
  this.test_controller.OnUnPublishSucc = (sid) => {
2579
- console.log('取消发布成功', sid, document.getElementById('publish_video1').name)
2580
- if (document.getElementById('publish_video1').name && sid != document.getElementById('publish_video1').name) {
2760
+ console.log('取消发布成功', sid, document.getElementById('publish_streamId1').name)
2761
+ if (document.getElementById('publish_streamId1').name && sid != document.getElementById('publish_streamId1').name) {
2581
2762
  this.sendMessage({
2582
2763
  'typeId': 2030,
2583
2764
  'sessionId': this.state.sessionId,
@@ -2595,7 +2776,8 @@ class Video extends Component {
2595
2776
  // }
2596
2777
 
2597
2778
  }
2598
- if (sid == document.getElementById('publish_video1').name || !document.getElementById('publish_video1').name) {
2779
+ if (sid == document.getElementById('publish_streamId1').name || !document.getElementById('publish_streamId1').name) {
2780
+ console.log('OnUnPublishSucc clearStreamRemain!!!')
2599
2781
  clearStreamRemain()
2600
2782
  }
2601
2783
  };
@@ -2685,6 +2867,27 @@ class Video extends Component {
2685
2867
  console.log('过滤掉的uid', participant)
2686
2868
  return
2687
2869
  }
2870
+
2871
+ if (participant.includes(IPAD_SUFFIX) && this.state.businessId){
2872
+ // ipad单独处理,不需要加入和退出的提示。但双录过程中ipad如果离开,要提示+循环播报直到ipad重新入会
2873
+ console.log('ipad退出房间', participant)
2874
+
2875
+ this.setState({
2876
+ IpadLeaveErrorModalVisible: true,
2877
+ ipadTag: '',
2878
+ })
2879
+ // 循环播放录制中断语音
2880
+ clearTimeout(this.ipadLeavePlay)
2881
+ this.ipadLeavePlay = () => {
2882
+ if(!this.state.ipadTag && document.getElementById("publish_streamId1")){
2883
+ let audio = new Audio(IpadLeaveAudio)
2884
+ audio.play()
2885
+ setTimeout(this.ipadLeavePlay, 3000);
2886
+ }
2887
+ }
2888
+ setTimeout(this.ipadLeavePlay, 0);
2889
+ return
2890
+ }
2688
2891
 
2689
2892
 
2690
2893
  this.appGetUsernameClick(participant).then((res) => {
@@ -2723,7 +2926,7 @@ class Video extends Component {
2723
2926
  // 弱网回调
2724
2927
  this.test_controller.OnNetworkWeak = (bpsSend, bpsRecv, sid) => {
2725
2928
  console.log('弱网回调', bpsSend, bpsRecv, sid)
2726
- if (sid == document.getElementById('publish_video1').name) {
2929
+ if (sid == document.getElementById('publish_streamId1').name) {
2727
2930
 
2728
2931
  this.detectNetworkWeak().then((isWeak) => {
2729
2932
  console.log('弱网结果:' + isWeak)
@@ -2756,6 +2959,11 @@ class Video extends Component {
2756
2959
  this.state.recordId = record_id
2757
2960
  this.videoRecordCallback('1', true)
2758
2961
  this.saveLog('mrtc OnStartRemoteRecordSucc')
2962
+ } else if (String(record_third_id).includes('_ipad')){
2963
+ this.state.ipadRecordId = record_id
2964
+ const busId = Number(record_third_id.split('_')[0])
2965
+ this.ipadRecordCallback('1', true, busId)
2966
+ this.saveLog('mrtc OnStartIpadRecordSucc')
2759
2967
  } else {
2760
2968
  // 业务录制
2761
2969
  this.state.businessRecordId = record_id
@@ -2780,6 +2988,10 @@ class Video extends Component {
2780
2988
  if (!record_third_id) {
2781
2989
  this.videoRecordCallback('1', false)
2782
2990
  this.saveLog('mrtc OnStartRemoteRecordFailed, code='+err_code)
2991
+ } else if (String(record_third_id).includes('_ipad')){
2992
+ const busId = Number(record_third_id.split('_')[0])
2993
+ this.ipadRecordCallback('1', false, busId)
2994
+ this.saveLog('mrtc OnStartIpadRecordFailed, code='+err_code)
2783
2995
  } else {
2784
2996
  this.businessRecordCallback('1', false, record_third_id)
2785
2997
  this.saveLog('mrtc OnStartRemoteBusinessRecordFailed, code='+err_code + ',businessId=' + record_third_id)
@@ -2796,6 +3008,11 @@ class Video extends Component {
2796
3008
  this.videoRecordCallback('2', true)
2797
3009
  this.saveLog('mrtc OnStopRemoteRecordSucc, recordId='+recordId)
2798
3010
  this.state.recordId = '';
3011
+ } else if (String(record_third_id).includes('_ipad')){
3012
+ const busId = Number(record_third_id.split('_')[0])
3013
+ this.ipadRecordCallback('2', true, busId)
3014
+ this.saveLog('mrtc OnStopIpadRecordSucc, recordId='+recordId)
3015
+ this.state.ipadRecordId = '';
2799
3016
  } else {
2800
3017
  this.businessRecordCallback('2', true, record_third_id)
2801
3018
  this.saveLog('mrtc OnStopRemoteBusinessRecordSucc, recordId='+recordId + ',businessId=' + record_third_id)
@@ -2818,6 +3035,10 @@ class Video extends Component {
2818
3035
  if (!record_third_id) {
2819
3036
  this.videoRecordCallback('2', false)
2820
3037
  this.saveLog('mrtc OnStopRemoteRecordFailed, err_code='+err_code)
3038
+ } else if (String(record_third_id).includes('_ipad')){
3039
+ const busId = Number(record_third_id.split('_')[0])
3040
+ this.ipadRecordCallback('2', false, busId)
3041
+ this.saveLog('mrtc OnStopIpadRecordFailed, err_code='+err_code)
2821
3042
  } else {
2822
3043
  this.businessRecordCallback('2', false, record_third_id)
2823
3044
  this.saveLog('mrtc OnStopRemoteBusinessRecordFailed, err_code='+err_code+',businessId=' + record_third_id)
@@ -2900,7 +3121,7 @@ class Video extends Component {
2900
3121
  clearTimeout(this.recordLoopPlay)
2901
3122
  this.recordLoopPlay = () => {
2902
3123
  console.log('loop recordId', this.state.recordId, 'businessRecordId ', this.state.businessRecordId)
2903
- if(!this.state.businessRecordId && document.getElementById("publish_video1")){
3124
+ if(!this.state.businessRecordId && document.getElementById("publish_streamId1")){
2904
3125
  let audio = new Audio(recordErrorAudio)
2905
3126
  audio.play()
2906
3127
  setTimeout(this.recordLoopPlay, 3000);
@@ -3127,7 +3348,7 @@ class Video extends Component {
3127
3348
  let startX = x2 // 绘制起始点x
3128
3349
  let startY = y1 - height // 绘制起始点y
3129
3350
  ctx.fillRect(startX, startY, width, height)
3130
- if (document.getElementById('publish_video1').name == sid && i == 39) {
3351
+ if (document.getElementById('publish_streamId1').name == sid && i == 39) {
3131
3352
  this.state.analyserHeight.set(sid, number / 40 / 70)
3132
3353
  this.state.analyserHeight = this.state.analyserHeight
3133
3354
  }
@@ -3173,128 +3394,24 @@ class Video extends Component {
3173
3394
 
3174
3395
 
3175
3396
  };
3176
-
3177
- const that = this;
3178
- this.asr_controller.OnGetSign = function(bizName, subBiz, uid) {
3179
- return 'signature'
3180
- }
3181
- // 连接成功回调
3182
- this.asr_controller.OnAsrConnectOK = function() {
3183
- // 需要状态控制
3184
- if (media_status == 1) {
3185
- return
3186
- }
3187
-
3188
- const config_param = {}
3189
- const biz_name = 'demo'
3190
- const sub_biz = 'default'
3191
- const uid = that.props.tellerAccount
3192
- const sampleRate = 16000
3193
- const procType = 8
3194
- config_param.bizName = biz_name
3195
- config_param.subBiz = sub_biz
3196
- config_param.uid = uid
3197
- config_param.sampleRate = sampleRate
3198
- config_param.procType = procType
3199
- config_param.mediaStreamType = 2 // 1:麦克风;2:传stream
3200
- // console.log(test_controller.GetMediaInfo(document.getElementById('publish_video1').name).audio_)
3201
- config_param.audio_ = that.test_controller.GetMediaInfo(document.getElementById('publish_video1').name).audio_
3202
- config_param.idleTime = 6 // 12s没有识别结果返回通知上层
3203
- config_param.tag = 'asr_tag0'
3204
- that.asr_sid = that.asr_controller.TurnOnMicrophone(config_param, config_param.audio_)
3205
- }
3206
- // 初始化成功
3207
- this.asr_controller.OnInitOk = function(sid, tag) {
3208
- console.log('OnInitOk:')
3209
- media_status = 1
3210
- }
3211
-
3212
- // 初始化失败
3213
- this.asr_controller.OnInitError = function(sid, code, msg, tag) {
3214
- console.log('OnInitError:' + msg)
3215
- that.asr_sid = ''
3216
- }
3217
-
3218
- // 识别结果
3219
- this.asr_controller.OnAsrMessage = function(msg, sid, tag, status) {
3220
- that.asr_controller.trace(`OnAsrMessage sid=${sid},status=${status},tag=${tag}`)
3221
- const parse = JSON.parse(msg)
3222
- const resultValue = parse.value
3223
- const sentence_id = parse.sentence_id
3224
- // sentence_id相同,取最后一个值
3225
- let text = resultValue || ''
3226
- const sensitiveArr = that.props.sensitiveWords
3227
- // const regex = new RegExp(sensitiveArr.join('|'), 'g') // /\#{(.+?)\}/g;
3228
- // text = text.replace(regex, function(r) { return '<span style="background: red;">' + r + '</span>' })
3229
- let matchArr = sensitiveArr.filter(el => text.includes(el));
3230
- if (matchArr.length>0) {
3231
- matchArr.forEach(el => {
3232
- that.messageClick('检测到敏感词:' + matchArr, 'error')
3233
- that.state.sensitiveTitle = '检测到敏感词:' + matchArr
3234
- clearTimeout(that.state.sensitiveTitleTimer)
3235
- that.state.sensitiveTitleTimer = setTimeout(() => {
3236
- that.state.sensitiveTitle = ''
3237
- }, 3000);
3238
- if (!that.state.sensitiveRecordMap[sentence_id] || !that.state.sensitiveRecordMap[sentence_id].includes(el)){
3239
- API.addSensitiveRecord({
3240
- tellerId: that.props.tellerAccount,
3241
- sessionId: that.state.sessionId,
3242
- sensitiveWord: el
3243
- });
3244
- if (!that.state.sensitiveRecordMap[sentence_id]) {
3245
- that.state.sensitiveRecordMap[sentence_id] = []
3246
- }
3247
- that.state.sensitiveRecordMap[sentence_id].push(el)
3248
- }
3249
- })
3250
- }
3251
- // that.AsrResultText = text
3252
- }
3253
-
3254
- // 停止录音回调
3255
- this.asr_controller.OnTurnOffMicrophoneOK = function(sid, tag) {
3256
- media_status = 0
3257
- that.asr_controller.Disconnect()
3258
- }
3259
- this.asr_controller.OnAsrMsgIdle = function(sid, tag) {
3260
- // that.AsrResultText = ''
3261
- that.asr_controller.trace('OnAsrMsgIdle')
3262
- }
3263
- this.asr_controller.OnAsrDisconnectOK = function() {
3264
- that.asr_controller.trace('Disconnect is success')
3265
- }
3266
-
3397
+
3398
+
3267
3399
  }
3268
3400
  startASR() {
3269
3401
  // const publish_sid = document.getElementById('publish_video1').name
3270
3402
 
3271
- if (media_status == 1) {
3272
- return
3273
- }
3274
- this.asr_controller.Connect(this.props.asrServerUrl)
3275
- message.success({
3276
- content: '敏感词检测已开启',
3277
- icon: <img src={require("../../assets/img/tooltips1_pass.png").default} alt="" ></img>,
3278
- className: 'successClassName',
3279
- top: 200,
3280
- // duration: 10
3281
- })
3282
- this.state.isAsrStart = true
3283
- this.state.sensitiveRecordMap = {}
3284
- // this.AsrResultText = ''
3403
+ // if (media_status == 1) {
3404
+ // return
3405
+ // }
3406
+ this.asr_controller.initWebSocket(this.props.asrServerUrl)
3285
3407
  }
3286
3408
  stopASR() {
3287
3409
  this.state.isAsrStart = false
3288
- // this.AsrResultText = ''
3289
- // const { publish_sid } = this.getSidsInfo()
3290
- if (media_status == 0) {
3291
- return
3292
- }
3293
- this.asr_controller.TurnOffMicrophone(this.asr_sid)
3294
- // clearInterval(this.asrTimer)
3295
- // if (this.localRecordStatus && this.client_record_id) {
3296
- // test_controller.StopRecord(this.client_record_id)
3410
+ // if (media_status == 0) {
3411
+ // return
3297
3412
  // }
3413
+ this.asr_controller.Disconnect()
3414
+
3298
3415
  message.success({
3299
3416
  content: '敏感词检测已关闭',
3300
3417
  icon: <img src={require("../../assets/img/tooltips1_pass.png").default} alt="" ></img>,
@@ -3363,6 +3480,27 @@ class Video extends Component {
3363
3480
  }
3364
3481
  }
3365
3482
  }
3483
+ // ipad录制回调
3484
+ ipadRecordCallback= async (type, status, businessId) => {
3485
+ try {
3486
+ let result = await API.videoRecordCallback({
3487
+ activityId: this.props.businessNumber,
3488
+ sessionId: this.state.sessionId,
3489
+ roomId: this.state.channelId + '',
3490
+ id: businessId,
3491
+ appId: this.state.appId,
3492
+ recordId: this.state.ipadRecordId,
3493
+ customerId: this.props.customerId,
3494
+ isIpad: 1,
3495
+ type: type,
3496
+ status: status
3497
+ });
3498
+ } catch (err) {
3499
+ console.error(err);
3500
+ if (err.status == 502 || err.status == 404) {
3501
+ }
3502
+ }
3503
+ }
3366
3504
  uploadLogCallback = async (url) => {
3367
3505
  try {
3368
3506
  let result = await API.uploadLogCallback({
@@ -3410,7 +3548,7 @@ class Video extends Component {
3410
3548
  });
3411
3549
  console.log(result);
3412
3550
  this.queryRecordStatus()
3413
- this.appGetUsername(document.getElementById('publish_video1').name)
3551
+ this.appGetUsername(document.getElementById('publish_streamId1').name)
3414
3552
  this.sendMessage({
3415
3553
  'typeId': 1014,
3416
3554
  'sessionId': this.state.sessionId,
@@ -3431,7 +3569,7 @@ class Video extends Component {
3431
3569
  componentWillUnmount() {
3432
3570
  this.saveLog('Exit meeting')
3433
3571
  if (this.test_controller && this.state.sessionType) {
3434
- clearStreamRemain()
3572
+ // clearStreamRemain() // 谨慎使用,有页面crash问题
3435
3573
  this.test_controller.LeaveRoom()
3436
3574
  this.test_controller.Disconnect()
3437
3575
  try {
@@ -3439,7 +3577,7 @@ class Video extends Component {
3439
3577
  beautyStop();
3440
3578
  console.log('beautyStop!!')
3441
3579
  } catch (err){
3442
- console.error(err)
3580
+ console.log(err)
3443
3581
  }
3444
3582
  }
3445
3583
  if (this.state.isAsrStart){
@@ -3449,9 +3587,13 @@ class Video extends Component {
3449
3587
  if (this.state.isPictureInPicture) {
3450
3588
  document.exitPictureInPicture()
3451
3589
  }
3590
+ worker.postMessage(false);
3591
+ worker.terminate();
3452
3592
  message.destroy()
3453
3593
  clearTimeout(this.loopPlay)
3454
3594
  clearTimeout(this.recordLoopPlay)
3595
+ clearTimeout(this.ipadLeavePlay)
3596
+ clearTimeout(this.ipadLowPowerPlay)
3455
3597
  clearInterval(this.state.drawCanvasInterval)
3456
3598
  clearInterval(this.state.faceDetectionTimer);
3457
3599
  clearInterval(this.state.imageDetectionTimer);
@@ -3590,9 +3732,9 @@ class Video extends Component {
3590
3732
  let params = `?v=${SDK_VERISON}`
3591
3733
  const _dependScripts = [
3592
3734
  // this.props.resourcePath + "/opencv.js" + params,
3593
- this.props.resourcePath + "/asr_api.js" + params,
3594
- this.props.resourcePath + "/reconnecting-websocket.min.js" + params,
3595
- this.props.resourcePath + "/resampler.js" + params,
3735
+ // this.props.resourcePath + "/asr_api.js" + params,
3736
+ // this.props.resourcePath + "/reconnecting-websocket.min.js" + params,
3737
+ // this.props.resourcePath + "/resampler.js" + params,
3596
3738
  this.props.resourcePath + "/beauty/beauty_frame_pkg.js" + params,
3597
3739
  this.props.resourcePath + "/adapter.js" + params,
3598
3740
  this.props.resourcePath + "/getMediaInfo.js" + params,
@@ -3646,14 +3788,12 @@ class Video extends Component {
3646
3788
  script.onreadystatechange = () => {
3647
3789
  if (script.readyState == 'loaded' || script.readyState == 'complete') {
3648
3790
  that.test_controller = new MeetingController();
3649
- that.asr_controller = new AsrController()
3650
3791
  that.mountClick()
3651
3792
  }
3652
3793
  }
3653
3794
  } else {
3654
3795
  script.onload = () => {
3655
3796
  that.test_controller = new MeetingController();
3656
- that.asr_controller = new AsrController()
3657
3797
  that.mountClick()
3658
3798
  }
3659
3799
  }
@@ -3714,8 +3854,95 @@ class Video extends Component {
3714
3854
  if (this.props.salesBranchCode) {
3715
3855
  this.queryBranchName()
3716
3856
  }
3857
+ window.imRoom = {
3858
+ sessionId: this.props.sessionId,
3859
+ userId: this.props.tellerAccount
3860
+ }
3717
3861
  }
3862
+ initAsrRecorder = () => {
3863
+ this.state.recorder = new Recorder({
3864
+ sampleBits: 16, // 采样位数,,默认是16
3865
+ sampleRate: 16000, //音频采样率,默认是16000Hz,
3866
+ numChannels: 1, // 声道,支持 1 或 2, 默认是1
3867
+ compiling: true // 是否边录边转换,默认是false
3868
+ })
3869
+ this.asr_controller = new MyAsrController({
3870
+ token: this.state.asrToken,
3871
+ appkey: this.state.asrAppKey,
3872
+ url: this.state.asrServerUrl,
3873
+ recorder: this.state.recorder
3874
+ })
3875
+
3876
+ let that = this;
3877
+ this.asr_controller.onConnectError = () => {
3878
+ this.messageClick('违禁词检测服务连接失败', 'error')
3879
+ }
3880
+
3881
+ this.asr_controller.onConnectOK = () => {
3882
+ message.success({
3883
+ content: '敏感词检测已开启',
3884
+ icon: <img src={require("../../assets/img/tooltips1_pass.png").default} alt="" ></img>,
3885
+ className: 'successClassName',
3886
+ top: 200,
3887
+ // duration: 10
3888
+ })
3889
+ this.state.recorder.start().then(() => {
3890
+ console.log('asr recorder 开启')
3891
+ }, (error) => {
3892
+ console.log(`出错了`);
3893
+ });
3894
+ this.state.isAsrStart = true
3895
+ this.state.sensitiveRecordMap = {}
3896
+ // this.AsrResultText = ''
3897
+ }
3718
3898
 
3899
+ this.asr_controller.onSentenceEnd = (msg) => {
3900
+ console.log('句子解析结果', msg.result)
3901
+ const resultValue = msg.result
3902
+ const sentence_id = msg.index
3903
+ API.keywordMatch({
3904
+ text: resultValue,
3905
+ appCode: `HSBCCode`
3906
+ }).then((re) => {
3907
+ if (re.data.match) {
3908
+ this.saveVideoPoint('pwd', `${resultValue}`)
3909
+ console.log('匹配到敏感词', re.data.matchRawTextItems)
3910
+ let matchArr = re.data.matchRawTextItems.map(el => el.matchedText);
3911
+ if (matchArr.length>0) {
3912
+ matchArr.forEach(el => {
3913
+ this.messageClick('检测到敏感词:' + matchArr, 'error')
3914
+ })
3915
+ }
3916
+ }
3917
+ });
3918
+ }
3919
+ // this.asr_controller.onAsrMessage = (msg) => {
3920
+ // console.log('收到解析结果', msg.result)
3921
+ // const resultValue = msg.result
3922
+ // const sentence_id = msg.index
3923
+ // // sentence_id相同,取最后一个值
3924
+ // let text = resultValue || ''
3925
+ // const sensitiveArr = that.props.sensitiveWords
3926
+ // let matchArr = sensitiveArr.filter(el => text.includes(el));
3927
+ // if (matchArr.length>0) {
3928
+ // matchArr.forEach(el => {
3929
+ // that.messageClick('检测到敏感词:' + matchArr, 'error')
3930
+ // that.state.sensitiveTitle = '检测到敏感词:' + matchArr
3931
+ // clearTimeout(that.state.sensitiveTitleTimer)
3932
+ // that.state.sensitiveTitleTimer = setTimeout(() => {
3933
+ // that.state.sensitiveTitle = ''
3934
+ // }, 3000);
3935
+ // if (!that.state.sensitiveRecordMap[sentence_id] || !that.state.sensitiveRecordMap[sentence_id].includes(el)){
3936
+
3937
+ // if (!that.state.sensitiveRecordMap[sentence_id]) {
3938
+ // that.state.sensitiveRecordMap[sentence_id] = []
3939
+ // }
3940
+ // that.state.sensitiveRecordMap[sentence_id].push(el)
3941
+ // }
3942
+ // })
3943
+ // }
3944
+ // }
3945
+ }
3719
3946
  voice = () => {
3720
3947
  if (this.isFileSuccuse()) {
3721
3948
  if (!this.state.voiceStatue) {
@@ -3785,8 +4012,9 @@ class Video extends Component {
3785
4012
  this.state.businessId = result.businessId;
3786
4013
  third_id_Map.set(result.businessRecordId, result.businessId);
3787
4014
  console.log(third_id_Map)
3788
- if (this.props.whetherDetectFace) this.startFaceDetection();
3789
- if (this.props.whetherDetectLight) this.startImageDetection();
4015
+ if (this.props.whetherDetectFace && this.props.recordMode != 2) this.startFaceDetection();
4016
+ if (this.props.whetherDetectLight && this.props.recordMode != 2) this.startImageDetection();
4017
+ if (this.props.whetherNeedAsr) this.startASR();
3790
4018
  }
3791
4019
  } else {
3792
4020
  this.state.recordId = ''
@@ -4009,6 +4237,36 @@ class Video extends Component {
4009
4237
  }
4010
4238
 
4011
4239
  };
4240
+ // 打开抄录/签署面板
4241
+ showModal=(moduleName)=>{
4242
+ if (!this.state.multiModuleShow) {
4243
+ this.setState({
4244
+ multiModuleShow:true,
4245
+ multiModule: moduleName,
4246
+ },()=>{
4247
+ })
4248
+ this.tabTitlesClick(
4249
+ {
4250
+ value: 'multiModule',
4251
+ name: '签署抄录'
4252
+ },'add'
4253
+ )
4254
+ }else{
4255
+ this.closeModule()
4256
+ }
4257
+ }
4258
+ // 关闭面板
4259
+ closeModule=()=>{
4260
+ setTimeout(() => {
4261
+ this.setState({
4262
+ multiModuleShow:false,
4263
+ multiModule: '',
4264
+ })
4265
+ this.tabTitlesClick('multiModule','delect')
4266
+ }, 0);
4267
+ // const sid = document.getElementById('video20').name;
4268
+ // sid ? this.test_controller.UnPublish(sid) : ''
4269
+ }
4012
4270
  handleOkPictureConfirm = () => {
4013
4271
  this.pictureInPictureClick('add')
4014
4272
  this.setState({isPictureConfirmModalVisible: false})
@@ -4020,6 +4278,19 @@ class Video extends Component {
4020
4278
  this.saveLog('Start business recording')
4021
4279
  this.enableServerRecording(this.state.businessId)
4022
4280
  }
4281
+ handleOkLowPowerConfirm = () => {
4282
+ this.setState({ ipadLowPowerErrorModalVisible: false})
4283
+ clearTimeout(this.ipadLowPowerPlay)
4284
+ }
4285
+ handleOkIpadLeaveConfirm = () => {
4286
+ // 检测ipad是否入会
4287
+ if (!this.state.ipadTag) {
4288
+ this.messageClick('未检测到IPAD,请重新加入后再试', 'error')
4289
+ } else {
4290
+ clearTimeout(this.ipadLeavePlay)
4291
+ this.setState({IpadLeaveErrorModalVisible: false})
4292
+ }
4293
+ }
4023
4294
  handleOk = () => {
4024
4295
  // 代表此时按钮是暂停会话,把isSuspend改成true变成恢复会话
4025
4296
  this.sendMessage({
@@ -4812,7 +5083,7 @@ class Video extends Component {
4812
5083
  userId = this.seeList(this.state.roomCustomerList, 'feedId', document.getElementById("feedId"+i).innerText).uid
4813
5084
  }
4814
5085
  }
4815
- if (document.getElementById('publish_video1').name == sid) {
5086
+ if (document.getElementById('publish_streamId1').name == sid) {
4816
5087
  userId = this.props.tellerAccount
4817
5088
  }
4818
5089
  try {
@@ -4832,7 +5103,7 @@ class Video extends Component {
4832
5103
  } else {
4833
5104
  this.messageClick('查询失败', 'error')
4834
5105
  }
4835
- if (this.props.isOpenSound && sid != document.getElementById('publish_video1').name) {
5106
+ if (this.props.isOpenSound && sid != document.getElementById('publish_streamId1').name) {
4836
5107
  if (result.data.userType == 1) {
4837
5108
  let src = autod
4838
5109
  let audio = new Audio(src)
@@ -4843,7 +5114,7 @@ class Video extends Component {
4843
5114
  audio.play()
4844
5115
  }
4845
5116
  }
4846
- if (document.getElementById('publish_video1').name == sid) {
5117
+ if (document.getElementById('publish_streamId1').name == sid) {
4847
5118
  this.setState({
4848
5119
  titleNameRm: data
4849
5120
  })
@@ -5426,7 +5697,7 @@ class Video extends Component {
5426
5697
  this.setState({
5427
5698
  isModalVisibleEnvironment: false,
5428
5699
  })
5429
- if (!this.state.isPictureInPicture) {
5700
+ if (!this.state.isPictureInPicture && this.props.recordMode != 2) {
5430
5701
  this.pictureInPicture()
5431
5702
  }
5432
5703
  }
@@ -5441,7 +5712,7 @@ class Video extends Component {
5441
5712
  loading: true
5442
5713
  })
5443
5714
  const config = {}
5444
- config.sid = document.getElementById('publish_video1').name
5715
+ config.sid = document.getElementById('publish_video1').name || document.getElementById('publish_streamId1').name
5445
5716
  config.videoSource = this.state.cameraValue
5446
5717
  config.audioSource = this.state.microphoneValue
5447
5718
  this.test_controller.ChangeProfile(config)
@@ -5499,7 +5770,7 @@ class Video extends Component {
5499
5770
  }
5500
5771
  changeMediaStream = () => {
5501
5772
  let publish_config = {}
5502
- publish_config.sid = document.getElementById('publish_video1').name
5773
+ publish_config.sid = document.getElementById('publish_video1').name || document.getElementById('publish_streamId1').name
5503
5774
  publish_config.media_type = 1
5504
5775
  publish_config.publish_device = 1
5505
5776
  // publish_config.videoSource = this.state.cameraValue
@@ -6036,9 +6307,9 @@ class Video extends Component {
6036
6307
  const isEnvironmentOK = !this.state.loading &&
6037
6308
  this.state.envInfo.networkResult=='合格' &&
6038
6309
  this.state.envInfo.batteryResult=='合格' &&
6039
- this.state.envInfo.cameraResult=='合格' &&
6310
+ (this.state.envInfo.cameraResult=='合格' || this.props.recordMode == 2) &&
6040
6311
  this.state.envInfo.microResult=='合格' &&
6041
- this.state.envInfo.lightResult=='合格'
6312
+ (this.state.envInfo.lightResult=='合格' || this.props.recordMode == 2 )
6042
6313
 
6043
6314
  const sectionStyle = this.state.tabTitles.length > 0 ? {
6044
6315
  zIndex: '-1',
@@ -6086,6 +6357,18 @@ class Video extends Component {
6086
6357
  }
6087
6358
  <canvas id="canvas" className="canvas"></canvas>
6088
6359
  </CanvasHome>
6360
+ <div className="videoDiv" style={{ display: (this.state.isSelect == 'multiModule') ? '' : 'none', }}>
6361
+ <div className="videoDiv">
6362
+ {/* <div style={{ display: (this.state.multiModuleShow) ? '' : 'none', height: '100%'}}> */}
6363
+ {
6364
+ this.state.multiModuleShow &&
6365
+ <div style={{ height: '100%'}}>
6366
+ <MultiModule moduleName={this.state.multiModule} data={this.state.moduleData} finish={this.closeModule} handleReceiveMsg={this.handleReceiveMsg}></MultiModule>
6367
+ </div>
6368
+ }
6369
+ </div>
6370
+
6371
+ </div>
6089
6372
  <div className="videoDiv" style={{ display: (this.state.isSelect == 'RMScreen' || this.state.isSelect == 'staffScreen') ? '' : 'none', }}>
6090
6373
  <div className="videoDiv" style={{ 'textAlign': 'center' }}>
6091
6374
  <video
@@ -6172,6 +6455,7 @@ class Video extends Component {
6172
6455
  <div id="videoList" className={`wrapper ${this.state.isVideoList? 'videoListClass': ''}`} style={{ width: '20%' }}>
6173
6456
  <div
6174
6457
  className={`itemed ${this.state.isVideoList? 'videoMinutuListClass': 'videoMinutuClass'}`}
6458
+ style={{ display: (this.props.recordMode == 2) ? 'none' : ''}}
6175
6459
  >
6176
6460
  <div className="publishVideoDiv">
6177
6461
 
@@ -6365,6 +6649,22 @@ class Video extends Component {
6365
6649
  ]}>
6366
6650
  <div className='endModal'>双录异常中断,请重新开启</div>
6367
6651
  </Modal>
6652
+ {/* ipad低电量确认 */}
6653
+ <Modal closable={false} centered={true} visible={this.state.ipadLowPowerErrorModalVisible} maskClosable={false} footer={[
6654
+ <div key='end'>
6655
+ <Button className="modelButtonOk" type="primary" danger onClick={this.handleOkLowPowerConfirm}>确定</Button>
6656
+ </div>
6657
+ ]}>
6658
+ <div className='endModal'>IPAD电量过低,请检查</div>
6659
+ </Modal>
6660
+ {/* 双录中ipad退出确认 */}
6661
+ <Modal closable={false} centered={true} visible={this.state.IpadLeaveErrorModalVisible} maskClosable={false} footer={[
6662
+ <div key='end'>
6663
+ <Button className="modelButtonOk" type="primary" danger onClick={this.handleOkIpadLeaveConfirm}>确定</Button>
6664
+ </div>
6665
+ ]}>
6666
+ <div className='endModal'>IPAD异常退出,请重新加入</div>
6667
+ </Modal>
6368
6668
  {/* 是否退出会议*/}
6369
6669
  <Modal closable={false} centered={true} visible={this.state.isModalVisibleEnd} maskClosable={false} footer={[
6370
6670
  <div key='end'>
@@ -6729,6 +7029,8 @@ class Video extends Component {
6729
7029
  key="2" className={this.state.envInfo.batteryResult=='不合格'? 'panel-error':''}>
6730
7030
  <p className='envClass'>电量:{this.state.envInfo.batteryLevel}({this.state.envInfo.batteryCharging})</p>
6731
7031
  </Panel>
7032
+ {
7033
+ this.props.recordMode != 2 &&
6732
7034
  <Panel header={<span>摄像头设备 - {this.state.envInfo.cameraResult}{this.state.envInfo.cameraResult=='不合格'? <img src={IconFail} />: <img src={IconSuccess} />}</span>}
6733
7035
  key="3" className={this.state.envInfo.cameraResult=='不合格'? 'panel-error':''}>
6734
7036
  <div >
@@ -6743,6 +7045,7 @@ class Video extends Component {
6743
7045
  {this.state.cameraList.length == 0 ? <p className="envClass">获取不到设备,请检查电脑“设置”中的摄像头权限是否开启,并重启浏览器再试</p> : null}
6744
7046
  </div>
6745
7047
  </Panel>
7048
+ }
6746
7049
  <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':''}>
6747
7050
  <div>
6748
7051
  {
@@ -6755,9 +7058,12 @@ class Video extends Component {
6755
7058
  {this.state.cameraList.length == 0 ? <p className="envClass">获取不到设备,请检查电脑“设置”中的麦克风权限是否开启,并重启浏览器再试</p> : null}
6756
7059
  </div>
6757
7060
  </Panel>
7061
+ {
7062
+ this.props.recordMode != 2 &&
6758
7063
  <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'}>
6759
7064
  <p className="envClass">{this.state.envInfo.lightResult=='合格'? '无过度背光、曝光':'过度背光、曝光'}</p>
6760
7065
  </Panel>
7066
+ }
6761
7067
  </Collapse>
6762
7068
  </Modal>
6763
7069
  <video className="mixedvideo" id="mixedvideo" autoPlay muted={true} width="0" height="0"></video>
@@ -6782,7 +7088,10 @@ Video.defaultProps = {
6782
7088
  callbackUrl: 'http://182.92.184.31:8720/hsbc/callback',
6783
7089
  // roomServerUrl: 'wss://app.uat.dsp.hsbcfts.com.cn/mpaas/mrtc/ws',
6784
7090
  roomServerUrl: 'wss://mrtc.mpaas.cn-hangzhou.aliyuncs.com/ws',
6785
- asrServerUrl: 'wss://ismis.alipay.com/ws',
7091
+ // asr公有云默认参数
7092
+ // asrServerUrl: 'wss://nls-gateway.cn-shanghai.aliyuncs.com/ws/v1',
7093
+ // asrAppKey: 'E6DAPlpMun5L2dJ7',
7094
+ // asrToken: 'a07198021d434d1288cd4ab3178712cb',
6786
7095
  resourcePath: 'https://counter-web.leimondata.cn:7199',
6787
7096
  // resourcePath: 'https://zuul.uat.dsp.hsbcfts.com.cn/wealth/js/',
6788
7097
  prohbiitPrompt: '当前无客户',
@@ -6808,8 +7117,10 @@ Video.defaultProps = {
6808
7117
  isWeakSound: false,
6809
7118
  whetherDetectFace: false, // 是否在双录时开启人脸检测
6810
7119
  whetherDetectLight: false, // 是否在双录时开启背光检测
7120
+ whetherNeedAsr: false, // 是否在双录时开启违禁词检测
6811
7121
  faceDetectInterval: 6, // 人脸检测间隔(秒)
6812
7122
  lightDetectInterval: 6, // 背光检测间隔(秒)
7123
+ lightSensitivity: 1, // 光线敏感度系数,默认1
6813
7124
  userSide: 2,
6814
7125
  meetingDuration: null, // 会议时长,单位小时
6815
7126
  recordMode: 1, // 录制模式 1远程录制 2网点录制