APICloud平台使用融云模块实现音视频通话实践经验总结分享

需求概要:实现视频拨打、接听、挂断、视频界面大小窗口、点击小窗口实现大小窗口互换。

实现思路:一方拨打后,另一方要能收到相应事件,然后接听。接通后,渲染对方视频画面。那么己方视频画面什么时候渲染呢?对于呼叫方,可以在呼叫后开始渲染,也可以接通事件事件发生后再开始渲染。对于接通方可以在点击接听按钮后开始渲染,也可以在接通事件发生后开始渲染。

有了上述思路,在模块文档中查找相应api,编写代码,就可以验证我们的思路是否可以实现。如果遇到问题,再调整实现思路。

以下是融云模块文档链接:https://docs.apicloud.com/Cli...

简要介绍用到的主要API:

**startCall   发起视频通话" title="音视频通话">音视频通话
addCallReceiveListener  音视频来电事件监听
accept 接听来电
addCallSessionListener 音视频通话事件的监听(包含响铃、接通、挂断等多个事件监听)setVideoView  设置视频区域
resetVideoView  重设视频区域
removeVideoView  移除视频区域
hangup 挂断**

下面讲解代码。

要调用音视频通话功能前应先调用 api.hasPermission 接口检查是否有麦克风、相机权限,如果没有,要先申请权限。

api.requestPermission({

list: ['microphone', 'camera', 'storage', 'photos'],

code: 1

})

融云初始化成功之后,可添加相应事件的监听。didReceiveCall 接到来电事件后,弹出接听页面。接听后,会执行到 didConnect 事件, 此时可设置本地窗口 setVideoView ;稍后会执行到remoteUserDidJoin (对端用户加入通话事件),此时可以通过 setVideoView 设置对端用户窗口。通过videoViewBringToFront 接口将本地小窗口调整到最前方。

 apiready = function () {

rong = api.require('rongCloud2');

rong.init({

huaweiPush: false

}, function (ret, err) {

if (ret.status == 'error') {

api.toast({

msg: err.code

});

} else {

console.log('初始化成功');

rong.setConnectionStatusListener(function (ret, err) {

console.log("连接状态监听:" + ret.result.connectionStatus);

});

//收到来电事件监听

rong.addCallReceiveListener({

target: 'didReceiveCall'

}, function (ret) {

console.log('didReceiveCall:' + JSON.stringify(ret))

callId = ret.callSession.callId;

api.toast({

msg: '来电请接听'

})

fnopenbtnframe(); //打开接听、挂断按钮所在的frame

});

// 通话连接成功监听

rong.addCallSessionListener({

target: 'didConnect'

}, function (ret) {

console.log('didConnect:' + JSON.stringify(ret))

var myname = api.getPrefs({

sync: true,

key: 'myname'

});

//打开本地窗口

fnsetVideoView(api.winWidth - 200, 100, 160, 200, myname);

//将本地窗口显示到最前方

setTimeout(function () {

rong.videoViewBringToFront({

userId: myname

})

}, 1000)

})

//通话已结束的事件

rong.addCallSessionListener({

target: 'didDisconnect'

}, function (ret) {

console.log('didDisconnect:' + JSON.stringify(ret))

})

//对端用户加入了通话的事件

rong.addCallSessionListener({

target: 'remoteUserDidJoin'

}, function (ret) {

console.log("对端用户加入了通话的事件:" + JSON.stringify(ret));

var uid = ret.userId;

//设置远端窗口

fnsetVideoView(0, 0, api.winWidth, api.winHeight, uid);

});

//监听视频区域点击事件,实现大小窗口切换

rong.addVideoViewListener(function (ret) {

//判断点击的是否是初始小窗口

if (ret.userId == myname && meissmall) {

fnresetVideoView(0, 0, api.winWidth, api.winHeight, ret.userId);

fnresetVideoView(api.winWidth - 200, 100, 160, 200, hename);

meissmall = false;

setTimeout(function () {

rong.videoViewBringToFront({

userId: hename

})

}, 1000)

setTimeout(function () {

fnopenbtnframe()

}, 1200)

}

if (ret.userId == hename && !meissmall) {

fnresetVideoView(0, 0, api.winWidth, api.winHeight, ret.userId);

fnresetVideoView(api.winWidth - 200, 100, 160, 200, myname);

meissmall = true;

setTimeout(function () {

rong.videoViewBringToFront({

userId: myname

})

}, 1000)

setTimeout(function () {

fnopenbtnframe()

}, 1200)

}

})

}

});

};

实现效果如下:

其他经验总结:

返回错误码34001,重启loader可解决,可能换账号登录,wifi 同步重启loader 有缓存用户信息导致。

接听不到来电事件,可尝试用4g 网络测试。有些公司防火墙,或者电脑共享的wifi 热点网络有限制或不稳定。

以上经验都是无数次排错总结出来的,看了至少能帮你节省两个工作日。

最后贴下完整代码:

<!DOCTYPE HTML>

<html>

<head>

<meta charset="utf-8">

<meta name="viewport"

content="maximum-scale=2.0,minimum-scale=1.0,user-scalable=1,width=device-width,initial-scale=1.0" />

<meta name="format-detection" content="telephone=no,email=no,date=no,address=no">

<title>Hello APP</title>

<link rel="stylesheet" type="text/css" href="../css/api.css" />

<script src="../script/sha1.js"></script>

<style>

body {

margin-top: 90px;

}

button {

padding: 10px

}

</style>

</head>

<body id="bd">

<button onclick="fnrequestPermission()">fnrequestPermission</button>

<input id="useName" placeholder="输入用户名" style="display: block" />

<div id="stauseName" style="display: none">

**用户已登录

</div>

<input id="fridendName" placeholder="输入好友用户名" style="" />

<br>

<button onclick="login()">

登录

</button>

<br>

<button onclick="fnstartCall()">

fnstartCall

</button>

<br>

<br><br>

<p>

<ul>

<li>1. 测试步骤</li>

<li>2. 准备两部手机A和B</li>

<li>3. A手机在【输入用户名】【输入好友用户名】处分别输入a, b;然后点登录</li>

<li>4. B手机在【输入用户名】【输入好友用户名】处分别输入b, a;然后点登录</li>

<li>5. 一部手机点fnstartCall</li>

<li>6. 另一部手机在弹出‘来电请接听提示后’,会弹出底部按钮frame,点击【接听】</li>

<li>7. 接通后,弹出大小视频窗口。点击小窗口可实现切换。</li>

</ul>

</p>

</body>

<script type="text/javascript" src="../script/api.js"></script>

<script type="text/javascript">

var rong;

var myname = '';

var hename = '';

var meissmall = true;

function fnrequestPermission() {

api.requestPermission({

list: ['microphone', 'camera', 'storage', 'photos'],

code: 1

})

}

apiready = function () {

rong = api.require('rongCloud2');

rong.init({

huaweiPush: false

}, function (ret, err) {

if (ret.status == 'error') {

api.toast({

msg: err.code

});

} else {

console.log('初始化成功');

rong.setConnectionStatusListener(function (ret, err) {

alert("setConnectionStatusListener::::::" + ret.result.connectionStatus);

});

rong.addCallReceiveListener({

target: 'didReceiveCall'

}, function (ret) {

console.log('didReceiveCall:' + JSON.stringify(ret))

callId = ret.callSession.callId;

api.toast({

msg: '来电请接听'

})

fnopenbtnframe();

});

rong.addCallSessionListener({

target: 'didConnect'

}, function (ret) {

console.log('didConnect:' + JSON.stringify(ret))

var myname = api.getPrefs({

sync: true,

key: 'myname'

});

//打开本地窗口

fnsetVideoView(api.winWidth - 200, 100, 160, 200, myname);

setTimeout(function () {

rong.videoViewBringToFront({

userId: myname

})

}, 1000)

})

rong.addCallSessionListener({

target: 'didDisconnect'

}, function (ret) {

console.log('didDisconnect:' + JSON.stringify(ret))

})

rong.addCallSessionListener({

target: 'remoteUserDidJoin'

}, function (ret) {

console.log("对端用户加入了通话的事件:" + JSON.stringify(ret));

var uid = ret.userId;

fnsetVideoView(0, 0, api.winWidth, api.winHeight, uid);

});

rong.addVideoViewListener(function (ret) {

//判断点击的是否是初始小窗口

if (ret.userId == myname && meissmall) {

fnresetVideoView(0, 0, api.winWidth, api.winHeight, ret.userId);

fnresetVideoView(api.winWidth - 200, 100, 160, 200, hename);

meissmall = false;

setTimeout(function () {

rong.videoViewBringToFront({

userId: hename

})

}, 1000)

setTimeout(function () {

fnopenbtnframe()

}, 1200)

}

if (ret.userId == hename && !meissmall) {

fnresetVideoView(0, 0, api.winWidth, api.winHeight, ret.userId);

fnresetVideoView(api.winWidth - 200, 100, 160, 200, myname);

meissmall = true;

setTimeout(function () {

rong.videoViewBringToFront({

userId: myname

})

}, 1000)

setTimeout(function () {

fnopenbtnframe()

}, 1200)

}

})

}

});

};

//打开视频区域

function fnsetVideoView(x, y, w, h, uid) {

rong.setVideoView({

rect: {

x: x,

y: y,

w: w,

h: h

},

userId: uid,

bg: '#ff0000',

renderModel: 'fit',

fixedOn: '',

fixed: false

});

}

function fnresetVideoView(x, y, w, h, uid) {

rong.resetVideoView({

rect: {

x: x,

y: y,

w: w,

h: h

},

userId: uid,

bg: '#ff0000',

renderModel: 'fit'

});

}

//移除视频区域

function fnremoveVideoView(ruid) {

rong.removeVideoView({

userId: ruid

});

}

function fnstartCall() {

myname = api.getPrefs({

sync: true,

key: 'myname'

});

hename = api.getPrefs({

sync: true,

key: 'hename'

});

rong.startCall({

targetId: hename,

mediaType: 'video',

conversationType: 'PRIVATE',

userIdList: [hename]

}, function (ret) {

console.log('startCall:' + JSON.stringify(ret))

callId = ret.callSession.callId;

});

fnopenbtnframe();

}

//打开按钮页面

function fnopenbtnframe() {

api.openFrame({

name: 'btframe',

url: 'button.html',

rect: {

marginLeft: 0,

marginBottom: 0,

h: 100,

w: 'auto'

}

})

}

function fnaccept() {

//同步返回结果:

myname = api.getPrefs({

sync: true,

key: 'myname'

});

hename = api.getPrefs({

sync: true,

key: 'hename'

});

rong.accept({

mediaType: 'video',

callId: callId

});

}

function fnhangup() {

rong.hangup();

fnremoveVideoView(hename);

fnremoveVideoView(myname);

api.closeFrame({

name: 'btframe'

})

}

function fngetCallSession() {

rong.getCallSession(function (ret) {

api.alert({

msg: JSON.stringify(ret)

});

});

}

//请求token

function login() {

var now = new Date();

var number = now.getSeconds();

//这将产生一个基于目前时间的0到59的整数。

var timestamp = Date.parse(new Date());

timestamp = timestamp / 1000;

var AppKey = "pwe86ga5p****"; //填写自己的参数

var appSecret = "Eo1hnmggH****"; //填写自己的参数

var Nonce = number;

var Timestamp = timestamp;

var Signature = SHA1(appSecret + Nonce + Timestamp);

var uid = document.getElementById('useName').value;

var uid2 = document.getElementById('fridendName').value;

api.setPrefs({

key: 'myname',

value: uid

})

api.setPrefs({

key: 'hename',

value: uid2

})

api.ajax({

url: 'http://api.cn.ronghub.com/user/getToken.json',

method: 'post',

headers: {

"Content-Type": "Application/x-www-form-urlencoded",

"App-Key": AppKey,

"Nonce": Nonce,

"Timestamp": Timestamp,

"Signature": Signature

},

data: {

'values': {

userId: uid,

name: uid,

}

}

}, function (ret, err) {

if (ret) {

token = ret.token;

connect();

var labelUsename = document.getElementById('stauseName');

labelUsename.style.display = "block";

labelUsename.innerHTML = uid + "已登录";

} else {

api.alert({

msg: JSON.stringify(err)

});

}

})

}

function logout() {

rong.logout(function (ret, err) {

console.log(JSON.stringify(ret));

if (ret.status == 'error')

api.toast({

msg: err.code

});

});

}

function connect() {

rong.connect({

token: token

}, function (ret, err) {

if (ret.status == 'success') {

console.log(ret.result.userId);

} else {

console.log(err.code)

}

});

}

function getConnectionStatus() {

rong.getConnectionStatus(function (ret, err) {

api.toast({

msg: ret.result.connectionStatus

});

})

}

</script>

</html>

以上是 APICloud平台使用融云模块实现音视频通话实践经验总结分享 的全部内容, 来源链接: utcz.com/z/267580.html

回到顶部