@belumi/beauty-sdk
v0.2.3
Published
Landmark-driven beauty engine SDK (skin smoothing, stickers, makeup, BG replace) with license-gated activation.
Downloads
1,378
Maintainers
Readme
@belumi/beauty-sdk
语言: English · 简体中文
浏览器直播美颜引擎,基于面部关键点驱动。集磨皮、美白、柔光、 肌色调整、MLS 五向双向形变(瘦脸/下巴/瘦鼻/大眼/丰唇,全部支持 反向)、完整眼妆(眉毛+眼线+多层眼影+美瞳+眼白+眼神光)、口红、 LUT 滤镜、背景虚化/替换、3D 关键点驱动贴纸于一个 npm 包内。
需要 SDK 发行方签发的 license 才能激活。
状态:v0.1.x — alpha。API 在 v1.0 之前可能演进。
安装
npm install @belumi/beauty-sdk --legacy-peer-depsSDK 已预编译(WASM 内联到 bundle)。消费方无需装 Rust 或其它 原生依赖。
快速上手
import {
ensurePrism,
setBeautyParam,
getProcessedStream,
dispose,
BelumiLicenseError,
} from '@belumi/beauty-sdk'
async function startBeauty(previewEl) {
try {
const { capabilities, license } = await ensurePrism(previewEl, {
licenseKey: process.env.BELUMI_LICENSE_KEY, // 或按你框架方式读 runtime config
enforceLicense: true,
})
// 调美颜参数(sync,滑块 @input 60Hz 拖动安全)
setBeautyParam('Skin', 'Beauty', 'skinSmoothingStrength', 0.6)
setBeautyParam('Skin', 'Beauty', 'skinWhiteningStrength', 0.4)
setBeautyParam('Face', 'Beauty', 'faceSlimAmount', 0.3)
// 把处理后的流喂给 RTC SDK
const processedStream = getProcessedStream(30)
// AgoraRTC.createCustomVideoTrack({ mediaStreamTrack: processedStream.getVideoTracks()[0] })
return capabilities
} catch (err) {
if (err instanceof BelumiLicenseError) {
console.error(`License 拒绝(code ${err.code}):`, err.message)
}
throw err
}
}
// 会话结束
await dispose()功能清单
| 能力 | License feature flag |
|---|---|
| 关键点驱动 3D AR 贴纸(猫耳 / 面具等)| stickers |
| 磨皮 — bilateral 双边滤波,只平色度 + 振幅感知阈值 | skin_smoothing |
| 美白 — Y 通道 tone curve + Cb/Cr shift | whitening |
| 柔光 — 高光区 Y 提亮 + 微粉调 rosy chrominance shift | softlight |
| 肌色调整 — 目标 CbCr overlay 保留原 Y | skin_color |
| 五向形变(双向 slider)— 瘦脸/下巴/鼻/眼/唇,67 控制点 MLS warp + Catmull-Rom 样条 + iris/眉毛/边缘 anchor | face_slim |
| 口红 — 20 点唇形 landmark + multiply blend | lip_makeup |
| 眼妆 — 眉毛/眼线/眼影/美瞳/眼白提亮/眼神光 | eyes_makeup |
| 眼妆 — 8 层控件(眉毛含 9 种眉形 + 眼线 + 上下/眼尾/眼头/卧蚕眼影 + 美瞳 + 眼白 + 眼神光)+ 11 preset look | eyes_makeup |
| LUT 滤镜(色彩分级) | filters |
| 背景虚化 | bg_blur |
| 背景替换(SelfieMulticlass 分割) | bg_replace |
| ABPN AI 祛痘(离线一次性,65MB ONNX) | (内置) |
你的 license 决定能用哪些功能——申请 license 时明确需要的功能集。
⚠️ 命名坑:上表
License feature flag一列是签 license 时 CSV 里用的名字(snake_case),要跟 Rust core 的from_csv匹配串 一致。SDK 运行时返回的capabilities对象、setBeautyParam的参数 键都用 camelCase(例如skinSmoothing,bgBlur),形似但不能 互换。签 license 时只能用上表的 snake_case 名字——用 camelCase 会静默 fallthrough 到0(功能关闭),签出来的 license 看着 valid 但对应能力就是不生效。完整 snake_case 白名单 + 一行 copy-paste 命令见docs/DEPLOY.md §4.1。
API 参考
ensurePrism(previewEl, options): Promise<{ instance, capabilities, license }>
激活 SDK。校验 license,加载 WASM 核心,初始化 WebGL 2 + MediaPipe。
参数
| 名称 | 类型 | 说明 |
|---|---|---|
| licenseKey | string(必填)| SDK 发行方签发的 license 字符串 |
| enforceLicense | boolean(默认 true)| false 时 license 无效仅 warn 不 throw,返回禁用状态 |
| mediapipeBaseUrl | string | 自定义 MediaPipe WASM + 模型 CDN |
| stickerCdnBase | string | 自定义 sticker PNG 托管(默认用内嵌图片)|
| abpnModelBase | string | ABPN ONNX 模型的 base URL(applyABPN() 用)。不打算用祛痘可以省略 |
| metricsReporter | (event, value) => void | 观测回调 |
| i18n | (key) => string | 用户可见错误翻译 |
| onCapabilityDowngrade | (reason) => void | 低端设备自动降级时触发 |
返回 { instance, capabilities, license }:
capabilities—{ stickers, skinSmoothing, whitening, softlight, skinColor, faceSlim, reshape, eyesMakeup, lipMakeup, makeup, filters, bgBlur, bgReplace }(每项布尔,跟 license 一致)。makeup是虚拟伞形 =eyesMakeup || lipMakeup;实际 license bits 是eyes_makeup(老)和lip_makeup(新,2026-07-27 从makeup重命名)。reshape(2026-07-27 从retouch重命名)严格跟随face_slimbit。license—{ valid, expiresAt: number, errorCode: LicenseErrorCode }
抛异常 BelumiLicenseError(Error 子类),当 enforceLicense !== false
且 license 无效。.code 为 LicenseErrorCode 之一:BadSignature /
BadFingerprint / Expired / DomainMismatch / MalformedStructure /
UnparseablePayload。
setBeautyParam(node, component, parameter, value)
调美颜参数。sync 调用,安全用于滑块 @input 60 Hz 拖动。取值范围
按参数类型见 Range 列。hex key 传 #rrggbb 字符串,其他传 number。
| Node | Component | Parameter | Range | 用途 |
|---|---|---|---|---|
| Skin | Beauty | skinSmoothingStrength | [0, 1] | 磨皮 bilateral 强度 |
| Skin | Beauty | skinWhiteningStrength | [0, 1] | 美白 tone curve 强度 |
| Softlight | Beauty | strength | [0, 1] | 柔光 强度 |
| SkinColor | Beauty | strength | [0, 1] | 肌色 overlay 强度 |
| SkinColor | Beauty | hex | #rrggbb | 肌色 目标颜色 |
| Face | Beauty | faceSlimAmount | [-1, 1] | 瘦脸 (-) 胖脸 / (+) 瘦脸 |
| Face | Beauty | chinShapeAmount | [-1, 1] | 下巴 (-) 圆下巴 / (+) 尖 V-line |
| Nose | Beauty | noseSlimAmount | [-1, 1] | 鼻子 (-) 宽鼻 / (+) 瘦鼻 |
| Eyes | Beauty | eyesEnlargeAmount | [-1, 1] | 眼睛 (-) 缩眼 / (+) 大眼 |
| Lips | Beauty | lipsPlumpAmount | [-1, 1] | 嘴唇 (-) 薄唇 / (+) 丰唇 |
带符号的参数走 pow(|v|, 1.3) gamma 曲线,低滑块值感知更柔和。反向
(负值)方向 chin/nose/lips 会额外 1.8× 放大补偿"反向阈值高"的视觉
落差。
setEyesMakeup(config)
配置眼妆 overlay。部分 config 会 merge 到当前状态——只传要改的 字段即可。所有 layer 默认关闭 / 0。
setEyesMakeup({
brows: { enabled: true, color: '#3a2a1a', style: 'natural' },
liner: { enabled: true, color: '#1a1a1a' },
shadow: { enabled: true, color: '#a67856' },
shadowLower: false, // 下眼影
shadowTail: false, // 眼尾深化(烟熏灵魂)
innerHighlight: false, // 眼头提亮
aegyoSal: false, // 卧蚕
iris: { enabled: false, color: '#5b8c5a' },
whitening: 0, // 0-1 眼白提亮
flare: 0, // 0-1 眼神光
})眉形 (brows.style):natural / arch / straight / tapered /
thick / short / high / curved / sad 共 9 种。
applyEyesMakeupLook(lookId): boolean
一键套用 preset look。返回 true 表示 id 存在,false 表示未知
id。会覆盖当前 eyesConfig。
applyEyesMakeupLook('smoky') // 深邃烟熏getEyesMakeupLooks(): Array<{ id, label, hint, config }> / EYE_LOOKS
返回 11 个 preset。EYE_LOOKS 是同一份数组的命名导出,方便直接用于
下拉菜单。Preset id:natural / sweet / smoky / jp-clean /
kr-arch / willow / gentle-moon / puppy / anime / red-lens /
reset。
getEyesMakeupConfig(): object
返回当前 merge 完的眼妆 config。
getProcessedStream(fps = 30): MediaStream
返回处理后的视频流。喂给 Agora / LiveKit / 任意 WebRTC 推流器。
switchEffect(url): Promise<void> / clearEffect(): Promise<void>
加载/移除 AR / 背景 / 贴纸 / 滤镜 / 口红 effect。URL scheme:
sticker:<id>— 3D 关键点贴纸bg:blur:<0-1>/bg:color:<#hex>/bg:image:<url>— 背景模式filter:<id>— LUT 色彩分级(cool/rose/warm/vintage/bw/snow)makeup:lip:<#hex>/makeup:lip:<#hex>:<intensity>/makeup:lip:off— 口红
applyABPN(): Promise<ImageData>
一次性 AI 祛痘(Alibaba ABPN, CVPR 2022, Apache 2.0)。抓当前 canvas
快照,跑 3 模型 pipeline(detection → inpainting → generator),返
retouch 后的 ImageData。
非实时 — WASM 单帧 5-15s。适用于用户触发的静态照片处理,不用于
直播主流。首次调用会从 abpnModelBase 下载 ~65MB ONNX,之后缓存。
需要在 ensurePrism options 里配 abpnModelBase 指向托管 3 个文件
的目录:
detection_uint8.onnx,inpainting_uint8.onnx,abpn_uint8.onnx
参考模型在 belumi-beauty-sdk/models/abpn/。把它们托管到自己的 CDN
再设 abpnModelBase。
局限:ABPN 训练数据是重痤疮图像,对雀斑 / 老年斑的 detection coverage 通常 0% —— 检测网 recognized 不出这类瑕疵。
dispose(): Promise<void>
释放 WebGL 上下文、结束 MediaPipe worker、关摄像头。
coreVersion(): Promise<string>
Build 版本标识(如 [email protected])。工单里带上有助排查。
License 系统
License 是 URL-safe 字符串,由 SDK 发行方签发。每份 license 授权指定 domain 上的指定功能集,有指定 TTL。
申请 license
跟 SDK 发行方提供:
- 客户 / 项目名
- SDK 会跑的 domain(支持
*.example.com通配) - 需要的功能集
- 期望 TTL(一般 90-365 天)
拿到一段 license 字符串。存到环境变量里——绝对不要写死在源码。
配 license
按你框架的 runtime config 机制配。
Nuxt 2(需要额外加 webpack 4 transpile):
// nuxt.config.js
export default {
publicRuntimeConfig: {
belumiLicense: process.env.BELUMI_LICENSE_KEY || '',
},
build: {
transpile: ['@belumi/beauty-sdk'],
},
}
// 代码里:
licenseKey: window.$nuxt.$config.belumiLicenseNuxt 3 — 不需要 transpile:
// nuxt.config.ts
runtimeConfig: {
public: { belumiLicense: '' }, // 从 NUXT_PUBLIC_BELUMI_LICENSE 注入
}
// 代码里:
licenseKey: useRuntimeConfig().public.belumiLicenseVite / Next.js / 普通 webpack 5 — 分别读 import.meta.env /
process.env.NEXT_PUBLIC_BELUMI_LICENSE / process.env.BELUMI_LICENSE_KEY。
无需 bundler 配置。
续期
License 到 expires_at 就失效。SDK 会以 LicenseErrorCode.Expired
拒绝。续期 = 发行方签发新的一份,消费方换 env var 重新部署。没有云端
heartbeat——SDK 不联网。签发后到过期前完全离线可用。
框架兼容矩阵
| 框架 | 备注 |
|---|---|
| Nuxt 2.15+ | 加 build.transpile: ['@belumi/beauty-sdk'] |
| Nuxt 3.x | 开箱即用 |
| Next.js 13+ | 用 dynamic(() => import(), { ssr: false })——SDK 仅客户端 |
| Vite 4+ | 开箱即用 |
| Create React App 5.x | 开箱即用 |
| Vue CLI 5.x | 开箱即用 |
| Angular 15+ | 开箱即用(未测)|
RTC 兼容矩阵
| RTC SDK | 集成方式 |
|---|---|
| Agora Web SDK 4.19+ | AgoraRTC.createCustomVideoTrack({ mediaStreamTrack }) |
| LiveKit Client 2.x | new LocalVideoTrack(mediaStreamTrack) |
| 原生 RTCPeerConnection | pc.addStream(processedStream) |
getProcessedStream() 返标准 W3C MediaStream——任何接受 media
stream track 的 RTC SDK 都能用。
排错
BelumiLicenseError: license signature does not verify
License 是给别的 SDK build 签的。跟发行方要针对当前 SDK 版本重签。
BelumiLicenseError: license expired
License 过期。申请续期。
BelumiLicenseError: license not valid for this hostname
当前 window.location.hostname 不在 license domain 白名单里。检查你
部署的 hostname 或重签一份含正确 domain 的 license。
Module parse failed: Unexpected token(webpack 4 / Nuxt 2)
把 SDK 加进 build.transpile:
// nuxt.config.js
build: { transpile: ['@belumi/beauty-sdk'] }Cannot read properties of null (reading 'bindTexture')
SDK 还没 ensurePrism 完成(或已 fail),代码就尝试渲染了。用
ensurePrism 返的 capabilities 做守卫,确保 SDK 就绪后才调
switchEffect / effect 相关 API。
支持
- License 申请 / 续期:联系 SDK 发行方
- Bug 报告:联系 SDK 发行方
许可
专有软件。详见 LICENSE 或联系发行方。
