uniapp中接入融云-IM 云服务

如何选择 IM 云服务供应商?主要看这三个因素:价格、核心服务稳定、技术资料及时的客服咨询。
之前集成过anyrtc,大家可以翻翻之前记录,主要是音视频通话服务,我发现,市场上众多的 IM 云服务,anyrtc 和融云 技术实现上很相似,视频通话服务技术对接也简单, 从长远看,收费服务意味着很大的风险,稳定好服务, 满足预期才能深入人心。

注册账户

首先前往官网注册:https://developer.rongcloud.cn/signup#?_sasdk=fMjUzMDkz

登陆成功后会有一个已经设置好的 appkey, 左侧菜单拉到最下方 【音视频通话】开启免费额度1万分钟,uniapp打包后一直使用这个开发appkey也是有1万分钟的额度。


项目配置

项目开发

  • app.vue
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
import * as call from "@/uni_modules/RongCloud-CallWrapper/lib/index";
import RCIMIWEngine from "@/uni_modules/RongCloud-IMWrapper-V2/js_sdk/RCIMEngine";
import permision from "@/js_sdk/wa-permission/permission.js";

// 应用唤醒后开始注册、连接im
onLaunch: function () {
// #ifdef APP-PLUS
this.init();
// 监听用户登录后回调
uni.$on("loginSuccess", (usnerinfo) => {
this.connectIM(usnerinfo);
});
// #endif
},
methods:{
init() {
call.onCallReceived((res) => {
console.log(
"Engine:OnCallReceived=>" + "监听通话呼入, 目标id=>",
res.data.targetId
);
// 接收到邀请呼叫 跳转呼叫页面
uni.navigateTo({
url: "/pages/room/call" + "?id=" + res.data.targetId,
});

this.localSession = res.data;
});
call.onCallDisconnected((res) => {
console.log(
"Engine:OnCallDisconnected=>" + "通话挂断/拒绝, 挂断原因=>",
res.data.reason
);

uni.navigateBack({
delta: 1,
});
// 重新渲染视频视图
uni.$emit("OnCallDisconnected");
});
call.onError((res) => {
console.log("通话过程中,发生异常");
});
call.onRemoteUserInvited((res) => {
console.log(
"Engine:OnRemoteUserInvited=>" +
"通话中的某一个参与者,邀请好友加入通话 ,远端Id为=>",
res.data.userId
);
uni.$emit("OnCallConnected");
});
call.onRemoteUserJoined((res) => {
console.log(
"Engine:OnRemoteUserJoined=>" +
"主叫端拨出电话,被叫端收到请求后,加入通话,对端Id为=>",
res.data.userId
);
uni.$emit("OnCallConnected");
});
},
//连接IM
async connectIM(userInfo) {
if (!userInfo.appKey || !userInfo.token) return;

this.imEngine = await RCIMIWEngine.create(userInfo.appKey, {});
this.imEngine.setOnConnectedListener((res) => {
if (res.code != 0) {
return;
}
//连接成功
call.init({});
if (uni.getSystemInfoSync().platform === "android") {
permision.requestAndroidPermission("android.permission.CAMERA");
permision.requestAndroidPermission("android.permission.RECORD_AUDIO");
}
});
let code = await this.imEngine.connect(userInfo.token, 10);
if (code != 0) {
uni.showToast({
title: "connect:" + code,
icon: "error",
});
} else {
uni.showToast({
title: "连接IM成功",
icon: "none",
duration: 2000,
});
}
},
}
  • pages.json
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
{
"path" : "pages/room/call",
"style" :
{
"navigationBarTitleText": "呼叫",
"enablePullDownRefresh": false,
"navigationStyle":"custom",
"gestureBack":"NO",
"app-plus" : {
"background":"white"
}
}
},
{
"path" : "pages/room/room",
"style" :
{
"navigationBarTitleText": "Room",
"enablePullDownRefresh": false,
"navigationStyle":"custom",
"gestureBack":"NO"
}
},
  • call.nvue 呼叫页面

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    <template>
    <view class="content">
    <view class="logo">
    <image class="logo-img" src="../../static/icon-ch.png" mode=""></image>
    <text class="name">{{ id }} </text>
    </view>


    <view class="container">
    <view class="icon" @click="hangup">
    <image
    class="icon_img"
    src="../../static/icon_hangup.png"
    mode=""
    ></image>

    <text class="icon_text">挂断 </text>
    </view>

    <view class="icon" @click="accept">
    <image
    class="icon_img"
    src="../../static/icon_accept.png"
    mode=""
    ></image>

    <text class="icon_text">接听 </text>
    </view>
    </view>
    </view>
    </template>

    <script>
    import * as call from "@/uni_modules/RongCloud-CallWrapper/lib/index";
    import RCBeautyEngine from "@/uni_modules/RongCloud-BeautyWrapper/lib/RCBeautyEngine";
    export default {
    data() {
    return {
    id: "",
    };
    },
    onLoad: function (option) {
    this.id = option.id;
    },
    methods: {
    hangup() {
    call.hangup();
    uni.navigateBack({
    delta: 1,
    });
    },
    accept() {
    let session = call.getCurrentCallSession();
    console.log('session: ', session);
    uni.setStorageSync('room-parameters', {
    callType: 'in',
    mediaType: session.mediaType === 0 ? 'audio' : 'video'
    });
    // 接受呼叫后跳转聊天页面
    uni.navigateTo({
    url: "/pages/room/room",
    });
    },
    },
    };
    </script>

  • room.nvue 聊天页面

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    <template>
    <view class="content">
    <!-- 单人视频 -->
    <view>
    <RongCloud-Call-RCUniCallView
    class="bigVideoView"
    :style="{ width: windowWidth + 'px', height: windowHeight + 'px' }"
    ref="bigVideoView"
    >
    </RongCloud-Call-RCUniCallView>
    <RongCloud-Call-RCUniCallView
    class="smallVideoView"
    :style="{ width: 200 + 'upx', height: 200 + 'upx' }"
    ref="smallVideoView"
    >
    </RongCloud-Call-RCUniCallView>
    </view>

    <view class="container">
    <text class="hangup" @click="hangup">挂断</text>
    </view>
    </view>
    </template>
    <script>
    import * as call from "@/uni_modules/RongCloud-CallWrapper/lib/index";
    import RCBeautyEngine from "@/uni_modules/RongCloud-BeautyWrapper/lib/RCBeautyEngine";
    export default {
    data() {
    return {
    mediaType: "video",
    callType: "out",
    callWay: 0, //呼叫方式 0 单聊 1 群聊
    targetId: "",
    isConnected: false,
    isSelf: false,
    viewArr: [],
    groupId: "",
    userIds: [],
    windowWidth: "",
    windowHeight: "",
    users: [],
    currentCallSession: {},
    };
    },
    onLoad: function () {
    var _this = this;
    uni.getStorage({
    key: "room-parameters",
    success: (res) => {
    this.mediaType = res.data.mediaType;
    this.callType = res.data.callType ? res.data.callType : "in";
    this.groupId = res.data.groupId ? res.data.groupId : "";
    this.userIds = res.data.userIds ? res.data.userIds : "";
    if (this.callType === "in") {
    console.log("呼入接受");
    this.accept();
    }
    },
    });
    uni.getSystemInfo({
    success: function (res) {
    _this.windowWidth = res.windowWidth;
    _this.windowHeight = res.windowHeight;
    },
    });
    uni.$on("OnCallConnected", this.onCallConnected);
    uni.$on("OnCallDisconnected", this.onCallDisconnected);
    },
    beforeDestroy() {
    uni.$off("OnCallDisconnected");
    uni.$off("OnCallConnected");
    },
    onUnload() {
    // call.hangup();
    },
    onHide() {
    // const session = call.getCurrentCallSession();
    // if (session) {
    // call.hangup();
    // }
    },
    methods: {
    hangup() {
    this.isSelf = true;
    call.hangup();
    uni.navigateBack({
    delta: 1,
    });
    },
    accept() {
    call.accept();
    },
    onCallConnected() {
    let context = this;
    console.log("oncallconnected接收了");
    call.enableSpeaker(true);
    this.currentCallSession = call.getCurrentCallSession();
    this.callWay = this.currentCallSession.callType;
    this.users = this.currentCallSession.users
    ? this.currentCallSession.users
    : [];
    let isHasMine = this.users.findIndex((item) => {
    return item.userId === this.currentCallSession.mine.userId;
    });
    if (isHasMine === -1) {
    this.users.push(this.currentCallSession.mine);
    }
    if (
    this.currentCallSession &&
    this.currentCallSession.users.length > 0
    ) {
    //视频是两个的时候
    if (this.currentCallSession.users.length <= 2) {
    setTimeout(() => {
    this.systemInfoSync(
    this.currentCallSession.mine.userId,
    this.$refs.smallVideoView.ref,
    true
    );
    this.viewArr = this.currentCallSession.users.filter((item) => {
    return item.userId !== this.currentCallSession.mine.userId;
    });
    this.viewArr.forEach((itm) => {
    this.targetId = itm.userId;
    this.systemInfoSync(
    itm.userId,
    this.$refs.bigVideoView.ref,
    false
    );
    });
    }, 100);
    }
    }
    },
    systemInfoSync(userId, ref, isZOrderOnTop) {
    switch (uni.getSystemInfoSync().platform) {
    case "android":
    call.setVideoView(userId, ref, 0, isZOrderOnTop);
    break;
    case "ios":
    call.setVideoView(userId, ref, 0);
    break;
    default:
    console.log("运行在开发者工具上");
    break;
    }
    },
    onCallDisconnected() {
    if (!this.isSelf) {
    uni.navigateBack({
    delta: 1,
    });
    }
    },
    },
    };
    </script>

结果


融云特点

  • 上手友好

  • 收费高


  • 技术咨询

    提交工单几乎是 1个小时网页回复

如何制作数据可视化大屏的城市地图 Uniapp如何实现持续定位,全程录音功能

Your browser is out-of-date!

Update your browser to view this website correctly. Update my browser now

×