相芯美颜

更新时间: 2025/08/06 13:52:46

网易云信 NERTC SDK 支持在 Flutter 项目中接入相芯(Faceunity)美颜特效 SDK,实现美颜、滤镜、贴纸等丰富美颜特效。在视频社交、在线教育、直播互动等场景中,您可以快速构建具备专业美颜能力的 Flutter 应用,提升用户在视频通话或直播过程中的形象表现力。

功能概述

通过集成相芯美颜 SDK,您可以在 Flutter 项目的 NERTC 音视频通话中实现以下功能:

  • 美化滤镜:支持美颜、滤镜、美妆、微整形等多种美化特效。
  • 贴纸道具:丰富的 AR 贴纸、动态表情等互动特效。
  • 实时美颜:基于深度学习的实时人脸检测和美化算法。
  • 跨平台支持:同时支持 Android 和 iOS 平台的 Flutter 应用。

工作原理

由于 Flutter 端的 GL 环境和原生环境进行了隔离,所以在 Flutter 中接入美颜时无法直接建立绑定关系,需要在原生端各自实现:

  1. Flutter 层通过 Method Channel 向原生层发送美颜控制指令。

  2. 原生层接收指令后,为 NERTC SDK 设置视频前处理回调接口。

  3. NERTC SDK 通过回调将采集到的视频帧数据传递给相芯美颜 SDK。

  4. 相芯美颜 SDK 处理完成后,将美颜后的视频帧返回给 NERTC SDK 进行编码和传输。

    相芯美颜原理

注意事项

  • GL 环境隔离:Flutter 端的 GL 环境和原生环境进行了隔离,美颜处理必须在原生端实现。
  • 纹理格式:Android 端需要处理 OES 纹理到 RGB 纹理的转换。
  • 图像方向:iOS 端需要根据旋转角度正确设置图像方向。
  • 内存管理:处理过程中需要注意内存的正确管理,防止内存泄漏。

前提条件

在集成相芯美颜 SDK 前,请确保您已完成以下准备工作:

示例项目

网易云信提供了示例代码供您参考 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
  1. 集成网易云信 NERTC SDK。如果您已完成本步骤,请跳过此步。

    pubspec.yaml 中添加 NERTC SDK 依赖:

    yamldependencies:
      nertc_core: ^5.8.23 # 请使用您项目中的实际版本
    
  2. 集成相芯美颜 SDK

    1. 配置 NERTC SDK 依赖。

      Android

      android/build.gradle 中添加依赖:

      gradledependencies {
          compileOnly 'com.netease.yunxin:nertc-base:x.x.x' // 使用您项目中的实际版本
          implementation project(path: ':faceunity_plugin') // 相芯提供的 Flutter 插件
      }
      
      iOS

      .podspec 文件中添加依赖:

      rubys.dependency 'NERtcSDK'
      s.dependency 'FURenderKit', '8.10.0'
      
    2. 配置 Flutter 依赖。

      pubspec.yaml 中添加相芯美颜插件:

      yamldependencies:
        nertc_core: ^5.8.23
        # 其他依赖...
      
  3. 更换鉴权文件。将相芯提供的 Android、iOS 鉴权文件替换到项目 faceunity_plugin 的正确位置,例如:

    • Androidfaceunity_plugin/android/src/main/kotlin/com/faceunity/faceunity_plugin/authpack.java
    • iOSfaceunity_plugin/ios/Classes/Tools/authpack.h

第二步:构建 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 平台编写美颜功能的核心实现代码:

Android
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;
    }
}
iOS
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();

参考文档

此文档是否对你有帮助?
有帮助
去反馈
  • 功能概述
  • 工作原理
  • 注意事项
  • 前提条件
  • 示例项目
  • 第一步:集成 SDK
  • 第二步:构建 Flutter 与原生的桥接层
  • 第三步:实现原生美颜处理逻辑
  • 第四步:集成到视频通话流程
  • 第五步:配置个性化美颜参数
  • 第六步:资源释放
  • 参考文档