videoVoice.nvue 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500
  1. <template>
  2. <view class="videoContont">
  3. <image style="width: 750rpx;position: absolute;top: 0;left: 0;z-index: 1;" :style="{height:sysInfoHeight+'px'}"
  4. src="../../static/images/my/videoBg.png" mode=""></image>
  5. <!-- 对方的视频 -->
  6. <trtc-remote-view v-if="remoteUserId" :userId="remoteUserId" :viewId="remoteUserId"
  7. style="width: 750rpx;position: absolute;top: 0;left: 0;z-index: 333 !important;"
  8. :style="{height:sysInfoHeight+'px'}"></trtc-remote-view>
  9. <!-- 我的视频大/小 -->
  10. <view :class="isJie?'mySmartVideo':'myVideo'" :style="{height:isJie?'300rpx':sysInfoHeight+'px'}">
  11. <trtc-local-view :userId="userId" :viewId="userId" style="flex: 1;"></trtc-local-view>
  12. </view>
  13. <!-- 顶部信息 -->
  14. <view class="topInfo" v-if="isRol == 1 && userType == 2">
  15. <image class="topInfo-avatar" :src="resumesIdInfo.avatar" mode="aspectFill"></image>
  16. <text class="topInfo-name">
  17. {{resumesIdInfo.resumesName}}
  18. </text>
  19. <view class="topInfo-time">
  20. <!-- 邀请你语音通话... -->
  21. <smhTimer v-if="isJie" ref="timer" :auto="isJie" />
  22. </view>
  23. </view>
  24. <view class="topInfo" v-if="isRol == 1 && userType == 1">
  25. <image class="topInfo-avatar" :src="company.companyLogo" mode="aspectFill"></image>
  26. <text class="topInfo-name">
  27. {{company.companyName}}
  28. </text>
  29. <view class="topInfo-time">
  30. <!-- 邀请你语音通话... -->
  31. <smhTimer v-if="isJie" ref="timer" :auto="isJie" />
  32. </view>
  33. </view>
  34. <view class="topInfo" v-if="isRol == 2 && userType == 1">
  35. <image class="topInfo-avatar" :src="company.companyLogo" mode="aspectFill"></image>
  36. <text class="topInfo-name">
  37. {{company.companyName}}
  38. </text>
  39. <view class="">
  40. <text class="topInfo-time" v-if="isRol == 2 && isJie == false">
  41. 邀请你通话...
  42. </text>
  43. <smhTimer v-if="isJie" ref="timer" :auto="isJie" />
  44. </view>
  45. </view>
  46. <view class="topInfo" v-if="isRol == 2 && userType == 2">
  47. <image class="topInfo-avatar" :src="resumesIdInfo.avatar" mode="aspectFill"></image>
  48. <text class="topInfo-name">
  49. {{resumesIdInfo.resumesName}}
  50. </text>
  51. <view class="">
  52. <text class="topInfo-time" v-if="isRol == 2 && isJie == false">
  53. 邀请你通话...
  54. </text>
  55. <smhTimer v-if="isJie" ref="timer" :auto="isJie" />
  56. </view>
  57. </view>
  58. <!-- 底部未接通按钮 -->
  59. <view v-if="isJie == false" class="bottomInfoContont">
  60. <!-- 发起人 -->
  61. <view v-if="isRol==1" class="bottomInfo" style="justify-content: center;">
  62. <view class="bottomInfo-item" @click="jieOrGuaCall(4)">
  63. <image class="bottomInfo-item-img" src="/static/images/voice/cancel.png" mode=""></image>
  64. <text class="bottomInfo-item-txt">
  65. 挂断
  66. </text>
  67. </view>
  68. </view>
  69. <!-- 底部操作(语音未接通) 接受人 -->
  70. <view v-if="isRol==2" class="bottomInfo">
  71. <view class="bottomInfo-item" @click="jieOrGuaCall(4)">
  72. <image class="bottomInfo-item-img" src="/static/images/voice/cancel.png" mode=""></image>
  73. <text class="bottomInfo-item-txt">
  74. 挂断
  75. </text>
  76. </view>
  77. <view class="bottomInfo-item" @click="jieOrGuaCall(2)">
  78. <image class="bottomInfo-item-img" src="/static/images/voice/answer.png" mode=""></image>
  79. <text class="bottomInfo-item-txt">
  80. 接听
  81. </text>
  82. </view>
  83. </view>
  84. </view>
  85. <!-- 底部接通后 -->
  86. <view class="bottomInfoContont" v-if="isJie == true">
  87. <!-- 语音通话 -->
  88. <view class="bottomInfo flex align-center justify-between" v-if="messageType == 21">
  89. <view class="bottomInfo-item" @click="setStopLocalAudio()">
  90. <view class="bottomInfo-item-center">
  91. <image class="bottomInfo-item-centerI"
  92. :src="isOpenMicrophone?'/static/images/voice/openMkf.png':'/static/images/voice/closeMkf.png'"
  93. mode="widthFix">
  94. </image>
  95. </view>
  96. <text class="bottomInfo-item-txt">
  97. {{isOpenMicrophone?'麦克风已开':'麦克风已关'}}
  98. </text>
  99. </view>
  100. <view class="bottomInfo-item" @click="jieOrGuaCall(4)">
  101. <image class="bottomInfo-item-img" src="/static/images/voice/cancel.png" mode=""></image>
  102. <text class="bottomInfo-item-txt">
  103. 挂断
  104. </text>
  105. </view>
  106. </view>
  107. <!-- 视频 -->
  108. <view class="bottomInfo flex align-center justify-between flex-wrap" v-if="messageType == 20">
  109. <view class="bottomInfo-item" @click="setStopLocalAudio()">
  110. <view class="bottomInfo-item-center">
  111. <image class="bottomInfo-item-centerI"
  112. :src="isOpenMicrophone?'/static/images/voice/openMkf.png':'/static/images/voice/closeMkf.png'"
  113. mode="widthFix">
  114. </image>
  115. </view>
  116. <text class="bottomInfo-item-txt">
  117. {{isOpenMicrophone?'麦克风已开':'麦克风已关'}}
  118. </text>
  119. </view>
  120. <view class="bottomInfo-item">
  121. <!-- 前置摄像头开启 -->
  122. <view class="bottomInfo-item-center" v-if="isFrontCamera" @click="selectVideoCamera()">
  123. <image class="bottomInfo-item-centerI" style="width: 70rpx;"
  124. src="/static/images/voice/fanzhuan_font.png" mode="widthFix">
  125. </image>
  126. </view>
  127. <!-- 后置摄像头开启 -->
  128. <view class="bottomInfo-item-center" @click="selectVideoCamera()"
  129. style="background-color: rgba(27,27,27, 0.4);" v-else>
  130. <image class="bottomInfo-item-centerI" style="width: 70rpx;"
  131. src="/static/images/voice/fanhzuan-back.png" mode="widthFix">
  132. </image>
  133. </view>
  134. <text class="bottomInfo-item-txt">
  135. 翻转摄像头
  136. </text>
  137. </view>
  138. <view class="bottomInfo-item">
  139. <!-- 摄像头开启 -->
  140. <view class="bottomInfo-item-center" v-if="isOpenCamera" @click="openOrClosCamera()">
  141. <image class="bottomInfo-item-centerI" style="width: 70rpx;"
  142. src="/static/images/voice/openSxt.png" mode="widthFix">
  143. </image>
  144. </view>
  145. <!-- 摄像头已关 -->
  146. <view class="bottomInfo-item-center" @click="openOrClosCamera()"
  147. style="background-color: rgba(27,27,27, 0.4);" v-else>
  148. <image class="bottomInfo-item-centerI" style="width: 70rpx;"
  149. src="/static/images/voice/closeSxt.png" mode="widthFix">
  150. </image>
  151. </view>
  152. <text class="bottomInfo-item-txt">
  153. {{isOpenCamera?'摄像头已开':'摄像头已关'}}
  154. </text>
  155. </view>
  156. <view class="bottomInfo-item" style="height: 0;width: 164rpx;">
  157. </view>
  158. <view class="bottomInfo-item" @click="jieOrGuaCall(4)" style="margin-top: 40rpx;">
  159. <image class="bottomInfo-item-img" src="/static/images/voice/cancel.png" mode=""></image>
  160. <text class="bottomInfo-item-txt">
  161. 挂断
  162. </text>
  163. <!-- {{remoteUserId}}-{{isJie}} -->
  164. </view>
  165. <view class="bottomInfo-item" style="height: 0;width: 164rpx;">
  166. </view>
  167. </view>
  168. </view>
  169. </view>
  170. </template>
  171. <script>
  172. import smhTimer from '@/components/smh-timer/smh-timer.vue'
  173. import httpRequest from '@/common/httpRequest.js'
  174. import TrtcCloud from "@/TrtcCloud/lib/index";
  175. import TrtcRemoteView from '@/TrtcCloud/view/TrtcRemoteView';
  176. import TrtcLocalView from '@/TrtcCloud/view/TrtcLocalView';
  177. import {
  178. TRTCAppScene,
  179. TRTCRoleType,
  180. TRTCAudioQuality,
  181. TRTCVideoStreamType,
  182. TRTCBeautyStyle,
  183. TRTCAudioRoute
  184. } from '@/TrtcCloud/lib/TrtcDefines';
  185. export default {
  186. components: {
  187. smhTimer,
  188. TrtcLocalView,
  189. TrtcRemoteView,
  190. },
  191. data() {
  192. return {
  193. trtcCloud: TrtcCloud.createInstance(), //创建 TRTC 的对象实例。
  194. sdkAppId: parseInt(uni.getStorageSync('sdkAppId')), //trtcSdkAppId
  195. byUserId: '', //对方的userId
  196. userId: uni.getStorageSync('userId').toString(),
  197. chatContentId: '',
  198. isRol: 1, //1:发起人 2:接受人
  199. messageType: '21', //类型 20:视频通话 21:语音通话
  200. chatConversationId: '',
  201. screenHeight: '', //屏幕高度
  202. videoStatusInter: null, //获取通话状态定时器
  203. videoStatus: 1, //通话状态 1:未接通 2:接通 4:挂断
  204. isJie: false, //是否接通 true:接通 false:未接通
  205. isOpenMicrophone: true, //是否打开麦克风
  206. isOpenCamera: true, //摄像头是否开启
  207. resumesIdInfo: {
  208. resumesName: '',
  209. avatar: '',
  210. }, //用户简历
  211. company: {
  212. companyLogo: '',
  213. companyName: '',
  214. }, //企业信息
  215. userType: 1, //1:用户 2:企业
  216. postPushId: '', //岗位id,
  217. resumesId: '', //简历id
  218. isRemoterAvailable: false, //是否拉取到别人的视频流
  219. isFrontCamera: true, //默认前置摄像头
  220. sysInfoHeight: 0, //屏幕总高度
  221. remoteUserId: '', //对方的userid
  222. byJoinUserId: '', //trtc监听到的userID
  223. };
  224. },
  225. watch: {
  226. videoStatus() {
  227. //通话中
  228. if (this.videoStatus == 2) {
  229. this.isJie = true
  230. //接听后开启麦克风采集
  231. this.startAudio()
  232. this.remoteUserId = this.byJoinUserId
  233. this.trtcCloud.startRemoteView(this.remoteUserId, TRTCVideoStreamType
  234. .TRTCVideoStreamTypeBig, this.remoteUserId);
  235. } else if (this.videoStatus == 4) { //如果等于4,那么就是挂断电话
  236. console.log(this.videoStatus, '走这里了4444444')
  237. this.exitRoom()
  238. }
  239. },
  240. },
  241. onLoad(option) {
  242. const sysInfoHeight = uni.getSystemInfoSync().screenHeight
  243. this.sysInfoHeight = sysInfoHeight
  244. //定时获取通话状态
  245. this.getVideoStatus()
  246. let systemInfo = uni.getSystemInfoSync();
  247. //获取手机系统状态栏高度
  248. this.screenHeight = systemInfo.screenHeight - systemInfo.statusBarHeight;
  249. if (option.byUserId) {
  250. this.byUserId = option.byUserId
  251. }
  252. if (option.isRol) {
  253. this.isRol = option.isRol
  254. }
  255. if (option.messageType) {
  256. this.messageType = option.messageType
  257. }
  258. if (option.chatConversationId) {
  259. this.chatConversationId = option.chatConversationId
  260. }
  261. if (option.chatContentId) {
  262. this.chatContentId = option.chatContentId
  263. //获取getUserSig 开始进房操作
  264. this.getUserSig()
  265. }
  266. if (option.postPushId) {
  267. this.postPushId = option.postPushId
  268. }
  269. console.log(option.resumesId, '这是resumesId')
  270. if (option.resumesId) {
  271. this.resumesId = option.resumesId
  272. }
  273. // if (option.userType) {
  274. // this.userType = option.userType
  275. // if (this.userType == 1) { //发起人是用户
  276. // if (this.isRol == 1) { //发起人
  277. // //查询企业信息
  278. // console.log('发起人查企业')
  279. // this.selectPostPushDetails()
  280. // } else { //接受人
  281. // //查询用户简历信息
  282. // console.log('接受人')
  283. // this.selectResumesByResumesId()
  284. // }
  285. // } else { //发起人是企业
  286. // if (this.isRol == 1) { //发起人
  287. // //查询用户简历信息
  288. // this.selectResumesByResumesId()
  289. // } else { //接受人
  290. // //查询企业信息
  291. // this.selectPostPushDetails()
  292. // }
  293. // }
  294. // }
  295. this.userType = uni.getStorageSync('userType')
  296. this.selectPostPushDetails()
  297. this.selectResumesByResumesId()
  298. console.log(this.userType, '当前的userType')
  299. this.onEventTric()
  300. },
  301. onUnload(e) {
  302. // 页面卸载的时候销毁一下trtc
  303. TrtcCloud.destroyInstance();
  304. //状态也重置一下
  305. uni.setStorageSync('isDial', false)
  306. },
  307. onBackPress(e) {
  308. if (e.from != 'navigateBack') { //如果不是挂断也走挂断操作
  309. console.log('返回')
  310. this.jieOrGuaCall(5)
  311. return true
  312. }
  313. },
  314. methods: {
  315. //定时器获取接电话的状态
  316. getVideoStatus() {
  317. this.videoStatus = uni.getStorageSync('videoStatus')
  318. this.videoStatusInter = setInterval(() => {
  319. this.videoStatus = uni.getStorageSync('videoStatus')
  320. }, 1000)
  321. },
  322. //开启/关闭摄像头
  323. openOrClosCamera() {
  324. if (this.isOpenCamera) { //关闭
  325. this.trtcCloud.stopLocalPreview();
  326. // this.trtcCloud.muteLocalVideo(TRTCVideoStreamType.TRTCVideoStreamTypeBig, true);
  327. } else { //开启
  328. this.trtcCloud.startLocalPreview(true, this.userId);
  329. // this.trtcCloud.muteLocalVideo(TRTCVideoStreamType.TRTCVideoStreamTypeBig, false);
  330. }
  331. this.isOpenCamera = !this.isOpenCamera
  332. },
  333. //翻转摄像头
  334. selectVideoCamera() {
  335. this.isFrontCamera = !this.isFrontCamera
  336. this.trtcCloud.switchCamera(this.isFrontCamera);
  337. },
  338. //开启/关闭麦克风
  339. setStopLocalAudio() {
  340. if (this.isOpenMicrophone) { //r如果麦克风开启则静音
  341. this.trtcCloud.muteLocalAudio(true); //静音
  342. this.isOpenMicrophone = false
  343. } else { //否则开启麦克风
  344. this.trtcCloud.muteLocalAudio(false);
  345. this.isOpenMicrophone = true
  346. }
  347. },
  348. //接电话或拒绝
  349. jieOrGuaCall(type) {
  350. let data = {
  351. videoStatus: type,
  352. chatContentId: this.chatContentId,
  353. }
  354. httpRequest.post('/app/chat/updateChatContent', data).then(res => {
  355. if (res.code == 0) {
  356. if (type == 4 || type == 5) { //挂断则退房
  357. this.exitRoom()
  358. } else if (type == 2) { //接通(接受人)
  359. this.isJie = true
  360. this.remoteUserId = this.byJoinUserId
  361. this.trtcCloud.startRemoteView(this.remoteUserId, TRTCVideoStreamType
  362. .TRTCVideoStreamTypeBig, this.remoteUserId);
  363. console.log(typeof this.remoteUserId, '这是对方的userid')
  364. console.log(this.remoteUserId, '这是对方的userid')
  365. }
  366. } else {
  367. uni.showToast({
  368. title: res.msg,
  369. icon: 'none'
  370. })
  371. }
  372. })
  373. },
  374. //开启视频(我)
  375. startLocalPreview() {
  376. //开启摄像头采集
  377. this.trtcCloud.startLocalPreview(this.isFrontCamera, this.userId);
  378. },
  379. //开启麦克风采集(我)
  380. startAudio() {
  381. //开启麦克风采集
  382. this.trtcCloud.startLocalAudio(TRTCAudioQuality.TRTCAudioQualityDefault);
  383. },
  384. //退房
  385. exitRoom() {
  386. this.trtcCloud.exitRoom();
  387. },
  388. //监听trtc sdk事件
  389. onEventTric() {
  390. //监听远端用户退出房间
  391. this.trtcCloud.on("onRemoteUserLeaveRoom", (userId) => {
  392. console.log('对方退房了')
  393. //直接退房
  394. this.exitRoom()
  395. });
  396. this.trtcCloud.on("onRemoteUserEnterRoom", (userId) => {
  397. console.log('对方进房了')
  398. this.byJoinUserId = userId.toString()
  399. })
  400. //远端用户是否存在可播放的画面
  401. // this.trtcCloud.on("onUserVideoAvailable", (res) => {
  402. // console.log(`远端有可播放的画面` + res);
  403. // const {
  404. // userId,
  405. // available
  406. // } = res;
  407. // if (userId && available) {
  408. // this.byJoinUserId = userId.toString()
  409. // }
  410. // });
  411. //自己进房的通知
  412. this.trtcCloud.on("onEnterRoom", (result) => {
  413. console.log('1111')
  414. if (result > 0) {
  415. console.log(`进房成功,耗时: ${result}ms`);
  416. if (this.messageType == 20) { //如果是视频通话则开启摄像头
  417. this.startLocalPreview()
  418. }
  419. }
  420. });
  421. this.trtcCloud.on('onExitRoom', (reason) => {
  422. console.log(`退房成功 reason = ${reason}`);
  423. //正常退出房间后再返回
  424. uni.navigateBack()
  425. });
  426. this.trtcCloud.on('onWarning', (res) => {
  427. console.log('- onWarning: ', JSON.stringify(res));
  428. });
  429. this.trtcCloud.on('onError', (res) => {
  430. console.log('- onError: ', JSON.stringify(res));
  431. });
  432. },
  433. //进房
  434. setEnterRoom(userSig) {
  435. const params = {
  436. strRoomId: this.chatContentId.toString(),
  437. sdkAppId: this.sdkAppId,
  438. userId: uni.getStorageSync('userId').toString(),
  439. userSig: userSig,
  440. role: TRTCRoleType.TRTCRoleAnchor, //anchor:“主播”角色,可以推流和拉流。 audience:“观众”角色,只能拉流观看,无法推流。
  441. }
  442. this.trtcCloud.enterRoom(params, TRTCAppScene.TRTCAppSceneVideoCall);
  443. },
  444. //获取sign
  445. getUserSig() {
  446. httpRequest.getT('/app/chat/selectSign').then(res => {
  447. if (res.code == 0) {
  448. //进房
  449. this.setEnterRoom(res.data)
  450. } else {
  451. uni.showToast({
  452. title: res.msg,
  453. icon: 'none'
  454. })
  455. }
  456. })
  457. },
  458. //获取企业信息
  459. selectPostPushDetails() {
  460. let data = {
  461. postPushId: this.postPushId
  462. }
  463. httpRequest.getT('/app/postPush/selectPostPushDetails', data).then(res => {
  464. if (res.code == 0) {
  465. this.company = res.data.company
  466. } else {
  467. uni.showToast({
  468. title: res.msg,
  469. icon: 'none'
  470. })
  471. }
  472. })
  473. },
  474. //获取用户简历
  475. selectResumesByResumesId() {
  476. let data = {
  477. resumesId: this.resumesId
  478. }
  479. httpRequest.getT('/app/resumes/selectResumesByResumesId', data).then(res => {
  480. if (res.code == 0) {
  481. this.resumesIdInfo = res.data
  482. }
  483. })
  484. },
  485. }
  486. }
  487. </script>
  488. <style lang="scss">
  489. @import url("./css/videoVoice.css");
  490. </style>