272 lines
10 KiB
Java
272 lines
10 KiB
Java
package com.yunbao.faceunity;
|
||
|
||
import static android.content.Context.SENSOR_SERVICE;
|
||
|
||
import android.content.Context;
|
||
import android.hardware.Camera;
|
||
import android.hardware.Sensor;
|
||
import android.hardware.SensorEvent;
|
||
import android.hardware.SensorEventListener;
|
||
import android.hardware.SensorManager;
|
||
import android.os.Environment;
|
||
import android.util.Log;
|
||
|
||
import com.faceunity.core.entity.FURenderOutputData;
|
||
import com.faceunity.core.enumeration.CameraFacingEnum;
|
||
import com.faceunity.core.enumeration.FUAIProcessorEnum;
|
||
import com.faceunity.core.enumeration.FUAITypeEnum;
|
||
import com.faceunity.core.enumeration.FUInputTextureEnum;
|
||
import com.faceunity.core.enumeration.FUTransformMatrixEnum;
|
||
import com.faceunity.core.faceunity.FUAIKit;
|
||
import com.faceunity.core.utils.CameraUtils;
|
||
import com.yunbao.faceunity.data.FaceBeautyDataFactory;
|
||
import com.yunbao.faceunity.data.FaceUnityDataFactory;
|
||
import com.yunbao.faceunity.entity.FaceBeautyBean;
|
||
import com.yunbao.faceunity.entity.FaceBeautyFilterBean;
|
||
import com.yunbao.faceunity.listener.FURendererListener;
|
||
import com.yunbao.faceunity.ui.FaceUnityView;
|
||
import com.yunbao.faceunity.utils.CSVUtils;
|
||
import com.yunbao.faceunity.utils.FURenderer;
|
||
import com.yunbao.faceunity.utils.FaceSPUtils;
|
||
import com.yunbao.faceunity.utils.FaceUnityData;
|
||
import com.yunbao.faceunity.utils.net.OkHttpUtils;
|
||
|
||
import java.io.File;
|
||
import java.text.SimpleDateFormat;
|
||
import java.util.Date;
|
||
import java.util.Locale;
|
||
import java.util.Map;
|
||
import java.util.Objects;
|
||
|
||
|
||
/**
|
||
* 美颜模块管理类
|
||
*/
|
||
public class FaceManager implements SensorEventListener {
|
||
private static boolean isInit = false;
|
||
private static final String TAG = FaceManager.class.getSimpleName();
|
||
private FaceUnityDataFactory mFaceUnityDataFactory;
|
||
private FaceManager.FaceStatusChanged faceStatusChanged;
|
||
private boolean pauseFace = false;
|
||
|
||
/**
|
||
* 初始化美颜模块,在AppContext中调用
|
||
*/
|
||
public static void initFaceUnity(Context context) {
|
||
if (isInit) {
|
||
return;
|
||
}
|
||
FaceUnityData.mApplication = context;
|
||
OkHttpUtils.getInstance().init(context, false);
|
||
FURenderer.getInstance().setup(context);
|
||
isInit = true;
|
||
}
|
||
|
||
private FURenderer mFURenderer;
|
||
|
||
/**
|
||
* 配置美颜SDK
|
||
*/
|
||
public void initFURender(Context context) {
|
||
initFaceUnity(context);
|
||
mFURenderer = FURenderer.getInstance();
|
||
mFURenderer.setInputTextureType(FUInputTextureEnum.FU_ADM_FLAG_COMMON_TEXTURE);
|
||
mFURenderer.setCameraFacing(CameraFacingEnum.CAMERA_FRONT);
|
||
mFURenderer.setInputBufferMatrix(FUTransformMatrixEnum.CCROT90_FLIPHORIZONTAL);
|
||
mFURenderer.setInputTextureMatrix(FUTransformMatrixEnum.CCROT90_FLIPHORIZONTAL);
|
||
mFURenderer.setOutputMatrix(FUTransformMatrixEnum.CCROT270);
|
||
mFURenderer.setInputOrientation(CameraUtils.INSTANCE.getCameraOrientation(Camera.CameraInfo.CAMERA_FACING_FRONT));
|
||
mFURenderer.setMarkFPSEnable(true);
|
||
mFaceUnityDataFactory = FaceUnityDataFactory.getInstance();
|
||
|
||
SensorManager mSensorManager = (SensorManager) context.getSystemService(SENSOR_SERVICE);
|
||
Sensor sensor = mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
|
||
mSensorManager.registerListener(this, sensor, SensorManager.SENSOR_DELAY_NORMAL);
|
||
}
|
||
|
||
/**
|
||
* 注册长按对比键事件
|
||
*
|
||
* @param faceUnityView
|
||
*/
|
||
public void setFaceUnityView(FaceUnityView faceUnityView) {
|
||
faceUnityView.setIFaceUnityInter(new FaceUnityView.IFaceUnityInter() {
|
||
@Override
|
||
public void onPause() {
|
||
if(onMirrorChanged!=null){
|
||
onMirrorChanged.onChange(false);
|
||
}
|
||
pauseFace = true;
|
||
}
|
||
|
||
@Override
|
||
public void onStart() {
|
||
if(onMirrorChanged!=null){
|
||
onMirrorChanged.onChange(true);
|
||
}
|
||
pauseFace = false;
|
||
}
|
||
});
|
||
}
|
||
|
||
public void loadConfig() {
|
||
initFaceBeauty();
|
||
}
|
||
|
||
public void initFaceBeauty() {
|
||
FaceBeautyDataFactory faceBeautyDataFactory;
|
||
faceBeautyDataFactory = new FaceBeautyDataFactory();
|
||
Map<String, ?> configMap = FaceSPUtils.getInstance().getAll();
|
||
for (String key : configMap.keySet()) {
|
||
if ("FilterViewHolder_".equals(key)) {
|
||
for (FaceBeautyFilterBean filter : faceBeautyDataFactory.getBeautyFilters()) {
|
||
if (filter.getKey().equals(configMap.get(key)) && !"origin".equals(configMap.get(key))) {
|
||
try {
|
||
faceBeautyDataFactory.onFilterSelected(filter.getKey(), Double.parseDouble((String) Objects.requireNonNull(configMap.get("FilterViewHolder_" + configMap.get(key) + "_val"))) / 100, filter.getDesRes());
|
||
Log.i(TAG, "test: 设置滤镜 =" + filter.getKey() + " val = " + configMap.get("FilterViewHolder_" + configMap.get(key) + "_val"));
|
||
} catch (Exception e) {
|
||
e.printStackTrace();
|
||
}
|
||
break;
|
||
}
|
||
}
|
||
} else if (key.startsWith("BeautySkinViewHolder_")) {
|
||
String name = key.replace("BeautySkinViewHolder_", "");
|
||
for (FaceBeautyBean bean : faceBeautyDataFactory.getShapeBeauty()) {
|
||
if (bean.getKey().equals(name)) {
|
||
try {
|
||
faceBeautyDataFactory.updateParamIntensity(bean.getKey(), Double.parseDouble((String) Objects.requireNonNull(configMap.get(key))));
|
||
Log.i(TAG, "test: 设置美颜 = " + bean.getKey() + " val = " + configMap.get(key));
|
||
} catch (Exception e) {
|
||
e.printStackTrace();
|
||
}
|
||
break;
|
||
}
|
||
}
|
||
} else if (key.startsWith("BeautyShapeViewHolder")) {
|
||
String name = key.replace("BeautyShapeViewHolder_", "");
|
||
for (FaceBeautyBean bean : faceBeautyDataFactory.getShapeBeauty()) {
|
||
if (bean.getKey().equals(name)) {
|
||
try {
|
||
faceBeautyDataFactory.updateParamIntensity(bean.getKey(), Double.parseDouble((String) Objects.requireNonNull(configMap.get(key))));
|
||
Log.i(TAG, "test: 设置美肤 = " + bean.getKey() + " val = " + configMap.get(key));
|
||
} catch (Exception e) {
|
||
e.printStackTrace();
|
||
}
|
||
break;
|
||
}
|
||
}
|
||
}
|
||
|
||
}
|
||
}
|
||
|
||
/**
|
||
* 监听人脸识别个数
|
||
*/
|
||
public void setFaceStatusChanged(FaceStatusChanged faceStatusChanged) {
|
||
this.faceStatusChanged = faceStatusChanged;
|
||
}
|
||
|
||
private boolean mIsFirstFrame = true;
|
||
private CSVUtils mCSVUtils;
|
||
private int mSkippedFrames = CAMERA_SWITCH_SKIP_FRAME;
|
||
// 相机切换跳过 5 帧,如果还有问题,可以增加帧数
|
||
private static final int CAMERA_SWITCH_SKIP_FRAME = 0;
|
||
private volatile boolean mSkip;
|
||
|
||
|
||
/**
|
||
* 记录渲染工具,调试用,在processVideoFrame里使用
|
||
*/
|
||
private void initCsvUtil(Context context) {
|
||
mCSVUtils = new CSVUtils(context);
|
||
SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd_HH-mm-ss", Locale.getDefault());
|
||
String dateStrDir = format.format(new Date(System.currentTimeMillis()));
|
||
dateStrDir = dateStrDir.replaceAll("-", "").replaceAll("_", "");
|
||
SimpleDateFormat df = new SimpleDateFormat("yyyyMMddHHmmssSSS", Locale.getDefault());
|
||
String dateStrFile = df.format(new Date());
|
||
String filePath = Environment.getExternalStoragePublicDirectory("") + dateStrDir + File.separator + "excel-" + dateStrFile + ".csv";
|
||
Log.d("CSV", "initLog: CSV file path:" + filePath);
|
||
StringBuilder headerInfo = new StringBuilder();
|
||
headerInfo.append("version:").append(FURenderer.getInstance().getVersion()).append(CSVUtils.COMMA)
|
||
.append("机型:").append(android.os.Build.MANUFACTURER).append(android.os.Build.MODEL)
|
||
.append("处理方式:Texture").append(CSVUtils.COMMA);
|
||
mCSVUtils.initHeader(filePath, headerInfo);
|
||
}
|
||
|
||
|
||
private FURendererListener mFURendererListener = new FURendererListener() {
|
||
|
||
@Override
|
||
public void onPrepare() {
|
||
mFaceUnityDataFactory.bindCurrentRenderer();
|
||
//Log.e(TAG, "mFURendererListener: onPrepare: ");
|
||
}
|
||
|
||
@Override
|
||
public void onTrackStatusChanged(FUAIProcessorEnum type, int status) {
|
||
Log.e(TAG, "onTrackStatusChanged: 人脸数: " + status);
|
||
if (faceStatusChanged != null) {
|
||
faceStatusChanged.onFaceChanged(status);
|
||
}
|
||
|
||
}
|
||
|
||
@Override
|
||
public void onFpsChanged(double fps, double callTime) {
|
||
final String FPS = String.format(Locale.getDefault(), "%.2f", fps);
|
||
// Log.d(TAG, "onFpsChanged FPS: " + FPS + ", callTime: " + String.format("%.2f", callTime));
|
||
}
|
||
|
||
@Override
|
||
public void onRelease() {
|
||
// RongCallClient.getInstance().unregisterVideoFrameObserver();
|
||
}
|
||
};
|
||
|
||
|
||
@Override
|
||
public void onSensorChanged(SensorEvent sensorEvent) {
|
||
|
||
}
|
||
|
||
@Override
|
||
public void onAccuracyChanged(Sensor sensor, int i) {
|
||
|
||
}
|
||
|
||
|
||
|
||
/**
|
||
* 释放资源
|
||
*/
|
||
public void release() {
|
||
mFURenderer.release();
|
||
try {
|
||
for (FUAITypeEnum value : FUAITypeEnum.values()) {
|
||
FUAIKit.getInstance().releaseAIProcessor(value);
|
||
}
|
||
} catch (Exception e) {
|
||
e.printStackTrace();
|
||
}
|
||
isInit = false;
|
||
|
||
}
|
||
|
||
OnMirrorChanged onMirrorChanged;
|
||
|
||
public void setOnMirrorChanged(OnMirrorChanged onMirrorChanged) {
|
||
this.onMirrorChanged = onMirrorChanged;
|
||
}
|
||
|
||
public interface FaceStatusChanged {
|
||
void onFaceChanged(int num);
|
||
}
|
||
|
||
|
||
public interface OnMirrorChanged{
|
||
void onChange(boolean falg);
|
||
}
|
||
}
|