更新记录
2.4.1(2026-07-20) 下载此版本
- 修复从插件市场导入后运行报
agora-player组件路径错误:pages_init.json中usingComponents路径改为以/开头,避免微信解析为相对页面目录
- 修复网络恢复后
danger级网络提示条需等待定时器才消失的问题 - 修复 demo 首页输入框在跨设备粘贴/第三方输入法场景下不同步的问题
- 插件目录与 ID 统一为
em-callkit-weixin(≤20 字符,符合 DCloud 规范) - 插件类型调整为前端模板,readme 与 package.json 增加 DCloud 插件市场链接
2.4.0(2026-07-20) 下载此版本
- 新增群组多人音视频通话:
- 主叫
inviteGroupCall/ 通话中inviteMoreParticipants追加邀请 - 被叫待接听页(群名、主叫方、被邀请成员,同意后才会加入)
- 视频模式自适应网格布局(1 全屏 / 2 上下 / 3 一大两小 / 4 宫格 / 6 宫格 / 9 宫格,末行居中),本地与远端等权瓦片
- 远端可见视频限 4 路,超出降级头像瓦片 + 隐藏 player 保活音频
- 语音模式 3 列头像网格,等待中成员半透明展示
- 新增
useGroupCallState群聊状态 Store
- 主叫
- 群聊通话页内置「邀请」入口:底部半屏成员多选面板(已在通话成员自动置灰),新增
getGroupMembers数据源选项 - 通话中新邀请的成员通过
participantStateChanged即时以等待态上屏 callState新增localUserId,昵称展示链统一为userInfoMap → participant.nickname → userId- 修复
agora-player组件默认在画面右上角显示 RTC uid 水印(改为仅 debug 模式显示) - 修复群聊页瓦片坐标相对容器重复偏移导致顶部黑框
- readme 补齐群聊接入文档、完整 API 表格与已知限制清单
平台兼容性
uni-app(5.07)
| Vue2 | Vue3 | Vue3插件版本 | Chrome | Safari | app-vue | app-nvue | Android | iOS | 鸿蒙 |
|---|---|---|---|---|---|---|---|---|---|
| × | √ | 2.4.1 | × | × | × | × | × | × | × |
| 微信小程序 | 微信小程序插件版本 | 支付宝小程序 | 抖音小程序 | 百度小程序 | 快手小程序 | 京东小程序 | 鸿蒙元服务 | QQ小程序 | 飞书小程序 | 小红书小程序 | 快应用-华为 | 快应用-联盟 |
|---|---|---|---|---|---|---|---|---|---|---|---|---|
| √ | 2.4.1 | × | × | × | × | × | × | × | × | × | × | × |
Easemob CallKit UniApp 微信小程序插件
环信 CallKit UniApp 微信小程序插件,基于 @easemob-community/callkit-core 构建,提供开箱即用的 1v1 与群组音视频通话能力。
- 📦 DCloud 插件市场
- 🏠 GitHub 仓库
平台支持
- ✅ UniApp Vue3
- ✅ 微信小程序
- ❌ App(App 端将单独建包)
快速开始
1. 导入插件
在 HBuilderX 中把本插件目录放入宿主项目的 uni_modules/ 下:
your-project/
├── pages.json
├── manifest.json
├── App.vue
└── uni_modules/
└── em-callkit-weixin/ ← 本插件
2. 安装环信 IM SDK
宿主项目需要自行安装并初始化环信 IM SDK:
npm install easemob-websdk
# 或
pnpm add easemob-websdk
插件已内置
@easemob-community/callkit-core和agora-miniapp-sdk,无需额外安装。
3. 配置小程序权限与域名
⚠️ 类目资质要求:微信小程序的
live-pusher/live-player组件仅对特定类目开放(如社交-直播、教育、医疗等)。请先在微信公众平台确认你的小程序类目具备实时音视频资质,否则真机上组件无法渲染,审核也会被驳回。参考:live-pusher 官方文档。
在 manifest.json 的 mp-weixin 节点中声明音视频权限:
{
"mp-weixin": {
"permission": {
"scope.record": { "desc": "用于音视频通话" },
"scope.camera": { "desc": "用于视频通话" }
}
}
}
并在微信小程序后台配置服务器域名:
- socket 合法域名:
wss://im-api-wechat.easemob.com - uploadFile 合法域名:
https://a1.easemob.com - downloadFile 合法域名:
https://a1.easemob.com - live-pusher / live-player 域名:按声网控制台配置(通常包含
*.agoraio.cn等)
4. 初始化 CallKit
在宿主项目的 App.vue 或业务入口中:
<script setup>
import { createIMConnectionAdapter, createUniappMpWeixinCallKit } from '@/uni_modules/em-callkit-weixin'
import SDK from 'easemob-websdk/uniApp/Easemob-chat'
// 1. 创建环信连接(宿主自行负责)
const conn = new SDK.connection({
appKey: 'your-app-key',
url: 'wss://im-api-wechat.easemob.com/websocket',
apiUrl: 'https://a1.easemob.com'
})
// 2. 登录
await conn.open({ user: 'userId', accessToken: 'token' })
// 3. 包装成 CallKit 需要的形态
const imClient = createIMConnectionAdapter(conn)
// 4. 初始化 CallKit
const callKit = createUniappMpWeixinCallKit({
imClient,
userProfile: {
userId: 'userId',
nickname: '我的昵称',
avatarURL: 'https://...'
}
})
// 5. 挂载到全局,供其他页面/组件使用
uni.$callKit = callKit
</script>
TypeScript 全局类型声明(可选)
如果宿主项目使用 TypeScript,建议在 types/ 目录添加全局声明,让 uni.$callKit 有类型提示:
// types/global.d.ts
import type { CallKitInstance } from '@/uni_modules/em-callkit-weixin'
declare global {
interface UniApp {
$callKit?: CallKitInstance
$imClient?: any
}
}
export {}
并在 tsconfig.json 的 include 中确保包含 types/**/*.d.ts。
5. 发起呼叫
在任意页面中:
<script setup>
function callUser(userId, callType) {
uni.navigateTo({
url: `/uni_modules/em-callkit-weixin/pages/single-call-page/single-call-page?targetUserId=${userId}&callType=${callType}`
})
}
// 语音呼叫
callUser('targetUserId', 'audio')
// 视频呼叫
callUser('targetUserId', 'video')
</script>
6. 发起群组通话
通过 inviteGroupCall 发起群语音/群视频通话(主叫会自动进入内置群聊通话页):
import { CALL_TYPE } from '@/uni_modules/em-callkit-weixin'
// 群视频通话
await uni.$callKit.inviteGroupCall({
groupId: 'group-id',
participantIds: ['user1', 'user2', 'user3'], // 被邀请的群成员 userId 列表
callType: CALL_TYPE.VIDEO_MULTI,
ext: { groupName: '产品讨论群' }
})
// 群语音通话
await uni.$callKit.inviteGroupCall({
groupId: 'group-id',
participantIds: ['user1', 'user2'],
callType: CALL_TYPE.AUDIO_MULTI,
ext: { groupName: '产品讨论群' }
})
被叫方会收到群聊来电,进入待接听页面(显示群名、主叫方、被邀请成员),同意后才加入通话。
通话中邀请更多成员
群聊通话页底部控制栏内置了「邀请」按钮,点击后弹出底部半屏成员选择面板(已在通话中的成员自动置灰)。面板的数据源需要宿主在初始化时提供:
const callKit = createUniappMpWeixinCallKit({
imClient,
getGroupMembers: async (groupId) => {
// 返回该群组全部成员,插件会把已在通话中的成员标记为不可选
const res = await conn.listGroupMembers({ groupId, pageNum: 1, pageSize: 100 })
return (res?.data || []).map((m) => ({
userId: m.member || m.owner || m.admin,
nickname: '可选昵称',
avatarURL: '可选头像'
}))
}
})
未配置 getGroupMembers 时点击「邀请」仅提示不可用。也可以通过 API 直接邀请:
await uni.$callKit.inviteMoreParticipants(['user4'])
群聊通话页布局:
- 视频模式:自适应网格(1 人全屏 / 2 人上下分屏 / 3 人一大两小 / 4 人 2×2 / 5~6 人 2列3行 / 7~9 人 3×3),本地与远端成员等权显示
- 语音模式:3 列头像网格,显示昵称、等待状态
- 受微信小程序
live-player并发能力限制,视频画面默认最多同时渲染 4 路,超出的成员显示头像占位(音频保持可听)
来电处理
插件提供三种来电处理方式,宿主可按需选择:
方式一:自行处理来电(推荐)
通过 onIncomingCall 回调完全自定义来电展示:
const callKit = createUniappMpWeixinCallKit({
imClient,
onIncomingCall: (payload) => {
// payload: { callerUserId, callType, callId }
console.log('收到来电', payload)
// 展示自定义弹窗
// 返回 true 表示宿主已处理,插件不再自动跳转
return true
}
})
方式二:使用内置通知条
在 App.vue 根节点放置组件:
<template>
<view class="app-root">
<invitation-notification :user-info-map="userInfoMap" />
<!-- 页面内容 -->
</view>
</template>
<script setup>
const userInfoMap = {
'user1': { nickname: '张三', avatarURL: 'https://...' }
}
</script>
组件会自动监听 incomingCall 事件,在顶部显示来电通知条,并提供接听/拒绝按钮。
方式三:默认跳转
如果既未设置 onIncomingCall,也未使用 invitation-notification,收到来电时插件默认自动跳转到内置单聊通话页。
完整 API
createUniappMpWeixinCallKit(options)
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
imClient |
IMAdaptedConnection |
是 | 经 createIMConnectionAdapter 包装后的环信连接 |
userProfile |
{ userId, nickname?, avatarURL? } |
否 | 当前用户资料 |
rtcAdapter |
RtcAdapter |
否 | 自定义 RTC 适配器,默认使用声网小程序 SDK |
onIncomingCall |
(payload) => boolean \| void |
否 | 来电回调,返回 true 拦截默认跳转 |
showDefaultToast |
boolean |
否 | 是否显示内置的通话结束状态 Toast("对方已拒绝"等),默认 true;宿主若已通过 onEvent 自行处理可设为 false |
getGroupMembers |
(groupId) => Promise<GroupMemberInfo[]> |
否 | 群成员数据源,群聊通话页「邀请」面板通过它拉取候选人 |
返回值:CallKitInstance
| 属性/方法 | 说明 |
|---|---|
core |
CallKitCore 实例,提供 inviteCall / answerCall / hangup 等核心 API |
rtcAdapter |
RtcAdapter 实例,提供 RTC 原子操作 |
setUserInfo(userId, info) |
设置单个用户资料(昵称/头像),通话页与来电通知展示用 |
setUserInfoMap(map) |
批量设置用户资料 |
onEvent(handler) |
订阅通话事件(callEnded / callRefused / participantJoined 等),返回取消订阅函数 |
inviteGroupCall(params) |
发起群组通话,见上文「发起群组通话」 |
inviteMoreParticipants(ids) |
群聊通话中追加邀请成员 |
getGroupMembers(groupId) |
宿主配置的群成员数据源(如已配置),供邀请面板拉取候选人 |
createIMConnectionAdapter(connection)
把环信 IM SDK 的 connection 包装成 CallKit 需要的形态。
参数:环信 SDK 的 connection 实例
返回值:IMAdaptedConnection
useCallState()
获取通话状态 Store:
import { useCallState } from '@/uni_modules/em-callkit-weixin'
const { state } = useCallState()
// state.status: 'idle' | 'inviting' | 'ringing' | 'in_call' | 'ended'
// state.callType: 'audio' | 'video'
// state.duration: number
// ...
useGroupCallState()
获取群聊通话状态 Store(自定义群聊通话页时使用):
import { useGroupCallState } from '@/uni_modules/em-callkit-weixin'
const { state } = useGroupCallState()
// state.session: { groupId, groupName, callType, callerUserId } | null
// state.participants: GroupParticipant[] // 已入会成员(含流地址、等待状态)
// state.invitedParticipants: GroupParticipant[] // 被邀请成员(响铃页展示)
// state.callStatus: 'idle' | 'ringing' | 'in_call' | 'ended'
createMpWeixinLogger(options?)
创建平台 Logger,可控制日志级别和上报:
import { createMpWeixinLogger } from '@/uni_modules/em-callkit-weixin'
const logger = createMpWeixinLogger({
level: 'warn', // 'verbose' | 'debug' | 'info' | 'warn' | 'error' | 'silent'
prefix: '[CallKit][微信小程序]'
})
默认根据环境自动判断:开发/体验版输出 debug,正式版只输出 warn/error。
已知限制
- 声网小程序 SDK 并发上限:单频道最多 17 人同时发送视频流、32 人同时发送纯音频流(视频+音频合计亦受限),详见声网文档
- 视频渲染路数:受微信小程序
live-player并发能力限制,群视频默认最多同时渲染 4 路画面,超出成员显示头像占位(音频正常) - 网格上限:群视频网格最多显示 9 个瓦片,更多成员以头像占位
- 远端成员状态:远端成员的静音/摄像头开关状态暂不透传到 UI(信令层未携带该字段)
- 来电响铃/震动:暂未内置,可通过
onEvent监听incomingCall自行接入uni.vibrateLong/innerAudioContext - App 端:本插件仅支持微信小程序,App 端将单独建包
常见问题
1. 真机上没有声音/画面
- 检查是否已申请
scope.record/scope.camera权限 - 检查微信小程序后台是否配置了服务器域名(live-pusher/live-player 需要)
- 查看控制台是否有
[CallKit][微信小程序]开头的错误日志
2. 收到来电没有弹窗
- 确认
imClient已正确传入 - 确认
onIncomingCall没有返回true(否则插件不会自动跳转) - 检查 IM 是否在线,是否能收到文本消息
3. 正式版日志太多
import { createMpWeixinLogger } from '@/uni_modules/em-callkit-weixin'
const logger = createMpWeixinLogger({ level: 'error' })
4. 如何自定义通话页面
通过 onIncomingCall 拦截来电后,自行导航到自定义页面,并调用 core.answerCall / core.hangup 等 API 控制通话。
开发
# 同步 callkit-core + agora-miniapp-sdk 到插件 vendor/
pnpm sync:all
# 类型检查
pnpm typecheck
详细开发规范见 skills/callkit-uniapp-mp-weixin-plugin.md。

收藏人数:
https://github.com/Easemob-Community/easemob-uikit-callkit/tree/dev/packages/callkit-uniapp-mp-weixin
下载插件并导入HBuilderX
下载插件ZIP
赞赏(0)
下载 5
赞赏 0
下载 12441660
赞赏 1934
赞赏
京公网安备:11010802035340号