1.查看操作记录按门铃带图片问题
2.视频对讲优化
This commit is contained in:
parent
dfb368d822
commit
d3969b6ba5
@ -142,7 +142,6 @@ class ConfiguringWifiLogic extends BaseGetXController {
|
||||
String result = utf8String(secretKeyList);
|
||||
|
||||
AppLog.log('解析配网信息: $result');
|
||||
AppLog.log('使用传入的RSSI值: ${state.rssi.value}');
|
||||
|
||||
// 解析 JSON 字符串为 Map
|
||||
Map<String, dynamic> jsonMap = json.decode(result);
|
||||
|
||||
@ -318,7 +318,7 @@ class _MessageListPageState extends State<MessageListPage>
|
||||
Container(
|
||||
width: 0.5,
|
||||
height: 120.h,
|
||||
color: AppColors.placeholderTextColor,
|
||||
color: Color.fromRGBO(0, 0, 0, 0.2),
|
||||
)
|
||||
],
|
||||
)),
|
||||
@ -352,12 +352,13 @@ class _MessageListPageState extends State<MessageListPage>
|
||||
),
|
||||
child: Container(
|
||||
width: 1.sw,
|
||||
margin: EdgeInsets.only(left: 20.w, right: 20.w, top: 8.h),
|
||||
margin: EdgeInsets.only(left: 20.w, right: 20.w, top: 20.h, bottom: 20.h),
|
||||
child: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: <Widget>[
|
||||
Wrap(
|
||||
children: <Widget>[
|
||||
// 时间
|
||||
Container(
|
||||
margin: EdgeInsets.only(top: 4.h),
|
||||
child: Text(
|
||||
@ -370,6 +371,7 @@ class _MessageListPageState extends State<MessageListPage>
|
||||
),
|
||||
),
|
||||
),
|
||||
// 竖线
|
||||
Container(
|
||||
width: 1,
|
||||
height: 10,
|
||||
@ -378,8 +380,10 @@ class _MessageListPageState extends State<MessageListPage>
|
||||
? AppColors.blackColor
|
||||
: AppColors.placeholderTextColor,
|
||||
),
|
||||
Container(transform: Matrix4.translationValues(0, -22, 0),
|
||||
child: Text(' ${messageItemEntity.data!}',
|
||||
// 标题
|
||||
Container(
|
||||
margin: EdgeInsets.only(top: 2.h),
|
||||
child: Text('${messageItemEntity.data!}',
|
||||
maxLines: 2,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
style: TextStyle(
|
||||
@ -389,7 +393,7 @@ class _MessageListPageState extends State<MessageListPage>
|
||||
: AppColors.placeholderTextColor,
|
||||
),
|
||||
)),
|
||||
Container(transform: Matrix4.translationValues(0, -8, 0), child: GestureDetector(
|
||||
Container(margin: EdgeInsets.only(top: 10.h), child: GestureDetector(
|
||||
child: Text('点击查看', style: TextStyle(fontWeight: FontWeight.w500, fontSize: 20.sp, color: AppColors.mainColor),),
|
||||
),alignment: Alignment.centerRight,)
|
||||
],
|
||||
|
||||
@ -44,29 +44,6 @@ class TalkViewNativeDecodeLogic extends BaseGetXController {
|
||||
// 添加成员变量缓存帧索引
|
||||
final Map<TalkDataH264Frame_FrameTypeE, List<MapEntry<int, int>>> _frameIndexCache = {};
|
||||
bool _frameIndexDirty = true;
|
||||
// 更新帧缓冲区时标记索引为脏数据
|
||||
void _invalidateFrameIndex() {
|
||||
_frameIndexDirty = true;
|
||||
}
|
||||
// 构建帧索引
|
||||
List<MapEntry<int, int>> _buildFrameIndex(TalkDataH264Frame_FrameTypeE frameType) {
|
||||
if (!_frameIndexDirty && _frameIndexCache.containsKey(frameType)) {
|
||||
return _frameIndexCache[frameType]!;
|
||||
}
|
||||
|
||||
final List<MapEntry<int, int>> index = [];
|
||||
for (int i = 0; i < state.h264FrameBuffer.length; i++) {
|
||||
final frame = state.h264FrameBuffer[i];
|
||||
if (frame['frameType'] == frameType) {
|
||||
index.add(MapEntry(frame['frameSeq'] as int, i));
|
||||
}
|
||||
}
|
||||
index.sort((a, b) => a.key.compareTo(b.key));
|
||||
|
||||
_frameIndexCache[frameType] = index;
|
||||
_frameIndexDirty = false;
|
||||
return index;
|
||||
}
|
||||
|
||||
// 添加网络质量评估变量
|
||||
int _networkQualityScore = 5; // 1-5分,5为最佳
|
||||
@ -532,6 +509,30 @@ class TalkViewNativeDecodeLogic extends BaseGetXController {
|
||||
}
|
||||
}
|
||||
|
||||
// 更新帧缓冲区时标记索引为脏数据
|
||||
void _invalidateFrameIndex() {
|
||||
_frameIndexDirty = true;
|
||||
}
|
||||
// 构建帧索引
|
||||
List<MapEntry<int, int>> _buildFrameIndex(TalkDataH264Frame_FrameTypeE frameType) {
|
||||
if (!_frameIndexDirty && _frameIndexCache.containsKey(frameType)) {
|
||||
return _frameIndexCache[frameType]!;
|
||||
}
|
||||
|
||||
final List<MapEntry<int, int>> index = [];
|
||||
for (int i = 0; i < state.h264FrameBuffer.length; i++) {
|
||||
final frame = state.h264FrameBuffer[i];
|
||||
if (frame['frameType'] == frameType) {
|
||||
index.add(MapEntry(frame['frameSeq'] as int, i));
|
||||
}
|
||||
}
|
||||
index.sort((a, b) => a.key.compareTo(b.key));
|
||||
|
||||
_frameIndexCache[frameType] = index;
|
||||
_frameIndexDirty = false;
|
||||
return index;
|
||||
}
|
||||
|
||||
int _findEarliestIFrame() {
|
||||
final iFrameIndexes = _buildFrameIndex(TalkDataH264Frame_FrameTypeE.I);
|
||||
return iFrameIndexes.isNotEmpty ? iFrameIndexes.first.value : -1;
|
||||
@ -1344,7 +1345,7 @@ class TalkViewNativeDecodeLogic extends BaseGetXController {
|
||||
try {
|
||||
// 使用较短超时时间
|
||||
final textureId = await VideoDecodePlugin.initDecoder(config)
|
||||
.timeout(Duration(milliseconds: 800));
|
||||
.timeout(Duration(milliseconds: 500));
|
||||
|
||||
if (textureId != null) {
|
||||
state.textureId.value = textureId;
|
||||
|
||||
@ -41,7 +41,7 @@ class TalkViewLogic extends BaseGetXController {
|
||||
|
||||
final LockDetailState lockDetailState = Get.put(LockDetailLogic()).state;
|
||||
|
||||
int bufferSize = 8; // 增大缓冲区,满时才渲染
|
||||
int bufferSize = 3; // 增大缓冲区,满时才渲染
|
||||
|
||||
int audioBufferSize = 2; // 音频默认缓冲2帧
|
||||
bool _isFirstAudioFrame = true; // 是否是第一帧
|
||||
@ -123,11 +123,12 @@ class TalkViewLogic extends BaseGetXController {
|
||||
_playAudioFrames();
|
||||
break;
|
||||
case TalkData_ContentTypeE.Image:
|
||||
// 如果缓冲区已满,移除最旧的帧
|
||||
if (state.videoBuffer.length >= bufferSize) {
|
||||
state.videoBuffer.removeAt(0);
|
||||
}
|
||||
// 固定长度缓冲区,最多保留bufferSize帧
|
||||
state.videoBuffer.add(talkData);
|
||||
if (state.videoBuffer.length > bufferSize) {
|
||||
state.videoBuffer.removeAt(0); // 移除最旧帧
|
||||
}
|
||||
break;
|
||||
}
|
||||
});
|
||||
@ -370,12 +371,21 @@ class TalkViewLogic extends BaseGetXController {
|
||||
|
||||
requestPermissions();
|
||||
|
||||
bool _isValidImageData(List<int> data) {
|
||||
// 检查数据长度
|
||||
if (data.length < 10) return false;
|
||||
// 检查JPEG格式 (0xFFD8FF)
|
||||
if (data[0] == 0xFF && data[1] == 0xD8 && data[2] == 0xFF) return true;
|
||||
// 检查PNG格式 (0x89504E47)
|
||||
if (data[0] == 0x89 && data[1] == 0x50 && data[2] == 0x4E && data[3] == 0x47) return true;
|
||||
return false;
|
||||
}
|
||||
// 启动视频渲染定时器(10fps)
|
||||
videoRenderTimer = Timer.periodic(const Duration(milliseconds: 100), (_) {
|
||||
final int now = DateTime.now().millisecondsSinceEpoch;
|
||||
if (state.videoBuffer.isNotEmpty) {
|
||||
final TalkData oldestFrame = state.videoBuffer.removeAt(0);
|
||||
if (oldestFrame.content.isNotEmpty) {
|
||||
if (oldestFrame.content.isNotEmpty && _isValidImageData(oldestFrame.content)) {
|
||||
state.listData.value =
|
||||
Uint8List.fromList(oldestFrame.content); // 备份原始数据
|
||||
final int decodeStart = DateTime.now().millisecondsSinceEpoch;
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user