Skip to content

Commit

Permalink
Merge pull request #29 from AgoraIO-Community/dev_108
Browse files Browse the repository at this point in the history
feat: beauty api 1.0.8
  • Loading branch information
weileifrank authored Oct 17, 2024
2 parents c29e052 + bf7e590 commit 5ae8258
Show file tree
Hide file tree
Showing 20 changed files with 762 additions and 712 deletions.
17 changes: 15 additions & 2 deletions Android/app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,8 @@ android {
// applicationId "com.thankyo.hwgame"
minSdkVersion 21
targetSdkVersion 31
versionCode 6
versionName "1.0.7"
versionCode 7
versionName "1.0.8"

testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
vectorDrawables {
Expand All @@ -29,15 +29,27 @@ android {
}
buildConfigField "String", "AGORA_APP_ID", "\"$AGORA_APP_ID\""
}
signingConfigs {
myConfig {
storeFile new File(rootProject.rootDir.absolutePath + "/keystore.key")
storePassword "965606"
keyAlias "agora"
keyPassword "965606"
v1SigningEnabled true
v2SigningEnabled true
}
}

buildTypes {
release {
minifyEnabled false
signingConfig signingConfigs.myConfig
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}
debug {
debuggable true
minifyEnabled false
signingConfig signingConfigs.myConfig
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}
}
Expand Down Expand Up @@ -89,6 +101,7 @@ dependencies {
implementation 'androidx.lifecycle:lifecycle-runtime-ktx:2.3.1'
implementation 'androidx.appcompat:appcompat:1.4.1'
implementation 'com.google.android.material:material:1.5.0'
implementation 'com.google.code.gson:gson:2.8.6'
testImplementation 'junit:junit:4.13.2'
androidTestImplementation 'androidx.test.ext:junit:1.1.3'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.4.0'
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -202,9 +202,9 @@ class FaceUnityActivity : ComponentActivity() {
}
setFrameRateSelect(intent.getStringExtra(EXTRA_FRAME_RATE) ?: "")
setOnFrameRateChangeListener { frameRate ->
mVideoEncoderConfiguration.frameRate = ReflectUtils.getStaticFiledValue(
VideoEncoderConfiguration::class.java, frameRate
) ?: 15
mVideoEncoderConfiguration.frameRate = ReflectUtils.getStaticFiledValue<FRAME_RATE>(
FRAME_RATE::class.java, frameRate
)?.value ?: 15
mRtcEngine.setVideoEncoderConfiguration(mVideoEncoderConfiguration)
}
}
Expand Down Expand Up @@ -308,6 +308,7 @@ class FaceUnityActivity : ComponentActivity() {

private fun initBeautyApi() {
FaceUnityBeautySDK.beautyConfig.reset()
FaceUnityBeautySDK.configureFURenderKit()
mFaceUnityApi.initialize(
Config(
applicationContext,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,11 @@ import android.util.Log
import com.faceunity.core.callback.OperateCallback
import com.faceunity.core.entity.FUBundleData
import com.faceunity.core.enumeration.FUAITypeEnum
import com.faceunity.core.faceunity.AICommonData.FUAIFACE_DISABLE_ARMESHV2
import com.faceunity.core.faceunity.AICommonData.FUAIFACE_DISABLE_DEL_SPOT
import com.faceunity.core.faceunity.AICommonData.FUAIFACE_DISABLE_FACE_OCCU
import com.faceunity.core.faceunity.AICommonData.FUAIFACE_DISABLE_SKIN_SEG
import com.faceunity.core.faceunity.AICommonData.FUAIFACE_ENABLE_ALL
import com.faceunity.core.faceunity.FUAIKit
import com.faceunity.core.faceunity.FURenderConfig.OPERATE_SUCCESS_AUTH
import com.faceunity.core.faceunity.FURenderKit
Expand All @@ -15,6 +20,7 @@ import com.faceunity.core.model.makeup.SimpleMakeup
import com.faceunity.core.model.prop.sticker.Sticker
import com.faceunity.core.utils.FULogger
import com.faceunity.wrapper.faceunity
import io.agora.beautyapi.demo.module.faceunity.utils.FuDeviceUtils
import io.agora.beautyapi.faceunity.FaceUnityBeautyAPI
import java.io.File

Expand All @@ -33,14 +39,49 @@ object FaceUnityBeautySDK {

private var authSuccess = false

/**
* 特效配置
*/
fun configureFURenderKit() {
val fukit = FUAIKit.getInstance();
fukit.setFaceDelayLeaveEnable(FuDeviceUtils.Config.FACE_DELAY_LEAVE_ENABLE)
when (FuDeviceUtils.Config.DEVICE_LEVEL) {
FuDeviceUtils.DEVICE_LEVEL_MINUS_ONE, FuDeviceUtils.DEVICE_LEVEL_ONE -> fukit.fuSetFaceAlgorithmConfig(
FUAIFACE_DISABLE_FACE_OCCU or FUAIFACE_DISABLE_SKIN_SEG or FUAIFACE_DISABLE_DEL_SPOT or FUAIFACE_DISABLE_ARMESHV2
)

FuDeviceUtils.DEVICE_LEVEL_TWO -> fukit.fuSetFaceAlgorithmConfig(
FUAIFACE_DISABLE_SKIN_SEG or FUAIFACE_DISABLE_DEL_SPOT or FUAIFACE_DISABLE_ARMESHV2
)

FuDeviceUtils.DEVICE_LEVEL_THREE -> fukit.fuSetFaceAlgorithmConfig(
FUAIFACE_DISABLE_SKIN_SEG
)

FuDeviceUtils.DEVICE_LEVEL_FOUR -> fukit.fuSetFaceAlgorithmConfig(FUAIFACE_ENABLE_ALL)
}
fukit.loadAIProcessor(
FuDeviceUtils.Config.BUNDLE_AI_FACE,
FUAITypeEnum.FUAITYPE_FACEPROCESSOR
)
fukit.faceProcessorSetFaceLandmarkQuality(if (FuDeviceUtils.Config.DEVICE_LEVEL >= 2) 2 else 1)
FURenderKit.getInstance()
.setDynamicQualityControl(FuDeviceUtils.Config.DEVICE_LEVEL <= FuDeviceUtils.DEVICE_LEVEL_ONE)
//高端机开启小脸检测
if (FuDeviceUtils.Config.DEVICE_LEVEL > FuDeviceUtils.DEVICE_LEVEL_ONE) fukit.fuFaceProcessorSetDetectSmallFace(
true
)
}

fun initBeauty(context: Context): Boolean {
val auth = try {
getAuth()
} catch (e: Exception) {
Log.w(TAG, e)
return false
} ?: return false

FuDeviceUtils.Config.DEVICE_LEVEL = FuDeviceUtils.judgeDeviceLevel(context)
FuDeviceUtils.Config.DEVICE_NAME = FuDeviceUtils.getDeviceName()
FURenderManager.setKitDebug(FULogger.LogLevel.TRACE)
FURenderManager.setCoreDebug(FULogger.LogLevel.ERROR)
FURenderManager.registerFURender(context, auth, object : OperateCallback {
Expand Down Expand Up @@ -290,8 +331,7 @@ object FaceUnityBeautySDK {
fuRenderKit.makeup = null
} else {
val makeup =
SimpleMakeup(FUBundleData("graphics" + File.separator + "face_makeup.bundle"))
makeup.setCombinedConfig(FUBundleData("$resourceBase/${value.path}"))
SimpleMakeup(FUBundleData("$resourceBase/${value.path}"))
makeup.makeupIntensity = value.intensity.toDouble()
fuRenderKit.makeup = makeup
}
Expand Down Expand Up @@ -321,7 +361,7 @@ object FaceUnityBeautySDK {
sticker = null
}

fun resume(){
fun resume() {
smooth = smooth
whiten = whiten
thinFace = thinFace
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -241,9 +241,9 @@ class FaceUnityControllerView : BeautyControllerView {
ItemInfo(
R.string.beauty_item_sticker_zhu,
R.mipmap.ic_sticker_fu_zh_fenshu,
isSelected = beautyConfig.sticker == "sticker/fu_zh_fenshu.bundle",
isSelected = beautyConfig.sticker == "sticker/daisypig.bundle",
onValueChanged = { _ ->
beautyConfig.sticker = "sticker/fu_zh_fenshu.bundle"
beautyConfig.sticker = "sticker/daisypig.bundle"
}
)
)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,168 @@
package io.agora.beautyapi.demo.module.faceunity.utils;

import static android.content.Context.MODE_PRIVATE;

import android.content.Context;
import android.content.SharedPreferences;
import android.os.Build;
import android.util.Log;

import com.faceunity.core.utils.FULogger;

import java.io.File;

import io.agora.beautyapi.demo.module.faceunity.utils.device.DeviceScoreUtils;

public class FuDeviceUtils {

public static final String TAG = "FuDeviceUtils";

public static final String DEVICE_LEVEL = "device_level";

public static final int DEVICE_LEVEL_FOUR = 4;
public static final int DEVICE_LEVEL_THREE = 3;

public static final int DEVICE_LEVEL_TWO = 2;
public static final int DEVICE_LEVEL_ONE = 1;
public static final int DEVICE_LEVEL_MINUS_ONE = -1;
public static final int DEVICE_LEVEL_EMPTY = -100;

public static final double DEVICE_SCORE_FOUR = 85.0;
public static final double DEVICE_SCORE_THREE = 78.0;
public static final double DEVICE_SCORE_TWO = 69.0;
public static final double DEVICE_SCORE_ONE = 64.0;

public static final String[] levelFourDevices = {};
public static final String[] levelThreeDevices = {};
public static final String[] levelTwoDevices = {};
public static final String[] levelOneDevices = {"PRO 7 Plus"};
public static final String Nexus_6P = "Nexus 6P";


public static int judgeDeviceLevel(Context context) {
return judgeDeviceLevel(context,false);
}

/**
* 判断设备级别
*
* @return int
*/
public static int judgeDeviceLevel(Context context,boolean ignoreCache) {
if (!ignoreCache) {
int cacheDeviceLevel = getCacheDeviceLevel(context);
if (cacheDeviceLevel > DEVICE_LEVEL_EMPTY) {
return cacheDeviceLevel;
}
}
//有一些设备不符合下述的判断规则,则走一个机型判断模式
int specialDevice = judgeDeviceLevelInDeviceName();
if (specialDevice > DEVICE_LEVEL_EMPTY) {
return specialDevice;
}
double score = DeviceScoreUtils.getDeviceScore();
int level = DEVICE_LEVEL_MINUS_ONE;
if (score > DEVICE_SCORE_ONE) {
level = DEVICE_LEVEL_ONE;
}
if (score > DEVICE_SCORE_TWO) {
level = DEVICE_LEVEL_TWO;
}
if (score > DEVICE_SCORE_THREE) {
level = DEVICE_LEVEL_THREE;
}
if (score > DEVICE_SCORE_FOUR) {
level = DEVICE_LEVEL_FOUR;
}
saveCacheDeviceLevel(context,level);
Log.d(TAG, "CPUName: " + DeviceScoreUtils.CPUName + " GPUName: " + DeviceScoreUtils.GPUName + " score: " + score + " level: " + level);
return level;
}

/**
* -1 不是特定的高低端机型
*
* @return
*/
private static int judgeDeviceLevelInDeviceName() {
String currentDeviceName = getDeviceName();
for (String deviceName : levelFourDevices) {
if (deviceName.equals(currentDeviceName)) {
return DEVICE_LEVEL_FOUR;
}
}
for (String deviceName : levelThreeDevices) {
if (deviceName.equals(currentDeviceName)) {
return DEVICE_LEVEL_THREE;
}
}
for (String deviceName : levelTwoDevices) {
if (deviceName.equals(currentDeviceName)) {
return DEVICE_LEVEL_TWO;
}
}
for (String deviceName : levelOneDevices) {
if (deviceName.equals(currentDeviceName)) {
return DEVICE_LEVEL_ONE;
}
}
return DEVICE_LEVEL_EMPTY;
}

/**
* 获取设备名
*
* @return String
*/
public static String getDeviceName() {
String deviceName = "";
if (Build.MODEL != null) {
deviceName = Build.MODEL;
}
Log.d(TAG, "deviceName: " + deviceName);
return deviceName;
}

/**
* 缓存设备等级
*
* @param level int
*/
public static void saveCacheDeviceLevel(Context context,int level) {
SharedPreferences sp = context.getSharedPreferences(DEVICE_LEVEL, MODE_PRIVATE);
sp.edit().putInt(DEVICE_LEVEL, level).apply();
}

/**
* 获取设备等级
*
* @return int
*/
public static int getCacheDeviceLevel(Context context) {
SharedPreferences sp = context.getSharedPreferences(DEVICE_LEVEL, MODE_PRIVATE);
return sp.getInt(DEVICE_LEVEL, DEVICE_LEVEL_EMPTY);
}

public static class Config{
/************************** 算法Model ******************************/
// 人脸识别
public static String BUNDLE_AI_FACE = "model" + File.separator + "ai_face_processor.bundle";
// 手势
public static String BUNDLE_AI_HAND = "model" + File.separator + "ai_hand_processor.bundle";
// 人体
public static String BUNDLE_AI_HUMAN = "model" + File.separator + "ai_human_processor.bundle";

// 舌头
public static String BUNDLE_AI_TONGUE = "graphics" + File.separator + "tongue.bundle";

//设备等级默认为中级
public static int DEVICE_LEVEL = FuDeviceUtils.DEVICE_LEVEL_TWO;

//设备名称
public static String DEVICE_NAME = "";


//人脸离开之后是否延迟10帧移除人脸相关信息
public static final boolean FACE_DELAY_LEAVE_ENABLE = false;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
package io.agora.beautyapi.demo.module.faceunity.utils.device;

import java.util.ArrayList;
import java.util.Collections;

/**
* DESC:
* Created on 2021/3/12
*/
public class DefaultScoreProvider implements DeviceScoreProvider {

public static final String[] badOtherGPUDevices = {"PowerVR Rogue GE"};
@Override
public double getCpuScore(String cpuName) {
int cpuCores = Runtime.getRuntime().availableProcessors();
ArrayList<Long> list = DeviceCpuUtils.getCPUFrequencies();
Collections.sort(list);
Collections.reverse(list);
DeviceScoreUtils.CPUFrequencies.clear();
for (int i = 0; i < list.size(); i++) {
DeviceScoreUtils.CPUFrequencies.add(list.get(i) / 1000 / 1000f + "GHz");
}
if (cpuCores <= 4) {
return 65;
}
if (list == null || list.isEmpty()) {
return 65;
}
double maxFre = list.get(0) / 1000 / 1000f;
if (maxFre < 2.2) {
return 65;
}
if (maxFre <= 2.4) {
return 70 - MathUtils.getScore(maxFre, 2.4, 5, 0.2);
}
if (maxFre <= 2.8) {
return 75 - MathUtils.getScore(maxFre, 2.8, 5, 0.4);
}
if (maxFre < 3.2) {
return 85 - MathUtils.getScore(maxFre, 3.2, 10, 0.4);
}
return 90 + (maxFre - 3.2) / 0.2;
}

@Override
public double getGpuScore(String glRenderer) {
// 处理个别低端设备
for (String badDevice : badOtherGPUDevices){
if (glRenderer.startsWith(badDevice)){
return 55;
}
}
return 65;
}
}
Loading

0 comments on commit 5ae8258

Please sign in to comment.