audioCall.nvue 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384
  1. <template>
  2. <view>
  3. <customNav :shownav="true" :title="i18n('audioCall.imtitle')" tinColor="#006AFF" jiantou="0"></customNav>
  4. <view class="contentColumnC" style="width: 700rpx;margin-left: 25rpx;margin-top: 50rpx;">
  5. <netImage class="spIcon" width="120" height="120" :mysrc="avatar" mymode="scaleToFill"></netImage>
  6. <text style="margin-top: 30rpx;font-size: 32rpx;">{{nickName}}</text>
  7. <image v-if="!callState" style="width: 80rpx;height: 80rpx;margin-top: 80rpx;" src="/static/imags/jietong.png" mode="scaleToFill" @click="bohaoAct(1)"></image>
  8. <image v-if="callState" style="width: 80rpx;height: 80rpx;margin-top: 80rpx;" src="/static/imags/guaduandd.png" mode="scaleToFill" @click="bohaoAct(2)"></image>
  9. <text style="margin-top: 80rpx;font-size: 32rpx;">{{noteMessage}}</text>
  10. </view>
  11. </view>
  12. </template>
  13. <script>
  14. import api from "@/pages/api/api.js"
  15. import permision from "@/TrtcCloud/permission.js";
  16. import TrtcCloud from '@/TrtcCloud/lib/index';
  17. import { TRTCAppScene, TRTCVideoStreamType, TRTCCloudDef } from '@/TrtcCloud/lib/TrtcDefines';
  18. import { genTestUserSig } from '@/debug/GenerateTestUserSig';
  19. import TrtcLocalView from '@/TrtcCloud/view/TrtcLocalView';
  20. import TrtcRemoteView from '@/TrtcCloud/view/TrtcRemoteView';
  21. //const roomId = Math.floor(Math.random() * 100000).toString();
  22. //const userId = 'user_' + Math.floor(Math.random() * 100000).toString();
  23. export default {
  24. components: {
  25. TrtcLocalView: TrtcLocalView,
  26. TrtcRemoteView: TrtcRemoteView,
  27. },
  28. data() {
  29. return {
  30. iscaller:false,
  31. trtcCloud: null,
  32. sdkAppId:1600036174,
  33. userSig: '',
  34. roomId: Math.floor(Math.random() * 100000),
  35. userId:'',
  36. appScene: TRTCAppScene.TRTCAppSceneVideoCall, // TRTCAppSceneVideoCall
  37. isFrontCamera: true,
  38. streamType: TRTCVideoStreamType.TRTCVideoStreamTypeBig,
  39. remoteUserId: '',
  40. userinfo:'',
  41. friend:'',
  42. nickName:'',
  43. avatar:'',
  44. noteMessage:'',
  45. callState:false,
  46. isAndroid:false,
  47. audioObj:null,
  48. soundPlay:false
  49. }
  50. },
  51. onLoad(option) {
  52. var systemInfo = uni.getSystemInfoSync();
  53. this.isAndroid = systemInfo.platform.toLowerCase() === 'android';
  54. console.log('onLoad---------------------');
  55. getApp().globalData.imViewOpen=true;
  56. this.userinfo = uni.getStorageSync('userInfo');
  57. this.userId='user_'+this.userinfo.userId;
  58. console.log(this.userId);
  59. if(option.caller==1){
  60. this.iscaller=true;
  61. var friendinfo = uni.getStorageSync('imUser');
  62. this.friend = {
  63. id:'userid_'+friendinfo.userId,
  64. name:friendinfo.nickName,
  65. avatar:friendinfo.avatar
  66. }
  67. console.log(friendinfo);
  68. this.nickName=friendinfo.nickName;
  69. this.avatar=friendinfo.avatar;
  70. this.noteMessage=this.i18n('audioCall.zhengzhj');
  71. }
  72. else{
  73. if(!this.isAndroid){
  74. this.audioObj=uni.createInnerAudioContext();
  75. this.audioObj.src='hybrid/html/xuanfu/img/y800.mp3';
  76. this.audioObj.play();
  77. this.soundPlay=true;
  78. }
  79. }
  80. },
  81. mounted() {
  82. if (uni.getSystemInfoSync().platform === 'android') {
  83. permision.requestAndroidPermission('android.permission.RECORD_AUDIO');
  84. permision.requestAndroidPermission('android.permission.CAMERA');
  85. }
  86. console.log('mounted---------------------');
  87. // 生成 userSig
  88. if(this.iscaller){//主动拨号
  89. this.getUserSig(this.userId);
  90. }
  91. else{//接听,解析发起人信息
  92. var payload=uni.getStorageSync('impayload');
  93. this.doPushMessage(payload);
  94. if(this.isAndroid){
  95. this.getUserSig(this.userId);
  96. }
  97. }
  98. },
  99. unmounted() {
  100. this.handleUninstallEvents();
  101. },
  102. onUnload() {
  103. if(this.soundPlay){
  104. this.audioObj.pause();
  105. }
  106. getApp().globalData.imViewOpen=false;
  107. this.destroyInstance();
  108. console.log('- onUnload');
  109. },
  110. onBackPress() {
  111. getApp().globalData.imViewOpen=false;
  112. this.destroyInstance();
  113. },
  114. methods: {
  115. i18n(str){
  116. var rstr = getApp().globalData.$t(str);
  117. return rstr;
  118. },
  119. doPushMessage(str){
  120. if(str.indexOf("\\\"")!=-1){
  121. str=str.replace(/\\\"/g, '\"');
  122. str = str.replace(/\"{/g, '{');
  123. str = str.replace(/}\"/g, '}');
  124. }
  125. var obj = JSON.parse(str)
  126. console.log('doPushMessage',obj)
  127. this.friend = {
  128. id:'userid_'+obj.userId,
  129. name:obj.nickName,
  130. avatar:obj.avatar
  131. }
  132. this.roomId=obj.roomId;
  133. this.nickName=obj.nickName;
  134. this.avatar=obj.avatar;
  135. },
  136. destroyInstance() {
  137. this.exitRoom();
  138. if (this.trtcCloud) {
  139. TrtcCloud.destroyInstance();
  140. this.trtcCloud = null;
  141. // uni.showToast({
  142. // title: '通话结束',
  143. // icon: 'none'
  144. // });
  145. }
  146. },
  147. createTrtcCloud() {
  148. // uni.showToast({
  149. // title: '创建实例 ',
  150. // icon: 'none',
  151. // });
  152. this.trtcCloud = TrtcCloud.createInstance();
  153. this.handleEvents();
  154. },
  155. enterRoom() {
  156. try {
  157. // 【1】创建实例
  158. this.createTrtcCloud();
  159. // 【2】进房
  160. const { roomId, userId, sdkAppId, appScene, userSig } = this;
  161. let param = { roomId: +roomId, userId, sdkAppId, userSig };
  162. console.log(param);
  163. this.trtcCloud.enterRoom(param, appScene);
  164. if(!this.iscaller){//接听者开始进入房间
  165. this.noteMessage=this.i18n('audioCall.zhengzjt');
  166. }
  167. } catch (error) {
  168. this.noteMessage=this.i18n('audioCall.wfjt');
  169. console.log(`enterRoom error = ${JSON.stringify(error)}`);
  170. // this.sdkAppId && uni.$enterRoomFailedUpload(this.sdkAppId, JSON.stringify(error));
  171. }
  172. },
  173. exitRoom() {
  174. try {
  175. this.stopLocalAudio();
  176. this.trtcCloud.exitRoom();
  177. this.remoteUserId = '';
  178. } catch (e) {
  179. // TODO handle the exception
  180. }
  181. },
  182. // 开启本地音频采集和上行
  183. startLocalAudio() {
  184. this.trtcCloud.enableAudioVolumeEvaluation(300);
  185. this.trtcCloud.startLocalAudio();
  186. },
  187. // 关闭本地音频采集和上行
  188. stopLocalAudio() {
  189. this.trtcCloud.stopLocalAudio();
  190. },
  191. handleEvents() {
  192. this.trtcCloud.on('onWarning', (res) => {
  193. // uni.showToast({
  194. // title: `onWarning: ${JSON.stringify(res)}`,
  195. // icon: 'none',
  196. // });
  197. });
  198. this.trtcCloud.on('onError', (res) => {
  199. console.log('- onError: ', JSON.stringify(res));
  200. // uni.showToast({
  201. // title: `error: ${JSON.stringify(res)}`,
  202. // icon: 'none',
  203. // });
  204. // this.sdkAppId && uni.$onErrorUpload(this.sdkAppId, JSON.stringify(res));
  205. });
  206. this.trtcCloud.on('onEnterRoom', (result) => {
  207. console.log(`- onEnterRoom = ${result}`);
  208. if (result > 0) {
  209. if(this.iscaller){
  210. //this.sentroomId();
  211. this.goEasypushmsg();
  212. }
  213. else{
  214. this.startLocalAudio();
  215. this.noteMessage=this.i18n('audioCall.yijietong');
  216. }
  217. // uni.showToast({
  218. // title: `进房成功,耗时: ${result}ms`,
  219. // icon: 'none',
  220. // });
  221. } else {
  222. this.noteMessage=this.i18n('audioCall.wfjt');
  223. console.log(`enter room failed,error code = ${result}`);
  224. }
  225. });
  226. this.trtcCloud.on('onExitRoom', (reason) => {
  227. this.noteMessage=this.i18n('audioCall.yiguanduan');
  228. console.log('onExitRoom',reason)
  229. // const reasonList = ['主动调用 exitRoom 退房', '被服务器踢出当前房间', '当前房间整个被解散'];
  230. // uni.showToast({
  231. // title: `退房 ${reasonList[reason]}`,
  232. // icon: 'none',
  233. // duration: 1000
  234. // });
  235. });
  236. this.trtcCloud.on('onFirstVideoFrame', (res) => {
  237. console.log(`渲染的首帧画面响应 = ${JSON.stringify(res)}`);
  238. });
  239. this.trtcCloud.on('onRemoteUserEnterRoom', (userId) => {
  240. this.remoteUserId = userId;
  241. this.startLocalAudio();
  242. this.noteMessage=this.i18n('audioCall.yijietong');
  243. // uni.showToast({
  244. // title: `远端进房: userId = ${userId}`,
  245. // icon: 'none',
  246. // });
  247. });
  248. this.trtcCloud.on('onUserVideoAvailable', (res) => {
  249. const {
  250. userId,
  251. available
  252. } = res;
  253. if (userId && available) {
  254. this.remoteUserId = userId;
  255. this.trtcCloud.startRemoteView(this.remoteUserId, this.streamType, this.remoteUserId);
  256. }
  257. });
  258. this.trtcCloud.on('onUserVoiceVolume', (res) => {
  259. //console.log('音量 = ', res);
  260. });
  261. },
  262. handleUninstallEvents() {
  263. this.trtcCloud.off('*');
  264. },
  265. //---------------------------------------------------------------
  266. bohaoAct(index){
  267. if(index==1){//接通
  268. if(this.soundPlay){
  269. this.audioObj.pause();
  270. }
  271. this.getUserSig(this.userId);
  272. }
  273. else if(index==2){//挂断
  274. uni.navigateBack();
  275. }
  276. },
  277. getUserSig(userId){
  278. this.callState=true;
  279. // console.log(userId);
  280. // // 本地生成 userSig
  281. // const { sdkAppId, userSig } = genTestUserSig(userId);
  282. // this.sdkAppId = sdkAppId;
  283. // this.userSig = userSig;
  284. // this.enterRoom();
  285. // console.log(userId,this.userSig);
  286. // return;
  287. //远程签名 userSig
  288. api('getUserSig',{
  289. userId:userId,
  290. },res=>{
  291. console.log('getUserSig',res)
  292. if(res.data.code==200){
  293. this.userSig = res.data.data;
  294. this.enterRoom();
  295. }
  296. else{
  297. this.noteMessage=this.i18n('audioCall.wfjt');
  298. }
  299. },failc=>{
  300. //console.log('getadvertis----',failc)
  301. })
  302. },
  303. sentroomId(){
  304. console.log('sentroomId')
  305. if(this.imUser.cid==''||this.imUser.cid==null||this.imUser.cid==undefined){
  306. uni.showToast({
  307. title:this.i18n('audioCall.hujiaosb'),
  308. icon: 'none',
  309. duration: 1000
  310. });
  311. return;
  312. }
  313. var payload={
  314. roomId:JSON.stringify(this.roomId),
  315. nickName:this.userinfo.nickName,
  316. avatar:this.userinfo.avatar,
  317. }
  318. console.log('sentroomId',this.imUser.cid);
  319. api('pushMsgYH',{
  320. cid:this.imUser.cid,
  321. title:'IM Call',
  322. content:'IM Call',
  323. payload:payload
  324. },res=>{
  325. console.log(res)
  326. },failc=>{
  327. //console.log('getadvertis----',failc)
  328. })
  329. },
  330. goEasypushmsg(){
  331. var payload={
  332. roomId:JSON.stringify(this.roomId),
  333. userId:this.userinfo.userId,
  334. nickName:this.userinfo.nickName,
  335. avatar:this.userinfo.avatar,
  336. ptype:1
  337. }
  338. console.log('goEasypushmsg1')
  339. var goEasy=getApp().globalData.goEasy;
  340. var pubsub = goEasy.pubsub;
  341. console.log('goEasypushmsg2')
  342. pubsub.publish({
  343. channel:this.friend.id, //请确认与接收端一致
  344. message:JSON.stringify(payload), //app内onMessage收到的消息内容
  345. notification: { //定义通知栏推送
  346. title: 'IM Call', //通知栏提醒标题,仅显示于通知栏
  347. body:'Call', //通知栏提醒内容,仅显示于通知栏
  348. },
  349. onSuccess: function () {
  350. console.log("Publish successfully.")
  351. },
  352. onFailed: function (error) {
  353. console.log("Failed to publish message, code:" + error.code + ' error:' + error.content);
  354. }
  355. });
  356. },
  357. }
  358. }
  359. </script>
  360. <style>
  361. .iconImg{
  362. margin-top: 30rpx;
  363. width: 200rpx;
  364. height: 200rpx;
  365. border-radius: 10rpx;
  366. background-color: #1A1A1A;
  367. }
  368. .spIcon{
  369. margin: 20rpx;
  370. width: 150rpx;
  371. height: 150rpx;
  372. }
  373. </style>