Daisy a5817cffeb 1,新增人脸部分命令协议调试
2,新增人脸相关接口处理 更新人脸信息、删除人脸、清空人脸(未完成)
3,部分人脸详情处理(待完善)
2024-01-24 18:51:18 +08:00

398 lines
12 KiB
Dart
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import 'dart:async';
import 'dart:convert';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';
import 'package:get/get.dart';
import 'package:star_lock/talk/call/callTalk.dart';
import '../../../../app_settings/app_colors.dart';
import '../../../../tools/showTFView.dart';
import 'realTimePicture_logic.dart';
class RealTimePicturePage extends StatefulWidget {
const RealTimePicturePage({Key? key}) : super(key: key);
@override
State<RealTimePicturePage> createState() => _RealTimePicturePageState();
}
class _RealTimePicturePageState extends State<RealTimePicturePage>
with TickerProviderStateMixin {
final logic = Get.put(RealTimePictureLogic());
final state = Get.find<RealTimePictureLogic>().state;
@override
void initState() {
super.initState();
//写一个定时器,三十秒后页面自动返回
state.autoBackTimer = Timer(const Duration(seconds: 30), () {
Get.back();
});
state.animationController = AnimationController(
vsync: this, // 确保使用的TickerProvider是当前Widget
duration: const Duration(seconds: 1),
);
;
state.animationController.repeat();
//动画开始、结束、向前移动或向后移动时会调用StatusListener
state.animationController.addStatusListener((status) {
// print("AnimationStatus:$status");
if (status == AnimationStatus.completed) {
state.animationController.reset();
state.animationController.forward();
} else if (status == AnimationStatus.dismissed) {
state.animationController.reset();
state.animationController.forward();
}
});
initiateUdpMonitorAction();
}
//发起监视命令,每隔一秒钟发一次,三十秒无应答则失败
void initiateUdpMonitorAction() {
// 每隔一秒调用一次 udpMonitorAction 方法
state.realTimePicTimer =
Timer.periodic(const Duration(seconds: 1), (timer) {
state.elapsedSeconds++;
logic.udpMonitorAction();
// 检查条件如果达到30秒且未得到应答则认为失败
if (state.elapsedSeconds >= 30) {
state.realTimePicTimer.cancel(); // 取消定时器
_handleFailure();
}
});
}
@override
Widget build(BuildContext context) {
return SizedBox(
width: 1.sw,
height: 1.sh,
child: Stack(
alignment: Alignment.center,
children: [
Obx(
() =>
state.listData.value.isEmpty || state.listData.value.length == 0
? Image.asset(
'images/main/monitorBg.png',
width: ScreenUtil().screenWidth,
height: ScreenUtil().screenHeight,
fit: BoxFit.cover,
)
: Builder(
builder: (BuildContext context) {
try {
return Image.memory(
state.listData.value,
gaplessPlayback: true,
width: 1.sw,
height: 1.sh,
fit: BoxFit.cover,
);
} catch (e, stackTrace) {
print('Error loading image: $e');
print('Stack trace: $stackTrace');
return Container();
}
},
),
),
Obx(() => state.listData.value.isEmpty
? Positioned(
bottom: 300.h,
child: Text(
'正在创建安全连接...',
style: TextStyle(color: Colors.black, fontSize: 26.sp),
))
: Container()),
Positioned(
bottom: 10.w,
child: Container(
width: 1.sw - 30.w * 2,
// height: 300.h,
margin: EdgeInsets.all(30.w),
decoration: BoxDecoration(
color: Colors.black.withOpacity(0.2),
borderRadius: BorderRadius.circular(20.h)),
child: Column(
children: [
SizedBox(height: 20.h),
bottomTopBtnWidget(),
SizedBox(height: 20.h),
bottomBottomBtnWidget(),
SizedBox(height: 20.h),
],
),
)),
Obx(() => state.listData.value.isEmpty
? buildRotationTransition()
: Container())
],
),
);
}
Widget bottomTopBtnWidget() {
return Row(mainAxisAlignment: MainAxisAlignment.center, children: [
// 打开关闭声音
GestureDetector(
onTap: () {
state.isOpenVoice.value = !state.isOpenVoice.value;
},
child: Container(
width: 50.w,
height: 50.w,
padding: EdgeInsets.all(5.w),
child: Obx(() => Image(
width: 40.w,
height: 40.w,
image: state.isOpenVoice.value
? const AssetImage(
"images/main/icon_lockDetail_monitoringCloseVoice.png")
: const AssetImage(
"images/main/icon_lockDetail_monitoringOpenVoice.png"))),
),
),
SizedBox(width: 60.w),
// 截图
GestureDetector(
onTap: () {
// Get.toNamed(Routers.monitoringRealTimeScreenPage);
},
child: Container(
width: 50.w,
height: 50.w,
padding: EdgeInsets.all(5.w),
child: Image(
width: 40.w,
height: 40.w,
image: const AssetImage(
"images/main/icon_lockDetail_monitoringScreenshot.png")),
),
),
SizedBox(width: 60.w),
// 录制
GestureDetector(
onTap: () {
// Get.toNamed(Routers.monitoringRealTimeScreenPage);
},
child: Container(
width: 50.w,
height: 50.w,
padding: EdgeInsets.all(5.w),
child: Image(
width: 40.w,
height: 40.w,
image: const AssetImage(
"images/main/icon_lockDetail_monitoringScreenRecording.png")),
),
),
]);
}
Widget bottomBottomBtnWidget() {
return Row(mainAxisAlignment: MainAxisAlignment.spaceEvenly, children: [
// 接听
Obx(() => bottomBtnItemWidget(
getAnswerBtnImg(), getAnswerBtnName(), Colors.white, () async {
//监视状态下不能发送录音
logic.showToast("监视状态下不能发送录音");
}, longPress: () async {
/*
// 开始长按
print("onLongPress");
//获取麦克风权限
await logic.getPermissionStatus().then((value) async {
if (!value) {
return;
}
// state.isSenderAudioData.value = false;
});
state.listAudioData.value = <int>[];
if (state.udpStatus.value == 8) {
state.udpStatus.value = 9;
}
// logic.readG711Data();
logic.startProcessing();
*/
}, longPressUp: () async {
/*
// 长按结束
print("onLongPressUp");
if (state.udpStatus.value == 9) {
state.udpStatus.value = 8;
}
*/
})),
bottomBtnItemWidget(
"images/main/icon_lockDetail_hangUp.png", "挂断", Colors.red, () async {
// 挂断
logic.udpHangUpAction();
CallTalk().stopPcmSound();
Get.back();
}),
bottomBtnItemWidget("images/main/icon_lockDetail_monitoringUnlock.png",
"开锁", AppColors.mainColor, () {
logic.showToast("监视中暂不能开锁");
/*
showDeletPasswordAlertDialog(context);
*/
})
]);
}
String getAnswerBtnImg() {
switch (state.udpStatus.value) {
case 8:
return "images/main/icon_lockDetail_monitoringUnTalkback.png";
case 9:
return "images/main/icon_lockDetail_monitoringTalkback.png";
default:
return "images/main/icon_lockDetail_monitoringUnTalkback.png";
}
}
String getAnswerBtnName() {
switch (state.udpStatus.value) {
case 8:
return "长按说话";
case 9:
return "松开发送";
default:
return "长按说话";
}
}
Widget bottomBtnItemWidget(
String iconUrl, String name, Color backgroundColor, Function() onClick,
{Function()? longPress, Function()? longPressUp}) {
var wh = 80.w;
return GestureDetector(
onTap: onClick,
onLongPress: longPress,
onLongPressUp: longPressUp,
child: SizedBox(
height: 140.h,
child: Column(
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Container(
width: wh,
height: wh,
decoration: BoxDecoration(
color: backgroundColor,
borderRadius: BorderRadius.circular((wh + 10.w * 2) / 2)),
padding: EdgeInsets.all(20.w),
child: Image.asset(iconUrl, fit: BoxFit.fitWidth),
),
SizedBox(height: 20.w),
Expanded(
child: Text(name,
style: TextStyle(fontSize: 20.sp, color: Colors.white),
textAlign: TextAlign.center))
],
)),
);
}
void showDeletPasswordAlertDialog(BuildContext context) {
showDialog(
barrierDismissible: false,
context: context,
builder: (BuildContext context) {
return ShowTFView(
title: "请输入六位数字开锁密码",
tipTitle: "",
controller: state.passwordTF,
inputFormatters: [
LengthLimitingTextInputFormatter(6), //限制长度
FilteringTextInputFormatter.allow(RegExp("[0-9]")),
],
sureClick: () async {
//发送删除锁请求
if (state.passwordTF.text.isEmpty) {
logic.showToast("请输入开锁密码");
return;
}
// List<int> numbers = state.passwordTF.text.split('').map((char) => int.parse(char)).toList();
// 开锁
// lockID
List<int> numbers = [];
List<int> lockIDData = utf8.encode(state.passwordTF.text);
numbers.addAll(lockIDData);
// topBytes = getFixedLengthList(lockIDData, 20 - lockIDData.length);
for (int i = 0; i < 6 - lockIDData.length; i++) {
numbers.add(0);
}
print("numbersnumbersnumbers:$numbers");
logic.udpOpenDoorAction(numbers);
},
cancelClick: () {
Get.back();
},
);
},
);
}
//旋转动画
Widget buildRotationTransition() {
return Positioned(
left: ScreenUtil().screenWidth / 2 - 220.w / 2,
top: ScreenUtil().screenHeight / 2 - 220.w / 2 - 150.h,
child: GestureDetector(
child: RotationTransition(
//设置动画的旋转中心
alignment: Alignment.center,
//动画控制器
turns: state.animationController,
//将要执行动画的子view
child: AnimatedOpacity(
opacity: 0.5,
duration: const Duration(seconds: 2),
child: Image.asset(
'images/main/realTime_connecting.png',
width: 220.w,
height: 220.w,
),
),
),
onTap: () {
state.animationController.forward();
initiateUdpMonitorAction();
},
),
);
}
void _handleFailure() {
// 在这里处理失败的逻辑
CallTalk().stopPcmSound();
state.realTimePicTimer.cancel();
state.autoBackTimer.cancel();
if (state.animationController != null) {
state.animationController.stop();
}
}
@override
void dispose() {
state.animationController.dispose();
state.realTimePicTimer.cancel();
state.autoBackTimer.cancel();
CallTalk().stopPcmSound();
super.dispose();
}
}