本文为您介绍Android端美颜特效SDK的接口文档、集成操作及简单使用示例,用于实现美颜特效功能。

前提条件

开发前的环境要求如下表所示。
类别 说明
系统版本 支持Android 4.3及以上版本。
Java版本 支持Java 1.7及以上版本。
API LEVEL 支持ANDROID SDK API LEVEL 18及以上版本。
Android Studio版本 支持Android Studio 2.3以上版本,下载Android Studio

参考资料

项目 链接
中文版接口文档说明
Sample示例工程 Sample示例工程

示例工程文件中,assets目录下包含Demo所有图片资源。

在GitHub上提供的Demo工程 Demo工程

目前提供接入范例包括:阿里云视频直播推流SDK、七牛直播SDK、腾讯云实时音视频SDK。

Maven方式集成SDK

  1. 在项目级build.gradle项目文件中添加阿里云Maven仓库。
    allprojects {
        repositories {
            google()
            jcenter()
            maven { url "https://maven.aliyun.com/repository/releases" }
        }
    }
  2. 在相应Android端SDK包的应用级build.gradle项目文件下,加入美颜特效SDK依赖项。
    • 专业pro版本:
      implementation "com.aliyun.maliang.android:queen:2.3.0-official-pro"
    • 旗舰ultimate版本:
      implementation "com.aliyun.maliang.android:queen:2.3.0-official-ultimate"
    • 全功能full版本:
      implementation "com.aliyun.maliang.android:queen:2.3.0-official-full"
说明

因美颜特效库可能与RTC等阿里云SDK存在内部底层库重复的问题,导致打包可能出现冲突。当出现冲突时,请在您的主工程打包build.gradle文件中增加如下packagingOptions配置项,以便排除重复库。若没有冲突,则不需要增加此处理。

android {    
  ...
  compileSdkVersion ... 
  ...
  packagingOptions {
        pickFirst '**/libMNN.so'       (若存在libMNN.so冲突时,则增加该行处理,否则不需要增加)
        pickFirst '**/libMNN_CL.so'    (若存在libMNN_CL.so冲突时,则增加该行处理,否则不需要增加)
        pickFirst '**/libc++_shared.so'(若存在libc++_shared.so冲突时,则增加该行处理,否则不需要增加)
    }
  ...
}

手动导入aar集成SDK

  1. 下载SDK并解压。
  2. 将解压SDK获得的.aar文件复制到工程的libs目录中。

配置License

请提前获取License,获取方式请参见获取美颜特效SDK License。获取后参考以下步骤将LicenseKey和LicenseFile(证书文件)配置到工程中。

说明
  • 当您同时集成视频直播美颜特效SDK和视频点播短视频SDK时,两者的LicenseKey和LicenseFile(证书文件)是相同的,只需配置一次即可(注意证书文件需使用最新的一份)。

  • 如果您购买的SDK版本发生变更或需要续期(SDK到期),需要更新证书文件。更新步骤如下:
    1. 重新获取Licence,操作请参见开通License授权发送邮件获取最新证书文件。
    2. 获取最新证书后,执行本文中配置License步骤更新证书。
将证书文件导入到工程的assets中,然后在AndroidManifest.xmlapplication节点下添加两个meta-data。示例如下:
<application
   android:icon="@drawable/icon"
   android:label="@string/app_name" >
    <meta-data
         android:name="com.aliyun.alivc_license.licensekey"   //元数据项名字,固定取值
         android:value="Your LicenseKey"/>   //元数据项指定值,请填入您邮件获取到的LicenseKey
    <meta-data
       android:name="com.aliyun.alivc_license.licensefile"
       android:value="Your LicenseFile Path"/>   //元数据项指定值,请填入证书文件在工程中相对assets的路径,例如alivc_license/AliVideoCert.crt
  ……
</application>

使用示例

说明
如果您是从V1.x.x版本升级到V2.0.0及更高版本时,需注意以下内容。
  • Java API的包名由com.taobao.android.libqueen变更为com.aliyun.android.libqueen
  • V2.0.0版本起SDK授权使用方式变更,您需要重新发送邮件到videosdk@service.aliyun.com申请补发LicenseKey和LicenseFile(证书文件),并在标题中注明申请补发,我们会在收到邮件后工作日48小时内,补发一体化LicenseKey和LicenseFile(证书文件)。收到补发文件后请参照配置License完成配置。
  • 创建QueenEngine实例,设置初始化纹理与视窗参数
    QueenEngine engine;
    try {
        com.aliyun.android.libqueen.QueenConfig config = new com.aliyun.android.libqueen.QueenConfig();
        // true表示直接输出到当前OpenGL的显示区域,默认为false
        config.toScreen = false;
        // true表示打开调试日志开关,默认为false,建议只在Debug包打开日志调试,避免影响性能
        config.enableDebugLog = false;
        // true表示需要Queen创建gl上下文,默认为false
        config.withContext = false;
        // true表示需要创建单独的线程,默认为false
        config.withNewGlThread = false;
        if (withContext || withNewGlThread) {
            // 如果需要Queen在单独的线程创建gl上下文,且需要共享当前线程的gl上下文,那么配置当前gl上下文
            if (Build.VERSION.SDK_INT >= 21) {
              config.shareGlContext = EGL14.eglGetCurrentContext().getNativeHandle();
            } else {
              config.shareGlContext = EGL14.eglGetCurrentContext().getHandle();
            }
        }
        // 传入Android.content.Context触发引擎的初始化
        // 第二个参数为创建实例的配置
        engine = new QueenEngine(mContext, config);
    } catch (InitializationException e) {
        e.printStackTrace();
    }
    
    // 设置输入纹理,用于美颜流程的渲染
    // 第四个参数表示输入纹理是否为OES类型的纹理
    engine.setInputTexture(textureId, textureWidth, textureHeight, true);
    
    // 非必要步骤:获得美颜输出纹理,可以在用于其他扩展业务,如果需要按照输入纹理方向返回输出纹理,则在生成纹理和设置纹理的时候,将“保持纹理方向”参数设置为true
    Texture2D outTexture = engine.autoGenOutTexture(true);
    
    // 设置视窗大小
    engine.setScreenViewport(0, 0, viewWidth, viewHeight);
    // 开启log日志打印调试模式,建议只在Debug包打开日志调试,避免影响性能
    engine.enableDebugLog();
  • 设置美白和基础美化功能参数
    • 美白
      // 美白开关
      engine.enableBeautyType(BeautyFilterType.kSkinWhiting, true);
      // 美白参数 [0,1]
      engine.setBeautyParam(
          BeautyParams.kBPSkinWhitening, 
          0.3f
      );
    • 基础美颜
      /**
       * 磨皮和锐化开关,
       * 第三个参数为基础美颜的模式,设置为kBMSkinBuffing_Natural,则美颜的效果更自然,细节保留更多;设置为kBMSkinBuffing_Strong,则效果更夸张,细节去除更多。
       */
      engine.enableBeautyType(BeautyFilterType.kSkinBuffing, true, BeautyFilterMode.kBMSkinBuffing_Natural);
      //   磨皮 [0,1]
      engine.setBeautyParam(BeautyParams.kBPSkinBuffing, 0.6f);
      //  锐化 [0,1]
      engine.setBeautyParam(BeautyParams.kBPSkinSharpen, 0.2f);
  • 设置高级功能参数
    使用高级功能,如高级美颜、美型、美体、美妆、滤镜、贴纸,需要调用执行算法。
    if (mUseTextureBuffer) { // 直接使用纹理数据执行算法
        engine.updateInputTextureBufferAndRunAlg(
                mCamera.inputAngle, mCamera.outAngle,
                mCamera.flipAxis, false);
    } else {
        // 输入帧图片流,
        engine.updateInputDataAndRunAlg(
            imageData, // 帧图片流
            ImageFormat.NV21, // 帧图片流格式
            imageWidth, // 帧图片宽度 
            imageHeight, // 帧图片高度
            0, // 用于检测的图像的跨度(以像素为单位),即每行的字节数, 默认情况下设为 0
            mCamera.inputAngle, // 当前输入帧图片需旋转的角度,计算方式参考Sample工程
            mCamera.outAngle, // 算法输出结果所需旋转的角度,计算方式参考Sample工程
            mCamera.flipAxis // 输出数据的xy轴翻转处理,0为不旋转,1为x轴翻转,2为y轴翻转
        );
    }
    • 高级美颜
      // 高级美颜开关
      engine.enableBeautyType(BeautyFilterType.kFaceBuffing, true);
      //  去除法令纹[0,1]
      engine.setBeautyParam(BeautyParams.kBPNasolabialFolds, 0.3f); 
      //祛眼袋[0,1]
      engine.setBeautyParam(BeautyParams.kBPPouch, 0.3f); 
      // 白牙[0,1]
      engine.setBeautyParam(BeautyParams.kBPWhiteTeeth, 0.2f); 
      // 滤镜美妆:口红[0,1]
      engine.setBeautyParam(BeautyParams.kBPLipstick, 0.2f); 
      // 滤镜美妆:腮红[0,1]
      engine.setBeautyParam(BeautyParams.kBPBlush, 0.2f);
      // 滤镜美妆:亮眼[0,1]
      engine.setBeautyParam(BeautyParams.kBPBrightenEye, 1.0f); 
      // 滤镜美妆:红润[0,1]
      engine.setBeautyParam(BeautyParams.kBPBlush, 1.0f);
      // 滤镜美妆:口红色相[-0.5,0.5],需配合饱和度、明度使用,参考颜色如下:土红(-0.125)、粉红(-0.1)、复古红(0.0)、紫红(-0.2)、正红(-0.08)、橘红(0.0)、紫色(-0.42)、橘色(0.125)、黄色(0.25)
      engine.setBeautyParam(BeautyParams.kBPLipstickColorParam, 0.0f);
      // 滤镜美妆:口红饱和度[0,1],需配合色相、明度使用,参考颜色如下:土红(0.25)、粉红(0.125)、复古红(1.0)、紫红(0.35)、正红(1.0)、橘红(0.35)、紫色(0.35)、橘色(0.25)、黄色(0.45)
      engine.setBeautyParam(BeautyParams.kBPLipstickGlossParam, 0.0f);
      // 滤镜美妆:口红明度[0,1],需配合色相、饱和度使用,参考颜色如下:土红(0.4)、粉红(0.0)、复古红(0.2)、紫红(0.0)、正红(0.0)、橘红(0.0)、紫色(0.0)、橘色(0.0)、黄色(0.0)
      engine.setBeautyParam(BeautyParams.kBPLipstickBrightnessParam, 1.0f);
      // 祛皱[0,1]
      engine.setBeautyParam(BeautyParams.kBPWrinkles, 0.2f);
      // 去暗沉[0,1]
      engine.setBeautyParam(BeautyParams.kBPBrightenFace, 0.2f);
      // 开启功能
      engine.enableBeautyType(BeautyFilterType.kHSV, true);
      // 饱和度[-1,1]
      engine.setBeautyParam(BeautyParams.kBPHSV_SATURATION, 0.2f);
      // 对比度[-1,1]
      engine.setBeautyParam(BeautyParams.kBPHSV_CONTRAST, 0.2f);
    • 人脸特效
      // 马赛克效果
      queenEngine.enableBeautyType(BeautyFilterType.kBTEffectMosaicing, true);
      queenEngine.setBeautyParam(BeautyParams.kBPEffects_Mosaicing, 0.45f);
    • 美型
      /**
       * 美型开关,其中第二个参数是功能开关,第三个参数为调试开关
       * 第四个参数为美型的模式,可以设置为kBMFaceShape_Baseline、kBMFaceShape_Main、kBMFaceShape_High、kBMFaceShape_Max四种模式,形变的幅度会依次变强
       */
      engine.enableBeautyType(BeautyFilterType.kFaceShape, true, false, BeautyFilterMode.kBMFaceShape_Main);
      /**
       * 美型参数:颧骨<br />
       * 参数范围:[0,1]
       */
      engine.updateFaceShape(FaceShapeType.typeCutCheek, 0.0f);
      /**
       * 美型参数:削脸<br />
       * 参数范围:[0,1]
       */
      engine.updateFaceShape(FaceShapeType.typeCutFace, 0.0f);
      /**
       * 美型参数:瘦脸<br />
       * 参数范围:[0,1]
       */
      engine.updateFaceShape(FaceShapeType.typeThinFace, 0.0f);
      /**
       * 美型参数:脸长<br />
       * 参数范围:[0,1]
       */
      engine.updateFaceShape(FaceShapeType.typeLongFace, 0.0f);
      /**
       * 美型参数:下巴缩短<br />
       * 参数范围:[-1,1]
       */
      engine.updateFaceShape(FaceShapeType.typeLowerJaw, 0.0f);
      /**
       * 美型参数:下巴拉长<br />
       * 参数范围:[-1,1]
       */
      engine.updateFaceShape(FaceShapeType.typeHigherJaw, 0.0f);
      /**
       * 美型参数:瘦下巴<br />
       * 参数范围:[0,1]
       */
      engine.updateFaceShape(FaceShapeType.typeThinJaw, 0.0f);
      /**
       * 美型参数:瘦下颌<br />
       * 参数范围:[0,1]
       */
      engine.updateFaceShape(FaceShapeType.typeThinMandible, 0.0f);
      /**
       * 美型参数:大眼<br />
       * 参数范围:[0,1]
       */
      engine.updateFaceShape(FaceShapeType.typeBigEye, 0.0f);
      /**
       * 美型参数:眼角1<br />
       * 参数范围:[0,1]
       */
      engine.updateFaceShape(FaceShapeType.typeEyeAngle1, 0.0f);
      /**
       * 美型参数:眼距<br />
       * 参数范围:[-1,1]
       */
      engine.updateFaceShape(FaceShapeType.typeCanthus, 0.0f);
      /**
       * 美型参数:拉宽眼距<br />
       * 参数范围:[-1,1]
       */
      engine.updateFaceShape(FaceShapeType.typeCanthus1, 0.0f);
      /**
       * 美型参数:眼角2<br />
       * 参数范围:[-1,1]
       */
      engine.updateFaceShape(FaceShapeType.typeEyeAngle2, 0.0f);
      /**
       * 美型参数:眼睛高度<br />
       * 参数范围:[-1,1]
       */
      engine.updateFaceShape(FaceShapeType.typeEyeTDAngle, 0.0f);
      /**
       * 美型参数:瘦鼻<br />
       * 参数范围:[0,1]
       */
      engine.updateFaceShape(FaceShapeType.typeThinNose, 0.0f);
      /**
       * 美型参数:鼻翼<br />
       * 参数范围:[0,1]
       */
      engine.updateFaceShape(FaceShapeType.typeNosewing, 0.0f);
      /**
       * 美型参数:鼻长<br />
       * 参数范围:[-1,1]
       */
      engine.updateFaceShape(FaceShapeType.typeNasalHeight, 0.0f);
      /**
       * 美型参数:鼻头长<br />
       * 参数范围:[-1,1]
       */
      engine.updateFaceShape(FaceShapeType.typeNoseTipHeight, 0.0f);
      /**
       * 美型参数:唇宽<br />
       * 参数范围:[-1,1]
       */
      engine.updateFaceShape(FaceShapeType.typeMouthWidth, 0.0f);
      /**
       * 美型参数:嘴唇大小<br />
       * 参数范围:[-1,1]
       */
      engine.updateFaceShape(FaceShapeType.typeMouthSize, 0.0f);
      /**
       * 美型参数:唇高<br />
       * 参数范围:[-1,1]
       */
      engine.updateFaceShape(FaceShapeType.typeMouthHigh, 0.0f);
      /**
       * 美型参数:人中<br />
       * 参数范围:[-1,1]
       */
      engine.updateFaceShape(FaceShapeType.typePhiltrum, 0.0f);
      /**
       * 美型参数:发际线
       * 参数范围:[-1,1]
       */
      engine.updateFaceShape(FaceShapeType.typeHairLine, 0.0f);
      /**
       * 美型参数:嘴角上扬(微笑)
       * 参数范围:[-1,1]
       */
      engine.updateFaceShape(FaceShapeType.typeSmile, 0.0f);
    • 美体
      /**
       * 美体开关,其中第二个参数是功能开关,第三个参数为调试开关 */
      queenEngine.enableBeautyType(BeautyFilterType.kBodyShape, true, false);
      /**
       * 美体参数:全身
       * 参数范围:[-1,1]
       */
      queenEngine.updateBodyShape(BodyShapeType.kFullBody, 1.0f);
      /**
       * 美体参数:小头
       * 参数范围:[-1,1]
       */
      queenEngine.updateBodyShape(BodyShapeType.kSmallHead, 1.0f);
      /**
       * 美体参数:瘦腿
       * 参数范围:[-1,1]
       */
      queenEngine.updateBodyShape(BodyShapeType.kThinLag, 1.0f);
      /**
       * 美体参数:长腿
       * 参数范围:[-1,1]
       */
      queenEngine.updateBodyShape(BodyShapeType.kLongLag, 1.0f);
      /**
       * 美体参数:脖子
       * 参数范围:[-1,1]
       */
      queenEngine.updateBodyShape(BodyShapeType.kLongNeck, 1.0f);
      /**
       * 美体参数:瘦腰
       * 参数范围:[-1,1]
       */
      queenEngine.updateBodyShape(BodyShapeType.kThinWaist, 1.0f);
      /**
       * 美体参数:丰胸
       * 参数范围:[-1,1]
       */
      queenEngine.updateBodyShape(BodyShapeType.kEnhanceBreast, 1.0f);
      /**
       * 美体参数:手臂
       * 参数范围:[-1,1]
       */
      queenEngine.updateBodyShape(BodyShapeType.kThinArm, 1.0f);
    • 美妆

      开启妆容

      // 第二个参数是开关,第三个参数是调试开关
      // 第四个参数是美妆的模式,目前仅对眉毛有作用,设置为BeautyFilterMode.kBMFaceMakeup_High,眉毛的形变会更明显,设置为BeautyFilterMode.kBMFaceMakeup_Baseline,眉形会变收敛
      engine.enableBeautyType(BeautyFilterType.kMakeup, true, false, BeautyFilterMode.kBMFaceMakeup_Baseline);
      
      // 设置美妆素材
      // 第一个参数是美妆类型
      // 第二个参数是素材文件路径,基于assets的相对路径,如"/makeup/蜜桃妆.png",也可以是有读取权限的绝对路径
      // 第三个参数是素材与人脸的融合类型,第四个参数是保留参数
      engine.setMakeupImage(MakeupType.kMakeupBlush,
                            new String[]{""},     
                            BlendType.kBlendCurve, 15);
      /** 
       * 整妆的类型是kMakeupWhole,设置单个素材即可实现全脸上妆,但是无法调节各部位细节。
       * 升级至1.4.0以上的用户,建议采用组合妆来替换整妆的效果,可以调节各部分细节,下面提供几种组合妆的模式:
       *  1、微醺妆:
       *     眼影(makeup/eyeshadow/naichazong.2.31.png 透明度:0.7)、
       *     睫毛(makeup/eyelash/yesheng.2.31.png 透明度:0.5)、
       *     腮红(makeup/blush/weixun.2.31.png 透明度:0.8)、
       *     眼线(makeup/eyeliner_292929/wenrou.2.31.png 透明度:0.5)、
       *     口红(makeup/mouth_wumian/standout.2.31.png 透明度:0.5)、
       *     高光(makeup/highlight/highlight.2.12.png, 透明度:0.4)
       *  2、雀斑妆:
       *     眼影(makeup/eyeshadow/taohuafen.2.31.png 透明度:0.7)、
       *     睫毛(makeup/eyelash/yesheng.2.31.png 透明度:0.5)、
       *     腮红(makeup/blush/cool.2.31.png 透明度:0.8)、
       *     眼线(makeup/eyeliner_292929/guima.2.31.png 透明度:0.5)、
       *     口红(makeup/mouth_yaochun/nanguase.2.31.png 透明度:0.5)、
       *     高光(makeup/highlight/highlight.2.12.png, 透明度:0.4)
       *  3、活泼妆:
       *     眼影(makeup/eyeshadow/tianchengse.2.31.png 透明度:0.7)、
       *     睫毛(makeup/eyelash/lingdong.2.31.png 透明度:0.5)、
       *     腮红(makeup/blush/luori.2.31.png 透明度:0.8)、
       *     眼线(makeup/eyeliner_292929/qizhi.2.31.png 透明度:0.5)、
       *     口红(makeup/mouth_yaochun/nanguase.2.31.png 透明度:0.5)、
       *     高光(makeup/highlight/highlight.2.12.png, 透明度:0.4)
       *  4、夜店妆:
       *     眼影(makeup/eyeshadow/yeqiangwei.2.31.png 透明度:0.7)、
       *     睫毛(makeup/eyelash/zhixing.2.31.png 透明度:0.5)、
       *     腮红(makeup/blush/shaonv.2.31.png 透明度:0.8)、
       *     眼线(makeup/eyeliner_292929/wenrou.2.31.png 透明度:0.5)、
       *     口红(makeup/mouth_zirun/zhenggongse.2.31.png 透明度:0.5)、
       *     高光(makeup/highlight/highlight.2.12.png, 透明度:0.4)
       **/
      
      // 设置美妆素材透明度
      // 第二个参数是透明度,第三个参数是保留参数
      engine.setMakeupAlpha(MakeupType.kMakeupBlush, 0.6f, 0.3f);

      关闭妆容

      engine.setMakeupImage(MakeupType.kMakeupBlush, new String[], BlendType.kBlendNormal, 15);

      开启卧蚕

       // 第二个参数是开关,第三个参数是调试开关
      engine.enableBeautyType(BeautyFilterType.kMakeup, true, false);
      
      engine.setMakeupImage(MakeupType.kMakeupWocan,
                            new String[]{""},   //目前采用内置素材,不支持定制  
                            BlendType.kBlendCurve, 15);
      
      engine.setMakeupAlpha(MakeupType.kMakeupWocan, 0.6f, 0.3f);
      关闭卧蚕
      engine.setMakeupImage(MakeupType.kMakeupWocan, new String[], BlendType.kBlendCurve, 15);
    • 换发色
      queenEngine.enableBeautyType(BeautyFilterType.kHairColor, true);
      /**
       * 三个参数分别为RGB值(浮点数)
       * 参考颜色如下:
       *   蓝色:  [0.3137f, 0.3137f, 0.6275f]
       *   紫色:  [0.6078f, 0.3529f, 0.6275f])
       *   天蓝色: [0.3333f, 0.5492f, 0.5491f])
       *   黄色:  [0.6471f, 0.5294f, 0.3529f])
       *   绿色:  [0.3725f, 0.5882f, 0.3137f])
       *   棕色:  [0.3922f, 0.3333f, 0.3137f])
       *   红色:  [0.5098f, 0.2745f, 0.2745f])
       */
      queenEngine.setHairColor(
        getQueenParam().hairRecord.colorRed,
        getQueenParam().hairRecord.colorGreen,
        getQueenParam().hairRecord.colorBlue);
    • 滤镜
      // 功能开关
      engine.enableBeautyType(BeautyFilterType.kLUT, true);
      // 设置滤镜资源路径,基于assets的相对路径,如“/lookups/lookup_1.png”,也可以是有读取权限的绝对路径
      engine.setFilter(lutResPath); 
      // 滤镜强度
      engine.setBeautyParam(BeautyParams.kBPLUT, 1.0f); 
    • 贴纸
      // 删除贴纸素材路径
      engine.removeMaterial(oldStickerResPath);
      // 添加贴纸素材路径,相同贴纸不能重复添加
      // 基于assets的相对路径,如"/sticker/baiyang",也可以是有读取权限的绝对路径
      engine.addMaterial(stickerResPath);
    • 蓝/绿幕抠图
      /**
       * 设置绿幕抠图参数
       * @param backgroundPath : 要替换的背景资源图文件地址,路径地址为"",则为关闭该项功能
       * @param blueScreenEnabled : 是否使用蓝幕,true为替换蓝幕背景,false则为替换绿幕背景
       * @param threshold 范围:【20,60】,默认建议取值30.    
       */
      engine.setGreenScreen(String backgroundPath, boolean blueScreenEnabled, float threshold);
    • 智能抠像
      // 开启智能抠像前,可以根据需要设置其性能模式,包括自动模式、最佳画质模式、平衡模式、最佳性能模式,如果不设置则默认为自动模式
      // engine.setSegmentPerformanceMode(SegmentPerformanceMode.Auto);
      // 删除背景素材路径
      engine.removeMaterial(oldBackgroundResPath);
      // 添加背景素材路径,相同贴纸不能重复添加
      // 基于assets的相对路径,如"/static/xiaomanyao",也可以是有读取权限的绝对路径
      engine.addMaterial(backgroundResPath);
      // 除了上述的替换背景之外,也可以直接开启背景虚化功能
      engine.enableBeautyType(BeautyFilterType.kBTBackgroundProcess, true);
      // 开启后默认是背景虚化,可以通过如下API设置为背景透明,适用于将输出当做前景,自行合成背景的场合
      engine.setSegmentBackgroundProcessType(BackgroundProcessType.kBackgroundTransparent);
    • AR隔空写字
      /**
       * 第一个参数是开关
       * 第二个参数是模式: 1 - 写字, 2 - 画画
       */
      queenEngine.setArWriting(true, getQueenParam().sArWritingRecord.mode);
    • 智能动态化
      // 开启智能动态优化:
      engine.enableBeautyType(BeautyFilterType.kBTAutoFilter, true);
      // 关闭智能动态优化:
      engine.enableBeautyType(BeautyFilterType.kBTAutoFilter, false);
  • 手势识别接入说明
    注册和注销算法回调。
    /** 注册算法回调 **/
    // 利用QueenEngine的句柄,创建一个算法实例,注册之后,对应的算法就会被执行
    // 第三个参数就是算法类型,具体参考AlgType类
    // 以下是手势识别算法的例子
    Algorithm algorithm = new Algorithm(engine.getEngineHandler(), "", com.taobao.android.libqueen.models.AlgType.kAAiGestureDetect);
    algorithm.registerAlgCallBack(new Algorithm.OnAlgDetectListener() {
        @Override
        public int onAlgDetectFinish(int algId, Object algResult) {
            if (algResult instanceof com.taobao.android.libqueen.algorithm.GestureData) {
                // GestureData包含静态手势和动作手势
                com.taobao.android.libqueen.algorithm.GestureData gestureData = (com.taobao.android.libqueen.algorithm.GestureData) algResult;
            }
            return 0;
        }
    });
    
    /** 注销算法回调 **/
    // 如果是绑定Algorithm的QueenEngine没有销毁,那么需要手动注销算法回调;如果QueenEngine被销毁了,那么Algorithm实例会自动失效。
    algorithm.unRegisterAlgCallBack();
  • 动作检测接入说明
    注册和注销算法回调。
    /** 注册算法回调 **/
    // 利用QueenEngine的句柄,创建一个算法实例,注册之后,对应的算法就会被执行
    // 第三个参数就是算法类型,具体参考AlgType类
    // 以下是动作检测算法的例子
    Algorithm algorithm = new Algorithm(engine.getEngineHandler(), "", com.taobao.android.libqueen.models.AlgType.kQueenAIBodySportDetect);
    algorithm.registerAlgCallBack(new Algorithm.OnAlgDetectListener() {
        @Override
        public int onAlgDetectFinish(int algId, Object algResult) {
            if (algResult instanceof BodyDetectData) {
              BodyDetectData resultData = (BodyDetectData)algResult;
              int sportType = resultData.getBodySportType();
              if (sportType <= 0) {
                // 姿态识别
                int poseType = resultData.getBodyPoseType();
                sb.append("【姿态识别】:").append(getBodyPoseName(poseType));
              } else {
                // 特定动作计数
                int sportCount = resultData.getBodySportCount();
                sb.append("【动作】:").append(getBodySportPoseName(sportType)).append("\r\n")
                  .append("【计数】:").append(sportCount);
              }
            }
            return 0;
        }
    });
    
    /** 注销算法回调 **/
    // 如果是绑定Algorithm的QueenEngine没有销毁,那么需要手动注销算法回调;如果QueenEngine被销毁了,那么Algorithm实例会自动失效。
    algorithm.unRegisterAlgCallBack();
  • 渲染
    // OES纹理的变换矩阵,通过SurfaceTexture获取
    float[] transformMatrix = new float[16];
    // 通过SurfaceTexture更新矩阵
    mSurfaceTexture.updateTexImage();
    mSurfaceTexture.getTransformMatrix(transformMatrix);
    
    // 渲染到当前窗口,如证书校验失败或者全部特效功能关闭,则SDK不会执行渲染操作
    int retCode = engine.renderTexture(transformMatrix);
    
    // 参考API文档
    // QUEEN_INVALID_LICENSE(-9),表示证书校验失败
    // QUEEN_NO_EFFECT(-10),表示全部特效功能关闭
    // 则需要业务方执行渲染,可参考Sample工程
    if (retCode == -9 || retCode == -10) {
        mFrameGlDrawer.draw(transformMatrix, mOESTextureId, true);
    }
  • 释放引擎
    // 释放引擎资源
    engine.release();
  • 资源下载能力
    // 初始化资源下载能力
    QueenMaterial.getInstance().init(context);
    
    // 设置资源下载监听
    QueenMaterial.getInstance().setCallback(new QueenMaterial.OnMaterialCallback() {
    
        @Override
        public void onReady(QueenMaterial.MaterialType materialType) {
            // 非UI线程回调资源下载完成(常规操作是关闭加载框,并触发业务逻辑)
    
            // 贴纸
            String stickerName = "1"; // 贴纸的相对路径
            String stickerPath = QueenMaterial.getInstance().getMaterialPath(QueenMaterial.MaterialType.STICKER) + File.separator + stickerName;
            // 将stickerPath配置到QueenEngine
            engine.addMaterial(stickerResPath);
        }
    
        @Override
        public void onProgress(QueenMaterial.MaterialType materialType, int currentSize, int totalSize, float progress) {
            // 非UI线程资源下载进度(常规操作是更新加载进度)
        }
    
        @Override
        public void onError(QueenMaterial.MaterialType materialType) {
            // 非UI线程资源下载错误(常规操作是关闭加载框,并提示用户检查网络和磁盘空间)
        }
    
    });
    
    // 触发资源下载(支持算法模型、贴纸、美妆、滤镜等),请根据业务需求触发下载
    // 注意1:只有使用了不带算法模型的SDK版本才需要下载算法模型,算法模型的下载必须先于QueenEngine的初始化使用,否则美颜效果会失效
    // 注意2:素材(贴纸、美妆、滤镜)可以随apk打包发布,也可以用下载方式接入
    if (QueenMaterial.getInstance().requestMaterial(QueenMaterial.MaterialType.MODEL)) {
        showProgressDialog();
    }

视频直播推流SDK接入范例

以视频直播推流SDK接入为例,请参见以下步骤。

  1. 确保已开启直播配置项,允许预处理模式。
    mAliLiveConfig.customPreProcessMode = CUSTOM_MODE_VIDEO_PREPROCESS;
  2. 初始化QueenEngine。
    engine = new QueenEngine(this, false);
  3. 注册视频处理回调代理,获取纹理更新。
    public int onTextureInput(int inputTexture, int textureWidth, int textureHeight) {
        glThreadId = Thread.currentThread().getId();
    
        if (mMediaChainEngine == null || !isBeautyEnable) {
        return inputTexture;
            }
        updateSettings();
    
        int[] oldFboId = new int[1];
        GLES20.glGetIntegerv(GLES20.GL_FRAMEBUFFER_BINDING, 
    IntBuffer.wrap(oldFboId));
    
        mMediaChainEngine.setInputTexture(inputTexture, textureWidth, 
    textureHeight, false);
    
       //如果画面旋转的话,就需要重新创建设置大小
       if (lastTextureWidth != textureWidth || lastTextureHeight != textureHeight) 
    {
       if (mOutTexture2D != null) {
           mOutTexture2D.release();
           mOutTexture2D = null;
                }
       lastTextureWidth = textureWidth;
       lastTextureHeight = textureHeight;
       mMediaChainEngine.setScreenViewport(0, 0, textureWidth,
    textureHeight);
            }
    
       if (mOutTexture2D == null) {
           mOutTexture2D = mMediaChainEngine.autoGenOutTexture();
            }
    
       if (mOutTexture2D == null) {
           return inputTexture;
           }
    
       long now = SystemClock.uptimeMillis();
    
       boolean hasRunAlg = false;
       if (USE_FRAME_SYNCHRONIZED) {
           mMediaChainEngine.setInputFlip(Flip.kNone);
           if (outAngle == 90 || outAngle == 270) {// 右 out = 90 / 左 out = 270
               mMediaChainEngine.setRenderAndFaceFlip(Flip.kFlipY, Flip.kNone);
               mMediaChainEngine.updateInputTextureBufferAndRunAlg(360-outAngle, outAngle, Flip.kFlipY, false);
          } else { // 正 out = 180 / 倒立 out = 0               
               mMediaChainEngine.setRenderAndFaceFlip(Flip.kNone, Flip.kFlipY);               
               mMediaChainEngine.updateInputTextureBufferAndRunAlg(180-outAngle, 180-outAngle, Flip.kNone, false); 
          }
          hasRunAlg = true;
          } else if (mAlgNativeBufferPtr != 0) {
              mMediaChainEngine.updateInputNativeBufferAndRunAlg(mAlgNativeBufferPtr, 
              mAlgDataFormat, mAlgDataWidth, mAlgDataHeight, nAlgDataStride, 
              inputAngle, outAngle, flipAxis);
          hasRunAlg = true;
          }
    
              int retCode = mMediaChainEngine.render();
              isAlgDataRendered = true;
    
              Log.i(TAG, Thread.currentThread().getId() + " - " +"render : " + 
          (SystemClock.uptimeMillis()-now) + "ms, hasRunAlg: " + hasRunAlg + ", 
          textureW: " + textureWidth + ", textureH: " + textureHeight + ", outAngle: " +
          outAngle);
             if (retCode == -9 || retCode == -10) {
                 Log.d(TAG, "queen error code:" + retCode + ",please ensure license valid");
                 return inputTexture;
           }
    
           GLES20.glBindFramebuffer(GL_FRAMEBUFFER, oldFboId[0]);
    
           return mOutTexture2D.getTextureId();
       }