Merge remote-tracking branch 'origin/develop_liyi' into develop_liyi

This commit is contained in:
Liuyf 2025-02-24 18:01:19 +08:00
commit 64563c90a1
20 changed files with 270 additions and 137 deletions

View File

@ -56,7 +56,7 @@
},
flushingTime: 0, // 禁用自动刷新
clearBuffer: false, // 保留解码缓存
maxBufferLength: 2,
fps:20,
onReady: () => {
console.log('播放器初始化完成');
// 通知Flutter端准备就绪

View File

@ -2,6 +2,7 @@ import 'dart:async';
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:star_lock/main/lockDetail/lockSet/lockSet/lockSetInfo_entity.dart';
import '../../../blue/io_reply.dart';
import '../../lockMian/entity/lockListInfo_entity.dart';
@ -9,7 +10,7 @@ import '../../lockMian/entity/lockListInfo_entity.dart';
class LockDetailState {
Rx<LockListInfoItemEntity> keyInfos = LockListInfoItemEntity().obs;
final Rx<LockSetInfoData> lockSetInfoData = LockSetInfoData().obs;
late StreamSubscription<Reply> replySubscription;
StreamSubscription? lockSetOpenOrCloseCheckInRefreshLockDetailWithAttendanceEvent;
StreamSubscription? LockSetChangeSetRefreshLockDetailWithTypeSubscription;

View File

@ -8,6 +8,7 @@ import 'package:flutter_easyloading/flutter_easyloading.dart';
import 'package:get/get.dart';
import 'package:network_info_plus/network_info_plus.dart';
import 'package:permission_handler/permission_handler.dart';
import 'package:star_lock/appRouters.dart';
import 'package:star_lock/app_settings/app_settings.dart';
import 'package:star_lock/blue/io_gateway/io_gateway_configuringWifi.dart';
import 'package:star_lock/blue/io_gateway/io_gateway_getStatus.dart';
@ -68,7 +69,12 @@ class ConfiguringWifiLogic extends BaseGetXController {
secretKey: secretKey,
peerId: peerId,
);
Get.close(2);
if (state.pageName.value == 'lockSet') {
Get.close(2);
} else {
Get.offAllNamed(Routers.starLockMain);
}
});
}
}

View File

@ -47,7 +47,8 @@ class _ConfiguringWifiPageState extends State<ConfiguringWifiPage>
SubmitBtn(
btnName: '确定'.tr,
onClick: () {
logic.senderConfiguringWifiAction();
FocusScope.of(context).requestFocus(FocusNode());
logic.senderConfiguringWifiAction();
},
),
],

View File

@ -9,6 +9,7 @@ class ConfiguringWifiState{
ConfiguringWifiState() {
var map = Get.arguments;
lockSetInfoData.value = map['lockSetInfoData'];
pageName.value = map['pageName'];
lockBasicInfo.value = lockSetInfoData.value.lockBasicInfo!;
if (map['wifiName'] != null) {
wifiName.value = map['wifiName'];
@ -20,6 +21,7 @@ class ConfiguringWifiState{
Rx<LockBasicInfo> lockBasicInfo = LockBasicInfo().obs;
RxString wifiName = ''.obs;
RxString pageName = ''.obs;
RxBool ifCurrentScreen = true.obs; // ,
RxInt sureBtnState = 0.obs;// 0() 1()

View File

@ -24,11 +24,18 @@ class _WifiListPageState extends State<WifiListPage> {
@override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Colors.white,
appBar: TitleAppBar(
return WillPopScope(
onWillPop: () async {
if (state.pageName.value == 'lockSet') {
return true;
}
return false;
},
child: Scaffold(
backgroundColor: Colors.white,
appBar: TitleAppBar(
barTitle: 'WIFI列表'.tr,
haveBack: true,
haveBack: state.pageName.value == 'lockSet',
actionsList: <Widget>[
TextButton(
child: Text(
@ -38,45 +45,50 @@ class _WifiListPageState extends State<WifiListPage> {
onPressed: logic.senderGetWifiListWifiAction,
),
],
backgroundColor: AppColors.mainColor),
body: Column(
children: <Widget>[
Expanded(
child: Obx(() => state.wifiNameDataList.value.isNotEmpty
? ListView.builder(
itemCount: state.wifiNameDataList.value.length,
itemBuilder: (BuildContext c, int index) {
Map wifiNameStr = state.wifiNameDataList.value[index];
return _messageListItem(
wifiNameStr['wifiName'], wifiNameStr['rssi'], () {
Get.toNamed(Routers.configuringWifiPage, arguments: {
'lockSetInfoData': state.lockSetInfoData.value,
'wifiName': wifiNameStr['wifiName'],
backgroundColor: AppColors.mainColor,
),
body: Column(
children: <Widget>[
Expanded(
child: Obx(() => state.wifiNameDataList.value.isNotEmpty
? ListView.builder(
itemCount: state.wifiNameDataList.value.length,
itemBuilder: (BuildContext c, int index) {
Map wifiNameStr = state.wifiNameDataList.value[index];
return _messageListItem(
wifiNameStr['wifiName'], wifiNameStr['rssi'], () {
Get.toNamed(Routers.configuringWifiPage,
arguments: {
'lockSetInfoData':
state.lockSetInfoData.value,
'wifiName': wifiNameStr['wifiName'],
'pageName': state.pageName.value,
});
});
})
: NoData(
noDataHeight: 1.sh -
ScreenUtil().statusBarHeight -
ScreenUtil().bottomBarHeight -
64.h)),
),
SubmitBtn(
btnName: '手动配网'.tr,
fontSize: 28.sp,
borderRadius: 20.w,
padding: EdgeInsets.only(top: 25.w, bottom: 25.w),
onClick: () {
Get.toNamed(Routers.configuringWifiPage,
arguments: <String, LockSetInfoData>{
'lockSetInfoData': state.lockSetInfoData.value
});
})
: NoData(
noDataHeight: 1.sh -
ScreenUtil().statusBarHeight -
ScreenUtil().bottomBarHeight -
64.h)),
),
SubmitBtn(
btnName: '手动配网'.tr,
fontSize: 28.sp,
borderRadius: 20.w,
padding: EdgeInsets.only(top: 25.w, bottom: 25.w),
onClick: () {
Get.toNamed(Routers.configuringWifiPage,
arguments: <String, LockSetInfoData>{
'lockSetInfoData': state.lockSetInfoData.value
});
}),
SizedBox(
height: 64.h,
)
],
));
}),
SizedBox(
height: 64.h,
)
],
)),
);
}
Widget _messageListItem(String wifiName, String rssi, Function() action) {

View File

@ -1,18 +1,22 @@
import 'package:get/get.dart';
import '../../lockSet/lockSetInfo_entity.dart';
class WifiListState{// 0() 1()
class WifiListState {
// 0() 1()
WifiListState() {
final map = Get.arguments;
lockSetInfoData.value = map['lockSetInfoData'];
pageName.value = map['pageName'];
lockBasicInfo.value = lockSetInfoData.value.lockBasicInfo!;
}
final RxList<Map<String, String>> wifiNameDataList = <Map<String, String>>[].obs;
final RxList<Map<String, String>> wifiNameDataList =
<Map<String, String>>[].obs;
Rx<LockSetInfoData> lockSetInfoData = LockSetInfoData().obs;
Rx<LockBasicInfo> lockBasicInfo = LockBasicInfo().obs;
RxBool ifCurrentScreen = true.obs; // ,
RxInt sureBtnState = 0.obs;
}
RxString pageName = ''.obs;
}

View File

@ -595,10 +595,10 @@ class _LockSetPageState extends State<LockSetPage>
isHaveLine: true,
isHaveDirection: true,
action: () {
Get.toNamed(Routers.wifiListPage,
arguments: <String, LockSetInfoData>{
'lockSetInfoData': state.lockSetInfoData.value
});
Get.toNamed(Routers.wifiListPage, arguments: {
'lockSetInfoData': state.lockSetInfoData.value,
'pageName': 'lockSet'
});
// Get.toNamed(Routers.configuringWifiPage, arguments: {
// 'lockSetInfoData': state.lockSetInfoData.value
// });

View File

@ -170,7 +170,7 @@ class _VideoLogDetailPageState extends State<VideoLogDetailPage> {
_buildImageItem(RecordListData recordData) {
return RotatedBox(
quarterTurns: 1,
quarterTurns: -1,
child: Image.network(
recordData.imagesUrl!,
fit: BoxFit.cover,

View File

@ -345,6 +345,8 @@ class LockFeature {
this.isSupportCatEye,
this.isSupportBackupBattery,
this.isNoSupportedBlueBroadcast,
this.wifiLockType,
this.wifi,
});
LockFeature.fromJson(Map<String, dynamic> json) {
@ -360,6 +362,8 @@ class LockFeature {
isSupportCatEye = json['isSupportCatEye'];
isSupportBackupBattery = json['isSupportBackupBattery'];
isNoSupportedBlueBroadcast = json['isNoSupportedBlueBroadcast'];
wifiLockType = json['wifiLockType'];
wifi = json['wifi'];
}
int? password;
@ -374,6 +378,8 @@ class LockFeature {
int? isSupportCatEye;
int? isSupportBackupBattery;
int? isNoSupportedBlueBroadcast;
int? wifiLockType;
int? wifi;
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = <String, dynamic>{};
@ -389,6 +395,8 @@ class LockFeature {
data['isSupportCatEye'] = isSupportCatEye;
data['isSupportBackupBattery'] = isSupportBackupBattery;
data['isNoSupportedBlueBroadcast'] = isNoSupportedBlueBroadcast;
data['wifiLockType'] = wifiLockType;
data['wifi'] = wifi;
return data;
}
}

View File

@ -1,11 +1,12 @@
import 'dart:async';
import 'package:flutter_blue_plus/flutter_blue_plus.dart';
import 'package:get/get.dart';
import 'package:star_lock/apm/apm_helper.dart';
import 'package:star_lock/appRouters.dart';
import 'package:star_lock/main/lockDetail/lockDetail/lockDetail_logic.dart';
import 'package:star_lock/main/lockDetail/lockSet/lockSet/lockSetInfo_entity.dart';
import 'package:star_lock/mine/addLock/saveLock/entity/SaveLockEntity.dart';
import '../../../app_settings/app_settings.dart';
@ -408,10 +409,11 @@ class SaveLockLogic extends BaseGetXController {
final String getMobile = (await Storage.getMobile())!;
ApmHelper.instance.trackEvent('save_lock_result', {
'lock_name':BlueManage().connectDeviceName,
'account':getMobile.isNotEmpty ? getMobile : (await Storage.getEmail())!,
'date':DateTool().getNowDateWithType(1),
'save_lock_result':'成功',
'lock_name': BlueManage().connectDeviceName,
'account':
getMobile.isNotEmpty ? getMobile : (await Storage.getEmail())!,
'date': DateTool().getNowDateWithType(1),
'save_lock_result': '成功',
});
backAction();
// await senderCustomPasswords();
@ -424,10 +426,11 @@ class SaveLockLogic extends BaseGetXController {
final String getMobile = (await Storage.getMobile())!;
ApmHelper.instance.trackEvent('save_lock_result', {
'lock_name':BlueManage().connectDeviceName,
'account':getMobile.isNotEmpty ? getMobile : (await Storage.getEmail())!,
'date':DateTool().getNowDateWithType(1),
'save_lock_result':'${entity.errorCode}--${entity.errorMsg}',
'lock_name': BlueManage().connectDeviceName,
'account':
getMobile.isNotEmpty ? getMobile : (await Storage.getEmail())!,
'date': DateTool().getNowDateWithType(1),
'save_lock_result': '${entity.errorCode}--${entity.errorMsg}',
});
}
}
@ -482,20 +485,52 @@ class SaveLockLogic extends BaseGetXController {
// );
// }
void backAction() {
void backAction() async {
eventBus.fire(RefreshLockListInfoDataEvent(clearScanDevices: true));
BlueManage().disconnect();
Future<void>.delayed(const Duration(seconds: 1), () {
Get.close(state.isFromMap == 1 ? (CommonDataManage().seletLockType == 0 ? 4 : 5) : (CommonDataManage().seletLockType == 0 ? 5 : 6));
});
// 2
Future<void>.delayed(const Duration(milliseconds: 200), () {
if (Get.isRegistered<LockDetailLogic>()) {
Get.find<LockDetailLogic>()
.functionBlocker
.countdownProhibited(duration: const Duration(seconds: 2));
//
final LockSetInfoEntity entity =
await ApiRepository.to.getLockSettingInfoDataIsNotLoadingIcon(
lockId: state.lockId.toString(),
);
if (entity.errorCode!.codeIsSuccessful) {
state.lockSetInfoData.value = entity.data!;
if (state.lockSetInfoData.value.lockFeature?.wifi == 1) {
// await Future<void>.delayed(const Duration(seconds: 1), () {c
// Get.close(state.isFromMap == 1
// ? (CommonDataManage().seletLockType == 0 ? 4 : 5)
// : (CommonDataManage().seletLockType == 0 ? 5 : 6));
// });
// // 2
// await Future<void>.delayed(const Duration(milliseconds: 200), () {
// if (Get.isRegistered<LockDetailLogic>()) {
// Get.find<LockDetailLogic>()
// .functionBlocker
// .countdownProhibited(duration: const Duration(seconds: 2));
// }
// });
// wifi锁WIFI
Get.toNamed(Routers.wifiListPage, arguments: {
'lockSetInfoData': state.lockSetInfoData.value,
'pageName': 'saveLock'
});
} else {
Future<void>.delayed(const Duration(seconds: 1), () {
Get.close(state.isFromMap == 1
? (CommonDataManage().seletLockType == 0 ? 4 : 5)
: (CommonDataManage().seletLockType == 0 ? 5 : 6));
});
// 2
Future<void>.delayed(const Duration(milliseconds: 200), () {
if (Get.isRegistered<LockDetailLogic>()) {
Get.find<LockDetailLogic>()
.functionBlocker
.countdownProhibited(duration: const Duration(seconds: 2));
}
});
}
});
}
}
@override

View File

@ -3,6 +3,7 @@ import 'dart:math';
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:star_lock/main/lockDetail/lockSet/lockSet/lockSetInfo_entity.dart';
import '../../../blue/blue_manage.dart';
@ -25,7 +26,7 @@ class SaveLockState {
RxString aliName = ''.obs;
RxInt pwdTimestamp = 0.obs;
RxMap addressInfo = {}.obs;
final Rx<LockSetInfoData> lockSetInfoData = LockSetInfoData().obs;
TextEditingController aliNameController = TextEditingController();
FocusNode focusNode = FocusNode();

View File

@ -292,21 +292,20 @@ class _MineSetPageState extends State<MineSetPage>
SizedBox(
height: 10.h,
),
Obx(() {
// AppLog.log('state.currentLanguageName: ${state.currentLanguageName} state.currentLanguage.value: ${state.currentLanguage.value}');
return CommonItem(
leftTitel: '多语言'.tr,
rightTitle: state.currentLanguageName,
isHaveLine: true,
isHaveDirection: true,
action: () async {
// Get.toNamed(Routers.mineMultiLanguagePage);
await Get.toNamed(Routers.mineMultiLanguagePage)!.then((value) {
state.currentLanguage.value = value['currentLanguage'];
setState(() {});
});
// AppLog.log('state.currentLanguageName: ${state.currentLanguageName} state.currentLanguage.value: ${state.currentLanguage.value}');
CommonItem(
leftTitel: '多语言'.tr,
rightTitle: state.currentLanguageName,
isHaveLine: true,
isHaveDirection: true,
action: () async {
// Get.toNamed(Routers.mineMultiLanguagePage);
await Get.toNamed(Routers.mineMultiLanguagePage)!.then((value) {
state.currentLanguage.value = value['currentLanguage'];
setState(() {});
});
}),
}),
/* 2024-01-12 by DaisyWu
Obx(() => CommonItem(
leftTitel: TranslationLoader.lanKeys!.lockScreen!.tr,

View File

@ -423,6 +423,15 @@ class ApiProvider extends BaseProvider {
'lockId': lockId,
}));
//
Future<Response> getLockSettingInfoDataIsNotLoadingIcon(String lockId) =>
post(
getLockSettingURL.toUrl,
jsonEncode({
'lockId': lockId,
}),
isUnShowLoading: true);
//
Future<Response> deletLockInfo(int lockId) => post(
deletLockURL.toUrl,

View File

@ -486,6 +486,12 @@ class ApiRepository {
final res = await apiProvider.getLockSettingInfoData(lockId);
return LockSetInfoEntity.fromJson(res.body);
}
// ()
Future<LockSetInfoEntity> getLockSettingInfoDataIsNotLoadingIcon(
{required String lockId}) async {
final res = await apiProvider.getLockSettingInfoDataIsNotLoadingIcon(lockId);
return LockSetInfoEntity.fromJson(res.body);
}
//
Future<LockListInfoEntity> deletOwnerLockData({required int lockId}) async {

View File

@ -160,6 +160,8 @@ class UdpTalkDataHandler extends ScpMessageBaseHandle
final TalkDataH264Frame talkDataH264Frame = TalkDataH264Frame();
talkDataH264Frame.mergeFromBuffer(talkData.content);
frameHandler.handleFrame(talkDataH264Frame);
AppLog.log(
"帧:${talkDataH264Frame.frameType},帧序号:${talkDataH264Frame.frameSeq},对应I帧序号${talkDataH264Frame.frameSeqI}");
}
///

View File

@ -1,52 +1,51 @@
import 'dart:collection';
import 'dart:typed_data';
import 'package:star_lock/app_settings/app_settings.dart';
import '../../proto/talk_data_h264_frame.pb.dart';
class H264FrameHandler {
final Map<int, TalkDataH264Frame> _frameBuffer = {};
final LinkedHashMap<int, TalkDataH264Frame> _frameBuffer = LinkedHashMap();
final void Function(List<int> frameData) onCompleteFrame;
int _lastProcessedSeq = -1;
final LinkedHashMap<int, TalkDataH264Frame_FrameTypeE> _frameTypeIndex = LinkedHashMap();
H264FrameHandler({required this.onCompleteFrame});
void handleFrame(TalkDataH264Frame frame) {
//
_frameBuffer[frame.frameSeq] = frame;
_frameTypeIndex[frame.frameSeq] = frame.frameType;
// GOP (Group of Pictures)
_tryAssembleFrames(frame.frameSeq);
}
void _tryAssembleFrames(int currentSeq) {
//
final List<int> sortedSeqs = _frameBuffer.keys.toList()..sort();
final List<int> framesToProcess = [];
int? startFrameSeq;
// I P
int? startFrameSeq;
for (var seq in sortedSeqs.reversed) {
final frame = _frameBuffer[seq];
if (frame?.frameType == TalkDataH264Frame_FrameTypeE.I) {
for (int seq = currentSeq; seq >= 0; seq--) {
final frameType = _frameTypeIndex[seq];
if (frameType == null) continue;
if (frameType == TalkDataH264Frame_FrameTypeE.I) {
startFrameSeq = seq;
break;
} else if (frame?.frameType == TalkDataH264Frame_FrameTypeE.P) {
// P I
if (_frameBuffer.containsKey(frame?.frameSeqI)) {
} else if (frameType == TalkDataH264Frame_FrameTypeE.P) {
if (_frameBuffer.containsKey(_frameBuffer[seq]!.frameSeqI)) {
startFrameSeq = seq;
break;
} else {
// I P
_frameBuffer.remove(seq);
_frameTypeIndex.remove(seq);
}
}
}
if (startFrameSeq != null) {
// I P
int expectedSeq = startFrameSeq;
for (var seq in sortedSeqs.where((s) => s >= startFrameSeq!)) {
if (seq != expectedSeq) break;
for (int seq = startFrameSeq; _frameBuffer.containsKey(seq); seq++) {
framesToProcess.add(seq);
expectedSeq++;
}
if (framesToProcess.isNotEmpty) {
@ -57,28 +56,50 @@ class H264FrameHandler {
}
}
void _clearOldFrames(int currentSeq) {
//
_frameBuffer.removeWhere((seq, frame) => seq < currentSeq - 200); //
}
void _processFrames(List<int> frameSeqs) {
//
final List<int> assembledData = [];
// final List<int> assembledData = [];
//
// for (var seq in frameSeqs) {
// final frame = _frameBuffer[seq]!;
// assembledData.addAll(frame.frameData);
//
// //
// _frameBuffer.remove(seq);
// }
//
// //
// onCompleteFrame(assembledData);
// Calculate the total length of the assembled data
int totalLength = frameSeqs.fold(
0, (sum, seq) => sum + _frameBuffer[seq]!.frameData.length);
// Allocate a buffer for the assembled data
final assembledData = Uint8List(totalLength);
int offset = 0;
for (var seq in frameSeqs) {
final frame = _frameBuffer[seq]!;
assembledData.addAll(frame.frameData);
assembledData.setRange(
offset, offset + frame.frameData.length, frame.frameData);
offset += frame.frameData.length;
//
// Remove the frame from the buffer after processing
_frameBuffer.remove(seq);
_frameTypeIndex.remove(seq);
}
//
// Callback with the complete frame data
onCompleteFrame(assembledData);
}
void clear() {
_frameBuffer.clear();
}
void _clearOldFrames(int currentSeq) {
//
_frameBuffer.removeWhere((seq, frame) => seq < currentSeq - 200); //
_frameTypeIndex.removeWhere((seq, frameType) => seq < currentSeq - 200);
}
}

View File

@ -112,7 +112,7 @@ class StartChartManage {
//
TalkExpectReq _defaultTalkExpect = TalkExpectReq(
videoType: [VideoTypeE.H264],
videoType: [VideoTypeE.IMAGE],
audioType: [AudioTypeE.G711],
);
@ -1119,7 +1119,7 @@ class StartChartManage {
void reSetDefaultTalkExpect() {
_defaultTalkExpect = TalkExpectReq(
videoType: [VideoTypeE.H264],
videoType: [VideoTypeE.IMAGE],
audioType: [AudioTypeE.G711],
);
}
@ -1131,7 +1131,7 @@ class StartChartManage {
///
void sendOnlyImageVideoTalkExpectData() {
final talkExpectReq = TalkExpectReq(
videoType: [VideoTypeE.H264],
videoType: [VideoTypeE.IMAGE],
audioType: [],
);
changeTalkExpectDataTypeAndReStartTalkExpectMessageTimer(
@ -1141,7 +1141,7 @@ class StartChartManage {
///
void sendImageVideoAndG711AudioTalkExpectData() {
final talkExpectReq = TalkExpectReq(
videoType: [VideoTypeE.H264],
videoType: [VideoTypeE.IMAGE],
audioType: [AudioTypeE.G711],
);
changeTalkExpectDataTypeAndReStartTalkExpectMessageTimer(

View File

@ -46,6 +46,8 @@ class TalkViewLogic extends BaseGetXController {
int audioFrameIntervalMs = 20; // 4522FPS
int minFrameIntervalMs = 30; // 33 FPS
int maxFrameIntervalMs = 100; // 1 FPS
//
List<int> _bufferedAudioFrames = <int>[];
///
void _initFlutterPcmSound() {
@ -533,15 +535,17 @@ class TalkViewLogic extends BaseGetXController {
//
Future<void> startProcessingAudio() async {
//
state.voiceProcessor?.addFrameListener(_onFrame);
state.voiceProcessor?.addErrorListener(_onError);
try {
if (await state.voiceProcessor?.hasRecordAudioPermission() ?? false) {
await state.voiceProcessor?.start(state.frameLength, state.sampleRate);
final bool? isRecording = await state.voiceProcessor?.isRecording();
state.isRecordingAudio.value = isRecording!;
state.startRecordingAudioTime.value = DateTime.now();
//
state.voiceProcessor
?.addFrameListeners(<VoiceProcessorFrameListener>[_onFrame]);
state.voiceProcessor?.addErrorListener(_onError);
} else {
// state.errorMessage.value = 'Recording permission not granted';
}
@ -576,23 +580,23 @@ class TalkViewLogic extends BaseGetXController {
//
Future<void> _onFrame(List<int> frame) async {
// 线
// final processedFrame = await compute(preprocessAudio, frame);
// final list = listLinearToALaw(processedFrame);
final List<int> processedFrame = preprocessAudio(frame);
final List<int> list = listLinearToALaw(processedFrame);
_bufferedAudioFrames.addAll(list);
final int ms = DateTime.now().millisecondsSinceEpoch -
state.startRecordingAudioTime.value.millisecondsSinceEpoch;
// UDP
await StartChartManage().sendTalkDataMessage(
talkData: TalkData(
content: list,
contentType: TalkData_ContentTypeE.G711,
durationMs: ms,
),
);
Future.delayed(const Duration(milliseconds: 1000)).whenComplete(() async {
// UDP
await StartChartManage().sendTalkDataMessage(
talkData: TalkData(
content: list,
contentType: TalkData_ContentTypeE.G711,
durationMs: ms,
),
);
});
}
//
@ -662,9 +666,31 @@ class TalkViewLogic extends BaseGetXController {
// return processedList;
// }
List<int> listLinearToALaw(List<int> pcmList) {
final List<int> aLawList = [];
List<int> adjustVolume(List<int> pcmList, double volume) {
final List<int> adjustedPcmList = [];
for (int pcmVal in pcmList) {
//
int adjustedPcmVal = (pcmVal * volume).round();
// 16-bit PCM
if (adjustedPcmVal > 32767) {
adjustedPcmVal = 32767;
} else if (adjustedPcmVal < -32768) {
adjustedPcmVal = -32768;
}
adjustedPcmList.add(adjustedPcmVal);
}
return adjustedPcmList;
}
List<int> listLinearToALaw(List<int> pcmList) {
//
final List<int> adjustedPcmList = adjustVolume(pcmList, 5.0);
// A-law
final List<int> aLawList = [];
for (int pcmVal in adjustedPcmList) {
final int aLawVal = linearToALaw(pcmVal);
aLawList.add(aLawVal);
}

View File

@ -37,7 +37,7 @@ class TalkViewState {
RxList<int> listAudioData = <int>[].obs; //
GlobalKey globalKey = GlobalKey();
Timer? oneMinuteTimeTimer; // 60
Timer? oneMinuteTimeTimer; // 60
RxInt oneMinuteTime = 0.obs; //
// 10
@ -89,4 +89,4 @@ class TalkViewState {
RxBool isLongPressing = false.obs; //
RxBool hasAudioData = false.obs; //
RxInt lastAudioTimestamp = 0.obs; //
}
}