fix:整理对讲状态、增加视频页面的旋转角度
This commit is contained in:
parent
4044b9b1e1
commit
87ed175fed
@ -12,11 +12,14 @@ import 'package:star_lock/talk/startChart/proto/gateway_reset.pb.dart';
|
||||
import 'package:star_lock/talk/startChart/proto/generic.pb.dart';
|
||||
import 'package:star_lock/talk/startChart/proto/talk_data.pb.dart';
|
||||
import 'package:star_lock/talk/startChart/proto/talk_expect.pb.dart';
|
||||
import 'package:star_lock/talk/startChart/views/talkView/talk_view_state.dart';
|
||||
|
||||
import '../../start_chart_manage.dart';
|
||||
|
||||
class UdpTalkExpectHandler extends ScpMessageBaseHandle
|
||||
implements ScpMessageHandler {
|
||||
final TalkViewState talkViewState = TalkViewState();
|
||||
|
||||
@override
|
||||
void handleReq(ScpMessage scpMessage) {
|
||||
// 收到预期音视频数据请求
|
||||
@ -33,9 +36,12 @@ class UdpTalkExpectHandler extends ScpMessageBaseHandle
|
||||
@override
|
||||
void handleResp(ScpMessage scpMessage) {
|
||||
// 收到预期音视频数据回复
|
||||
final GenericResp genericResp = scpMessage.Payload;
|
||||
if (checkGenericRespSuccess(genericResp)) {
|
||||
final TalkExpectResp talkExpectResp = scpMessage.Payload;
|
||||
if (talkExpectResp != null) {
|
||||
print('收到预期音视频数据回复');
|
||||
// 停止发送预期数据的定时器
|
||||
startChartManage.stopTalkExpectMessageTimer();
|
||||
talkViewState.rotateAngle.value = talkExpectResp.rotate ?? 0;
|
||||
}
|
||||
}
|
||||
|
||||
@ -56,12 +62,12 @@ class UdpTalkExpectHandler extends ScpMessageBaseHandle
|
||||
int? spIndex,
|
||||
int? messageId}) {
|
||||
if (messageType == MessageTypeConstant.Resp) {
|
||||
// final TalkExpectResp talkExpectResp = TalkExpectResp();
|
||||
// talkExpectResp.mergeFromBuffer(byte);
|
||||
// return talkExpectResp;
|
||||
final GenericResp genericResp = GenericResp();
|
||||
genericResp.mergeFromBuffer(byte);
|
||||
return genericResp;
|
||||
final TalkExpectResp talkExpectResp = TalkExpectResp();
|
||||
talkExpectResp.mergeFromBuffer(byte);
|
||||
return talkExpectResp;
|
||||
// final GenericResp genericResp = GenericResp();
|
||||
// genericResp.mergeFromBuffer(byte);
|
||||
// return genericResp;
|
||||
} else if (messageType == MessageTypeConstant.Req) {
|
||||
final TalkExpectReq talkExpect = TalkExpectReq();
|
||||
talkExpect.mergeFromBuffer(byte);
|
||||
|
||||
@ -32,11 +32,11 @@ class TalkViewLogic extends BaseGetXController {
|
||||
|
||||
Timer? _syncTimer; // 音视频播放刷新率定时器
|
||||
int _startTime = 0; // 开始播放时间戳,用于判断帧数据中的时间戳位置
|
||||
final int bufferSize = 8; // 缓冲区大小(以帧为单位)
|
||||
final int bufferSize = 20; // 缓冲区大小(以帧为单位)
|
||||
final List<int> frameTimestamps = []; // 帧时间戳用于计算 FPS
|
||||
int frameIntervalMs = 45; // 初始帧间隔设置为45毫秒(约22FPS)
|
||||
int minFrameIntervalMs = 30; // 最小帧间隔(约33 FPS)
|
||||
int maxFrameIntervalMs = 500; // 最大帧间隔(约2 FPS)
|
||||
int maxFrameIntervalMs = 500; // 最大帧间隔(约1 FPS)
|
||||
// int maxFrameIntervalMs = 100; // 最大帧间隔(约10 FPS)
|
||||
|
||||
/// 初始化音频播放器
|
||||
@ -54,7 +54,7 @@ class TalkViewLogic extends BaseGetXController {
|
||||
|
||||
/// 挂断
|
||||
void udpHangUpAction() async {
|
||||
if (state.talkStatus.value == TalkStatus.duringCall) {
|
||||
if (state.talkStatus.value == TalkStatus.answeredSuccessfully) {
|
||||
// 如果是通话中就挂断
|
||||
StartChartManage().sendTalkHangupMessage();
|
||||
} else {
|
||||
@ -66,31 +66,13 @@ class TalkViewLogic extends BaseGetXController {
|
||||
|
||||
// 发起接听命令
|
||||
void initiateAnswerCommand() {
|
||||
StartChartManage().sendTalkAcceptMessage();
|
||||
}
|
||||
|
||||
void _updateFps(List<int> frameTimestamps) {
|
||||
final int now = DateTime.now().millisecondsSinceEpoch;
|
||||
// 移除超过1秒的时间戳
|
||||
frameTimestamps.removeWhere((timestamp) => now - timestamp > 1000);
|
||||
|
||||
// 计算 FPS
|
||||
final double fps = frameTimestamps.length.toDouble();
|
||||
|
||||
// 更新 FPS
|
||||
state.fps.value = fps;
|
||||
StartChartManage().startTalkAcceptTimer();
|
||||
}
|
||||
|
||||
// 监听音视频数据流
|
||||
void _startListenTalkData() {
|
||||
state.talkDataRepository.talkDataStream.listen((TalkData talkData) {
|
||||
final contentType = talkData.contentType;
|
||||
final currentTimestamp = DateTime.now().millisecondsSinceEpoch;
|
||||
|
||||
/// 如果不是通话中的状态不处理对讲数据
|
||||
if (state.startChartTalkStatus.status != TalkStatus.duringCall) {
|
||||
return;
|
||||
}
|
||||
|
||||
// 判断数据类型,进行分发处理
|
||||
switch (contentType) {
|
||||
@ -105,10 +87,10 @@ class TalkViewLogic extends BaseGetXController {
|
||||
if (state.videoBuffer.length < bufferSize) {
|
||||
state.videoBuffer.add(talkData);
|
||||
}
|
||||
print('talkData durationMs-->:${talkData.durationMs}');
|
||||
// print('talkData durationMs-->:${talkData.durationMs}');
|
||||
|
||||
/// 更新网络状态
|
||||
updateNetworkStatus(currentTimestamp);
|
||||
// updateNetworkStatus(currentTimestamp);
|
||||
break;
|
||||
}
|
||||
});
|
||||
@ -187,10 +169,6 @@ class TalkViewLogic extends BaseGetXController {
|
||||
if (state.videoBuffer.length > 1) {
|
||||
state.videoBuffer.removeAt(0);
|
||||
} else {
|
||||
// // 记录当前时间戳
|
||||
// frameTimestamps.add(DateTime.now().millisecondsSinceEpoch);
|
||||
// // 计算并更新 FPS
|
||||
// _updateFps(frameTimestamps);
|
||||
_playVideoData(state.videoBuffer.removeAt(0));
|
||||
}
|
||||
}
|
||||
@ -236,10 +214,6 @@ class TalkViewLogic extends BaseGetXController {
|
||||
if (state.videoBuffer.length > 1) {
|
||||
state.videoBuffer.removeAt(0);
|
||||
} else {
|
||||
// // 记录当前时间戳
|
||||
// frameTimestamps.add(DateTime.now().millisecondsSinceEpoch);
|
||||
// // 计算并更新 FPS
|
||||
// _updateFps(frameTimestamps);
|
||||
_playVideoData(state.videoBuffer.removeAt(0));
|
||||
}
|
||||
}
|
||||
@ -371,7 +345,8 @@ class TalkViewLogic extends BaseGetXController {
|
||||
}
|
||||
|
||||
/// 修改发送预期数据
|
||||
StartChartManage().changeTalkExpectDataType(talkExpect: talkExpectReq);
|
||||
StartChartManage().changeTalkExpectDataTypeAndReStartTalkExpectMessageTimer(
|
||||
talkExpect: talkExpectReq);
|
||||
state.isOpenVoice.value = !state.isOpenVoice.value;
|
||||
}
|
||||
|
||||
|
||||
@ -81,26 +81,29 @@ class _TalkViewPageState extends State<TalkViewPage>
|
||||
canPop: false,
|
||||
child: RepaintBoundary(
|
||||
key: state.globalKey,
|
||||
child: Image.memory(
|
||||
state.listData.value,
|
||||
gaplessPlayback: true,
|
||||
width: 1.sw,
|
||||
height: 1.sh,
|
||||
fit: BoxFit.cover,
|
||||
filterQuality: FilterQuality.high,
|
||||
errorBuilder: (
|
||||
BuildContext context,
|
||||
Object error,
|
||||
StackTrace? stackTrace,
|
||||
) {
|
||||
return Container(color: Colors.transparent);
|
||||
},
|
||||
child: RotatedBox(
|
||||
quarterTurns: 1, // 顺时针旋转 90 度(1 个四分之一圈)
|
||||
child: Image.memory(
|
||||
state.listData.value,
|
||||
gaplessPlayback: true,
|
||||
width: 1.sw,
|
||||
height: 1.sh,
|
||||
fit: BoxFit.cover,
|
||||
filterQuality: FilterQuality.high,
|
||||
errorBuilder: (
|
||||
BuildContext context,
|
||||
Object error,
|
||||
StackTrace? stackTrace,
|
||||
) {
|
||||
return Container(color: Colors.transparent);
|
||||
},
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
Obx(() => state.talkStatus.value == TalkStatus.answeredSuccessfully
|
||||
Obx(() => state.listData.value.isEmpty
|
||||
? Positioned(
|
||||
bottom: 300.h,
|
||||
child: Text(
|
||||
@ -141,7 +144,7 @@ class _TalkViewPageState extends State<TalkViewPage>
|
||||
// ),
|
||||
// ),
|
||||
// ),
|
||||
Obx(() => state.talkStatus.value == TalkStatus.answeredSuccessfully
|
||||
Obx(() => state.listData.value.isEmpty
|
||||
? buildRotationTransition()
|
||||
: Container())
|
||||
],
|
||||
@ -154,7 +157,7 @@ class _TalkViewPageState extends State<TalkViewPage>
|
||||
// 打开关闭声音
|
||||
GestureDetector(
|
||||
onTap: () {
|
||||
if (state.talkStatus.value == TalkStatus.duringCall) {
|
||||
if (state.talkStatus.value == TalkStatus.answeredSuccessfully) {
|
||||
// 打开关闭声音
|
||||
logic.updateTalkExpect();
|
||||
}
|
||||
@ -177,7 +180,7 @@ class _TalkViewPageState extends State<TalkViewPage>
|
||||
// 截图
|
||||
GestureDetector(
|
||||
onTap: () async {
|
||||
if (state.talkStatus.value == TalkStatus.duringCall) {
|
||||
if (state.talkStatus.value == TalkStatus.answeredSuccessfully) {
|
||||
await logic.captureAndSavePng();
|
||||
}
|
||||
},
|
||||
@ -196,7 +199,7 @@ class _TalkViewPageState extends State<TalkViewPage>
|
||||
// 录制
|
||||
GestureDetector(
|
||||
onTap: () async {
|
||||
if (state.talkStatus.value == TalkStatus.duringCall) {
|
||||
if (state.talkStatus.value == TalkStatus.answeredSuccessfully) {
|
||||
if (state.isRecordingScreen.value) {
|
||||
await logic.stopRecording();
|
||||
print('停止录屏');
|
||||
@ -245,8 +248,7 @@ class _TalkViewPageState extends State<TalkViewPage>
|
||||
getAnswerBtnName(),
|
||||
Colors.white,
|
||||
longPress: () async {
|
||||
if (state.talkStatus.value == TalkStatus.answeredSuccessfully ||
|
||||
state.talkStatus.value == TalkStatus.duringCall) {
|
||||
if (state.talkStatus.value == TalkStatus.answeredSuccessfully) {
|
||||
print('开始录音');
|
||||
logic.startProcessingAudio();
|
||||
}
|
||||
@ -283,7 +285,6 @@ class _TalkViewPageState extends State<TalkViewPage>
|
||||
case TalkStatus.waitingAnswer:
|
||||
return 'images/main/icon_lockDetail_monitoringAnswerCalls.png';
|
||||
case TalkStatus.answeredSuccessfully:
|
||||
case TalkStatus.duringCall:
|
||||
return 'images/main/icon_lockDetail_monitoringUnTalkback.png';
|
||||
default:
|
||||
return 'images/main/icon_lockDetail_monitoringAnswerCalls.png';
|
||||
@ -295,7 +296,6 @@ class _TalkViewPageState extends State<TalkViewPage>
|
||||
case TalkStatus.waitingAnswer:
|
||||
return '接听'.tr;
|
||||
case TalkStatus.answeredSuccessfully:
|
||||
case TalkStatus.duringCall:
|
||||
return '长按说话'.tr;
|
||||
default:
|
||||
return '接听'.tr;
|
||||
|
||||
@ -5,6 +5,7 @@ import 'package:flutter/material.dart';
|
||||
import 'package:flutter_voice_processor/flutter_voice_processor.dart';
|
||||
import 'package:get/get.dart';
|
||||
import 'package:get/get_rx/get_rx.dart';
|
||||
import 'package:get/get_rx/src/rx_types/rx_types.dart';
|
||||
import 'package:network_info_plus/network_info_plus.dart';
|
||||
import 'package:star_lock/talk/startChart/constant/talk_status.dart';
|
||||
import 'package:star_lock/talk/startChart/handle/other/talk_data_repository.dart';
|
||||
@ -71,11 +72,12 @@ class TalkViewState {
|
||||
RxBool isRecordingScreen = false.obs; // 是否录屏中
|
||||
RxBool isRecordingAudio = false.obs; // 是否录音中
|
||||
Rx<DateTime> startRecordingAudioTime = DateTime.now().obs; // 开始录音时间
|
||||
Rx<DateTime> endRecordingAudioTime= DateTime.now().obs; // 结束录音时间
|
||||
RxInt recordingAudioTime= 0.obs; // 录音时间持续时间
|
||||
Rx<DateTime> endRecordingAudioTime = DateTime.now().obs; // 结束录音时间
|
||||
RxInt recordingAudioTime = 0.obs; // 录音时间持续时间
|
||||
RxDouble fps = 0.0.obs; // 添加 FPS 计数
|
||||
late VoiceProcessor? voiceProcessor; // 音频处理器、录音
|
||||
final int frameLength = 320; //录音视频帧长度为320
|
||||
final int sampleRate = 8000; //录音频采样率为8000
|
||||
List<List<int>> recordingAudioAllFrames = <List<int>>[]; // 录制音频的所有帧
|
||||
RxInt rotateAngle = 0.obs; // 旋转角度(以弧度为单位)
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user