diff --git a/lib/talk/starChart/views/talkView/talk_view_logic.dart b/lib/talk/starChart/views/talkView/talk_view_logic.dart index 63fbafc7..c901d5ab 100644 --- a/lib/talk/starChart/views/talkView/talk_view_logic.dart +++ b/lib/talk/starChart/views/talkView/talk_view_logic.dart @@ -47,7 +47,9 @@ class TalkViewLogic extends BaseGetXController { // 添加开始时间记录 int _startTime = 0; // 开始播放时间戳 + int _startAudioTime = 0; // 开始播放时间戳 bool _isFirstFrame = true; // 是否是第一帧 + bool _isFirstAudioFrame = true; // 是否是第一帧 // 定义音频帧缓冲和发送函数 final List _bufferedAudioFrames = []; @@ -90,16 +92,28 @@ class TalkViewLogic extends BaseGetXController { final contentType = talkData.contentType; final currentTime = DateTime.now().millisecondsSinceEpoch; - // 第一帧到达时记录开始时间 - if (_isFirstFrame) { - _startTime = currentTime; - _isFirstFrame = false; - } - // 判断数据类型,进行分发处理 switch (contentType) { case TalkData_ContentTypeE.G711: - if (state.audioBuffer.length >= bufferSize) { + // 第一帧到达时记录开始时间 + if (_isFirstAudioFrame) { + _startAudioTime = currentTime; + _isFirstAudioFrame = false; + } + + // 计算音频延迟 + final expectedTime = _startAudioTime + talkData.durationMs; + final audioDelay = currentTime - expectedTime; + + // 如果延迟太大,清空缓冲区并直接播放 + if (audioDelay > 500) { + state.audioBuffer.clear(); + if (state.isOpenVoice.value) { + _playAudioFrames(); + } + return; + } + if (state.audioBuffer.length >= audioBufferSize) { state.audioBuffer.removeAt(0); // 丢弃最旧的数据 } state.audioBuffer.add(talkData); // 添加新数据 @@ -107,9 +121,17 @@ class TalkViewLogic extends BaseGetXController { _playAudioFrames(); break; case TalkData_ContentTypeE.Image: - // 计算实际延迟:(当前系统时间 - 开始时间) - 帧的预期播放时间 + // 第一帧到达时记录开始时间 + if (_isFirstFrame) { + _startTime = currentTime; + _isFirstFrame = false; + AppLog.log('记录第一帧的时间戳${currentTime},${talkData.durationMs}'); + } + + // 计算实际延迟:当前时间 - 预期播放时间 final expectedTime = _startTime + talkData.durationMs; - final videoDelay = currentTime - expectedTime; + final videoDelay = currentTime - expectedTime; // 修改延迟计算方式 + // 动态调整缓冲区 _adjustBufferSize(videoDelay); // 然后添加到播放缓冲区