帖子
帖子
用户
博客
课程

融云单人多人音频通话

YonBuilder移动开发 2022-6-14 18:07 670人浏览 5人回复
原作者: 川哥哥 收藏 邀请
摘要

一、页面效果展示(视频演示http://139.155.81.223/demo/) 二、功能实现的思路 使用之前必须先获取token、init、connect,同时需要到融云后台开通音视频通话功能(开通或者关闭30分钟后生效)。 单人通话逻辑比较 ...

一、页面效果展示(视频演示http://139.155.81.223/demo/

1.jpg

二、功能实现的思路
使用之前必须先获取token、init、connect,同时需要到融云后台开通音视频通话功能(开通或者关闭30分钟后生效)。
单人通话逻辑比较简单,主要会用到didReceiveCall、didConnect、didDisconnect等三个事件。
主要通话流程:①发起通话    ②监听来电    ③接听或者挂断。

多人通话逻辑复杂一点,并且只能应用在群组或者讨论组,会用到didReceiveCall、didConnect、remoteUserDidJoin、remoteUserDidLeft、remoteUserDidInvite、didDisconnect等六个事件。通话实体getCallSession个人觉得可以不用。

主要通话流程:①在组里选择几个成员发起通话 ②成员收到来电 ③成员接听或者挂断。
④邀请几个成员加入当前通话 ⑤被邀请组员收到来电 ⑥被邀请组员接听或挂断来电
⑦通话组员监听是否有新成员加入或成员退出。

为了让页面代码逻辑更简单,设计了四个页面
index.html(融云初始化、所有监听等主要业务代码)
receive-call.html(接收端业务代码,单人多人通话代码)
send-call.html(发送端业务代码,单人多人通话代码)
friends.html(群组或讨论组成员列表)

index.html首页融云初始化以及监听代码如下:
  1. var rong = api.require('rongCloud2');
  2.         rong.init(function (ret, err) {
  3.             if (ret.status == 'success') {
  4.                 rong.connect({
  5.                     token: $api.getStorage('token')
  6.                 }, function (ret, err) {
  7.                 });
  8.             }
  9.         });
  10.         //来电事件
  11.         rong.addCallReceiveListener({
  12.             target: 'didReceiveCall'
  13.         }, function (ret) {
  14.             if (ret.callSession.status) {
  15.                 var callType = 'more';
  16.                 if (ret.callSession.conversationType == 'PRIVATE') {
  17.                     callType = 'one';
  18.                 }
  19.                 api.openWin({
  20.                     name: 'receive-call',
  21.                     url: 'receive-call.html',
  22.                     pageParam: {
  23.                         uid: ret.callSession.callerUserId,
  24.                         userIdList: [ret.callSession.observerUserList],
  25.                         callId: ret.callSession.callId,
  26.                         callType: callType
  27.                     },
  28.                     animation: {type: "fade"}
  29.                 });
  30.             }
  31.         });
  32.         //通话结束事件
  33.         rong.addCallSessionListener({
  34.             target: 'didDisconnect'
  35.         }, function (ret) {
  36.             api.sendEvent({
  37.                 name: 'didDisconnect'
  38.             });
  39.         });
  40.         //对端挂断事件
  41.         rong.addCallSessionListener({
  42.             target: 'remoteUserDidLeft'
  43.         }, function (ret) {
  44.             api.sendEvent({
  45.                 name: 'remoteUserDidLeft',
  46.                 extra: {uid: ret.userId}
  47.             });
  48.         });
  49.         //接听事件
  50.         rong.addCallSessionListener({
  51.             target: 'didConnect'
  52.         }, function (ret) {
  53.             api.sendEvent({
  54.                 name: 'didConnect'
  55.             });
  56.         });
  57.         //加入通话事件
  58.         rong.addCallSessionListener({
  59.             target: 'remoteUserDidJoin'
  60.         }, function (ret) {
  61.             api.sendEvent({
  62.                 name: 'remoteUserDidJoin',
  63.                 extra: { uid: ret.userId}
  64.             });
  65.         });
  66.         //邀请加入通话的事件
  67.         rong.addCallSessionListener({
  68.             target: 'remoteUserDidInvite'
  69.         }, function (ret) {
  70.             api.sendEvent({
  71.                 name: 'remoteUserDidInvite',
  72.                 extra: {uid: ret.userId}
  73.             });
  74.         });
复制代码


单人通话
调用startCall发起通话,需要注意userIdLis参数必填否则无法建立通话,对方也无法收到来电事件。
  1. rong.startCall({
  2.         targetId: '3001',    //用户id
  3.         userIdList: ['3001'] //必填如果不填无法建立通话
  4.     }, function (ret) {
  5.         if (ret.callSession.callId) {
  6.             api.openWin({
  7.                 name: 'send-call',
  8.                 url: 'send-call.html',
  9.                 pageParam: {
  10.                     uid: '3000',                   //自己的用户id
  11.                     userIdList: ['3001'],
  12.                     callId: ret.callSession.callId,//发送者可以通过通话id挂断通话
  13.                     callType: 'one'                //通话类型单人one 多人more
  14.                 },
  15.                 animation: { type: "fade"}
  16.             })
  17.         }
  18.     })
复制代码

发送端页面send-call.html需要处理来电接听事件(didConnect)以及通话结束事件(didDisconnect)、显示对方用户个人信息、通话计时。
当用户接听时就开始计时,时间格式00:00:00代码如下:
  1. timer(){
  2.                     var that = this
  3.                     clearInterval(time)
  4.                     time = setInterval(function () {
  5.                         number++
  6.                         var hour = that.add0(Math.floor(number / 60 / 60));
  7.                         var min = that.add0(Math.floor(number / 60) % 60);
  8.                         var s = that.add0(number % 60);
  9.                         that.time = hour + ':' + min + ':' + s
  10.                     }, 1000)
  11.                 }
复制代码

Index.html页面监听来电事件并打开接收端页面receive-call.html并传递相关参数
  1. rong.addCallReceiveListener({
  2.             target: 'didReceiveCall'
  3.         }, function (ret) {
  4.             if (ret.callSession.status) {
  5.                 var callType = 'more';
  6.                 if (ret.callSession.conversationType == 'PRIVATE') {
  7.                     callType = 'one';
  8.                 }
  9.                 api.openWin({
  10.                     name: 'receive-call',
  11.                     url: 'receive-call.html',
  12.                     pageParam: {
  13.                         uid: ret.callSession.callerUserId,
  14.                         userIdList: [ret.callSession.observerUserList],
  15.                         callId: ret.callSession.callId,
  16.                         callType: callType
  17.                     },
  18.                     animation: {type: "fade"}
  19.                 });
  20.             }
  21.         });
复制代码
接收端页面receive-call.html需要显示对方用户个人信息、通话计时、接听、挂断等。
当用户挂断或者自己挂断就关闭相应页面,长时间不接听系统自动触发通话结束事件。


多人通话
调用startCall发起通话,注意targetId为讨论组或者群组id,参数conversationType必填同时要和targetId类型保持一致,参数userIdLis里面用户必须是本群组或者讨论组成员同时不能填自己的id。
  1. rong.startCall({
  2.         targetId: 'group318', //群组或者讨论组id
  3.         conversationType: 'GROUP',//必填必须和targetId类型保持一致。
  4.         userIdList: ['3001','3002'] //不能填自己的id
  5.     }, function (ret) {
  6.         if (ret.callSession.callId) {
  7.             api.openWin({
  8.                 name: 'send-call',
  9.                 url: 'send-call.html',
  10.                 pageParam: {
  11.                     uid: '3000',                   //自己的用户id
  12.                     userIdList: ['3001','3002'] ,
  13.                     callId: ret.callSession.callId,//通话id
  14.                     callType: 'more'               //通话类型单人one 多人more
  15.                 },
  16.                 animation: {type: "fade"}
  17.             })
  18.         }
  19.     })
复制代码


发送端页面send-call.html需要处理以下业务
通话已接通的事件(didConnect)
对端用户加入了通话的事件(remoteUserDidJoin)
对端用户挂断(remoteUserDidLeft)
有用户被邀请加入通话的事件(remoteUserDidInvite)
通话结束事件(didDisconnect)
以及显示和更新当前通话成员信息、通话计时。

  1. //通话接通事件
  2.         api.addEventListener({
  3.             name: 'didConnect'
  4.         }, function (ret, err) {
  5.             vm.Connect = true
  6.             vm.title = '通话中...'//改变通话状态
  7.             vm.timer();//开始计时
  8.         });
  9.         //对端加入通话事件
  10.         api.addEventListener({
  11.             name: 'remoteUserDidJoin'
  12.         }, function (ret, err) {
  13.             var obj = vm.inData(ret.value.uid);
  14.             for (var i = 0; i < vm.userList.length; i++) {
  15.                 var rs = vm.userList[i]
  16.                 if (ret.value.uid == rs.uid) {
  17.                     rs.avatar = obj.avatar;//更新用户头像
  18.                 }
  19.             }
  20.         });
  21.         //对端挂断电话
  22.         api.addEventListener({
  23.             name: 'remoteUserDidLeft'
  24.         }, function (ret, err) {
  25.             var obj = vm.inData(ret.value.uid);
  26.             for (var i = 0; i < vm.userList.length; i++) {
  27.                 var rs = vm.userList[i]
  28.                 if (ret.value.uid == rs.uid) {
  29.                     vm.userList.splice(i, 1);//删除用户数据
  30.                 }
  31.             }
  32.         });
  33.         //通话结束
  34.         api.addEventListener({
  35.             name: 'didDisconnect'
  36.         }, function (ret, err) {
  37.             api.closeWin();
  38.         });
  39.         //邀请加入通话的事件
  40.         api.addEventListener({
  41.             name: 'remoteUserDidInvite'
  42.         }, function (ret, err) {
  43.             var rs = vm.inData(ret.value.uid);
  44.             let obj = { uid: rs.uid, nickname: rs.nickname, avatar: '../res/user.png' }
  45.             vm.userList.push(obj)
  46.         });
复制代码


当对端用户加入了通话时更新用户头像同时也通话计时,当对端用户挂断时移除该用户,当有用户被邀请加入通话时新增用户数据但是头像为灰色默认头像,当通话结束时关闭当前页。

接收端页面receive-call.html需要处理以下业务
对端用户加入了通话的事件(remoteUserDidJoin)
对端用户挂断(remoteUserDidLeft)
通话结束事件(didDisconnect)
以及显示和更新当前通话成员信息、计时。

监听代码如下:
  1. //对端加入通话
  2.         api.addEventListener({
  3.             name: 'remoteUserDidJoin'
  4.         }, function (ret, err) {
  5.             var has = false
  6.             for (var i in vm.userList) {
  7.                 if (vm.userList[i].uid == ret.value.uid) {
  8.                     has = true
  9.                     vm.userList[i].avatar = vm.inData(ret.value.uid).avatar;//更新用户头像
  10.                 }
  11.             }
  12.             if (has == false) {
  13.                 var rs = vm.inData(ret.value.uid);
  14.                 vm.userList.push(rs)//增加用户信息
  15.             }
  16.         });
  17.         //对端挂断电话
  18.         api.addEventListener({
  19.             name: 'remoteUserDidLeft'
  20.         }, function (ret, err) {
  21.             var obj = vm.inData(ret.value.uid);
  22.             for (var i = 0; i < vm.userList.length; i++) {
  23.                 var rs = vm.userList[i]
  24.                 if (ret.value.uid == rs.uid) {
  25.                     vm.userList.splice(i, 1);//删除用户
  26.                 }
  27.             }
  28.         });
  29.         //通话结束
  30.         api.addEventListener({
  31.             name: 'didDisconnect'
  32.         }, function (ret, err) {
  33.             api.closeWin();
  34.         });
复制代码


当自己接听电话时开始计时,当对端用户加入了通话时新增用户信息,当对端用户挂断时移除该用户,当通话结束时关闭当前页,长时间不接听系统自动触发通话结束事件。

三、测试地址
22.png

http://139.155.81.223:9000/ry.apk
测试账号  3000-3005  6个账号


评论
670人参与,5条评论

精彩评论
  • 技术咨询-特特 老司机 1047Y币
    发表于 2022-5-18 11:47
    可以可以  赞一个
  • Arly【770104707】 版主 53052Y币
    发表于 2022-5-19 21:34
    赞赞赞
  • 技术咨询-F 版主 6Y币
    发表于 2022-5-20 13:39
  • 安静的帅气 马路杀手 380Y币
    发表于 2023-5-23 11:03
    demo地址打不开了
  • zhou1 业余车手 319Y币
    发表于 2023-7-19 16:41
    好长时间没有逛论坛了,发现平台编译时要什么实名验证,还有平台要迁移啥的,数据库也连接不上了

查看全部评论>>