更新记录
1.0.0(2026-05-25)
新增功能
- 新增组件:
<ima-liveness>,uni-app x 离线人脸活体检测 UTS 原生组件
- 新增属性:
facing、previewCornerRadius、previewCornerRadiusRate、enabled、actions、requiredFrames、autoStart、debug、autoRecordVideo、recordAudio、saveVideoToGallery、livenessMode、colorPhaseDuration、colorRandomOrder、previewColorFlash、autoMaxScreenBrightness
- 新增事件:
onCameraOpened、onCameraClosed、onCameraError、onActionChange、onActionCompleted、onLivenessPass、onFaceStatus、onFaceError、onVideoRecordStart、onVideoRecordEnd、onVideoRecordError、onColorPhaseChange、onColorLivenessPass、onColorLivenessFail
- 新增方法(expose):
open、close、reset、isOpened、startDetection、restartDetection
- 支持动作活体:
mouth_open、blink、smile、head_nod、head_shake、head_shake_left、head_shake_right
- 支持炫彩活体(白/红/绿/蓝采样),可选
colorRandomOrder 随机颜色顺序
- 支持混合模式
livenessMode="hybrid"(炫彩 + 动作)
- 支持检测过程自动录像:
autoRecordVideo;分析帧录制模式(Preview + Analysis 两路,避免预览变暗);可选 recordAudio 与 saveVideoToGallery
- 支持
previewColorFlash 预览框内炫彩 overlay,或页面整页变色(previewColorFlash="false")
- 支持
autoMaxScreenBrightness 检测期间自动将窗口亮度调至最大并保持常亮
android端 基于 CameraX + ML Kit 完成开发;示例见宿主工程 pages/camera/(动作活体、随机动作、炫彩活体、混合流程、自动录像等)
ios端 暂未实现(保留模板)
harmony端 兼容式组件不支持
- 初始版
问题修复
无
功能优化
无
平台兼容性
uni-app(4.87)
| Vue2 |
Vue2插件版本 |
Vue3 |
Vue3插件版本 |
Chrome |
Safari |
app-vue |
app-vue插件版本 |
app-nvue |
app-nvue插件版本 |
Android |
Android插件版本 |
iOS |
鸿蒙 |
鸿蒙插件版本 |
| √ |
1.0.0 |
√ |
1.0.0 |
× |
× |
√ |
1.0.0 |
√ |
1.0.0 |
5.0 |
1.0.0 |
× |
5.0以下(不包括5.0) |
1.0.0 |
| 微信小程序 |
支付宝小程序 |
抖音小程序 |
百度小程序 |
快手小程序 |
京东小程序 |
鸿蒙元服务 |
QQ小程序 |
飞书小程序 |
小红书小程序 |
快应用-华为 |
快应用-联盟 |
| × |
× |
× |
× |
× |
× |
× |
× |
× |
× |
× |
× |
uni-app x(4.87)
| Chrome |
Safari |
Android |
Android插件版本 |
iOS |
鸿蒙 |
鸿蒙插件版本 |
微信小程序 |
| × |
× |
5.0 |
1.0.0 |
× |
5.0以下(不包括5.0) |
1.0.0 |
× |
其他
离线人脸活体检测,全程离线,无需联网,可自定义页面(ima-liveness)
离线人脸活体检测(ima-liveness) 原生组件,支持 动作活体、炫彩活体、混合活体,可选 检测过程自动录像、预览圆角、屏幕最大亮度 等能力。全程离线,无需联网。
⚠️注意️
- 本插件为 uni-app x UTS 原生组件,Android 端需制作自定义基座 后真机调试
- ⚠️注意️:只能在
.nvue、.uvue 页面中使用,不支持 .vue
- 组件标签为
<ima-liveness>
- 本插件实现的是 活体检测(Liveness),不是人脸识别、人脸比对、人脸搜索
ios端 暂未实现(保留模板)
harmony端 兼容式组件不支持
- 宿主工程示例页路径:
pages/camera/(动作活体、随机动作、炫彩活体、混合流程、自动录像等)
支持功能
open:打开摄像头预览
close:关闭摄像头预览
reset:重置活体检测状态
isOpened:查询摄像头预览是否已打开
startDetection:手动开始活体检测(可传入动作列表)
restartDetection:停止后重新开始检测
- 动作活体:眨眼、张嘴、微笑、点头、摇头等(见下方动作列表)
- 炫彩活体:屏幕白/红/绿/蓝阶段采样,防照片/屏幕攻击
- 混合活体:
livenessMode="hybrid",先炫彩后动作(原生协调器顺序)
- 自动录像:
autoRecordVideo,采用分析帧录制(Preview + Analysis),避免绑定 VideoCapture 导致预览变暗
- 预览圆角:
previewCornerRadius / previewCornerRadiusRate,支持圆形预览
- 炫彩展示:
previewColorFlash="true" 在预览框内 overlay;false 时由页面整页变色
- 自动最大亮度:
autoMaxScreenBrightness,检测期间窗口亮度调至最大并保持常亮
活体模式(livenessMode)
| 值 |
说明 |
action |
仅动作活体(默认) |
color |
仅炫彩活体 |
hybrid |
炫彩通过后继续动作活体 |
支持的动作(actions)
| 值 |
说明 |
blink |
眨眼 |
mouth_open |
张嘴 |
smile |
微笑 |
head_nod |
点头 |
head_shake |
左右摇头 |
head_shake_left |
向左摇头 |
head_shake_right |
向右摇头 |
自定义调整
- 自定义调整页面地址:
uni_modules/ima-liveness/utssdk/app-android/index.vue
- 炫彩阈值、AWB、采样逻辑等可在
utssdk/app-android/ 下 Kotlin 源文件中调整(修改后需重编自定义基座)
- 类型定义:
uni_modules/ima-liveness/utssdk/interface.uts
需要权限
- 摄像头(必须)
- 麦克风(
autoRecordVideo + recordAudio 时)
- 存储 / 相册(
saveVideoToGallery 时)
"android.permission.CAMERA"
"android.permission.RECORD_AUDIO"
"android.permission.READ_MEDIA_VIDEO"
"android.permission.READ_EXTERNAL_STORAGE"
"android.permission.WRITE_EXTERNAL_STORAGE"
- 插件已在
AndroidManifest.xml 中声明上述权限;宿主 manifest.json 的 distribute.android.permissions 需同步配置
// 活体检测必须
<uses-permission android:name="android.permission.CAMERA" />
// 自动录像且含音频时需要
<uses-permission android:name="android.permission.RECORD_AUDIO" />
// 保存录像到相册时需要
<uses-permission android:name="android.permission.READ_MEDIA_VIDEO" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
使用示例【此示例仅实现基础动作活体,更多示例请导入宿主工程】
- 新建一个
liveness.nvue 文件
- ⚠️注意️:只能在
.nvue、.uvue 的文件后缀下才生效,不支持 .vue
<template>
<view class="page">
<text class="title">请将正脸置于框内</text>
<text class="tip">{{ actionTip }}</text>
<view class="camera-wrap">
<ima-liveness
ref="livenessRef"
class="camera-view"
facing="front"
:enabled="true"
:actions="livenessActions"
:requiredFrames="5"
:autoStart="true"
:previewCornerRadiusRate="0.5"
@onCameraOpened="onCameraOpened"
@onActionChange="onActionChange"
@onLivenessPass="onLivenessPass"
@onFaceError="onFaceError"
/>
</view>
<text class="status">{{ statusText }}</text>
</view>
</template>
<script>
export default {
data() {
return {
livenessActions: ['blink', 'mouth_open'],
actionTip: '请保持正脸',
statusText: '准备开始检测',
}
},
methods: {
onCameraOpened() {
this.statusText = '相机已打开,请完成活体动作'
},
onActionChange(e) {
const detail = e.detail || {}
this.actionTip = detail.tip || '请完成动作'
this.statusText = '动作 ' + ((detail.index || 0) + 1) + '/' + (detail.total || 0)
},
onLivenessPass(e) {
console.log('活体通过', e.detail)
this.statusText = '活体检测通过'
uni.showToast({ title: '验证通过', icon: 'success' })
// 可将结果回传上一页
const pages = getCurrentPages()
if (pages.length >= 2) {
const prev = pages[pages.length - 2]
if (prev.$vm && prev.$vm.onLivenessResult) {
prev.$vm.onLivenessResult({ passed: true, ...(e.detail || {}) })
}
}
uni.navigateBack()
},
onFaceError(e) {
console.warn('检测错误', e.detail)
},
},
}
</script>
<style>
.page {
flex: 1;
align-items: center;
padding: 40rpx;
}
.title {
font-size: 32rpx;
font-weight: 600;
}
.tip {
margin-top: 24rpx;
color: #1677ff;
}
.camera-wrap {
margin-top: 40rpx;
width: 620rpx;
height: 620rpx;
}
.camera-view {
width: 500rpx;
height: 500rpx;
}
.status {
margin-top: 40rpx;
font-size: 28rpx;
}
</style>
炫彩活体示例(片段)
<ima-liveness
facing="front"
livenessMode="color"
:colorPhaseDuration="600"
:previewColorFlash="false"
:actions="['blink']"
:autoStart="true"
@onColorPhaseChange="onColorPhaseChange"
@onColorLivenessPass="onColorLivenessPass"
@onColorLivenessFail="onColorLivenessFail"
@onLivenessPass="onLivenessPass"
/>
自动录像示例(片段)
<ima-liveness
facing="front"
:actions="['blink', 'mouth_open']"
:autoRecordVideo="true"
:recordAudio="true"
:saveVideoToGallery="true"
@onVideoRecordStart="onVideoRecordStart"
@onVideoRecordEnd="onVideoRecordEnd"
@onVideoRecordError="onVideoRecordError"
@onLivenessPass="onLivenessPass"
/>
Api
| 属性 |
类型 |
默认值 |
说明 |
平台 |
| facing |
String |
"front" |
摄像头:front(前置)、back(后置) |
android |
| previewCornerRadius |
Number |
0 |
预览圆角半径(像素) |
android |
| previewCornerRadiusRate |
Number |
0.5 |
预览圆角比例(0~1),0.5 为圆形 |
android |
| enabled |
Boolean |
true |
是否启用检测 |
android |
| actions |
Array |
[] |
动作列表,空则使用内置默认序列 |
android |
| requiredFrames |
Number |
5 |
单动作判定所需连续帧数 |
android |
| autoStart |
Boolean |
true |
相机打开后是否自动开始检测 |
android |
| debug |
Boolean |
false |
调试模式 |
android |
| autoRecordVideo |
Boolean |
false |
检测过程是否自动录像 |
android |
| recordAudio |
Boolean |
true |
录像是否包含麦克风(需 autoRecordVideo) |
android |
| saveVideoToGallery |
Boolean |
false |
录像是否保存到系统相册 |
android |
| livenessMode |
String |
"action" |
活体模式:action / color / hybrid |
android |
| colorPhaseDuration |
Number |
450 |
炫彩单阶段时长(ms) |
android |
| colorRandomOrder |
Boolean |
false |
炫彩颜色顺序是否随机(白基准固定最前) |
android |
| previewColorFlash |
Boolean |
false |
是否在预览框内显示炫彩 overlay |
android |
| autoMaxScreenBrightness |
Boolean |
false |
检测期间是否自动将屏幕亮度调至最大 |
android |
方法
| 方法名称 |
说明 |
方法参数 |
平台 |
| open |
打开摄像头预览 |
无 |
android |
| close |
关闭摄像头预览 |
无 |
android |
| reset |
重置检测状态 |
无 |
android |
| isOpened |
查询预览是否已打开 |
无,返回 Boolean |
android |
| startDetection |
开始活体检测 |
actionList:动作数组,可选 |
android |
| restartDetection |
重新开始检测 |
actionList:动作数组,可选 |
android |
事件
| 事件名称 |
说明 |
回调参数(detail) |
平台 |
| onCameraOpened |
相机打开 |
{} |
android |
| onCameraClosed |
相机关闭 |
{} |
android |
| onCameraError |
相机错误 |
{ action, message } |
android |
| onActionChange |
切换动作提示 |
{ action, index, total, tip, hasFace?, faceCount?, rePrompt? } |
android |
| onActionCompleted |
单项动作完成 |
{ action, index, total } |
android |
| onLivenessPass |
活体检测通过 |
{ actions, colorPassed?, mode? } |
android |
| onFaceStatus |
人脸状态 |
{ hasFace, faceCount } |
android |
| onFaceError |
检测错误 |
{ code, message } |
android |
| onVideoRecordStart |
自动录像开始 |
{ path } |
android |
| onVideoRecordEnd |
自动录像结束 |
{ path, uri, duration, size, suffix } |
android |
| onVideoRecordError |
自动录像失败 |
{ action, message } |
android |
| onColorPhaseChange |
炫彩阶段变化 |
{ phase, index, total, tip, color } |
android |
| onColorLivenessPass |
炫彩阶段通过 |
{ passed } |
android |
| onColorLivenessFail |
炫彩阶段失败 |
{ reason, retryable } |
android |