两人聊天视频通话

适用场景:手机端两人聊天中进行视频通话

 

主要过程:

前提:会使用到三个弹窗 view :呼叫弹窗(弹窗 1 )、来电弹窗(弹窗 2 )、视频通话中弹窗(弹窗 3

1 )视频通话前:

我方:点击视频通话,弹出呼叫弹窗,并通知对方。对方:接收到信号弹出来电弹窗,选择同意 / 拒绝。

2 )视频通话中:

我方:接收到对方同意的信号,切换视频通话中的弹窗,进行视频通话 ; 若对方拒绝,则关闭当前弹窗。对方:若同意则切换视频通话中的弹窗,若拒绝则关闭当前弹窗。

3 )结束视频通话:

我方点击结束通话:我方:关闭当前弹窗。对方:接收到信号也关闭当前弹窗。

对方点击结束通话:对方:关闭当前弹窗。我方:接收到信号也关闭当前弹窗。

4 )根据不同的操作过程生成不同的通话记录,例如:“对方已拒绝”、“已取消”、“通话时长 02:33” 等。

 

具体操作如下:(本地不能测试,要发布到外网上测试)

一、页面层的位置上端对端实时通信元素( peer )的操作:如下图所示:

 

 

友情链接: peer 元素使用手册: http://www.wware.org/wide/setup.html#?content=/v/wide/setup/element/peer.html

设置peer元素:点击peer元素设置呼叫类型(音频/视频).选择视频就要填写视频上的对应id值,下图所示;选择音频就应在源码格式下在peer元素上添加 data-remoteaudioid="xx",xx为对应音频播放器的id;

 

操作:

1.在peer元素上添加属性绑定:{"data-x-wid":dataxwid,"data--call-control":datacallcontrol,"data--call-wid":datacallwid,"data-x-localurl":dataxlocalurl,"data-x-remoteurl":dataxremoteurl} ,并给变量初始化变量初始化:{"dataxlocalurl":"","dataxremoteurl":"","datavsrclocal":"","datavsrcremote":"","dataxwid":"","datacallwid":"","datacallcontrol":"","kaishi":""}。如下图所示(相关参数含义可参考元素手册):

 

 

在层上添加权限检查元素(获取摄像头和录音的权限):如下图所示

 

 

 

2. 逻辑操作:

(1)在元素上添加绑定数据编程:选择其他事件: peercalled.video ,添加绑定数据编程:

_vm.laidian0(true); //当收到呼叫请求的时候,打开来电弹窗,及弹窗2

如下图所示:

 

 

 

 

(2)在peer元素上添加绑定数据编程:选择其他事件:peerconnect.video ,添加绑定数据编程:

//将用户当前的视频流赋给弹窗3中的视频播放器绑定的变量(我方视频播放器窗口)

_vm.datavsrclocal(_vm.dataxlocalurl());

 

//将对方传回来的视频流赋给弹窗3中的视频播放器绑定的变量(对方视频播放器窗口)

_vm.datavsrcremote(_vm.dataxremoteurl());

 

//将对方传回来的音频流赋给弹窗3中的音频播放器绑定的变量(音频播放器窗口)

//_vm.datasrc(_vm.dataxremoteurl());_vm.dataplay("play");

var ms=new Date().getTime();

_vm.kaishi(ms);

 

_vm.huchu0(false); //关闭呼出弹窗,即弹窗

_vm.tonghua0(true ); //开启通话中的弹窗,即弹窗

 

 

如下图所示:

 

 

 

 

(3)在元素上添加绑定数据编程:选择其他事件:peerclose.video ,添加绑定数据编程:

_vm.tonghua0(false); //当连接关闭的时候,关闭通话中的弹窗,即弹窗3

_vm.laidian0(false); //当连接关闭的时候,关闭来电弹窗,即弹窗2

_vm.huchu0(false); //当连接关闭的时候,关闭来电弹窗,即弹窗1

 

如下图所示:

 

 

 

 

(4)在 peer元素上添加绑定数据编程:选择其他事件: peercalling.video ,添加绑定数据编程:

 

_vm.datacallcontrol("waiting"); //当发起呼叫的时候,将peer元素应答状态改为waiting状态,即呼叫等待中,解决第二次主动发起呼叫主叫方不能挂断问题,如下图所示

 

 

 

 

(5)在peer元素上添加提交数据:选择其他事件:peerinit ,额外逻辑:提交数据,并填写相应视口和参数。如下图所示:

 

 

参数说明:

 

 

dataxwid peer 元素绑定的自定义变量,表示: 当前用户的 websocketID

 

视口处理内容:将获取到的当前用户的 websocketID(dataxwid)存入数据可以用户表的某个字段(用于对方获取我方的dataxwid,才能建立上连接)(具体代码省略)

 

 

二、页面点击视频图标进行的操作:如下图所示:

 

 

 

 

(1)在视频图标上添加提交数据,如下图所示:

 

 

 

视口传入参数说明:kfid :自定义变量,聊天对话中,对方的用户表的_id

视口说明:用来获取到对方的 websocketID(之前已经存入到用户表的某一个字段,可直接查询获取),返回参数中返回如下:即返回对方websocketID值,调整peer元素状态,并将呼出弹窗弹出

function() {

_.extend(finish_data, {

"success": true,

"_runCommand": [{

"command": "updatelv",

"wid": tmp_data.wid, // 对方的 websocketID

"datacallwid":tmp_data.wid, // 对方的 websocketID

"datacallcontrol":"waiting", // 将 peer 元素上绑定的用于控制状态的变量变为等待状态(“ waiting” )

"huchu0":"show" // 弹出呼出弹窗,即弹窗 1

}]

}]

});

},

 

 

 

三、 3 个弹窗的操作:弹窗如下图所示:

呼出弹窗,即弹窗 1

 

 

来电弹窗,即弹窗 2

 

 

通话弹窗,即弹窗 3

 

 

 

1 )弹窗 1 具体操作:

1 )在静音图标处添加绑定数据编程:

if (_vm.datacallcontrol() === "mute") { // 当为静音的时候

_vm.datacallcontrol(""); // 不静音

} else {

_vm.datacallcontrol("mute"); // 否则开启静音

}

如下图所示:

 

 

 

 

 

2 )在右侧取消图标处添加绑定数据编程:

_vm.datacallcontrol("cancel"); // 将控制变量改为取消状态(“ cancel”

_vm.huchu0(false); // 关闭呼出弹窗,即弹窗 1

如下图所示:

 

 

 

 

2 )弹窗 2 具体操作:

1 )显示来电对方的信息,如示例图中的 kiss2 (来电对方的昵称),即绑定变量进行显示,

获取方式在页面读取视口中返回即可(因为是两人聊天,对方昵称可以得到),绑定见下图:

 

 

2 )在取消图标处添加提交数据(由于需要创建数据记录,所以此处不使用绑定数据编程的方式):如下图所示:

 

 

参数说明:

kfid :自定义变量,对方的用户表的 _id

视口操作说明:

1 》添加数据库相关操作,此处略(按自己项目需求自己添加)

2 》以上逻辑添加完成之后,添加”发送通知消息“代码段,类似如下:

/*INSBEGIN:WSNOTIFY*/

function() {

return reqlib('msgbroker');

},

function(msgbroker) {

function _2Date(value, format) {

try {

if (format) {

return moment.utc(value)

.format(format);

} else {

return moment.utc(value)

.format();

}

} catch (e) {

return value;

}

}

var domain = req.wwdomain();

var uid = inputs.kfid;

var msg = {

"command": "MESSAGE",

"headers": {

"random": Math.random(),

"subscription": "sub-0"

},

"body": ""

};

msg.headers._runCommand = JSON.stringify([{

"command": "vmArrFuc",

"params": ["push", "chattable", {

"headpic": tmp_data.user.headpic,

"nickname": tmp_data.user.nickname,

"chattable7theuserid": inputs.kfid, // 所属用户 id

"chattable7senderid": tmp_data.uid, // 发送人 id

"chattable7recipienti": inputs.kfid, // 接收人 id

"chattable7messagecon": " 对方已拒绝 ",

"chattable7sendingtim": _2Date(),

"chattable7messagetyp": " 视频 ",

"chattable7speechdura": 0,

"chattable7voice": ""

}]

}]);

 

return msgbroker.notifyuser(domain, uid, msg);

 

 

},

//@wweditorinfo:{"id":"a189fffd8eceaebf0c6c516cba3d15c0","editor":{"step1":false,"stepUser":{"domain":{"from":"const","value":"kefu7zxkfb"},"uid":{"from":"tmp_data","value":"0000"},"msg":{"from":"inputs","value":"kefu7zxkfb7ltnr"},"isFilter":false}}}

/*INSEND:WSNOTIFY*/

 

3 》最后添加输出代码段:类似如下:

 

/*INSBEGIN:STDOUT*/

function() {

_.extend(finish_data, {

"success": true,

"_runCommand": [{

"command": "updatelv",

"params": [{

"laidian0": "", // 关闭来电弹窗,即弹窗 2

"datacallcontrol": "reject" // 将控制状态改为拒绝(” reject“

}]

}, {

"command": "vmArrFuc",

"params": ["push", "chattable", { // 尾部追加我方消息记录

"headpic": tmp_data.user.headpic,

"nickname": tmp_data.user.nickname,

"chattable7theuserid": tmp_data.uid, // 所属用户 id

"chattable7senderid": tmp_data.uid, // 发送人 id

"chattable7recipienti": inputs.kfid, // 接收人 id

"chattable7messagecon": " 已取消 ",

"chattable7sendingtim": moment()

.utc()

.format(),

"chattable7messagetyp": " 视频 ",

"chattable7speechdura": 0,

"chattable7voice": ""

}]

}]

});

},

//@wweditorinfo:{"id":"cf760ed9cbd5d5e99d047f3b7ac9dad0","editor":{"jsonValue":{"success":true,"_runCommand":[{"command":"updatelv","params":[{"a":"newValue"}]},{"command":"vmArrFuc","params":["push"," 数组变量名 ",{" 属性名 1":" 属性值 1"},{" 属性名 2":" 属性值 2"}]}]},"steppurpose":{"purpose":"finishdata"}}}

/*INSEND:STDOUT*/

 

 

3 )在接受图标处添加绑定数据编程:

_vm.datacallcontrol("accept"); // 将控制状态改为接受(“ accept”

_vm.laidian0(""); // 关闭来电弹窗,即弹窗 2

_vm.tonghua0(true); // 打开通话中的弹窗,即弹窗 3

如下图所示:

 

 

 

3 )弹窗 3 具体操作:

1) 添加音频播放器或视频播放器:

添加音频播放器,如下图所示,直接添加音频播放器并设置id,添加属性{"data--play":dataplay,"data--src":datasrc},并给变量初始化变量初始化{"dataplay":"pause","datasrc":""}

 

 添加两个视频播放器,分别直接添加一个p标签,在p标签内添加一个video标签,在video标签上设置id和属性 {"src":remotevideo}或 {"src":localvideo} ,具体如下图所示

 

3 )在静音图标处添加绑定数据编程:

if (_vm.datacallcontrol() === "mute") { // 当控制状态为静音的时候(“ mute”

_vm.datacallcontrol(""); // 取消静音

} else {

_vm.datacallcontrol("mute"); // 否则开启静音

}

如下图所示:

 

 

 

4 )在取消图标处,添加提交数据,如下图所示:

 

 

 

 

参数说明:

kfid :自定义变量,对方的用户表的 _id

kaishi :自定义变量,开始视频的时间

视口说明:

1 》其他对数据库的操作逻辑省略,根据项目需求而定 ;

2 》上述逻辑之后加上“发送通知消息”代码段:示例如下:

/*INSBEGIN:WSNOTIFY*/

function() {

return reqlib('msgbroker');

},

function(msgbroker) {

function _2Date(value, format) {

try {

if (format) {

return moment.utc(value)

.format(format);

} else {

return moment.utc(value)

.format();

}

} catch (e) {

return value;

}

}

var domain = req.wwdomain();

var uid = inputs.kfid;

var msg = {

"command": "MESSAGE",

"headers": {

"random": Math.random(),

"subscription": "sub-0"

},

"body": ""

};

msg.headers._runCommand = JSON.stringify([{

"command": "vmArrFuc",

"params": ["push", "chattable", {

"headpic": tmp_data.user.headpic,

"nickname": tmp_data.user.nickname,

"chattable7theuserid": inputs.kfid, // 所属用户 id

"chattable7senderid": tmp_data.uid, // 发送人 id

"chattable7recipienti": inputs.kfid, // 接收人 id

"chattable7messagecon": tmp_data.neirong,

"chattable7sendingtim": _2Date(),

"chattable7messagetyp": " 视频 ",

"chattable7speechdura": 0,

"chattable7voice": "",

"you":"off",

"zuo":"off"

}]

}]);

 

return msgbroker.notifyuser(domain, uid, msg);

 

 

},

//@wweditorinfo:{"id":"a189fffd8eceaebf0c6c516cba3d15c0","editor":{"step1":false,"stepUser":{"domain":{"from":"const","value":"kefu7zxkfb"},"uid":{"from":"tmp_data","value":"0000"},"msg":{"from":"inputs","value":"kefu7zxkfb7ltnr"},"isFilter":false}}}

/*INSEND:WSNOTIFY*/

 

 

3 》最后添加返回数据代码段:示例如下:

/*INSBEGIN:STDOUT*/

function() {

_.extend(finish_data, {

"success": true,

"_runCommand": [{

"command": "updatelv",

"params": [{

"tonghua0": "", // 关闭视频通话中的弹窗,即弹窗 3

"datacallcontrol": "hangup" // 使视频状态改为挂断状态(“ hangup”

}]

}, {

"command": "vmArrFuc",

"params": ["push", "chattable", { // 在当前聊天记录中尾部追加一条记录

"headpic": tmp_data.user.headpic,

"nickname": tmp_data.user.nickname,

"chattable7theuserid": tmp_data.uid, // 所属用户 id

"chattable7senderid": tmp_data.uid, // 发送人 id

"chattable7recipienti": inputs.kfid, // 接收人 id

"chattable7messagecon": tmp_data.neirong,

"chattable7sendingtim": moment()

.utc()

.format(),

"chattable7messagetyp": " 视频 ",

"chattable7speechdura": 0,

"chattable7voice": "",

"you":"off",

"zuo":"off"

}]

}]

});

},

//@wweditorinfo:{"id":"cf760ed9cbd5d5e99d047f3b7ac9dad0","editor":{"jsonValue":{"success":true,"_runCommand":[{"command":"updatelv","params":[{"a":"newValue"}]},{"command":"vmArrFuc","params":["push"," 数组变量名 ",{" 属性名 1":" 属性值 1"},{" 属性名 2":" 属性值 2"}]}]},"steppurpose":{"purpose":"finishdata"}}}

/*INSEND:STDOUT*/

 

 

最后关于测试,需要注意:

安卓手机之间、 ios 手机之间、安卓与 ios 手机之间的测试,需要找网管进行相应的配置才可进行,否则可能测试不通。

语音聊天测试汇总

行:接收方;列:发起方安卓版app安卓版微信浏览器IOSappIOS微信浏览器PC
安卓版app1. 语音通话:互相通话无问题.1. 语音通话:安卓版app主叫安卓微信浏览器通话无问题.由于IOSapp暂时没有麦克风权限,无法测试1. 语音通话:安卓版app主叫IOS微信浏览器有问题,被叫方点击接听时,被叫方会由“收到呼叫请求”直接进入“连接关闭”状态,主叫方由“接收到信号”状态等待30秒后自动进入“连接关闭”状态.1. 语音通话:安卓版app主叫PC浏览器通话无问题.
安卓版微信浏览器1. 语音通话:安卓微信浏览器主叫安卓版app有问题,被叫方点击接听时,主叫方会直接进入“连接关闭”状态,被叫方由“接收到信号”状态等待30秒后自动进入“连接关闭”状态.1. 语音通话:互相通话无问题由于IOSapp暂时没有麦克风权限,无法测试1. 语音通话: 安卓版微信浏览器主叫IOS微信浏览器有问题,被叫方点击接听时,被叫方会由“收到呼叫请求”直接进入“连接关闭”状态,主叫方由“接收到信号”状态等待30秒后自动进入“连接关闭”状态.之后主叫方重新呼叫,被叫方无反应(需要双方页面刷新后,被叫方才会有“收到呼叫请求”反应).1. 语音通话:安卓版微信浏览器主叫PC浏览器 通话无问题.
IOSapp由于IOSapp暂时没有麦克风权限,无法测试由于IOSapp暂时没有麦克风权限,无法测试由于IOSapp暂时没有麦克风权限,无法测试由于IOSapp暂时没有麦克风权限,无法测试由于IOSapp暂时没有麦克风权限,无法测试
IOS微信浏览器1. 语音通话:IOS微信浏览器主叫安卓版app有问题,主叫方点击立即通话后,主叫方会直接进入“连接关闭”状态,被叫方无反应1. 语音通话:IOS微信浏览器主叫安卓版微信浏览器有问题,主叫方点击立即通话后,主叫方会直接进入“连接关闭”状态,被叫方无反应由于IOSapp暂时没有麦克风权限,无法测试1. 语音通话:IOS微信浏览器主叫IOS微信浏览器有问题,主叫方点击立即通话后,主叫方会直接进入“连接关闭”状态,被叫方无反应1. 语音通话:IOS微信浏览器主叫PC浏览器有问题,主叫方点击立即通话后,主叫方会直接进入“连接关闭”状态,被叫方无反应
PC1. 语音通话:PC浏览器主叫安卓版app有问题,被叫方点击接听时,主叫方会直接进入“连接关闭”状态,被叫方由“接收到信号”状态等待30秒后自动进入“连接关闭”状态.1. 语音通话:PC浏览器主叫安卓版微信浏览器通话无问题.由于IOSapp暂时没有麦克风权限,无法测试1. 语音通话:PC浏览器主叫IOS微信浏览器有问题,被叫方点击接听时,被叫方会由“收到呼叫请求”直接进入“连接关闭”状态,主叫方由“接收到信号”状态等待30秒后自动进入“连接关闭”状态.1. 语音通话:互相通话无问题.