diff --git a/assets/html/h264.html b/assets/html/h264.html
index 97143565..63303e3c 100644
--- a/assets/html/h264.html
+++ b/assets/html/h264.html
@@ -56,7 +56,7 @@
},
flushingTime: 0, // 禁用自动刷新
clearBuffer: false, // 保留解码缓存
- maxBufferLength: 2,
+ fps:20,
onReady: () => {
console.log('播放器初始化完成');
// 通知Flutter端准备就绪
diff --git a/lib/main/lockDetail/lockDetail/lockDetail_state.dart b/lib/main/lockDetail/lockDetail/lockDetail_state.dart
index 5e168524..760f1289 100755
--- a/lib/main/lockDetail/lockDetail/lockDetail_state.dart
+++ b/lib/main/lockDetail/lockDetail/lockDetail_state.dart
@@ -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 keyInfos = LockListInfoItemEntity().obs;
-
+ final Rx lockSetInfoData = LockSetInfoData().obs;
late StreamSubscription replySubscription;
StreamSubscription? lockSetOpenOrCloseCheckInRefreshLockDetailWithAttendanceEvent;
StreamSubscription? LockSetChangeSetRefreshLockDetailWithTypeSubscription;
diff --git a/lib/talk/starChart/handle/impl/udp_talk_data_handler.dart b/lib/talk/starChart/handle/impl/udp_talk_data_handler.dart
index a95b1c78..cb00a0d3 100644
--- a/lib/talk/starChart/handle/impl/udp_talk_data_handler.dart
+++ b/lib/talk/starChart/handle/impl/udp_talk_data_handler.dart
@@ -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}");
}
/// 处理图片数据
diff --git a/lib/talk/starChart/handle/other/h264_frame_handler.dart b/lib/talk/starChart/handle/other/h264_frame_handler.dart
index 5eaa27df..2b4ea1ee 100644
--- a/lib/talk/starChart/handle/other/h264_frame_handler.dart
+++ b/lib/talk/starChart/handle/other/h264_frame_handler.dart
@@ -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 _frameBuffer = {};
+ final LinkedHashMap _frameBuffer = LinkedHashMap();
final void Function(List frameData) onCompleteFrame;
- int _lastProcessedSeq = -1;
+
+ final LinkedHashMap _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 sortedSeqs = _frameBuffer.keys.toList()..sort();
final List 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 frameSeqs) {
// 按顺序组装帧数据
- final List assembledData = [];
+ // final List 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);
+ }
}