PixelFree + Agora Flutter 视频美颜贴纸插件集成与使用文档

204 阅读2分钟

PixelFree + Agora Flutter 视频美颜贴纸插件集成与使用文档

1. 环境准备

  • Flutter SDK 3.x 及以上
  • Android minSdkVersion 21+
  • iOS 11+
  • Agora RTC Engine 6.3.0

2. 依赖配置

pubspec.yaml 添加如下依赖:

dependencies:
  flutter:
    sdk: flutter
  agora_rtc_engine: 6.3.0
  path_provider: ^2.0.11
  permission_handler: ^11.3.0
  shared_preferences: ^2.0.0
  path: ^1.8.0

资源声明

确保 pubspec.yaml 中包含:

flutter:
  assets:
    - assets/Resource/pixelfreeAuth.lic
    - assets/Resource/filter_model.bundle
    - assets/Resource/Stickers/
    - assets/icons/
    - assets/bundle/   # 贴纸功能需要此目录

3. 资源准备

  • 贴纸/滤镜 bundle:放在 assets/bundle/ 目录下(如 cat_fa_qia.bundle)。
  • 美颜授权文件:assets/Resource/pixelfreeAuth.lic
  • 滤镜模型:assets/Resource/filter_model.bundle
  • 图标:assets/icons/

4. Android 原生配置

  • android/app/build.gradle.kts 需设置 minSdk = 21ndkVersion 与 PixelFree SDK 匹配。
  • Lib 目录下需有 android-release.aar 包含 PixelFree 的 .so 文件以及插件。

5. iOS 原生配置

  • android/app/build.gradle.kts 需设置 minSdk = 21ndkVersion 与 PixelFree SDK 匹配。
  • Lib 目录下需有 android-release.aar 包含 PixelFree 的 .so 文件以及插件。

6. 初始化与权限

await [Permission.microphone, Permission.camera].request();

7. RTC Engine 初始化与 PixelFree 扩展加载

_rtcEngine = createAgoraRtcEngine();
await _rtcEngine.initialize(RtcEngineContext(
  appId: Config.rtcAppId,
  channelProfile: ChannelProfileType.channelProfileLiveBroadcasting,
));
await _rtcEngine.enableVideo();
await _rtcEngine.startPreview();
​
// 加载 PixelFree 扩展
if (Platform.isAndroid) {
  await _rtcEngine.loadExtensionProvider(path: 'AgoraPixelFreeExtension');
}
await _rtcEngine.enableExtension(
  provider: Config.pixelFreeProvider,
  extension: Config.pixelFreeExtension,
  enable: true,
);

8. PixelFree 授权与模型加载

// 初始化 PixelFree
await _rtcEngine.setExtensionProperty(
  provider: Config.pixelFreeProvider,
  extension: Config.pixelFreeExtension,
  key: 'pfNewPixelFree',
  value: jsonEncode({'data': ''}),
);
​
// 加载授权文件
final authFilePath = await _copyAsset('assets/Resource/pixelfreeAuth.lic');
await _rtcEngine.setExtensionProperty(
  provider: Config.pixelFreeProvider,
  extension: Config.pixelFreeExtension,
  key: 'pfCreateBeautyItemFromBundle',
  value: jsonEncode({'data': authFilePath, 'type': 2}),
);
​
// 加载滤镜模型
final filterModelPath = await _copyAsset('assets/Resource/filter_model.bundle');
await _rtcEngine.setExtensionProperty(
  provider: Config.pixelFreeProvider,
  extension: Config.pixelFreeExtension,
  key: 'pfCreateBeautyItemFromBundle',
  value: jsonEncode({'data': filterModelPath, 'type': 0}),
);

9. 美颜/滤镜/贴纸设置 API

9.1 设置美颜参数

await _rtcEngine.setExtensionProperty(
  provider: Config.pixelFreeProvider,
  extension: Config.pixelFreeExtension,
  key: 'pfSetBeautyFilterParam',
  value: jsonEncode({'key': PFBeautyFilterType.PFBeautyFilterTypeFaceWhitenStrength.index, 'value': 0.8}),
);
  • key:美颜参数类型(见下方枚举)
  • value:参数值(float/int/string)

9.2 设置滤镜

// 设置滤镜名
await _rtcEngine.setExtensionProperty(
  provider: Config.pixelFreeProvider,
  extension: Config.pixelFreeExtension,
  key: 'pfSetBeautyFilterParam',
  value: jsonEncode({'key': PFBeautyFilterType.PFBeautyFilterName.index, 'value': 'cat_fa_qia'}),
);
// 设置滤镜强度
await _rtcEngine.setExtensionProperty(
  provider: Config.pixelFreeProvider,
  extension: Config.pixelFreeExtension,
  key: 'pfSetBeautyFilterParam',
  value: jsonEncode({'key': PFBeautyFilterType.PFBeautyFilterStrength.index, 'value': 0.7}),
);

9.3 设置贴纸

await _rtcEngine.setExtensionProperty(
  provider: Config.pixelFreeProvider,
  extension: Config.pixelFreeExtension,
  key: 'pfCreateBeautyItemFromBundle',
  value: jsonEncode({'data': bundlePath, 'type': 3}),
);
  • bundlePath:本地贴纸 bundle 路径(需先拷贝到 app document 目录)

10. 枚举类型(与 C 层一致)

enum PFBeautyFilterType {
  PFBeautyFilterTypeFace_EyeStrength, // 0
  PFBeautyFilterTypeFace_thinning,    // 1
  PFBeautyFilterTypeFace_narrow,      // 2
  PFBeautyFilterTypeFace_chin,        // 3
  PFBeautyFilterTypeFace_V,           // 4
  PFBeautyFilterTypeFace_small,       // 5
  PFBeautyFilterTypeFace_nose,        // 6
  PFBeautyFilterTypeFace_forehead,    // 7
  PFBeautyFilterTypeFace_mouth,       // 8
  PFBeautyFilterTypeFace_philtrum,    // 9
  PFBeautyFilterTypeFace_long_nose,   // 10
  PFBeautyFilterTypeFace_eye_space,   // 11
  PFBeautyFilterTypeFace_smile,       // 12
  PFBeautyFilterTypeFace_eye_rotate,  // 13
  PFBeautyFilterTypeFace_canthus,     // 14
  PFBeautyFilterTypeFaceBlurStrength, // 15
  PFBeautyFilterTypeFaceWhitenStrength, // 16
  PFBeautyFilterTypeFaceRuddyStrength,  // 17
  PFBeautyFilterTypeFaceSharpenStrength, // 18
  PFBeautyFilterTypeFaceM_newWhitenStrength, // 19
  PFBeautyFilterTypeFaceH_qualityStrength,   // 20
  PFBeautyFilterTypeFaceEyeBrighten,         // 21
  PFBeautyFilterName,                        // 22
  PFBeautyFilterStrength,                    // 23
  PFBeautyFilterLvmu,                        // 24
  PFBeautyFilterSticker2DFilter,             // 25
  PFBeautyFilterTypeOneKey,                  // 26
  PFBeautyFilterWatermark,                   // 27
  PFBeautyFilterExtend,                      // 28
}

11. 常见问题与排查

  • 资源无法加载:务必 flutter clean && flutter pub get && flutter run,并检查 pubspec.yaml 缩进。
  • 新加 bundle 不生效:需重新 run,热重载无效。
  • iOS 端贴纸不显示:需在 Xcode 里确认所有 bundle 被打包进 Runner target。
  • 参数无效:请确保 key、value 类型与 C 层一致,key 用 Dart 枚举的 .index

12. 参考代码片段

// 贴纸 bundle 拷贝
Future<String> _getStickerBundlePath(String bundleName) async {
  final data = await rootBundle.load('assets/bundle/$bundleName');
  final appDir = await getApplicationDocumentsDirectory();
  final bundlePath = '${appDir.path}/$bundleName';
  final file = File(bundlePath);
  await file.writeAsBytes(data.buffer.asUint8List());
  return bundlePath;
}