Merge branch 'develop_liyi' into 'canary_release'
Develop liyi See merge request StarlockTeam/app-starlock!17
This commit is contained in:
commit
306b366f73
@ -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<String, ui.Image> _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<void> 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<void> 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<void> _onFrame(List<int> frame) async {
|
||||
// 添加最大缓冲限制
|
||||
if (_bufferedAudioFrames.length > state.frameLength * 3) {
|
||||
_bufferedAudioFrames.clear(); // 清空过多积累的数据
|
||||
return;
|
||||
}
|
||||
|
||||
// 首先应用固定增益提升基础音量
|
||||
List<int> amplifiedFrame = _applyGain(frame, 1.6);
|
||||
// 编码为G711数据
|
||||
List<int> 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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -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<DateTime> startRecordingAudioTime = DateTime.now().obs; // 开始录音时间
|
||||
Rx<DateTime> 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
|
||||
|
||||
@ -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';
|
||||
|
||||
@ -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
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user