互动表情
更新时间: 2026/07/31 11:06:48
NERTC SDK 支持互动表情(贴纸)功能。
功能介绍
互动表情(贴纸)功能可在本地视频流的人脸上叠加内置的动态贴纸效果,通常与美颜、滤镜等功能配合使用,适用于人脸贴纸等趣味场景。
NERTC SDK 通过美颜模块统一管理贴纸的添加与移除,开发者无需单独集成贴纸模块。
典型应用场景:
- 在线直播: 主播通过趣味贴纸增强互动效果,提升观众参与感。
- 视频通话: 用户为自身添加个性化贴纸,增加通话趣味性。
- 短视频拍摄: 拍摄者实时预览贴纸效果,丰富视频内容表现力。
示例项目
NERTC SDK 提供云信美颜 API Example,您可以直接下载源码进行体验。
效果展示
| 暴富 | 啤酒 | 鲜花 |
|---|---|---|
![]() |
![]() |
![]() |
注意事项
- 调用互动表情接口前,必须先开启美颜功能。请通过
startBeauty与enableBeauty(true)接口开启美颜后再操作贴纸接口。 - 互动表情功能需在引擎初始化之后调用,加入房间前后均可调用。
- 贴纸资源通常包含
template.json、001.json、sticker/sticker.json及图片序列等文件,调用addBeautySticker时需传入贴纸目录路径。 - 若贴纸资源放在 APK
assets中,建议在应用启动时将其复制到 App 外部私有目录后再传给 SDK。 - 若贴纸资源从服务器下载,需先下载到 App 私有目录;若为 zip 包,还需解压后再传入贴纸目录路径。
- 同一时间仅支持展示一个贴纸。切换贴纸时可直接调用
addBeautySticker(newPath);取消贴纸时调用removeBeautySticker()。
实现方法
准备贴纸资源
贴纸资源为一个目录,内含 template.json、001.json、sticker/sticker.json 以及图片序列等文件。调用 addBeautySticker 时需传入贴纸目录路径。
从 assets 加载(建议启动时复制到外部私有目录):
javaprivate class BeauyAssetsLoaderTask extends AsyncTask<Void, Void, Integer> {
@Override
protected Integer doInBackground(Void... voids) {
int ret = 0;
for (NEAssetsEnum type : NEAssetsEnum.values()) {
ret = AssetUtils.copyAssetRecursive(
getAssets(),
type.getAssetsPath(),
getBeautyAssetPath(type),
false
);
if (ret != 0 || isCancelled()) {
break;
}
}
return ret;
}
}
若您从服务器动态加载资源:
- 请将贴纸资源下载到 App 私有目录。
- 若为 zip 包,需先解压。
- 将解压后的目录路径传入 SDK。
详细流程请参考 服务器动态拉取贴纸。
初始化 NERtc 并启动美颜模块
在 SDK 初始化完成、本地视频开启后启动美颜模块:
java//初始化 SDK
NERtcEx.getInstance().init(getApplicationContext(), APP_KEY, callback, options);
//启动美颜模块
NERtcEx.getInstance().startBeauty();
//开启本地视频并设置画布
NERtcEx.getInstance().enableLocalVideo(true);
NERtcEx.getInstance().setupLocalVideoCanvas(localVideoView);
加入房间后开启美颜效果:
java//加入房间
NERtcEx.getInstance().joinChannel(token, channelName, uid);
//开启美颜效果
NERtcEx.getInstance().enableBeauty(true);
添加或移除贴纸
用户选择贴纸时调用 addBeautySticker,传入贴纸目录路径:
javaNERtcEx.getInstance().addBeautySticker(
mStickerlists.get("sticker_2d").get(position).path
);
API Example 中的最小调用示例:
javaString stickerPath = getBeautyAssetPath(NEAssetsEnum.STICKERS, "glass");
NERtcEx.getInstance().addBeautySticker(stickerPath);
取消贴纸时调用 removeBeautySticker:
javaNERtcEx.getInstance().removeBeautySticker();
同一时间仅展示一个贴纸。切换时直接调用 addBeautySticker(newPath) 即可。
关闭和释放资源
退出房间或关闭页面时,按以下顺序关闭相关功能:
java//关闭美颜效果
NERtcEx.getInstance().enableBeauty(false);
//停止美颜模块
NERtcEx.getInstance().stopBeauty();
//离开房间
NERtcEx.getInstance().leaveChannel();
如果页面销毁后不再使用 RTC,再调用 release() 释放资源:
javaNERtcEx.getInstance().release();
服务器动态拉取贴纸
贴纸资源可存放在业务服务器或 CDN 上,按需下载。推荐服务器下发贴纸配置,客户端根据配置下载并缓存:
json{
"id": "glass",
"version": "1.0.0",
"url": "https://example.com/stickers/glass.zip",
"md5": "optional-md5",
"template": "template.json"
}
资源包推荐使用 zip 格式。解压后应得到完整的贴纸目录,内含 template.json、001.json、sticker/sticker.json 以及图片序列等文件。客户端可按 id/version 建立缓存目录,避免版本冲突:
textcontext.getExternalFilesDir("stickers")/glass/1.0.0/
通用流程:
- 请求服务器贴纸配置列表。
- 检查本地是否已有相同
id + version的缓存资源。 - 无缓存时下载 zip 到临时文件。
- 校验文件大小、MD5 或业务签名。
- 解压到临时目录,确认
template.json存在。 - 原子替换到正式缓存目录。
- 用户选择贴纸时,将正式缓存目录路径传入 SDK。
调用示例:
javaFile stickerDir = new File(
context.getExternalFilesDir("stickers"),
"glass/1.0.0"
);
// 下载并解压完成后,stickerDir 应直接包含 template.json。
NERtcEx.getInstance().addBeautySticker(stickerDir.getAbsolutePath());
- SDK 接口仅接收本地贴纸目录路径,不直接接收 HTTP URL。
- 解压后的目录层级需保持稳定,传入路径应能直接找到
template.json。 - 下载和解压请在后台线程执行,完成后切回主线程更新贴纸列表。
- 建议保留版本号和校验字段,资源更新时通过版本变化触发重新下载。
资源添加规则
- 内置资源:将贴纸目录放入
assets/2D/<stickerName>/,目录结构可参考glass或rabbiteating。 - 动态资源:将贴纸 zip 上传至服务器或 CDN,客户端下载、校验、解压至 App 私有目录。
- 确保传入 SDK 的目录中存在
template.json及贴纸素材文件。 - 若使用 API Example 的内置结构,将资源放入
assets/stickers/<stickerName>/,并在NEStickerEnum中添加对应枚举。 - 选择贴纸时调用
addBeautySticker(stickerPath)。
调用顺序建议
- 初始化 NERtc SDK。
- 准备美颜、贴纸资源(动态贴纸需提前下载、校验并解压至本地)。
- 设置本地视频渲染视图,开启本地视频。
- 调用
startBeauty。 - 加入频道后调用
enableBeauty(true)。 - 用户选择贴纸时调用
addBeautySticker。 - 退出频道或销毁页面时,依次执行:
enableBeauty(false)→stopBeauty()→leaveChannel()。
常见问题
Q1:贴纸不生效?
- 确认已调用
startBeauty并开启美颜(enableBeauty(true))。 - 确认传入的是贴纸资源目录路径,而非图标文件路径。
- 确认
assets中的资源已复制到 App 可访问目录,且路径有效。 - 确认当前贴纸资源与平台 SDK 版本匹配。
Q2:退出房间后再次进入美颜异常?
退出时确保关闭顺序完整:enableBeauty(false) → stopBeauty() → leaveChannel()。







