|
@@ -26,6 +26,11 @@ class FacialRecognitionException implements Exception {
|
|
|
final String message;
|
|
|
|
|
|
FacialRecognitionException(this.code, this.message);
|
|
|
+
|
|
|
+ @override
|
|
|
+ String toString() {
|
|
|
+ return "[FacialRecognitionException] code: $code, message: $message.";
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
/// 人脸识别采集器
|
|
@@ -52,38 +57,72 @@ class FacialRecognitionCapturer {
|
|
|
int _workedCount = 0;
|
|
|
_Worker? _worker;
|
|
|
Object? _result;
|
|
|
+ bool _isBusy = false;
|
|
|
+ bool _isPause = false;
|
|
|
+
|
|
|
+ camera.CameraController? _cameraController;
|
|
|
+ mlkit.FaceDetector? _faceDetector;
|
|
|
|
|
|
/// 识别结果
|
|
|
Object? get result => _result;
|
|
|
|
|
|
/// 初始化
|
|
|
- Future<void> init() async {
|
|
|
- //
|
|
|
+ Future<void> init(
|
|
|
+ camera.CameraController? cameraController,
|
|
|
+ mlkit.FaceDetector faceDetector,
|
|
|
+ ) async {
|
|
|
+ _cameraController = cameraController;
|
|
|
+ _faceDetector = faceDetector;
|
|
|
+ logger.i("FacialRecognitionCapturer init.");
|
|
|
+ }
|
|
|
+
|
|
|
+ /// 暂停
|
|
|
+ void callPause() {
|
|
|
+ _isPause = true;
|
|
|
+ logger.i("FacialRecognitionCapturer pause.");
|
|
|
+ }
|
|
|
+
|
|
|
+ /// 继续
|
|
|
+ void callContinue() {
|
|
|
+ _isPause = false;
|
|
|
+ logger.i("FacialRecognitionCapturer continue.");
|
|
|
}
|
|
|
|
|
|
/// 开启工作
|
|
|
- void run() async {
|
|
|
- while (result == null) {
|
|
|
+ Future<void> run() async {
|
|
|
+ logger.i("FacialRecognitionCapturer start run...");
|
|
|
+ _isBusy = true;
|
|
|
+ while (_isBusy) {
|
|
|
if (_workedCount > retryLimit) {
|
|
|
+ stop();
|
|
|
+ timeoutEvent.emit(this, null);
|
|
|
break;
|
|
|
}
|
|
|
- _workedCount++;
|
|
|
- await _doOnce();
|
|
|
- // 每次间隔100ms
|
|
|
+ if (_isPause == false) {
|
|
|
+ _workedCount++;
|
|
|
+ await _doOnce();
|
|
|
+ }
|
|
|
+ // 每次间隔100ms检测一次
|
|
|
await Future.delayed(const Duration(milliseconds: 100));
|
|
|
}
|
|
|
+ logger.i("FacialRecognitionCapturer run finish.");
|
|
|
}
|
|
|
|
|
|
/// 停止工作
|
|
|
void stop() {
|
|
|
+ logger.i("FacialRecognitionCapturer stop...");
|
|
|
+ _isBusy = false;
|
|
|
_workedCount = retryLimit + 1;
|
|
|
_worker?.stop();
|
|
|
_worker = null;
|
|
|
+ logger.i("FacialRecognitionCapturer stop done.");
|
|
|
}
|
|
|
|
|
|
Future<void> _doOnce() async {
|
|
|
try {
|
|
|
final $ = WorkVariables();
|
|
|
+ $.cameraController = _cameraController;
|
|
|
+ $.faceDetector = _faceDetector;
|
|
|
$.imgCachedCallback = (value) {
|
|
|
// 通知识别帧已缓存本地
|
|
|
frameCachedEvent.emit(this, value);
|
|
@@ -93,9 +132,10 @@ class FacialRecognitionCapturer {
|
|
|
await _worker!.run();
|
|
|
_result = $.result;
|
|
|
if ($.result != null) {
|
|
|
+ // 暂停等待success回调处理后发送继续工作信号
|
|
|
+ callPause();
|
|
|
// 识别成功
|
|
|
successEvent.emit(this, $.result!);
|
|
|
- stop();
|
|
|
}
|
|
|
} on FacialRecognitionException catch (e) {
|
|
|
if (e.code > 0) {
|
|
@@ -155,15 +195,13 @@ class _Worker {
|
|
|
$.cachedFile = file;
|
|
|
$.imgCachedCallback?.call("");
|
|
|
} on camera.CameraException catch (e) {
|
|
|
- abortWithException(
|
|
|
- FacialRecognitionExceptionCode.PTHOT_TAKE_ERROR,
|
|
|
- e.description ?? "拍摄失败",
|
|
|
- );
|
|
|
- } catch (e) {
|
|
|
- abortWithException(
|
|
|
- FacialRecognitionExceptionCode.PTHOT_TAKE_ERROR,
|
|
|
- "拍摄失败",
|
|
|
- );
|
|
|
+ logger.e("FacialRecognitionCapturer._Worker takePhoto error.", e);
|
|
|
+ // TODO: 暂时不提示
|
|
|
+ // abortWithException(
|
|
|
+ // FacialRecognitionExceptionCode.PTHOT_TAKE_ERROR,
|
|
|
+ // e.description ?? "拍摄失败",
|
|
|
+ // );
|
|
|
+ abort();
|
|
|
}
|
|
|
}
|
|
|
|
|
@@ -171,13 +209,10 @@ class _Worker {
|
|
|
Future<void> detectFace() async {
|
|
|
try {
|
|
|
final image = mlkit.InputImage.fromFilePath($.cachedFile!.path);
|
|
|
- final faceDetector = mlkit.FaceDetector(
|
|
|
- options: mlkit.FaceDetectorOptions(),
|
|
|
- );
|
|
|
- final faces = await faceDetector.processImage(image);
|
|
|
+ final faces = await $.faceDetector!.processImage(image);
|
|
|
$.faceNum = faces.length;
|
|
|
} catch (e) {
|
|
|
- //TODO:
|
|
|
+ logger.e("FacialRecognitionCapturer._Worker detectFace error.", e);
|
|
|
abort();
|
|
|
}
|
|
|
}
|
|
@@ -223,7 +258,7 @@ class _Worker {
|
|
|
}
|
|
|
$.result = url;
|
|
|
} catch (e) {
|
|
|
- logger.e("FacialRecognitionCapturer Worker upload file error.", e);
|
|
|
+ logger.e("FacialRecognitionCapturer._Worker upload file error.", e);
|
|
|
abortWithException(
|
|
|
FacialRecognitionExceptionCode.PTHOT_UPLOAD_FAIL,
|
|
|
"上传人像失败",
|
|
@@ -249,6 +284,8 @@ class _Worker {
|
|
|
|
|
|
class WorkVariables {
|
|
|
camera.CameraController? cameraController;
|
|
|
+ mlkit.FaceDetector? faceDetector;
|
|
|
+
|
|
|
ValueChanged<String>? imgCachedCallback;
|
|
|
|
|
|
camera.XFile? cachedFile;
|