You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
PayloadAPP/Src/GDDC/gddcdlg.cpp

611 lines
18 KiB
C++

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

#include "gddcdlg.h"
#include "ui_gddcdlg.h"
#include <QDateTime>
#include <QDir>
#include <QNetworkInterface>
#include <QTabBar>
#include <QTabWidget>
#include <iostream>
#include <windows.h>
#include <wtsapi32.h>
#pragma comment(lib, "Wtsapi32.lib")
using namespace std;
DWORD GetmPid(LPCWSTR ProcessName) {
PWTS_PROCESS_INFOW wts;
DWORD Count;
DWORD i = 0;
BOOL result =
WTSEnumerateProcessesW(WTS_CURRENT_SERVER_HANDLE, 0, 1, &wts, &Count);
if (result == 0) {
cout << "WTSEnumerateProcessesW Error" << endl;
return 1;
}
cout << "WTSEnumerateProcessesW Success" << endl;
for (i; i < Count; i++) {
if (lstrcmpiW(wts[i].pProcessName, ProcessName) == 0) {
DWORD pid = wts[i].ProcessId;
cout << "find pid:" << pid << endl;
return pid;
break;
}
}
WTSFreeMemory(wts);
}
#define CONFIG_PATH "config.ini"
#define CMDPAGEHIGHT 210
#define STATEPAGEWIDTH 250
GDDCdlg::GDDCdlg(QWidget *parent) : QWidget(parent), ui(new Ui::GDDCdlg) {
ui->setupUi(this);
initWindow();
initParam();
initSignalSlot();
}
GDDCdlg::~GDDCdlg() {
// 停止所有通信
stopPushURL();
stopConnectURL1();
stopConnectURL2();
stopConnectSerialCtrl();
stopConnectUDPCtrl();
stopConnectTCPCtrl();
delete m_DlgGDDCSet;
delete m_GDDCCmdDlg;
delete m_GDDCStateDlg;
delete ui;
}
// 初始化window
void GDDCdlg::initWindow() {
QPalette palette;
// 设置主窗口背景颜色
palette.setColor(QPalette::Window, QColor(50, 50, 50));
this->setPalette(palette);
// 嵌入到主窗口
setWindowFlags(Qt::CustomizeWindowHint | Qt::FramelessWindowHint);
hide();
m_DlgGDDCSet = new GDDCSet(this);
m_DlgGDDCSet->setWindowFlags(Qt::Dialog);
m_DlgGDDCSet->setWindowModality(Qt::WindowModal); // 设置为模态对话框
m_GDDCCmdDlg = new GDDCCmdDlg(this);
m_GDDCStateDlg = new GDDCStateInfo(this);
ui->pushButShowStatePage->setIcon(QIcon(":/res/right.png"));
ui->pushButShowCmdPage->setIcon(QIcon(":/res/down.png"));
ui->WgtffmpegVideo->setVedioSaveFileDirPath("./Video");
}
// 初始化参数
void GDDCdlg::initParam() {
pointSelectionTracking = false;
Is_openVideo = false;
isCmdPageShow = true;
isStatePageShow = true;
detectionAreaSetting = false;
connectFlag.resize(12, false);
}
// 初始化信号与槽
void GDDCdlg::initSignalSlot() {
/*******有四种方式*******/
// 方式一
connect(ui->pushButtonSet, SIGNAL(clicked()), this,
SLOT(pushButtonSet_clicked()));
// 方式二
// connect(ui->pushButtonSet,&QPushButton::clicked,this,&::GDDCdlg::pushButtonSet_clicked);
// 方式三
// connect(ui->pushButtonSet,
// QOverload<bool>::of(&QPushButton::clicked),this,&::GDDCdlg::pushButtonSet_clicked);
// 方式四
// connect(ui->pushButtonSet,&QPushButton::clicked,[=](bool
// check){pushButtonSet_clicked();});
connect(ui->pushButShowCmdPage, SIGNAL(clicked()), this,
SLOT(pushButShowCmdPage_clicked())); // 控制页面隐藏显示按钮
connect(ui->pushButShowStatePage, SIGNAL(clicked()), this,
SLOT(pushButShowStatePage_clicked())); // 状态页面隐藏显示按钮
connect(m_DlgGDDCSet, SIGNAL(SignalStartConnect(int)), this,
SLOT(startConnect(int))); // 开始连接
connect(m_DlgGDDCSet, SIGNAL(SignalStopConnect(int)), this,
SLOT(stopConnect(int))); // 停止连接
}
// 槽函数开始连接
void GDDCdlg::startConnect(int type) {
switch (type) {
case 1: // 播放视频1
stopConnectURL2();
startConnectURL1();
break;
case 2: // 播放视频2
stopConnectURL1();
startConnectURL2();
break;
case 3: // 串口控制
startConnectSerialCtrl();
break;
case 4: // UDP控制
stopConnectTCPCtrl();
startConnectUDPCtrl();
break;
case 5: // TCP控制
stopConnectUDPCtrl();
startConnectTCPCtrl();
break;
case 6: // 视频(1)推流
startPushURL();
break;
default:
break;
}
}
// 槽函数停止连接
void GDDCdlg::stopConnect(int type) {
switch (type) {
case 1:
stopConnectURL1();
break;
case 2:
stopConnectURL2();
break;
case 3:
stopConnectSerialCtrl();
break;
case 4:
stopConnectUDPCtrl();
break;
case 5:
stopConnectTCPCtrl();
break;
case 6:
stopPushURL();
break;
default:
break;
}
}
// bool GDDCdlg::eventFilter(QObject *watched, QEvent *event)
// {
// qDebug() << this->geometry().x();
// qDebug() << this->geometry().y();
// QPoint sPoint2=QCursor::pos();
// qDebug()<<"相对于屏幕坐标2:"<<"("<<sPoint2.rx()<<","<<sPoint2.ry()<<")";
// QPoint windowPoint=this->mapFromGlobal(sPoint2);
// qDebug()<<"相对于窗口坐标:"<<"("<<windowPoint.rx()<<","<<windowPoint.ry()<<")";
// return true;
// }
// 鼠标左键
void GDDCdlg::mousePressEvent(QMouseEvent *event) {
// 如果鼠标左键按下
if (event->type() == QEvent::MouseButtonPress) {
// AI检测区域设置
if (m_GDDCCmdDlg->detectionAreaSetting == true) {
QPointF sPoint1 = event->globalPosition();
sPoint1 = QCursor::pos();
QPointF widgetPoint = ui->WgtffmpegVideo->mapFromGlobal(sPoint1);
double a = ui->WgtffmpegVideo->width();
double b = ui->WgtffmpegVideo->height();
double dir = 1920 / a * widgetPoint.rx() - 960;
double pitch = -(1080 / b * widgetPoint.ry() - 540);
m_GDDCCmdDlg->setAIDetcLineEditText(QString::number((int)dir),
QString::number((int)pitch));
}
// 目标跟踪
if (m_GDDCCmdDlg->pointSelectionTracking == true) {
QPointF sPoint1 = event->globalPosition();
QPointF widgetPoint = ui->WgtffmpegVideo->mapFromGlobal(sPoint1);
double a = ui->WgtffmpegVideo->width();
double b = ui->WgtffmpegVideo->height();
double dir = 1920 / a * widgetPoint.rx() - 960;
double pitch = -(1080 / b * widgetPoint.ry() - 540);
std::byte buffer[10];
buffer[0] = (std::byte)0x3A;
buffer[1] = (std::byte)(dir);
buffer[2] = (std::byte)((int)dir >> 8);
buffer[3] = (std::byte)pitch;
buffer[4] = (std::byte)((int)pitch >> 8);
buffer[5] = (std::byte)0x00;
buffer[6] = (std::byte)0x00;
buffer[7] = (std::byte)0x00;
buffer[8] = (std::byte)0x00;
buffer[9] = (std::byte)0x00;
// 发送5次
m_GDDCCmdDlg->sendCurDate(buffer, 3);
}
}
}
// 鼠标移动
void GDDCdlg::mouseMoveEvent(QMouseEvent *event) {
if (m_GDDCCmdDlg->detectionAreaSetting == true) {
// qDebug() << this->geometry().x();
// qDebug() << this->geometry().y();
QPointF sPoint1 = event->globalPosition();
// qDebug()<<"相对于屏幕坐标1:"<<"("<<sPoint1.rx()<<","<<sPoint1.ry()<<")";
QPointF sPoint2 = QCursor::pos();
// qDebug()<<"相对于屏幕坐标2:"<<"("<<sPoint2.rx()<<","<<sPoint2.ry()<<")";
QPointF windowPoint = this->mapFromGlobal(sPoint2);
// qDebug()<<"相对于窗口坐标:"<<"("<<windowPoint.rx()<<","<<windowPoint.ry()<<")";
QPointF widgetPoint = ui->WgtffmpegVideo->mapFromGlobal(sPoint1);
// qDebug()<<"相对于控件坐标:"<<"("<<widgetPoint.rx()<<","<<widgetPoint.ry()<<")";
// 更新LineEdit信息
double a = ui->WgtffmpegVideo->width();
double b = ui->WgtffmpegVideo->height();
double dir = 1920 / a * widgetPoint.rx() - 960;
double pitch = -(1080 / b * widgetPoint.ry() - 540);
m_GDDCCmdDlg->setAIDetcLineEditText(QString::number((int)dir),
QString::number((int)pitch));
}
}
// 区域重绘
void GDDCdlg::resizeEvent(QResizeEvent *event) {
resizeUI(); // 重新设置布局
}
// 重新设置布局
void GDDCdlg::resizeUI() {
/* -------------->x
* | (0,0)
* |
* |
* |
* |
* ↓ y
*/
double GDDCPageHeight = (double)(this->height());
double GDDCPageWidth = (double)(this->width());
// qDebug()<<"宽度,高度:"<<GDDCPageHeight<<GDDCPageWidth;
/******控制区位置和大小设置*****/
double cmdAreaHeight;
double cmdAreaWidth;
if (isStatePageShow) {
cmdAreaWidth = GDDCPageWidth - STATEPAGEWIDTH;
} else {
cmdAreaWidth = GDDCPageWidth;
}
if (isCmdPageShow) {
cmdAreaHeight = CMDPAGEHIGHT;
} else {
cmdAreaHeight = 0;
}
m_GDDCCmdDlg->setGeometry(0, GDDCPageHeight - cmdAreaHeight,
(int)cmdAreaWidth, (int)cmdAreaHeight);
m_GDDCCmdDlg->setTabWidgetGeometry(0, 0, cmdAreaWidth, cmdAreaHeight);
/*********状态区位置和大小设置***********/
double stateAreaHeight = GDDCPageHeight;
double stateAreaWidth;
if (isStatePageShow) {
stateAreaWidth = STATEPAGEWIDTH;
} else {
stateAreaWidth = 0;
}
m_GDDCStateDlg->setGeometry(GDDCPageWidth - stateAreaWidth, 0, stateAreaWidth,
stateAreaHeight);
m_GDDCStateDlg->setTableViewGeometry(0, 0, stateAreaWidth, stateAreaHeight);
/*******视频区位置和大小设置********/
double VideoAreaHeight = GDDCPageHeight - cmdAreaHeight; // 视频区高度
double VideoAreaWidth = GDDCPageWidth - stateAreaWidth; // 视频区宽度
// //高度值相对比较大
// if(VideoAreaHeight*16>VideoAreaWidth*9)
// {
// double setVideoAreaWidth = VideoAreaWidth;//等于吊舱页面宽度-状态区高度
// double setVideoAreaHeight = VideoAreaWidth*9/16;
// ui->WgtffmpegVideo->setGeometry(0,0.5*(VideoAreaHeight-setVideoAreaHeight),(int)setVideoAreaWidth,(int)setVideoAreaHeight);
// }
// //宽度值相对比较大
// else
// {
// double setVideoAreaHeight =
// VideoAreaHeight;//等于吊舱页面高度-控制区高度 double setVideoAreaWidth
// = VideoAreaHeight*16/9;
// ui->WgtffmpegVideo->setGeometry(0.5*(VideoAreaWidth-setVideoAreaWidth),0,(int)setVideoAreaWidth,(int)setVideoAreaHeight);
// }
ui->WgtffmpegVideo->setGeometry(20, 20, (int)VideoAreaWidth,
(int)VideoAreaHeight);
/**************设置按钮****************/
ui->pushButtonSet->setGeometry(GDDCPageWidth - stateAreaWidth - 45, 0, 40,
40);
/**********控制页显示隐藏按钮********/
ui->pushButShowCmdPage->setGeometry(
cmdAreaWidth * 0.5, GDDCPageHeight - cmdAreaHeight - 15, 50, 15);
ui->pushButShowCmdPage->raise();
/**********状态页显示隐藏按钮********/
ui->pushButShowStatePage->setGeometry(GDDCPageWidth - stateAreaWidth - 15,
(stateAreaHeight - cmdAreaHeight) * 0.5,
15, 50);
ui->pushButShowStatePage->raise();
}
void GDDCdlg::setGlobalSetMap(
std::unordered_map<QString, settingStruct> &gSetMap) {
if (m_DlgGDDCSet) {
m_DlgGDDCSet->initPullURL(gSetMap["光电吊舱"].net.remoteIp);
}
}
// 定时器处理
void GDDCdlg::GDDCControlTimeOut() {
if (m_GDDCCmdDlg->sendTimes > 0) { // 优先发送次数指令
m_GDDCCmdDlg->sendTimes -= 1;
// UDP控制
if (connectFlag[3]) {
udpSocket->writeDatagram(m_GDDCCmdDlg->m_DCcmdBuffer,
m_DlgGDDCSet->m_myPairNetwork.getRemoteAddr(),
m_DlgGDDCSet->m_myPairNetwork.getRemotePort());
}
// TCP控制
// 串口控制
if (m_GDDCCmdDlg->sendTimes == 0) {
m_GDDCCmdDlg->clearTJDCCmdBuffer();
}
} else { // 发送常发帧或长按指令
m_GDDCCmdDlg->UpdateDataTJDC();
// UDP控制
if (connectFlag[3]) {
udpSocket->writeDatagram(m_GDDCCmdDlg->m_DCcmdBuffer,
m_DlgGDDCSet->m_myPairNetwork.getRemoteAddr(),
m_DlgGDDCSet->m_myPairNetwork.getRemotePort());
}
// TCP控制
// 串口控制
}
}
// 播放视频1
void GDDCdlg::startConnectURL1() {
if (!connectFlag[0]) {
connectFlag[0] = true;
ffmpegvideoDlg *videoDlg = ui->WgtffmpegVideo;
// 开始拉流
videoDlg->m_flowType = m_DlgGDDCSet->m_FlowType;
videoDlg->setStreamIP(m_DlgGDDCSet->m_playURL1);
videoDlg->setPlayVideo(true);
// ui->WgtffmpegVideo->play(m_DlgGDDCSet->m_playURL1);
}
}
// 关闭视频1
void GDDCdlg::stopConnectURL1() {
if (connectFlag[0]) {
connectFlag[0] = false;
// Is_openVideo = false;
// ui->WgtffmpegVideo->m_PlayStatus = Is_openVideo;
ui->WgtffmpegVideo->setPlayVideo(false);
// ui->WgtffmpegVideo->stop();
}
}
// 播放视频2
void GDDCdlg::startConnectURL2() {
if (!connectFlag[1]) {
connectFlag[1] = true;
}
}
// 关闭视频2
void GDDCdlg::stopConnectURL2() {
if (connectFlag[1]) {
connectFlag[1] = false;
}
}
void GDDCdlg::startConnectSerialCtrl() {
if (!connectFlag[2]) {
connectFlag[2] = true;
}
}
void GDDCdlg::stopConnectSerialCtrl() {
if (connectFlag[2]) {
connectFlag[2] = false;
}
}
// 开始UDP控制通信
void GDDCdlg::startConnectUDPCtrl() {
if (!connectFlag[3]) {
/*启动定时器*/
GDDCControlTimer = new QTimer();
GDDCControlTimer->setInterval(100);
connect(GDDCControlTimer, &QTimer::timeout, this,
[=]() { GDDCControlTimeOut(); });
GDDCControlTimer->start();
// 创建udp socket对象
udpSocket = new QUdpSocket(this);
/*接收*/
// QList<QHostAddress> ipAddressesList =
// QNetworkInterface::allAddresses();//获取本机ip
udpSocket->bind(m_DlgGDDCSet->m_myPairNetwork.getLocalPort());
connect(udpSocket, SIGNAL(readyRead()), this, SLOT(UDPMessageReceive()));
connectFlag[3] = true;
}
}
// 停止UDP控制通信
void GDDCdlg::stopConnectUDPCtrl() {
if (connectFlag[3]) {
// 关闭定时器
GDDCControlTimer->stop();
delete GDDCControlTimer;
udpSocket->abort(); // 关闭套接字,并丢缓冲区中的所有待处理数据
delete udpSocket;
connectFlag[3] = false;
}
}
// 开始TCP控制通信
void GDDCdlg::startConnectTCPCtrl() {
if (!connectFlag[4]) {
connectFlag[4] = true;
}
}
// 停止TCP控制通信
void GDDCdlg::stopConnectTCPCtrl() {
if (connectFlag[4]) {
connectFlag[4] = false;
}
}
// 开始视频推流
void GDDCdlg::startPushURL() {
if (!connectFlag[5]) {
// //方式1命令行推流
// process = new QProcess();
// connect(process, &QProcess::readyReadStandardOutput, this, [=]() mutable
// {
// QString Output = process->readAllStandardOutput();
// qDebug() << "Output:" << Output;
// });
// connect(process, &QProcess::readyReadStandardError, this, [=]() mutable {
// QString Error = process->readAllStandardError();
// qDebug() << "Error Output:" << Error;
// });
// // process->start("cmd",QStringList()<<"/c"<<"ffmpeg -i
// // rtmp://liteavapp.qcloud.com/live/liteavdemoplayerstreamid -c copy -f
// flv
// // rtmp://182.92.130.23/app/test");
// QStringList m_cmd;
// QString str;
// // str = "ffmpeg -i " + m_DlgGDDCSet->m_playURL1 + " -c copy -f flv " +
// // m_DlgGDDCSet->m_pushURL;
// str = "ffmpeg -rtsp_transport tcp -i " + m_DlgGDDCSet->m_playURL1 + "
// -c:v libx264 -c:a copy -f flv " +
// m_DlgGDDCSet->m_pushURL;
// m_cmd << "/c" << str;
// process->start("cmd", m_cmd);
// //方式2代码推流
// if(!connectFlag[0])
// {
// QMessageBox::information(NULL, tr("提示"), "请先开始连接",
// QMessageBox::Ok); m_DlgGDDCSet->setPushStreamText("推送"); return;
// }
ffmpegvideoDlg *videoDlg = ui->WgtffmpegVideo;
videoDlg->setStreamIP(m_DlgGDDCSet->m_playURL1);
videoDlg->setPushStreamIP(m_DlgGDDCSet->m_pushURL);
qDebug() << "DLG:" << m_DlgGDDCSet->m_pushURL;
videoDlg->setPushStream(true);
m_DlgGDDCSet->setPushStreamText("停止推送");
connectFlag[5] = true;
}
}
// 停止视频推流
void GDDCdlg::stopPushURL() {
if (connectFlag[5]) {
// //方式1命令行推流
// if (process != nullptr) {
// process->terminate();
// process->close();
// process->kill();
// // 检查进程退出状态
// if (process->exitStatus() == QProcess::CrashExit) {
// qDebug() << "Process crashed";
// } else {
// qDebug() << "Process exited normally";
// }
// delete process;
// // 推流进程未自动关闭,手动关闭
// int pids = GetmPid(L"ffmpeg.exe");
// qDebug() << "ffmpeg.exe进程的pid为:" << pids;
// if (pids != 0) {
// QStringList m_cmd;
// m_cmd << "/c" << "taskkill /pid " << QString::number(pids) << " -f";
// QProcess::startDetached("cmd", m_cmd);
// }
// }
// 方式2代码推流
// ui->WgtffmpegVideo->setPushStreamIP("");
ui->WgtffmpegVideo->setPushStream(false);
m_DlgGDDCSet->setPushStreamText("推送");
connectFlag[5] = false;
}
}
// 设置页面弹出
void GDDCdlg::pushButtonSet_clicked() {
m_DlgGDDCSet->show();
m_DlgGDDCSet->activateWindow(); // 置为顶层
}
// udp数据接收
void GDDCdlg::UDPMessageReceive() {
QByteArray data;
data.resize(udpSocket->pendingDatagramSize());
QHostAddress addr;
quint16 port;
udpSocket->readDatagram(data.data(), data.size(), &addr, &port);
// 吊舱状态数据更新
m_GDDCStateDlg->UDPMessageReceive(data, data.size());
}
// 控制页面隐藏与显示
void GDDCdlg::pushButShowCmdPage_clicked() {
if (isCmdPageShow) {
m_GDDCCmdDlg->setVisible(false);
isCmdPageShow = false;
resizeUI();
ui->pushButShowCmdPage->setIcon(QIcon(":/res/up.png"));
// ui->pushButton->setGeometry(this->width()/2,this->height()-50,50,50);
} else {
m_GDDCCmdDlg->setVisible(true);
isCmdPageShow = true;
resizeUI();
ui->pushButShowCmdPage->setIcon(QIcon(":/res/down.png"));
// ui->pushButton->setGeometry(this->width()/2,ui->tabWidget->height(),50,50);
}
}
// 状态页面隐藏与显示
void GDDCdlg::pushButShowStatePage_clicked() {
if (isStatePageShow) {
m_GDDCStateDlg->setVisible(false);
isStatePageShow = false;
resizeUI();
ui->pushButShowStatePage->setIcon(QIcon(":/res/left.png"));
} else {
m_GDDCStateDlg->setVisible(true);
isStatePageShow = true;
resizeUI();
ui->pushButShowStatePage->setIcon(QIcon(":/res/right.png"));
// ui->pushButton->setGeometry(this->width()/2,ui->tabWidget->height(),50,50);
}
}