diff --git a/lib/talk/starChart/views/talkView/talk_view_logic.dart b/lib/talk/starChart/views/talkView/talk_view_logic.dart index 523742c4..8c0e3737 100644 --- a/lib/talk/starChart/views/talkView/talk_view_logic.dart +++ b/lib/talk/starChart/views/talkView/talk_view_logic.dart @@ -7,7 +7,6 @@ import 'package:flutter/foundation.dart'; import 'package:flutter/rendering.dart'; import 'package:flutter/services.dart'; import 'package:flutter_pcm_sound/flutter_pcm_sound.dart'; -import 'package:flutter_screen_recording/flutter_screen_recording.dart'; import 'package:flutter_voice_processor/flutter_voice_processor.dart'; import 'package:gallery_saver/gallery_saver.dart'; import 'package:get/get.dart'; @@ -57,6 +56,11 @@ class TalkViewLogic extends BaseGetXController { final Map _imageCache = {}; + // 添加帧率计算相关变量 + int _frameCount = 0; + int _lastFpsUpdateTime = 0; + Timer? _fpsTimer; + /// 初始化音频播放器 void _initFlutterPcmSound() { const int sampleRate = 8000; @@ -176,6 +180,17 @@ class TalkViewLogic extends BaseGetXController { state.listData.value = Uint8List.fromList(oldestFrame.content); state.videoBuffer.removeAt(oldestIndex); // 移除已播放的帧 + // 更新帧率计算 + _frameCount++; + final currentTime = DateTime.now().millisecondsSinceEpoch; + final elapsed = currentTime - _lastFpsUpdateTime; + + if (elapsed >= 1000) { + // 每秒更新一次 + state.fps.value = (_frameCount * 1000 / elapsed).round(); + _frameCount = 0; + _lastFpsUpdateTime = currentTime; + } // AppLog.log('🎬 播放帧 - 缓冲区剩余: ${state.videoBuffer.length}/${bufferSize}, ' // '播放延迟: ${currentTime - oldestFrame.durationMs}ms, ' // '帧时间戳: ${oldestFrame.durationMs}'); @@ -420,35 +435,35 @@ class TalkViewLogic extends BaseGetXController { } Future startRecording() async { - requestPermissions(); - if (state.isRecordingScreen.value) { - showToast('录屏已开始,请勿重复点击'); - } - bool start = await FlutterScreenRecording.startRecordScreen( - "Screen Recording", // 视频文件名 - titleNotification: "Recording in progress", // 通知栏标题 - messageNotification: "Tap to stop recording", // 通知栏内容 - ); - - if (start) { - state.isRecordingScreen.value = true; - } + // requestPermissions(); + // if (state.isRecordingScreen.value) { + // showToast('录屏已开始,请勿重复点击'); + // } + // bool start = await FlutterScreenRecording.startRecordScreen( + // "Screen Recording", // 视频文件名 + // titleNotification: "Recording in progress", // 通知栏标题 + // messageNotification: "Tap to stop recording", // 通知栏内容 + // ); + // + // if (start) { + // state.isRecordingScreen.value = true; + // } } Future stopRecording() async { - String path = await FlutterScreenRecording.stopRecordScreen; - print("Recording saved to: $path"); - - // 将视频保存到系统相册 - bool? success = await GallerySaver.saveVideo(path); - if (success == true) { - print("Video saved to gallery"); - } else { - print("Failed to save video to gallery"); - } - - showToast('录屏结束,已保存到系统相册'); - state.isRecordingScreen.value = false; + // String path = await FlutterScreenRecording.stopRecordScreen; + // print("Recording saved to: $path"); + // + // // 将视频保存到系统相册 + // bool? success = await GallerySaver.saveVideo(path); + // if (success == true) { + // print("Video saved to gallery"); + // } else { + // print("Failed to save video to gallery"); + // } + // + // showToast('录屏结束,已保存到系统相册'); + // state.isRecordingScreen.value = false; } @override @@ -496,6 +511,7 @@ class TalkViewLogic extends BaseGetXController { state.oneMinuteTimeTimer?.cancel(); // 取消旧定时器 state.oneMinuteTimeTimer = null; // 取消旧定时器 state.oneMinuteTime.value = 0; + super.onClose(); } @@ -659,32 +675,39 @@ class TalkViewLogic extends BaseGetXController { // 音频帧处理 Future _onFrame(List frame) async { + // 添加最大缓冲限制 + if (_bufferedAudioFrames.length > state.frameLength * 3) { + _bufferedAudioFrames.clear(); // 清空过多积累的数据 + return; + } + // 首先应用固定增益提升基础音量 List amplifiedFrame = _applyGain(frame, 1.6); // 编码为G711数据 List encodedData = G711Tool.encode(amplifiedFrame, 0); // 0表示A-law _bufferedAudioFrames.addAll(encodedData); - - final int ms = DateTime.now().millisecondsSinceEpoch - - state.startRecordingAudioTime.value.millisecondsSinceEpoch; + // 使用相对时间戳 + final int ms = DateTime.now().millisecondsSinceEpoch % 1000000; // 使用循环时间戳 int getFrameLength = state.frameLength; if (Platform.isIOS) { getFrameLength = state.frameLength * 2; } - if (_bufferedAudioFrames.length >= getFrameLength) { - // 发送音频数据到UDP - await StartChartManage() - .sendTalkDataMessage( - talkData: TalkData( - content: _bufferedAudioFrames, - contentType: TalkData_ContentTypeE.G711, - durationMs: ms, - ), - ) - .then((value) { - _bufferedAudioFrames.clear(); - }); + // 添加发送间隔控制 + if (_bufferedAudioFrames.length >= state.frameLength) { + try { + await StartChartManage().sendTalkDataMessage( + talkData: TalkData( + content: _bufferedAudioFrames, + contentType: TalkData_ContentTypeE.G711, + durationMs: ms, + ), + ); + } finally { + _bufferedAudioFrames.clear(); // 确保清理缓冲区 + } + } else { + _bufferedAudioFrames.addAll(encodedData); } } diff --git a/lib/talk/starChart/views/talkView/talk_view_state.dart b/lib/talk/starChart/views/talkView/talk_view_state.dart index 1ff29b5e..aafc8605 100644 --- a/lib/talk/starChart/views/talkView/talk_view_state.dart +++ b/lib/talk/starChart/views/talkView/talk_view_state.dart @@ -45,6 +45,7 @@ class TalkViewState { late Timer answerTimer; late Timer hangUpTimer; late Timer openDoorTimer; + Timer? fpsTimer; late AnimationController animationController; late Timer autoBackTimer = @@ -79,7 +80,7 @@ class TalkViewState { Rx startRecordingAudioTime = DateTime.now().obs; // 开始录音时间 Rx endRecordingAudioTime = DateTime.now().obs; // 结束录音时间 RxInt recordingAudioTime = 0.obs; // 录音时间持续时间 - RxDouble fps = 0.0.obs; // 添加 FPS 计数 + RxInt fps = 0.obs; // 添加 FPS 计数 late VoiceProcessor? voiceProcessor; // 音频处理器、录音 final int frameLength = 320; //录音视频帧长度为640 final int sampleRate = 8000; //录音频采样率为8000 diff --git a/lib/talk/starChart/webView/h264_web_logic.dart b/lib/talk/starChart/webView/h264_web_logic.dart index e8e28784..4b7edc5e 100644 --- a/lib/talk/starChart/webView/h264_web_logic.dart +++ b/lib/talk/starChart/webView/h264_web_logic.dart @@ -7,7 +7,6 @@ import 'package:flutter/foundation.dart'; import 'package:flutter/rendering.dart'; import 'package:flutter/services.dart'; import 'package:flutter_pcm_sound/flutter_pcm_sound.dart'; -import 'package:flutter_screen_recording/flutter_screen_recording.dart'; import 'package:flutter_voice_processor/flutter_voice_processor.dart'; import 'package:gallery_saver/gallery_saver.dart'; import 'package:get/get.dart'; diff --git a/pubspec.yaml b/pubspec.yaml index 12e5cd85..f0f95559 100755 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -266,7 +266,7 @@ dependencies: # fast_rsa: ^3.6.6 protobuf: ^3.1.0 #录屏 - flutter_screen_recording: 2.0.16 + #flutter_screen_recording: 2.0.16 #图库保存 gallery_saver: ^2.3.2 fixnum: ^1.1.1