相芯美颜
更新时间: 2025/08/06 13:52:46
网易云信 NERTC SDK 支持在 Flutter 项目中接入相芯(Faceunity)美颜特效 SDK,实现美颜、滤镜、贴纸等丰富美颜特效。在视频社交、在线教育、直播互动等场景中,您可以快速构建具备专业美颜能力的 Flutter 应用,提升用户在视频通话或直播过程中的形象表现力。
功能概述
通过集成相芯美颜 SDK,您可以在 Flutter 项目的 NERTC 音视频通话中实现以下功能:
- 美化滤镜:支持美颜、滤镜、美妆、微整形等多种美化特效。
- 贴纸道具:丰富的 AR 贴纸、动态表情等互动特效。
- 实时美颜:基于深度学习的实时人脸检测和美化算法。
- 跨平台支持:同时支持 Android 和 iOS 平台的 Flutter 应用。
工作原理
由于 Flutter 端的 GL 环境和原生环境进行了隔离,所以在 Flutter 中接入美颜时无法直接建立绑定关系,需要在原生端各自实现:
-
Flutter 层通过 Method Channel 向原生层发送美颜控制指令。
-
原生层接收指令后,为 NERTC SDK 设置视频前处理回调接口。
-
NERTC SDK 通过回调将采集到的视频帧数据传递给相芯美颜 SDK。
-
相芯美颜 SDK 处理完成后,将美颜后的视频帧返回给 NERTC SDK 进行编码和传输。
注意事项
- GL 环境隔离:Flutter 端的 GL 环境和原生环境进行了隔离,美颜处理必须在原生端实现。
- 纹理格式:Android 端需要处理 OES 纹理到 RGB 纹理的转换。
- 图像方向:iOS 端需要根据旋转角度正确设置图像方向。
- 内存管理:处理过程中需要注意内存的正确管理,防止内存泄漏。
前提条件
在集成相芯美颜 SDK 前,请确保您已完成以下准备工作:
- Flutter 3.10.0 及以上版本,Dart 3.0.0 及以上版本
- Android 系统版本 5.0 (API Level 21) 及以上
- iOS 11 及以上版本 iOS 设备
- Xcode 11.0 及以上版本,Android Studio 版本 Dolphin 及以上版本
- 已获取网易云信 AppKey
- 已集成 NERTC SDK 到您的 Flutter 项目中
- 已实现基础音视频通话功能
- 已从相芯科技获取以下资源:
- 相芯美颜 SDK 及相关资源文件
- 相芯美颜 SDK 的证书文件(authpack)
示例项目
网易云信提供了示例代码供您参考 FUNeRTCFlutter。
第一步:集成 SDK
推荐的项目结构如下(仅供参考):
-Flutter-Project
-android
-src
-build.gradle // 修改处 1:Android 依赖配置
-settings.gradle
-example
-android
-ios
-lib
-test
-pubspec.yaml // 修改处 3:Flutter 依赖配置
-ios
-Assets
-Classes
-nertc_faceunit_plugin.podspec // 修改处 2:iOS 依赖配置
-faceunity_ui_flutter
-faceunity_plugin // 相芯的美颜插件库,直接拷贝到项目中
-android
-src
-main
-kotlin.com.faceunity.faceunity_plugin
-authpack.java // 相芯鉴权文件,需要替换
-ios
-Classes
-Tools
-authpack.h // 相芯鉴权文件,需要替换
-lib
-test
-pubspec.yaml
-
集成网易云信 NERTC SDK。如果您已完成本步骤,请跳过此步。
在
pubspec.yaml
中添加 NERTC SDK 依赖:yaml
dependencies: nertc_core: ^5.8.23 # 请使用您项目中的实际版本
-
集成相芯美颜 SDK
-
配置 NERTC SDK 依赖。
Android在
android/build.gradle
中添加依赖:gradle
dependencies { compileOnly 'com.netease.yunxin:nertc-base:x.x.x' // 使用您项目中的实际版本 implementation project(path: ':faceunity_plugin') // 相芯提供的 Flutter 插件 }
iOS在
.podspec
文件中添加依赖:ruby
s.dependency 'NERtcSDK' s.dependency 'FURenderKit', '8.10.0'
-
配置 Flutter 依赖。
在
pubspec.yaml
中添加相芯美颜插件:yaml
dependencies: nertc_core: ^5.8.23 # 其他依赖...
-
-
更换鉴权文件。将相芯提供的 Android、iOS 鉴权文件替换到项目
faceunity_plugin
的正确位置,例如:- Android:
faceunity_plugin/android/src/main/kotlin/com/faceunity/faceunity_plugin/authpack.java
- iOS:
faceunity_plugin/ios/Classes/Tools/authpack.h
- Android:
第二步:构建 Flutter 与原生的桥接层
接下来需要在 Dart 层建立与原生平台的通信机制:
Dart// 美颜插件主类
class NertcFaceunityPlugin {
/// 启用或关闭美颜功能
/// [enable] true-启用美颜,false-关闭美颜
/// 返回操作结果状态码
Future<int?> enableFuBeauty(bool enable) {
return NertcFaceunityPluginPlatform.instance.enableFuBeauty(enable);
}
}
// Method Channel 实现类
class MethodChannelNertcFaceunityPlugin extends NertcFaceunityPluginPlatform {
/// 与原生平台通信的方法通道
@visibleForTesting
final methodChannel = const MethodChannel('nertc_faceunity_plugin');
@override
Future<int?> enableFuBeauty(bool enable) async {
final result = await methodChannel.invokeMethod<int>(
'enableFuBeauty',
{'enable': enable}
);
return result;
}
}
第三步:实现原生美颜处理逻辑
现在分别为 Android 和 iOS 平台编写美颜功能的核心实现代码:
Javapublic class NertcFaceunityPlugin implements FlutterPlugin, MethodCallHandler {
private FURenderKit mFuRenderKit;
@Override
public void onMethodCall(@NonNull MethodCall call, @NonNull Result result) {
if (call.method.equals("enableFuBeauty")) {
Boolean flag = call.argument("enable");
int response = enableFuBeauty(flag);
result.success(response);
} else {
result.notImplemented();
}
}
/**
* 启用或关闭美颜功能
* @param enable true-启用美颜,false-关闭美颜
* @return 操作结果状态码
*/
private int enableFuBeauty(boolean enable) {
int result = 0;
if (enable) {
// 初始化相芯美颜
mFuRenderKit = FURenderKit.getInstance();
// 设置视频前处理回调
NERtcEx.getInstance().setVideoCallback(this::onVideoCallback, false);
} else {
// 移除视频回调
NERtcEx.getInstance().setVideoCallback(null, false);
}
return result;
}
/**
* 视频帧处理回调
* @param neRtcVideoFrame NERTC 视频帧数据
* @return 是否成功处理
*/
private boolean onVideoCallback(NERtcVideoFrame neRtcVideoFrame) {
// 检查相芯 SDK 是否已初始化
if (!FaceunityKit.INSTANCE.isKitInit()) {
return false;
}
// 只处理 OES 纹理格式
if (neRtcVideoFrame.format != NERtcVideoFrame.Format.TEXTURE_OES) {
return false;
}
int width = neRtcVideoFrame.width;
int height = neRtcVideoFrame.height;
// 创建输入数据
FURenderInputData inputData = new FURenderInputData(width, height);
FURenderInputData.FUTexture texture = new FURenderInputData.FUTexture(
FUInputTextureEnum.FU_ADM_FLAG_EXTERNAL_OES_TEXTURE,
neRtcVideoFrame.textureId
);
inputData.setTexture(texture);
// 进行美颜处理
FURenderOutputData outputData = mFuRenderKit.renderWithInput(inputData);
// 更新视频帧数据
neRtcVideoFrame.format = NERtcVideoFrame.Format.TEXTURE_RGB;
neRtcVideoFrame.textureId = outputData.getTexture().getTexId();
return true;
}
}
Objective-C@implementation NertcFaceunityPlugin
- (void)handleMethodCall:(FlutterMethodCall*)call result:(FlutterResult)result {
if ([@"enableFuBeauty" isEqualToString:call.method]) {
NSNumber *enableVal = call.arguments[@"enable"];
int response = [self enableFuBeauty:enableVal.boolValue];
result(@(response));
} else {
result(FlutterMethodNotImplemented);
}
}
/**
* 启用或关闭美颜功能
* @param enable YES-启用美颜,NO-关闭美颜
* @return 操作结果状态码
*/
- (int)enableFuBeauty:(BOOL)enable {
int result = 0;
if (enable) {
// 设置视频帧观察者
result = [[NERtcEngine sharedEngine] setVideoFrameObserver:self];
} else {
// 移除视频帧观察者
result = [[NERtcEngine sharedEngine] setVideoFrameObserver:nil];
}
return result;
}
/**
* 视频帧捕获回调
* @param bufferRef 视频帧缓冲区
* @param rotation 旋转角度
*/
- (void)onNERtcEngineVideoFrameCaptured:(CVPixelBufferRef)bufferRef
rotation:(NERtcVideoRotationType)rotation {
// 检查相芯 SDK 是否已初始化
if (!fuIsLibraryInit()) {
return;
}
// 创建输入对象
FURenderInput *input = [[FURenderInput alloc] init];
input.pixelBuffer = bufferRef;
input.renderConfig.imageOrientation = 0;
// 根据旋转角度设置图像方向
FUImageOrientation orientation = FUImageOrientationUP;
switch (rotation) {
case kNERtcVideoRotation_0:
orientation = FUImageOrientationUP;
break;
case kNERtcVideoRotation_90:
orientation = FUImageOrientationLeft;
break;
case kNERtcVideoRotation_180:
orientation = FUImageOrientationDown;
break;
case kNERtcVideoRotation_270:
orientation = FUImageOrientationRight;
break;
default:
break;
}
input.renderConfig.imageOrientation = orientation;
// 进行美颜处理
FURenderOutput *outPut = [[FURenderKit shareRenderKit] renderWithInput:input];
// 将处理后的数据复制回原始缓冲区
[self convertPixBuffer:outPut.pixelBuffer dstPixBuffer:bufferRef];
}
@end
第四步:集成到视频通话流程
完成原生层开发后,在 Flutter 主应用中将美颜功能与视频通话无缝集成:
Dartclass VideoCallPage extends StatefulWidget {
final String channelName;
final int uid;
final NertcFaceunityPlugin _nertcFaceunityPlugin = NertcFaceunityPlugin();
VideoCallPage({required this.channelName, required this.uid});
@override
_VideoCallPageState createState() => _VideoCallPageState();
}
class _VideoCallPageState extends State<VideoCallPage> {
late NERtcEngine _engine;
bool _engineInited = false;
@override
void initState() {
super.initState();
_initEngine();
}
/// 初始化引擎并加入房间
void _initEngine() {
var options = const NERtcOptions(logLevel: NERtcLogLevel.info);
_engine.create(appKey: '网易云信 appkey', channelEventCallback: this, options: options)
.then((value) => _engine.enableLocalVideo(true)) // 启用本地视频
.then((value) => widget._nertcFaceunityPlugin.enableFuBeauty(true)) // 启用美颜
.then((value) => _engine.joinChannel('网易云信 token', widget.channelName, widget.uid)) // 加入房间
.then((value) {
_engineInited = true;
setState(() {});
});
}
/// 离开房间并释放资源
void _deinitEngine() async {
await widget._nertcFaceunityPlugin.enableFuBeauty(false); // 关闭美颜
await _engine.leaveChannel(); // 离开房间
await _engine.release(); // 释放引擎
_engineInited = false;
}
@override
void dispose() {
_deinitEngine();
super.dispose();
}
}
第五步:配置个性化美颜参数
基础美颜功能就绪后,您可以进一步利用相芯提供的丰富美颜参数进行个性化定制。相芯提供了 Flutter 插件 faceunity_plugin
,您可以通过该插件设置各种美颜参数。具体的美颜参数设置和使用方法请参考 faceunity_ui_flutter
项目示例。
第六步:资源释放
在应用退出或不再需要美颜功能时,请及时释放相关资源:
Dart// 关闭美颜功能
await _nertcFaceunityPlugin.enableFuBeauty(false);
// 释放 NERTC 引擎
await _engine.release();