@yqzk/liveness-detection-web-component 1.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/CHANGELOG.md +30 -0
- package/LICENSE +21 -0
- package/README.md +350 -0
- package/dist/index.d.ts +15 -0
- package/dist/index.js +1 -0
- package/dist/index.umd.cjs +1 -0
- package/package.json +78 -0
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
All notable changes to this project will be documented in this file.
|
|
4
|
+
|
|
5
|
+
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
|
6
|
+
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
|
+
|
|
8
|
+
## [1.0.0] - 2025-11-10
|
|
9
|
+
|
|
10
|
+
### Added
|
|
11
|
+
- 初始版本发布
|
|
12
|
+
- 标准 Web Component 实现
|
|
13
|
+
- 支持活体检测核心功能
|
|
14
|
+
- 支持自定义主题和样式
|
|
15
|
+
- 多语言支持(中文/英文)
|
|
16
|
+
- TypeScript 类型定义
|
|
17
|
+
- ES Module 和 UMD 格式支持
|
|
18
|
+
- 完整的事件系统
|
|
19
|
+
|
|
20
|
+
### Features
|
|
21
|
+
- 实时人脸检测
|
|
22
|
+
- 活体动作验证
|
|
23
|
+
- 自动超时处理
|
|
24
|
+
- 错误重试机制
|
|
25
|
+
- 响应式设计
|
|
26
|
+
|
|
27
|
+
### Documentation
|
|
28
|
+
- 完整的 API 文档
|
|
29
|
+
- 使用示例(HTML/React/Vue)
|
|
30
|
+
- 浏览器兼容性说明
|
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025 Liaoning YQZK Team
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,350 @@
|
|
|
1
|
+
# @liveness-detection/web-component
|
|
2
|
+
|
|
3
|
+
活体检测 Web Component - 标准 Web 组件,可集成到任何前端框架。
|
|
4
|
+
|
|
5
|
+
## 特性
|
|
6
|
+
|
|
7
|
+
- 🎯 标准 Web Component,无框架依赖
|
|
8
|
+
- 📦 支持 ES Module 和 UMD 格式
|
|
9
|
+
- 🎨 样式内置,无需额外 CSS 文件
|
|
10
|
+
- 📱 响应式设计,自适应各种屏幕
|
|
11
|
+
- 🌐 完整的 TypeScript 类型支持
|
|
12
|
+
- ⚡ 自动预热,快速启动
|
|
13
|
+
|
|
14
|
+
## 安装
|
|
15
|
+
|
|
16
|
+
```bash
|
|
17
|
+
npm install @liveness-detection/web-component
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
## 快速开始
|
|
21
|
+
|
|
22
|
+
### 在 HTML 中使用
|
|
23
|
+
|
|
24
|
+
```html
|
|
25
|
+
<!DOCTYPE html>
|
|
26
|
+
<html>
|
|
27
|
+
<body>
|
|
28
|
+
<!-- 1. 添加组件标签 -->
|
|
29
|
+
<liveness-detector
|
|
30
|
+
api-endpoint="https://your-api.com"
|
|
31
|
+
theme="light"
|
|
32
|
+
language="zh">
|
|
33
|
+
</liveness-detector>
|
|
34
|
+
|
|
35
|
+
<!-- 2. 导入并使用 -->
|
|
36
|
+
<script type="module">
|
|
37
|
+
import '@liveness-detection/web-component';
|
|
38
|
+
|
|
39
|
+
const detector = document.querySelector('liveness-detector');
|
|
40
|
+
|
|
41
|
+
// 初始化配置
|
|
42
|
+
await detector.init({
|
|
43
|
+
apiEndpoint: 'https://your-api.com',
|
|
44
|
+
timeout: 60000
|
|
45
|
+
});
|
|
46
|
+
|
|
47
|
+
// 监听事件
|
|
48
|
+
detector.addEventListener('detectionComplete', (e) => {
|
|
49
|
+
console.log('检测成功:', e.detail);
|
|
50
|
+
});
|
|
51
|
+
|
|
52
|
+
detector.addEventListener('detectionError', (e) => {
|
|
53
|
+
console.error('检测失败:', e.detail);
|
|
54
|
+
});
|
|
55
|
+
|
|
56
|
+
// 开始检测
|
|
57
|
+
const result = await detector.detect();
|
|
58
|
+
</script>
|
|
59
|
+
</body>
|
|
60
|
+
</html>
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
### 在 React 中使用
|
|
64
|
+
|
|
65
|
+
```tsx
|
|
66
|
+
import { useEffect, useRef } from 'react';
|
|
67
|
+
import '@liveness-detection/web-component';
|
|
68
|
+
|
|
69
|
+
function App() {
|
|
70
|
+
const detectorRef = useRef<any>(null);
|
|
71
|
+
|
|
72
|
+
useEffect(() => {
|
|
73
|
+
const detector = detectorRef.current;
|
|
74
|
+
|
|
75
|
+
// 初始化
|
|
76
|
+
detector.init({
|
|
77
|
+
apiEndpoint: 'https://your-api.com',
|
|
78
|
+
timeout: 60000,
|
|
79
|
+
theme: 'light'
|
|
80
|
+
});
|
|
81
|
+
|
|
82
|
+
// 监听事件
|
|
83
|
+
const handleComplete = (e: CustomEvent) => {
|
|
84
|
+
console.log('检测成功:', e.detail);
|
|
85
|
+
};
|
|
86
|
+
|
|
87
|
+
const handleError = (e: CustomEvent) => {
|
|
88
|
+
console.error('检测失败:', e.detail);
|
|
89
|
+
};
|
|
90
|
+
|
|
91
|
+
detector.addEventListener('detectionComplete', handleComplete);
|
|
92
|
+
detector.addEventListener('detectionError', handleError);
|
|
93
|
+
|
|
94
|
+
return () => {
|
|
95
|
+
detector.removeEventListener('detectionComplete', handleComplete);
|
|
96
|
+
detector.removeEventListener('detectionError', handleError);
|
|
97
|
+
};
|
|
98
|
+
}, []);
|
|
99
|
+
|
|
100
|
+
const startDetection = async () => {
|
|
101
|
+
try {
|
|
102
|
+
const result = await detectorRef.current.detect();
|
|
103
|
+
console.log('检测结果:', result);
|
|
104
|
+
} catch (error) {
|
|
105
|
+
console.error('检测失败:', error);
|
|
106
|
+
}
|
|
107
|
+
};
|
|
108
|
+
|
|
109
|
+
return (
|
|
110
|
+
<div>
|
|
111
|
+
<liveness-detector
|
|
112
|
+
ref={detectorRef}
|
|
113
|
+
api-endpoint="https://your-api.com"
|
|
114
|
+
theme="light"
|
|
115
|
+
language="zh"
|
|
116
|
+
/>
|
|
117
|
+
<button onClick={startDetection}>开始检测</button>
|
|
118
|
+
</div>
|
|
119
|
+
);
|
|
120
|
+
}
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
### 在 Vue 中使用
|
|
124
|
+
|
|
125
|
+
```vue
|
|
126
|
+
<template>
|
|
127
|
+
<div>
|
|
128
|
+
<liveness-detector
|
|
129
|
+
ref="detectorRef"
|
|
130
|
+
api-endpoint="https://your-api.com"
|
|
131
|
+
theme="light"
|
|
132
|
+
language="zh"
|
|
133
|
+
@detectionComplete="handleComplete"
|
|
134
|
+
@detectionError="handleError"
|
|
135
|
+
/>
|
|
136
|
+
<button @click="startDetection">开始检测</button>
|
|
137
|
+
</div>
|
|
138
|
+
</template>
|
|
139
|
+
|
|
140
|
+
<script setup lang="ts">
|
|
141
|
+
import { ref, onMounted } from 'vue';
|
|
142
|
+
import '@liveness-detection/web-component';
|
|
143
|
+
|
|
144
|
+
const detectorRef = ref<any>(null);
|
|
145
|
+
|
|
146
|
+
onMounted(async () => {
|
|
147
|
+
// 初始化
|
|
148
|
+
await detectorRef.value.init({
|
|
149
|
+
apiEndpoint: 'https://your-api.com',
|
|
150
|
+
timeout: 60000,
|
|
151
|
+
theme: 'light'
|
|
152
|
+
});
|
|
153
|
+
});
|
|
154
|
+
|
|
155
|
+
const handleComplete = (e: CustomEvent) => {
|
|
156
|
+
console.log('检测成功:', e.detail);
|
|
157
|
+
};
|
|
158
|
+
|
|
159
|
+
const handleError = (e: CustomEvent) => {
|
|
160
|
+
console.error('检测失败:', e.detail);
|
|
161
|
+
};
|
|
162
|
+
|
|
163
|
+
const startDetection = async () => {
|
|
164
|
+
try {
|
|
165
|
+
const result = await detectorRef.value.detect();
|
|
166
|
+
console.log('检测结果:', result);
|
|
167
|
+
} catch (error) {
|
|
168
|
+
console.error('检测失败:', error);
|
|
169
|
+
}
|
|
170
|
+
};
|
|
171
|
+
</script>
|
|
172
|
+
```
|
|
173
|
+
|
|
174
|
+
### 使用 UMD 格式(浏览器直接引入)
|
|
175
|
+
|
|
176
|
+
```html
|
|
177
|
+
<!DOCTYPE html>
|
|
178
|
+
<html>
|
|
179
|
+
<body>
|
|
180
|
+
<liveness-detector id="detector"></liveness-detector>
|
|
181
|
+
|
|
182
|
+
<!-- 直接引入 UMD 文件 -->
|
|
183
|
+
<script src="node_modules/@liveness-detection/web-component/dist/index.umd.cjs"></script>
|
|
184
|
+
|
|
185
|
+
<script>
|
|
186
|
+
const detector = document.getElementById('detector');
|
|
187
|
+
|
|
188
|
+
// 初始化
|
|
189
|
+
detector.init({
|
|
190
|
+
apiEndpoint: 'https://your-api.com'
|
|
191
|
+
}).then(() => {
|
|
192
|
+
console.log('初始化完成');
|
|
193
|
+
|
|
194
|
+
// 开始检测
|
|
195
|
+
return detector.detect();
|
|
196
|
+
}).then(result => {
|
|
197
|
+
console.log('检测成功:', result);
|
|
198
|
+
}).catch(error => {
|
|
199
|
+
console.error('检测失败:', error);
|
|
200
|
+
});
|
|
201
|
+
</script>
|
|
202
|
+
</body>
|
|
203
|
+
</html>
|
|
204
|
+
```
|
|
205
|
+
|
|
206
|
+
## API 文档
|
|
207
|
+
|
|
208
|
+
### 配置接口
|
|
209
|
+
|
|
210
|
+
```typescript
|
|
211
|
+
interface LivenessDetectorConfig {
|
|
212
|
+
apiEndpoint: string; // API 服务地址(必填)
|
|
213
|
+
timeout?: number; // 超时时间(毫秒),默认 60000
|
|
214
|
+
retryCount?: number; // 重试次数,默认 3
|
|
215
|
+
modalMode?: boolean; // 是否使用模态框模式
|
|
216
|
+
theme?: 'light' | 'dark' | 'auto'; // 主题,默认 'auto'
|
|
217
|
+
language?: string; // 语言,默认 'zh-CN'
|
|
218
|
+
enableFrameStorage?: boolean; // 是否启用帧存储
|
|
219
|
+
cameraConfig?: {
|
|
220
|
+
width?: number; // 摄像头宽度
|
|
221
|
+
height?: number; // 摄像头高度
|
|
222
|
+
facingMode?: 'user' | 'environment'; // 摄像头方向
|
|
223
|
+
};
|
|
224
|
+
uiConfig?: {
|
|
225
|
+
showProgress?: boolean; // 是否显示进度
|
|
226
|
+
showInstructions?: boolean; // 是否显示指引
|
|
227
|
+
enableSound?: boolean; // 是否启用声音
|
|
228
|
+
};
|
|
229
|
+
}
|
|
230
|
+
```
|
|
231
|
+
|
|
232
|
+
### HTML 属性 (Attributes)
|
|
233
|
+
|
|
234
|
+
| 属性 | 类型 | 必填 | 说明 |
|
|
235
|
+
|------|------|------|------|
|
|
236
|
+
| `api-endpoint` | string | 是 | API 服务地址 |
|
|
237
|
+
| `modal-mode` | boolean | 否 | 是否使用模态框模式 |
|
|
238
|
+
| `theme` | 'light' \| 'dark' \| 'auto' | 否 | 主题模式,默认 'auto' |
|
|
239
|
+
| `language` | string | 否 | 语言,默认 'zh-CN' |
|
|
240
|
+
| `timeout` | number | 否 | 超时时间(毫秒),默认 60000 |
|
|
241
|
+
| `retry-count` | number | 否 | 重试次数,默认 3 |
|
|
242
|
+
|
|
243
|
+
### 方法 (Methods)
|
|
244
|
+
|
|
245
|
+
```typescript
|
|
246
|
+
// 初始化检测器
|
|
247
|
+
await detector.init(config?: Partial<LivenessDetectorConfig>): Promise<void>
|
|
248
|
+
|
|
249
|
+
// 开始检测(返回检测结果)
|
|
250
|
+
await detector.detect(): Promise<DetectionResult>
|
|
251
|
+
|
|
252
|
+
// 停止检测
|
|
253
|
+
await detector.stop(): Promise<void>
|
|
254
|
+
|
|
255
|
+
// 反初始化(清理资源)
|
|
256
|
+
await detector.deinit(): Promise<void>
|
|
257
|
+
|
|
258
|
+
// 获取当前状态
|
|
259
|
+
detector.getStatus(): {
|
|
260
|
+
initialized: boolean;
|
|
261
|
+
detecting: boolean;
|
|
262
|
+
sessionId: string | null;
|
|
263
|
+
phase?: DetectionPhase;
|
|
264
|
+
progress?: number;
|
|
265
|
+
}
|
|
266
|
+
```
|
|
267
|
+
|
|
268
|
+
### 事件 (Events)
|
|
269
|
+
|
|
270
|
+
| 事件名 | 说明 | 事件详情类型 |
|
|
271
|
+
|--------|------|-------------|
|
|
272
|
+
| `initialized` | 初始化完成 | `{ config: LivenessDetectorConfig }` |
|
|
273
|
+
| `detectionStart` | 检测开始 | `DetectionStartEvent` |
|
|
274
|
+
| `detectionProgress` | 检测进度更新 | `DetectionProgressEvent` |
|
|
275
|
+
| `detectionComplete` | 检测完成 | `DetectionCompleteEvent` |
|
|
276
|
+
| `detectionError` | 检测错误 | `DetectionErrorEvent` |
|
|
277
|
+
| `detectionStopped` | 检测停止 | `{ sessionId: string }` |
|
|
278
|
+
|
|
279
|
+
### 类型定义
|
|
280
|
+
|
|
281
|
+
```typescript
|
|
282
|
+
interface DetectionResult {
|
|
283
|
+
success: boolean;
|
|
284
|
+
confidence: number;
|
|
285
|
+
timestamp: number;
|
|
286
|
+
sessionId: string;
|
|
287
|
+
// ... 更多字段
|
|
288
|
+
}
|
|
289
|
+
|
|
290
|
+
interface DetectionStartEvent {
|
|
291
|
+
sessionId: string;
|
|
292
|
+
config: DetectionConfig;
|
|
293
|
+
}
|
|
294
|
+
|
|
295
|
+
interface DetectionProgressEvent {
|
|
296
|
+
sessionId: string;
|
|
297
|
+
phase: DetectionPhase;
|
|
298
|
+
progress: number;
|
|
299
|
+
currentAction?: string;
|
|
300
|
+
timeRemaining?: number;
|
|
301
|
+
}
|
|
302
|
+
|
|
303
|
+
interface DetectionCompleteEvent {
|
|
304
|
+
sessionId: string;
|
|
305
|
+
result: DetectionResult;
|
|
306
|
+
duration: number;
|
|
307
|
+
}
|
|
308
|
+
|
|
309
|
+
interface DetectionErrorEvent {
|
|
310
|
+
sessionId: string;
|
|
311
|
+
error: string;
|
|
312
|
+
code?: string;
|
|
313
|
+
recoverable?: boolean;
|
|
314
|
+
}
|
|
315
|
+
```
|
|
316
|
+
|
|
317
|
+
## 样式说明
|
|
318
|
+
|
|
319
|
+
**无需额外 CSS 文件!**
|
|
320
|
+
|
|
321
|
+
样式已经内置在 JavaScript 中,通过 Shadow DOM 自动注入。组件会自动:
|
|
322
|
+
- 适配浅色/深色主题
|
|
323
|
+
- 响应式布局
|
|
324
|
+
- 继承父元素的 CSS 变量
|
|
325
|
+
|
|
326
|
+
如需自定义样式,可以通过 CSS 变量覆盖:
|
|
327
|
+
|
|
328
|
+
```css
|
|
329
|
+
liveness-detector {
|
|
330
|
+
--ld-primary-color: #007bff;
|
|
331
|
+
--ld-border-radius: 8px;
|
|
332
|
+
/* 更多变量... */
|
|
333
|
+
}
|
|
334
|
+
```
|
|
335
|
+
|
|
336
|
+
## 浏览器支持
|
|
337
|
+
|
|
338
|
+
- Chrome >= 90
|
|
339
|
+
- Firefox >= 88
|
|
340
|
+
- Safari >= 14
|
|
341
|
+
- Edge >= 90
|
|
342
|
+
- 支持 Web Components 的现代浏览器
|
|
343
|
+
|
|
344
|
+
## 许可证
|
|
345
|
+
|
|
346
|
+
MIT License
|
|
347
|
+
|
|
348
|
+
## 支持
|
|
349
|
+
|
|
350
|
+
如有问题,请提交 [Issue](https://github.com/your-org/liveness-detection/issues)
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 活体检测Web Component入口文件
|
|
3
|
+
* 导出所有公共API和类型定义
|
|
4
|
+
*/
|
|
5
|
+
export { LivenessDetector } from './LivenessDetector';
|
|
6
|
+
export type { LivenessDetectorConfig, DetectionStartEvent, DetectionProgressEvent, DetectionCompleteEvent, DetectionErrorEvent } from './LivenessDetector';
|
|
7
|
+
export { createLivenessDetector } from './utils/factory';
|
|
8
|
+
export { validateConfig } from './utils/validation';
|
|
9
|
+
export { DEFAULT_CONFIG } from './constants';
|
|
10
|
+
export declare const VERSION: string;
|
|
11
|
+
declare global {
|
|
12
|
+
interface HTMLElementTagNameMap {
|
|
13
|
+
'liveness-detector': import('./LivenessDetector').LivenessDetector;
|
|
14
|
+
}
|
|
15
|
+
}
|