feat: 对讲中APP发送录音到锁声量增大
This commit is contained in:
parent
9aac85f20e
commit
6adc1b41d3
@ -46,6 +46,8 @@ class TalkViewLogic extends BaseGetXController {
|
||||
int audioFrameIntervalMs = 20; // 初始帧间隔设置为45毫秒(约22FPS)
|
||||
int minFrameIntervalMs = 30; // 最小帧间隔(约33 FPS)
|
||||
int maxFrameIntervalMs = 100; // 最大帧间隔(约1 FPS)
|
||||
// 定义音频帧缓冲和发送函数
|
||||
List<int> _bufferedAudioFrames = <int>[];
|
||||
|
||||
/// 初始化音频播放器
|
||||
void _initFlutterPcmSound() {
|
||||
@ -533,15 +535,17 @@ class TalkViewLogic extends BaseGetXController {
|
||||
|
||||
//开始录音
|
||||
Future<void> startProcessingAudio() async {
|
||||
// 增加录音帧监听器和错误监听器
|
||||
state.voiceProcessor?.addFrameListener(_onFrame);
|
||||
state.voiceProcessor?.addErrorListener(_onError);
|
||||
try {
|
||||
if (await state.voiceProcessor?.hasRecordAudioPermission() ?? false) {
|
||||
await state.voiceProcessor?.start(state.frameLength, state.sampleRate);
|
||||
final bool? isRecording = await state.voiceProcessor?.isRecording();
|
||||
state.isRecordingAudio.value = isRecording!;
|
||||
state.startRecordingAudioTime.value = DateTime.now();
|
||||
|
||||
// 增加录音帧监听器和错误监听器
|
||||
state.voiceProcessor
|
||||
?.addFrameListeners(<VoiceProcessorFrameListener>[_onFrame]);
|
||||
state.voiceProcessor?.addErrorListener(_onError);
|
||||
} else {
|
||||
// state.errorMessage.value = 'Recording permission not granted';
|
||||
}
|
||||
@ -576,23 +580,23 @@ class TalkViewLogic extends BaseGetXController {
|
||||
|
||||
// 音频帧处理
|
||||
Future<void> _onFrame(List<int> frame) async {
|
||||
// 预处理和转码操作放到异步计算线程
|
||||
// final processedFrame = await compute(preprocessAudio, frame);
|
||||
// final list = listLinearToALaw(processedFrame);
|
||||
final List<int> processedFrame = preprocessAudio(frame);
|
||||
final List<int> list = listLinearToALaw(processedFrame);
|
||||
_bufferedAudioFrames.addAll(list);
|
||||
|
||||
final int ms = DateTime.now().millisecondsSinceEpoch -
|
||||
state.startRecordingAudioTime.value.millisecondsSinceEpoch;
|
||||
|
||||
// 发送音频数据到UDP
|
||||
await StartChartManage().sendTalkDataMessage(
|
||||
talkData: TalkData(
|
||||
content: list,
|
||||
contentType: TalkData_ContentTypeE.G711,
|
||||
durationMs: ms,
|
||||
),
|
||||
);
|
||||
Future.delayed(const Duration(milliseconds: 1000)).whenComplete(() async {
|
||||
// 发送音频数据到UDP
|
||||
await StartChartManage().sendTalkDataMessage(
|
||||
talkData: TalkData(
|
||||
content: list,
|
||||
contentType: TalkData_ContentTypeE.G711,
|
||||
durationMs: ms,
|
||||
),
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
// 错误监听
|
||||
@ -662,9 +666,31 @@ class TalkViewLogic extends BaseGetXController {
|
||||
// return processedList;
|
||||
// }
|
||||
|
||||
List<int> listLinearToALaw(List<int> pcmList) {
|
||||
final List<int> aLawList = [];
|
||||
List<int> adjustVolume(List<int> pcmList, double volume) {
|
||||
final List<int> adjustedPcmList = [];
|
||||
for (int pcmVal in pcmList) {
|
||||
// 调整音量
|
||||
int adjustedPcmVal = (pcmVal * volume).round();
|
||||
|
||||
// 裁剪到 16-bit PCM 范围
|
||||
if (adjustedPcmVal > 32767) {
|
||||
adjustedPcmVal = 32767;
|
||||
} else if (adjustedPcmVal < -32768) {
|
||||
adjustedPcmVal = -32768;
|
||||
}
|
||||
|
||||
adjustedPcmList.add(adjustedPcmVal);
|
||||
}
|
||||
return adjustedPcmList;
|
||||
}
|
||||
|
||||
List<int> listLinearToALaw(List<int> pcmList) {
|
||||
// 先调节音量
|
||||
final List<int> adjustedPcmList = adjustVolume(pcmList, 5.0);
|
||||
|
||||
// 再进行 A-law 编码
|
||||
final List<int> aLawList = [];
|
||||
for (int pcmVal in adjustedPcmList) {
|
||||
final int aLawVal = linearToALaw(pcmVal);
|
||||
aLawList.add(aLawVal);
|
||||
}
|
||||
|
||||
@ -37,7 +37,7 @@ class TalkViewState {
|
||||
RxList<int> listAudioData = <int>[].obs; //得到的音频流字节数据
|
||||
GlobalKey globalKey = GlobalKey();
|
||||
|
||||
Timer? oneMinuteTimeTimer; // 定时器超过60秒关闭当前界面
|
||||
Timer? oneMinuteTimeTimer; // 定时器超过60秒关闭当前界面
|
||||
RxInt oneMinuteTime = 0.obs; // 定时器秒数
|
||||
|
||||
// 定时器如果发送了接听的命令 而没收到回复就每秒重复发送10次
|
||||
@ -89,4 +89,4 @@ class TalkViewState {
|
||||
RxBool isLongPressing = false.obs; // 旋转角度(以弧度为单位)
|
||||
RxBool hasAudioData = false.obs; // 是否有音频数据
|
||||
RxInt lastAudioTimestamp = 0.obs; // 最后接收到的音频数据的时间戳
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user