首页 > 建站教程 > APP开发,混合APP >  apicloud rongcloud2视频聊天踩坑正文

apicloud rongcloud2视频聊天踩坑

    近段时间,公司需要做个视频聊天效果,效果图如下:





    从上面看,应该是画中画效果,即大窗口显示对方,小窗口显示自己。

    因为是apicloud项目,所以首先想到了融云,研究了两天,总算弄出来了,期间遇到的最大的坑就是,文档说IOS不支持监听didConnect、remoteUserDidJoin两个事件,即IOS拨打电话,对方接听,IOS收不到事件提醒。经过测试,的确收不到,那怎么办,后来官方技术又说支持,要把拨打电话的事件,和这些监听事件放在同一个页面,试了,果然如此,太坑。

下面是代码总结

    下面的代码直接放到对应的位置,只要注意下call文件夹的位置,call文件夹位置放好,里面的代码对应的位置修改。还有就是 uid和targetId,有些要求改,有些不要,代码里我都注释清楚了:
    call文件夹里面有几个按钮,以及两个html,一个是showVideo_win,用来显示视频的,一个是showVideo_frm,用来显示挂断、接听等按钮的
//-------------------------初始化融云页面,这里我就举例为 main.html
data: {
    timer:null,   //循环播放铃声的定时器
},

created:function(){
    this.initRongCloud();  //这个放在created里面,初始化融云
}

methods:{
    initRongCloud:function(){
        var that = this;
        //初始化融云,如果存在 rongToken 的话
        if($api.getStorage('rongToken')){
            //初始化融云
            var rong = api.require('rongCloud2');
            rong.init(function(ret, err) {
                if (ret.status == 'success') {
                } else {
                    api.alert({
                        title: '提示',
                        msg: '聊天服务器连接失败,请重新登录!',
                    }, function(ret, err){
                        func.loginOut();
                    });
                }
            });
            //实时接收新消息
            that.receiveMessage();

            //实时监听融云连接状态
            that.setConnectionStatusListener();

            //连接
            that.connectRongCloud();

        }
    },
    //连接融云
    connectRongCloud: function(){
        var that = this;
        var rong = api.require('rongCloud2');
        rong.connect({
            token : $api.getStorage('rongToken')
        }, function(ret, err) {
            if(ret.status == 'success'){
                //设置视频语音电话监听
                that.setCallListener();
            }
            if (ret.code == '31003') {
                console.log('聊天服务器不可用');
            }else if(ret.code == '31004'){
                api.alert({
                    title: '提示',
                    msg: '错误的令牌(Token),Token 解析失败,请重新向身份认证服务器获取 Token!',
                }, function(ret, err){
                    func.loginOut();
                });
            }else if(ret.code == '31002'){
                console.log('错误的 App Key,或者 App Key 被服务器积极拒绝');
            }else if(ret.code == '33002'){
                console.log('聊天服务端数据库错误');
            }else if(ret.code == '31000'){
                console.log('聊天服务器超时');
            }else if(ret.code == '-10000'){
                //未调用 init 方法进行初始化
                that.initRongCloud();
            }else if(ret.code == '-10002'){
                console.log('聊天服务器connect输入参数错误');
            }else if(ret.code == '-1000'){
                console.log('聊天服务器重复connect');
            }
        });
    },
    ////////////////////////////视频语音 监听/////////////////////////////
    setCallListener:function(){
        var that = this;
        var rong = api.require('rongCloud2');
        //收到来电的事件
        rong.addCallReceiveListener({
            target:'didReceiveCall'
        },function(ret){
            console.log('收到来电的事件:'+JSON.stringify(ret))
            var callId = ret.callSession.callId;
            var uid = ret.callSession.targetId;
            //这里就是进入视频界面,uid、callId在这里不需要更改。callStatus是按钮状态,3表示来电显示。
            func.openWin('showVideo_win','call/showVideo_win.html',{uid:uid,callId:callId,callStatus:3});
            //播放声音
            api.startPlay({
                path: 'widget://html/call/voice.amr'   //声音放在call文件夹里面,如果要改位置,注意这里也要更改
            }, function(ret, err) {
            });
            that.timer = setInterval(function(){
                api.startPlay({
                    path: 'widget://html/call/voice.amr'   //声音放在call文件夹里面,如果要改位置,注意这里也要更改
                }, function(ret, err) {
                });
            },5000)
        });

        //通话已接通的事件
        rong.addCallSessionListener({
            target:'didConnect'
        },function(ret){
            console.log('通话已接通的事件'+JSON.stringify(ret))
            //关闭声音
            api.stopPlay();
            clearInterval(that.timer)
        });

        //对端用户加入了通话的事件
        rong.addCallSessionListener({
            target:'remoteUserDidJoin'
        },function(ret){
            console.log('对端用户加入了通话的事件'+JSON.stringify(ret))
            rong.getCallSession(function(ret) {
                //电话接通执行的代码放在这里,不能放到上面的didConnect里面。
                api.execScript({
                    name: 'showVideo_win',
                    frameName: 'showVideo_frm',
                    script: 'window.rootVue.setCallStatus('+2+');'  //showVideo_win页面也在call文件夹里,这里更改callStatus为2,即接通
                });
                //callerUserId 拨打电话的用户ID
                //selfUserId  自己的ID
                //targetId    对方的ID
                api.execScript({
                    name: 'showVideo_win',
                    script: 'window.rootVue.showVideo("'+ret.selfUserId+'","'+ret.targetId+'");'  //这里的selfUserId和targetId也不要动,就这么写。
                });
                //重新打开showVideo_frm,将按钮的frame提到video的前面来
                api.execScript({
                    name: 'showVideo_win',
                    script: 'openFram();'
                });
            });
            //关闭声音
            api.stopPlay();
            clearInterval(that.timer)
        });
        //对端用户正在振铃的事件
        rong.addCallSessionListener({
            target:'remoteUserDidRing'
        },function(ret){
            console.log('对端用户正在振铃的事件'+JSON.stringify(ret))
        });
        //对端用户切换了媒体类型的事件
        rong.addCallSessionListener({
            target:'remoteUserDidChangeMediaType'
        },function(ret){
            console.log('对端用户切换了媒体类型的事件'+JSON.stringify(ret))
        });
        //对端用户开启或关闭了摄像头的状态的事件
        rong.addCallSessionListener({
            target:'remoteUserDidDisableCamera'
        },function(ret){
            console.log('对端用户开启或关闭了摄像头的状态的事件'+JSON.stringify(ret))
        });
        //通话已结束的事件
        rong.addCallSessionListener({
            target:'didDisconnect'
        },function(ret){
            console.log('通话已结束的事件'+JSON.stringify(ret))
            api.closeWin({
                name: 'showVideo_win'
            });
            clearInterval(that.timer)
        });
        //对端用户挂断
        rong.addCallSessionListener({
            target:'remoteUserDidLeft'
        },function(ret){
            console.log('对端用户挂断'+JSON.stringify(ret))
            api.closeWin({
                name: 'showVideo_win'
            });
            clearInterval(that.timer)
        });
    },
    ////////////////////////////视频语音 监听/////////////////////////////
}

//※※※※※※※这个拨打电话的事件一定要放在main里面,跟监听放一个页面,否则会导致ios监听不到didConnect 和 remoteUserDidJoin 两个事件(研究了两天才发现这个问题的)
function makeCall(targetId){   //这里的targetId,就是接听电话人的ID
    var rong = api.require('rongCloud2');
    rong.isCallEnabled({
        conversationType:'PRIVATE',
        mediaType:'video'
    },function(ret){
        if(ret.enabled){
            var extra = {};
            //设置拨打电话和被拨打电话人的昵称和头像,用来显示在来电提醒和拨打电话界面
            extra.headImg1 = func.session().headImg;  //这是拨打电话的头像,一般从 localStorage 里面读取
            extra.userName1 = func.session().userName;  //这是拨打电话的昵称,一般从 localStorage 里面读取
            extra.headImg3 = headImg2;  //这是接听电话的头像,想办法获取,可以在拨打电话事件执行之前获取到,然后传到这里来
            extra.userName3 = userName2;  /这是接听电话的昵称,想办法获取,可以在拨打电话事件执行之前获取到,然后传到这里来
            rong.startCall({
                targetId:targetId,
                mediaType:'video',
                conversationType: 'PRIVATE',
                extra:JSON.stringify(extra),
                userIdList: [targetId,func.session().userId]  //双方的ID,没有前后顺序之分
            },function(ret){
                var targetId = targetId;
                var uid = func.session().userId;  //这里的uid是自己的id
                var callId = ret.callSession.callId;
                func.openWin('showVideo_win','call/showVideo_win.html',{uid:uid,callId:callId,callStatus:1,targetId:targetId});
            });
        }else{
            func.msg('请在融云后台开通音视频');
        }
    })
}

//-------------------------初始化融云页面,这里我就举例为 main.html  end ---------------------


//-----------------拨打电话界面,很简单,就是点击拨打电话按钮,执行下面的代码即可
api.execScript({
    name: 'main',
    script: 'makeCall("'+targetId+'");'  //这里的targetId,就是接听电话人的ID,
});
//-------------------拨打电话界面 end -------------------
     还有个call文件夹,里面是布局好的页面,拨打电话进入这个界面,直接显示画中画效果的视频。
     点击下载融云视频聊天文件