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