usc-rtc-client 1.1.6 → 2.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/Readme.md +278 -108
- package/dist/client/RtcClient.d.ts +16 -0
- package/dist/client/RtcClientBase.d.ts +32 -0
- package/dist/client/RtcClientEvent.d.ts +15 -0
- package/dist/client/RtcSignalApi.d.ts +51 -0
- package/dist/client/RtcSignalServer.d.ts +19 -0
- package/dist/index.d.ts +25 -0
- package/dist/index.es.js +1374 -0
- package/dist/index.umd.js +6 -0
- package/dist/log/Logger.d.ts +4 -0
- package/dist/message/SignalMessage.d.ts +26 -0
- package/dist/message/SingalMessageType.d.ts +20 -0
- package/dist/peer/LocalStreamHandler.d.ts +94 -0
- package/dist/peer/RTCPeerConnectionHandler.d.ts +94 -0
- package/dist/peer/StreamUtil.d.ts +12 -0
- package/dist/session/RtcAbstractSession.d.ts +34 -0
- package/dist/session/RtcCalledSession.d.ts +10 -0
- package/dist/session/RtcCalledTyped.d.ts +9 -0
- package/dist/session/RtcInviteStatus.d.ts +8 -0
- package/dist/session/RtcSession.d.ts +24 -0
- package/dist/session/RtcSessionEvent.d.ts +11 -0
- package/dist/session/RtcSessionStatus.d.ts +5 -0
- package/dist/session/RtcSessionStatusAdapter.d.ts +1 -0
- package/dist/session/UscRtcProtocol.d.ts +6 -0
- package/dist/websocket/RtcSocketServerHandler.d.ts +31 -0
- package/dist/websocket/RtcWebSocket.d.ts +31 -0
- package/dist/websocket/RtcWebSocketEvent.d.ts +5 -0
- package/package.json +14 -13
- package/dist/index.esm.js +0 -1
- package/dist/index.js +0 -1
package/Readme.md
CHANGED
|
@@ -1,13 +1,16 @@
|
|
|
1
|
-
|
|
1
|
+
# 音视频通话 webrtc sdk 开发手册
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
3
|
+
## 1.安装
|
|
4
|
+
|
|
5
|
+
```sh
|
|
6
|
+
//使用yarn安装
|
|
6
7
|
yarn add usc-rtc-client
|
|
7
8
|
//使用npm安装
|
|
8
9
|
npm install usc-rtc-client
|
|
9
10
|
```
|
|
10
|
-
|
|
11
|
+
|
|
12
|
+
## 2.简单使用 demo
|
|
13
|
+
|
|
11
14
|
```javascript
|
|
12
15
|
//用户A,演示主叫端的逻辑
|
|
13
16
|
import { RtcClient, createRtcClient, RtcSessionEvent, RtcClientEvent } from "usc-rtc-client"
|
|
@@ -56,10 +59,14 @@ startClientB()
|
|
|
56
59
|
|
|
57
60
|
```
|
|
58
61
|
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
62
|
+
## 3.sdk 说明
|
|
63
|
+
|
|
64
|
+
此项目为 typescript 项目,按照 npm 的约定生成了 type 描述文件,具体 api 说明请在 type 描述文件中进行查看,以下是一些重要的 Api 说明:
|
|
65
|
+
|
|
66
|
+
### 1.createRtcClient
|
|
67
|
+
|
|
68
|
+
此方法用来创建一个 webrtc 的终端,内部已经封装了心跳,信令交互,以及视频处理的逻辑,api 描述如下:
|
|
69
|
+
|
|
63
70
|
```javascript
|
|
64
71
|
declare const createRtcClient: (config: {
|
|
65
72
|
server: string; //信令服务器的地址
|
|
@@ -68,36 +75,44 @@ declare const createRtcClient: (config: {
|
|
|
68
75
|
expireTime?: number; //注册信令的过期时间,默认是60s
|
|
69
76
|
}) => Promise<RtcClient>; //注意,这里返回的是Promise的对象,resolve前置是在创建websocket链接之后发送一次心跳信息,等待服务器返回确认信息
|
|
70
77
|
```
|
|
78
|
+
|
|
71
79
|
使用事例:
|
|
80
|
+
|
|
72
81
|
```javascript
|
|
73
|
-
import { createRtcClient } from
|
|
74
|
-
let client
|
|
82
|
+
import { createRtcClient } from 'usc-rtc-client'
|
|
83
|
+
let client = await createRtcClient({ server: 'wss://xxxxxx.com/', localNumber: '7001' })
|
|
75
84
|
```
|
|
76
85
|
|
|
77
|
-
|
|
78
|
-
|
|
86
|
+
### 2.RtcClient
|
|
87
|
+
|
|
88
|
+
RtcClient 是用来实例化 webrtc 终端的对象,内部主要方法如下
|
|
89
|
+
|
|
79
90
|
- createSession(remoteNumber?: string): RtcSession 用来来创建一个会话
|
|
80
|
-
-
|
|
81
|
-
- reConnect() 重新连接信令服务器,如果之前处于连接状态会自动调用destory的方法
|
|
82
|
-
- on(event:RtcClientEvent,cb:Function)
|
|
83
|
-
- sendPttMessage() 此方法是后续添加,是用来发送ptt消息,消息具体格式请参考ptt对讲以及ims开发文档
|
|
91
|
+
- destroy() 销毁客户端,会销毁所有创建的会话以及断开与信令服务器的链接,与信令服务器断开链接之后也会自动触发此方法
|
|
92
|
+
- reConnect() 重新连接信令服务器,如果之前处于连接状态会自动调用 destory 的方法
|
|
93
|
+
- on(event:RtcClientEvent,cb:Function) 注册相关监听事件
|
|
94
|
+
- sendPttMessage() 此方法是后续添加,是用来发送 ptt 消息,消息具体格式请参考 ptt 对讲以及 ims 开发文档
|
|
84
95
|
|
|
85
96
|
事例代码:
|
|
97
|
+
|
|
86
98
|
```javascript
|
|
87
|
-
import { createRtcClient,RtcClientEvent,RtcSession,RtcCalledSession } from
|
|
88
|
-
let client
|
|
89
|
-
let session:RtcSession = client.createSession(
|
|
90
|
-
client.on(RtcClientEvent.invite,(calledSession:RtcCalledSession)=>{})
|
|
99
|
+
import { createRtcClient, RtcClientEvent, RtcSession, RtcCalledSession } from 'usc-rtc-client'
|
|
100
|
+
let client = await createRtcClient({ server: 'wss://xxxxxx.com/', localNumber: '7001' })
|
|
101
|
+
let session: RtcSession = client.createSession('7002')
|
|
102
|
+
client.on(RtcClientEvent.invite, (calledSession: RtcCalledSession) => {})
|
|
91
103
|
```
|
|
92
104
|
|
|
93
|
-
|
|
105
|
+
### 3.RtcClientEvent
|
|
106
|
+
|
|
94
107
|
RtcClientEvent 表示底层封装向上抛出的一些业务与非业务的生命周期事件,具体如下
|
|
108
|
+
|
|
95
109
|
- connected 信令服务器连接成功事件
|
|
96
110
|
- disconnected 信令服务器断开事件,连接失败这里也可以触发
|
|
97
|
-
- invite
|
|
98
|
-
- FPREInfo 收到ptt消息通知事件(目前主要为ptt组在线用户查询消息,具体格式参考ptt对讲以及ims开发文档)
|
|
111
|
+
- invite 收到音视频通话邀请的事件
|
|
112
|
+
- FPREInfo 收到 ptt 消息通知事件(目前主要为 ptt 组在线用户查询消息,具体格式参考 ptt 对讲以及 ims 开发文档)
|
|
99
113
|
|
|
100
114
|
事例代码
|
|
115
|
+
|
|
101
116
|
```javascript
|
|
102
117
|
import { createRtcClient , RtcClientEvent,RtcCalledSession } from "usc-rtc-client"
|
|
103
118
|
let client = await createRtcClient({server:"wss://xxxxxx.com/",localNumber:"7001"})
|
|
@@ -111,28 +126,31 @@ client.on(RtcClientEvent.invite,(session:RtcCalledSession)=>{
|
|
|
111
126
|
})
|
|
112
127
|
```
|
|
113
128
|
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
129
|
+
### 4.RtcSession
|
|
130
|
+
|
|
131
|
+
RtcSession 是用来实例化 RtcClient 所创建的音视频会话的对象,内部主要方法如下
|
|
132
|
+
|
|
133
|
+
- addRemote(remoteNumber: string) 修改需要呼叫的用户
|
|
117
134
|
- rejectCall() 拒绝邀请,使用于创建会话过程中的会议类型变更
|
|
118
135
|
- acceptCall() 接受邀请,使用于创建会话过程中的会议类型变更
|
|
119
136
|
- start() 开始呼叫
|
|
120
|
-
-
|
|
121
|
-
- getAllInputResource()
|
|
122
|
-
- useDefaultDevice(container: HTMLVideoElement)
|
|
123
|
-
- useAudio(deviceId) 使用对应deviceId的麦克风设备作为音频流,如果deviceId为undefined,那么使用默认的设备作为音频源
|
|
124
|
-
- useDeviceVideo(deviceId) 使用对应deviceid摄像头设备的视频流,如果deviceId为undefined,那么使用默认的设备作为视频源
|
|
125
|
-
- useDeskTopVideo()
|
|
137
|
+
- destroy() 销毁会话,如果呼叫已经开始,会先向被叫端发送 bye 请求
|
|
138
|
+
- getAllInputResource() 获取所有的音视频输入源
|
|
139
|
+
- useDefaultDevice(container: HTMLVideoElement) 使用默认的本地音视频输入设备(麦克风与摄像头),并将本地的流媒体渲染到对应的 video 上(可以不传),实际上是下面几个方法的组合使用
|
|
140
|
+
- useAudio(deviceId) 使用对应 deviceId 的麦克风设备作为音频流,如果 deviceId 为 undefined,那么使用默认的设备作为音频源
|
|
141
|
+
- useDeviceVideo(deviceId) 使用对应 deviceid 摄像头设备的视频流,如果 deviceId 为 undefined,那么使用默认的设备作为视频源
|
|
142
|
+
- useDeskTopVideo() 使用桌面流作为视频流输入
|
|
126
143
|
- disableAudio() 禁用本地流的音频输入,本地音频静音
|
|
127
144
|
- disableVideo() 禁用本地流的视频输入,关闭本地视频画面
|
|
128
|
-
- enableAudio()
|
|
129
|
-
- enableVideo()
|
|
130
|
-
- renderLocalStreamToContainer(container:HTMLVideoElement|HTMLAudioElement) 将本地的流媒体使用对应的video或者audio元素进行播放
|
|
131
|
-
- on(event:RtcSessionEvent,cb:Function)
|
|
145
|
+
- enableAudio() 启用本地音频输入
|
|
146
|
+
- enableVideo() 启用本地视频输入
|
|
147
|
+
- renderLocalStreamToContainer(container:HTMLVideoElement|HTMLAudioElement) 将本地的流媒体使用对应的 video 或者 audio 元素进行播放
|
|
148
|
+
- on(event:RtcSessionEvent,cb:Function) 注册相关监听事件
|
|
132
149
|
- addDeviceChangeListener(listener) 注册物理输入设备变化监听事件,如摄像头拔线之类的操作
|
|
133
|
-
- removeDeviceChangeListener(listener) 删除物理输入设备变化监听事件(组件化的框架如react之类的,在组件销毁的时候使用这个方法进行回收)
|
|
150
|
+
- removeDeviceChangeListener(listener) 删除物理输入设备变化监听事件(组件化的框架如 react 之类的,在组件销毁的时候使用这个方法进行回收)
|
|
134
151
|
|
|
135
152
|
事例代码
|
|
153
|
+
|
|
136
154
|
```javascript
|
|
137
155
|
...
|
|
138
156
|
session.addRemote("7003")
|
|
@@ -140,27 +158,30 @@ await session.useDefaultDevice(document.getElementById("localplayer"))
|
|
|
140
158
|
session.start()
|
|
141
159
|
```
|
|
142
160
|
|
|
143
|
-
|
|
144
|
-
|
|
161
|
+
### 5.RtcCalledSession
|
|
162
|
+
|
|
163
|
+
RtcCalledSession 是用来实例化被叫会话的对象,主要方法如下
|
|
164
|
+
|
|
145
165
|
- getRemoteNumber() 获取呼叫自己的远端号码
|
|
146
166
|
- rejectCall() 拒绝邀请,使用于创建会话与会话过程中的会议类型变更
|
|
147
167
|
- acceptCall() 接受邀请,使用于创建会话与会话过程中的会议类型变更
|
|
148
|
-
-
|
|
149
|
-
- getAllInputResource()
|
|
150
|
-
- useDefaultDevice(container: HTMLVideoElement)
|
|
151
|
-
- useAudio(deviceId) 使用对应deviceId的麦克风设备作为音频流,如果deviceId为undefined,那么使用默认的设备作为音频源
|
|
152
|
-
- useDeviceVideo(deviceId) 使用对应deviceid摄像头设备的视频流,如果deviceId为undefined,那么使用默认的设备作为视频源
|
|
153
|
-
- useDeskTopVideo()
|
|
168
|
+
- destroy() 销毁会话,如果呼叫已经开始,会先向被叫端发送 bye 请求
|
|
169
|
+
- getAllInputResource() 获取所有的音视频输入源
|
|
170
|
+
- useDefaultDevice(container: HTMLVideoElement) 使用默认的本地音视频输入设备(麦克风与摄像头),并将本地的流媒体渲染到对应的 video 上(可以不传),实际上是下面几个方法的组合使用
|
|
171
|
+
- useAudio(deviceId) 使用对应 deviceId 的麦克风设备作为音频流,如果 deviceId 为 undefined,那么使用默认的设备作为音频源
|
|
172
|
+
- useDeviceVideo(deviceId) 使用对应 deviceid 摄像头设备的视频流,如果 deviceId 为 undefined,那么使用默认的设备作为视频源
|
|
173
|
+
- useDeskTopVideo() 使用桌面流作为视频流输入
|
|
154
174
|
- disableAudio() 禁用本地流的音频输入,本地音频静音
|
|
155
175
|
- disableVideo() 禁用本地流的视频输入,关闭本地视频画面
|
|
156
|
-
- enableAudio()
|
|
157
|
-
- enableVideo()
|
|
158
|
-
- renderLocalStreamToContainer(container:HTMLVideoElement|HTMLAudioElement) 将本地的流媒体使用对应的video或者audio元素进行播放
|
|
159
|
-
- on(event:RtcSessionEvent,cb:Function)
|
|
176
|
+
- enableAudio() 启用本地音频输入
|
|
177
|
+
- enableVideo() 启用本地视频输入
|
|
178
|
+
- renderLocalStreamToContainer(container:HTMLVideoElement|HTMLAudioElement) 将本地的流媒体使用对应的 video 或者 audio 元素进行播放
|
|
179
|
+
- on(event:RtcSessionEvent,cb:Function) 注册相关监听事件
|
|
160
180
|
- addDeviceChangeListener(listener) 注册物理输入设备变化监听事件,如摄像头拔线之类的操作
|
|
161
|
-
- removeDeviceChangeListener(listener) 删除物理输入设备变化监听事件(组件化的框架如react之类的,在组件销毁的时候使用这个方法进行回收
|
|
181
|
+
- removeDeviceChangeListener(listener) 删除物理输入设备变化监听事件(组件化的框架如 react 之类的,在组件销毁的时候使用这个方法进行回收
|
|
162
182
|
|
|
163
183
|
事例代码
|
|
184
|
+
|
|
164
185
|
```javascript
|
|
165
186
|
...
|
|
166
187
|
client.on(RtcClientEvent.invite,async (session:RtcCalledSession)=>{
|
|
@@ -169,16 +190,19 @@ client.on(RtcClientEvent.invite,async (session:RtcCalledSession)=>{
|
|
|
169
190
|
})
|
|
170
191
|
```
|
|
171
192
|
|
|
172
|
-
|
|
193
|
+
### 6.RtcSessionEvent
|
|
194
|
+
|
|
173
195
|
会话流程事件
|
|
196
|
+
|
|
174
197
|
- bye 会话结束事件
|
|
175
198
|
- stream 会话收到流的事件
|
|
176
|
-
- localAudioChange
|
|
177
|
-
- localVideoChange
|
|
178
|
-
- reInvite 会话过程中修改会话类型会重新发invite 比如原先只是语音通话,然后变成视频会话
|
|
199
|
+
- localAudioChange 本地音频流设备发生了变化
|
|
200
|
+
- localVideoChange 本地视频流设备发生了变化
|
|
201
|
+
- reInvite 会话过程中修改会话类型会重新发 invite 比如原先只是语音通话,然后变成视频会话
|
|
179
202
|
- localStreamChange 本地流发生了变化
|
|
180
203
|
|
|
181
204
|
事例代码
|
|
205
|
+
|
|
182
206
|
```javascript
|
|
183
207
|
...
|
|
184
208
|
session.on(RtcSessionEvent.stream,({audioOnly,stream})=>{
|
|
@@ -186,8 +210,8 @@ session.on(RtcSessionEvent.stream,({audioOnly,stream})=>{
|
|
|
186
210
|
//use audio to play
|
|
187
211
|
}else{
|
|
188
212
|
let playerContainer = document.getElementById("player")
|
|
189
|
-
playerContainer.srcObject =
|
|
190
|
-
playerContainer.
|
|
213
|
+
playerContainer.srcObject = stream
|
|
214
|
+
playerContainer.play()
|
|
191
215
|
}
|
|
192
216
|
})
|
|
193
217
|
...
|
|
@@ -197,30 +221,97 @@ session.on(RtcSessionEvent.bye,()=>{
|
|
|
197
221
|
})
|
|
198
222
|
```
|
|
199
223
|
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
224
|
+
## 4.监控模式
|
|
225
|
+
|
|
226
|
+
监控模式是本 SDK 提供的一种特殊功能,允许在不建立完整通话会话的情况下,单向播放远程流。
|
|
227
|
+
|
|
228
|
+
### 1.使用 playRemote 函数
|
|
229
|
+
|
|
203
230
|
```javascript
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
231
|
+
import { playRemote } from 'usc-rtc-client'
|
|
232
|
+
|
|
233
|
+
// 监控模式播放远程流
|
|
234
|
+
async function startMonitoring(remoteNumber) {
|
|
235
|
+
try {
|
|
236
|
+
// 创建监控播放器
|
|
237
|
+
const monitorPlayer = document.getElementById('monitor-player')
|
|
238
|
+
|
|
239
|
+
// 开始监控远程号码
|
|
240
|
+
const player = await playRemote(
|
|
241
|
+
'ws://your-signaling-server-url', // 信令服务器地址
|
|
242
|
+
remoteNumber, // 要监控的远程号码
|
|
243
|
+
monitorPlayer, // 视频容器
|
|
244
|
+
{
|
|
245
|
+
audioOnly: false, // 是否仅播放音频
|
|
246
|
+
autoPlay: true, // 是否自动播放
|
|
247
|
+
muted: false, // 是否静音
|
|
248
|
+
}
|
|
249
|
+
)
|
|
250
|
+
|
|
251
|
+
console.log('监控会话创建成功')
|
|
252
|
+
|
|
253
|
+
// 5秒后结束监控
|
|
254
|
+
setTimeout(() => {
|
|
255
|
+
player.destroy()
|
|
256
|
+
console.log('监控会话已结束')
|
|
257
|
+
}, 5000)
|
|
258
|
+
} catch (error) {
|
|
259
|
+
console.error('监控会话创建失败:', error)
|
|
260
|
+
}
|
|
261
|
+
}
|
|
210
262
|
```
|
|
211
263
|
|
|
212
|
-
|
|
213
|
-
|
|
264
|
+
### 2.playRemote 函数参数说明
|
|
265
|
+
|
|
266
|
+
| 参数名 | 类型 | 描述 | 是否必填 |
|
|
267
|
+
| ------------ | ---------------- | ---------------- | -------- |
|
|
268
|
+
| server | string | 信令服务器地址 | 是 |
|
|
269
|
+
| remoteNumber | string | 要监控的远程号码 | 是 |
|
|
270
|
+
| container | HTMLVideoElement | 视频播放容器 | 是 |
|
|
271
|
+
| options | object | 可选配置项 | 否 |
|
|
272
|
+
|
|
273
|
+
options 配置项:
|
|
274
|
+
| 配置项 | 类型 | 默认值 | 描述 |
|
|
275
|
+
|--------|------|--------|------|
|
|
276
|
+
| audioOnly | boolean | false | 是否仅播放音频 |
|
|
277
|
+
| autoPlay | boolean | true | 是否自动播放 |
|
|
278
|
+
| muted | boolean | false | 是否静音 |
|
|
279
|
+
|
|
280
|
+
### 3.监控模式的特点
|
|
281
|
+
|
|
282
|
+
- 监控模式下会自动禁用心跳功能,减少网络通信
|
|
283
|
+
- 监控模式是单向的,被监控方不会收到任何通知
|
|
284
|
+
- 监控模式适合用于监控、预览等场景
|
|
285
|
+
|
|
286
|
+
## 5.ptt 消息接口
|
|
287
|
+
|
|
288
|
+
### 1.启用 ptt 客户端功能
|
|
289
|
+
|
|
290
|
+
本客户端(webrtc)集成了 ptt 对讲客户端的全部接口,功能等同于 usc-ptt-sdk 提供的功能,若想单独使用 ptt 功能,可直接安装 usc-ptt-sdk 即可;以下是集成的功能及用法说明:
|
|
291
|
+
|
|
292
|
+
```javascript
|
|
293
|
+
await createRtcClient({
|
|
294
|
+
server,
|
|
295
|
+
localNumber,
|
|
296
|
+
enablePtt: true, // 初始化客户端时,可传入enablePtt,true表示启用ptt客户端,不传或flase表示不使用ptt客户端,
|
|
297
|
+
pttServer: 'ws://localhost:40000', //pttClient服务器地址,当enablePtt为true时,需要传入该字段,否则初始化失败
|
|
298
|
+
})
|
|
299
|
+
```
|
|
300
|
+
|
|
301
|
+
### 2.RtcClient 集成的 ptt 接口
|
|
302
|
+
|
|
303
|
+
当启用 ptt 客户端时,ptt 客户端提供的接口将可以在 RtcClient 上使用,接口说明如下:
|
|
214
304
|
joinGroup('100114','10000008003','10.168.1.17',20023) //加入对讲组
|
|
215
305
|
quitGroup() //退出组
|
|
216
|
-
talk()
|
|
217
|
-
stop()
|
|
306
|
+
talk() //说话
|
|
307
|
+
stop() //停止说话
|
|
218
308
|
|
|
219
309
|
事例代码
|
|
310
|
+
|
|
220
311
|
```javascript
|
|
221
312
|
const client = await createRtcClient({ server, localNumber, enablePtt: true, pttServer: 'ws://localhost:40000' })
|
|
222
313
|
// 加入组
|
|
223
|
-
client.joinGroup('100114','10000008003','10.168.1.17',20023)
|
|
314
|
+
client.joinGroup('100114', '10000008003', '10.168.1.17', 20023)
|
|
224
315
|
//退出组
|
|
225
316
|
client.quitGroup()
|
|
226
317
|
//本客户端用户需要说话时调用(须先加入一个对讲组)
|
|
@@ -228,9 +319,11 @@ client.talk()
|
|
|
228
319
|
//停止说话
|
|
229
320
|
client.stop()
|
|
230
321
|
|
|
231
|
-
|
|
322
|
+
以上接口只作为向服务器发送请求消息, 结果将以客户端事件的形式响应给用户, 开发人员只需要在初始化完客户端后监听相应的事件即可
|
|
232
323
|
```
|
|
233
|
-
|
|
324
|
+
|
|
325
|
+
### 3.PTTEvent
|
|
326
|
+
|
|
234
327
|
```javascript
|
|
235
328
|
PTTEvent 表示底层封装向上抛出的一些业务与非业务的生命周期事件,具体如下
|
|
236
329
|
const clientEvent = {
|
|
@@ -243,41 +336,118 @@ const clientEvent = {
|
|
|
243
336
|
```
|
|
244
337
|
|
|
245
338
|
事例代码
|
|
339
|
+
|
|
246
340
|
```javascript
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
341
|
+
const client = await createRtcClient({ server, localNumber, enablePtt: true, pttServer: 'ws://localhost:40000' })
|
|
342
|
+
client.on(PTTEvent.ACTIVE_GROUP, (e) => {
|
|
343
|
+
// e为空字符串时表示当前没有加入任何组,否则e为加入的组的组id
|
|
344
|
+
if (e) console.log(`进入组:${e}`)
|
|
345
|
+
else console.log('退出组')
|
|
346
|
+
})
|
|
347
|
+
client.on(PTTEvent.SPEAKER, (e) => {
|
|
348
|
+
// e为空字符串时表示当前没有人在说话或当前说话人停止说话,否则e为说话人的ptt号
|
|
349
|
+
if (e) console.log(`${e}正在说话`)
|
|
350
|
+
else console.log(`停止说话`)
|
|
351
|
+
})
|
|
352
|
+
client.on(PTTEvent.TALKING, (e) => {
|
|
353
|
+
// e为true时表示当前自己在说话,否则表示自己停止说话
|
|
354
|
+
if (e) console.log(`您正在说话`)
|
|
355
|
+
else console.log(`您已停止说话`)
|
|
356
|
+
})
|
|
357
|
+
client.on(PTTEvent.JOIN_INFO, (e) => {
|
|
358
|
+
// 有用户加入组时通知,
|
|
359
|
+
// e的结构如下
|
|
360
|
+
// {
|
|
361
|
+
// user:8003, 加入的用户号
|
|
362
|
+
// group:100114, 组id
|
|
363
|
+
// code:1, 0表示退出组,1表示加入组
|
|
364
|
+
// }
|
|
365
|
+
console.log(`用户加入通知:${JSON.stringify(e)}`)
|
|
366
|
+
})
|
|
367
|
+
```
|
|
368
|
+
|
|
369
|
+
## 6.最佳实践
|
|
370
|
+
|
|
371
|
+
### 1.错误处理
|
|
372
|
+
|
|
373
|
+
在使用 SDK 时,建议添加适当的错误处理,以提高应用的稳定性:
|
|
374
|
+
|
|
375
|
+
```javascript
|
|
376
|
+
try {
|
|
377
|
+
const client = await createRtcClient({ server, localNumber })
|
|
378
|
+
// 使用client
|
|
379
|
+
} catch (error) {
|
|
380
|
+
console.error('创建RTC客户端失败:', error)
|
|
381
|
+
// 处理错误,如提示用户重试
|
|
382
|
+
}
|
|
383
|
+
|
|
384
|
+
// 会话事件处理
|
|
385
|
+
session.on(RtcSessionEvent.stream, ({ stream }) => {
|
|
386
|
+
if (stream) {
|
|
387
|
+
const container = document.getElementById('player')
|
|
388
|
+
container.srcObject = stream
|
|
389
|
+
container.play().catch((error) => {
|
|
390
|
+
console.error('播放流失败:', error)
|
|
391
|
+
// 处理自动播放失败的情况
|
|
392
|
+
})
|
|
393
|
+
}
|
|
394
|
+
})
|
|
279
395
|
```
|
|
280
396
|
|
|
281
|
-
###
|
|
282
|
-
|
|
283
|
-
|
|
397
|
+
### 2.资源释放
|
|
398
|
+
|
|
399
|
+
在不需要使用 SDK 或会话结束时,建议释放相关资源:
|
|
400
|
+
|
|
401
|
+
```javascript
|
|
402
|
+
// 销毁会话
|
|
403
|
+
session.destroy()
|
|
404
|
+
|
|
405
|
+
// 销毁客户端
|
|
406
|
+
client.destroy()
|
|
407
|
+
|
|
408
|
+
// 释放流资源
|
|
409
|
+
releaseStreamFromContainer(container)
|
|
410
|
+
```
|
|
411
|
+
|
|
412
|
+
### 3.设备管理
|
|
413
|
+
|
|
414
|
+
在使用音视频设备前,建议先检查设备是否可用:
|
|
415
|
+
|
|
416
|
+
```javascript
|
|
417
|
+
const resources = await session.getAllInputResource()
|
|
418
|
+
if (resources.audio.length === 0) {
|
|
419
|
+
console.error('没有检测到麦克风')
|
|
420
|
+
// 处理没有麦克风的情况
|
|
421
|
+
}
|
|
422
|
+
if (resources.video.length === 0) {
|
|
423
|
+
console.error('没有检测到摄像头')
|
|
424
|
+
// 处理没有摄像头的情况
|
|
425
|
+
}
|
|
426
|
+
```
|
|
427
|
+
|
|
428
|
+
## 7.限制
|
|
429
|
+
|
|
430
|
+
- 目前仅做了 chrome 浏览器的兼容支持,要求 chrome 内核版本在 90 以上
|
|
431
|
+
- webrtc 接口调用的页面需要依赖 https 环境(本地地址如 localhost,127.0.0.1 除外),页面运行环境如果无法提供支持,请在 chrome 的 unsafely-treat-insecure 中添加白名单来让页面支持 webrtc(chrome 浏览器打开 chrome://flags/#unsafely-treat-insecure-origin-as-secure,在 Insecure origins treated as secure 下面的输入框中添加您的网页地址,选择右边的 enable,重启浏览器生效)
|
|
432
|
+
|
|
433
|
+
## 8.API 参考
|
|
434
|
+
|
|
435
|
+
### 核心函数
|
|
436
|
+
|
|
437
|
+
- `createRtcClient(config)`: 创建 RTC 客户端
|
|
438
|
+
- `playRemote(server, remoteNumber, container, options)`: 监控模式播放远程流
|
|
439
|
+
- `renderStreamToContainer(stream, container)`: 渲染流到容器
|
|
440
|
+
- `releaseStreamFromContainer(container)`: 从容器释放流
|
|
441
|
+
- `enableLog()`: 启用日志
|
|
442
|
+
|
|
443
|
+
### 事件类型
|
|
444
|
+
|
|
445
|
+
- `RtcClientEvent`: 客户端事件
|
|
446
|
+
- `RtcSessionEvent`: 会话事件
|
|
447
|
+
- `PTTEvent`: PTT 事件
|
|
448
|
+
|
|
449
|
+
### 类
|
|
450
|
+
|
|
451
|
+
- `RtcClient`: RTC 客户端类
|
|
452
|
+
- `RtcSession`: 会话类
|
|
453
|
+
- `RtcCalledSession`: 被叫会话类
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { RtcSession } from './../session/RtcSession';
|
|
2
|
+
import { RtcClientBase } from './RtcClientBase';
|
|
3
|
+
import { RtcAbstractSession } from '../session/RtcAbstractSession';
|
|
4
|
+
export declare class RtcClient extends RtcClientBase {
|
|
5
|
+
allSession: RtcAbstractSession[];
|
|
6
|
+
createSession(remoteNumber?: string): RtcSession;
|
|
7
|
+
playRemote(remoteNumber: string, container: HTMLVideoElement, options?: {
|
|
8
|
+
audioOnly?: boolean;
|
|
9
|
+
autoPlay?: boolean;
|
|
10
|
+
muted?: boolean;
|
|
11
|
+
}): Promise<RtcSession>;
|
|
12
|
+
processMessage(data: any): void;
|
|
13
|
+
destroy(): void;
|
|
14
|
+
removeSession(session: RtcAbstractSession): void;
|
|
15
|
+
onDisConnected(): void;
|
|
16
|
+
}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { RtcSignalApi } from './RtcSignalApi';
|
|
2
|
+
/**
|
|
3
|
+
* RTC终端基础类,用来处理心跳等信息
|
|
4
|
+
*/
|
|
5
|
+
export declare abstract class RtcClientBase extends RtcSignalApi {
|
|
6
|
+
static defaultExpireTime: number;
|
|
7
|
+
pttClient?: any;
|
|
8
|
+
pttServer?: string;
|
|
9
|
+
enablePtt?: boolean;
|
|
10
|
+
constructor(config: {
|
|
11
|
+
server: string;
|
|
12
|
+
localNumber: string;
|
|
13
|
+
heartTime?: number;
|
|
14
|
+
expireTime?: number;
|
|
15
|
+
enablePtt?: boolean;
|
|
16
|
+
pttServer?: string;
|
|
17
|
+
});
|
|
18
|
+
initPttClient(): Promise<undefined>;
|
|
19
|
+
/**
|
|
20
|
+
*
|
|
21
|
+
* @param group 对讲组Id
|
|
22
|
+
* @param user 用户ptt账号
|
|
23
|
+
* @param ptts ptt对讲组使用的webscoket服务器,从ptt组中获取
|
|
24
|
+
* @param port ptt对讲组使用的webscoket服务器端口,从ptt组中获取
|
|
25
|
+
*/
|
|
26
|
+
joinGroup(group: string, user: string, ptts: string, port: number): void;
|
|
27
|
+
quitGroup(): void;
|
|
28
|
+
talk(): void;
|
|
29
|
+
stop(): void;
|
|
30
|
+
onConnected(): void;
|
|
31
|
+
onDisConnected(): void;
|
|
32
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
export declare enum RtcClientEvent {
|
|
2
|
+
connected = "connected",
|
|
3
|
+
disconnected = "disconnected",
|
|
4
|
+
invite = "invite"
|
|
5
|
+
}
|
|
6
|
+
export declare enum PTTEvent {
|
|
7
|
+
PTTInfo = "PTTInfo",
|
|
8
|
+
FPREInfo = "FPREInfo",
|
|
9
|
+
IMSInfo = "IMSInfo",
|
|
10
|
+
ERROR = "error",
|
|
11
|
+
SPEAKER = "speaker",
|
|
12
|
+
TALKING = "talking",
|
|
13
|
+
ACTIVE_GROUP = "activeGroup",
|
|
14
|
+
JOIN_INFO = "joinInfo"
|
|
15
|
+
}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import { RtcInviteStatus } from './../session/RtcInviteStatus';
|
|
2
|
+
import { RtcSignalServer } from './RtcSignalServer';
|
|
3
|
+
/**
|
|
4
|
+
* 信令请求Api
|
|
5
|
+
*/
|
|
6
|
+
export declare abstract class RtcSignalApi extends RtcSignalServer {
|
|
7
|
+
/**
|
|
8
|
+
* send register message to the server
|
|
9
|
+
*/
|
|
10
|
+
register(): Promise<any>;
|
|
11
|
+
unRegister(): void;
|
|
12
|
+
/**
|
|
13
|
+
* send a invite request to user
|
|
14
|
+
* @param user the remote user who you want invite
|
|
15
|
+
* @param cid the session id
|
|
16
|
+
* @param sdp sdp content
|
|
17
|
+
* @returns
|
|
18
|
+
*/
|
|
19
|
+
invite(user: string, cid: string, sdp?: string): Promise<any>;
|
|
20
|
+
/**
|
|
21
|
+
* send a ice request to user
|
|
22
|
+
* @param user the remote user
|
|
23
|
+
* @param cid session id
|
|
24
|
+
* @param ice ice message
|
|
25
|
+
* @returns
|
|
26
|
+
*/
|
|
27
|
+
sendIce(user: string, cid: string, ice: RTCIceCandidate): void;
|
|
28
|
+
/**
|
|
29
|
+
* send bye message
|
|
30
|
+
* @param user the remote user
|
|
31
|
+
* @param cid session id
|
|
32
|
+
*/
|
|
33
|
+
sendBye(user: string, cid: string): void;
|
|
34
|
+
/**
|
|
35
|
+
* answer message
|
|
36
|
+
* @param status answer status
|
|
37
|
+
* @param seq the seq number from offer
|
|
38
|
+
* @param to the remote offer user
|
|
39
|
+
* @param cid session id
|
|
40
|
+
* @param sdp sdp content
|
|
41
|
+
*/
|
|
42
|
+
answer(status: RtcInviteStatus, seq: number, to: string, cid: string, sdp?: string): void;
|
|
43
|
+
/**
|
|
44
|
+
* answer message
|
|
45
|
+
* @param xd_oper ptt infoType
|
|
46
|
+
* @param xd_name the groupId
|
|
47
|
+
* @param user the ptt user number
|
|
48
|
+
*/
|
|
49
|
+
sendPttMessage(data: any): void;
|
|
50
|
+
sendDtmf(user: string, cid: string, dtmf: string): Promise<any>;
|
|
51
|
+
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { SignalMessage } from './../message/SignalMessage';
|
|
2
|
+
import { RtcSocketServerHandler } from '../websocket/RtcSocketServerHandler';
|
|
3
|
+
/**
|
|
4
|
+
* rtc 信令服务器,用来处理信令消息,以及按照协议获取信令的返回结果
|
|
5
|
+
*/
|
|
6
|
+
export declare abstract class RtcSignalServer extends RtcSocketServerHandler {
|
|
7
|
+
asyncProducer: Map<number, Function>;
|
|
8
|
+
/**
|
|
9
|
+
* 发送需要回应消息的信令消息
|
|
10
|
+
*/
|
|
11
|
+
sendRespondableMessage(message: SignalMessage): Promise<any>;
|
|
12
|
+
/**
|
|
13
|
+
* 获取异步回调
|
|
14
|
+
*/
|
|
15
|
+
getAsyncResolve(seq: number): Function | undefined;
|
|
16
|
+
onDisConnected(e?: CloseEvent): void;
|
|
17
|
+
onReviceMessage(data: any): void;
|
|
18
|
+
abstract processMessage(data: any): any;
|
|
19
|
+
}
|