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