接入方案分为 3 步:
第一步:通过 MethodChannel 通道 开启/关闭 TRTC 自定义渲染逻辑;
第二步:在 TRTC 自定义渲染处理逻辑 onProcessVideoFrame() 中使用美颜处理模块对原始视频帧进行处理;
第三步:客户的美颜处理模块也需要在 Dart 通过接口设置当前美颜的参数,客户可以通过 MethodChannel 的方式设置美颜参数。这部分客户可根据自己的需求和使用的美颜自行定制。
一、步骤1:实现 Dart 层到 Native 开始/关闭美颜的控制接口
实现 Dart 层接口:
final channel = MethodChannel('TUICallKitCustomBeauty'); void enableTUICallKitCustomBeauty() async { await channel.invokeMethod('enableTUICallKitCustomBeauty'); } void disableTUICallKitCustomBeauty() async { await channel.invokeMethod('disableTUICallKitCustomBeauty'); }
实现对应 Native 层接口:
JavaSwiftpublic class MainActivity extends FlutterActivity { private static final String channelName = "TUICallKitCustomBeauty"; private MethodChannel channel; @Override public void configureFlutterEngine(@NonNull FlutterEngine flutterEngine) { super.configureFlutterEngine(flutterEngine); channel = new MethodChannel(flutterEngine.getDartExecutor().getBinaryMessenger(), channelName); channel.setMethodCallHandler(((call, result) -> { switch (call.method) { case "enableTUICallKitCustomBeauty": enableTUICallKitCustomBeauty(); break; case "disableTUICallKitCustomBeauty": disableTUICallKitCustomBeauty(); break; default: break; } result.success(""); })); } public void enableTUICallKitCustomBeauty() { } public void disableTUICallKitCustomBeauty() { }}J@UIApplicationMain@objc class AppDelegate: FlutterAppDelegate { var channel: FlutterMethodChannel? override func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { GeneratedPluginRegistrant.register(with: self) guard let controller = window?.rootViewController as? FlutterViewController else { fatalError("Invalid root view controller") } channel = FlutterMethodChannel(name: "TUICallKitCustomBeauty", binaryMessenger: controller.binaryMessenger) channel?.setMethodCallHandler({ [weak self] call, result in guard let self = self else { return } switch (call.method) { case "enableTUICallKitCustomBeauty": self.enableTUICallKitCustomBeauty() break case "disableTUICallKitCustomBeauty": self.disableTUICallKitCustomBeauty() break default: break } }) result(nil) return super.application(application, didFinishLaunchingWithOptions: launchOptions) } func enableTUICallKitCustomBeauty() { } func disableTUICallKitCustomBeauty() { }}S
二、步骤2:在 Native 的 TRTC 自定义渲染逻辑中完成美颜处理
注意:Android 在接入美颜过程中需要先依赖 LiteAVSDK_Professional, 在 Android 工程的 app/build.gradle 中添加一下依赖:
dependencies{
api "com.tencent.liteav:LiteAVSDK_Professional:latest.release"
}
JavaSwiftJvoid enableTUICallKitCustomBeauty() { TRTCCloud.sharedInstance(getApplicationContext()). setLocalVideoProcessListener(TRTC_VIDEO_PIXEL_FORMAT_Texture_2D, TRTC_VIDEO_BUFFER_TYPE_TEXTURE, new VideoFrameListerer());}void disableTUICallKitCustomBeauty() { TRTCCloud.sharedInstance(getApplicationContext()). setLocalVideoProcessListener(TRTC_VIDEO_PIXEL_FORMAT_Texture_2D, TRTC_VIDEO_BUFFER_TYPE_TEXTURE, null);}class VideoFrameListerer implements TRTCCloudListener.TRTCVideoFrameListener {
private XXXBeautyModel mBeautyModel = XXXBeautyModel.sharedInstance();
@Override
public int onProcessVideoFrame(TRTCCloudDef.TRTCVideoFrame trtcVideoFrame,
TRTCCloudDef.TRTCVideoFrame trtcVideoFrame1) {
// 美颜处理逻辑 mBeautyModel.process(trtcVideoFrame, trtcVideoFrame1); ……
return 0;
}
@Override
public void onGLContextCreated() {
}
@Override
public void onGLContextDestory() {
}
}let videoFrameListener: TRTCVideoFrameListener = TRTCVideoFrameListener()func enableTUICallKitCustomBeauty() { TRTCCloud.sharedInstance().setLocalVideoProcessDelegete(videoFrameListener, pixelFormat: ._Texture_2D, bufferType: .texture)}func disableTUICallKitCustomBeauty() { TRTCCloud.sharedInstance().setLocalVideoProcessDelegete(nil, pixelFormat: ._Texture_2D, bufferType: .texture)}class TRTCVideoFrameListener: NSObject, TRTCVideoFrameDelegate { let bueutyModel = XXXXBeautyModel.shareIntance() func onProcessVideoFrame(_ srcFrame: TRTCVideoFrame, dstFrame: TRTCVideoFrame) -> UInt32 { // 美颜处理逻辑 bueutyModel.onProcessVideoFrame(srcFrame, dstFrame) …… return 0 }}S
三、步骤3:客户自定义第三方美颜参数控制逻辑
此部分客户可以根据自己的需求使用具体的美颜模块,参见 步骤1 实现美颜参数的设置功能,具体实现根据具体使用情况决定。
四、接入腾讯美颜特效
腾讯美颜特效的接入方法也同样遵循上述方法,现在以腾讯美颜特效为例,详细介绍接入方法:
五、步骤1:美颜资源下载与集成
1. 根据你购买的套餐下载 SDK。
2. 添加文件到自己的工程中:
AndroidiOS
1. 在 app 模块下找到 build.gradle 文件,添加你对应套餐的 maven 引用地址,例如你选择的是 S1-04 套餐,则添加如下代码:
dependencies { implementation 'com.tencent.mediacloud:TencentEffect_S1-04:latest.release'}
各套餐对应的 maven 地址,请参见文档。
2. 在 app 模块下找到 src/main/assets 文件夹,如果没有则创建,检查下载的 SDK 包中是否有 MotionRes 文件夹,如果有则将此文件夹拷贝到 ../src/main/assets 目录下。
3. 在 app 模块下找到 AndroidManifest.xml 文件,在 application 表填内添加如下标签。
<uses-native-library android:name="libOpenCL.so" android:required="true" /> //此处的true 表示如果没有此库,则应用将无法正常运行。系统不允许在没有此库的设备上安装应用。 //false表示应用可以使用此库(如果存在),但专门在没有此库的情况下运行(如果有必要)。系统允许安装应用,即使不存在此库也是如此。如果你使用 "false",则需要自行负责妥善处理库不存在的情况。 //Android 页面介绍:https://developer.android.com/guide/topics/manifest/uses-native-library-element
添加后如下:
4. 混淆配置
·如果你在打 release 包时,启用了编译优化(把 minifyEnabled 设置为 true ),会裁掉一些未在 Java 层调用的代码,而这些代码有可能会被 Native 层调用,从而引起 no xxx method 的异常。
·如果你启用了这样的编译优化,那就要添加这些 keep 规则,防止 xmagic 的代码被裁掉:
-keep class com.tencent.xmagic.** { *;}-keep class org.light.** { *;}-keep class org.libpag.** { *;}-keep class org.extra.** { *;}-keep class com.gyailib.**{ *;}-keep class com.tencent.cloud.iai.lib.** { *;}-keep class com.tencent.beacon.** { *;}-keep class com.tencent.qimei.** { *;}-keep class androidx.exifinterface.** { *;}
1. 添加美颜资源到你的工程。添加后如下(你的资源种类跟下图不完全一致):
2. 在 demo 中把 demo/lib/producer 里面的4个类:BeautyDataManager、BeautyPropertyProducer、BeautyPropertyProducerAndroid 和 BeautyPropertyProducerIOS 复制添加到自己的 Flutter 工程中,这 4 个类是用来配置美颜资源,把美颜类型展示在美颜面板中。
六、步骤2:引用 Flutter 版本 SDK
·GitHub 引用:在工程的 pubspec.yaml 文件中添加如下引用:
tencent_effect_flutter: git: url: https://github.com/TencentCloud/tencenteffect-sdk-flutter
·本地引用:从 tencent_effect_flutter 下载最新版本的 tencent_effect_flutter,然后把文件夹 android、ios、lib和文件pubspec.yaml、tencent_effect_flutter.iml添加到工程目录下,然后在工程的 pubspec.yaml 文件中添加如下引用:(可参考demo )
tencent_effect_flutter: path: ../
tencent_effect_flutter 只是提供一个桥接,里面依赖的 XMagic 默认是最新版的,真正实现美颜是 XMagic。
如果要使用最新版本的美颜 SDK,你可以通过以下步骤进行 SDK 升级:
AndroidiOS在工程目录下执行命令:flutter pub upgrade 或者在 subspec.yaml 页面的右上角单击 Pub upgrade。在工程目录下执行命令:flutter pub upgrade,然后在 iOS 目录下执行命令:pod update。
七、步骤3:实现 Dart 层到 Native 开始/关闭美颜的控制接口
此部分可以参见 接入第三方美颜特效-步骤1。
八、步骤4:在 Native 的 TRTC 自定义渲染逻辑中完成美颜处理
AndroidiOSAndroid 在接入美颜过程中需要先依赖 LiteAVSDK_Professional, 在 Android 工程的 app/build.gradle 中添加以下依赖:
dependencies{
api "com.tencent.liteav:LiteAVSDK_Professional:latest.release"
}void enableTUICallKitCustomBeauty() { TRTCCloud.sharedInstance(getApplicationContext()). setLocalVideoProcessListener(TRTC_VIDEO_PIXEL_FORMAT_Texture_2D, TRTC_VIDEO_BUFFER_TYPE_TEXTURE, new VideoFrameListerer());}void disableTUICallKitCustomBeauty() { TRTCCloud.sharedInstance(getApplicationContext()). setLocalVideoProcessListener(TRTC_VIDEO_PIXEL_FORMAT_Texture_2D, TRTC_VIDEO_BUFFER_TYPE_TEXTURE, null);}class VideoFrameListerer implements TRTCCloudListener.TRTCVideoFrameListener { private XXXBeautyModel mBeautyModel = XXXBeautyModel.sharedInstance(); @Override public int onProcessVideoFrame(TRTCCloudDef.TRTCVideoFrame trtcVideoFrame, TRTCCloudDef.TRTCVideoFrame trtcVideoFrame1) { trtcVideoFrame1.texture.textureId = XmagicApiManager.getInstance()
.process(trtcVideoFrame.texture.textureId, trtcVideoFrame.width, trtcVideoFrame.height); return 0; } @Override public void onGLContextCreated() { } @Override public void onGLContextDestory() { }}import TXLiteAVSDK_Professionalimport tencent_effect_flutterlet videoFrameListener: TRTCVideoFrameListener = TRTCVideoFrameListener()func enableTUICallKitCustomBeauty() { TRTCCloud.sharedInstance().setLocalVideoProcessDelegete(videoFrameListener, pixelFormat: ._Texture_2D, bufferType: .texture)}func disableTUICallKitCustomBeauty() { TRTCCloud.sharedInstance().setLocalVideoProcessDelegete(nil, pixelFormat: ._Texture_2D, bufferType: .texture)}class TRTCVideoFrameListener: NSObject, TRTCVideoFrameDelegate { func onProcessVideoFrame(_ srcFrame: TRTCVideoFrame, dstFrame: TRTCVideoFrame) -> UInt32 { dstFrame.textureId = GLuint(XmagicApiManager.shareSingleton().getTextureId(ConvertBeautyFrame.convertTRTCVideoFrame(trtcVideoFrame: srcFrame))) return 0 }}public class ConvertBeautyFrame: NSObject { public static func convertToTRTCPixelFormat(beautyPixelFormat: ITXCustomBeautyPixelFormat) -> TRTCVideoPixelFormat { switch beautyPixelFormat { case .Unknown: return ._Unknown case .I420: return ._I420 case .Texture2D: return ._Texture_2D case .BGRA: return ._32BGRA case .NV12: return ._NV12 } } public static func convertTRTCVideoFrame(trtcVideoFrame: TRTCVideoFrame) -> ITXCustomBeautyVideoFrame { let beautyVideoFrame = ITXCustomBeautyVideoFrame() beautyVideoFrame.data = trtcVideoFrame.data beautyVideoFrame.pixelBuffer = trtcVideoFrame.pixelBuffer beautyVideoFrame.width = UInt(trtcVideoFrame.width) beautyVideoFrame.height = UInt(trtcVideoFrame.height) beautyVideoFrame.textureId = trtcVideoFrame.textureId switch trtcVideoFrame.rotation { case ._0: beautyVideoFrame.rotation = .rotation_0 case ._90: beautyVideoFrame.rotation = .rotation_90 case ._180: beautyVideoFrame.rotation = .rotation_180 case ._270: beautyVideoFrame.rotation = .rotation_270 default: beautyVideoFrame.rotation = .rotation_0 } switch trtcVideoFrame.pixelFormat { case ._Unknown: beautyVideoFrame.pixelFormat = .Unknown case ._I420: beautyVideoFrame.pixelFormat = .I420 case ._Texture_2D: beautyVideoFrame.pixelFormat = .Texture2D case ._32BGRA: beautyVideoFrame.pixelFormat = .BGRA case ._NV12: beautyVideoFrame.pixelFormat = .NV12 default: beautyVideoFrame.pixelFormat = .Unknown } beautyVideoFrame.bufferType = ITXCustomBeautyBufferType(rawValue: trtcVideoFrame.bufferType.rawValue) ?? .Unknown beautyVideoFrame.timestamp = trtcVideoFrame.timestamp return beautyVideoFrame }}
九、步骤5:开启美颜并设置美颜参数
完成上述配置后,可以通过 enableTUICallKitCustomBeauty()/disableTUICallKitCustomBeauty() 开启/关闭美颜。可以通过 腾讯特效美颜 Flutter 接口 设置美颜参数。