xj-meeting-sdk-v2
v1.0.9
Published
A Vue 2 meeting SDK component
Readme
XJ Meeting SDK Vue2
一个基于 Vue 2 的视频会议 SDK 组件,集成了 WebRTC 服务器。
功能特性
- 基于 WebRTC 的实时视频通话
- 支持多人视频会议
- 集成 xj WebRTC 服务器
- 支持 Vue 2.x
- 使用 Quasar UI 框架
技术栈
- Vue 2.6.14
- WebRTC
- xj WebRTC Server
- Quasar 1.22.10
- sdp-transform 2.15.0
- webrtc-adapter 8.2.4
安装
# 使用 pnpm 安装依赖
pnpm install开发
# 启动开发服务器
pnpm serve构建
构建库文件
# 构建 SDK 库文件
pnpm lib构建后的文件将在 dist 目录下:
xj-meeting-sdk-vue2.common.js- CommonJS 格式xj-meeting-sdk-vue2.umd.js- UMD 格式xj-meeting-sdk-vue2.umd.min.js- UMD 格式(压缩版)xj-meeting-sdk-vue2.css- 样式文件
构建应用
# 构建整个应用
pnpm build本地预览构建结果
HTTP 服务
# 启动 HTTP 服务
npx serve dist访问 http://localhost:3000
HTTPS 服务(推荐)
- 生成自签名证书:
mkdir -p ssl && openssl req -newkey rsa:2048 -new -nodes -x509 -days 365 -keyout ssl/key.pem -out ssl/cert.pem -subj "/C=CN/ST=State/L=City/O=Organization/OU=Unit/CN=localhost"- 启动 HTTPS 服务:
npx serve dist --ssl-cert ssl/cert.pem --ssl-key ssl/key.pem --listen 3000访问 https://localhost:3000
注意:使用自签名证书时,浏览器会显示证书不受信任的警告,这是正常的。在开发环境中可以忽略此警告继续访问。
WebSocket 安全配置
当通过 HTTPS 访问应用时,WebSocket 连接也必须使用安全连接(WSS)。配置已更新为:
- WebSocket:
wss://${host}:4188/ - HTTP API:
https://${host}:8088/janus
确保 xj 服务器:
- 配置了有效的 SSL 证书
- 启用了 WSS 支持
- 正确配置了 4188 端口的 WSS 服务
测试
# 运行单元测试
pnpm test目录结构
src/- 源代码目录components/- Vue 组件assets/- 静态资源
dist/- 构建输出目录tests/- 测试文件public/- 公共资源目录
浏览器支持
- Chrome ≥ 70
- Firefox ≥ 65
- Safari ≥ 12
- Edge ≥ 79
许可证
MIT
MeetingComponent 组件功能说明
组件概述
MeetingComponent.vue 是一个功能完整的视频会议组件,提供了丰富的会议功能和现代化的用户界面。
主要功能
1. 会议基础功能
- 会议加入/退出
- 自动加入指定会议室:通过 SIP 协议自动连接并加入指定的会议室,支持自定义会议号和用户信息
- 优雅的退出机制:在用户退出时自动关闭所有媒体流,清理资源,断开连接
- 显示加载状态和进度:使用优雅的动画效果显示会议加入进度,提供良好的用户体验
2. 媒体控制
音频控制
- 麦克风开关:一键控制本地音频流的开启/关闭,支持快捷键操作
- 扬声器开关:控制远程音频的播放/静音,适用于需要暂时屏蔽声音的场景
- 音量控制:实时调节音频输入输出音量,支持可视化音量显示
- 音频设备切换:动态切换音频输入输出设备,无需重新加入会议
视频控制
- 摄像头开关:一键控制本地视频流的开启/关闭,支持设备级别的控制
- 视频设备切换:在多个摄像头之间无缝切换,自动处理视频流的重新协商
- 视频预览功能:会议前预览本地视频画面,调整摄像头参数
屏幕共享
- 开启/停止屏幕共享:支持分享整个屏幕、应用窗口或浏览器标签
- 屏幕共享状态管理:实时显示共享状态,支持画质和帧率控制
- 异常处理:自动处理共享中断、权限变更等异常情况
3. 会议信息显示
状态栏信息
- 会议标题显示:清晰展示当前会议的名称和主题
- 会议时长实时计时:精确记录会议持续时间,支持多种时间格式
- 网络状态实时监控:通过图标和文字直观显示当前网络质量
- 全屏模式切换:支持一键切换全屏显示,优化会议体验
会议详情
- 会议标题:可自定义的会议名称,支持动态修改
- 会议号:唯一的会议标识符,便于分享和加入
- 开始时间:记录会议开始的具体时间,支持多时区显示
- 参会人数:实时统计当前参会人数,显示在线状态
4. 参会者管理
- 参会者列表
- 显示所有参会者:实时更新的参会者列表,包含在线状态
- 参会者角色显示:区分主持人、普通参会者等不同角色
- 参会者媒体状态:显示每个参会者的音视频状态
- 实时状态更新:自动同步参会者的状态变化,包括进入、退出等事件
5. 设备管理
- 设备设置
- 音频设备选择:支持选择和测试多个音频输入输出设备
- 视频设备选择:支持选择不同的摄像头,预览视频效果
- 扬声器设备选择:独立的扬声器设备选择,支持音频测试
- 设备切换过渡:平滑处理设备切换过程,确保通话不中断
6. 邀请功能
- 会议邀请
- 生成会议链接:自动生成包含会议信息的邀请链接
- 复制邀请链接:一键复制功能,支持多种格式的邀请信息
- 邀请分享功能:集成多种分享渠道,如邮件、消息等
7. 网络质量管理
- 网络状态监控
- 实时质量显示:通过图标直观展示当前网络状态
- 状态可视化:使用不同颜色和图标展示网络质量等级
- 自动网络调整:根据网络状况自动调整音视频质量
8. 用户界面特性
响应式设计
- 屏幕适配:自动适应不同尺寸的显示设备
- 移动端支持:针对触摸屏优化的交互体验
- 过渡动画:流畅的状态切换动画,提升用户体验
暗色主题
- 主题适配:自动检测并适应系统主题设置
- 暗色优化:专门优化的暗色模式配色方案
加载状态
- 加载动画:美观的加载动画效果
- 进度显示:清晰的进度指示器
- 状态反馈:及时的操作反馈和提示
9. 安全特性
- 安全连接
- WSS 支持:安全的 WebSocket 连接,防止中间人攻击
- HTTPS 协议:加密的 HTTP 通信,保护数据传输安全
- 媒体加密:端到端的媒体流加密,保护通话内容
技术实现特点
1. 媒体处理
- 使用 WebRTC 技术进行实时通信
- 支持音视频设备的动态切换
- 处理各种媒体流异常情况
2. 状态管理
- 完整的生命周期管理
- 可靠的资源清理机制
- 异常状态自动恢复
3. 性能优化
- 优化的视频渲染性能
- 高效的事件处理机制
- 智能的资源管理
4. 错误处理
- 完善的错误捕获机制
- 友好的错误提示
- 自动重试机制
使用方法
<template>
<meeting-component
ref="meetingComponent"
:meeting-code="meetingCode"
:login-name="userName"
:login-pwd="userPwd"
:server-host="serverHost"
:wss-port="wssPort"
:https-port="httpsPort"
:ice-servers="iceServers"
:log-level="logLevel"
:custom-buttons="[
{ label: '举手', value: 'raiseHand', icon: 'pan_tool', color: 'primary' },
{ label: '投票', value: 'vote', icon: 'how_to_vote', color: 'secondary' }
]"
@registration-success="onRegistrationSuccess"
@meeting-not-found="onMeetingNotFound"
@custom-button-click="onCustomButtonClick"
/>
</template>
<script>
import MeetingComponent from 'xj-meeting-sdk-vue2/dist/MeetingComponent.vue';
export default {
components: { MeetingComponent },
data() {
return {
meetingCode: '123456', // 会议号
userName: 'your_login_name', // 登录用户名
userPwd: 'your_password', // 登录密码
serverHost: 'wss://your-server-host', // WebSocket服务器主机
wssPort: 4088, // WebSocket信令端口
httpsPort: 8088, // HTTPS API端口
iceServers: [ // WebRTC ICE服务器配置
{ urls: 'stun:stun.l.google.com:19302' }
],
logLevel: 'info' // 日志级别
}
},
methods: {
onRegistrationSuccess() {
// SIP 注册成功回调
console.log('SIP 注册成功');
},
onMeetingNotFound(meetingCode) {
// 会议号未找到回调
console.warn('会议未找到:', meetingCode);
},
onCustomButtonClick(btn) {
// btn.value 区分按钮类型
if (btn.value === 'raiseHand') {
// 举手逻辑
} else if (btn.value === 'vote') {
// 投票逻辑
}
}
}
}
</script>配置选项(Props)
| Prop | 类型 | 必填 | 默认值 | 说明 | |------------------|----------------|------|----------|--------------------------------------------------------------| | meeting-code | String | 是 | - | 会议号,唯一标识会议 | | login-name | String | 是 | - | 登录用户名 | | login-pwd | String | 是 | - | 登录密码 | | server-host | String | 是 | - | WebSocket 服务器主机(如 10.94.3.3) | | wss-port | Number | 否 | - | WebSocket 信令端口 | | https-port | Number | 否 | - | HTTPS API 端口 | | ice-servers | Array | 否 | - | WebRTC ICE 服务器配置 | | debug | Boolean | 否 | false | 是否开启调试模式 | | log-level | Number | 否 | 0 | 日志级别,0为关闭,1~N为不同详细程度 | | custom-buttons | Array | 否 | [] | 自定义按钮配置数组 | | sipServerHost | String | 否 | '' | SIP 服务器主机(软终端专用) | | sipServerPort | String/Number | 否 | '' | SIP 服务器端口(软终端专用) | | displayName | String | 否 | '' | 显示名称(软终端专用) | | loginType | String/Number | 否 | 1 | 登录类型,1为普通账号,2为软终端账号 | | nameFilter | Function/RegExp| 否 | null | 参会者名称过滤规则,支持函数或正则,常用于脱敏或格式化展示 |
事件说明
| 事件名 | 回调参数 | 说明 | |-----------------------|------------------------|----------------------------------------| | registration-success | 无 | SIP 注册成功 | | meeting-not-found | meetingCode: String | 会议号未找到 | | custom-button-click | btn: Object | 自定义按钮点击事件 |
注意事项
浏览器兼容性
- 确保浏览器支持 WebRTC
- 检查浏览器的媒体设备权限
- 注意不同浏览器的特定实现差异
网络要求
- 建议使用有线网络或稳定的 WiFi
- 确保防火墙允许 WebRTC 流量
- 建议带宽至少 1Mbps 上行和下行
安全考虑
- 在生产环境中使用 HTTPS
- 配置正确的 WSS 服务
- 实施适当的访问控制
日志自动行号脚本
本项目提供了一个自动为 customLog 日志补全/替换真实行号的 Node.js 脚本:
脚本位置
replaceCustomLogLineNumber.js
脚本作用
- 自动扫描
src/components/DeviceSettings.vue文件,将所有 customLog 的第5个参数(行号)补全或替换为当前 customLog 语句所在的真实行号。 - 支持 customLog 只有4个参数(自动补全)和已有第5个参数(自动替换)。
- 运行后会在终端输出替换/补全的数量和明细,便于核查。
使用方法
node replaceCustomLogLineNumber.js输出示例
customLog 第5个参数已自动补全为真实行号(含空缺情况)!
替换已有第5个参数的数量: 27
补全缺失第5个参数的数量: 0
替换明细:
第265行 替换为: customLog('error', '初始化设备失败', error, 'DeviceSettings', 265)
...注意事项
- 仅会处理
src/components/DeviceSettings.vue文件。 - 如需处理其他文件,可修改脚本中的
filePath路径。 - 建议在代码提交前运行该脚本,保证日志定位准确。
TODO 下一步要实现的功能
- 被动呼叫接听功能
- 手机适配功能
修改了quasar的源码样式,然后打包到了插件中,使用的时候引用插件的样式就可以了
.disabled, [disabled], .disabled *, [disabled] * { outline: 0 !important; cursor: default; }
自定义按钮(custom-buttons)使用示例
方式一:事件监听方式
<meeting-component
...
:custom-buttons="[
{ label: '举手', value: 'raiseHand', icon: 'pan_tool', color: 'primary' },
{ label: '投票', value: 'vote', icon: 'how_to_vote', color: 'secondary' }
]"
@custom-button-click="onCustomButtonClick"
/>methods: {
onCustomButtonClick(btn) {
// btn.value 区分按钮类型
if (btn.value === 'raiseHand') {
// 举手逻辑
} else if (btn.value === 'vote') {
// 投票逻辑
}
}
}方式二:回调函数方式
<meeting-component
...
:custom-buttons="[
{ label: '举手', value: 'raiseHand', icon: 'pan_tool', color: 'primary', onClick: handleRaiseHand },
{ label: '投票', value: 'vote', icon: 'how_to_vote', color: 'secondary', onClick: handleVote }
]"
/>methods: {
handleRaiseHand(btn) {
// 举手逻辑
},
handleVote(btn) {
// 投票逻辑
}
}按钮对象字段说明: | 字段 | 类型 | 说明 | |---------|----------|------------------------------| | label | String | 按钮显示文本 | | value | String | 按钮唯一标识 | | icon | String | 按钮图标(可选) | | color | String | 按钮颜色(可选) | | onClick | Function | 按钮点击回调(可选,优先级高)|
如果按钮对象设置了 onClick 回调,则点击时会优先调用该回调,否则会触发 @custom-button-click 事件。
nameFilter 使用示例
只显示冒号前内容:
nameFilter: name => {
const match = name.match(/^([^:]+):/);
return match ? match[1] : name;
}在 App.vue 传递:
<meeting-component
...
:name-filter="nameFilter"
/>版本更新说明
1.0.4
- 去掉quasar下display样式
- 增加加入会议的时候,可以通过密码入会功能
1.0.5
- 统一更改服务端接口名称
1.0.6
- 增加来电接听功能
- 修改挂断后页面的ui展示
1.0.7
- 增加登录接口密码加密传输逻辑,提升安全性[sdk至少使用这个版本]
1.0.8
- 增加登录的时候对webrtc网关服务认证调用
1.0.9
- 解决密码登录的时候,ip写死的问题
