从上面看,应该是画中画效果,即大窗口显示对方,小窗口显示自己。
因为是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文件夹,里面是布局好的页面,拨打电话进入这个界面,直接显示画中画效果的视频。
点击下载融云视频聊天文件