@vostone/web-sdk
v1.1.2
Published
Vue 3 composables for WebRTC SIP calling and local media
Readme
@vostone/web-sdk
面向 Vue 3 的浏览器端 SIP/WebRTC 能力封装:基于 JsSIP 完成注册、呼出、来电接听与挂断;配套 本地音视频/屏幕共享 组合式函数,便于嵌入任意 Vue 项目。
特性
- useSipCall:从业务 HTTP 接口拉取注册账号、按顺序尝试注册、音视频/单向视频呼出、来电振铃与接听、远端流绑定到传入的
video/audio元素。 - useLocalMedia:枚举摄像头/麦克风、预览、静音/关视频、屏幕共享及与 SIP 轨道替换联动。
环境要求
- Vue ^3.4
- 支持 WebRTC 与 getUserMedia 的现代浏览器
- 需自行提供可访问的 WSS SIP 中继与平台下发的注册信息接口(见下文)
安装
在目标项目中安装依赖(示例使用 npm):
npm install @vostone/web-sdk vue依赖说明:JsSIP 已打入 SDK 产物;crypto-js、events 列为本包 dependencies,一般会随 SDK 自动安装。Vue 3 仍为 peerDependency,需一并安装。
使用 Vite 时(重要)
SDK依赖 Node 风格的 events。构建后会在产物中 静态 import npm 的 events。Vite 默认会把模块名 events 当成 Node 内置并打成空桩,运行时会报错(例如 Dynamic require of "events" is not supported 或 EventEmitter is not exported by __vite-browser-external)。
请在 vite.config.ts 中为 events 配置 alias,指向本机安装的 npm 包(建议在应用里显式依赖 "events": "^3.3.0",保证路径稳定):
import { fileURLToPath } from 'url'
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
export default defineConfig({
resolve: {
alias: {
events: fileURLToPath(new URL('./node_modules/events/events.js', import.meta.url)),
},
},
plugins: [vue()],
})vite.config.ts 若使用 import.meta.url,可为 tsconfig.node.json 增加 "types": ["node"] 并安装 @types/node(开发依赖)。
若通过 monorepo / file: 引用本地包,构建 SDK 后由应用安装即可:
cd packages/sip-web-sdk && npm install && npm run build在应用中:
{
"dependencies": {
"@vostone/web-sdk": "file:../packages/sip-web-sdk"
}
}快速开始
1. 本地媒体
import { useLocalMedia } from '@vostone/web-sdk'
const localMedia = useLocalMedia({
onOutgoingVideoTrackChanged: (track) => sipCall.replaceOutgoingVideoTrack(track),
onOutgoingAudioTrackChanged: (track) => sipCall.replaceOutgoingAudioTrack(track),
})在模板中挂载本地预览 video,并在 onMounted / nextTick 后调用:
localMedia.setLocalVideoElement(videoEl)
await localMedia.refreshDevices()2. SIP 会话
将本地媒体适配器与远端 DOM 访问器传入 useSipCall:
import { useSipCall } from '@vostone/web-sdk'
const sipCall = useSipCall(
{
ensureLocalStreamReady: localMedia.ensureLocalStreamReady,
ensureMicOnlyStreamReady: localMedia.ensureMicOnlyStreamReady,
stopLocalMedia: localMedia.stopLocalMedia,
getOutgoingStream: localMedia.getOutgoingStream,
getMediaStreamForIncomingAnswer: localMedia.getMediaStreamForIncomingAnswer,
getOutgoingAudioTrack: localMedia.getOutgoingAudioTrack,
},
{
remoteVideoEl: () => remoteVideoRef.value,
remoteAudioEl: () => remoteAudioRef.value,
},
{
// 必填:拉取注册账号的 GET 地址
registerInfoUrl: 'https://your-api/caller/getRegisterInfo',
// 必填,拉取注册账号的密钥
auth: {
appId: '...',
accessKey: '...',
accessSecret: '...',
},
debugJsSip: false,
},
)初始化拉取账号并注册:
await sipCall.loadSipConfig()
await sipCall.goOnline()发起呼叫(target 为被叫号码或 SIP user 部分,具体与平台域名配置一致):
sipCall.makeCall(target, 'video') // 或 'audio' | 'oneWayVideo'来电时由 sipCall.isIncomingCall / sipCall.incomingFrom 展示 UI,并调用:
sipCall.answerIncomingCall()
sipCall.rejectIncomingCall()结束:
sipCall.hangup()
sipCall.goOffline()API 说明
useLocalMedia(options?)
| 返回/方法 | 说明 |
|-----------|------|
| cameraDevices / microphoneDevices | 设备列表 |
| selectedCameraId / selectedMicrophoneId | 当前选中设备 |
| refreshDevices() | 刷新设备枚举 |
| ensureLocalStreamReady() | 保证本地音视频流(含屏幕共享时的组合逻辑) |
| ensureMicOnlyStreamReady() | 仅麦克风,用于单向视频呼出等场景 |
| switchToCamera() | 切换摄像头后重新采集 |
| startScreenShare() / stopScreenShare() | 屏幕共享 |
| toggleLocalMute() / toggleLocalVideo() | 本地静音、关画面 |
| stopLocalMedia() | 停止本地轨道 |
| setLocalVideoElement(el) | 绑定本地预览 video |
useSipCall(media, elements, options)
media(SipMediaAdapter):与 useLocalMedia 提供的方法一致,用于在呼叫/接听时获取 MediaStream 或替换发送端轨道。
elements(SipRemoteElements):
remoteVideoEl()/remoteAudioEl():返回远端渲染用的HTMLVideoElement/HTMLAudioElement(可为null)。
options(SipSdkOptions):
| 字段 | 说明 |
|------|------|
| registerInfoUrl | 必填。拉取 SIP 账号列表的 GET 完整 URL;SDK 不包含任何默认接口地址。为空或非法 URL 时,loadSipConfig() 会写入 registerError |
| auth | 必填。HMAC 鉴权字段 appId、accessKey、accessSecret 须由业务注入,SDK 不包含任何默认密钥。任一项为空时,loadSipConfig() 会写入 registerError;服务端返回 401/403 时提示校验密钥是否正确 |
| debugJsSip | 为 true 时打开 JsSIP 调试输出 |
主要状态(ref):
status、currentUsername、registerError、callError、callNotice、isConfigLoading、isRegistering、isRegistered、isCalling、isIncomingCall、incomingFrom、sipConfig。
主要方法:
| 方法 | 说明 |
|------|------|
| loadSipConfig() | 请求注册信息并填充内部候选账号 |
| goOnline() / goOffline() | 注册上线 / 下线并清理会话 |
| makeCall(target, mode?) | mode: 'video' | 'audio' | 'oneWayVideo' |
| hangup() | 挂断当前通话 |
| answerIncomingCall() / rejectIncomingCall() | 接听 / 拒接 |
| replaceOutgoingVideoTrack / replaceOutgoingAudioTrack | 通话中替换发送轨道(与 useLocalMedia 回调配合) |
TypeScript
包内导出全部类型定义;应用侧需保证 Vue 单文件组件模块声明(如 declare module '*.vue')由本工程维护。
许可
MIT
