app-starlock/lib/main/lockDetail/realTimePicture/realTimePicture_logic.dart

324 lines
9.0 KiB
Dart
Raw Normal View History

2024-01-03 15:24:42 +08:00
import 'dart:async';
import 'dart:math';
import 'package:flutter/services.dart';
import 'package:flutter_voice_processor/flutter_voice_processor.dart';
import 'package:get/get.dart';
import 'package:permission_handler/permission_handler.dart';
2024-01-06 14:49:44 +08:00
import 'package:star_lock/talk/call/callTalk.dart';
2024-01-03 15:24:42 +08:00
import '../../../../talk/call/g711.dart';
import '../../../../talk/udp/udp_manage.dart';
import '../../../../talk/udp/udp_senderManage.dart';
import '../../../../tools/baseGetXController.dart';
import '../../../../tools/eventBusEventManage.dart';
2024-04-26 15:38:59 +08:00
import '../../../app_settings/app_settings.dart';
2024-01-09 13:51:35 +08:00
import 'realTimePicture_state.dart';
2024-01-03 15:24:42 +08:00
class RealTimePictureLogic extends BaseGetXController {
final RealTimePictureState state = RealTimePictureState();
/// 初始化发送声音
initRecorder() {
state.voiceProcessor = VoiceProcessor.instance;
}
/// 收到视频流数据
StreamSubscription? _getTVDataRefreshUIEvent;
void _getTVDataRefreshUIAction() {
// 蓝牙协议通知传输跟蓝牙之外的数据传输类不一样 eventBus
_getTVDataRefreshUIEvent =
eventBus.on<GetTVDataRefreshUI>().listen((event) {
if (event.tvList.isNotEmpty) {
// 预加载图片数据
final Uint8List imageData = Uint8List.fromList(event.tvList);
2024-01-03 15:24:42 +08:00
// 更新状态
state.listData.value = imageData;
}
});
}
2024-01-05 09:26:12 +08:00
/// 收到UDP发送的状态
StreamSubscription? _getUDPStatusRefreshUIEvent;
void _getUDPStatusRefreshUIAction() {
_getUDPStatusRefreshUIEvent =
eventBus.on<GetUDPStatusMonitorUI>().listen((event) {
2024-01-05 09:26:12 +08:00
state.udpStatus.value = event.udpStatus;
});
}
/// 监视
udpMonitorAction() async {
UDPSenderManage.sendMainProtocol(
command: 152,
commandTypeIsCalling: 1,
subCommand: 1,
2024-01-08 11:28:22 +08:00
lockID: state.getLockName.value,
2024-01-05 09:26:12 +08:00
lockIP: UDPManage().host,
userMobile: await state.userUid,
2024-01-05 09:26:12 +08:00
userMobileIP: await state.userMobileIP,
endData: []);
}
2024-01-03 15:24:42 +08:00
/// 挂断
udpHangUpAction() async {
UDPSenderManage.sendMainProtocol(
2024-01-05 09:26:12 +08:00
command: 152,
2024-01-03 15:24:42 +08:00
commandTypeIsCalling: 1,
subCommand: 30,
lockID: UDPManage().lockId,
lockIP: UDPManage().host,
userMobile: await state.userUid,
2024-01-03 15:24:42 +08:00
userMobileIP: await state.userMobileIP,
endData: []);
}
/// 开门
2024-01-09 11:36:51 +08:00
udpOpenDoorAction(List<int> list) async {
2024-01-03 15:24:42 +08:00
UDPSenderManage.sendMainProtocol(
2024-01-05 09:26:12 +08:00
command: 152,
2024-01-03 15:24:42 +08:00
commandTypeIsCalling: 1,
subCommand: 10,
lockID: UDPManage().lockId,
lockIP: UDPManage().host,
userMobile: await state.userUid,
2024-01-03 15:24:42 +08:00
userMobileIP: await state.userMobileIP,
2024-01-09 11:36:51 +08:00
endData: list);
2024-01-03 15:24:42 +08:00
Get.back();
}
Future<void> _readG711Data() async {
final String filePath = 'assets/s10-g711.bin';
final List<int> audioData = await G711().readAssetFile(filePath);
2024-04-26 15:38:59 +08:00
// AppLog.log('发送读取711文件数据为:$audioData');// 数据为:$audioData
2024-01-03 15:24:42 +08:00
// return;
2024-04-26 15:38:59 +08:00
// AppLog.log('发送读取711文件数据长度为:${audioData.length}');// 数据为:$audioData
2024-01-03 15:24:42 +08:00
if (audioData.isNotEmpty) {
// 在这里处理你的音频数据
// pcmBytes = G711().convertList(audioData);
2024-04-26 15:38:59 +08:00
// AppLog.log('发送转换pcmBytes数据长度为:${pcmBytes.length}');
2024-01-03 15:24:42 +08:00
int start = 0;
final int length = 320;
2024-01-03 15:24:42 +08:00
while (start < audioData.length) {
// await Future.delayed(const Duration(milliseconds: 50));
final int end = (start + length > audioData.length)
2024-01-03 15:24:42 +08:00
? audioData.length
: start + length;
final List<int> sublist = audioData.sublist(start, end);
2024-01-03 15:24:42 +08:00
sendRecordData({
'bytes': sublist,
2024-01-03 15:24:42 +08:00
// "udpSendDataFrameNumber": 0,
'lockID': UDPManage().lockId,
'lockIP': UDPManage().host,
'userMobile': await state.userUid,
'userMobileIP': await state.userMobileIP,
2024-01-03 15:24:42 +08:00
});
2024-04-26 15:38:59 +08:00
AppLog.log(sublist.toString());
2024-01-03 15:24:42 +08:00
start += length;
}
2024-04-26 15:38:59 +08:00
AppLog.log('G711数据发送完成');
2024-01-03 15:24:42 +08:00
} else {
2024-04-26 15:38:59 +08:00
AppLog.log('Failed to read audio data.');
2024-01-03 15:24:42 +08:00
}
}
Future<void> startProcessing() async {
frameListener(List<int> frame) async {
2024-04-26 15:38:59 +08:00
// AppLog.log('Get data.length:${frame.length} Received data:$frame');
2024-01-03 15:24:42 +08:00
for (int i = 0; i < frame.length; i++) {
frame[i] = linearToULaw(frame[i]);
}
2024-04-26 15:38:59 +08:00
// AppLog.log('change Get data.length:${frame.length} change Received data:$frame');
2024-01-03 15:24:42 +08:00
await Future.delayed(const Duration(milliseconds: 50));
sendRecordData({
'bytes': frame,
2024-01-03 15:24:42 +08:00
// "udpSendDataFrameNumber": 0,
'lockID': UDPManage().lockId,
'lockIP': UDPManage().host,
'userMobile': await state.userUid,
'userMobileIP': await state.userMobileIP,
2024-01-03 15:24:42 +08:00
});
}
errorListener(VoiceProcessorException error) {
AppLog.log('VoiceProcessorException: $error');
2024-01-03 15:24:42 +08:00
}
state.voiceProcessor?.addFrameListener(frameListener);
state.voiceProcessor?.addErrorListener(errorListener);
try {
if (await state.voiceProcessor?.hasRecordAudioPermission() ?? false) {
await state.voiceProcessor?.start(320, 8000);
final bool? isRecording = await state.voiceProcessor?.isRecording();
2024-01-03 15:24:42 +08:00
} else {}
} on PlatformException catch (ex) {
AppLog.log('PlatformException: $ex');
2024-01-03 15:24:42 +08:00
} finally {}
}
Future<void> stopProcessing() async {
try {
await state.voiceProcessor?.stop();
} on PlatformException catch (ex) {
AppLog.log('PlatformException: $ex');
2024-01-03 15:24:42 +08:00
} finally {}
}
void onError(Object e) {
2024-04-26 15:38:59 +08:00
AppLog.log(e.toString());
2024-01-03 15:24:42 +08:00
}
sendRecordData(Map<String, dynamic> args) async {
final List<int> bytes = args['bytes'];
2024-01-03 15:24:42 +08:00
// int udpSendDataFrameNumber = args["udpSendDataFrameNumber"];
final String? lockID = args['lockID'];
final String? lockIP = args['lockIP'];
final String? userMobile = args['userMobile'];
final String? userMobileIP = args['userMobileIP'];
2024-01-03 15:24:42 +08:00
state.udpSendDataFrameNumber++;
if (state.udpSendDataFrameNumber >= 65536) state.udpSendDataFrameNumber = 1;
// 57
final List<int> topBytes = [];
2024-01-03 15:24:42 +08:00
topBytes.addAll([
1, 1, 1, 1, // 时间戳
1, 0, // 音频
1, 0, // 帧序号
64, 0, 0, 0, // 帧长度
1, 0, // 总包数
1, 0, // 当前包号
64, 1, // 数据长度
176, 4, // 保留
]);
topBytes[6] = state.udpSendDataFrameNumber & 0x000000FF;
topBytes[7] = (state.udpSendDataFrameNumber & 0x0000FF00) >> 8;
2024-01-03 15:24:42 +08:00
topBytes.addAll(bytes);
AppLog.log('setVoiceBytes:$topBytes');
2024-01-03 15:24:42 +08:00
UDPSenderManage.sendMainProtocol(
command: 152,
2024-01-03 15:24:42 +08:00
commandTypeIsCalling: 1,
subCommand: 8,
lockID: lockID,
lockIP: lockIP,
userMobile: userMobile,
userMobileIP: userMobileIP,
endData: topBytes);
// UDPManage().sendData(topBytes);
}
// 拿到的音频转化成pcm
int linearToULaw(int pcmVal) {
int mask;
int seg;
int uval;
if (pcmVal < 0) {
pcmVal = 0x84 - pcmVal;
mask = 0x7F;
} else {
pcmVal += 0x84;
mask = 0xFF;
}
seg = search(pcmVal);
if (seg >= 8) {
return 0x7F ^ mask;
} else {
uval = seg << 4;
uval |= (pcmVal >> (seg + 3)) & 0xF;
2024-01-03 15:24:42 +08:00
return uval ^ mask;
}
}
int search(int val) {
final List<int> table = [
2024-01-03 15:24:42 +08:00
0xFF,
0x1FF,
0x3FF,
0x7FF,
0xFFF,
0x1FFF,
0x3FFF,
0x7FFF
];
final int size = 8;
2024-01-03 15:24:42 +08:00
for (int i = 0; i < size; i++) {
if (val <= table[i]) {
return i;
}
}
return size;
}
double _calculateVolumeLevel(List<int> frame) {
double rms = 0.0;
for (int sample in frame) {
rms += pow(sample, 2);
}
rms = sqrt(rms / frame.length);
final double dbfs = 20 * log(rms / 32767.0) / log(10);
final double normalizedValue = (dbfs + 50) / 50;
2024-01-03 15:24:42 +08:00
return normalizedValue.clamp(0.0, 1.0);
}
Future<bool> getPermissionStatus() async {
final Permission permission = Permission.microphone;
2024-01-03 15:24:42 +08:00
//granted 通过denied 被拒绝permanentlyDenied 拒绝且不在提示
final PermissionStatus status = await permission.status;
2024-01-03 15:24:42 +08:00
if (status.isGranted) {
return true;
} else if (status.isDenied) {
requestPermission(permission);
} else if (status.isPermanentlyDenied) {
openAppSettings();
} else if (status.isRestricted) {
requestPermission(permission);
} else {}
return false;
}
///申请权限
void requestPermission(Permission permission) async {
final PermissionStatus status = await permission.request();
2024-01-03 15:24:42 +08:00
if (status.isPermanentlyDenied) {
openAppSettings();
}
}
@override
void onReady() {
super.onReady();
_getTVDataRefreshUIAction();
2024-01-05 09:26:12 +08:00
_getUDPStatusRefreshUIAction();
2024-01-03 15:24:42 +08:00
initRecorder();
}
@override
void onInit() {
super.onInit();
}
@override
void onClose() {
CallTalk().finishAVData();
2024-01-03 15:24:42 +08:00
_getTVDataRefreshUIEvent!.cancel();
2024-01-05 09:26:12 +08:00
_getUDPStatusRefreshUIEvent!.cancel();
if (state.oneMinuteTimeTimer != null) {
state.oneMinuteTimeTimer.cancel();
}
2024-01-03 15:24:42 +08:00
stopProcessing();
state.listData.value = Uint8List(0);
2024-01-03 15:24:42 +08:00
}
}