fix:增加音视频数据的丢包率判断、调整udp发送和接收缓冲区大小
This commit is contained in:
parent
9f2c049147
commit
bf4c2b4750
@ -50,6 +50,10 @@ import 'package:star_lock/tools/deviceInfo_utils.dart';
|
||||
import 'package:star_lock/tools/storage.dart';
|
||||
import 'package:uuid/uuid.dart';
|
||||
|
||||
// Socket选项常量
|
||||
const int SO_RCVBUF = 8; // 接收缓冲区
|
||||
const int SO_SNDBUF = 7; // 发送缓冲区
|
||||
|
||||
class StartChartManage {
|
||||
// 私有构造函数,防止外部直接new对象
|
||||
StartChartManage._internal();
|
||||
@ -125,6 +129,17 @@ class StartChartManage {
|
||||
// 获取 StartChartTalkStatus 的唯一实例
|
||||
StartChartTalkStatus talkStatus = StartChartTalkStatus.instance;
|
||||
|
||||
// 音视频帧级丢包统计变量
|
||||
final Map<int, Set<int>> _avFrameParts = {};
|
||||
int _avFrameTotal = 0;
|
||||
int _avFrameLost = 0;
|
||||
|
||||
// 查询音视频帧丢包率
|
||||
double getAvFrameLossRate() {
|
||||
if (_avFrameTotal == 0) return 0.0;
|
||||
return _avFrameLost / _avFrameTotal;
|
||||
}
|
||||
|
||||
// 星图服务初始化
|
||||
Future<void> init() async {
|
||||
if (F.isXHJ) {
|
||||
@ -225,6 +240,25 @@ class StartChartManage {
|
||||
var addressIListenFrom = InternetAddress.anyIPv4;
|
||||
RawDatagramSocket.bind(addressIListenFrom, localPort)
|
||||
.then((RawDatagramSocket socket) {
|
||||
|
||||
// 设置接收缓冲区大小 (SO_RCVBUF = 8)
|
||||
socket.setRawOption(
|
||||
RawSocketOption.fromInt(
|
||||
RawSocketOption.levelSocket,
|
||||
8, // SO_RCVBUF for Android/iOS
|
||||
2 * 1024 * 1024, // 2MB receive buffer
|
||||
),
|
||||
);
|
||||
|
||||
// 设置发送缓冲区大小 (SO_SNDBUF = 7)
|
||||
socket.setRawOption(
|
||||
RawSocketOption.fromInt(
|
||||
RawSocketOption.levelSocket,
|
||||
7, // SO_SNDBUF for Android/iOS
|
||||
2 * 1024 * 1024, // 2MB send buffer
|
||||
),
|
||||
);
|
||||
|
||||
_udpSocket = socket;
|
||||
|
||||
/// 广播功能
|
||||
@ -1017,35 +1051,54 @@ class StartChartManage {
|
||||
void _onReceiveData(RawDatagramSocket socket, BuildContext context) {
|
||||
socket.listen((RawSocketEvent event) {
|
||||
if (event == RawSocketEvent.read) {
|
||||
Datagram? dg = socket.receive();
|
||||
try {
|
||||
if (dg?.data != null) {
|
||||
final deserialize = ScpMessage.deserialize(dg!.data);
|
||||
Datagram? dg;
|
||||
while ((dg = socket.receive()) != null) {
|
||||
try {
|
||||
if (dg?.data != null) {
|
||||
final deserialize = ScpMessage.deserialize(dg!.data);
|
||||
|
||||
// //ToDo: 增加对讲调试、正式可删除
|
||||
// UdpTalkDataHandler().updateRecvDataRate(dg.data.length);
|
||||
|
||||
// // 更新调试信息
|
||||
// Provider.of<DebugInfoModel>(context, listen: false).updateDebugInfo(
|
||||
// UdpTalkDataHandler().getLastRecvDataRate() ~/ 1024, // 转换为KB
|
||||
// UdpTalkDataHandler().getLastRecvPacketCount(),
|
||||
// UdpTalkDataHandler().getLastSendDataRate() ~/ 1024, // 转换为KB
|
||||
// UdpTalkDataHandler().getLastSendPacketCount(),
|
||||
// );
|
||||
|
||||
if (deserialize != null) {
|
||||
// 处理返回数据
|
||||
_handleUdpResultData(deserialize);
|
||||
}
|
||||
if (deserialize.PayloadType != PayloadTypeConstant.heartbeat) {
|
||||
if (deserialize.Payload != null) {
|
||||
// _log(text: 'Udp收到结构体数据---》$deserialize');
|
||||
// 音视频帧丢包统计:只统计PayloadType==talkData的数据包,结合分包信息
|
||||
if (deserialize != null &&
|
||||
deserialize.PayloadType == PayloadTypeConstant.talkData) {
|
||||
int? msgId = deserialize.MessageId;
|
||||
int spTotal = deserialize.SpTotal ?? 1;
|
||||
int spIndex = deserialize.SpIndex ?? 1;
|
||||
if (msgId != null) {
|
||||
// 记录收到的分包
|
||||
_avFrameParts.putIfAbsent(msgId, () => <int>{});
|
||||
_avFrameParts[msgId]!.add(spIndex);
|
||||
// 如果收到最后一个分包,判断该帧是否完整
|
||||
if (spIndex == spTotal) {
|
||||
_avFrameTotal++;
|
||||
if (_avFrameParts[msgId]!.length < spTotal) {
|
||||
_avFrameLost++;
|
||||
// _log(text: '音视频丢包,丢失的messageId: $msgId');
|
||||
}
|
||||
_avFrameParts.remove(msgId);
|
||||
// 可选:每100帧打印一次丢包率
|
||||
if (_avFrameTotal % 100 == 0) {
|
||||
_log(
|
||||
text:
|
||||
'音视频帧丢包率: ${(getAvFrameLossRate() * 100).toStringAsFixed(2)}%');
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (deserialize != null) {
|
||||
// 处理返回数据
|
||||
_handleUdpResultData(deserialize);
|
||||
}
|
||||
// if (deserialize.PayloadType != PayloadTypeConstant.heartbeat) {
|
||||
// if (deserialize.Payload != null) {
|
||||
// _log(text: 'Udp收到结构体数据---》$deserialize');
|
||||
// }
|
||||
// _log(text: 'text---》${utf8.decode(deserialize.Payload)}');
|
||||
// }
|
||||
}
|
||||
} catch (e, stackTrace) {
|
||||
throw StartChartMessageException('$e\n,$stackTrace');
|
||||
}
|
||||
} catch (e, stackTrace) {
|
||||
throw StartChartMessageException('$e\n,$stackTrace');
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user