将所需相关依赖文件放到指定目录
依赖文件 | 存放路径 |
---|---|
agora-rtc-sdk.jar |
AgoraWithAIWorksAndroid\app\libs |
64位libagora-rtc-sdk-jni.so |
AgoraWithAIWorksAndroid\app\src\main\jniLibs\arm64-v8a |
32位libagora-rtc-sdk-jni.so |
AgoraWithAIWorksAndroid\app\src\main\jniLibs\armeabi-v7a |
网课助手头文件 | AgoraWithAIWorksAndroid\app\src\main\cpp\aiworks\aw_education_api.h |
64位网课助手libaw_concentration_detect.so |
AgoraWithAIWorksAndroid\agora-aiworks\src\main\jniLibs\arm64-v8a |
32位网课助手libaw_concentration_detect.so |
32位网课助手libaw_concentration_detect.so |
64位c++库 libc++_shared.so |
AgoraWithAIWorksAndroid\agora-aiworks\src\main\jniLibs\arm64-v8a |
32位c++库 libc++_shared.so |
AgoraWithAIWorksAndroid\agora-aiworks\src\main\jniLibs\armeabi-v7a |
使用 RtcEngine create(RtcEngineConfig config) 初始化方法
//更换为开发者自己的appID
private static final String appId = "#YOUR APP ID#";
......
RtcEngineConfig config = new RtcEngineConfig();
config.mContext = this;
config.mAppId = appId;
//通过插件提供的接口获取native provider句柄
//注册native provider句柄,其中:vender用于区分不同的插件,observer用于监听该插件的消息
config.addExtension(ExtensionManager.EXTENSION_NAME);
config.mExtensionObserver = this;
......
mRtcEngine = RtcEngine.create(config);
//enable插件
mRtcEngine.enableExtension(EXTENSION_VENDOR_NAME, EXTENSION_VIDEO_FILTER_NAME, true);
2.1 addExtensionProvider
可多次调用,以注册多个插件(需使用不同的VENDOR_NAME
)
2.2 注册插件的消息回调需要实现 io.agora.rtc2.IMediaExtensionObserver
的 onEvent
接口
@Override
public void onEvent(String provider_name, String ext_name, final String key, final String json_value) {
//key/value是插件消息的键值对
......
}
设置插件参数
设置摄像头角度(人脸与设备的相对位置参数),模型加载路径,设备重力传感器方向等,参数用 json 的方式传输,第一个参数是注册的vendor名,第二个参数是参数的键,第三个参数是json字符串。
// Android
RtcEngine.setExtensionProperty(EXTENSION_VENDOR_NAME, EXTENSION_VIDEO_FILTER_NAME, propertyKey, propertyString);
参数解释如下
{
"plugin.aiworks.awCameraHorizontalViewAngle": 30f,
"plugin.aiworks.awCameraVerticalViewAngle":20f,
"plugin.aiworks.awCameraFocalength":3.5f,
"plugin.aiworks.awEDModelPath": "网课助手模型的路径",
"plugin.aiworks.awSensorOri": "重力传感器方向角",
"plugin.aiworks.awEDRest": "网课助手检测状态重置",
"plugin.aiworks.awEDRelease": "网课助手资源释放",
}
AIWorks education API 接口说明
/*
* SDK初始化
* mode_path: 模型文件所在目录
* interval: 检测间隔
* return: 初始化成功>=0 失败<0
*/
AW_SDK_API
int aw_education_init(const char *modelDir, int interval)
/*
* SDK是否已经初始化
* return:true 初始化,false未初始化
*/
AWEXPORT_API
bool aw_education_isinited();
/*
* 设置人脸与设备的相对位置参数(通过adb shell dumpsys media.camera)
* camera_horizontal_view_angle:horizontal-view-angle的值
* camera_vertical_view_angle:vertical-view-angle的值
* camera_focalength:focal-length的值
* human_fraction:默认值1.0
* desk_fraction:默认值1.0
*/
AWEXPORT_API
void aw_education_setHumanDistanceParam(float camera_horizontal_view_angle, float camera_vertical_view_angle, float camera_focalength, float human_fraction, float desk_fraction);
/*
* 网课助手检测引擎
* image :输入的原始检测数据(I420格式数据)
* preview_width/preview_height (输入的原始数据的宽高:预览的宽高)
* format:输入的原始数据的格式(I420)
* rotation:输入的原始数据的旋转角度(前摄:270,后摄: 90)
* flat:输入的设备Z轴角度,如果不需要检测设备平放时的低头,可以使用不带本参数的方法或传入90
*/
AWEXPORT_API
void aw_education_frame_detect(unsigned char *image, int width, int height, int format, int rotation, int flat);
/**
* 检测到的状态信息(在aw_education_frame_detect之后调用)
* info:状态信息
**/
AWEXPORT_API
void aw_education_fetch_result(aw_education_result_info *info);
/**
* SDK资源释放
*/
AW_SDK_API
void aw_education_destroy();
不同的识别结果将以 json 的方式返回(换背景预留)
5.1 检测状态的结果
"plugin.aiworks.education.info": [
{
"raise_count": //举手次数//
"doubt_count": //疑惑次数//
"smile_count": //微笑次数//
"yawn_count": //打哈欠次数//
"eye_blink_count": //眨眼次数//
"sleep_time": //瞌睡次数//
"eye_time": //用眼次数//
"prostrate_time": //趴着次数//
"lookdown_time": //俯视次数//
"headup_time": //仰头次数//
"headdown_time": //低头次数//
"no_person": //当前的无人入镜状态//
"over_angle": //当前的偏角过大提示//
"facemask": //当前的口罩状态//
"headtilt": //歪头次数//
"leftheadtilt": //左歪头次数 ,是headtilt子集//
"rightheadtilt": //右歪头次数,是headtilt子集//
"faceprofile": //侧脸次数//
"leftfaceprofile": //左侧脸次数,是faceprofile子集//
"rightfaceprofile": //右侧脸次数,是faceprofile子集//
"lookaround": //东张西望次数//
"human_distance": //当前的人脸到屏幕距离//
"angle1, angle2, angle3": //当前的人脸的pitch yaw roll角度//
"expression": //当前的人脸表情 deprecated//
"nodhead": //点头次数//
"shakeHead": //摇头次数//
"shouldertilt": //斜肩次数//
"leftshouldertilt": //左斜肩次数,是shouldertilt子集//
"rightshouldertilt": //右斜肩次数,是shouldertilt子集//
"desk_distance": //当前的人眼到桌面的距离 为定制化功能,默认无//
"liedown": //仰躺次数//
"brightness": //当前的图像的明亮度,为定制化功能,默认无//
"mouthopen_count": //张嘴次数//
"faceoutside": //当前人脸三分之一以上出画时为真,其他情况比如人在画面中 间或完全没有入镜时均为假//
"leftfaceoutside": //左边出画,faceoutside的子集//
"rightfaceoutside": //右边出画,faceoutside的子集//
}
]
功能模块 | 依赖文件 |
---|---|
网课助手模块 | ConcentrateLib.framework |
网课助手模块 | mnn.metallib (注意:此文件需要放在工程的根目录下) |
网课助手模块 | opencv2.framework (依赖的opencv库) |
功能模块 | 资源文件 |
---|---|
网课助手模块 | AWPortrait.framework -> eyemodel/EC_A_n_v1_un.bin (模型文件) |
网课助手模块 | AWPortrait.framework -> eyemodel/EC_A_n_v1.param (模型文件) |
网课助手模块 | AWPortrait.framework -> facemodel/FC_A0_N_v1.m.bin (模型文件) |
网课助手模块 | AWPortrait.framework -> facemodel/FD_J_n_v1.m.bin (模型文件) |
网课助手模块 | AWPortrait.framework -> facemodel/FE_C_n_v2_2class.m.bin (模型文件) |
网课助手模块 | AWPortrait.framework -> facemodel/FE_C_n_v2.m.bin (模型文件) |
网课助手模块 | AWPortrait.framework -> facemodel/FL_D_n_v1.m.bin (模型文件) |
网课助手模块 | AWPortrait.framework -> facemodel/FP_A_N_v1.m.bin (模型文件) |
网课助手模块 | AWPortrait.framework -> facemodel/MC_C_n_v1.m.bin (模型文件) |
网课助手模块 | AWPortrait.framework -> handmodel/HGD_J_v1_n.m.bin (模型文件) |
网课助手模块 | AWPortrait.framework -> handmodel/HGD_J_v2_n.m.bin (模型文件) |
初始化AIWorks plugin
使用 RtcEngine sharedEngineWithConfig
初始化方法
// iOS
AgoraRtcEngineConfig *cfg = [AgoraRtcEngineConfig new];
cfg.appId = appID;
AwVideoFilterManager *provider = [AwVideoFilterManager sharedInstance];
[provider loadPlugin];
AwVideoExtensionObject *obj = [provider mediaFilterExtension];
obj.observer = self;
cfg.mediaFilterExtensions = @[obj];
self.agoraKit = [AgoraRtcEngineKit sharedEngineWithConfig:cfg delegate:self];
注册虚拟背景的回调
// iOS
cfg.eventDelegate = self; // self为实现了AgoraMediaFilterEventDelegate接口的对象
其中 self
需要实现以下 protocol
// iOS
@protocol AgoraMediaFilterEventDelegate <NSObject>
- (void)onEvent:(NSString * __nullable)vendor
key:(NSString * __nullable)key
json_value:(NSString * __nullable)json_value;
@end
设置插件参数
设置摄像头角度(人脸与设备的相对位置参数),模型加载路径,设备重力传感器方向等,参数用 json 的方式传输
// iOS
[[AwVideoFilterManager sharedInstance] setParameter:jsonString];
参数解释如下
{
"plugin.aiworks.awEDModelPath": "网课助手模型的路径",
"plugin.aiworks.awSensorOri": "重力传感器方向角",
"plugin.aiworks.awEDRest": "网课助手检测状态重置",
"plugin.aiworks.awEDRelease": "网课助手资源释放",
}
PS: 需要使用SDK Cpp相关Interface,需要引入AgoraRtcKit2.framework
, 需要Emedded & Sign
AIWorks education API 接口说明
/*
* SDK初始化
* mode_path: 模型文件所在目录
* interval: 检测间隔
* return: 初始化成功>=0 失败<0
*/
AW_SDK_API
int aw_education_init(const char *modelDir, int interval)
/*
* SDK是否已经初始化
* return:true 初始化,false未初始化
*/
AWEXPORT_API
bool aw_education_isinited();
/*
* 设置人脸与设备的相对位置参数(通过adb shell dumpsys media.camera)
* camera_horizontal_view_angle:horizontal-view-angle的值
* camera_vertical_view_angle:vertical-view-angle的值
* camera_focalength:focal-length的值
* human_fraction:默认值1.0
* desk_fraction:默认值1.0
*/
AWEXPORT_API
void aw_education_setHumanDistanceParam(float camera_horizontal_view_angle, float camera_vertical_view_angle, float camera_focalength, float human_fraction, float desk_fraction);
/*
* 网课助手检测引擎
* image :输入的原始检测数据(I420格式数据)
* preview_width/preview_height (输入的原始数据的宽高:预览的宽高)
* format:输入的原始数据的格式(I420)
* rotation:输入的原始数据的旋转角度(前摄:270,后摄: 90)
* flat:输入的设备Z轴角度,如果不需要检测设备平放时的低头,可以使用不带本参数的方法或传入90
*/
AWEXPORT_API
void aw_education_frame_detect(unsigned char *image, int width, int height, int format, int rotation, int flat);
/**
* 检测到的状态信息(在aw_education_frame_detect之后调用)
* info:状态信息
**/
AWEXPORT_API
void aw_education_fetch_result(aw_education_result_info *info);
/**
* SDK资源释放
*/
AW_SDK_API
void aw_education_destroy();
不同的识别结果将以 json 的方式返回(换背景预留)
5.1 检测状态的结果
"plugin.aiworks.education.info": [
{
"raise_count": //举手次数//
"doubt_count": //疑惑次数//
"smile_count": //微笑次数//
"yawn_count": //打哈欠次数//
"eye_blink_count": //眨眼次数//
"sleep_time": //瞌睡次数//
"eye_time": //用眼次数//
"prostrate_time": //趴着次数//
"lookdown_time": //俯视次数//
"headup_time": //仰头次数//
"headdown_time": //低头次数//
"no_person": //当前的无人入镜状态//
"over_angle": //当前的偏角过大提示//
"facemask": //当前的口罩状态//
"headtilt": //歪头次数//
"leftheadtilt": //左歪头次数 ,是headtilt子集//
"rightheadtilt": //右歪头次数,是headtilt子集//
"faceprofile": //侧脸次数//
"leftfaceprofile": //左侧脸次数,是faceprofile子集//
"rightfaceprofile": //右侧脸次数,是faceprofile子集//
"lookaround": //东张西望次数//
"human_distance": //当前的人脸到屏幕距离//
"angle1, angle2, angle3": //当前的人脸的pitch yaw roll角度//
"expression": //当前的人脸表情 deprecated//
"nodhead": //点头次数//
"shakeHead": //摇头次数//
"shouldertilt": //斜肩次数//
"leftshouldertilt": //左斜肩次数,是shouldertilt子集//
"rightshouldertilt": //右斜肩次数,是shouldertilt子集//
"desk_distance": //当前的人眼到桌面的距离 为定制化功能,默认无//
"liedown": //仰躺次数//
"brightness": //当前的图像的明亮度,为定制化功能,默认无//
"mouthopen_count": //张嘴次数//
"faceoutside": //当前人脸三分之一以上出画时为真,其他情况比如人在 面 中 间或完全没有入镜时均为假//
"leftfaceoutside": //左边出画,faceoutside的子集//
"rightfaceoutside": //右边出画,faceoutside的子集//
}
]