tencent cloud

文档反馈

最后更新时间:2024-04-03 17:23:11
    本篇文档主要介绍在 TUICallKit 中接入美颜特效的方法。
    在 Flutter 中完成自定义美颜处理,需要通过 TRTC 自定义视频渲染完成。由于 Flutter 不善于进行大量实时数据传输的特性,涉及 TRTC 的自定义视频渲染部分需要在 Native 部分完成。 具体的方案如下:
    
    
    接入方案分为 3 步:
    第一步:通过 MethodChannel 通道 开启/关闭 TRTC 自定义渲染逻辑。 第二步:在 TRTC 自定义渲染处理逻辑 onProcessVideoFrame() 中使用 美颜处理模块 对原始视频帧进行处理。 第三步:客户的美颜处理模块也需要在 Dart 通过接口设置当前美颜的参数,客户可以通过 MethodChannel 的方式设置美颜参数。这部分客户可根据自己的需求和使用的美颜自行定制。

    接入第三方美颜特效

    步骤1:实现 Dar t层到 Native 的“开始/结束”美颜的控制接口

    实现 Dart 层接口:
    final channel = MethodChannel('TUICallKitCustomBeauty');
    void enableTUICallKitCustomBeauty() async {
    await channel.invokeMethod('enableTUICallKitCustomBeauty');
    }
    
    void disableTUICallKitCustomBeauty() async {
    await channel.invokeMethod('disableTUICallKitCustomBeauty');
    }
    实现对应 Native 层接口:
    java
    swift
    public 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() {
    }
    }
    @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() {
    }
    }

    步骤2:在 Native 的 TRTC 自定义渲染逻辑中完成美颜处理

    注意:
    Android 在接入美颜过程中需要先依赖 LiteAVSDK_Professional, 在Android工程的 app/build.gradle中添加一下依赖: dependencies{ api "com.tencent.liteav:LiteAVSDK_Professional:latest.release" }
    java
    swift
    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) { // 美颜处理逻辑
    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
    }
    }

    步骤3:客户自定义第三方美颜参数控制逻辑

    此部分客户可以根据自己的需求和具体使用的美颜模块,参考 步骤1 种实现美颜参数的设置功能,具体实现根据具体使用情况决定。

    接入腾讯美颜特效

    腾讯美颜特效的接入方法也同样遵循上述方法,现在以腾讯美颜特效为例,详细介绍接入方法:

    步骤1:美颜资源下载与集成

    1. 根据您购买的套餐 下载 SDK
    2. 添加文件到自己的工程中:
    Android
    iOS
    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",则需要自行负责妥善处理库不存在的情况。
    添加后如下图:
    
    
    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,然后把文件夹 androidioslib和文件pubspec.yamltencent_effect_flutter.iml添加到工程目录下,然后在工程的 pubspec.yaml 文件中添加如下引用:(可参考demo)
    tencent_effect_flutter:
    path: ../
    tencent_effect_flutter 只是提供一个桥接,里面依赖的 XMagic 默认是最新版的,真正实现美颜是 XMagic。
    如果要使用最新版本的美颜 SDK,您可以通过以下步骤进行 SDK 升级:
    Android
    iOS
    在工程目录下执行命令:flutter pub upgrade 或者在 subspec.yaml 页面的右上角单击 Pub upgrade。
    在工程目录下执行命令:flutter pub upgrade,然后在 iOS 目录下执行命令:pod update

    步骤3:实现Dart层到Native的 开始/结束 美颜的控制接口

    此部分可以参考 接入第三方美颜特效/步骤1 ,此处不在赘述。

    步骤4:在 Native 的 TRTC 自定义渲染逻辑中完成美颜处理

    Android
    iOS
    Android 在接入美颜过程中需要先依赖 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_Professional
    import tencent_effect_flutter
    
    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 {
    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接口 设置美颜参数。
    联系我们

    联系我们,为您的业务提供专属服务。

    技术支持

    如果你想寻求进一步的帮助,通过工单与我们进行联络。我们提供7x24的工单服务。

    7x24 电话支持