

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