# 使用说明 (/zh-CN/realtime-media/marketplace/build/integrate-extensions/faceunity-ar)

> For AI agents: see the complete documentation index at [llms.txt](/llms.txt).

<_PlatformTabsGroup>
<_PlatformProcessedMarker groupMode="structured" canonicalPlatform="android" platform="android" />
## 技术原理 [#技术原理]

本文介绍如何在你的项目中集成和使用相芯美颜道具高级版插件。相芯美颜道具高级版插件是对相芯 Nama SDK 核心 API 的封装。通过[声网 SDK v4.x](/zh-CN/realtime-media/rtc) 提供的 [`setExtensionProperty`](/zh-CN/api-reference/rtc/android/extension#api_irtcengine_setextensionproperty) 方法，传入指定的 `key` 和 `value` 参数，你可以快速集成相芯的美颜能力。

`setExtensionProperty` 方法的 `key` 参数与相芯的 API 名称完全对应，`value` 参数以 JSON 格式包装该 API 的部分或全部参数。因此，调用该方法时只要传入指定的 `key` 和 `value`，就可以调用对应的相芯 API，实现美颜的有关功能。

## 前提条件 [#前提条件]

Android 开发环境需满足以下要求：

- Android Studio 4.1 以上版本。
- 运行 Android 5.0 或以上版本的真机（非模拟器）。

## 示例项目 [#示例项目]

声网[云市场](https://console.shengwang.cn/marketplace/list/all)提供了相芯美颜道具高级版插件 Android、iOS 和 Flutter 的示例项目，你可以前往插件详情页克隆或下载并进行体验。

## 集成和调用流程 [#集成和调用流程]

### 1. 集成 SDK 和插件 [#1-集成-sdk-和插件]

开始前，你需要在项目中分别集成声网视频 SDK 和相芯美颜道具高级版插件。

#### 1.1 使用声网 SDK 实现音视频互动 [#11-使用声网-sdk-实现音视频互动]

插件需要与 [RTC SDK](/zh-CN/realtime-media/rtc) 搭配使用。参考以下文档集成 RTC SDK 并实现基础的音视频互动：

<Cards>
  <Card title="实现音视频互动" href="/zh-CN/realtime-media/rtc/get-started/quick-start" />
</Cards>

#### 1.2 购买和激活插件 [#12-购买和激活插件]

你需要进入[声网控制台 > 云市场](https://console.shengwang.cn/marketplace/list/all)页面，按照提示购买相芯美颜道具高级版插件，并且联系声网提供你的包名（例如 `yourCompany.yourProject.faceunity`）。随后你会收到与包名唯一对应的证书文件，用于后续集成插件。

<a id="integration"></a>
#### 1.3 集成插件 [#13-集成插件]

参考以下步骤集成插件：

1. 进入[声网控制台 > 云市场](https://console.shengwang.cn/marketplace/list/all)页面，下载**相芯美颜道具高级版**的 Android 插件动态库压缩包。
2. 解压文件夹，将所有 `.aar` 文件保存到项目文件夹，比如 `/app/libs`  路径。
3. 将证书文件 `authpack.java` 保存到你在获取证书文件时提供的包名所对应的路径下（例如：获取证书文件时提供的包名为 `io.agora.rte.extension.faceunity.example`，那么证书文件需要保存到 `/app/src/main/java/io/agora/rte/extension/faceunity/example` 路径）。
4. [点击下载](https://download.agora.io/marketplace/release/Agora_Marketplace_FaceUnity_v8.11.0_Resource.zip)相芯美颜插件的资源包，将所需的模型和道具文件保存到项目文件夹，比如 `/app/res/Resource` 路径。资源包中提供的文件详见[参考信息](#ref)。
5. 打开 `app/build.gradle` 文件，在 `dependencies` 中添加如下行：

    ```java
    implementation fileTree(dir: "libs", include: ["*.jar", "*.aar"])
    ```

6. 导入需要用到的类：

    ```java
    import io.agora.rtc2.Constants;
    import io.agora.rtc2.IMediaExtensionObserver;
    import io.agora.rtc2.IRtcEngineEventHandler;
    import io.agora.rtc2.RtcEngine;
    import io.agora.rtc2.RtcEngineConfig;
    import io.agora.rtc2.video.VideoCanvas;
    import io.agora.rte.extension.faceunity.ExtensionManager;
    ```

#### 1.4 升级插件 [#14-升级插件]

声网云市场推荐你在更新插件版本前使用数据库工具（如 SQLite）实现插件版本管理，从而确保插件版本与对应的资源包版本一致。因为当插件版本和资源包版本未对齐时，会出现 App 闪退、崩溃等现象。

以下是用 SQLite 来进行插件版本管理的示例：

  1. 使用 SQLite 数据库自行维护插件包和资源包的版本信息。
  2. 每次项目初始化时，自动检测当前项目使用的资源包版本：
      - 如果无记录文件或记录的资源包版本为旧，则更新资源。成功更新后，回写最新资源包版本信息到 SQLite。
      - 如果记录的资源包版本与当前匹配，则正常实现业务。

如果你的项目已经集成过声网云市场提供的第三方插件，并需要更新插件，可以参考以下步骤来保证更新后的可用性。

以下升级流程以**相芯美颜特效**插件为例：

  1. 参考[集成插件](#13-集成插件)章节下载所需平台最新版本的插件包和资源包。

  2. 删除项目内旧版本的插件包及其资源包后，再将新版插件和资源包放入对应位置。或者直接在对应目录下用新版插件和资源包替换旧版。

  3. 删除设备上用老版本插件和资源包编译的 App，重新编译你的项目并运行。

:::warning[注意]
编译 App 时，系统会优先使用连接设备上存在的资源包。请务必在删除旧版本应用程序后再进行编译和运行，否则可能会出现插件版本与资源包不匹配的情况，从而导致各种意外问题。
:::

### 2. 启用插件 [#2-启用插件]

创建并初始化 `RtcEngine` 后，首先调用 `enableExtension` 启用插件，再调用其它 API（`enableVideo`、`joinChannel` 等）。

```java
RtcEngineConfig config = new RtcEngineConfig();

mRtcEngine = RtcEngine.create(config);
// 启用插件
mRtcEngine.enableExtension("FaceUnity", "Effect", enabled);
```

### 3. 初始化插件 [#3-初始化插件]

当收到声网 SDK 的 `onExtensionStarted` 回调后，你可以在主线程或其他工作线程中调用 `setExtensionProperty` 并传入对应的 `key` 和 `value` 进行初始化:

1. 初始化。对应的 `key` 为 `fuSetup`，`value` 为证书文件 authpack 的指针。
2. 加载 AI 模型。对应的 `key` 为 `fuLoadAIModelFromPackage`，`value` 包含 AI 能力模型文件 `ai_xxx.bundle` 的路径以及 AI 能力类型。

:::note[注意]
声网建议你在 `onExtensionStarted` 回调中仅做标记处理（比如设置一个 flag），避免在回调中直接执行初始化等耗时操作，以防阻塞 SDK 事件循环。
:::

```java
private void initExtension() {
    // 初始化
    try {
        JSONObject jsonObject = new JSONObject();
        JSONArray jsonArray = new JSONArray();
        for (byte it : authpack.A()) {
            jsonArray.put(it);
        }
        jsonObject.put("authdata", jsonArray);
        setExtensionProperty("fuSetup", jsonObject.toString());
    } catch (JSONException e) {
        Log.e(TAG, e.toString());
    }

    // 加载 AI 模型
    File modelDir = new File(getExternalFilesDir("assets"),
            "face_unity/model/ai_face_processor.bundle");
    try {
        JSONObject jsonObject = new JSONObject();
        jsonObject.put("data", modelDir.getAbsolutePath());
        // 通过 type 参数设置 AI 能力类型为 FUAITYPE_FACEPROCESSOR，对应取值为 1 << 8
        jsonObject.put("type", 1 << 8);
        setExtensionProperty("fuLoadAIModelFromPackage", jsonObject.toString());
    } catch (JSONException e) {
        Log.e(TAG, e.toString());
    }
}

// 方便多次调用 setExtensionProperty
private void setExtensionProperty(String key, String property) {
    mRtcEngine.setExtensionProperty("FaceUnity", "Effect", key, property);
}
```

### 4. 设置美颜效果和人体识别 [#4-设置美颜效果和人体识别]

设置美颜效果需要调用 `setExtensionProperty` 并传入对应的 `key` 和 `value`，实现以下功能：

- 加载道具、调节美颜强度
- 人脸、手势和人体识别

你可以根据场景需要进行组合调用。相关的 `key` 和 `value` 详见 [key-value 说明](/zh-CN/realtime-media/marketplace/reference/faceunity-ar-api)。

### 5. 释放资源 [#5-释放资源]

需要停止使用插件时，按照以下步骤释放资源：

1. 调用 `setExtensionProperty` 并传入 `key` 为 `fuDestroyLibData`，释放插件占用的资源。
2. 收到 `fuDestroyLibData` 回调后，调用 `destroy` 方法销毁 `RtcEngine` 对象。

<a id="ref"></a>
## 参考信息 [#参考信息]
### API 参考 [#api-参考]

- [声网 SDK 的插件相关方法和回调](/zh-CN/api-reference/rtc/android/extension#toc_extension)
- [插件的 key-value 说明](/zh-CN/realtime-media/marketplace/reference/faceunity-ar-api)

### 常见问题 [#常见问题]

**问题 1：运行示例项目，美颜为什么没有生效？**

通常有以下几个原因：

- 插件动态库没有保存在正确位置，或者没有导入；
- 相芯资源包中的文件没有保存在正确位置，或者缺少部分文件；
- 证书文件与 App 包名不一致，导致鉴权失败。

**问题 2：为什么开启采集后需要 1s 左右才能渲染出视频？**

加载相芯美颜资源的操作会造成 GL 渲染线程卡顿，加载资源的过程大概耗时 800ms。建议通过业务处理（比如添加 loading 界面）规避。

**问题 3：为什么在编译 App 时会出现 `models: no match` 的报错？**

该错误通常是由于资源包匹配问题引起的。很可能是因为在编译新插件时，没有删除旧版本的 App。建议你删除旧版 App 后重新编译运行。

<a id="resource"></a>
### 素材包结构 [#素材包结构]

相芯美颜道具高级版插件的资源包文件结构详见：

  - [Android 资源包结构](https://gitee.com/hangzhou_xiangxin_1/FULiveDemoDroid/blob/master/doc/Android_Nama_Demo_%E8%BF%90%E8%A1%8C%E6%96%87%E6%A1%A3.md#2-demo%E6%96%87%E4%BB%B6%E7%BB%93%E6%9E%84)
  - [iOS 资源包结构](https://gitee.com/hangzhou_xiangxin_1/FULiveDemo/blob/master/docs/iOS_Nama_SDK_%E9%9B%86%E6%88%90%E6%8C%87%E5%AF%BC%E6%96%87%E6%A1%A3.md#2-sdk%E6%96%87%E4%BB%B6%E7%BB%93%E6%9E%84%E4%BD%BF%E7%94%A8%E6%96%B0%E6%9E%B6%E6%9E%84furenderkit%E5%8A%A8%E6%80%81%E5%BA%93)

更多的接口调用方式可以参考相芯 Nama SDK 的文档：

	- [Android 文档](https://gitee.com/hangzhou_xiangxin_1/FULiveDemoDroid/blob/master/doc)
	- [iOS 文档](https://gitee.com/hangzhou_xiangxin_1/FULiveDemo/tree/master/docs)
<_PlatformProcessedMarker close="true" />

<_PlatformProcessedMarker groupMode="structured" canonicalPlatform="android" platform="ios" />
本文介绍如何在你的项目中集成和使用相芯美颜道具高级版插件。
## 技术原理 [#技术原理-1]

相芯美颜道具高级版插件是对相芯 Nama SDK 核心 API 的封装。通过[声网 SDK v4.x](/zh-CN/realtime-media/rtc) 提供的 [`setExtensionPropertyWithVendor`](/zh-CN/api-reference/rtc/ios/extension#api_irtcengine_setextensionproperty) 方法，传入指定的 `key` 和 `value` 参数，你可以快速集成相芯的美颜能力。

`setExtensionPropertyWithVendor` 方法的 `key` 参数与相芯的 API 名称完全对应，`value` 参数以 JSON 格式包装该 API 的部分或全部参数。因此，调用该方法时只要传入指定的 `key` 和 `value`，就可以调用对应的相芯 API，实现美颜的有关功能。

## 前提条件 [#前提条件-1]

iOS 开发环境需满足以下要求：

- Xcode 9.0 或以上版本。
- 运行 iOS 9.0 或以上版本的真机（非模拟器）。

## 示例项目 [#示例项目-1]

声网[云市场](https://console.shengwang.cn/marketplace/list/all)提供了相芯美颜道具高级版插件 Android、iOS 和 Flutter 的示例项目，你可以前往插件详情页克隆或下载并进行体验。

## 集成和调用流程 [#集成和调用流程-1]

### 1. 集成 SDK 和插件 [#1-集成-sdk-和插件-1]

开始前，你需要在项目中分别集成声网视频 SDK 和相芯美颜道具高级版插件。

#### 1.1 使用声网 SDK 实现音视频互动 [#11-使用声网-sdk-实现音视频互动-1]

插件需要与 [RTC SDK](/zh-CN/realtime-media/rtc) 搭配使用。参考以下文档集成 RTC SDK 并实现基础的音视频互动：

<Cards>
  <Card title="实现音视频互动" href="/zh-CN/realtime-media/rtc/get-started/quick-start" />
</Cards>

#### 1.2 购买和激活插件 [#12-购买和激活插件-1]

你需要进入[声网控制台 > 云市场](https://console.shengwang.cn/marketplace/list/all)页面，按照提示购买相芯美颜道具高级版插件，并且联系声网提供你的包名（例如 `yourCompany.yourProject.faceunity`）。随后你会收到与包名唯一对应的证书文件，用于后续集成插件。

<a id="integration"></a>
#### 1.3 集成插件 [#13-集成插件-1]

参考以下步骤集成插件：

1. 进入[声网控制台 > 云市场](https://console.shengwang.cn/marketplace/list/all)页面，下载**相芯美颜道具高级版**的 iOS 插件动态库压缩包。
2. 解压文件夹，将所有 `.framework` 文件导入项目，并将 **Embed** 修改为 **Embed & Sign**。
3. 将证书文件 `authpack.h` 引入你的 Xcode 项目。
4. [点击下载](https://download.agora.io/marketplace/release/Agora_Marketplace_FaceUnity_v8.11.0_Resource.zip)相芯美颜插件的资源包，将所需的模型和道具文件保存到项目文件夹，比如 `Resource` 路径。资源包中提供的文件详见[参考信息](#ref)。

    ```shell
     项目文件夹示例
    .
    ├── <ProjectName>
    ├── <ProjectName>.xcodeproj
    └── Resource
    ```

5. 导入需要用到的头文件：

    ```objc
    #import <AgoraRtcKit/AgoraRtcEngineKit.h>
    #import "authpack.h"
    ```

#### 1.4 升级插件 [#14-升级插件-1]

声网云市场推荐你在更新插件版本前使用数据库工具（如 SQLite）实现插件版本管理，从而确保插件版本与对应的资源包版本一致。因为当插件版本和资源包版本未对齐时，会出现 App 闪退、崩溃等现象。

以下是用 SQLite 来进行插件版本管理的示例：

  1. 使用 SQLite 数据库自行维护插件包和资源包的版本信息。
  2. 每次项目初始化时，自动检测当前项目使用的资源包版本：
      - 如果无记录文件或记录的资源包版本为旧，则更新资源。成功更新后，回写最新资源包版本信息到 SQLite。
      - 如果记录的资源包版本与当前匹配，则正常实现业务。

如果你的项目已经集成过声网云市场提供的第三方插件，并需要更新插件，可以参考以下步骤来保证更新后的可用性。

以下升级流程以**相芯美颜特效**插件为例：

  1. 参考[集成插件](#13-集成插件-1)章节下载所需平台最新版本的插件包和资源包。

  2. 删除项目内旧版本的插件包及其资源包后，再将新版插件和资源包放入对应位置。或者直接在对应目录下用新版插件和资源包替换旧版。

  3. 删除设备上用老版本插件和资源包编译的 App，重新编译你的项目并运行。

:::warning[注意]
编译 App 时，系统会优先使用连接设备上存在的资源包。请务必在删除旧版本应用程序后再进行编译和运行，否则可能会出现插件版本与资源包不匹配的情况，从而导致各种意外问题。
:::

### 2. 启用插件 [#2-启用插件-1]

创建并初始化 `AgoraRtcEngineKit` 后，首先调用 `enableExtensionWithVendor` 启用插件，再调用其它 API（`enableVideo`、`joinChannelByToken` 等）。

```objc
[self.agoraKit enableExtensionWithVendor:@"FaceUnity"
                               extension:@"Effect"
                                 enabled:self.enable];
```

### 3. 初始化插件 [#3-初始化插件-1]

当收到声网 SDK 的 `onExtensionStarted` 回调后，你可以在主线程或其他工作线程中调用 `setExtensionPropertyWithVendor` 并传入对应的 `key` 和 `value` 进行初始化:

1. 初始化。对应的 `key` 为 `fuSetup`，`value` 为证书文件 authpack 的指针。
2. 加载 AI 模型。对应的 `key` 为 `fuLoadAIModelFromPackage`，`value` 包含 AI 能力模型文件 `ai_xxx.bundle` 的路径以及 AI 能力类型。

:::note[注意]
声网建议你在 `onExtensionStarted` 回调中仅做标记处理（比如设置一个 flag），避免在回调中直接执行初始化等耗时操作，以防阻塞 SDK 事件循环。
:::

```objc
- (void)loadAIModels {
    [self.agoraKit
        setExtensionPropertyWithVendor:@"FaceUnity"
                             extension:@"Effect"
                                   key:@"fuLoadAIModelFromPackage"
                                 value:[self toJson:@{
                                   @"data": [[NSBundle mainBundle]
                                       pathForResource:@"ai_face_processor"
                                                ofType:@"bundle"],
                                   // 通过 type 参数设置 AI 能力类型为 FUAITYPE_FACEPROCESSOR，对应取值为 1 << 8
                                   @"type": @(1 << 8)
                                 }]];

    [self.agoraKit
        setExtensionPropertyWithVendor:@"FaceUnity"
                             extension:@"Effect"
                                   key:@"fuLoadAIModelFromPackage"
                                 value:[self toJson:@{
                                   @"data": [[NSBundle mainBundle]
                                       pathForResource:@"ai_hand_processor"
                                                ofType:@"bundle"],
                                   @"type": @(1 << 3)
                                 }]];

    [self.agoraKit
        setExtensionPropertyWithVendor:@"FaceUnity"
                             extension:@"Effect"
                                   key:@"fuLoadAIModelFromPackage"
                                 value:[self toJson:@{
                                   @"data": [[NSBundle mainBundle]
                                       pathForResource:@"ai_human_processor_gpu"
                                                ofType:@"bundle"],
                                   @"type": @(1 << 9)
                                 }]];

    [self.agoraKit
        setExtensionPropertyWithVendor:@"FaceUnity"
                             extension:@"Effect"
                                   key:@"fuCreateItemFromPackage"
                                 value:[self toJson:@{
                                   @"data": [[NSBundle mainBundle]
                                       pathForResource:@"aitype"
                                                ofType:@"bundle"]
                                 }]];

    [self.agoraKit
        setExtensionPropertyWithVendor:@"FaceUnity"
                             extension:@"Effect"
                                   key:@"fuItemSetParam"
                                 value:[self toJson:@{
                                   @"obj_handle": [[NSBundle mainBundle]
                                       pathForResource:@"aitype"
                                                ofType:@"bundle"],
                                   @"name": @"aitype",
                                   @"value": @(1 << 8 | 1 << 30 | 1 << 3),
                                 }]];
}
```

### 4. 设置美颜效果和人体识别 [#4-设置美颜效果和人体识别-1]

设置美颜效果需要调用 `setExtensionPropertyWithVendor` 并传入对应的 `key` 和 `value`，实现以下功能：

- 加载道具、调节美颜强度
- 人脸、手势和人体识别

你可以根据场景需要进行组合调用。相关的 `key` 和 `value` 详见 [key-value 说明](/zh-CN/realtime-media/marketplace/reference/faceunity-ar-api)。

### 5. 释放资源 [#5-释放资源-1]

需要停止使用插件时，按照以下步骤释放资源：

1. 调用 `setExtensionPropertyWithVendor` 并传入 `key` 为 `fuDestroyLibData`，释放插件占用的资源。
2. 收到 `fuDestroyLibData` 回调后，调用 `destroy` 方法销毁 `AgoraRtcEngineKit` 对象。

<a id="ref"></a>
## 参考信息 [#参考信息-1]
### API 参考 [#api-参考-1]

- [声网 SDK 的插件相关方法和回调](/zh-CN/api-reference/rtc/ios/extension#toc_extension)
- [插件的 key-value 说明](/zh-CN/realtime-media/marketplace/reference/faceunity-ar-api)

### 常见问题 [#常见问题-1]

**问题 1：运行示例项目，美颜为什么没有生效？**

通常有以下几个原因：

- 插件动态库没有保存在正确位置，或者没有导入；
- 相芯资源包中的文件没有保存在正确位置，或者缺少部分文件；
- 证书文件与 App 包名不一致，导致鉴权失败。

**问题 2：为什么开启采集后需要 1s 左右才能渲染出视频？**

加载相芯美颜资源的操作会造成 GL 渲染线程卡顿，加载资源的过程大概耗时 800ms。建议通过业务处理（比如添加 loading 界面）规避。

**问题 3：为什么在编译 App 时会出现 `models: no match` 的报错？**

该错误通常是由于资源包匹配问题引起的。很可能是因为在编译新插件时，没有删除旧版本的 App。建议你删除旧版 App 后重新编译运行。

<a id="resource"></a>
### 素材包结构 [#素材包结构-1]

相芯美颜道具高级版插件的资源包文件结构详见：

  - [Android 资源包结构](https://gitee.com/hangzhou_xiangxin_1/FULiveDemoDroid/blob/master/doc/Android_Nama_Demo_%E8%BF%90%E8%A1%8C%E6%96%87%E6%A1%A3.md#2-demo%E6%96%87%E4%BB%B6%E7%BB%93%E6%9E%84)
  - [iOS 资源包结构](https://gitee.com/hangzhou_xiangxin_1/FULiveDemo/blob/master/docs/iOS_Nama_SDK_%E9%9B%86%E6%88%90%E6%8C%87%E5%AF%BC%E6%96%87%E6%A1%A3.md#2-sdk%E6%96%87%E4%BB%B6%E7%BB%93%E6%9E%84%E4%BD%BF%E7%94%A8%E6%96%B0%E6%9E%B6%E6%9E%84furenderkit%E5%8A%A8%E6%80%81%E5%BA%93)

更多的接口调用方式可以参考相芯 Nama SDK 的文档：

	- [Android 文档](https://gitee.com/hangzhou_xiangxin_1/FULiveDemoDroid/blob/master/doc)
	- [iOS 文档](https://gitee.com/hangzhou_xiangxin_1/FULiveDemo/tree/master/docs)
<_PlatformProcessedMarker close="true" />

<_PlatformProcessedMarker groupMode="structured" canonicalPlatform="android" platform="flutter" />
本文介绍如何在你的项目中集成和使用相芯美颜道具高级版插件。
## 技术原理 [#技术原理-2]

相芯美颜道具高级版插件是对相芯 Nama SDK 核心 API 的封装。通过[声网 SDK v4.x](/zh-CN/realtime-media/rtc) 提供的 [`setExtensionProperty`](/zh-CN/api-reference/rtc/android/extension#api_irtcengine_setextensionproperty) 方法，传入指定的 `key` 和 `value` 参数，你可以快速集成相芯的美颜能力。

`setExtensionProperty` 方法的 `key` 参数与相芯的 API 名称完全对应，`value` 参数以 JSON 格式包装该 API 的部分或全部参数。因此，调用该方法时只要传入指定的 `key` 和 `value`，就可以调用对应的相芯 API，实现美颜的有关功能。

## 前提条件 [#前提条件-2]

### 开发环境要求 [#开发环境要求]

如果你的目标平台为 iOS，你的开发环境需要满足以下需求：

- Flutter 2.0 或更高版本
- Dart 2.14.0 或更高版本
- macOS 操作系统
- 最新版本的 Xcode

如果你的目标平台为 Android，你的开发环境需要满足以下需求：

- Flutter 2.0 或更高版本
- Dart 2.14.0 或更高版本
- macOS 或 Windows 操作系统
- 最新版本的 Android Studio

### 运行环境要求 [#运行环境要求]

- 如果你的目标平台为 iOS，你需要有一台 iOS 的设备。
- 如果你的目标平台为 Android，你需要有一台 Android 设备或模拟器。

:::info[信息]
你需要运行 `flutter doctor` 命令检查开发环境和运行环境是否满足要求。
:::

## 示例项目 [#示例项目-2]

声网[云市场](https://console.shengwang.cn/marketplace/list/all)提供了相芯美颜道具高级版插件 Android、iOS 和 Flutter 的示例项目，你可以前往插件详情页克隆或下载并进行体验。

## 集成和调用流程 [#集成和调用流程-2]

### 1. 集成 SDK 和插件 [#1-集成-sdk-和插件-2]

开始前，你需要在项目中分别集成声网视频 SDK 和相芯美颜道具高级版插件。

#### 1.1 使用声网 SDK 实现音视频互动 [#11-使用声网-sdk-实现音视频互动-2]

插件需要与 [RTC SDK](/zh-CN/realtime-media/rtc) 搭配使用。参考以下文档集成 RTC SDK 并实现基础的音视频互动：

#### 1.2 购买和激活插件 [#12-购买和激活插件-2]

你需要进入[声网控制台 > 云市场](https://console.shengwang.cn/marketplace/list/all)页面，按照提示购买相芯美颜道具高级版插件，并且联系声网提供你的包名（例如 `yourCompany.yourProject.faceunity`）。随后你会收到与包名唯一对应的证书文件，用于后续集成插件。

<a id="integration"></a>
#### 1.3 集成插件 [#13-集成插件-2]

参考以下步骤集成插件：

1. 在 Flutter 项目中，根据实际需要集成原生的 Android 和/或 iOS 插件：

<Accordions type="multiple">
<Accordion title="通过 Gradle 集成 Android 插件">

1. 进入[声网控制台 > 云市场](https://console.shengwang.cn/marketplace/list/all)页面，下载**相芯美颜道具高级版**的 Android 插件动态库压缩包。
2. 解压文件夹，将所有 `.aar` 文件保存到项目文件夹，比如 `android/libs`  路径。

   <DocsImage alt="Android 插件 .aar 文件目录示例" src="https://web-cdn.agora.io/docs-files/1673335651833" displayWidth="50%" />

3. 打开 `android/app/build.gradle` 文件，在 `dependencies` 中添加如下行：

   ```java
   implementation fileTree(dir: "${rootProject.projectDir}/libs", include: ["*.aar"])
   ```
</Accordion>
</Accordions>


<Accordions type="multiple">
<Accordion title="通过 CocoaPods 集成 iOS 插件">

1. 进入[声网控制台 > 云市场](https://console.shengwang.cn/marketplace/list/all)页面，下载**相芯美颜道具高级版**的 iOS 插件动态库压缩包。
2. 解压文件夹，将所有 `.framework` 文件导入项目。
   ![iOS 插件 .framework 文件导入示例](https://web-cdn.agora.io/docs-files/1676977533150)

3. 在 `.podspec` 文件中添加依赖，示例如下：

    ```ruby
    Pod::Spec.new do |s|
    s.name             = 'Extensions'
    s.version          = '0.1.0'
    s.summary          = 'ByteDance effect plugin for声网 RTE extensions.'
    s.description      = 'project.description'
    s.homepage         = 'https://github.com/AgoraIO-Community/AgoraMarketPlace'
    s.author           = { 'Agora' => 'developer@agora.io' }
    s.source           = { :path => '.' }
    s.vendored_frameworks = 'FURenderKit.framework', 'AgoraFaceUnityExtension.framework'
    s.platform = :ios, '9.0'
    end
    ```

4. 在 `Podfile` 文件中添加如下行：

    ```ruby
    pod 'Extensions', :path => "./"
    ```
</Accordion>
</Accordions>


2. 添加证书文件：将插件包里的证书文件（`authpack.java` 或 `authpack.h`）转换成 dart 语法，并保存到项目文件夹，比如 `lib` 路径。`authpack.java` 和 `authpack.h` 所包含的证书数据一样。以转换 `authpack.h` 文件为例，将文件内的数据复制到 `List<int> gAuthPackage = [];` 这一行的 `[]` 中即可：

    ```dart
    /// 填写示例：List<int> gAuthPackage = [10, 13, -98, -100, 126, ...];
    List<int> gAuthPackage = [Paste your authpack data];
    ```

<DocsImage alt="Flutter 项目中的 authpack 数据示例" src="https://web-cdn.agora.io/docs-files/1673335764163" displayWidth="50%" />

3. [点击下载](https://download.agora.io/marketplace/release/Agora_Marketplace_FaceUnity_v8.11.0_Resource.zip)相芯美颜插件的资源包，将所需的模型和道具 `.bundle` 文件通过 [Flutter assets](https://docs.flutter.dev/development/ui/assets-and-images) 的方式保存到项目文件夹，比如 `Resource` 路径。资源包中提供的文件详见[参考信息](#ref)。

<DocsImage alt="Flutter 资源包目录示例" src="https://web-cdn.agora.io/docs-files/1673335775613" displayWidth="50%" />

4. 在 `pubspec.yaml` 文件中添加依赖项，示例如下：

   ```yaml
   environment:
     sdk: '>=2.18.6 <3.0.0'

   dependencies:
     flutter:
       sdk: flutter

     cupertino_icons: ^1.0.2
     #声网 Flutter SDK 依赖项，请使用最新版本的 agora_rtc_engine
     agora_rtc_engine: ^6.0.0
     path_provider: ^2.0.11
     permission_handler: ^8.3.0
     path: ^1.8.0

   # The following section is specific to Flutter packages.
   flutter:

     # 添加相芯资源文件依赖项
     assets:
       - Resource/graphics/aitype.bundle
       - Resource/items/ItemSticker/CatSparks.bundle
       - Resource/model/ai_face_processor.bundle
   ```

5. 导入需要用到的 dart 文件：

   ```dart
   import 'package:agora_rtc_engine/agora_rtc_engine.dart';
   import 'authpack.dart' as authpack;
   ```

#### 1.4 升级插件 [#14-升级插件-2]

声网云市场推荐你在更新插件版本前使用数据库工具（如 SQLite）实现插件版本管理，从而确保插件版本与对应的资源包版本一致。因为当插件版本和资源包版本未对齐时，会出现 App 闪退、崩溃等现象。

以下是用 SQLite 来进行插件版本管理的示例：

  1. 使用 SQLite 数据库自行维护插件包和资源包的版本信息。
  2. 每次项目初始化时，自动检测当前项目使用的资源包版本：
      - 如果无记录文件或记录的资源包版本为旧，则更新资源。成功更新后，回写最新资源包版本信息到 SQLite。
      - 如果记录的资源包版本与当前匹配，则正常实现业务。

如果你的项目已经集成过声网云市场提供的第三方插件，并需要更新插件，可以参考以下步骤来保证更新后的可用性。

以下升级流程以**相芯美颜特效**插件为例：

  1. 参考[集成插件](#13-集成插件-2)章节下载所需平台最新版本的插件包和资源包。

  2. 删除项目内旧版本的插件包及其资源包后，再将新版插件和资源包放入对应位置。或者直接在对应目录下用新版插件和资源包替换旧版。

  3. 删除设备上用老版本插件和资源包编译的 App，重新编译你的项目并运行。

:::warning[注意]
编译 App 时，系统会优先使用连接设备上存在的资源包。请务必在删除旧版本应用程序后再进行编译和运行，否则可能会出现插件版本与资源包不匹配的情况，从而导致各种意外问题。
:::

### 2. 启用插件 [#2-启用插件-2]

创建并初始化 `RtcEngine` 后，首先调用 `enableExtension` 启用插件，再调用其它 API（`enableVideo`、`joinChannel` 等）。

```dart
// On Android, you should load libAgoraFaceUnityExtension.so explicitly
if (Platform.isAndroid) {
  await _rtcEngine.loadExtensionProvider(path: 'AgoraFaceUnityExtension');
}
await _rtcEngine.enableExtension(
    provider: "FaceUnity", extension: "Effect", enable: true);
```

### 3. 初始化插件 [#3-初始化插件-2]

当收到声网 SDK 的 `onExtensionStarted` 回调后，你可以在主线程或其他工作线程中调用 `setExtensionProperty` 并传入对应的 `key` 和 `value` 进行初始化:

1. 初始化。对应的 `key` 为 `fuSetup`，`value` 为证书文件 authpack 的指针。
2. 加载 AI 模型。对应的 `key` 为 `fuLoadAIModelFromPackage`，`value` 包含 AI 能力模型文件 `ai_xxx.bundle` 的路径以及 AI 能力类型。

:::note[注意]
声网建议你在 `onExtensionStarted` 回调中仅做标记处理（比如设置一个 flag），避免在回调中直接执行初始化等耗时操作，以防阻塞 SDK 事件循环。
:::

```dart
Future<void> _initFUExtension() async {
  // 初始化
  await _rtcEngine.setExtensionProperty(
      provider: 'FaceUnity',
      extension: 'Effect',
      key: 'fuSetup',
      value: jsonEncode({'authdata': authpack.gAuthPackage}));

  // 加载 AI 模型
  final aiFaceProcessorPath =
      await _copyAsset('Resource/model/ai_face_processor.bundle');
  await _rtcEngine.setExtensionProperty(
      provider: 'FaceUnity',
      extension: 'Effect',
      key: 'fuLoadAIModelFromPackage',
      // 通过 type 参数设置 AI 能力类型为 FUAITYPE_FACEPROCESSOR，对应取值为 1 << 8
      value: jsonEncode({'data': aiFaceProcessorPath, 'type': 1 << 8}));
}
```

### 4. 设置美颜效果和人体识别 [#4-设置美颜效果和人体识别-2]

设置美颜效果需要调用 `setExtensionProperty` 并传入对应的 `key` 和 `value`，实现以下功能：

- 加载道具、调节美颜强度
- 人脸、手势和人体识别

你可以根据场景需要进行组合调用。相关的 `key` 和 `value` 详见 [key-value 说明](/zh-CN/realtime-media/marketplace/reference/faceunity-ar-api)。

设置猫耳效果的示例如下：

```dart
Future<void> _setupCatSparksEffect() async {
  final aiFaceProcessorPath =
      await _copyAsset('Resource/model/ai_face_processor.bundle');
  await _rtcEngine.setExtensionProperty(
      provider: 'FaceUnity',
      extension: 'Effect',
      key: 'fuLoadAIModelFromPackage',
      // 通过 type 参数设置 AI 能力类型为 FUAITYPE_FACEPROCESSOR，对应取值为 1 << 8
      value: jsonEncode({'data': aiFaceProcessorPath, 'type': 1 << 8}));

  final catSparksPath =
      await _copyAsset('Resource/items/ItemSticker/CatSparks.bundle');
  await _rtcEngine.setExtensionProperty(
      provider: 'FaceUnity',
      extension: 'Effect',
      key: 'fuCreateItemFromPackage',
      value: jsonEncode({'data': catSparksPath}));
}
```

### 5. 释放资源 [#5-释放资源-2]

需要停止使用插件时，按照以下步骤释放资源：

1. 调用 `setExtensionProperty` 并传入 `key` 为 `fuDestroyLibData`，释放插件占用的资源。
2. 收到 `fuDestroyLibData` 回调后，调用 `destroy` 方法销毁 `RtcEngine` 对象。

<a id="ref"></a>
## 参考信息 [#参考信息-2]
### API 参考 [#api-参考-2]

- [声网 SDK 的插件相关方法和回调](/zh-CN/api-reference/rtc/flutter/extension#toc_extension)
- [插件的 key-value 说明](/zh-CN/realtime-media/marketplace/reference/faceunity-ar-api)

### 常见问题 [#常见问题-2]

**问题 1：运行示例项目，美颜为什么没有生效？**

通常有以下几个原因：

- 插件动态库没有保存在正确位置，或者没有导入；
- 相芯资源包中的文件没有保存在正确位置，或者缺少部分文件；
- 证书文件与 App 包名不一致，导致鉴权失败。

**问题 2：为什么开启采集后需要 1s 左右才能渲染出视频？**

加载相芯美颜资源的操作会造成 GL 渲染线程卡顿，加载资源的过程大概耗时 800ms。建议通过业务处理（比如添加 loading 界面）规避。

**问题 3：为什么在编译 App 时会出现 `models: no match` 的报错？**

该错误通常是由于资源包匹配问题引起的。很可能是因为在编译新插件时，没有删除旧版本的 App。建议你删除旧版 App 后重新编译运行。

<a id="resource"></a>
### 素材包结构 [#素材包结构-2]

相芯美颜道具高级版插件的资源包文件结构详见：

  - [Android 资源包结构](https://gitee.com/hangzhou_xiangxin_1/FULiveDemoDroid/blob/master/doc/Android_Nama_Demo_%E8%BF%90%E8%A1%8C%E6%96%87%E6%A1%A3.md#2-demo%E6%96%87%E4%BB%B6%E7%BB%93%E6%9E%84)
  - [iOS 资源包结构](https://gitee.com/hangzhou_xiangxin_1/FULiveDemo/blob/master/docs/iOS_Nama_SDK_%E9%9B%86%E6%88%90%E6%8C%87%E5%AF%BC%E6%96%87%E6%A1%A3.md#2-sdk%E6%96%87%E4%BB%B6%E7%BB%93%E6%9E%84%E4%BD%BF%E7%94%A8%E6%96%B0%E6%9E%B6%E6%9E%84furenderkit%E5%8A%A8%E6%80%81%E5%BA%93)

更多的接口调用方式可以参考相芯 Nama SDK 的文档：

	- [Android 文档](https://gitee.com/hangzhou_xiangxin_1/FULiveDemoDroid/blob/master/doc)
	- [iOS 文档](https://gitee.com/hangzhou_xiangxin_1/FULiveDemo/tree/master/docs)
<_PlatformProcessedMarker close="true" />
</_PlatformTabsGroup>
