import 'dart:convert'; import 'dart:io'; import 'package:get/get.dart'; import 'package:star_lock/appRouters.dart'; import 'package:star_lock/app_settings/app_settings.dart'; import 'package:star_lock/main/lockMian/entity/lockListInfo_entity.dart'; import 'package:star_lock/talk/starChart/constant/message_type_constant.dart'; import 'package:star_lock/talk/starChart/constant/talk_status.dart'; import 'package:star_lock/talk/starChart/entity/scp_message.dart'; import 'package:star_lock/talk/starChart/handle/scp_message_base_handle.dart'; import 'package:star_lock/talk/starChart/handle/scp_message_handle.dart'; import 'package:star_lock/talk/starChart/proto/generic.pb.dart'; import 'package:star_lock/talk/starChart/proto/talk_expect.pb.dart'; import 'package:star_lock/talk/starChart/proto/talk_request.pb.dart'; import 'package:star_lock/tools/commonDataManage.dart'; import 'package:star_lock/tools/push/xs_jPhush.dart'; import 'package:star_lock/tools/storage.dart'; import 'package:star_lock/translations/current_locale_tool.dart'; class UdpTalkRequestHandler extends ScpMessageBaseHandle implements ScpMessageHandler { RxString currentLanguage = CurrentLocaleTool.getCurrentLocaleString().obs; // 当前选择语言 @override void handleReq(ScpMessage scpMessage) async { // 判断是否登录账户 final loginData = await Storage.getLoginData(); // 如果登录账户不为空,且不是被动接听状态,且不是接听成功状态 if (loginData != null && (talkStatus.status != TalkStatus.passiveCallWaitingAnswer || talkStatus.status != TalkStatus.answeredSuccessfully)) { // 收到对讲请求 final TalkReq talkReq = scpMessage.Payload; startChartManage.FromPeerId = scpMessage.ToPeerId!; startChartManage.ToPeerId = scpMessage.FromPeerId!; startChartManage.lockPeerId = scpMessage.FromPeerId!; // 处理收到接听请求后的事件 _talkRequestEvent( talkObjectName: talkReq.callerName, lockPeerID: scpMessage.FromPeerId!, ); // 回复成功 replySuccessMessage(scpMessage); } else { // 拒绝接听,回复失败 replyErrorMessage(scpMessage); AppLog.log('正在接听,回复拒绝'); } } @override void handleResp(ScpMessage scpMessage) { // 收到对讲请求回复 final GenericResp genericResp = scpMessage.Payload; if (checkGenericRespSuccess(genericResp)) { // 收到对讲请求的应答 startChartManage.FromPeerId = scpMessage.ToPeerId!; startChartManage.ToPeerId = scpMessage.FromPeerId!; startChartManage.lockPeerId = scpMessage.FromPeerId!; // 处理预期数据格式 _handleResponseSendExpect( lockPeerID: scpMessage.FromPeerId!, ); // 发送预期数据 startChartManage.startTalkExpectTimer(); // 停止发送对讲请求 startChartManage.stopCallRequestMessageTimer(); // 收到应答后取消超时判断 talkeRequestOverTimeTimerManager.cancel(); // 启动发送ping startChartManage.startTalkPingMessageTimer(); // 启动ping命令超时判断 talkePingOverTimeTimerManager.start(); } } @override void handleInvalidReq(ScpMessage scpMessage) {} @override void handleRealTimeData(ScpMessage scpMessage) {} // 来电事件的处理 void _talkRequestEvent({ required String talkObjectName, required String lockPeerID, }) async { // 发送预期数据、通知锁板需要获取视频数据 _handleRequestSendExpect(lockPeerID: lockPeerID); // 播放铃声 //test:使用自定义铃声 playRingtone(); // 显示状态栏弹窗 // _showTalkRequestNotification(talkObjectName: talkObjectName); // 设置为等待接听状态 talkStatus.setPassiveCallWaitingAnswer(); // 获取锁支持项 final LockListInfoItemEntity currentKeyInfo = CommonDataManage().currentKeyInfo; var isWifiLockType = currentKeyInfo.lockFeature?.wifiLockType == 1; final LockListInfoGroupEntity? lockListInfoGroupEntity = await Storage.getLockMainListData(); if (lockListInfoGroupEntity != null) { lockListInfoGroupEntity!.groupList?.forEach((element) { final lockList = element.lockList; if (lockList != null && lockList.length != 0) { for (var lockInfo in lockList) { final peerId = lockInfo.network?.peerId; if (peerId != null && peerId != '') { if (peerId == lockPeerID) { isWifiLockType = lockInfo.lockFeature?.wifiLockType == 1; } } } } }); } if (isWifiLockType) { Get.toNamed(Routers.imageTransmissionView); return; } if (startChartManage .getDefaultTalkExpect() .videoType .contains(VideoTypeE.H264)) { Get.toNamed( Routers.h264WebView, ); } else { Get.toNamed( Routers.starChartTalkView, ); } } // 收到来电请求时进行本地通知 Future _showTalkRequestNotification( {required String talkObjectName}) async { if (Platform.isAndroid) { final Map message = { 'platform': 'all', 'audience': 'all', 'notification': >{ 'android': { 'title': '呼叫提醒'.tr, 'alert': '${'收到来自'.tr}($talkObjectName)${'锁的呼叫'.tr}。', 'extras': { 'image_url': 'https://image.baidu.com/search/detail?ct=503316480&z=0&ipn=d&word=视频通话图标&step_word=&hs=0&pn=18&spn=0&di=7456461798821068801&pi=0&rn=1&tn=baiduimagedetail&is=0%2C0&istype=0&ie=utf-8&oe=utf-8&in=&cl=2&lm=-1&st=undefined&cs=3670633426%2C2210940696&os=2119936476%2C3383901310&simid=3670633426%2C2210940696&adpicid=0&lpn=0&ln=1216&fr=&fmq=1738909566404_R&fm=&ic=undefined&s=undefined&hd=undefined&latest=undefined©right=undefined&se=&sme=&tab=0&width=undefined&height=undefined&face=undefined&ist=&jit=&cg=&bdtype=0&oriquery=&objurl=https%3A%2F%2Ftenfei03.cfp.cn%2Fcreative%2Fvcg%2Fnowarter800%2Fnew%2FVCG211249198901.jpg&fromurl=ippr_z2C%24qAzdH3FAzdH3Fooo_z%26e3Bev2_z%26e3Bv54AzdH3Fv6jwptejAzdH3F8dnla9lla0&gsm=1e&rpstart=0&rpnum=0&islist=&querylist=&nojc=undefined&dyTabStr=MCwxMiwzLDEsMiwxMyw3LDYsNSw5&lid=9610633549467928081' } } } }; if (currentLanguage.value == 'zh_CN') { XSJPushProvider().showCustomNotification(message); } } /* const AndroidNotificationDetails androidPlatformChannelSpecifics = AndroidNotificationDetails('1', 'flutter_channel', importance: Importance.max, priority: Priority.high, playSound: true, ticker: 'ticker'); const NotificationDetails platformChannelSpecifics = NotificationDetails(android: androidPlatformChannelSpecifics); // 获取锁名 // String? getLockName = await Storage.getString(saveLockAlias); final FlutterLocalNotificationsPlugin flutterLocalNotificationsPlugin = FlutterLocalNotificationsPlugin(); // 执行本地通知 await flutterLocalNotificationsPlugin.show(0, '呼叫提醒'.tr, '${'收到来自'.tr}($talkObjectName)${'锁的呼叫'.tr}。', platformChannelSpecifics, payload: 'item x'); */ } @override deserializePayload( {required int payloadType, required int messageType, required List byte, int? offset, int? PayloadLength, int? spTotal, int? spIndex, int? messageId}) { if (messageType == MessageTypeConstant.Resp) { final GenericResp genericResp = GenericResp(); genericResp.mergeFromBuffer(byte); return genericResp; } else if (messageType == MessageTypeConstant.Req) { final TalkReq talkReq = TalkReq(); talkReq.mergeFromBuffer(byte); return talkReq; } else { String payload = utf8.decode(byte); return payload; } } /// app收到的对讲请求后,发送的预期数据 void _handleRequestSendExpect({ required String lockPeerID, }) async { final LockListInfoItemEntity currentKeyInfo = CommonDataManage().currentKeyInfo; var isH264 = currentKeyInfo.lockFeature?.isH264 == 1; var isMJpeg = currentKeyInfo.lockFeature?.isMJpeg == 1; final LockListInfoGroupEntity? lockListInfoGroupEntity = await Storage.getLockMainListData(); if (lockListInfoGroupEntity != null) { lockListInfoGroupEntity!.groupList?.forEach((element) { final lockList = element.lockList; if (lockList != null && lockList.length != 0) { for (var lockInfo in lockList) { final peerId = lockInfo.network?.peerId; if (peerId != null && peerId != '') { if (peerId == lockPeerID) { isH264 = lockInfo.lockFeature?.isH264 == 1; isMJpeg = lockInfo.lockFeature?.isMJpeg == 1; } } } } }); } // 优先使用H264,其次是MJPEG if (isH264) { // 锁支持H264,发送H264视频和G711音频期望 startChartManage.sendOnlyH264VideoTalkExpectData(); print( 'app收到的对讲请求后,发送的预期数据=========锁支持H264,发送H264视频格式期望数据,peerID=${lockPeerID}'); } else if (isMJpeg) { // 锁只支持MJPEG,发送图像视频和G711音频期望 startChartManage.sendOnlyImageVideoTalkExpectData(); print( 'app收到的对讲请求后,发送的预期数据=========锁不支持H264,支持MJPEG,发送MJPEG视频格式期望数据,peerID=${lockPeerID}'); } else { // 默认使用图像视频 startChartManage.sendOnlyImageVideoTalkExpectData(); print( 'app收到的对讲请求后,发送的预期数据=========锁不支持H264和MJPEG,默认发送MJPEG视频格式期望数据,peerID=${lockPeerID}'); } } /// app主动发请求,收到回复后发送的预期数据 void _handleResponseSendExpect({ required String lockPeerID, }) async { final LockListInfoItemEntity currentKeyInfo = CommonDataManage().currentKeyInfo; var isH264 = currentKeyInfo.lockFeature?.isH264 == 1; var isMJpeg = currentKeyInfo.lockFeature?.isMJpeg == 1; final LockListInfoGroupEntity? lockListInfoGroupEntity = await Storage.getLockMainListData(); if (lockListInfoGroupEntity != null) { lockListInfoGroupEntity!.groupList?.forEach((element) { final lockList = element.lockList; if (lockList != null && lockList.length != 0) { for (var lockInfo in lockList) { final peerId = lockInfo.network?.peerId; if (peerId != null && peerId != '') { if (peerId == lockPeerID) { isH264 = lockInfo.lockFeature?.isH264 == 1; isMJpeg = lockInfo.lockFeature?.isMJpeg == 1; } } } } }); } // 优先使用H264,其次是MJPEG if (isH264) { // 锁支持H264,发送H264视频和G711音频期望 startChartManage.sendH264VideoAndG711AudioTalkExpectData(); AppLog.log( 'app主动发对讲请求,收到回复后发送的预期数据=======锁支持H264,发送H264视频格式期望数据,peerID=${lockPeerID}'); } else if (isMJpeg) { // 锁只支持MJPEG,发送图像视频和G711音频期望 startChartManage.sendImageVideoAndG711AudioTalkExpectData(); AppLog.log( 'app主动发对讲请求,收到回复后发送的预期数据=======锁不支持H264,支持MJPEG,发送MJPEG视频格式期望数据,peerID=${lockPeerID}'); } else { // 默认使用图像视频 startChartManage.sendImageVideoAndG711AudioTalkExpectData(); AppLog.log( 'app主动发对讲请求,收到回复后发送的预期数据=======锁不支持H264和MJPEG,默认发送MJPEG视频格式期望数据,peerID=${lockPeerID}'); } } }