更新记录
1.0.0(2026-09-30)
首次发布
平台兼容性
uni-app x(4.75)
| Chrome | Safari | Android | iOS | 鸿蒙 | 微信小程序 |
|---|---|---|---|---|---|
| × | × | 5.0 | 14 | 12 | × |
其他
| 多语言 | 暗黑模式 | 宽屏模式 | 蒸汽模式 |
|---|---|---|---|
| × | × | √ | √ |
yh-nsfw 内容安全审核与证件识别插件 — 使用文档
插件路径:
uni_modules/yh-nsfw/
版本:1.1.0
适用框架:uni-app x(HBuilderX ^5.07 / uni-app-x ^4.75)
参考页面:pages/jianhuang/jianhuang.uvue
授权与价格
| 授权版本 | 价格 | 包含内容 | 适用人群 |
|---|---|---|---|
| 普通版 | 18.88 元 | 编译后的 UTS 插件,可直接在项目中使用插件能力 | 只需要接入功能、不关心底层实现的开发者 |
| 源码版 | 388.88 元 | 全部 UTS / Kotlin / Swift / ArkTS 源码,可自由阅读、修改、二次开发 | 需要定制审核逻辑、深度集成或自行维护的团队 |
- 普通版与源码版的区别仅在于是否提供源码;各平台实际可用功能不同,请以下方"平台支持矩阵"为准(例如微信小程序端仅提供敏感词能力),并非每个平台都包含全部功能
- 源码版可自行调整检测阈值、增删模型、修改各端原生实现;修改后请自行维护,不再适用原版升级覆盖
- 授权为一次性付费,无后续年费、无按调用量收费(对比云端审核年费用,见 0.3 节)
★ 我们卖的不是模型本身,而是整合与整备能力
插件中的底层模型 / 引擎多为公开开源组件(清单及许可证见 0.9 节),它们可以被任何人免费获取。你为这份授权支付的费用,对应的是作者提供的整合、工程化与整备工作,主要包括:
- 跨端整合:将鉴黄、OCR、语音识别、敏感词检测等分散的开源能力整合为统一的 UTS 接口,在 Android / iOS / 鸿蒙 / Web / 小程序上一套调用方式
- 工程化落地:模型格式转换、推理引擎接入、内存与线程管理、视频抽帧与音轨提取、相机拍摄组件、异常兜底等大量"最后一公里"工作
- 流水线编排:鉴黄 + OCR + 敏感词的组合审核、违规帧判定、防静态图绕过等业务链路
- 持续维护:兼容性更新、问题修复与使用文档(按作者计划提供,不构成强制义务)
源码版的额外价值 —— 完全自主可控:
- 🔁 可自行更换模型:如替换为你自己训练或其他来源的 NSFW / OCR / 语音模型(需自行确认替换模型的授权,并适配输入输出格式)
- ⚙️ 可自行调配参数:违规概率阈值、抽帧率、连续违规帧数、敏感词库等均可按需修改
- 🛠️ 可改造原生实现:三端源码开放,可接入你自有的审核服务或私有模型
普通版适合"拿来即用"的开发者;源码版适合需要按自身业务深度定制、并具备相应技术能力的团队。购买普通版不包含上述自主改造所需的源码。
版权声明与商用授权
Copyright © 2026 远火(黑龙江)网络科技有限公司. All Rights Reserved.
- 本插件的原创部分(UTS/Kotlin/Swift/ArkTS 代码、审核编排逻辑、本文档)著作权归上述版权人所有,受《中华人民共和国著作权法》及《计算机软件保护条例》保护。著作权自开发完成之日起自动产生
- 商用授权:购买授权即获得在你自己名下的应用 / 产品中商业使用本插件的权利,功能可用于营利性业务
- 授权限制:
- 授权按开发者 / 主体授予,不得将插件本身或其源码(含源码版)以任何形式转售、出租、再授权、公开传播或作为插件 / 模板 / 脚手架分发给第三方
- 不得移除或篡改版权声明
- 普通版不含源码,不得进行反编译、逆向工程
- 第三方组件不适用本授权:插件所含模型 / 开源组件的著作权归各自权利人所有(清单见 0.9 节),你的商用使用须同时满足其许可证条件(如保留 LICENSE / NOTICE)。其中标"待确认"的组件,在其来源与许可证核实清楚之前,版权人不对其商用合规性作出保证,请使用方(及版权人本人)完成核实后再商用
- 本授权条款不限制使用方对其自有数据及基于本插件独立开发的业务成果所享有的权利
★ 敏感词库可自由配置(全端通用,含小程序)
插件自带 2925 个词的内建词库(涉黄、涉政、暴恐、辱骂、违禁品等),开箱即用;同时词库不是写死的,你可以按自己的业务自由替换或扩充。三种配置方式:
| 方式 | 调用 | 词库来源 | 适用情况 |
|---|---|---|---|
| ① 用内建词库 | loadWordLibrary() |
插件内置,零文件 IO | 大多数项目,什么都不用配 |
| ② 自定义 JSON 文件 | loadWordLibrary({ filePath: '/static/my-words.json' }) |
项目 /static/ 下你自己新建的 JSON 文件(插件不提供此文件) |
想长期维护一份自己的词库,替换掉内建词库 |
| ③ 运行时直接传词 | loadWordLibrary({ words: ['词1','词2'] }) |
代码 / 服务端下发的数组 | 服务端热更、按场景动态换词库 |
方式 ② 的文件放哪、怎么写:
- 路径:放到项目根目录的
/static/下(例如/static/my-words.json),调用时filePath就填/static/my-words.json - 内容就是一个字符串数组的 JSON,不要包对象:
["违禁词一", "违禁词二", "违禁词三"]
方式 ③ 可带版本号,便于统计当前用的是哪一版词库:
loadWordLibrary({ words: serverWords, version: '2026.09.30' })
补充说明:
- 内建词库的源文件在插件内
utssdk/shared/bundledWords.uts(由sensitiveWords-lite.json生成,共 2925 词);源码版用户也可以直接改这个文件再重新编译 - 词库加载后,
checkTextSync(同步文本审核)以及图片 / 视频 / 语音审核里的文字敏感词判定,都会使用你加载的这版词库 - 三种方式都支持,微信小程序端只有敏感词能力,同样用这套
loadWordLibrary+checkTextSync,改昵称、备注时直接调用即可
零、使用场景与端侧优势(为什么用这个插件)
0.1 典型应用场景(来自线上项目实战)
内容安全不是"一个鉴黄接口",而是贯穿用户全生命周期的一条链路。以下场景均已在实际项目(本地生活 + 社交类 App)中落地:
| 业务环节 | 具体场景 | 使用的能力 |
|---|---|---|
| 注册 / 编辑资料 | 昵称、个性签名、用户备注、地区等文字合规 | checkTextSync 敏感词检测 |
| 商家入驻 | 营业执照拍照 OCR,自动填充企业名称 / 统一社会信用代码 | scanBusinessPermit |
| 实名认证 | 身份证正反面 OCR,自动填充姓名 / 证件号 / 住址 | inspectDocumentImage |
| 头像上传 | 头像涉黄检测,违规直接拦截 | checkImages |
| 发布服务 / 动态 | 多图涉黄 + 图内文字(二维码、联系方式、广告词)识别审核 | checkImages(鉴黄 + OCR + 敏感词) |
| 发布视频 | 视频画面抽帧鉴黄 + 画面文字 + 音轨语音内容鉴定 + 防静态图绕过 | checkVideoUpload / openVideoSession + grabVideoFrame |
| 聊天 / 语音消息 | 语音内容鉴定(语音及视频音轨转文字 + 敏感词审核) | checkAudioUpload / transcribeAudio |
| 小程序 / 机构认证 | 小程序名称、简介、Logo 审核 | checkTextSync + checkImages |
0.2 传统云端审核,到底有多贵
走云厂商内容安全 API,用户每发一张图、一条语音、一个昵称修改,都是一次可计费的 API 调用。以主流云厂商公开定价为例(价格具有时效性,下表仅供参考,实际收费请以各云厂商官网实时公示价格及你的合同为准):
| 审核项 | 云端单价 |
|---|---|
| 图片审核 · 通用 | 15 元 / 万次 |
| 图片审核 · 高级(头像 / 帖子 / 评论场景) | 30 元 / 万次 |
| 图片审核 · 大模型版 | 45 元 / 万次 |
| 文本审核(昵称 / 私聊 / 公聊评论) | 7.5 元 / 万次 |
| 文本审核 · 大模型版 | 20 元 / 万次 |
| 语音审核 | 225 元 / 万分钟(≈ 1.35 元 / 小时) |
| 视频语音审核 | 202.5 元 / 万分钟(≈ 1.22 元 / 小时) |
| 文档审核 | 0.225 元 / 50 页 |
| 图片 QPS 预留包 | 833 元 / QPS / 月 |
| 视频并发路数 | 466.66 元 / 路 / 月 |
这还只是"鉴定费"。一套完整的云端方案,还有四层隐藏成本:
- 上传流量费:图片 / 视频必须先完整上传到服务器才能审。一条 15 秒短视频 5~20MB,消耗的是用户 4G/5G 流量;弱网下用户要盯着上传进度条转圈,内容还没审,耐心先没了
- 对象存储(OSS/COS)费:违规内容也得先存一份、审完再删,存储费和请求次数费照收
- CDN / 回源带宽费:拉取待审文件、审核结果异步回调,都产生带宽费用
- 峰值扩容费:晚高峰 QPS 不够,要么让用户排队,要么按 833 元 / QPS / 月买预留——大部分时间还闲置着
0.3 算一笔年账(1 万 DAU 的中小平台)
保守模型(假设性测算,仅供参考,实际成本因业务规模与厂商定价而异):日均发布图片 2 万张、文本检测 1 万次、视频 500 条 × 15 秒、语音 1000 条 × 20 秒:
| 成本项 | 年费用(估算) |
|---|---|
| 图片审核 730 万次 × 15 元/万 | ≈ 10,950 元 |
| 文本审核 365 万次 × 7.5 元/万 | ≈ 2,740 元 |
| 视频审核 760 小时 × 1.22 元/小时 | ≈ 930 元 |
| 语音审核 203 小时 × 1.35 元/小时 | ≈ 275 元 |
| OSS 存储 + 上传 / 回源带宽 | ≈ 5,000 ~ 15,000 元 |
| 峰值 QPS 预留(高峰保底) | 数千元起 |
| 合计 | 约 2 万 ~ 4 万元 / 年 |
而 10 万 DAU 时,这笔账就是 20 万 ~ 40 万元 / 年。内容越繁荣、社区越活跃,审核账单越贵——审核成本成了业务增长的"反向税"。
0.4 性价比:18.88 元到底有多值
做内容安全通常只有三条路:买云服务、自己造、用本插件。直接对比:
| 对比项 | 云端 API(年年付) | 完全自研 | yh-nsfw 普通版 | yh-nsfw 源码版 |
|---|---|---|---|---|
| 首次投入 | 0 元开通 | 30 万 ~ 80 万元 / 年人力 | 18.88 元 | 388.88 元 |
| 后续费用 | 2 万 ~ 40 万元 / 年,逐年续 | 持续养团队 | 0 | 0 |
| 上线周期 | 1~2 周(含服务端联调) | 3~6 个月起 | 半天接入 | 半天接入 |
| 覆盖端数 | 取决于逐家采购 | 三端各做一遍 | Android/iOS/鸿蒙/H5/小程序 | 同左 |
| 模型 / 词库维护 | 云厂商负责 | 自己采数据、训练、更新 | 作者按计划提供更新(不构成强制义务) | 自己掌控 |
| 定制自由度 | 低(只能配规则) | 高 | 中(阈值/词库可调) | 高 |
| 隐性成本 | 流量 + OSS + CDN + 扩容 | 管理成本 + 踩坑成本 | 无 | 无 |
几个直观的成本参照(仅针对已在为云端审核付费的用户):
- ☕ 费用参照:18.88 元约相当于云端方案(2 万 ~ 4 万元 / 年)不到半天的支出
- 🖼️ 按鉴定次数算:以云端图片审核 15 元 / 万次计,18.88 元约相当于 1.26 万次图片审核的费用(具体因厂商而异)
- 👨💻 源码版 vs 自研:一名会三端原生 + AI 模型的工程师,月薪通常 2 万 ~ 4 万元;388.88 元约相当于其半小时左右的人力成本,获得的是一套已在三端实现的工程参考。能否满足你的实际需求,请结合下方能力边界自行评估
- 📈 规模参照:业务量越大,云端按次计费的累计支出越高,而本插件授权费用固定。是否划算取决于你自身的业务模型与用量,请独立测算
🎯 普通版以较低的一次性支出替代云端按次累计付费;源码版提供全部源码供有能力的团队自行改造。请结合审核能力边界(0.7 节)理性评估,本插件不替代人工审核。
0.5 端侧识别:把成本消灭在用户的手机里
yh-nsfw 把审核能力(NSFW 鉴黄模型、OCR 引擎、语音识别、敏感词引擎)内置到客户端,绝大多数检测在设备本地完成、模型随包内置,使用方无需自建审核服务(端侧行为的例外情况见 0.6 节说明):
- 💰 无按次计费:对开发者没有调用次数费用,也无需购买 QPS 配额
- 📶 减少上传流量:图片选完即审、视频抽帧即审、语音就地转写,不必为审核把完整文件上传服务器,可节省用户上传流量及服务端入口带宽、对象存储
- ⚡ 响应较快:本地推理单图通常在数百毫秒级(具体耗时因设备性能而异);相比"上传完成 → 排队 → 审核 → 异步回调"的云端链路,反馈更及时
- 🔒 有助于隐私保护:身份证、营业执照等属于《个人信息保护法》规定的敏感个人信息。端侧处理可减少证件图像向服务器的传输;但请注意 0.6 节所列的系统服务例外,使用方仍需在隐私政策中如实披露
- 📴 多数场景离线可用:地下室、电梯、弱网等环境下,已加载好的本地模型仍可工作(首次使用需下载模型的场景除外)
- 🧩 架构较简单:无需审核服务端、回调接口、OSS 生命周期策略等,前端调用即可
- 🚀 利用设备端算力分担:检测在各用户设备上进行,使用方无需为高并发单独扩容(实际表现受设备 CPU/内存/电量约束)
0.6 端侧 vs 云端 一览
| 维度 | 云端 API 方案 | yh-nsfw 端侧方案 |
|---|---|---|
| 审核费用 | 按次累计计费 | 无按次费用(一次性授权) |
| 上传流量 | 需上传完整文件 | 一般无需为审核上传 |
| 对象存储 / CDN | 通常需要 | 一般不需要 |
| 峰值扩容 | 需按 QPS 购买 | 无需服务端扩容 |
| 响应速度 | 取决于网络与排队 | 通常数百毫秒级(因设备而异) |
| 弱网 / 离线 | 通常不可用 | 本地模型多数可用(例外见下) |
| 证件数据 | 图像上传至服务器 | 多在端侧处理(例外见下) |
| 服务端开发 | 需要鉴权 / 回调 / 重试 | 较少 |
| 成本曲线 | 随用量上涨 | 授权费用固定 |
⚠️ 端侧行为的例外(并非所有环节在所有设备上都完全离线):
- iOS 语音识别:插件优先使用设备端识别(
requiresOnDeviceRecognition);但当设备/系统不支持端侧中文识别时,会回退到系统语音识别服务,此时语音数据由 Apple 处理。使用方需在 App 隐私说明中披露,具体行为以设备实际支持情况为准 - Android OCR(ML Kit):文字识别组件由 Google 提供(非开源),依赖 Google Play Services;模型可能在首次使用时下载。在没有 GMS 的设备上能否正常工作,请务必真机验证
- 上述系统服务的数据处理规则适用对应平台的官方条款
💡 建议实践(端云结合):用端侧审核前置过滤大部分明显违规内容,仅对高风险 / 高价值内容(如提现、实名变更等)再走云端复审留证,从而减少云端调用量。是否采用及具体比例,请按你的业务合规要求自行确定。
0.7 ⚠️ 审核能力边界(务必知悉)
任何自动化审核(包括本插件,也包括所有云端服务)都不是 100% 准确的,本插件只能过滤大部分明显违规内容,不能保证全部识别:
- 存在漏判:经过裁剪、拼接、遮挡、翻拍、加滤镜、谐音变体、暗语、新出现的黑话等对抗手段的内容,可能绕过检测
- 存在误判:正常的艺术、医疗、教育、健身等内容可能被误拦,需给用户提供申诉入口
- 模型有边界:内置模型只覆盖其训练过的类别和语种,无法理解全部语境、讽刺与隐喻
- 抽帧有盲区:视频按固定间隔抽帧,理论上存在违规画面恰好落在两帧之间的可能(插件已用 dHash 跳帧等机制降低风险,但无法归零)
🔴 本插件的定位是"自动化初筛 + 人工提效工具",不是最终裁决者。正式上线务必保留人工复审 / 用户举报 / 内容下架机制,对高风险场景(支付、实名、未成年人相关等)加强审核。
0.8 免责声明
- 本插件按"现状"提供,作者不对审核结果的准确性、完整性、及时性作任何明示或默示的保证
- 因依赖本插件审核结果(包括漏判、误判)所导致的任何直接或间接损失、监管处罚、法律纠纷,由使用方自行承担全部责任
- 使用方有义务根据自身业务所处行业与适用法律法规,自行配置检测策略、补充词库,并建立必要的人工审核与应急处置流程
- 插件内模型、第三方依赖(推理引擎、OCR、语音识别组件等)的相关权利归各自权利人所有,使用方需自行确认其授权范围符合自身用途(详见 0.9 节清单)
- 插件代码本身不收集、不上传用户数据;0.6 节所列的系统服务由对应平台按其条款处理;使用方在插件之外自行实现的网络请求、数据上报等行为,与本插件无关
0.9 模型与第三方组件清单(授权与合规须知)
本插件由作者自研代码 + 下列模型 / 第三方组件构成。标"待确认"项表示需由作者核实来源后补充,使用方在确认前请谨慎商用;MIT / Apache 等开源许可均要求保留版权与许可声明。
| 组件 | 用途 / 所在端 | 来源 | 许可证 | 是否免费 |
|---|---|---|---|---|
| nsfw_model.tflite / .ms | NSFW 鉴黄(安卓/鸿蒙),MobileNetV2 224×224 五分类 | 待确认(常见同类开源模型如 GantMan/nsfw_model 为 MIT;转换格式不改变原版权归属) | 待确认 | 待确认 |
| TensorFlow Lite | Android 推理引擎 | Apache-2.0 | 是 | |
| MindSpore Lite | 鸿蒙推理引擎 | 华为 | Apache-2.0 | 是 |
| encoder/decoder/joiner.int8.onnx | 语音 Zipformer int8(安卓/鸿蒙) | k2-fsa/sherpa-onnx 官方模型 | Apache-2.0 | 是 |
| sherpa-onnx | 语音识别引擎(安卓/鸿蒙) | k2-fsa | Apache-2.0 | 是 |
| ML Kit Text Recognition(含中文) | Android OCR | Google(非开源,依赖 Google Play Services) | ML Kit 服务条款 | 免费但受条款约束 |
| Vision / SFSpeechRecognizer | iOS OCR / 语音 | Apple 系统框架 | Apple 许可 | 系统提供 |
| module_ocr.har | 鸿蒙 OCR | 待确认(再分发授权必须核实) | 待确认 | 待确认 |
| @ohos/mp4parser | 鸿蒙视频解析 | 待确认 | 待确认 | 待确认 |
| Tesseract.js + tessdata | Web OCR(需宿主自行引入) | tesseract.js 社区 | Apache-2.0 | 是 |
| 内建敏感词库 | 文本检测 | 待确认(若整理自第三方词库需确认授权) | 待确认 | 待确认 |
合规建议:
- 在插件包内随附各开源组件的 LICENSE 原文及版权声明(NOTICE)
- 商用发布前完成全部"待确认"项的来源与许可证核实,尤其是 module_ocr.har(源码版会向购买者交付该文件)和敏感词库
- 使用方需在自己 App 的隐私政策中,按实际情况披露端侧处理及 0.6 节所列系统服务
★★★ 引用插件时三条必做配置(置顶提醒)
将 yh-nsfw 插件引用到新项目时,以下三项缺一不可,漏配将导致编译报错或功能缺失:
1. 复制 common/ 下两个文件到项目根目录
插件内 uni_modules/yh-nsfw/common/ 包含两个业务封装文件,页面通过 @/common/xxx.uts 引用,必须复制到项目根目录 common/ 下,否则编译报错:
[plugin:uts] Cannot find module "@/common/nsfw-check" from "pages/index/index.uvue"
[plugin:uni:app-uvue] Could not resolve "@/common/permission-tip-manager.uts"
cp uni_modules/yh-nsfw/common/nsfw-check.uts common/nsfw-check.uts
cp uni_modules/yh-nsfw/common/permission-tip-manager.uts common/permission-tip-manager.uts
nsfw-check.uts— 上传前审核公共封装(鉴黄/视频/语音一站式检测 + 违规提示)permission-tip-manager.uts— Android 媒体权限请求封装(相机/录音/存储权限统一申请 + 拒绝引导)
详见 6.1.1 节
2. 复制 harmony-configs/ 到项目根目录
插件内 uni_modules/yh-nsfw/harmony-configs/ 是鸿蒙原生工程配置模板(module.json5 + string.json),必须复制到项目根目录,否则鸿蒙端编译时无法读取权限声明,导致功能缺失或运行时权限被拒。
cp -r uni_modules/yh-nsfw/harmony-configs harmony-configs
详见 6.1.2 节
3. ★ iOS 必须配置语音识别权限(NSSpeechRecognitionUsageDescription)
重点提醒:yh-nsfw 的语音 / 视频音轨内容鉴定功能(transcribeAudio)在 iOS 端使用 Apple SFSpeechRecognizer 框架,必须在 manifest.json 的 app-ios.distribute.privacyDescription 中声明 NSSpeechRecognitionUsageDescription,否则:
- 调用
transcribeAudio时 iOS 系统直接拒绝,功能无响应 - App Store 审核会因缺少语音识别隐私描述而被拒
- 即使不主动调用 transcribeAudio,只要代码中引用了该函数,iOS 仍可能触发权限检查
配置方法(manifest.json):
"app-ios": {
"distribute": {
"privacyDescription": {
"NSSpeechRecognitionUsageDescription": "将您发送的语音消息及视频中的语音转换为文字,用于离线内容安全审核。"
}
}
}
同时需要
NSMicrophoneUsageDescription(麦克风录音)配合,否则录音功能无权限。完整 iOS 权限配置见 5.2 节。
一、插件能力总览
yh-nsfw 是一个内容安全一体化 UTS 插件,检测与识别主要在设备本地执行,模型随包内置(端侧行为的例外情况见 0.6 节)。
| 能力模块 | 说明 |
|---|---|
| 图片鉴黄 | MobileNetV2 NSFW 五分类(drawings/hentai/neutral/porn/sexy),判定 porn/hentai 概率是否超阈值 |
| 视频画面鉴黄 | 会话式抽帧 → dHash 跳帧 → 鉴黄推理,支持连续违规帧提前终止 |
| 语音 / 视频音轨内容鉴定 | Sherpa-ONNX Zipformer int8 将音频或视频音轨转写为文字,再做敏感词审核,识别语音中违规内容 |
| 敏感词检测 | FastScan 自动机敏感词扫描,同步返回打码文本 + 命中词列表 |
| 证件 OCR 识别 | 身份证、营业执照、银行卡、车牌、VIN、登机牌、考试卷、合同等文档识别 |
| 一站式审核 | 图片(鉴黄 + OCR 文字 + 敏感词)、视频(画面鉴黄 + 帧文字 + 音轨语音鉴定)、音频(语音鉴定) |
二、平台支持矩阵
| 功能 | Android | iOS | 鸿蒙 | H5 (Web) | 微信小程序 |
|---|---|---|---|---|---|
| 图片鉴黄 (detectImage) | ✓ | ✓ | ✓ | — | — |
| 视频抽帧鉴黄 (openVideoSession/grabVideoFrame) | ✓ | ✓ | ✓ | — | — |
| 语音 / 视频音轨鉴定 (transcribeAudio) | ✓ | ✓ | ✓ | — | — |
| 敏感词检测 (checkTextSync/loadWordLibrary) | ✓ | ✓ | ✓ | ✓ | ✓ |
| 证件 OCR (inspectDocumentImage/scanBusinessPermit) | ✓ | ✓ | ✓ | ✓ | — |
| OCR 运行时查询 (describeOcrRuntime) | ✓ | ✓ | ✓ | ✓ | — |
| 一站式图片审核 (checkImage) | ✓ | ✓ | ✓ | — | — |
| 一站式视频审核 (checkVideo) | ✓ | ✓ | ✓ | — | — |
| 一站式音频审核 (checkAudio) | ✓ | ✓ | ✓ | — | — |
条件编译:鉴黄/视频/语音相关 API 仅在
#ifdef APP-ANDROID || APP-IOS || APP-HARMONY块内调用;OCR 在 H5 端可用;敏感词全端可用。
三、各端权限清单
3.1 Android 权限
| 权限 | 用途 | 适用版本 |
|---|---|---|
android.permission.CAMERA |
证件拍摄组件(lqj-ocr-live)相机预览 | 全版本 |
android.permission.RECORD_AUDIO |
录制语音消息 + 语音转文字 | 全版本 |
android.permission.READ_MEDIA_IMAGES |
从相册选择图片进行鉴黄/OCR | Android 13+ (API 33+) |
android.permission.READ_MEDIA_VIDEO |
从相册选择视频进行鉴黄/音轨审核 | Android 13+ (API 33+) |
android.permission.READ_MEDIA_AUDIO |
选择音频文件进行转写审核 | Android 13+ (API 33+) |
android.permission.READ_EXTERNAL_STORAGE (maxSdkVersion=32) |
读取媒体文件(兼容 Android 12 及以下) | Android ≤12 (API ≤32) |
3.2 iOS 隐私描述(Info.plist)
| Key | 用途 |
|---|---|
NSCameraUsageDescription |
拍摄文档图像执行 OCR 识别、证件拍摄与内容审核 |
NSPhotoLibraryUsageDescription |
读取本地图片/视频执行 OCR、鉴黄审核与文档分析 |
NSPhotoLibraryAddUsageDescription |
保存导出的整理图片或 PDF 文档 |
NSMicrophoneUsageDescription |
录制语音消息及视频中的语音,进行语音转文字审核 |
NSSpeechRecognitionUsageDescription |
语音消息及视频语音转文字,用于离线内容安全审核 |
3.3 鸿蒙 (HarmonyOS) 权限
鸿蒙权限在 module.json5 的 requestPermissions 数组中声明:
| 权限 | 用途 |
|---|---|
ohos.permission.CAMERA |
证件拍摄组件相机预览 |
ohos.permission.READ_IMAGEVIDEO |
读取相册图片/视频 |
ohos.permission.READ_AUDIO |
读取音频文件进行语音转写 |
安装 yh-nsfw UTS 插件后,插件
utssdk/app-harmony/中的权限声明会自动合并到最终鸿蒙工程。如需手动添加,编辑鸿蒙工程entry/src/main/module.json5的requestPermissions。
四、各端环境要求
4.1 Android
| 项目 | 要求 |
|---|---|
| minSdkVersion | 21(插件最低要求) |
| targetSdkVersion | 34(Android 14,支持 READMEDIA* 权限分级) |
| abiFilters | ["arm64-v8a"](仅支持 64 位 ARM) |
| HBuilderX | ^5.07 |
| uni-app-x | ^4.75 |
Gradle 依赖(插件自动引入):
androidx.camera:camera-core:1.3.3
androidx.camera:camera-camera2:1.3.3
androidx.camera:camera-lifecycle:1.3.3
androidx.camera:camera-view:1.3.3
com.google.mlkit:text-recognition:16.0.1
com.google.mlkit:text-recognition-chinese:16.0.1
Maven 仓库(插件 config.json 已配置,自动合并):
maven { url 'https://maven.aliyun.com/repository/public' }
maven { url 'https://maven.aliyun.com/repository/google' }
maven { url 'https://maven.aliyun.com/repository/central' }
4.2 iOS
| 项目 | 要求 |
|---|---|
| deploymentTarget | 14.0 |
| HBuilderX | ^5.07 |
| uni-app-x | ^4.75 |
原生框架(插件自动引入):
- Vision.framework(文字识别)
- AVFoundation(音轨提取)
- Photos(相册访问)
隐私清单: 插件已内置 PrivacyInfo.xcprivacy,符合 App Store 隐私要求。
4.3 鸿蒙 (HarmonyOS)
| 项目 | 要求 |
|---|---|
| HBuilderX | ^5.07 |
| uni-app-x | ^4.75 |
| ArkTS 版本 | 鸿蒙 NEXT(API 12+) |
OHPM 依赖(插件 config.json 已配置,自动合并):
{
"sherpa_onnx": "1.13.3",
"@ohos/mp4parser": "2.0.7",
"module_ocr": "./libs/module_ocr.har"
}
sherpa_onnx:语音转写引擎@ohos/mp4parser:视频音轨提取module_ocr:OCR 文字识别引擎(本地 HAR 包)
五、manifest.json 配置
5.1 Android 权限配置
在 manifest.json 的 app-android.distribute 中添加:
"app-android": {
"distribute": {
"minSdkVersion": "21",
"targetSdkVersion": "34",
"abiFilters": ["arm64-v8a"],
"permissions": [
"<uses-permission android:name=\"android.permission.CAMERA\"/>",
"<uses-permission android:name=\"android.permission.RECORD_AUDIO\"/>",
"<uses-permission android:name=\"android.permission.READ_MEDIA_IMAGES\"/>",
"<uses-permission android:name=\"android.permission.READ_MEDIA_VIDEO\"/>",
"<uses-permission android:name=\"android.permission.READ_MEDIA_AUDIO\"/>",
"<uses-permission android:name=\"android.permission.READ_EXTERNAL_STORAGE\" android:maxSdkVersion=\"32\"/>"
]
}
}
5.2 iOS 隐私描述配置
在 manifest.json 的 app-ios.distribute 中添加:
"app-ios": {
"distribute": {
"deploymentTarget": "14.0",
"privacyDescription": {
"NSCameraUsageDescription": "用于拍摄文档图像并执行 OCR 识别、证件拍摄与内容审核。",
"NSPhotoLibraryUsageDescription": "用于读取本地图片/视频执行 OCR 识别、鉴黄审核与文档分析。",
"NSPhotoLibraryAddUsageDescription": "用于保存导出的整理图片或 PDF 文档。",
"NSMicrophoneUsageDescription": "用于录制语音消息及视频中的语音,以进行语音转文字内容安全审核。",
"NSSpeechRecognitionUsageDescription": "将您发送的语音消息及视频中的语音转换为文字,用于离线内容安全审核。"
}
}
}
5.3 鸿蒙配置
在 manifest.json 的 app-harmony.distribute 中添加基础配置:
"app-harmony": {
"distribute": {
"deviceTypes": ["phone", "tablet"],
"deviceArchs": ["arm64-v8a"]
}
}
鸿蒙权限由 UTS 插件
utssdk/app-harmony/自动合并,无需在 manifest.json 手动声明。若手动配置,编辑鸿蒙工程的entry/src/main/module.json5。
5.4 鸿蒙原生工程配置(harmony-configs/)
项目根目录下的 harmony-configs/ 是鸿蒙原生工程配置模板,HBuilderX 编译鸿蒙时自动读取并合并到生成的鸿蒙工程中。
目录结构:
harmony-configs/
└── entry/
└── src/
└── main/
├── module.json5 ← 鸿蒙模块配置(权限/Ability/metadata)
└── resources/
└── base/
└── element/
└── string.json ← 权限说明文案与 Ability 名称
module.json5 关键配置项:
| 配置项 | 说明 |
|---|---|
deviceTypes |
支持设备类型:phone / tablet / 2in1 |
abilities |
入口 Ability(EntryAbility),声明 entity.system.home 实现桌面图标启动 |
querySchemes |
URL Scheme 白名单(如 weixin / wxopensdk,用于微信分享/登录跳转) |
requestPermissions |
鸿蒙运行时权限声明(见下表) |
metadata |
第三方 SDK 配置(wx_appid / GETUI_APPID / client_id 等) |
requestPermissions 权限清单:
| 权限 | 用途 | 说明 |
|---|---|---|
ohos.permission.INTERNET |
网络访问 | uniCloud 调用、HTTP 请求 |
ohos.permission.MICROPHONE |
麦克风录音 | 语音消息录制 + transcribeAudio 语音转写 |
ohos.permission.LOCATION |
精确定位 | 获取用户位置(如需地理位置功能) |
ohos.permission.APPROXIMATELY_LOCATION |
大致定位 | 辅助定位 |
yh-nsfw 鸿蒙权限补充:以上为项目基础权限。yh-nsfw 插件还需以下权限,由 UTS 插件
utssdk/app-harmony/自动合并:
ohos.permission.CAMERA— 证件拍摄组件ohos.permission.READ_IMAGEVIDEO— 读取相册图片/视频ohos.permission.READ_AUDIO— 读取音频文件如需手动添加,在
module.json5的requestPermissions数组中追加:{ "name": "ohos.permission.CAMERA", "reason": "$string:camera_permission_reason", "usedScene": { "abilities": ["EntryAbility"], "when": "inuse" } }, { "name": "ohos.permission.READ_IMAGEVIDEO", "reason": "$string:read_media_permission_reason", "usedScene": { "abilities": ["EntryAbility"], "when": "inuse" } }, { "name": "ohos.permission.READ_AUDIO", "reason": "$string:read_media_permission_reason", "usedScene": { "abilities": ["EntryAbility"], "when": "inuse" } }并在
string.json中补充对应的reason文案。
string.json 用途: 存放 module.json5 中 $string:xxx 引用的文案(Ability 名称/描述、权限申请理由)。鸿蒙系统在申请权限时会弹出系统对话框,reason 字段的内容即为对话框中展示给用户的说明文字。
六、安装与集成步骤
6.1 安装插件
将 yh-nsfw 插件放入项目的 uni_modules/ 目录:
项目根目录/
├── uni_modules/
│ └── yh-nsfw/ ← 插件目录
│ ├── package.json
│ ├── utssdk/
│ │ ├── interface.uts ← 统一类型定义 + 函数声明
│ │ ├── index.uts ← 平台分发入口(条件编译路由到各端实现)
│ │ ├── app-android/ ← Android 原生实现(Kotlin + TensorFlow Lite)
│ │ ├── app-ios/ ← iOS 原生实现(Swift + Vision)
│ │ ├── app-harmony/ ← 鸿蒙原生实现(ArkTS + sherpa_onnx)
│ │ ├── web/ ← H5 端实现(仅 OCR + 敏感词)
│ │ ├── mp-weixin/ ← 微信小程序端实现(仅敏感词)
│ │ └── shared/ ← 全端共享逻辑(敏感词引擎等)
│ ├── common/ ← ★ 业务封装层(需手动复制到项目根目录,见 6.1.1)
│ │ ├── nsfw-check.uts ← 上传前审核公共封装
│ │ └── permission-tip-manager.uts
│ ├── index/ ← ★ 示例文件(见 6.1.3,复制到项目 pages/ 下)
│ │ └── index.uvue ← 完整调用示例演示页
│ └── ...
├── common/ ← ★ 从插件 common/ 复制到此处
│ ├── nsfw-check.uts ← 上传前审核公共封装(鉴黄/视频/语音一站式检测 + 违规提示)
│ └── permission-tip-manager.uts
├── harmony-configs/ ← ★ 从插件 harmony-configs/ 复制到此处(见 6.1.2)
│ └── entry/src/main/
│ ├── module.json5 ← 鸿蒙模块配置(权限/Ability/metadata/querySchemes)
│ └── resources/base/element/
│ └── string.json ← 权限说明文案与 Ability 名称
├── pages/
│ └── index/
│ └── index.uvue ← ★ 示例文件:从插件 index/ 复制到此处(鉴黄/视频/语音/OCR/敏感词六大场景演示)
├── manifest.json ← 各端权限与环境配置
└── yh-nsfw使用文档.md ← 本文档
6.1.1 ★ 必读:复制 common/ 下文件到项目根目录(引用插件时必做)
适用场景:将 yh-nsfw 插件引用到新项目时,插件目录
uni_modules/yh-nsfw/common/下有两个业务封装文件,必须手动复制到项目根目录的common/下,否则页面编译报错:[plugin:uts] Cannot find module "@/common/nsfw-check" from "pages/index/index.uvue" [plugin:uni:app-uvue] Could not resolve "@/common/permission-tip-manager.uts"
需要复制的文件:
| 文件 | 用途 | 引用位置 |
|---|---|---|
nsfw-check.uts |
上传前审核公共封装(鉴黄/视频/语音一站式检测 + 违规提示) | index.uvue L142 import { showViolationTip } from '@/common/nsfw-check.uts' |
permission-tip-manager.uts |
Android 媒体权限请求封装(相机/录音/存储权限统一申请 + 拒绝引导) | index.uvue L145 import { requestMediaPermission } from '@/common/permission-tip-manager.uts' |
原因:这两个文件是业务编排层(组合调用插件原子 API + uni.showLoading/showToast 等 UI 交互),不属于插件导出的 utssdk/ 范畴,@/uni_modules/yh-nsfw 不会自动导出它们。页面通过 @/common/xxx.uts 路径引用,因此必须放在项目根目录。
操作步骤:
# 将插件内的 common/ 下两个文件复制到项目根目录 common/
cp uni_modules/yh-nsfw/common/nsfw-check.uts common/nsfw-check.uts
cp uni_modules/yh-nsfw/common/permission-tip-manager.uts common/permission-tip-manager.uts
复制后目录结构:
项目根目录/
├── uni_modules/yh-nsfw/common/ ← 插件内的原始副本(保留,勿删)
│ ├── nsfw-check.uts
│ └── permission-tip-manager.uts
└── common/ ← 复制到根目录的副本(页面 import 引用此目录)
├── nsfw-check.uts
└── permission-tip-manager.uts
插件内的
common/目录是源文件副本,保留用于版本对照和后续更新。项目根目录的common/是实际被页面引用的文件,可根据项目需求修改违规提示文案、检测阈值等业务规则。
6.1.2 ★ 必读:复制 harmony-configs/ 到项目根目录(引用插件时必做)
适用场景:将 yh-nsfw 插件引用到新项目时,插件目录
uni_modules/yh-nsfw/harmony-configs/包含鸿蒙原生工程配置模板,必须手动复制到项目根目录,否则 HBuilderX 编译鸿蒙时无法读取到module.json5中的权限声明和 Ability 配置,导致鸿蒙端功能缺失或运行时权限被拒。
操作步骤:
# 将插件内的 harmony-configs/ 整个目录复制到项目根目录
cp -r uni_modules/yh-nsfw/harmony-configs harmony-configs
复制后目录结构:
项目根目录/
├── uni_modules/yh-nsfw/harmony-configs/ ← 插件内的原始副本(保留,勿删)
│ └── entry/src/main/
│ ├── module.json5 ← 鸿蒙模块配置(权限/Ability/metadata)
│ └── resources/base/element/string.json ← 权限说明文案
└── harmony-configs/ ← 复制到根目录的副本(编译时实际读取此文件)
└── entry/src/main/
├── module.json5
└── resources/base/element/string.json
复制后需检查/修改的内容(harmony-configs/entry/src/main/module.json5):
| 配置项 | 是否需改 | 说明 |
|---|---|---|
metadata.wx_appid |
视情况 | 如需微信分享/登录,改为你的微信 AppID;不需要则删除 |
metadata.GETUI_APPID |
视情况 | 如需个推推送,改为你的个推 AppID;不需要则删除 |
metadata.client_id |
视情况 | 如需华为登录,改为你的华为 client_id;不需要则删除 |
requestPermissions |
必须检查 | 确保包含 yh-nsfw 所需权限(见 5.4 节) |
abilities |
通常不改 | EntryAbility 入口配置 |
querySchemes |
视情况 | 如不需微信跳转,可删除 weixin/wxopensdk |
复制后需检查/修改的内容(harmony-configs/entry/src/main/resources/base/element/string.json):
| 字符串 | 是否需改 | 说明 |
|---|---|---|
module_desc / EntryAbility_desc / EntryAbility_label |
视情况 | 改为你的应用名称和描述 |
location_permission_reason |
视情况 | 如不需要定位权限,可删除对应文案 |
microphone_permission_reason |
通常保留 | 麦克风权限理由(语音转写必需) |
如需为 yh-nsfw 的 CAMERA/READ_IMAGEVIDEO/READ_AUDIO 权限补充
reason文案,在string.json的string数组中添加:{ "name": "camera_permission_reason", "value": "用于拍摄证件图像并执行 OCR 识别" }, { "name": "read_media_permission_reason", "value": "用于读取本地图片/视频/音频进行内容审核" }
6.1.3 复制示例文件 index/ 到项目 pages/ 目录
插件内 uni_modules/yh-nsfw/index/index.uvue 是示例文件,包含全部功能的完整调用演示(鉴黄、视频抽帧、语音转写、OCR 证件识别、敏感词检测等六大场景),可直接复制到项目的 pages/ 目录下运行参考:
cp -r uni_modules/yh-nsfw/index pages/index
该文件仅作调用示例,不复制不影响插件功能;复制后需确保
pages.json中已注册pages/index/index页面路径,并已按 6.1.1 复制好common/下两个依赖文件,否则示例页编译会报错。
6.2 配置 manifest.json
按第五节配置各端权限。
6.3 配置鸿蒙原生工程(harmony-configs/)
如需鸿蒙端功能,按第 5.4 节配置 harmony-configs/entry/src/main/module.json5 的 requestPermissions,确保包含麦克风、相机等权限声明,并在 string.json 中补充对应的权限理由文案。
6.4 在页面中引入
// #ifdef APP-ANDROID || APP-IOS || APP-HARMONY
import {
checkTextSync,
closeVideoSession,
detectImage,
describeOcrRuntime,
grabVideoFrame,
initModel,
inspectDocumentImage,
isModelReady,
isWordLibraryReady,
loadWordLibrary,
openVideoSession,
readTextFromImage,
scanBusinessPermit,
transcribeAudio
} from '@/uni_modules/yh-nsfw'
import type {
LqjDocumentResult,
LqjTextUnit,
YhNsfwAudioResult,
YhNsfwGrabbedFrame,
YhNsfwVideoSession,
YhNsfwWordLibraryOptions
} from '@/uni_modules/yh-nsfw'
// #endif
七、API 总览
7.1 鉴黄(图片/视频)
| 函数 | 签名 | 说明 |
|---|---|---|
initModel |
(options?: YhNsfwInitOptions) => void |
预加载 NSFW 模型(首次调用 detectImage 前必须执行) |
isModelReady |
() => boolean |
查询模型是否已加载就绪 |
detectImage |
(options: YhNsfwImageOptions) => void |
单张图片鉴黄检测 |
openVideoSession |
(videoPath, success, fail?) => void |
打开视频抽帧会话(纯内存,无中间文件) |
grabVideoFrame |
(session, timeMs, success, fail?) => void |
抓取指定时刻单帧,同时鉴黄 + OCR |
closeVideoSession |
(session: string) => void |
关闭会话释放资源(幂等) |
releaseModel |
() => void |
释放 NSFW 模型内存 |
7.2 语音 / 视频音轨内容鉴定
| 函数 | 签名 | 说明 |
|---|---|---|
transcribeAudio |
(filePath, success, fail?) => void |
提取音频/视频音轨并转写为文字(无音轨返回空串),供敏感词审核 |
releaseWhisperModel |
() => void |
释放语音模型内存 |
7.3 敏感词检测
| 函数 | 签名 | 说明 |
|---|---|---|
loadWordLibrary |
(options?: YhNsfwWordLibraryOptions) => void |
加载词库(零参 = 内建词库) |
isWordLibraryReady |
() => boolean |
查询词库是否已加载 |
checkTextSync |
(text: string) => YhNsfwTextCheckResult |
同步检测文本是否含敏感词 |
7.4 证件 OCR
| 函数 | 签名 | 说明 |
|---|---|---|
describeOcrRuntime |
() => LqjRuntimeSnapshot |
查询 OCR 运行时(平台/引擎/支持能力) |
inspectDocumentImage |
(options: LqjDocumentOptions) => void |
通用文档识别(含身份证) |
scanBusinessPermit |
(options: LqjDocumentOptions) => void |
营业执照识别 |
scanIdCard |
(options: LqjDocumentOptions) => void |
身份证识别(快捷封装) |
scanBankCard |
(options: LqjDocumentOptions) => void |
银行卡识别 |
scanVehiclePlate |
(options: LqjDocumentOptions) => void |
车牌识别 |
readTextFromImage |
(options: LqjTextReadOptions) => void |
纯文字识别(不提取结构化字段) |
polishDocumentImage |
(options: LqjPolishOptions) => void |
文档整理(透视校正/增强) |
exportDocumentFile |
(options: LqjExportOptions) => void |
导出为 JPEG/PDF/Base64 |
7.5 上传前审核公共封装(common/nsfw-check.uts)
common/nsfw-check.uts 是业务层与插件 API 之间的封装模块,将鉴黄/视频/语音/OCR/敏感词整合为「上传前一站式审核」高层 API。检测中的 loading 与违规拦截提示均由本模块统一弹出,调用方无需再处理。
适用场景:发帖/评论/聊天图片上传、视频上传、语音消息发送前的自动内容审核。
| 函数 | 签名 | 说明 |
|---|---|---|
checkImages |
(paths: string[], done: NsfwImagesDone) => void |
批量图片审核:鉴黄(porn/hentai > 0.5)+ OCR 文字敏感词,返回通过路径列表 + 违规数 |
checkVideoUpload |
(path: string, done: (res: VideoCheckResult) => void) => void |
视频审核:会话式抽帧鉴黄(连续 3 帧违规)+ 帧文字(累计 2 帧命中)+ 音轨转写敏感词 |
checkAudioUpload |
(path: string, done: (res: AudioCheckResult) => void) => void |
语音审核:transcribeAudio 转写 + checkTextSync 敏感词 |
validateVideoBasic |
(durationSec, sizeBytes, ext) => VideoBasicResult |
视频基础校验(时长/大小/格式,不调用模型) |
prewarmDetection |
(onReady?: (() => void) \| null) => void |
预热检测引擎(提前加载 NSFW 模型 + 词库) |
showViolationTip |
(message: string, onComplete: () => void) => void |
统一违规提示(iOS 弹 modal、其他端 toast) |
检测结果类型:
| 类型 | 字段 | 说明 |
|---|---|---|
NsfwImagesDone |
passPaths: string[], violationCount: number |
图片检测结果回调 |
VideoCheckResult |
pass: boolean, reason: string |
视频检测结果(reason: '' 放行 / 'nsfw' 鉴黄 / 'text' 文字 / 'voice' 语音) |
AudioCheckResult |
pass: boolean, reason: string |
语音检测结果(reason: '' 放行 / 'voice' 违规语音) |
调用示例:
import { checkImages, checkVideoUpload, checkAudioUpload, showViolationTip } from '@/common/nsfw-check.uts'
// 图片上传前审核
checkImages(imagePaths, (passPaths, violationCount) => {
if (violationCount > 0) {
// 违规提示已由模块内部弹出,此处仅处理通过的部分
uploadToServer(passPaths)
} else {
uploadToServer(passPaths)
}
})
// 视频上传前审核
checkVideoUpload(videoPath, (res) => {
if (res.pass) {
uploadVideo(videoPath)
}
// 违规时模块已弹出提示,res.reason 标明原因
})
// 语音消息发送前审核
checkAudioUpload(audioPath, (res) => {
if (res.pass) {
sendVoiceMessage(audioPath)
}
})
检测规则:
- 图片:鉴黄 porn/hentai > 0.5 判违规 → 鉴黄通过后 OCR 识别图内文字 → 命中敏感词同样判违规
- 视频:每秒抽 1 帧,dHash 跳帧防静态图绕过 → 连续 3 帧鉴黄违规判
nsfw→ 帧文字累计 2 帧命中判text→ 音轨转写敏感词判voice;最长 60 秒、最多 60 帧 - 语音:transcribeAudio 转写全文 → checkTextSync 敏感词判定
八、调用示例
8.1 模型预热 + 图片鉴黄
// 首次使用前必须预加载模型
function ensureModel(done: (ok: boolean) => void): void {
if (isModelReady()) {
done(true)
return
}
initModel({
success: () => { done(true) },
fail: (err) => {
console.error('模型加载失败:', err.errMsg)
done(false)
}
})
}
// 单张图片鉴黄:porn/hentai > 0.5 判违规
function detectOneImage(path: string): Promise<boolean> {
return new Promise<boolean>((resolve) => {
detectImage({
imagePath: path,
success: (res) => {
const compliant = !(res.scores.porn > 0.5 || res.scores.hentai > 0.5)
console.log('图片鉴黄:', path, 'porn=', res.scores.porn,
'hentai=', res.scores.hentai, 'compliant=', compliant)
resolve(compliant)
},
fail: (err) => {
console.warn('鉴黄异常,默认放行:', err.errMsg)
resolve(true) // 引擎异常默认放行,避免阻断流程
}
})
})
}
8.2 会话式视频抽帧鉴黄
// 1. 打开视频会话(拿到 sessionId + 总时长)
const session = await new Promise<YhNsfwVideoSession>((resolve, reject) => {
openVideoSession(videoPath,
(res) => resolve(res),
(err) => reject(new Error(err.errMsg)))
})
// 2. 按时间点抽帧(同时鉴黄 + OCR 文字识别)
const frame = await new Promise<YhNsfwGrabbedFrame | null>((resolve, reject) => {
grabVideoFrame(session.session, timeMs,
(frame) => resolve(frame), // null = 该时刻无可用帧,跳过即可
(err) => reject(new Error(err.errMsg)))
})
if (frame != null) {
console.log('时间点:', frame.timeMs, '类别:', frame.category,
'概率:', frame.probability, '违规:', frame.violation, '文字:', frame.text)
// 帧文字做敏感词判定
if (frame.text.length > 0 && checkTextSync(frame.text).illegal) {
console.log('帧文字命中敏感词')
}
}
// 3. 结束后关闭会话(释放原生资源,幂等)
closeVideoSession(session.session)
8.3 语音 / 视频音轨内容鉴定
function transcribeAsync(filePath: string): Promise<string> {
return new Promise<string>((resolve, reject) => {
transcribeAudio(filePath,
(res: YhNsfwAudioResult) => resolve(res.text),
(err) => reject(new Error(err.errMsg)))
})
}
// 使用:支持音频文件和视频文件(自动提取音轨)
const text = await transcribeAsync(audioPath)
if (text.length > 0 && checkTextSync(text).illegal) {
console.log('语音内容违规')
}
8.4 身份证 OCR 识别
// 选图前先查运行时是否支持 OCR
const runtime = describeOcrRuntime()
if (!runtime.supportsOcr) {
uni.showToast({ title: '当前平台不支持OCR识别', icon: 'none' })
return
}
// 身份证人像面识别(documentHint = 'idCard')
inspectDocumentImage({
imagePath: imagePath,
languages: ['zh', 'en'],
// #ifdef APP-ANDROID
mode: 'fast', // Android 用 fast 模式(ML Kit)
// #endif
// #ifndef APP-ANDROID
mode: 'accurate', // iOS/鸿蒙用 accurate 模式(Vision/模块化OCR)
// #endif
documentHint: 'idCard',
polishBeforeRead: true, // 先做文档整理(透视校正+彩色增强)
polishMode: 'color',
success: (res: LqjDocumentResult) => {
// 结构化字段优先
let name = ''
let idNumber = ''
for (const field of res.fields) {
if (field.key == 'name') name = field.value
else if (field.key == 'idNumber') idNumber = field.value
}
// 结构化字段为空时,从全文正则兜底
if (name.length == 0) name = extractNameFromText(res.fullText)
if (idNumber.length == 0) idNumber = extractIdNumberFromText(res.fullText)
console.log('姓名:', name, '证件号:', idNumber, '耗时:', res.durationMs + 'ms')
},
fail: (err) => {
console.error('身份证识别失败:', err.errMsg)
}
})
8.5 营业执照 OCR 识别
scanBusinessPermit({
imagePath: imagePath,
languages: ['zh', 'en'],
// #ifdef APP-ANDROID
mode: 'fast',
// #endif
// #ifndef APP-ANDROID
mode: 'accurate',
// #endif
polishBeforeRead: true,
polishMode: 'color',
success: (res: LqjDocumentResult) => {
// 结构化字段 + 全文正则两轨提取
let licenseNumber = ''
let companyName = ''
let regDate = ''
for (const field of res.fields) {
if (field.key == 'licenseNumber') licenseNumber = field.value
else if (field.key == 'companyName') companyName = field.value
// ... 更多字段
}
console.log('统一社会信用代码:', licenseNumber, '企业名称:', companyName)
},
fail: (err) => {
console.error('营业执照识别失败:', err.errMsg)
}
})
8.6 敏感词检测
// 1. 加载词库(零参 = 插件内建词库,全端零 IO)
loadWordLibrary({
success: () => {
console.log('词库加载成功, ready =', isWordLibraryReady())
}
} as YhNsfwWordLibraryOptions)
// 2. 同步检测文本
const r = checkTextSync(inputText)
if (r.illegal) {
console.log('命中敏感词:', r.hits)
console.log('打码文本:', r.filtered)
console.log('命中字符数:', r.count)
} else {
console.log('文本检测通过')
}
// r.ready = false 时表示词库未加载,检测被跳过,illegal 恒为 false
8.7 自定义词库
// 方式一:传入词库数组(如服务端热更词库)
loadWordLibrary({
words: ['敏感词1', '敏感词2', ...],
version: '2.0',
success: () => { console.log('自定义词库加载成功') }
} as YhNsfwWordLibraryOptions)
// 方式二:传入词库 JSON 文件路径(string[] 的 JSON)
loadWordLibrary({
filePath: '/static/words.json',
version: '2.0',
success: () => { console.log('文件词库加载成功') }
} as YhNsfwWordLibraryOptions)
九、jianhuang.uvue 完整调用模式
pages/jianhuang/jianhuang.uvue 是插件的完整演示页面,覆盖六大场景:
| 场景 | 涉及 API | 说明 |
|---|---|---|
| 文本检测 | checkTextSync |
同步敏感词检测,即时打码 |
| 图片鉴黄 | detectImage + initModel |
批量图片顺序鉴黄,porn/hentai > 0.5 判违规 |
| 视频审核 | openVideoSession → grabVideoFrame → closeVideoSession |
会话式抽帧,每帧同时鉴黄 + OCR + 敏感词 |
| 语音审核 | transcribeAudio + checkTextSync |
录音/选音频 → 转文字 → 敏感词判定 |
| 证件识别 | inspectDocumentImage + scanBusinessPermit + describeOcrRuntime |
身份证人像面/国徽面 + 营业执照 |
| 运行时查询 | describeOcrRuntime |
查询 OCR 引擎/平台/支持能力 |
关键模式
- 模型预热:首次调用
detectImage前必须initModel,用isModelReady()判断是否已就绪 - Promise 化:所有回调式 API 包装为 Promise,便于
async/await链式调用 - 异常放行:鉴黄/OCR 引擎异常时默认放行(resolve(true)),避免阻断业务流程
- Loading 防卡死:延迟 500ms 弹 loading,防止检测过快导致"结束后才弹出"
- Android/iOS 模式差异:OCR
mode用条件编译区分——Androidfast(ML Kit),iOS/鸿蒙accurate(Vision/模块化) - 结构化字段 + 全文正则双轨提取:OCR 结果优先用
res.fields结构化字段,为空时从res.fullText正则兜底
十、注意事项
- 条件编译:鉴黄/视频/语音 API 仅在
#ifdef APP-ANDROID || APP-IOS || APP-HARMONY内调用,H5/小程序端调用会编译报错 - 模型初始化:
detectImage首次调用前必须执行initModel,否则推理失败 - 词库加载:
checkTextSync在词库未加载时(ready=false)会跳过检测,illegal恒为false(放行) - 视频会话:
openVideoSession是纯内存会话,无中间帧文件;用完必须closeVideoSession释放 - 内存管理:长时间不使用时调用
releaseModel()/releaseWhisperModel()释放模型内存 - Android 权限分级:targetSdkVersion ≥ 33 时使用
READ_MEDIA_*,< 33 时使用READ_EXTERNAL_STORAGE - iOS 隐私描述:App Store 审核要求所有 Info.plist 隐私描述必须具体明确,不能为空
- 鸿蒙 OHPM 依赖:
module_ocr.har是本地包,确保插件utssdk/app-harmony/libs/目录存在 - 仅 arm64-v8a:插件仅编译了 arm64-v8a 架构,不支持 x86/armeabi-v7a
- 数据安全:所有检测/识别在本地执行,模型内置在插件中,不上传任何用户数据

收藏人数:
购买源码授权版(
试用
使用 HBuilderX 导入示例项目
赞赏(0)
下载 10
赞赏 0
下载 12649129
赞赏 1953
赞赏
京公网安备:11010802035340号