@crh-fe/oava-customer-sdk 1.0.1 → 1.0.2
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 +226 -7
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,21 +1,240 @@
|
|
|
1
|
-
#
|
|
1
|
+
# @crh-fe/oava-customer-sdk
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
> 数字人视频见证 / 自助视频 双录访客端 SDK
|
|
4
|
+
>
|
|
5
|
+
> 由 `widget` 工程构建产出,对应源码 [widget/lib/customerIndex.js](../../lib/customerIndex.js)。
|
|
6
|
+
>
|
|
7
|
+
> 包名:`@crh-fe/oava-customer-sdk` · 版本:`1.0.1` · 入口:`dist/customerComponent.js`
|
|
4
8
|
|
|
5
|
-
|
|
9
|
+
---
|
|
10
|
+
|
|
11
|
+
## 一、特性
|
|
12
|
+
|
|
13
|
+
- 基于 React + WebRTC 的访客端视频组件,支持**数字人坐席**和**真人坐席**两种模式
|
|
14
|
+
- 一行 `new` 即可创建实例,自带 TURN/媒体协商、推流、订阅
|
|
15
|
+
- 提供人脸在框检测、等待超时、转人工等业务事件回调
|
|
16
|
+
- ES Module 包,`type: "module"`,浏览器原生或 webpack 5 均可消费
|
|
17
|
+
|
|
18
|
+
---
|
|
19
|
+
|
|
20
|
+
## 二、安装
|
|
21
|
+
|
|
22
|
+
### 1. 从内部 npm 源安装(推荐)
|
|
23
|
+
|
|
24
|
+
```bash
|
|
25
|
+
npm install @crh-fe/oava-customer-sdk
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
### 2. 本地 tarball 安装
|
|
29
|
+
|
|
30
|
+
仓库内已打好包:
|
|
31
|
+
|
|
32
|
+
```bash
|
|
33
|
+
npm install ./packages/customer-sdk/oava-customer-sdk-1.0.1.tgz
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
### 3. 通过 `public/` 静态文件直接引用(不推荐,仅用于本地调试)
|
|
37
|
+
|
|
38
|
+
把 `widget/output/customerComponent.js` 拷到消费者工程的 `public/` 目录,然后用 `<script>` 标签引入,会挂载在 `window.CustomerComponent`(default export)。客户 demo [`demo/customer-demo/src/components/Home.vue`](../../../demo/customer-demo/src/components/Home.vue) 同时支持这两种方式的在线切换。
|
|
39
|
+
|
|
40
|
+
---
|
|
41
|
+
|
|
42
|
+
## 三、快速开始
|
|
43
|
+
|
|
44
|
+
```js
|
|
45
|
+
import Customer from "@crh-fe/oava-customer-sdk";
|
|
46
|
+
|
|
47
|
+
// 1. 实例化,传入 TURN 服务地址
|
|
48
|
+
const client = new Customer("turn:49.234.13.99?transport=udp");
|
|
49
|
+
|
|
50
|
+
// 2. 监听会话结束事件(必接)
|
|
51
|
+
client.onEnd((e) => {
|
|
52
|
+
// e.code 参考下方【事件码表】
|
|
53
|
+
console.log("会话结束", e);
|
|
54
|
+
client.destroy();
|
|
55
|
+
});
|
|
56
|
+
|
|
57
|
+
// 3. 初始化挂载。id 为空时挂到 body,否则挂到指定容器
|
|
58
|
+
client.init("", {
|
|
59
|
+
roomToken: "后端派单接口返回的 roomToken",
|
|
60
|
+
aiServerUrl: "https://your-face-detect-server.com",
|
|
61
|
+
faceCheckTimer: 3000, // 人脸在框检测间隔,单位 ms,默认 2000
|
|
62
|
+
maxWaitTime: 120, // 等待数字人/真人接入超时,单位 s,默认 120
|
|
63
|
+
userFaceBase64: "...", // 可选,用户人脸 base64,做人像比对
|
|
64
|
+
});
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
---
|
|
68
|
+
|
|
69
|
+
## 四、API 参考
|
|
70
|
+
|
|
71
|
+
### 4.1 `new CustomerComponent(turnServerUrl)`
|
|
72
|
+
|
|
73
|
+
| 参数 | 类型 | 必填 | 说明 |
|
|
74
|
+
| --- | --- | --- | --- |
|
|
75
|
+
| `turnServerUrl` | `string` | 否 | IRTC 媒体平台 TURN 地址,默认 `turn:106.15.227.129:3478?transport=udp` |
|
|
76
|
+
|
|
77
|
+
构造函数会在控制台输出:
|
|
78
|
+
|
|
79
|
+
```
|
|
80
|
+
[SDK Version] v1.0.1
|
|
81
|
+
[SDK version] v1.0.1, turnServerUrl: <传入值>
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
### 4.2 `init(id, options)`
|
|
85
|
+
|
|
86
|
+
挂载并启动组件。
|
|
87
|
+
|
|
88
|
+
| 参数 | 类型 | 必填 | 说明 |
|
|
89
|
+
| --- | --- | --- | --- |
|
|
90
|
+
| `id` | `string` | 否 | 容器 DOM 的 `id`;**传空字符串时挂载到 `body`**,会动态创建一个 `position: fixed; inset: 0;` 的全屏容器,组件卸载时自动移除 |
|
|
91
|
+
| `options` | `object` | 是 | 见下表 |
|
|
92
|
+
|
|
93
|
+
#### `options` 字段
|
|
94
|
+
|
|
95
|
+
| 字段 | 类型 | 必填 | 说明 |
|
|
96
|
+
| --- | --- | --- | --- |
|
|
97
|
+
| `roomToken` | `string` | 是 | 房间 token,由后端 `/tokens` 或派单接口下发 |
|
|
98
|
+
| `aiServerUrl` | `string` | 是 | 人脸在框检测服务地址 |
|
|
99
|
+
| `faceCheckTimer` | `number` | 否 | 人脸在框检测间隔,单位 **ms**,默认 `2000` |
|
|
100
|
+
| `maxWaitTime` | `number` | 否 | 等待数字人/真人接入的最大时长,单位 **s**,默认 `120` |
|
|
101
|
+
| `userFaceBase64` | `string` | 否 | 用户人脸 base64,用于人像比对 |
|
|
102
|
+
|
|
103
|
+
### 4.3 `destroy()`
|
|
104
|
+
|
|
105
|
+
销毁组件、断开 WebRTC 推拉流、卸载 React 树,并自动移除由 `init("", ...)` 创建的 `customer-component-container-id` 容器。**一次会话结束务必调用**,否则下次 `new` 会残留 DOM。
|
|
106
|
+
|
|
107
|
+
### 4.4 `onEnd(callback)`
|
|
108
|
+
|
|
109
|
+
注册会话结束回调,**只能触发一次**,触发后回调被置空。回调参数:
|
|
110
|
+
|
|
111
|
+
```ts
|
|
112
|
+
type EndCallbackParams = {
|
|
113
|
+
code: string; // 状态码,见下表
|
|
114
|
+
message: string; // 描述
|
|
115
|
+
data?: any; // 业务数据
|
|
116
|
+
type?: string; // 自定义事件类型
|
|
117
|
+
reason?: string; // 主动离开时的原因
|
|
118
|
+
};
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
#### 事件码表
|
|
122
|
+
|
|
123
|
+
| code | 含义 |
|
|
124
|
+
| --- | --- |
|
|
125
|
+
| `300` | 见证通过 |
|
|
126
|
+
| `301` | 见证不通过 |
|
|
127
|
+
| `400` | 用户自己主动离开 |
|
|
128
|
+
| `401` | 用户自己主动离开,去自助视频 |
|
|
129
|
+
| `6001` | 加入房间失败 |
|
|
130
|
+
| `6002` | 创建本地摄像头失败 |
|
|
131
|
+
| `6003` | 本地推流异常中断 |
|
|
132
|
+
| `6004` | 推送本地画面失败 |
|
|
133
|
+
| `6005` | 订阅数字人画面失败 |
|
|
134
|
+
| `6008` | 数字人流结束 |
|
|
135
|
+
| `7000` | 服务异常 |
|
|
136
|
+
| `7002` | 数字人坐席离开 |
|
|
137
|
+
| `8001` | 等待数字人接入超时 |
|
|
138
|
+
| `8002` | 等待真人坐席接入超时 |
|
|
139
|
+
|
|
140
|
+
> 转人工(`transfer`)期间,坐席相关的 6001/7002 等事件会被**抑制**,不再触发 `onEnd`,直到 `cancel-transfer` 复位。
|
|
141
|
+
|
|
142
|
+
---
|
|
143
|
+
|
|
144
|
+
## 五、完整示例(对齐客户 demo)
|
|
145
|
+
|
|
146
|
+
[`demo/customer-demo/src/components/Home.vue`](../../../demo/customer-demo/src/components/Home.vue) 里的最小闭环:
|
|
147
|
+
|
|
148
|
+
```js
|
|
149
|
+
import Customer from "@crh-fe/oava-customer-sdk";
|
|
150
|
+
|
|
151
|
+
// 1. 加入排队
|
|
152
|
+
const queueRes = await request({
|
|
153
|
+
url: `${aiUrl}/auditcenter/authless/openapi/video/joinQueue`,
|
|
154
|
+
data: { task_id: taskId },
|
|
155
|
+
});
|
|
156
|
+
|
|
157
|
+
// 2. 轮询排队结果,坐席接入后拿到 roomToken
|
|
158
|
+
const queryRes = await request({
|
|
159
|
+
url: `${aiUrl}/auditcenter/authless/openapi/video/queryQueue`,
|
|
160
|
+
data: { task_id: taskId },
|
|
161
|
+
});
|
|
162
|
+
const { room_id, room_token } = JSON.parse(queryRes.data.json_params);
|
|
163
|
+
|
|
164
|
+
const tokenRes = await request({
|
|
165
|
+
url: "https://zmscrh.zealcomm.cn/tokens",
|
|
166
|
+
data: { room: room_id, user: "testuser", role: "presenter", domain: "public" },
|
|
167
|
+
});
|
|
168
|
+
|
|
169
|
+
// 3. 实例化 SDK 并启动
|
|
170
|
+
const client = new Customer("turn:49.234.13.99?transport=udp");
|
|
171
|
+
|
|
172
|
+
client.onEnd((e) => {
|
|
173
|
+
if (e.code == "300") showSuccess(); // 见证通过
|
|
174
|
+
else if (e.code == "301") showFail(); // 见证不通过
|
|
175
|
+
else if (e.code == "200") return; // 收到转人工,不结束
|
|
176
|
+
else queryAuditResult(); // 其它码:查后端审核结果
|
|
177
|
+
client.destroy();
|
|
178
|
+
});
|
|
179
|
+
|
|
180
|
+
client.init("", {
|
|
181
|
+
roomToken: tokenRes, // 派单接口下发的 roomToken
|
|
182
|
+
aiServerUrl: "https://cpekh.test.cairenhui.com", // 人脸在框检测
|
|
183
|
+
faceCheckTimer: 300000,
|
|
184
|
+
maxWaitTime: 10000,
|
|
185
|
+
});
|
|
186
|
+
```
|
|
187
|
+
|
|
188
|
+
---
|
|
189
|
+
|
|
190
|
+
## 六、构建与发布
|
|
191
|
+
|
|
192
|
+
### 6.1 本地构建
|
|
193
|
+
|
|
194
|
+
回到 `widget/` 根目录:
|
|
6
195
|
|
|
7
196
|
```bash
|
|
197
|
+
# 产出 output/customerComponent.js 并同步到本 package 的 dist/
|
|
8
198
|
npm run build:npm:customer
|
|
9
199
|
```
|
|
10
200
|
|
|
11
|
-
|
|
201
|
+
它会按顺序执行:
|
|
202
|
+
1. `npm run build` — rollup 打包
|
|
203
|
+
2. `npm run sanitize:customer` — 去除 bundle 中残留的 propTypes 警告链接等
|
|
204
|
+
3. `npm run sync:customer-package` — 把产物拷到 `packages/customer-sdk/dist/`
|
|
205
|
+
|
|
206
|
+
### 6.2 打包 tgz
|
|
207
|
+
|
|
208
|
+
```bash
|
|
209
|
+
cd packages/customer-sdk
|
|
210
|
+
npm pack # 产出 oava-customer-sdk-<version>.tgz
|
|
211
|
+
```
|
|
212
|
+
|
|
213
|
+
仓库内已附 `oava-customer-sdk-1.0.1.tgz`,可直接 `npm install` 本地引用。
|
|
214
|
+
|
|
215
|
+
### 6.3 发布到 npm
|
|
12
216
|
|
|
13
217
|
```bash
|
|
14
218
|
cd packages/customer-sdk
|
|
15
219
|
npm publish
|
|
220
|
+
# 私有源:npm publish --registry=https://your-private-registry/
|
|
16
221
|
```
|
|
17
222
|
|
|
18
|
-
|
|
223
|
+
发布前确认:
|
|
224
|
+
- `packages/customer-sdk/package.json` 里的 `name` 已改成你想要的 scope(当前为 `@crh-fe/oava-customer-sdk`)
|
|
225
|
+
- `version` 字段按语义化版本号递增
|
|
226
|
+
- `dist/customerComponent.js` 是最新构建产物
|
|
227
|
+
|
|
228
|
+
---
|
|
229
|
+
|
|
230
|
+
## 七、注意事项
|
|
19
231
|
|
|
20
|
-
|
|
21
|
-
-
|
|
232
|
+
1. **包体积约 2.8 MB**(含 React/ReactDOM/IRT 媒体 SDK/业务组件),首次加载建议走 CDN 或拆 chunk 懒加载。
|
|
233
|
+
2. **纯 ESM 包**(`type: "module"`):webpack 4 / 旧版 vue-cli 默认走 CJS interop 会拿不到 `default`,请升级到 webpack 5 / vue-cli ≥ 5,或按需使用 `import("@crh-fe/oava-customer-sdk")` 动态导入。
|
|
234
|
+
3. **必须先 `npm install`**:项目依赖里要显式声明 `@crh-fe/oava-customer-sdk`,否则构建/运行会报模块未找到。
|
|
235
|
+
4. **TURN 地址要可访问**:构造器里的 TURN 服务必须与生产/测试环境媒体平台对齐,否则视频流不通。
|
|
236
|
+
5. **onEnd 仅触发一次**:会话结束、收到见证结论、转人工之外的超时/异常都会触发,记得在回调里调用 `client.destroy()` 释放资源。
|
|
237
|
+
6. **来源切换**(仅在 demo 中需要):demo 同时演示了
|
|
238
|
+
- 本地静态文件 `public/customerComponent.js`(适合 SDK 还没发布时的联调)
|
|
239
|
+
- npm 包 `@crh-fe/oava-customer-sdk`(适合已发布后回归验证)
|
|
240
|
+
切换时务必先 `destroy()` 旧实例,避免 DOM/媒体通道残留。
|