乐趣区

关于音视频:使用融云SDK在APICloud平台实现单人多人音频通话

一、成果展现

二、性能实现的思路

应用之前必须先获取 token、init、connect,同时须要到融云后盾开明音视频通话性能(开明或者敞开 30 分钟后失效)。

单人通话逻辑比较简单,次要会用到 didReceiveCall、didConnect、didDisconnect 等三个事件。

次要通话流程:

(1)发动通话

(2)监听复电

(3)接听或者挂断

多人通话逻辑简单一点,并且只能利用在群组或者讨论组,会用到 didReceiveCall、didConnect、remoteUserDidJoin、remoteUserDidLeft、remoteUserDidInvite、didDisconnect 等六个事件。

次要通话流程:

(1)在组里抉择几个成员发动通话

(2)成员收到复电

(3)成员接听或者挂断

(4)邀请几个成员退出以后通话

(5)被邀请组员收到复电

(6)被邀请组员接听或挂断复电

(7)通话组员监听是否有新成员退出或成员退出

为了让页面代码逻辑更简略,设计了四个页面

index.html(融云初始化、所有监听等次要业务代码)

receive-call.html(接收端业务代码,单人多人通话代码)

send-call.html(发送端业务代码,单人多人通话代码)

friends.html(群组或探讨组成员列表)

index.html 首页融云初始化以及监听代码如下:

        var rong = api.require('rongCloud2');
        rong.init(function (ret, err) {if (ret.status == 'success') {
                rong.connect({token: $api.getStorage('token')
                }, function (ret, err) {});
            }
        });
        // 复电事件
        rong.addCallReceiveListener({target: 'didReceiveCall'}, function (ret) {if (ret.callSession.status) {
                var callType = 'more';
                if (ret.callSession.conversationType == 'PRIVATE') {callType = 'one';}
                api.openWin({
                    name: 'receive-call',
                    url: 'receive-call.html',
                    pageParam: {
                        uid: ret.callSession.callerUserId,
                        userIdList: [ret.callSession.observerUserList],
                        callId: ret.callSession.callId,
                        callType: callType
                    },
                    animation: {type: "fade"}
                });
            }
        });
        // 通话完结事件
        rong.addCallSessionListener({target: 'didDisconnect'}, function (ret) {
            api.sendEvent({name: 'didDisconnect'});
        });
        // 对端挂断事件
        rong.addCallSessionListener({target

1、单人通话

调用 startCall 发动通话,须要留神 userIdLis 参数必填否则无奈建设通话,对方也无奈收到复电事件。

    rong.startCall({
        targetId: '3001',    // 用户 id
        userIdList: ['3001'] // 必填如果不填无奈建设通话
    }, function (ret) {if (ret.callSession.callId) {
            api.openWin({
                name: 'send-call',
                url: 'send-call.html',
                pageParam: {
                    uid: '3000',                   // 本人的用户 id
                    userIdList: ['3001'],
                    callId: ret.callSession.callId,// 发送者能够通过通话 id 挂断通话
                    callType: 'one'                // 通话类型单人 one 多人 more
                },
                animation: {type: "fade"}
            })
        }
    })

发送端页面 send-call.html 须要解决复电接听事件(didConnect)以及通话完结事件(didDisconnect)、显示对方用户个人信息、通话计时。

当用户接听时就开始计时,工夫格局 00:00:00 代码如下:

        timer(){
                    var that = this
                    clearInterval(time)
                    time = setInterval(function () {
                        number++
                        var hour = that.add0(Math.floor(number / 60 / 60));
                        var min = that.add0(Math.floor(number / 60) % 60);
                        var s = that.add0(number % 60);
                        that.time = hour + ':' + min + ':' + s
                    }, 1000)
                }

Index.html 页面监听复电事件并关上接收端页面 receive-call.html 并传递相干参数

        rong.addCallReceiveListener({target: 'didReceiveCall'}, function (ret) {if (ret.callSession.status) {
                var callType = 'more';
                if (ret.callSession.conversationType == 'PRIVATE') {callType = 'one';}
                api.openWin({
                    name: 'receive-call',
                    url: 'receive-call.html',
                    pageParam: {
                        uid: ret.callSession.callerUserId,
                        userIdList: [ret.callSession.observerUserList],
                        callId: ret.callSession.callId,
                        callType: callType
                    },
                    animation: {type: "fade"}
                });
            }
        });

接收端页面 receive-call.html 须要显示对方用户个人信息、通话计时、接听、挂断等。

当用户挂断或者本人挂断就敞开相应页面,长时间不接听零碎主动触发通话完结事件。

2、多人通话

调用 startCall 发动通话,留神 targetId 为讨论组或者群组 id,参数 conversationType 必填同时要和 targetId 类型保持一致,参数 userIdLis 外面用户必须是本群组或者探讨组成员同时不能填本人的 id。

   rong.startCall({
        targetId: 'group318', // 群组或者讨论组 id
        conversationType: 'GROUP',// 必填必须和 targetId 类型保持一致。userIdList: ['3001','3002'] // 不能填本人的 id
    }, function (ret) {if (ret.callSession.callId) {
            api.openWin({
                name: 'send-call',
                url: 'send-call.html',
                pageParam: {
                    uid: '3000',                   // 本人的用户 id
                    userIdList: ['3001','3002'] ,
                    callId: ret.callSession.callId,// 通话 id
                    callType: 'more'               // 通话类型单人 one 多人 more
                },
                animation: {type: "fade"}
            })
        }
    })

发送端页面 send-call.html 须要解决以下业务

通话已接通的事件(didConnect)

对端用户退出了通话的事件(remoteUserDidJoin)

对端用户挂断(remoteUserDidLeft)

有用户被邀请退出通话的事件(remoteUserDidInvite)

通话完结事件(didDisconnect)

以及显示和更新以后通话成员信息、通话计时。

       // 通话接通事件
        api.addEventListener({name: 'didConnect'}, function (ret, err) {
            vm.Connect = true
            vm.title = '通话中...'// 扭转通话状态
            vm.timer();// 开始计时});
        // 对端退出通话事件
        api.addEventListener({name: 'remoteUserDidJoin'}, function (ret, err) {var obj = vm.inData(ret.value.uid);
            for (var i = 0; i < vm.userList.length; i++) {var rs = vm.userList[i]
                if (ret.value.uid == rs.uid) {rs.avatar = obj.avatar;// 更新用户头像}
            }
        });
        // 对端挂断电话
        api.addEventListener({name: 'remoteUserDidLeft'}, function (ret, err) {var obj = vm.inData(ret.value.uid);
            for (var i = 0; i < vm.userList.length; i++) {var rs = vm.userList[i]
                if (ret.value.uid == rs.uid) {vm.userList.splice(i, 1);// 删除用户数据
                }
            }
        });
        // 通话完结
        api.addEventListener({name: 'didDisconnect'}, function (ret, err) {api.closeWin();
        });
        // 邀请退出通话的事件
        api.addEventListener({name: 'remoteUserDidInvite'}, function (ret, err) {var rs = vm.inData(ret.value.uid);
            let obj = {uid: rs.uid, nickname: rs.nickname, avatar: '../res/user.png'}
            vm.userList.push(obj)
        });

当对端用户退出了通话时更新用户头像同时也通话计时,当对端用户挂断时移除该用户,当有用户被邀请退出通话时新增用户数据然而头像为灰色默认头像,当通话完结时敞开当前页。

接收端页面 receive-call.html 须要解决以下业务

对端用户退出了通话的事件(remoteUserDidJoin)

对端用户挂断(remoteUserDidLeft)

通话完结事件(didDisconnect)

以及显示和更新以后通话成员信息、计时。

监听代码如下:

       // 对端退出通话
        api.addEventListener({name: 'remoteUserDidJoin'}, function (ret, err) {
            var has = false
            for (var i in vm.userList) {if (vm.userList[i].uid == ret.value.uid) {
                    has = true
                    vm.userList[i].avatar = vm.inData(ret.value.uid).avatar;// 更新用户头像
                }
            }
            if (has == false) {var rs = vm.inData(ret.value.uid);
                vm.userList.push(rs)// 减少用户信息
            }
        });
        // 对端挂断电话
        api.addEventListener({name: 'remoteUserDidLeft'}, function (ret, err) {var obj = vm.inData(ret.value.uid);
            for (var i = 0; i < vm.userList.length; i++) {var rs = vm.userList[i]
                if (ret.value.uid == rs.uid) {vm.userList.splice(i, 1);// 删除用户
                }
            }
        });
        // 通话完结
        api.addEventListener({name: 'didDisconnect'}, function (ret, err) {api.closeWin();
        });

当本人接听电话时开始计时,当对端用户退出了通话时新增用户信息,当对端用户挂断时移除该用户,当通话完结时敞开当前页,长时间不接听零碎主动触发通话完结事件。

退出移动版