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

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

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

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

简要介绍用到的次要API:

**startCall   发动音视频通话
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>