fix: 增加日志
This commit is contained in:
parent
41aea1d1bf
commit
f6e900aaad
@ -1,4 +1,3 @@
|
||||
|
||||
import 'dart:async';
|
||||
|
||||
import 'package:star_lock/blue/entity/lock_user_no_list_entity.dart';
|
||||
@ -22,10 +21,10 @@ import 'io_tool/manager_event_bus.dart';
|
||||
import 'sender_data.dart';
|
||||
|
||||
class SenderBeforeDataManage {
|
||||
|
||||
factory SenderBeforeDataManage() => shareManager()!;
|
||||
|
||||
SenderBeforeDataManage._init();
|
||||
|
||||
static SenderBeforeDataManage? _manager;
|
||||
|
||||
static SenderBeforeDataManage? shareManager() {
|
||||
@ -42,6 +41,7 @@ class SenderBeforeDataManage {
|
||||
|
||||
// 监听设备返回的数据
|
||||
StreamSubscription<Reply>? _replySubscription;
|
||||
|
||||
// 是否是添加用户之前的调用
|
||||
bool isBeforeAddUser = true;
|
||||
|
||||
@ -123,14 +123,14 @@ class SenderBeforeDataManage {
|
||||
final int status = reply.data[6];
|
||||
switch (status) {
|
||||
case 0x00:
|
||||
//成功
|
||||
//成功
|
||||
CommonDataManage().initUserNo = 0;
|
||||
CommonDataManage().currentKeyInfo.initUserNo = 0;
|
||||
|
||||
_updateLockInitUserNo();
|
||||
break;
|
||||
case 0x06:
|
||||
//无权限
|
||||
//无权限
|
||||
final List<int> token = reply.data.sublist(2, 6);
|
||||
final List<String> strTokenList = changeIntListToStringList(token);
|
||||
Storage.setStringList(saveBlueToken, strTokenList);
|
||||
@ -139,17 +139,15 @@ class SenderBeforeDataManage {
|
||||
CommandSenderManager().sendNormalData(transferSmartLockData);
|
||||
break;
|
||||
default:
|
||||
//失败
|
||||
//失败
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
//获取清除用户列表指令
|
||||
Future<List<int>> getCleanUpUsers({List<int>? tokenList}) async {
|
||||
final LockUserNoListEntity entity = await ApiRepository.to
|
||||
.getLockUserNoList(lockId: CommonDataManage().currentKeyInfo.lockId!);
|
||||
if (!entity.errorCode!.codeIsSuccessful ||
|
||||
(entity.data?.userNos ?? <int>[]).isEmpty) {
|
||||
final LockUserNoListEntity entity = await ApiRepository.to.getLockUserNoList(lockId: CommonDataManage().currentKeyInfo.lockId!);
|
||||
if (!entity.errorCode!.codeIsSuccessful || (entity.data?.userNos ?? <int>[]).isEmpty) {
|
||||
throw Exception('ApiRepository.to.getLockUserNoList 访问失败');
|
||||
}
|
||||
final List<String>? privateKey = await Storage.getStringList(saveBluePrivateKey);
|
||||
@ -197,27 +195,28 @@ class SenderBeforeDataManage {
|
||||
int endDateTime = 0;
|
||||
bool isRound = false;
|
||||
int useCountLimit = 0xffff;
|
||||
if(currentKeyInfo.keyType == XSConstantMacro.keyTypeTime){
|
||||
if (currentKeyInfo.keyType == XSConstantMacro.keyTypeTime) {
|
||||
// 限时
|
||||
startDateTime = currentKeyInfo.startDate! ~/ 1000;
|
||||
endDateTime = currentKeyInfo.endDate! ~/ 1000;
|
||||
}else if(currentKeyInfo.keyType == XSConstantMacro.keyTypeLoop){
|
||||
} else if (currentKeyInfo.keyType == XSConstantMacro.keyTypeLoop) {
|
||||
// 循环
|
||||
isRound = true;
|
||||
startTime = DateTime.fromMillisecondsSinceEpoch(currentKeyInfo.startDate!);
|
||||
endTime = DateTime.fromMillisecondsSinceEpoch(currentKeyInfo.endDate!);
|
||||
|
||||
startDateTime = DateTool().dateToTimestamp(DateTool().dateToYMDString(currentKeyInfo.startDate!.toString()), 1) ~/ 1000;
|
||||
endDateTime = (DateTool().dateToTimestamp(DateTool().dateToYMDString(currentKeyInfo.endDate!.toString()), 1) + CommonDataManage().dayLatestTime) ~/ 1000;
|
||||
}else if(currentKeyInfo.keyType == XSConstantMacro.keyTypeOnce){
|
||||
// 单次
|
||||
useCountLimit = 1;
|
||||
}
|
||||
endDateTime =
|
||||
(DateTool().dateToTimestamp(DateTool().dateToYMDString(currentKeyInfo.endDate!.toString()), 1) + CommonDataManage().dayLatestTime) ~/ 1000;
|
||||
} else if (currentKeyInfo.keyType == XSConstantMacro.keyTypeOnce) {
|
||||
// 单次
|
||||
useCountLimit = 1;
|
||||
}
|
||||
|
||||
// AppLog.log("startTime.hour:${startTime!.hour} startTime.minute:${startTime!.minute} endTime.hour:${endTime!.hour} endTime.minute:${endTime!.minute}}");
|
||||
// AppLog.log("startTime.hour:${startTime!.hour} startTime.minute:${startTime!.minute} endTime.hour:${endTime!.hour} endTime.minute:${endTime!.minute}}");
|
||||
final AddUserCommand addUserData = AddUserCommand(
|
||||
lockID: BlueManage().connectDeviceName,
|
||||
authUserID: currentKeyInfo.senderUserId!.toString(),
|
||||
authUserID: currentKeyInfo.senderUserId?.toString() ?? '1',
|
||||
keyID: currentKeyInfo.keyId.toString(),
|
||||
userID: await Storage.getUid(),
|
||||
openMode: 1,
|
||||
@ -226,10 +225,7 @@ class SenderBeforeDataManage {
|
||||
expireDate: endDateTime,
|
||||
useCountLimit: useCountLimit,
|
||||
isRound: isRound ? 1 : 0,
|
||||
weekRound: isRound
|
||||
? DateTool().accordingTheCycleIntoTheCorrespondingNumber(
|
||||
currentKeyInfo.weekDays!)
|
||||
: 0,
|
||||
weekRound: isRound ? DateTool().accordingTheCycleIntoTheCorrespondingNumber(currentKeyInfo.weekDays!) : 0,
|
||||
startHour: isRound ? startTime!.hour : 0,
|
||||
startMin: isRound ? startTime!.minute : 0,
|
||||
endHour: isRound ? endTime!.hour : 0,
|
||||
@ -271,8 +267,7 @@ class SenderBeforeDataManage {
|
||||
// 普通用户接收电子钥匙之后 更新锁用户NO
|
||||
Future<void> _updateLockUserNo(List<int> dataList) async {
|
||||
final LockNetTokenEntity entity = await ApiRepository.to.updateLockUserNo(
|
||||
keyId: CommonDataManage().currentKeyInfo.keyId.toString(),
|
||||
lockUserNo: CommonDataManage().currentKeyInfo.lockUserNo.toString());
|
||||
keyId: CommonDataManage().currentKeyInfo.keyId.toString(), lockUserNo: CommonDataManage().currentKeyInfo.lockUserNo.toString());
|
||||
if (entity.errorCode!.codeIsSuccessful) {
|
||||
eventBus.fire(RefreshLockListInfoDataEvent());
|
||||
eventBus.fire(LockAddUserSucceedEvent(<int>[0], 0));
|
||||
@ -281,9 +276,8 @@ class SenderBeforeDataManage {
|
||||
|
||||
// 更新锁用户InitUserNo
|
||||
Future<void> _updateLockInitUserNo() async {
|
||||
final LockNetTokenEntity entity = await ApiRepository.to.updateLockInitUserNo(
|
||||
lockId: CommonDataManage().currentKeyInfo.lockId ?? 0,
|
||||
initUserNo: CommonDataManage().currentKeyInfo.initUserNo ?? 0);
|
||||
final LockNetTokenEntity entity = await ApiRepository.to
|
||||
.updateLockInitUserNo(lockId: CommonDataManage().currentKeyInfo.lockId ?? 0, initUserNo: CommonDataManage().currentKeyInfo.initUserNo ?? 0);
|
||||
if (entity.errorCode!.codeIsSuccessful) {
|
||||
eventBus.fire(RefreshLockListInfoDataEvent());
|
||||
eventBus.fire(LockInitUserNoEvent());
|
||||
|
||||
@ -88,17 +88,18 @@ class LockListLogic extends BaseGetXController {
|
||||
break;
|
||||
case 0x06:
|
||||
//无权限
|
||||
final List<String>? token = await Storage.getStringList(saveBlueToken);
|
||||
final List<int> getTokenList = changeStringListToIntList(token!);
|
||||
|
||||
final List<int> tokenData = reply.data.sublist(2, 6);
|
||||
final List<String> saveStrList = changeIntListToStringList(tokenData);
|
||||
Storage.setStringList(saveBlueToken, saveStrList);
|
||||
IoSenderManage.senderFactoryDataReset(
|
||||
lockID: BlueManage().connectDeviceName,
|
||||
userID: await Storage.getUid(),
|
||||
keyID: '1',
|
||||
needAuthor: 1,
|
||||
publicKey: state.lockListInfoItemEntity.value.bluetooth!.publicKey!.cast<int>(),
|
||||
privateKey: state.lockListInfoItemEntity.value.bluetooth!.privateKey!.cast<int>(),
|
||||
token: getTokenList);
|
||||
lockID: BlueManage().connectDeviceName,
|
||||
userID: await Storage.getUid(),
|
||||
keyID: '1',
|
||||
needAuthor: 1,
|
||||
publicKey: state.publicKey,
|
||||
privateKey: state.privateKey,
|
||||
token: tokenData,
|
||||
);
|
||||
break;
|
||||
case 0x07:
|
||||
//无权限
|
||||
@ -172,14 +173,14 @@ class LockListLogic extends BaseGetXController {
|
||||
}
|
||||
|
||||
/// 以下为删除逻辑
|
||||
void deleyLockLogicOfRoles() {
|
||||
void deleyLockLogicOfRoles(LockListInfoItemEntity keyInfo) {
|
||||
if (state.lockListInfoItemEntity.value.isLockOwner == 1) {
|
||||
// 超级管理员必须通过连接蓝牙删除
|
||||
showTipView.showIosTipWithContentDialog('删除锁后,所有信息都会一起删除,确定删除锁吗?'.tr, () {
|
||||
// 删除锁
|
||||
AppLog.log('调用了删除锁');
|
||||
showTipView.resetGetController();
|
||||
showTipView.showTFViewAlertDialog(state.passwordTF, '请输入登录密码'.tr, '请输入登录密码'.tr, checkLoginPassword);
|
||||
showTipView.showTFViewAlertDialog(state.passwordTF, '请输入登录密码'.tr, '请输入登录密码'.tr, () => checkLoginPassword(keyInfo));
|
||||
});
|
||||
} else if (state.lockListInfoItemEntity.value.keyRight == 1) {
|
||||
// 授权管理员弹框提示
|
||||
@ -195,13 +196,13 @@ class LockListLogic extends BaseGetXController {
|
||||
}
|
||||
|
||||
// 查询账户密码
|
||||
Future<void> checkLoginPassword() async {
|
||||
Future<void> checkLoginPassword(LockListInfoItemEntity keyInfo) async {
|
||||
final LockListInfoEntity entity = await ApiRepository.to.checkLoginPassword(
|
||||
password: state.passwordTF.text,
|
||||
);
|
||||
if (entity.errorCode!.codeIsSuccessful) {
|
||||
Get.back();
|
||||
factoryDataResetAction();
|
||||
factoryDataResetAction(keyInfo);
|
||||
}
|
||||
}
|
||||
|
||||
@ -233,7 +234,7 @@ class LockListLogic extends BaseGetXController {
|
||||
}
|
||||
|
||||
// 恢复出厂设置
|
||||
Future<void> factoryDataResetAction() async {
|
||||
Future<void> factoryDataResetAction(LockListInfoItemEntity keyInfo) async {
|
||||
showEasyLoading();
|
||||
showBlueConnetctToastTimer(
|
||||
isShowBlueConnetctToast: false,
|
||||
@ -241,15 +242,13 @@ class LockListLogic extends BaseGetXController {
|
||||
dismissEasyLoading();
|
||||
showDeletAlertTipDialog();
|
||||
});
|
||||
BlueManage().blueSendData(state.lockListInfoItemEntity.value.lockName!, (BluetoothConnectionState connectionState)
|
||||
async {
|
||||
BlueManage().blueSendData(state.lockListInfoItemEntity.value.lockName!, (BluetoothConnectionState connectionState) async {
|
||||
if (connectionState == BluetoothConnectionState.connected) {
|
||||
final List<int> publicKeyData = state.lockListInfoItemEntity.value.bluetooth!.publicKey!.cast<int>();
|
||||
final List<String> saveStrList = changeIntListToStringList(publicKeyData);
|
||||
await Storage.setStringList(saveBluePublicKey, saveStrList);
|
||||
|
||||
// 私钥
|
||||
final List<String>? privateKey = await Storage.getStringList(saveBluePrivateKey);
|
||||
final List<int> privateKeyData = state.lockListInfoItemEntity.value.bluetooth!.privateKey!.cast<int>();
|
||||
final List<String> savePrivateKeyList = changeIntListToStringList(privateKeyData);
|
||||
await Storage.setStringList(saveBluePrivateKey, savePrivateKeyList);
|
||||
@ -262,15 +261,18 @@ class LockListLogic extends BaseGetXController {
|
||||
final List<String> saveTokenList = changeIntListToStringList(<int>[0, 0, 0, 0]);
|
||||
await Storage.setStringList(saveBlueToken, saveTokenList);
|
||||
|
||||
|
||||
IoSenderManage.senderFactoryDataReset(
|
||||
lockID: BlueManage().connectDeviceName,
|
||||
userID: await Storage.getUid(),
|
||||
keyID: '1',
|
||||
needAuthor: 1,
|
||||
publicKey: publicKeyData,
|
||||
privateKey: privateKeyData,
|
||||
publicKey: keyInfo.bluetooth?.publicKey ?? [],
|
||||
privateKey: keyInfo.bluetooth?.privateKey ?? [],
|
||||
token: <int>[0, 0, 0, 0]);
|
||||
state.publicKey.value = keyInfo.bluetooth?.publicKey ?? [];
|
||||
state.privateKey.value = keyInfo.bluetooth?.privateKey ?? [];
|
||||
state.publicKey.refresh();
|
||||
state.privateKey.refresh();
|
||||
} else if (connectionState == BluetoothConnectionState.disconnected) {
|
||||
dismissEasyLoading();
|
||||
cancelBlueConnetctToastTimer();
|
||||
|
||||
@ -2,6 +2,7 @@ import 'package:flutter/material.dart';
|
||||
import 'package:flutter_screenutil/flutter_screenutil.dart';
|
||||
import 'package:flutter_slidable/flutter_slidable.dart';
|
||||
import 'package:get/get.dart';
|
||||
import 'package:star_lock/app_settings/app_settings.dart';
|
||||
import 'package:star_lock/main/lockMian/lockList/lockList_state.dart';
|
||||
|
||||
import '../../../appRouters.dart';
|
||||
@ -14,8 +15,7 @@ import 'lockListGroup_view.dart';
|
||||
import 'lockList_logic.dart';
|
||||
|
||||
class LockListPage extends StatefulWidget {
|
||||
const LockListPage({required this.lockListInfoGroupEntity, Key? key})
|
||||
: super(key: key);
|
||||
const LockListPage({required this.lockListInfoGroupEntity, Key? key}) : super(key: key);
|
||||
final LockListInfoGroupEntity lockListInfoGroupEntity;
|
||||
|
||||
@override
|
||||
@ -30,41 +30,41 @@ class _LockListPageState extends State<LockListPage> with RouteAware {
|
||||
void initState() {
|
||||
super.initState();
|
||||
logic = Get.put(LockListLogic(widget.lockListInfoGroupEntity));
|
||||
state = Get
|
||||
.find<LockListLogic>()
|
||||
.state;
|
||||
state = Get.find<LockListLogic>().state;
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Obx(() => Scaffold(
|
||||
body: ListView.separated(
|
||||
itemCount: logic.groupDataListFiltered.length,
|
||||
itemBuilder: (BuildContext context, int index) {
|
||||
final GroupList itemData = logic.groupDataListFiltered[index];
|
||||
return _buildLockExpandedList(context, index, itemData, key: ValueKey(itemData.groupId));
|
||||
},
|
||||
shrinkWrap: true,
|
||||
physics: const AlwaysScrollableScrollPhysics(),
|
||||
separatorBuilder: (BuildContext context, int index) {
|
||||
return const Divider(
|
||||
height: 1,
|
||||
color: AppColors.greyLineColor,
|
||||
);
|
||||
}),
|
||||
));
|
||||
return Obx(
|
||||
() => Scaffold(
|
||||
body: ListView.separated(
|
||||
itemCount: logic.groupDataList.length,
|
||||
itemBuilder: (BuildContext context, int index) {
|
||||
final GroupList itemData = logic.groupDataListFiltered[index];
|
||||
return _buildLockExpandedList(context, index, itemData, key: ValueKey(itemData.groupId));
|
||||
},
|
||||
shrinkWrap: true,
|
||||
physics: const AlwaysScrollableScrollPhysics(),
|
||||
separatorBuilder: (BuildContext context, int index) {
|
||||
return const Divider(
|
||||
height: 1,
|
||||
color: AppColors.greyLineColor,
|
||||
);
|
||||
},
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
//设备多层级列表
|
||||
Widget _buildLockExpandedList(BuildContext context, int index,
|
||||
GroupList itemData, {Key? key}) {
|
||||
final List<LockListInfoItemEntity> lockItemList =
|
||||
itemData.lockList ?? <LockListInfoItemEntity>[];
|
||||
Widget _buildLockExpandedList(BuildContext context, int index, GroupList itemData, {Key? key}) {
|
||||
final List<LockListInfoItemEntity> lockItemList = itemData.lockList ?? <LockListInfoItemEntity>[];
|
||||
return LockListGroupView(
|
||||
key: key,
|
||||
onTap: () {
|
||||
//是否选中组
|
||||
if (itemData.isChecked) {} else {}
|
||||
if (itemData.isChecked) {
|
||||
} else {}
|
||||
setState(() {});
|
||||
},
|
||||
typeImgList: const <dynamic>[],
|
||||
@ -91,9 +91,12 @@ class _LockListPageState extends State<LockListPage> with RouteAware {
|
||||
children: <Widget>[
|
||||
SlidableAction(
|
||||
onPressed: (BuildContext context) {
|
||||
state.publicKey.value = keyInfo.bluetooth?.publicKey ?? [];
|
||||
state.privateKey.value = keyInfo.bluetooth?.privateKey ?? [];
|
||||
state.lockListInfoItemEntity.value = keyInfo;
|
||||
state.lockListInfoItemEntity.refresh();
|
||||
logic.deleyLockLogicOfRoles();
|
||||
AppLog.log('msg=================:${state.lockListInfoItemEntity.value}');
|
||||
logic.deleyLockLogicOfRoles(keyInfo);
|
||||
},
|
||||
backgroundColor: Colors.red,
|
||||
foregroundColor: Colors.white,
|
||||
@ -103,58 +106,46 @@ class _LockListPageState extends State<LockListPage> with RouteAware {
|
||||
],
|
||||
),
|
||||
child: lockInfoListItem(keyInfo, isLast, () {
|
||||
if ((keyInfo.keyType == XSConstantMacro.keyTypeTime ||
|
||||
keyInfo.keyType == XSConstantMacro.keyTypeLoop) &&
|
||||
(keyInfo.keyStatus ==
|
||||
XSConstantMacro.keyStatusWaitIneffective)) {
|
||||
if ((keyInfo.keyType == XSConstantMacro.keyTypeTime || keyInfo.keyType == XSConstantMacro.keyTypeLoop) &&
|
||||
(keyInfo.keyStatus == XSConstantMacro.keyStatusWaitIneffective)) {
|
||||
logic.showToast('您的钥匙未生效'.tr);
|
||||
return;
|
||||
}
|
||||
if ((keyInfo.keyType == XSConstantMacro.keyTypeTime ||
|
||||
keyInfo.keyType == XSConstantMacro.keyTypeLong ||
|
||||
keyInfo.keyType == XSConstantMacro.keyTypeLoop) &&
|
||||
keyInfo.keyType == XSConstantMacro.keyTypeLong ||
|
||||
keyInfo.keyType == XSConstantMacro.keyTypeLoop) &&
|
||||
(keyInfo.keyStatus == XSConstantMacro.keyStatusFrozen)) {
|
||||
logic.showToast('您的钥匙已冻结'.tr);
|
||||
return;
|
||||
}
|
||||
if ((keyInfo.keyType == XSConstantMacro.keyTypeTime ||
|
||||
keyInfo.keyType == XSConstantMacro.keyTypeLoop) &&
|
||||
if ((keyInfo.keyType == XSConstantMacro.keyTypeTime || keyInfo.keyType == XSConstantMacro.keyTypeLoop) &&
|
||||
(keyInfo.keyStatus == XSConstantMacro.keyStatusExpired)) {
|
||||
logic.showToast('您的钥匙已过期'.tr);
|
||||
return;
|
||||
}
|
||||
Get.toNamed(Routers.lockDetailMainPage,
|
||||
arguments: <String, Object>{
|
||||
// "lockMainEntity": widget.lockMainEntity,
|
||||
'keyInfo': keyInfo,
|
||||
'isOnlyOneData': false,
|
||||
});
|
||||
Get.toNamed(Routers.lockDetailMainPage, arguments: <String, Object>{
|
||||
// "lockMainEntity": widget.lockMainEntity,
|
||||
'keyInfo': keyInfo,
|
||||
'isOnlyOneData': false,
|
||||
});
|
||||
}),
|
||||
);
|
||||
}),
|
||||
);
|
||||
}
|
||||
|
||||
Widget lockInfoListItem(LockListInfoItemEntity keyInfo, bool isLast,
|
||||
Function() action) {
|
||||
Widget lockInfoListItem(LockListInfoItemEntity keyInfo, bool isLast, Function() action) {
|
||||
return GestureDetector(
|
||||
onTap: action,
|
||||
child: Container(
|
||||
// height: 122.h,
|
||||
margin: isLast
|
||||
? EdgeInsets.only(left: 20.w, right: 20.w, top: 20.w, bottom: 20.w)
|
||||
: EdgeInsets.only(left: 20.w, right: 20.w, top: 20.w),
|
||||
margin: isLast ? EdgeInsets.only(left: 20.w, right: 20.w, top: 20.w, bottom: 20.w) : EdgeInsets.only(left: 20.w, right: 20.w, top: 20.w),
|
||||
decoration: BoxDecoration(
|
||||
color: (((keyInfo.keyType == XSConstantMacro.keyTypeTime ||
|
||||
keyInfo.keyType == XSConstantMacro.keyTypeLoop) &&
|
||||
(keyInfo.keyStatus ==
|
||||
XSConstantMacro.keyStatusWaitIneffective ||
|
||||
keyInfo.keyStatus ==
|
||||
XSConstantMacro.keyStatusFrozen ||
|
||||
keyInfo.keyStatus ==
|
||||
XSConstantMacro.keyStatusExpired)) ||
|
||||
(keyInfo.keyType == XSConstantMacro.keyTypeLong &&
|
||||
keyInfo.keyStatus == XSConstantMacro.keyStatusFrozen))
|
||||
color: (((keyInfo.keyType == XSConstantMacro.keyTypeTime || keyInfo.keyType == XSConstantMacro.keyTypeLoop) &&
|
||||
(keyInfo.keyStatus == XSConstantMacro.keyStatusWaitIneffective ||
|
||||
keyInfo.keyStatus == XSConstantMacro.keyStatusFrozen ||
|
||||
keyInfo.keyStatus == XSConstantMacro.keyStatusExpired)) ||
|
||||
(keyInfo.keyType == XSConstantMacro.keyTypeLong && keyInfo.keyStatus == XSConstantMacro.keyStatusFrozen))
|
||||
? AppColors.greyBackgroundColor
|
||||
: Colors.white,
|
||||
borderRadius: BorderRadius.circular(20.w),
|
||||
@ -178,9 +169,7 @@ class _LockListPageState extends State<LockListPage> with RouteAware {
|
||||
style: TextStyle(
|
||||
fontSize: 24.sp,
|
||||
fontWeight: FontWeight.w500,
|
||||
color: keyInfo.passageMode == 1
|
||||
? AppColors.openPassageModeColor
|
||||
: AppColors.darkGrayTextColor),
|
||||
color: keyInfo.passageMode == 1 ? AppColors.openPassageModeColor : AppColors.darkGrayTextColor),
|
||||
),
|
||||
],
|
||||
),
|
||||
@ -194,8 +183,7 @@ class _LockListPageState extends State<LockListPage> with RouteAware {
|
||||
SizedBox(width: 2.w),
|
||||
Text(
|
||||
'${keyInfo.electricQuantity!}%',
|
||||
style: TextStyle(
|
||||
fontSize: 18.sp, color: AppColors.darkGrayTextColor),
|
||||
style: TextStyle(fontSize: 18.sp, color: AppColors.darkGrayTextColor),
|
||||
),
|
||||
SizedBox(width: 30.w),
|
||||
],
|
||||
@ -212,10 +200,7 @@ class _LockListPageState extends State<LockListPage> with RouteAware {
|
||||
borderRadius: BorderRadius.circular(5.w),
|
||||
color: AppColors.openPassageModeColor,
|
||||
),
|
||||
child: Text('常开模式开启'.tr,
|
||||
style: TextStyle(
|
||||
fontSize: 18.sp,
|
||||
color: AppColors.appBarIconColor)),
|
||||
child: Text('常开模式开启'.tr, style: TextStyle(fontSize: 18.sp, color: AppColors.appBarIconColor)),
|
||||
),
|
||||
],
|
||||
)),
|
||||
@ -227,8 +212,7 @@ class _LockListPageState extends State<LockListPage> with RouteAware {
|
||||
SizedBox(width: 30.w),
|
||||
Text(
|
||||
'远程开锁'.tr,
|
||||
style: TextStyle(
|
||||
fontSize: 18.sp, color: AppColors.darkGrayTextColor),
|
||||
style: TextStyle(fontSize: 18.sp, color: AppColors.darkGrayTextColor),
|
||||
),
|
||||
],
|
||||
)),
|
||||
@ -242,15 +226,11 @@ class _LockListPageState extends State<LockListPage> with RouteAware {
|
||||
padding: EdgeInsets.only(right: 5.w, left: 5.w),
|
||||
decoration: BoxDecoration(
|
||||
borderRadius: BorderRadius.circular(5.w),
|
||||
color:
|
||||
DateTool().compareTimeIsOvertime(keyInfo.endDate!)
|
||||
? AppColors.listTimeYellowColor
|
||||
: AppColors.mainColor,
|
||||
),
|
||||
child: Text(logic.getKeyEffective(keyInfo),
|
||||
style: TextStyle(fontSize: 18.sp, color: Colors.white)
|
||||
// child: Text(logic.compareTimeIsOvertime(keyInfo.endDate!) ? "已过期" : "余${logic.compareTimeGetDaysFromNow(keyInfo.endDate!)}天", style: TextStyle(fontSize: 18.sp, color: Colors.white)
|
||||
color: DateTool().compareTimeIsOvertime(keyInfo.endDate!) ? AppColors.listTimeYellowColor : AppColors.mainColor,
|
||||
),
|
||||
child: Text(logic.getKeyEffective(keyInfo), style: TextStyle(fontSize: 18.sp, color: Colors.white)
|
||||
// child: Text(logic.compareTimeIsOvertime(keyInfo.endDate!) ? "已过期" : "余${logic.compareTimeGetDaysFromNow(keyInfo.endDate!)}天", style: TextStyle(fontSize: 18.sp, color: Colors.white)
|
||||
),
|
||||
),
|
||||
],
|
||||
)),
|
||||
@ -259,13 +239,8 @@ class _LockListPageState extends State<LockListPage> with RouteAware {
|
||||
children: <Widget>[
|
||||
SizedBox(width: 30.w),
|
||||
Text(
|
||||
"${logic.getUseKeyTypeStr(keyInfo.startDate, keyInfo.endDate,
|
||||
keyInfo.keyType)}/${keyInfo.isLockOwner == 1
|
||||
? '超级管理员'.tr
|
||||
: (keyInfo.keyRight == 1 ? "授权管理员".tr : "普通用户"
|
||||
.tr)}",
|
||||
style: TextStyle(
|
||||
fontSize: 18.sp, color: AppColors.darkGrayTextColor),
|
||||
"${logic.getUseKeyTypeStr(keyInfo.startDate, keyInfo.endDate, keyInfo.keyType)}/${keyInfo.isLockOwner == 1 ? '超级管理员'.tr : (keyInfo.keyRight == 1 ? "授权管理员".tr : "普通用户".tr)}",
|
||||
style: TextStyle(fontSize: 18.sp, color: AppColors.darkGrayTextColor),
|
||||
),
|
||||
],
|
||||
),
|
||||
@ -287,13 +262,10 @@ class _LockListPageState extends State<LockListPage> with RouteAware {
|
||||
@override
|
||||
void dispose() {
|
||||
Get.delete<LockListLogic>();
|
||||
|
||||
/// 取消路由订阅
|
||||
AppRouteObserver().routeObserver.unsubscribe(this);
|
||||
super
|
||||
.
|
||||
dispose
|
||||
(
|
||||
);
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
/// 从上级界面进入 当前界面即将出现
|
||||
|
||||
@ -14,5 +14,7 @@ class LockListState{
|
||||
RxBool ifCurrentScreen = true.obs; // 是否是当前界面,用于判断是否需要针对当前界面进行展示
|
||||
RxBool showSearch = false.obs; // 是否是当前界面,用于判断是否需要针对当前界面进行展示
|
||||
RxString searchStr = ''.obs; // 是否是当前界面,用于判断是否需要针对当前界面进行展示
|
||||
RxList<int> publicKey=<int>[].obs;
|
||||
RxList<int> privateKey=<int>[].obs;
|
||||
|
||||
}
|
||||
@ -194,7 +194,7 @@ class _LockListXHJPageState extends State<LockListXHJPage> with RouteAware {
|
||||
onPressed: (BuildContext context) {
|
||||
state.lockListInfoItemEntity.value = keyInfo;
|
||||
state.lockListInfoItemEntity.refresh();
|
||||
logic.deleyLockLogicOfRoles();
|
||||
logic.deleyLockLogicOfRoles(keyInfo);
|
||||
},
|
||||
backgroundColor: Colors.red,
|
||||
foregroundColor: Colors.white,
|
||||
|
||||
@ -36,7 +36,7 @@ class UdpTalkDataHandler extends ScpMessageBaseHandle implements ScpMessageHandl
|
||||
|
||||
if (scpMessage.Payload != null) {
|
||||
final TalkData talkData = scpMessage.Payload;
|
||||
AppLog.log('收到数据');
|
||||
|
||||
_handleTalkData(
|
||||
talkData: talkData,
|
||||
scpMessage: scpMessage,
|
||||
|
||||
@ -104,10 +104,8 @@ class TalkViewNativeDecodeLogic extends BaseGetXController {
|
||||
codecType: 'h264',
|
||||
);
|
||||
// 初始化解码器并获取textureId
|
||||
AppLog.log(
|
||||
'StartChartManage().videoWidth:${StartChartManage().videoWidth}');
|
||||
AppLog.log(
|
||||
'StartChartManage().videoHeight:${StartChartManage().videoHeight}');
|
||||
AppLog.log('StartChartManage().videoWidth:${StartChartManage().videoWidth}');
|
||||
AppLog.log('StartChartManage().videoHeight:${StartChartManage().videoHeight}');
|
||||
final textureId = await VideoDecodePlugin.initDecoder(config);
|
||||
if (textureId != null) {
|
||||
Future.microtask(() => state.textureId.value = textureId);
|
||||
@ -172,15 +170,11 @@ class TalkViewNativeDecodeLogic extends BaseGetXController {
|
||||
ScpMessage scpMessage,
|
||||
) {
|
||||
// 动态回绕阈值判断,frameSeq较小时阈值也小
|
||||
if (!_pendingStreamReset &&
|
||||
_lastFrameSeq != null &&
|
||||
frameType == TalkDataH264Frame_FrameTypeE.I &&
|
||||
frameSeq < _lastFrameSeq!) {
|
||||
if (!_pendingStreamReset && _lastFrameSeq != null && frameType == TalkDataH264Frame_FrameTypeE.I && frameSeq < _lastFrameSeq!) {
|
||||
int dynamicThreshold = _getFrameSeqRolloverThreshold(_lastFrameSeq!);
|
||||
if ((_lastFrameSeq! - frameSeq) > dynamicThreshold) {
|
||||
// 检测到新流I帧,frameSeq大幅回绕,进入loading并重置所有本地状态
|
||||
AppLog.log(
|
||||
'检测到新流I帧,frameSeq大幅回绕,进入loading并重置: frameSeq=$frameSeq, lastFrameSeq=$_lastFrameSeq, 阈值=$dynamicThreshold');
|
||||
AppLog.log('检测到新流I帧,frameSeq大幅回绕,进入loading并重置: frameSeq=$frameSeq, lastFrameSeq=$_lastFrameSeq, 阈值=$dynamicThreshold');
|
||||
Future.microtask(() => state.isLoading.value = true);
|
||||
_pendingStreamReset = true;
|
||||
// 先暂停帧处理定时器,防止竞态
|
||||
@ -197,8 +191,7 @@ class TalkViewNativeDecodeLogic extends BaseGetXController {
|
||||
// 继续往下执行
|
||||
} else {
|
||||
// 小幅度乱序,直接丢弃
|
||||
AppLog.log(
|
||||
'检测到I帧乱序(未超过回绕阈值$dynamicThreshold),丢弃: frameSeq=$frameSeq, lastFrameSeq=$_lastFrameSeq');
|
||||
AppLog.log('检测到I帧乱序(未超过回绕阈值$dynamicThreshold),丢弃: frameSeq=$frameSeq, lastFrameSeq=$_lastFrameSeq');
|
||||
return;
|
||||
}
|
||||
}
|
||||
@ -238,8 +231,7 @@ class TalkViewNativeDecodeLogic extends BaseGetXController {
|
||||
|
||||
// 如果缓冲区超出最大大小,优先丢弃P/B帧
|
||||
while (state.h264FrameBuffer.length >= state.maxFrameBufferSize) {
|
||||
int pbIndex = state.h264FrameBuffer
|
||||
.indexWhere((f) => f['frameType'] == TalkDataH264Frame_FrameTypeE.P);
|
||||
int pbIndex = state.h264FrameBuffer.indexWhere((f) => f['frameType'] == TalkDataH264Frame_FrameTypeE.P);
|
||||
if (pbIndex != -1) {
|
||||
state.h264FrameBuffer.removeAt(pbIndex);
|
||||
} else {
|
||||
@ -260,8 +252,7 @@ class TalkViewNativeDecodeLogic extends BaseGetXController {
|
||||
final int intervalMs = (1000 / state.targetFps).round();
|
||||
|
||||
// 创建新定时器
|
||||
state.frameProcessTimer =
|
||||
Timer.periodic(Duration(milliseconds: intervalMs), (timer) {
|
||||
state.frameProcessTimer = Timer.periodic(Duration(milliseconds: intervalMs), (timer) {
|
||||
_processNextFrameFromBuffer();
|
||||
});
|
||||
AppLog.log('启动帧处理定时器,目标帧率: ${state.targetFps}fps,间隔: ${intervalMs}ms');
|
||||
@ -280,24 +271,18 @@ class TalkViewNativeDecodeLogic extends BaseGetXController {
|
||||
}
|
||||
|
||||
// 优先查找I帧,按frameSeq最小的I帧消费
|
||||
final iFrames = state.h264FrameBuffer
|
||||
.where((f) => f['frameType'] == TalkDataH264Frame_FrameTypeE.I)
|
||||
.toList();
|
||||
iFrames
|
||||
.sort((a, b) => (a['frameSeq'] as int).compareTo(b['frameSeq'] as int));
|
||||
final iFrames = state.h264FrameBuffer.where((f) => f['frameType'] == TalkDataH264Frame_FrameTypeE.I).toList();
|
||||
iFrames.sort((a, b) => (a['frameSeq'] as int).compareTo(b['frameSeq'] as int));
|
||||
|
||||
if (iFrames.isNotEmpty) {
|
||||
// 有I帧,消费最小的I帧,并记录其frameSeq
|
||||
final minIFrame = iFrames.first;
|
||||
final minIFrameSeq = minIFrame['frameSeq'];
|
||||
final targetIndex = state.h264FrameBuffer.indexWhere(
|
||||
(f) =>
|
||||
f['frameType'] == TalkDataH264Frame_FrameTypeE.I &&
|
||||
f['frameSeq'] == minIFrameSeq,
|
||||
(f) => f['frameType'] == TalkDataH264Frame_FrameTypeE.I && f['frameSeq'] == minIFrameSeq,
|
||||
);
|
||||
state.isProcessingFrame = true;
|
||||
final Map<String, dynamic>? frameMap =
|
||||
state.h264FrameBuffer.removeAt(targetIndex);
|
||||
final Map<String, dynamic>? frameMap = state.h264FrameBuffer.removeAt(targetIndex);
|
||||
if (frameMap == null) {
|
||||
state.isProcessingFrame = false;
|
||||
return;
|
||||
@ -308,11 +293,7 @@ class TalkViewNativeDecodeLogic extends BaseGetXController {
|
||||
final int? frameSeqI = frameMap['frameSeqI'];
|
||||
final int? pts = frameMap['pts'];
|
||||
final ScpMessage? scpMessage = frameMap['scpMessage'];
|
||||
if (frameData == null ||
|
||||
frameType == null ||
|
||||
frameSeq == null ||
|
||||
frameSeqI == null ||
|
||||
pts == null) {
|
||||
if (frameData == null || frameType == null || frameSeq == null || frameSeqI == null || pts == null) {
|
||||
state.isProcessingFrame = false;
|
||||
return;
|
||||
}
|
||||
@ -321,11 +302,8 @@ class TalkViewNativeDecodeLogic extends BaseGetXController {
|
||||
return;
|
||||
}
|
||||
lastDecodedIFrameSeq = minIFrameSeq;
|
||||
// AppLog.log('送入解码器的P帧数据frameSeq:${frameSeq},frameSeqI:${frameSeqI},'
|
||||
// 'frameType:${frameType},messageId:${scpMessage!.MessageId}');
|
||||
// final spsData = NaluUtils.filterNalusByType(frameData, 7);
|
||||
// final ppsData = NaluUtils.filterNalusByType(frameData, 8);
|
||||
// AppLog.log('SPSDATA:${spsData},ppsData:${ppsData}');
|
||||
AppLog.log('送入解码器的P帧数据frameSeq:${frameSeq},frameSeqI:${frameSeqI},'
|
||||
'frameType:${frameType},messageId:${scpMessage!.MessageId}');
|
||||
await VideoDecodePlugin.sendFrame(
|
||||
frameData: frameData,
|
||||
frameType: 0,
|
||||
@ -340,24 +318,16 @@ class TalkViewNativeDecodeLogic extends BaseGetXController {
|
||||
|
||||
// 没有I帧时,只消费refIFrameSeq等于lastDecodedIFrameSeq的P帧
|
||||
if (lastDecodedIFrameSeq != null) {
|
||||
final validPFrames = state.h264FrameBuffer
|
||||
.where((f) =>
|
||||
f['frameType'] == TalkDataH264Frame_FrameTypeE.P &&
|
||||
f['frameSeqI'] == lastDecodedIFrameSeq)
|
||||
.toList();
|
||||
final validPFrames =
|
||||
state.h264FrameBuffer.where((f) => f['frameType'] == TalkDataH264Frame_FrameTypeE.P && f['frameSeqI'] == lastDecodedIFrameSeq).toList();
|
||||
if (validPFrames.isNotEmpty) {
|
||||
validPFrames.sort(
|
||||
(a, b) => (a['frameSeq'] as int).compareTo(b['frameSeq'] as int));
|
||||
validPFrames.sort((a, b) => (a['frameSeq'] as int).compareTo(b['frameSeq'] as int));
|
||||
final minPFrame = validPFrames.first;
|
||||
final targetIndex = state.h264FrameBuffer.indexWhere(
|
||||
(f) =>
|
||||
f['frameType'] == TalkDataH264Frame_FrameTypeE.P &&
|
||||
f['frameSeq'] == minPFrame['frameSeq'] &&
|
||||
f['frameSeqI'] == lastDecodedIFrameSeq,
|
||||
(f) => f['frameType'] == TalkDataH264Frame_FrameTypeE.P && f['frameSeq'] == minPFrame['frameSeq'] && f['frameSeqI'] == lastDecodedIFrameSeq,
|
||||
);
|
||||
state.isProcessingFrame = true;
|
||||
final Map<String, dynamic>? frameMap =
|
||||
state.h264FrameBuffer.removeAt(targetIndex);
|
||||
final Map<String, dynamic>? frameMap = state.h264FrameBuffer.removeAt(targetIndex);
|
||||
if (frameMap == null) {
|
||||
state.isProcessingFrame = false;
|
||||
return;
|
||||
@ -368,11 +338,7 @@ class TalkViewNativeDecodeLogic extends BaseGetXController {
|
||||
final int? frameSeqI = frameMap['frameSeqI'];
|
||||
final int? pts = frameMap['pts'];
|
||||
final ScpMessage? scpMessage = frameMap['scpMessage'];
|
||||
if (frameData == null ||
|
||||
frameType == null ||
|
||||
frameSeq == null ||
|
||||
frameSeqI == null ||
|
||||
pts == null) {
|
||||
if (frameData == null || frameType == null || frameSeq == null || frameSeqI == null || pts == null) {
|
||||
state.isProcessingFrame = false;
|
||||
return;
|
||||
}
|
||||
@ -427,8 +393,7 @@ class TalkViewNativeDecodeLogic extends BaseGetXController {
|
||||
AppLog.log("==== 启动新的数据流监听 ====");
|
||||
_isListening = true;
|
||||
|
||||
_streamSubscription = state.talkDataRepository.talkDataStream
|
||||
.listen((TalkDataModel talkDataModel) async {
|
||||
_streamSubscription = state.talkDataRepository.talkDataStream.listen((TalkDataModel talkDataModel) async {
|
||||
_processFrame(talkDataModel);
|
||||
});
|
||||
}
|
||||
@ -437,8 +402,7 @@ class TalkViewNativeDecodeLogic extends BaseGetXController {
|
||||
void _playAudioFrames() {
|
||||
// 如果缓冲区为空或未达到目标大小,不进行播放
|
||||
// 音频缓冲区要求更小,以减少延迟
|
||||
if (state.audioBuffer.isEmpty ||
|
||||
state.audioBuffer.length < audioBufferSize) {
|
||||
if (state.audioBuffer.isEmpty || state.audioBuffer.length < audioBufferSize) {
|
||||
return;
|
||||
}
|
||||
|
||||
@ -446,8 +410,7 @@ class TalkViewNativeDecodeLogic extends BaseGetXController {
|
||||
TalkData? oldestFrame;
|
||||
int oldestIndex = -1;
|
||||
for (int i = 0; i < state.audioBuffer.length; i++) {
|
||||
if (oldestFrame == null ||
|
||||
state.audioBuffer[i].durationMs < oldestFrame.durationMs) {
|
||||
if (oldestFrame == null || state.audioBuffer[i].durationMs < oldestFrame.durationMs) {
|
||||
oldestFrame = state.audioBuffer[i];
|
||||
oldestIndex = i;
|
||||
}
|
||||
@ -477,8 +440,7 @@ class TalkViewNativeDecodeLogic extends BaseGetXController {
|
||||
break;
|
||||
case TalkStatus.answeredSuccessfully:
|
||||
state.oneMinuteTimeTimer?.cancel(); // 取消旧定时器
|
||||
state.oneMinuteTimeTimer ??=
|
||||
Timer.periodic(const Duration(seconds: 1), (Timer t) {
|
||||
state.oneMinuteTimeTimer ??= Timer.periodic(const Duration(seconds: 1), (Timer t) {
|
||||
if (state.isLoading.isFalse) {
|
||||
state.oneMinuteTime.value++;
|
||||
}
|
||||
@ -493,9 +455,7 @@ class TalkViewNativeDecodeLogic extends BaseGetXController {
|
||||
|
||||
/// 播放音频数据
|
||||
void _playAudioData(TalkData talkData) async {
|
||||
if (state.isOpenVoice.value &&
|
||||
state.isLoading.isFalse &&
|
||||
state.isRecordingAudio.value == false) {
|
||||
if (state.isOpenVoice.value && state.isLoading.isFalse && state.isRecordingAudio.value == false) {
|
||||
List<int> encodedData = G711Tool.decode(talkData.content, 0); // 0表示A-law
|
||||
// 将 PCM 数据转换为 PcmArrayInt16
|
||||
final PcmArrayInt16 fromList = PcmArrayInt16.fromList(encodedData);
|
||||
@ -670,11 +630,9 @@ class TalkViewNativeDecodeLogic extends BaseGetXController {
|
||||
AppLog.log('截图失败: 未找到当前上下文');
|
||||
return;
|
||||
}
|
||||
final RenderRepaintBoundary boundary = state.globalKey.currentContext!
|
||||
.findRenderObject()! as RenderRepaintBoundary;
|
||||
final RenderRepaintBoundary boundary = state.globalKey.currentContext!.findRenderObject()! as RenderRepaintBoundary;
|
||||
final ui.Image image = await boundary.toImage();
|
||||
final ByteData? byteData =
|
||||
await image.toByteData(format: ui.ImageByteFormat.png);
|
||||
final ByteData? byteData = await image.toByteData(format: ui.ImageByteFormat.png);
|
||||
|
||||
if (byteData == null) {
|
||||
AppLog.log('截图失败: 图像数据为空');
|
||||
@ -702,15 +660,13 @@ class TalkViewNativeDecodeLogic extends BaseGetXController {
|
||||
|
||||
// 远程开锁
|
||||
Future<void> remoteOpenLock() async {
|
||||
final LockListInfoItemEntity currentKeyInfo =
|
||||
CommonDataManage().currentKeyInfo;
|
||||
final LockListInfoItemEntity currentKeyInfo = CommonDataManage().currentKeyInfo;
|
||||
|
||||
var lockId = currentKeyInfo.lockId ?? 0;
|
||||
var remoteUnlock = currentKeyInfo.lockSetting?.remoteUnlock ?? 0;
|
||||
|
||||
final lockPeerId = StartChartManage().lockPeerId;
|
||||
final LockListInfoGroupEntity? lockListInfoGroupEntity =
|
||||
await Storage.getLockMainListData();
|
||||
final LockListInfoGroupEntity? lockListInfoGroupEntity = await Storage.getLockMainListData();
|
||||
if (lockListInfoGroupEntity != null) {
|
||||
lockListInfoGroupEntity!.groupList?.forEach((element) {
|
||||
final lockList = element.lockList;
|
||||
@ -728,8 +684,7 @@ class TalkViewNativeDecodeLogic extends BaseGetXController {
|
||||
});
|
||||
}
|
||||
if (remoteUnlock == 1) {
|
||||
final LoginEntity entity = await ApiRepository.to
|
||||
.remoteOpenLock(lockId: lockId.toString(), timeOut: 60);
|
||||
final LoginEntity entity = await ApiRepository.to.remoteOpenLock(lockId: lockId.toString(), timeOut: 60);
|
||||
if (entity.errorCode!.codeIsSuccessful) {
|
||||
showToast('已开锁'.tr);
|
||||
StartChartManage().lockListPeerId = [];
|
||||
@ -756,8 +711,7 @@ class TalkViewNativeDecodeLogic extends BaseGetXController {
|
||||
state.startRecordingAudioTime.value = DateTime.now();
|
||||
|
||||
// 增加录音帧监听器和错误监听器
|
||||
state.voiceProcessor
|
||||
?.addFrameListeners(<VoiceProcessorFrameListener>[_onFrame]);
|
||||
state.voiceProcessor?.addFrameListeners(<VoiceProcessorFrameListener>[_onFrame]);
|
||||
state.voiceProcessor?.addErrorListener(_onError);
|
||||
} else {
|
||||
// state.errorMessage.value = 'Recording permission not granted';
|
||||
@ -777,8 +731,7 @@ class TalkViewNativeDecodeLogic extends BaseGetXController {
|
||||
state.endRecordingAudioTime.value = DateTime.now();
|
||||
|
||||
// 计算录音的持续时间
|
||||
final Duration duration = state.endRecordingAudioTime.value
|
||||
.difference(state.startRecordingAudioTime.value);
|
||||
final Duration duration = state.endRecordingAudioTime.value.difference(state.startRecordingAudioTime.value);
|
||||
|
||||
state.recordingAudioTime.value = duration.inSeconds;
|
||||
} on PlatformException catch (ex) {
|
||||
@ -848,10 +801,8 @@ class TalkViewNativeDecodeLogic extends BaseGetXController {
|
||||
_bufferedAudioFrames.addAll(encodedData);
|
||||
|
||||
// 启动定时发送器(仅启动一次)
|
||||
if (_startProcessingAudioTimer == null &&
|
||||
_bufferedAudioFrames.length > chunkSize) {
|
||||
_startProcessingAudioTimer =
|
||||
Timer.periodic(Duration(milliseconds: intervalMs), _sendAudioChunk);
|
||||
if (_startProcessingAudioTimer == null && _bufferedAudioFrames.length > chunkSize) {
|
||||
_startProcessingAudioTimer = Timer.periodic(Duration(milliseconds: intervalMs), _sendAudioChunk);
|
||||
}
|
||||
}
|
||||
|
||||
@ -887,8 +838,7 @@ class TalkViewNativeDecodeLogic extends BaseGetXController {
|
||||
}
|
||||
|
||||
/// 修改发送预期数据
|
||||
StartChartManage().changeTalkExpectDataTypeAndReStartTalkExpectMessageTimer(
|
||||
talkExpect: talkExpectReq);
|
||||
StartChartManage().changeTalkExpectDataTypeAndReStartTalkExpectMessageTimer(talkExpect: talkExpectReq);
|
||||
|
||||
// 不立即loading,继续解码旧流帧,等待frameSeq回绕检测
|
||||
// 仅重置frameSeq回绕检测标志
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user