添加按钮与指示灯相关串口通信
This commit is contained in:
parent
b6215897df
commit
77cbb4ad3d
54
Channel.cpp
54
Channel.cpp
@ -5,6 +5,7 @@
|
|||||||
#include <QFileInfo>
|
#include <QFileInfo>
|
||||||
#include <QProcess>
|
#include <QProcess>
|
||||||
#include <QTime>
|
#include <QTime>
|
||||||
|
#include <chrono>
|
||||||
|
|
||||||
LinkObject* Channel::audioInput = nullptr;
|
LinkObject* Channel::audioInput = nullptr;
|
||||||
LinkObject* Channel::audioOutput = nullptr;
|
LinkObject* Channel::audioOutput = nullptr;
|
||||||
@ -16,10 +17,6 @@ extern LinkObject* vo1;
|
|||||||
Channel::Channel(QObject* parent)
|
Channel::Channel(QObject* parent)
|
||||||
: QObject(parent)
|
: QObject(parent)
|
||||||
{
|
{
|
||||||
timer = new QTimer();
|
|
||||||
timer->setInterval(duration);
|
|
||||||
timer->stop();
|
|
||||||
|
|
||||||
videoInput = nullptr;
|
videoInput = nullptr;
|
||||||
videoOutput = nullptr;
|
videoOutput = nullptr;
|
||||||
videoEncoder = nullptr;
|
videoEncoder = nullptr;
|
||||||
@ -48,8 +45,6 @@ Channel::Channel(QObject* parent)
|
|||||||
rtspServer = Link::create("Rtsp");
|
rtspServer = Link::create("Rtsp");
|
||||||
rtspServer->start();
|
rtspServer->start();
|
||||||
}
|
}
|
||||||
|
|
||||||
connect(timer, SIGNAL(timeout()), this, SLOT(onTimeout()));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -88,8 +83,9 @@ void Channel::init()
|
|||||||
record = Link::create("Mux");
|
record = Link::create("Mux");
|
||||||
QVariantMap dataMp4;
|
QVariantMap dataMp4;
|
||||||
dataMp4["format"] = "mp4";
|
dataMp4["format"] = "mp4";
|
||||||
// dataMp4["lowLatency"] = true;
|
dataMp4["segmentDuration"] = duration;
|
||||||
// dataMp4["filecache"] = 20480000;
|
dataMp4["lowLatency"] = true;
|
||||||
|
dataMp4["filecache"] = 20480000;
|
||||||
record->setData(dataMp4);
|
record->setData(dataMp4);
|
||||||
videoInput->linkV(videoEncoder)->linkV(record);
|
videoInput->linkV(videoEncoder)->linkV(record);
|
||||||
audioInput->linkA(audioEncoder)->linkA(record);
|
audioInput->linkA(audioEncoder)->linkA(record);
|
||||||
@ -127,40 +123,20 @@ void Channel::init()
|
|||||||
file->linkV(videoDecoder)->linkV(videoOutput);
|
file->linkV(videoDecoder)->linkV(videoOutput);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief 一段录制完毕
|
|
||||||
*/
|
|
||||||
void Channel::onTimeout()
|
|
||||||
{
|
|
||||||
while (int secs = QTime::currentTime().second() % 60 != 0) {
|
|
||||||
}
|
|
||||||
QString curTime = QDateTime::currentDateTime().toString("yyyyMMddhhmm");
|
|
||||||
QString path = QString("%1/%2/%3.mp4").arg(Constant::VideoPath).arg(channelName).arg(curTime);
|
|
||||||
// 重新分片
|
|
||||||
record->invoke("segment", path);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief 开始录制
|
* @brief 开始录制
|
||||||
*/
|
*/
|
||||||
void Channel::startRecord()
|
void Channel::startRecord()
|
||||||
{
|
{
|
||||||
if (!isMountDisk()) {
|
|
||||||
Log::error("there are no disk mounted");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
while (int secs = QTime::currentTime().second() % 60 != 0) {
|
while (int secs = QTime::currentTime().second() % 60 != 0) {
|
||||||
}
|
}
|
||||||
|
|
||||||
QString curTime = QDateTime::currentDateTime().toString("yyyyMMddhhmm");
|
QString curTime = QDateTime::currentDateTime().toString("yyyyMMddhhmm");
|
||||||
QVariantMap dataRecord;
|
QVariantMap dataRecord;
|
||||||
QString path = QString("%1/%2/%3.mp4").arg(Constant::VideoPath).arg(channelName).arg(curTime);
|
QString path = QString("%1/%2/%3.mp4").arg(Constant::VideoPath).arg(channelName).arg(curTime + "_%02d");
|
||||||
dataRecord["path"] = path;
|
dataRecord["path"] = path;
|
||||||
record->start(dataRecord);
|
record->start(dataRecord);
|
||||||
isRecord = true;
|
isRecord = true;
|
||||||
Log::info("{} start recording...", channelName.toStdString());
|
Log::info("{} start recording...", channelName.toStdString());
|
||||||
|
|
||||||
timer->start();
|
|
||||||
emit showRecordState(true);
|
emit showRecordState(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -171,7 +147,6 @@ void Channel::stopRecord()
|
|||||||
{
|
{
|
||||||
Log::info("{} stop recording...", channelName.toStdString());
|
Log::info("{} stop recording...", channelName.toStdString());
|
||||||
record->stop(true);
|
record->stop(true);
|
||||||
timer->stop();
|
|
||||||
emit showRecordState(false);
|
emit showRecordState(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -245,7 +220,6 @@ void Channel::startPlayLive()
|
|||||||
void Channel::back()
|
void Channel::back()
|
||||||
{
|
{
|
||||||
Log::info("{} back 10s", channelName.toStdString());
|
Log::info("{} back 10s", channelName.toStdString());
|
||||||
qDebug() << channelName << "back 10s";
|
|
||||||
int curPos = file->invoke("getPosition").toInt();
|
int curPos = file->invoke("getPosition").toInt();
|
||||||
curPos -= 10 * 1000;
|
curPos -= 10 * 1000;
|
||||||
file->invoke("seek", curPos);
|
file->invoke("seek", curPos);
|
||||||
@ -277,13 +251,15 @@ void Channel::togglePause()
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief 判断是否挂载磁盘
|
* @brief 显示播放结束提示
|
||||||
* @return
|
|
||||||
*/
|
*/
|
||||||
bool Channel::isMountDisk()
|
void Channel::showFinishPromot()
|
||||||
{
|
{
|
||||||
QString info = Tool::writeCom(QString("df %1").arg(Constant::MountedPath));
|
videoInput->unLinkV(videoDecoder);
|
||||||
if (!info.contains(Constant::MountedPath))
|
QVariantMap dataImage;
|
||||||
return false;
|
dataImage["path"] = Constant::FinishImagePath;
|
||||||
return true;
|
image->setData(dataImage);
|
||||||
}
|
image->start(dataImage);
|
||||||
|
image->linkV(videoOutput);
|
||||||
|
state = Finish;
|
||||||
|
}
|
17
Channel.h
17
Channel.h
@ -12,7 +12,8 @@ public:
|
|||||||
Stop,
|
Stop,
|
||||||
Playback,
|
Playback,
|
||||||
Pause,
|
Pause,
|
||||||
Error
|
Error,
|
||||||
|
Finish
|
||||||
};
|
};
|
||||||
explicit Channel(QObject* parent = nullptr);
|
explicit Channel(QObject* parent = nullptr);
|
||||||
void init();
|
void init();
|
||||||
@ -31,7 +32,7 @@ public:
|
|||||||
|
|
||||||
LinkObject* record;
|
LinkObject* record;
|
||||||
// 单个视频时长
|
// 单个视频时长
|
||||||
int duration = 10 * 60 * 1000;
|
int duration = 1 * 60 * 1000;
|
||||||
bool isRecord = false;
|
bool isRecord = false;
|
||||||
|
|
||||||
LinkObject* file;
|
LinkObject* file;
|
||||||
@ -55,19 +56,11 @@ public:
|
|||||||
|
|
||||||
void startPlayLive();
|
void startPlayLive();
|
||||||
|
|
||||||
|
void showFinishPromot();
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void playEnd();
|
void playEnd();
|
||||||
void showRecordState(bool state);
|
void showRecordState(bool state);
|
||||||
|
|
||||||
private slots:
|
|
||||||
void onTimeout();
|
|
||||||
|
|
||||||
private:
|
|
||||||
// 用于分段录制的计时器
|
|
||||||
QTimer* timer;
|
|
||||||
|
|
||||||
private:
|
|
||||||
bool isMountDisk();
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // CHANNEL_H
|
#endif // CHANNEL_H
|
||||||
|
@ -28,6 +28,7 @@ void CheckStorageThread::run()
|
|||||||
int64_t available = Tool::getAvailableStorage(Constant::MountedPath);
|
int64_t available = Tool::getAvailableStorage(Constant::MountedPath);
|
||||||
if (available < THRESHOLD) {
|
if (available < THRESHOLD) {
|
||||||
Log::info("there are not enough storage, then remove some files...");
|
Log::info("there are not enough storage, then remove some files...");
|
||||||
|
emit diskWillFull();
|
||||||
// 获取文件列表
|
// 获取文件列表
|
||||||
QStringList fileList = Tool::getFileList(QString("%1/%2").arg(Constant::VideoPath).arg(Constant::MainChannel));
|
QStringList fileList = Tool::getFileList(QString("%1/%2").arg(Constant::VideoPath).arg(Constant::MainChannel));
|
||||||
if (!fileList.isEmpty()) {
|
if (!fileList.isEmpty()) {
|
||||||
@ -52,6 +53,8 @@ void CheckStorageThread::run()
|
|||||||
Log::error("remove file {} failed", path.toStdString());
|
Log::error("remove file {} failed", path.toStdString());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
emit diskNotFull();
|
||||||
}
|
}
|
||||||
QThread::msleep(INTERVAL);
|
QThread::msleep(INTERVAL);
|
||||||
}
|
}
|
||||||
|
@ -8,6 +8,10 @@ class CheckStorageThread : public QThread {
|
|||||||
public:
|
public:
|
||||||
CheckStorageThread();
|
CheckStorageThread();
|
||||||
|
|
||||||
|
signals:
|
||||||
|
void diskWillFull(); // 磁盘空间不足
|
||||||
|
void diskNotFull(); // 磁盘空间充足
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void run() override;
|
void run() override;
|
||||||
};
|
};
|
||||||
|
@ -22,6 +22,7 @@ public:
|
|||||||
static constexpr char* MountedPath = "/root/usb";
|
static constexpr char* MountedPath = "/root/usb";
|
||||||
static constexpr char* ErrorImagePath = "/opt/RecordControlApplication/images/error.jpeg";
|
static constexpr char* ErrorImagePath = "/opt/RecordControlApplication/images/error.jpeg";
|
||||||
static constexpr char* EmptyImagePath = "/opt/RecordControlApplication/images/empty.jpeg";
|
static constexpr char* EmptyImagePath = "/opt/RecordControlApplication/images/empty.jpeg";
|
||||||
|
static constexpr char* FinishImagePath = "/opt/RecordControlApplication/images/finish.jpeg";
|
||||||
static constexpr char* MainChannel = "HDMI-A";
|
static constexpr char* MainChannel = "HDMI-A";
|
||||||
static constexpr char* SecondaryChannel = "HDMI-B";
|
static constexpr char* SecondaryChannel = "HDMI-B";
|
||||||
};
|
};
|
||||||
|
@ -1,5 +1,4 @@
|
|||||||
#include "Message.h"
|
#include "Message.h"
|
||||||
#include <QDebug>
|
|
||||||
#include <QSpacerItem>
|
#include <QSpacerItem>
|
||||||
#include <QTimer>
|
#include <QTimer>
|
||||||
#include <QVBoxLayout>
|
#include <QVBoxLayout>
|
||||||
@ -69,7 +68,6 @@ void Message::showMessage(QString content, int duration, Level level)
|
|||||||
// apeend new
|
// apeend new
|
||||||
QPushButton* btn = generateButton(content, level);
|
QPushButton* btn = generateButton(content, level);
|
||||||
layout->insertWidget(count, btn);
|
layout->insertWidget(count, btn);
|
||||||
qDebug() << this->children();
|
|
||||||
|
|
||||||
QTimer* timer = new QTimer();
|
QTimer* timer = new QTimer();
|
||||||
timer->setInterval(duration);
|
timer->setInterval(duration);
|
||||||
|
@ -32,7 +32,6 @@ SOURCES += \
|
|||||||
main.cpp \
|
main.cpp \
|
||||||
Widget.cpp \
|
Widget.cpp \
|
||||||
TcpServer.cpp \
|
TcpServer.cpp \
|
||||||
TcpController.cpp \
|
|
||||||
Channel.cpp \
|
Channel.cpp \
|
||||||
Menu.cpp\
|
Menu.cpp\
|
||||||
ProgressBar.cpp \
|
ProgressBar.cpp \
|
||||||
@ -40,19 +39,28 @@ SOURCES += \
|
|||||||
Tool.cpp \
|
Tool.cpp \
|
||||||
CheckStorageThread.cpp \
|
CheckStorageThread.cpp \
|
||||||
Constant.h \
|
Constant.h \
|
||||||
Log.cpp
|
Log.cpp \
|
||||||
|
TcpRequest.cpp \
|
||||||
|
TcpConnectionHandler.cpp \
|
||||||
|
TcpRequestHandler.cpp \
|
||||||
|
TcpResponse.cpp \
|
||||||
|
SerialPortTool.cpp
|
||||||
|
|
||||||
HEADERS += \
|
HEADERS += \
|
||||||
Widget.h \
|
Widget.h \
|
||||||
TcpServer.h \
|
TcpServer.h \
|
||||||
TcpController.h \
|
|
||||||
Channel.h \
|
Channel.h \
|
||||||
Menu.h \
|
Menu.h \
|
||||||
ProgressBar.h \
|
ProgressBar.h \
|
||||||
Message.h \
|
Message.h \
|
||||||
Tool.h \
|
Tool.h \
|
||||||
CheckStorageThread.h \
|
CheckStorageThread.h \
|
||||||
Log.h
|
Log.h \
|
||||||
|
TcpRequest.h \
|
||||||
|
TcpConnectionHandler.h \
|
||||||
|
TcpRequestHandler.h \
|
||||||
|
TcpResponse.h \
|
||||||
|
SerialPortTool.h
|
||||||
|
|
||||||
FORMS += \
|
FORMS += \
|
||||||
Menu.ui \
|
Menu.ui \
|
||||||
|
275
SerialPortTool.cpp
Normal file
275
SerialPortTool.cpp
Normal file
@ -0,0 +1,275 @@
|
|||||||
|
#include "SerialPortTool.h"
|
||||||
|
#include "Log.h"
|
||||||
|
|
||||||
|
SerialPortTool::SerialPortTool(QObject* parent)
|
||||||
|
: QObject(parent)
|
||||||
|
{
|
||||||
|
|
||||||
|
serialPort = new QSerialPort();
|
||||||
|
connect(serialPort, SIGNAL(readyRead()), this, SLOT(onReayRead()));
|
||||||
|
connect(serialPort, SIGNAL(error(QSerialPort::SerialPortError)), this, SLOT(onSerialError(QSerialPort::SerialPortError)));
|
||||||
|
|
||||||
|
timer = new QTimer();
|
||||||
|
timer->setInterval(3000);
|
||||||
|
timer->stop();
|
||||||
|
connect(timer, SIGNAL(timeout()), this, SLOT(onTimeout()));
|
||||||
|
|
||||||
|
auto makeCommand = [=](QString lightNum, QString enable) {
|
||||||
|
return QByteArray::fromHex(QString("A2 B2 08 02 %1 %2 C2 D2").arg(lightNum).arg(enable).toLatin1());
|
||||||
|
};
|
||||||
|
|
||||||
|
cmdMap[PlaybackStart] = makeCommand("01", "01");
|
||||||
|
cmdMap[PlaybackEnd] = makeCommand("01", "00");
|
||||||
|
cmdMap[RecordStart] = makeCommand("02", "01");
|
||||||
|
cmdMap[RecordEnd] = makeCommand("02", "00");
|
||||||
|
cmdMap[PlayPause] = makeCommand("03", "01");
|
||||||
|
cmdMap[PlayResume] = makeCommand("03", "00");
|
||||||
|
cmdMap[DiskWillFull] = makeCommand("04", "01");
|
||||||
|
cmdMap[DiskNotFull] = makeCommand("04", "00");
|
||||||
|
cmdMap[PowerOn] = makeCommand("05", "01");
|
||||||
|
cmdMap[PowerOff] = makeCommand("05", "00");
|
||||||
|
cmdMap[Forward] = makeCommand("06", "01");
|
||||||
|
cmdMap[LoopOn] = makeCommand("07", "01");
|
||||||
|
cmdMap[LoopOff] = makeCommand("07", "00");
|
||||||
|
cmdMap[Back] = makeCommand("08", "01");
|
||||||
|
cmdMap[MainChannelOn] = makeCommand("09", "01");
|
||||||
|
cmdMap[MainChannelOff] = makeCommand("09", "00");
|
||||||
|
cmdMap[SecondaryChannelOn] = makeCommand("0A", "01");
|
||||||
|
cmdMap[SecondaryChannelOff] = makeCommand("0A", "00");
|
||||||
|
}
|
||||||
|
|
||||||
|
SerialPortTool::~SerialPortTool()
|
||||||
|
{
|
||||||
|
serialPort->close();
|
||||||
|
delete serialPort;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 打开串口
|
||||||
|
*/
|
||||||
|
void SerialPortTool::open()
|
||||||
|
{
|
||||||
|
serialPort->setPortName("ttyAMA2");
|
||||||
|
serialPort->setBaudRate(QSerialPort::Baud115200);
|
||||||
|
serialPort->setDataBits(QSerialPort::Data8);
|
||||||
|
serialPort->setParity(QSerialPort::NoParity);
|
||||||
|
serialPort->setStopBits(QSerialPort::OneStop);
|
||||||
|
serialPort->setFlowControl(QSerialPort::NoFlowControl);
|
||||||
|
if (serialPort->open(QIODevice::ReadWrite)) {
|
||||||
|
Log::info("open serial port: /dev/ttyAMA2 success");
|
||||||
|
} else {
|
||||||
|
Log::error("open serial port: /dev/ttyAMA2 failed, ready to retry...");
|
||||||
|
timer->start();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 关闭串口
|
||||||
|
*/
|
||||||
|
void SerialPortTool::close()
|
||||||
|
{
|
||||||
|
serialPort->close();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 串口报错槽函数
|
||||||
|
*/
|
||||||
|
void SerialPortTool::onSerialError(QSerialPort::SerialPortError error)
|
||||||
|
{
|
||||||
|
if (error == QSerialPort::ResourceError) {
|
||||||
|
Log::error("serial port break, try to reopen");
|
||||||
|
serialPort->close();
|
||||||
|
timer->start();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 重连串口
|
||||||
|
*/
|
||||||
|
void SerialPortTool::onTimeout()
|
||||||
|
{
|
||||||
|
timer->stop();
|
||||||
|
bool ret = serialPort->open(QIODevice::ReadWrite);
|
||||||
|
if (!ret) {
|
||||||
|
Log::info("reopen serial port: /dev/ttyAMA2 success");
|
||||||
|
timer->start();
|
||||||
|
} else {
|
||||||
|
Log::error("reopen serial port: /dev/ttyAMA2 failed, ready to retry...");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 读取并处理收到的串口指令
|
||||||
|
*/
|
||||||
|
void SerialPortTool::onReayRead()
|
||||||
|
{
|
||||||
|
// 当缓冲区中有大于8个字节的数据时才处理
|
||||||
|
if (serialPort->bytesAvailable() < 8)
|
||||||
|
return;
|
||||||
|
|
||||||
|
// 由于本项目串口的数据频率小,可以将全部读到的数据当做一条指令来解析
|
||||||
|
// 当发送数据频率很大时,可以使用另外的缓冲区来存储读到的数据,然后读取缓冲区的数据进行指令的解析
|
||||||
|
// 将缓冲区的数据全部读取出来
|
||||||
|
QByteArray data = serialPort->readAll();
|
||||||
|
qDebug() << "data:" << data;
|
||||||
|
// 对接受的数据进行协议解析
|
||||||
|
|
||||||
|
// 查找包头和包尾
|
||||||
|
QByteArray head = QByteArray::fromHex("A2 B2");
|
||||||
|
QByteArray tail = QByteArray::fromHex("C2 D2");
|
||||||
|
//... 0xA2 0xB2 0x08 0x01 0x01 0x00 0xC2 0xD2 ...
|
||||||
|
// || ||
|
||||||
|
// indexHead indexTail
|
||||||
|
int indexHead = data.indexOf(head);
|
||||||
|
int indexTail = data.indexOf(tail);
|
||||||
|
// 没有查找到包头和包尾
|
||||||
|
if (indexHead == -1 || indexTail == -1)
|
||||||
|
return;
|
||||||
|
|
||||||
|
// 从接收的数据中截取出一帧数据
|
||||||
|
QByteArray frame = data.mid(indexHead, indexTail + 2 - indexHead);
|
||||||
|
if (frame.length() <= 4)
|
||||||
|
return;
|
||||||
|
// 对一帧数据进行校验
|
||||||
|
// 长度校验不通过
|
||||||
|
if (frame[2] != frame.length())
|
||||||
|
return;
|
||||||
|
// 命令类型
|
||||||
|
if (data.at(3) != 0x01)
|
||||||
|
return;
|
||||||
|
|
||||||
|
switch (frame[4]) {
|
||||||
|
case 1:
|
||||||
|
emit btnPlaybackClicked();
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
emit btnPreviousClicked();
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
emit btnPauseClicked();
|
||||||
|
break;
|
||||||
|
case 4:
|
||||||
|
emit btnReturnClicked();
|
||||||
|
break;
|
||||||
|
case 5:
|
||||||
|
emit btnBackClicked();
|
||||||
|
break;
|
||||||
|
case 6:
|
||||||
|
emit btnNextClicked();
|
||||||
|
break;
|
||||||
|
case 7:
|
||||||
|
emit btnForwardClicked();
|
||||||
|
break;
|
||||||
|
case 8:
|
||||||
|
emit btnDoneClicked();
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void SerialPortTool::onPlaybackStart()
|
||||||
|
{
|
||||||
|
serialPort->write(cmdMap.value(PlaybackStart));
|
||||||
|
serialPort->flush();
|
||||||
|
}
|
||||||
|
|
||||||
|
void SerialPortTool::onPlaybackEnd()
|
||||||
|
{
|
||||||
|
serialPort->write(cmdMap.value(PlaybackEnd));
|
||||||
|
serialPort->flush();
|
||||||
|
}
|
||||||
|
|
||||||
|
void SerialPortTool::onRecordStart()
|
||||||
|
{
|
||||||
|
serialPort->write(cmdMap.value(RecordStart));
|
||||||
|
serialPort->flush();
|
||||||
|
}
|
||||||
|
|
||||||
|
void SerialPortTool::onRecordEnd()
|
||||||
|
{
|
||||||
|
serialPort->write(cmdMap.value(RecordEnd));
|
||||||
|
serialPort->flush();
|
||||||
|
}
|
||||||
|
|
||||||
|
void SerialPortTool::onPlayPause()
|
||||||
|
{
|
||||||
|
serialPort->write(cmdMap.value(PlayPause));
|
||||||
|
serialPort->flush();
|
||||||
|
}
|
||||||
|
|
||||||
|
void SerialPortTool::onPlayResume()
|
||||||
|
{
|
||||||
|
serialPort->write(cmdMap.value(PlayResume));
|
||||||
|
serialPort->flush();
|
||||||
|
}
|
||||||
|
|
||||||
|
void SerialPortTool::onDiskWillFull()
|
||||||
|
{
|
||||||
|
serialPort->write(cmdMap.value(DiskWillFull));
|
||||||
|
serialPort->flush();
|
||||||
|
}
|
||||||
|
|
||||||
|
void SerialPortTool::onDiskNotFull()
|
||||||
|
{
|
||||||
|
serialPort->write(cmdMap.value(DiskNotFull));
|
||||||
|
serialPort->flush();
|
||||||
|
}
|
||||||
|
void SerialPortTool::onPowerOn()
|
||||||
|
{
|
||||||
|
serialPort->write(cmdMap.value(PowerOn));
|
||||||
|
serialPort->flush();
|
||||||
|
}
|
||||||
|
void SerialPortTool::onPowerOff()
|
||||||
|
{
|
||||||
|
serialPort->write(cmdMap.value(PowerOff));
|
||||||
|
serialPort->flush();
|
||||||
|
}
|
||||||
|
|
||||||
|
void SerialPortTool::onFoward()
|
||||||
|
{
|
||||||
|
serialPort->write(cmdMap.value(Forward));
|
||||||
|
serialPort->flush();
|
||||||
|
}
|
||||||
|
|
||||||
|
void SerialPortTool::onBack()
|
||||||
|
{
|
||||||
|
serialPort->write(cmdMap.value(Back));
|
||||||
|
serialPort->flush();
|
||||||
|
}
|
||||||
|
|
||||||
|
void SerialPortTool::onLoopOn()
|
||||||
|
{
|
||||||
|
serialPort->write(cmdMap.value(LoopOn));
|
||||||
|
serialPort->flush();
|
||||||
|
}
|
||||||
|
|
||||||
|
void SerialPortTool::onLoopOff()
|
||||||
|
{
|
||||||
|
serialPort->write(cmdMap.value(LoopOff));
|
||||||
|
serialPort->flush();
|
||||||
|
}
|
||||||
|
|
||||||
|
void SerialPortTool::onMainChannelOn()
|
||||||
|
{
|
||||||
|
serialPort->write(cmdMap.value(MainChannelOn));
|
||||||
|
serialPort->flush();
|
||||||
|
}
|
||||||
|
|
||||||
|
void SerialPortTool::onMainChannelOff()
|
||||||
|
{
|
||||||
|
serialPort->write(cmdMap.value(MainChannelOff));
|
||||||
|
serialPort->flush();
|
||||||
|
}
|
||||||
|
|
||||||
|
void SerialPortTool::onSecondaryChannelOn()
|
||||||
|
{
|
||||||
|
serialPort->write(cmdMap.value(SecondaryChannelOn));
|
||||||
|
serialPort->flush();
|
||||||
|
}
|
||||||
|
|
||||||
|
void SerialPortTool::onSecondaryChannelOff()
|
||||||
|
{
|
||||||
|
serialPort->write(cmdMap.value(SecondaryChannelOff));
|
||||||
|
serialPort->flush();
|
||||||
|
}
|
77
SerialPortTool.h
Normal file
77
SerialPortTool.h
Normal file
@ -0,0 +1,77 @@
|
|||||||
|
#ifndef SERIALPORT_H
|
||||||
|
#define SERIALPORT_H
|
||||||
|
#include <QMap>
|
||||||
|
#include <QObject>
|
||||||
|
#include <QSerialPort>
|
||||||
|
#include <QTimer>
|
||||||
|
|
||||||
|
class SerialPortTool : public QObject {
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
explicit SerialPortTool(QObject* parent = 0);
|
||||||
|
~SerialPortTool();
|
||||||
|
void open();
|
||||||
|
void close();
|
||||||
|
public slots:
|
||||||
|
void onPlaybackStart();
|
||||||
|
void onPlaybackEnd();
|
||||||
|
void onRecordStart();
|
||||||
|
void onRecordEnd();
|
||||||
|
void onPlayPause();
|
||||||
|
void onPlayResume();
|
||||||
|
void onDiskWillFull();
|
||||||
|
void onDiskNotFull();
|
||||||
|
void onPowerOn();
|
||||||
|
void onPowerOff();
|
||||||
|
void onFoward();
|
||||||
|
void onBack();
|
||||||
|
void onLoopOn();
|
||||||
|
void onLoopOff();
|
||||||
|
void onMainChannelOn();
|
||||||
|
void onMainChannelOff();
|
||||||
|
void onSecondaryChannelOn();
|
||||||
|
void onSecondaryChannelOff();
|
||||||
|
|
||||||
|
private slots:
|
||||||
|
void onSerialError(QSerialPort::SerialPortError error);
|
||||||
|
void onTimeout();
|
||||||
|
void onReayRead();
|
||||||
|
signals:
|
||||||
|
void btnPlaybackClicked();
|
||||||
|
void btnPreviousClicked();
|
||||||
|
void btnPauseClicked();
|
||||||
|
void btnReturnClicked();
|
||||||
|
void btnBackClicked();
|
||||||
|
void btnNextClicked();
|
||||||
|
void btnForwardClicked();
|
||||||
|
void btnDoneClicked();
|
||||||
|
|
||||||
|
private:
|
||||||
|
enum CommandType {
|
||||||
|
PlaybackStart,
|
||||||
|
PlaybackEnd,
|
||||||
|
RecordStart,
|
||||||
|
RecordEnd,
|
||||||
|
PlayPause,
|
||||||
|
PlayResume,
|
||||||
|
DiskWillFull,
|
||||||
|
DiskNotFull,
|
||||||
|
PowerOn,
|
||||||
|
PowerOff,
|
||||||
|
Forward,
|
||||||
|
Back,
|
||||||
|
LoopOn,
|
||||||
|
LoopOff,
|
||||||
|
MainChannelOn,
|
||||||
|
MainChannelOff,
|
||||||
|
SecondaryChannelOff,
|
||||||
|
SecondaryChannelOn
|
||||||
|
};
|
||||||
|
|
||||||
|
QSerialPort* serialPort; // 串口
|
||||||
|
QMap<CommandType, QByteArray> cmdMap; // 指令列表
|
||||||
|
QTimer* timer;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // SERIALPORT_H
|
38
TcpConnectionHandler.cpp
Normal file
38
TcpConnectionHandler.cpp
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
#include "TcpConnectionHandler.h"
|
||||||
|
#include "Log.h"
|
||||||
|
#include "TcpResponse.h"
|
||||||
|
|
||||||
|
TcpConnectionHandler::TcpConnectionHandler(QTcpSocket* socket, TcpRequestHandler* handler, QObject* parent)
|
||||||
|
: socket(socket)
|
||||||
|
, handler(handler)
|
||||||
|
, QObject(parent)
|
||||||
|
{
|
||||||
|
request = new TcpRequest();
|
||||||
|
response = new TcpResponse(socket);
|
||||||
|
connect(socket, SIGNAL(readyRead()), this, SLOT(onReadyRead()));
|
||||||
|
connect(socket, SIGNAL(disconnected()), this, SLOT(onDisconnected()));
|
||||||
|
}
|
||||||
|
|
||||||
|
TcpConnectionHandler::~TcpConnectionHandler()
|
||||||
|
{
|
||||||
|
delete request;
|
||||||
|
delete response;
|
||||||
|
}
|
||||||
|
|
||||||
|
void TcpConnectionHandler::onReadyRead()
|
||||||
|
{
|
||||||
|
bool ret = request->readFromSocket(socket);
|
||||||
|
if (!ret) {
|
||||||
|
response->error(request->getErrorString());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
handler->service(request, response);
|
||||||
|
}
|
||||||
|
|
||||||
|
void TcpConnectionHandler::onDisconnected()
|
||||||
|
{
|
||||||
|
Log::info("one client disconnected");
|
||||||
|
emit disconnected();
|
||||||
|
|
||||||
|
socket->close();
|
||||||
|
}
|
29
TcpConnectionHandler.h
Normal file
29
TcpConnectionHandler.h
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
#ifndef TCPCONNECTIONHANDLER_H
|
||||||
|
#define TCPCONNECTIONHANDLER_H
|
||||||
|
|
||||||
|
#include "TcpRequest.h"
|
||||||
|
#include "TcpRequestHandler.h"
|
||||||
|
#include <QObject>
|
||||||
|
#include <QTcpSocket>
|
||||||
|
|
||||||
|
class TcpConnectionHandler : public QObject {
|
||||||
|
Q_OBJECT
|
||||||
|
public:
|
||||||
|
explicit TcpConnectionHandler(QTcpSocket* socket, TcpRequestHandler* handler, QObject* parent = nullptr);
|
||||||
|
~TcpConnectionHandler();
|
||||||
|
|
||||||
|
private slots:
|
||||||
|
void onReadyRead();
|
||||||
|
void onDisconnected();
|
||||||
|
|
||||||
|
signals:
|
||||||
|
void disconnected();
|
||||||
|
|
||||||
|
private:
|
||||||
|
QTcpSocket* socket;
|
||||||
|
TcpRequest* request;
|
||||||
|
TcpResponse* response;
|
||||||
|
TcpRequestHandler* handler;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // TCPCONNECTIONHANDLER_H
|
@ -1,59 +0,0 @@
|
|||||||
#ifndef TCPCONTROLLER_H
|
|
||||||
#define TCPCONTROLLER_H
|
|
||||||
|
|
||||||
#include <QDir>
|
|
||||||
#include <QMap>
|
|
||||||
#include <QObject>
|
|
||||||
#include <QTcpSocket>
|
|
||||||
#include <functional>
|
|
||||||
|
|
||||||
using Routes = QMap<QString, std::function<void(QTcpSocket*)>>;
|
|
||||||
|
|
||||||
class TcpController : public QObject {
|
|
||||||
Q_OBJECT
|
|
||||||
public:
|
|
||||||
TcpController(QObject* parent = nullptr);
|
|
||||||
Routes getRoutes();
|
|
||||||
|
|
||||||
private:
|
|
||||||
Routes routes;
|
|
||||||
void setIpaddr(QTcpSocket* socket);
|
|
||||||
|
|
||||||
void setName(QTcpSocket* socket);
|
|
||||||
void getName(QTcpSocket* socket);
|
|
||||||
|
|
||||||
void setVideoEnc(QTcpSocket* socket);
|
|
||||||
void getVideoEnc(QTcpSocket* socket);
|
|
||||||
|
|
||||||
void getFileList(QTcpSocket* socket);
|
|
||||||
void deleteFile(QTcpSocket* socket);
|
|
||||||
|
|
||||||
void setRecordMode(QTcpSocket* socket);
|
|
||||||
void setPlaybackMode(QTcpSocket* socket);
|
|
||||||
|
|
||||||
void reboot(QTcpSocket* socket);
|
|
||||||
|
|
||||||
inline QVariantMap parseParams(QTcpSocket* socket);
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief 解析tcp请求参数
|
|
||||||
* @param socket
|
|
||||||
* @return
|
|
||||||
*/
|
|
||||||
inline QVariantMap TcpController::parseParams(QTcpSocket* socket)
|
|
||||||
{
|
|
||||||
QVariantMap params;
|
|
||||||
// exmaple:data1=xxx\r\ndata2=xxx\r\n...
|
|
||||||
QStringList data = QString(socket->readAll()).split("\r\n");
|
|
||||||
|
|
||||||
for (int i = 0; i < data.length(); i++) {
|
|
||||||
if (data.at(i).contains("=")) {
|
|
||||||
QStringList pair = data.at(i).split("=");
|
|
||||||
params.insert(pair[0], pair[1]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return params;
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif // TCPCONTROLLER_H
|
|
73
TcpRequest.cpp
Normal file
73
TcpRequest.cpp
Normal file
@ -0,0 +1,73 @@
|
|||||||
|
#include "TcpRequest.h"
|
||||||
|
#include "Log.h"
|
||||||
|
#include <Json.h>
|
||||||
|
|
||||||
|
QString TcpRequest::getUrl()
|
||||||
|
{
|
||||||
|
return url;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 获取请求体参数
|
||||||
|
*/
|
||||||
|
QVariantMap TcpRequest::getBodyParams()
|
||||||
|
{
|
||||||
|
QVariantMap params = this->parseParams();
|
||||||
|
return params;
|
||||||
|
}
|
||||||
|
|
||||||
|
QString TcpRequest::getErrorString()
|
||||||
|
{
|
||||||
|
return errorString;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 从缓冲区读取数据
|
||||||
|
*/
|
||||||
|
bool TcpRequest::readFromSocket(QTcpSocket* socket)
|
||||||
|
{
|
||||||
|
// 读取第一行
|
||||||
|
QString str = socket->readLine().trimmed();
|
||||||
|
if (!str.contains("Url: ")) {
|
||||||
|
Log::error(QString("receive error headers: %1").arg(str).toStdString());
|
||||||
|
socket->readAll();
|
||||||
|
socket->flush();
|
||||||
|
errorString = "未知请求路径参数:" + str;
|
||||||
|
return false;
|
||||||
|
} else {
|
||||||
|
url = str.split(": ")[1];
|
||||||
|
}
|
||||||
|
// 读取第二行
|
||||||
|
str = socket->readLine().trimmed();
|
||||||
|
if (!str.contains("Content-Length: ")) {
|
||||||
|
contentLength = 0;
|
||||||
|
} else {
|
||||||
|
contentLength = str.split(": ")[1].toLongLong();
|
||||||
|
}
|
||||||
|
// 如果请求体长度为0就不再往下读取
|
||||||
|
if (contentLength == 0) {
|
||||||
|
socket->readAll();
|
||||||
|
socket->flush();
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
body.clear();
|
||||||
|
// 读取空行并丢弃
|
||||||
|
socket->readLine();
|
||||||
|
// 循环读取数据,直到读取了content-length长度数据
|
||||||
|
qint64 readSize = 0;
|
||||||
|
while (socket->bytesAvailable() > 0) {
|
||||||
|
char bytes[contentLength];
|
||||||
|
qint64 size = socket->read(bytes, contentLength - readSize);
|
||||||
|
if (size == -1) {
|
||||||
|
errorString = "socket读取数据出错";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
readSize += size;
|
||||||
|
body += QString::fromLocal8Bit(bytes, size);
|
||||||
|
if (readSize >= contentLength) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
42
TcpRequest.h
Normal file
42
TcpRequest.h
Normal file
@ -0,0 +1,42 @@
|
|||||||
|
#ifndef TCPREQUEST_H
|
||||||
|
#define TCPREQUEST_H
|
||||||
|
|
||||||
|
#include <QTcpSocket>
|
||||||
|
class TcpRequest {
|
||||||
|
public:
|
||||||
|
bool readFromSocket(QTcpSocket* socket);
|
||||||
|
QString getUrl();
|
||||||
|
QVariantMap getBodyParams();
|
||||||
|
QString getErrorString();
|
||||||
|
|
||||||
|
private:
|
||||||
|
QString url; // 请求路径
|
||||||
|
qint64 contentLength = 0; // 请求体长度
|
||||||
|
QString body; // 请求体
|
||||||
|
|
||||||
|
QString errorString;
|
||||||
|
|
||||||
|
private:
|
||||||
|
inline QVariantMap parseParams();
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 解析请求体参数
|
||||||
|
*/
|
||||||
|
inline QVariantMap TcpRequest::parseParams()
|
||||||
|
{
|
||||||
|
QVariantMap map;
|
||||||
|
QStringList list = body.split("&");
|
||||||
|
for (QString str : list) {
|
||||||
|
if (str.isEmpty()) {
|
||||||
|
continue;
|
||||||
|
} else {
|
||||||
|
QString key = str.split("=")[0];
|
||||||
|
QString value = str.split("=")[1];
|
||||||
|
map[key] = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return map;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // TCPREQUEST_H
|
@ -1,4 +1,4 @@
|
|||||||
#include "TcpController.h"
|
#include "TcpRequestHandler.h"
|
||||||
#include "Channel.h"
|
#include "Channel.h"
|
||||||
#include "Constant.h"
|
#include "Constant.h"
|
||||||
#include "Json.h"
|
#include "Json.h"
|
||||||
@ -9,34 +9,49 @@
|
|||||||
|
|
||||||
extern const QList<Channel*> channelList;
|
extern const QList<Channel*> channelList;
|
||||||
|
|
||||||
TcpController::TcpController(QObject* parent)
|
TcpRequestHandler::TcpRequestHandler(QObject* parent)
|
||||||
: QObject(parent)
|
: QObject(parent)
|
||||||
{
|
{
|
||||||
// 映射请求路径与处理函数
|
|
||||||
routes.insert("set_ipaddr", std::bind(&TcpController::setIpaddr, this, std::placeholders::_1));
|
|
||||||
routes.insert("set_video_enc", std::bind(&TcpController::setVideoEnc, this, std::placeholders::_1));
|
|
||||||
routes.insert("get_video_enc", std::bind(&TcpController::getVideoEnc, this, std::placeholders::_1));
|
|
||||||
routes.insert("get_file_list", std::bind(&TcpController::getFileList, this, std::placeholders::_1));
|
|
||||||
routes.insert("delete_file", std::bind(&TcpController::deleteFile, this, std::placeholders::_1));
|
|
||||||
routes.insert("set_name", std::bind(&TcpController::setName, this, std::placeholders::_1));
|
|
||||||
routes.insert("get_name", std::bind(&TcpController::getName, this, std::placeholders::_1));
|
|
||||||
routes.insert("set_record_mode", std::bind(&TcpController::setRecordMode, this, std::placeholders::_1));
|
|
||||||
routes.insert("set_playback_mode", std::bind(&TcpController::setPlaybackMode, this, std::placeholders::_1));
|
|
||||||
routes.insert("reoot", std::bind(&TcpController::reboot, this, std::placeholders::_1));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Routes TcpController::getRoutes()
|
void TcpRequestHandler::service(TcpRequest* request, TcpResponse* response)
|
||||||
{
|
{
|
||||||
return this->routes;
|
QString url = request->getUrl();
|
||||||
|
response->setUrl(url);
|
||||||
|
if (url == "/set_ip_addr") {
|
||||||
|
this->setIpaddr(request, response);
|
||||||
|
} else if (url == "/set_name") {
|
||||||
|
this->setName(request, response);
|
||||||
|
} else if (url == "/get_name") {
|
||||||
|
this->getName(request, response);
|
||||||
|
} else if (url == "/set_video_enc") {
|
||||||
|
this->setVideoEnc(request, response);
|
||||||
|
} else if (url == "/get_video_enc") {
|
||||||
|
this->getVideoEnc(request, response);
|
||||||
|
} else if (url == "/get_file_list") {
|
||||||
|
this->getFileList(request, response);
|
||||||
|
} else if (url == "/delete_file") {
|
||||||
|
this->deleteFile(request, response);
|
||||||
|
} else if (url == "/set_record_mode") {
|
||||||
|
this->setRecordMode(request, response);
|
||||||
|
} else if (url == "/set_playback_mode") {
|
||||||
|
this->setPlaybackMode(request, response);
|
||||||
|
} else if (url == "/reboot") {
|
||||||
|
this->reboot(request, response);
|
||||||
|
} else if (url == "/set_current_time") {
|
||||||
|
this->setCurrentTime(request, response);
|
||||||
|
} else {
|
||||||
|
response->error("访问路径未找到");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief 设置盒子的ip
|
* @brief 设置盒子的ip
|
||||||
* @param socket
|
* @param socket
|
||||||
*/
|
*/
|
||||||
void TcpController::setIpaddr(QTcpSocket* socket)
|
void TcpRequestHandler::setIpaddr(TcpRequest* request, TcpResponse* reponse)
|
||||||
{
|
{
|
||||||
QVariantMap params = this->parseParams(socket);
|
QVariantMap params = request->getBodyParams();
|
||||||
QVariantMap netMap = Json::loadFile(Constant::NetConfigPath).toMap();
|
QVariantMap netMap = Json::loadFile(Constant::NetConfigPath).toMap();
|
||||||
|
|
||||||
if (params.contains("ip"))
|
if (params.contains("ip"))
|
||||||
@ -47,7 +62,7 @@ void TcpController::setIpaddr(QTcpSocket* socket)
|
|||||||
netMap["gateway"] = params.value("gateway");
|
netMap["gateway"] = params.value("gateway");
|
||||||
|
|
||||||
Json::saveFile(netMap, Constant::NetConfigPath);
|
Json::saveFile(netMap, Constant::NetConfigPath);
|
||||||
socket->write("url=set_ipaddr\r\nstatus=success");
|
reponse->success();
|
||||||
Tool::writeCom(Constant::NetScriptPath);
|
Tool::writeCom(Constant::NetScriptPath);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -55,41 +70,41 @@ void TcpController::setIpaddr(QTcpSocket* socket)
|
|||||||
* @brief 设置盒子的名称
|
* @brief 设置盒子的名称
|
||||||
* @param socket
|
* @param socket
|
||||||
*/
|
*/
|
||||||
void TcpController::setName(QTcpSocket* socket)
|
void TcpRequestHandler::setName(TcpRequest* request, TcpResponse* reponse)
|
||||||
{
|
{
|
||||||
QVariantMap params = this->parseParams(socket);
|
QVariantMap params = request->getBodyParams();
|
||||||
if (params.isEmpty() || !params.contains("name")) {
|
if (params.isEmpty() || !params.contains("name")) {
|
||||||
Log::error("setName params error, missing param \"name\"");
|
Log::error("setName params error, missing param \"name\"");
|
||||||
socket->write("url=set_name\r\nstatus=error");
|
reponse->error("名称不能为空");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
QVariantMap cfg = Json::loadFile(Constant::ConfigurationPath).toMap();
|
QVariantMap cfg = Json::loadFile(Constant::ConfigurationPath).toMap();
|
||||||
cfg["name"] = params.value("name");
|
cfg["name"] = params.value("name");
|
||||||
Json::saveFile(cfg, Constant::ConfigurationPath);
|
Json::saveFile(cfg, Constant::ConfigurationPath);
|
||||||
socket->write("url=set_name\r\nstatus=success");
|
reponse->success();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief 获取盒子名称
|
* @brief 获取盒子名称
|
||||||
*/
|
*/
|
||||||
void TcpController::getName(QTcpSocket* socket)
|
void TcpRequestHandler::getName(TcpRequest* request, TcpResponse* reponse)
|
||||||
{
|
{
|
||||||
QVariantMap config = Json::loadFile(Constant::ConfigurationPath).toMap();
|
QVariantMap config = Json::loadFile(Constant::ConfigurationPath).toMap();
|
||||||
QString name = config["name"].toString();
|
QString name = config["name"].toString();
|
||||||
QString data = QString("url=get_name\r\nstatus=success\r\nname=%1").arg(name);
|
QString data = QString("url=get_name\r\nstatus=success\r\nname=%1").arg(name);
|
||||||
socket->write(data.toStdString().data());
|
reponse->success("", name);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief 设置视频录制参数
|
* @brief 设置视频录制参数
|
||||||
* @param socket
|
* @param socket
|
||||||
*/
|
*/
|
||||||
void TcpController::setVideoEnc(QTcpSocket* socket)
|
void TcpRequestHandler::setVideoEnc(TcpRequest* request, TcpResponse* reponse)
|
||||||
{
|
{
|
||||||
QVariantMap params = this->parseParams(socket);
|
QVariantMap params = request->getBodyParams();
|
||||||
if (params.isEmpty() || !params.contains("interface")) {
|
if (params.isEmpty() || !params.contains("interface")) {
|
||||||
Log::error("setVideoEncode params error, missing param \"interface\"");
|
Log::error("setVideoEncode params error, missing param \"interface\"");
|
||||||
socket->write("url=set_video_enc\r\nstatus=error");
|
reponse->error("缺少接口参数");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -101,7 +116,7 @@ void TcpController::setVideoEnc(QTcpSocket* socket)
|
|||||||
}
|
}
|
||||||
if (chn) {
|
if (chn) {
|
||||||
// 修改分辨率和帧率
|
// 修改分辨率和帧率
|
||||||
chn->videoEncoder->setData(params);
|
// chn->videoEncoder->setData(params);
|
||||||
// 更新配置文件
|
// 更新配置文件
|
||||||
QVariantMap cfg = Json::loadFile(Constant::ConfigurationPath).toMap();
|
QVariantMap cfg = Json::loadFile(Constant::ConfigurationPath).toMap();
|
||||||
QVariantList interfaces = cfg.value("interface").toList();
|
QVariantList interfaces = cfg.value("interface").toList();
|
||||||
@ -121,10 +136,10 @@ void TcpController::setVideoEnc(QTcpSocket* socket)
|
|||||||
}
|
}
|
||||||
cfg["interface"] = interfaces;
|
cfg["interface"] = interfaces;
|
||||||
Json::saveFile(cfg, Constant::ConfigurationPath);
|
Json::saveFile(cfg, Constant::ConfigurationPath);
|
||||||
socket->write("url=set_video_enc\r\nstatus=success");
|
reponse->success("修改录制参数成功,重启后生效");
|
||||||
} else {
|
} else {
|
||||||
Log::error("set video encode params error, no such interface {}", interface.toStdString());
|
Log::error("set video encode params error, no such interface {}", interface.toStdString());
|
||||||
socket->write("url=set_video_enc\r\nstatus=error");
|
reponse->error(QString("无对应接口: %1").arg(interface));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -132,9 +147,9 @@ void TcpController::setVideoEnc(QTcpSocket* socket)
|
|||||||
* @brief 获取视频录制参数
|
* @brief 获取视频录制参数
|
||||||
* @param socket
|
* @param socket
|
||||||
*/
|
*/
|
||||||
void TcpController::getVideoEnc(QTcpSocket* socket)
|
void TcpRequestHandler::getVideoEnc(TcpRequest* request, TcpResponse* reponse)
|
||||||
{
|
{
|
||||||
QVariantMap params = this->parseParams(socket);
|
QVariantMap params = request->getBodyParams();
|
||||||
|
|
||||||
if (params.contains("interface")) {
|
if (params.contains("interface")) {
|
||||||
QString interface = params.value("interface").toString();
|
QString interface = params.value("interface").toString();
|
||||||
@ -149,21 +164,11 @@ void TcpController::getVideoEnc(QTcpSocket* socket)
|
|||||||
targetInterfaceCfg = item;
|
targetInterfaceCfg = item;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
QString width;
|
|
||||||
QString height;
|
|
||||||
QString framerate;
|
|
||||||
QVariantMap encodeV = targetInterfaceCfg.value("encV").toMap();
|
QVariantMap encodeV = targetInterfaceCfg.value("encV").toMap();
|
||||||
width = encodeV.value("width").toString();
|
reponse->success("", encodeV);
|
||||||
height = encodeV.value("height").toString();
|
|
||||||
framerate = encodeV.value("framerate").toString();
|
|
||||||
QString data = QString("url=get_video_enc\r\nstatus=success\r\nwidth=%1\r\nheight=%2\r\nframerate=%3")
|
|
||||||
.arg(width)
|
|
||||||
.arg(height)
|
|
||||||
.arg(framerate);
|
|
||||||
socket->write(data.toStdString().data());
|
|
||||||
} else {
|
} else {
|
||||||
Log::error("getVideoEnc params error, missing param \"interface\"");
|
Log::error("getVideoEnc params error, missing param \"interface\"");
|
||||||
socket->write("url=get_video_enc\r\nstatus=error");
|
reponse->error("缺少接口参数");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -172,12 +177,12 @@ void TcpController::getVideoEnc(QTcpSocket* socket)
|
|||||||
* @brief 获取文件列表
|
* @brief 获取文件列表
|
||||||
* @param socket
|
* @param socket
|
||||||
*/
|
*/
|
||||||
void TcpController::getFileList(QTcpSocket* socket)
|
void TcpRequestHandler::getFileList(TcpRequest* request, TcpResponse* reponse)
|
||||||
{
|
{
|
||||||
QVariantMap params = this->parseParams(socket);
|
QVariantMap params = request->getBodyParams();
|
||||||
if (params.isEmpty() || !params.contains("interface")) {
|
if (params.isEmpty() || !params.contains("interface")) {
|
||||||
Log::error("getFileList params error, missing param \"interface\"");
|
Log::error("getFileList params error, missing param \"interface\"");
|
||||||
socket->write("url=get_file_list\r\nstatus=error");
|
reponse->error("缺少接口参数");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -186,26 +191,24 @@ void TcpController::getFileList(QTcpSocket* socket)
|
|||||||
|
|
||||||
QStringList videoList = Tool::getFileList(videoPath);
|
QStringList videoList = Tool::getFileList(videoPath);
|
||||||
|
|
||||||
if (videoList.isEmpty()) {
|
// 复制两份测试用
|
||||||
Log::error("getFileList error, video dir is empty ");
|
QStringList copy = videoList;
|
||||||
socket->write("url=get_file_list\r\nstatus=error");
|
QStringList copy1 = videoList;
|
||||||
return;
|
videoList.append(copy);
|
||||||
}
|
videoList.append(copy1);
|
||||||
QString data;
|
reponse->success("获取文件成功", videoList);
|
||||||
data = "url=get_file_list\r\nstatus=success\r\n" + videoList.join("\r\n");
|
|
||||||
socket->write(data.toStdString().data());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief 删除文件
|
* @brief 删除文件
|
||||||
* @param socket
|
* @param socket
|
||||||
*/
|
*/
|
||||||
void TcpController::deleteFile(QTcpSocket* socket)
|
void TcpRequestHandler::deleteFile(TcpRequest* request, TcpResponse* reponse)
|
||||||
{
|
{
|
||||||
QVariantMap params = this->parseParams(socket);
|
QVariantMap params = request->getBodyParams();
|
||||||
if (!params.contains("interface") || !params.contains("filename")) {
|
if (!params.contains("interface") || !params.contains("filename")) {
|
||||||
Log::error("deleteFile params error, missing params \"interface\" or \"filename\"");
|
Log::error("deleteFile params error, missing params \"interface\" or \"filename\"");
|
||||||
socket->write("url=delete_file\r\nstatus=error");
|
reponse->error("缺少端口或文件名");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -219,10 +222,10 @@ void TcpController::deleteFile(QTcpSocket* socket)
|
|||||||
if (video.exists()) {
|
if (video.exists()) {
|
||||||
video.remove();
|
video.remove();
|
||||||
Log::info("remove video {}", filePath.toStdString());
|
Log::info("remove video {}", filePath.toStdString());
|
||||||
socket->write("url=delete_file\r\nstatus=success");
|
reponse->success("删除成功");
|
||||||
} else {
|
} else {
|
||||||
Log::error("error, file: {} dont exist", filePath.toStdString());
|
Log::error("error, file: {} dont exist", filePath.toStdString());
|
||||||
socket->write("url=delete_file\r\nstatus=error");
|
reponse->error("文件不存在");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -230,12 +233,12 @@ void TcpController::deleteFile(QTcpSocket* socket)
|
|||||||
* @brief 设置录制模式,一路录制/两路录制,只修改配置文件,重启之后生效
|
* @brief 设置录制模式,一路录制/两路录制,只修改配置文件,重启之后生效
|
||||||
* @param socket
|
* @param socket
|
||||||
*/
|
*/
|
||||||
void TcpController::setRecordMode(QTcpSocket* socket)
|
void TcpRequestHandler::setRecordMode(TcpRequest* request, TcpResponse* reponse)
|
||||||
{
|
{
|
||||||
QVariantMap params = this->parseParams(socket);
|
QVariantMap params = request->getBodyParams();
|
||||||
if (!params.contains("recordMode")) {
|
if (!params.contains("recordMode")) {
|
||||||
Log::error("setRecordMode params error, missing param \"recordMode\"");
|
Log::error("setRecordMode params error, missing param \"recordMode\"");
|
||||||
socket->write("url=set_record_mode\r\nstatus=error");
|
reponse->error("缺少录制模式参数");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
int recordMode = params.value("recordMode").toInt();
|
int recordMode = params.value("recordMode").toInt();
|
||||||
@ -243,60 +246,93 @@ void TcpController::setRecordMode(QTcpSocket* socket)
|
|||||||
&& recordMode != Constant::TwoChannelRecord
|
&& recordMode != Constant::TwoChannelRecord
|
||||||
&& recordMode != Constant::NoChannelRecord) {
|
&& recordMode != Constant::NoChannelRecord) {
|
||||||
Log::error("setRecordMode params error, unkown param \"recordMode\": {}", recordMode);
|
Log::error("setRecordMode params error, unkown param \"recordMode\": {}", recordMode);
|
||||||
socket->write("url=set_record_mode\r\nstatus=error");
|
reponse->error("录制参数错误");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
QVariantMap cfg = Json::loadFile(Constant::ConfigurationPath).toMap();
|
QVariantMap cfg = Json::loadFile(Constant::ConfigurationPath).toMap();
|
||||||
int mode = cfg["recordMode"].toInt();
|
int mode = cfg["recordMode"].toInt();
|
||||||
if (recordMode == mode) {
|
if (recordMode == mode) {
|
||||||
Log::info("record mode has not changed, there is nothing need to do");
|
Log::info("record mode has not changed, there is nothing need to do");
|
||||||
socket->write("url=set_record_mode\r\nstatus=success");
|
reponse->success("录制参数无需改变");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// 更新配置文件
|
// 更新配置文件
|
||||||
cfg["recordMode"] = recordMode;
|
cfg["recordMode"] = recordMode;
|
||||||
Json::saveFile(cfg, Constant::ConfigurationPath);
|
Json::saveFile(cfg, Constant::ConfigurationPath);
|
||||||
socket->write("url=set_record_mode\r\nstatus=success");
|
reponse->success("设置录制参数成功, 重启后生效");
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief 设置回放模式, 一路回放/两路同时回放,只修改配置文件,重启之后生效
|
* @brief 设置回放模式, 一路回放/两路同时回放,只修改配置文件,重启之后生效
|
||||||
* @param socket
|
* @param socket
|
||||||
*/
|
*/
|
||||||
void TcpController::setPlaybackMode(QTcpSocket* socket)
|
void TcpRequestHandler::setPlaybackMode(TcpRequest* request, TcpResponse* reponse)
|
||||||
{
|
{
|
||||||
QVariantMap params = this->parseParams(socket);
|
QVariantMap params = request->getBodyParams();
|
||||||
if (!params.contains("playbackMode")) {
|
if (!params.contains("playbackMode")) {
|
||||||
Log::error("setPlaybackMode params error, missing param \"playbackmode\"");
|
Log::error("setPlaybackMode params error, missing param \"playbackmode\"");
|
||||||
socket->write("url=set_playback_mode\r\nstatus=error");
|
reponse->error("缺少回放模式参数");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
int playbackMode = params.value("playbackMode").toInt();
|
int playbackMode = params.value("playbackMode").toInt();
|
||||||
if (playbackMode != Constant::OneChannelPlayback
|
if (playbackMode != Constant::OneChannelPlayback
|
||||||
&& playbackMode != Constant::TwoChannelPlayback) {
|
&& playbackMode != Constant::TwoChannelPlayback) {
|
||||||
Log::error("setPlayBack params error, unkown param \"playbackMode\": {}", playbackMode);
|
Log::error("setPlayBack params error, unkown param \"playbackMode\": {}", playbackMode);
|
||||||
socket->write("url=set_playback_mode\r\nstatus=error");
|
reponse->error("回放模式参数错误");
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
QVariantMap cfg = Json::loadFile(Constant::ConfigurationPath).toMap();
|
QVariantMap cfg = Json::loadFile(Constant::ConfigurationPath).toMap();
|
||||||
|
int mode = cfg["playbackMode"].toInt();;
|
||||||
|
if (playbackMode == mode) {
|
||||||
|
Log::info("record mode has not changed, there is nothing need to do");
|
||||||
|
reponse->success("回放参数无需改变");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// 跟新配置文件
|
||||||
cfg["playbackMode"] = playbackMode;
|
cfg["playbackMode"] = playbackMode;
|
||||||
Json::saveFile(cfg, Constant::ConfigurationPath);
|
Json::saveFile(cfg, Constant::ConfigurationPath);
|
||||||
socket->write("url=set_playback_mode\r\nstatus=success");
|
reponse->success("修改回放模式成功,重启后生效");
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief 重启程序
|
* @brief 重启程序
|
||||||
* @param socket
|
* @param socket
|
||||||
*/
|
*/
|
||||||
void TcpController::reboot(QTcpSocket* socket)
|
void TcpRequestHandler::reboot(TcpRequest* request, TcpResponse* reponse)
|
||||||
{
|
{
|
||||||
// 先停止所有的录制
|
// 先停止所有的录制
|
||||||
for (Channel* chn : channelList) {
|
for (Channel* chn : channelList) {
|
||||||
chn->stopRecord();
|
chn->stopRecord();
|
||||||
}
|
}
|
||||||
socket->write("url=reboot\r\nstatus=success");
|
reponse->success("重启成功");
|
||||||
socket->flush();
|
|
||||||
|
|
||||||
// 退出程序,等待后台运行的shell脚本重启程序
|
// 退出程序,等待后台运行的shell脚本重启程序
|
||||||
exit(0);
|
exit(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 设置当前开发板时间,进行时间同步
|
||||||
|
* @param socket
|
||||||
|
*/
|
||||||
|
void TcpRequestHandler::setCurrentTime(TcpRequest* request, TcpResponse* reponse)
|
||||||
|
{
|
||||||
|
QVariantMap params = request->getBodyParams();
|
||||||
|
if (!params.contains("time")) {
|
||||||
|
Log::error("setCurrentTime params error, missing params \"time\"");
|
||||||
|
reponse->error("缺少时间参数");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
QString time = params.value("time").toString();
|
||||||
|
QString cmd = QString("/link/bin/rtc -s time %1").arg(time);
|
||||||
|
QString result = Tool::writeCom(cmd);
|
||||||
|
// 修改成功会返回类似信息, "Tue Mar 5 15:51:18 CST 2024"
|
||||||
|
if (result.isEmpty()) {
|
||||||
|
reponse->error("时间同步失败");
|
||||||
|
return;
|
||||||
|
} else {
|
||||||
|
reponse->success("时间同步成功");
|
||||||
|
}
|
||||||
}
|
}
|
35
TcpRequestHandler.h
Executable file
35
TcpRequestHandler.h
Executable file
@ -0,0 +1,35 @@
|
|||||||
|
#ifndef TCPCONTROLLER_H
|
||||||
|
#define TCPCONTROLLER_H
|
||||||
|
|
||||||
|
#include "TcpRequest.h"
|
||||||
|
#include "TcpResponse.h"
|
||||||
|
#include <QObject>
|
||||||
|
#include <QTcpSocket>
|
||||||
|
|
||||||
|
class TcpRequestHandler : public QObject {
|
||||||
|
Q_OBJECT
|
||||||
|
public:
|
||||||
|
TcpRequestHandler(QObject* parent = nullptr);
|
||||||
|
void service(TcpRequest* request, TcpResponse* reponse);
|
||||||
|
|
||||||
|
private:
|
||||||
|
void setIpaddr(TcpRequest* request, TcpResponse* reponse);
|
||||||
|
|
||||||
|
void setName(TcpRequest* request, TcpResponse* reponse);
|
||||||
|
void getName(TcpRequest* request, TcpResponse* reponse);
|
||||||
|
|
||||||
|
void setVideoEnc(TcpRequest* request, TcpResponse* reponse);
|
||||||
|
void getVideoEnc(TcpRequest* request, TcpResponse* reponse);
|
||||||
|
|
||||||
|
void getFileList(TcpRequest* request, TcpResponse* reponse);
|
||||||
|
void deleteFile(TcpRequest* request, TcpResponse* reponse);
|
||||||
|
|
||||||
|
void setRecordMode(TcpRequest* request, TcpResponse* reponse);
|
||||||
|
void setPlaybackMode(TcpRequest* request, TcpResponse* reponse);
|
||||||
|
|
||||||
|
void reboot(TcpRequest* request, TcpResponse* reponse);
|
||||||
|
|
||||||
|
void setCurrentTime(TcpRequest* request, TcpResponse* reponse);
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // TCPCONTROLLER_H
|
67
TcpResponse.cpp
Normal file
67
TcpResponse.cpp
Normal file
@ -0,0 +1,67 @@
|
|||||||
|
#include "TcpResponse.h"
|
||||||
|
#include <Json.h>
|
||||||
|
|
||||||
|
TcpResponse::TcpResponse(QTcpSocket* socket)
|
||||||
|
: socket(socket)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 设置url
|
||||||
|
* @param url
|
||||||
|
*/
|
||||||
|
void TcpResponse::setUrl(const QString& url)
|
||||||
|
{
|
||||||
|
this->url = url;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 成功
|
||||||
|
*/
|
||||||
|
void TcpResponse::success(QString msg, QVariant data)
|
||||||
|
{
|
||||||
|
QByteArray respone;
|
||||||
|
// 请求路径
|
||||||
|
respone += QString("Url: %1\r\n").arg(url).toUtf8();
|
||||||
|
|
||||||
|
// 响应数据
|
||||||
|
QVariantMap map;
|
||||||
|
map["status"] = "success";
|
||||||
|
map["msg"] = msg.isEmpty() ? "响应成功" : msg;
|
||||||
|
map["data"] = data.isNull() ? "" : data;
|
||||||
|
QByteArray byteData = Json::encode(map).toUtf8();
|
||||||
|
int length = byteData.length();
|
||||||
|
|
||||||
|
// 响应体长度
|
||||||
|
respone += QString("Content-Length: %1\r\n\r\n").arg(length).toUtf8();
|
||||||
|
respone += byteData;
|
||||||
|
|
||||||
|
socket->write(respone);
|
||||||
|
socket->flush();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 错误相应
|
||||||
|
*/
|
||||||
|
void TcpResponse::error(QString msg)
|
||||||
|
{
|
||||||
|
QByteArray respone;
|
||||||
|
// 请求路径
|
||||||
|
respone += QString("Url: %1\r\n").arg(url).toUtf8();
|
||||||
|
|
||||||
|
// 响应数据
|
||||||
|
QVariantMap map;
|
||||||
|
map["status"] = "error";
|
||||||
|
map["msg"] = msg.isEmpty() ? "响应失败" : msg;
|
||||||
|
map["data"] = "";
|
||||||
|
// 打包成json格式
|
||||||
|
QByteArray byteData = Json::encode(map).toUtf8();
|
||||||
|
int length = byteData.length();
|
||||||
|
|
||||||
|
// 响应体长度
|
||||||
|
respone += QString("Content-Length: %1\r\n\r\n").arg(length).toUtf8();
|
||||||
|
respone += byteData;
|
||||||
|
|
||||||
|
socket->write(respone);
|
||||||
|
socket->flush();
|
||||||
|
}
|
20
TcpResponse.h
Normal file
20
TcpResponse.h
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
#ifndef TCPRESPONSE_H
|
||||||
|
#define TCPRESPONSE_H
|
||||||
|
|
||||||
|
#include <QTcpSocket>
|
||||||
|
|
||||||
|
class TcpResponse {
|
||||||
|
public:
|
||||||
|
explicit TcpResponse(QTcpSocket* socket);
|
||||||
|
|
||||||
|
void success(QString msg = "", QVariant data = QVariant());
|
||||||
|
void error(QString msg = "");
|
||||||
|
void setUrl(const QString& url);
|
||||||
|
|
||||||
|
private:
|
||||||
|
QTcpSocket* socket;
|
||||||
|
|
||||||
|
QString url;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // TCPRESPONSE_H
|
@ -5,10 +5,46 @@
|
|||||||
TcpServer::TcpServer(QObject* parent)
|
TcpServer::TcpServer(QObject* parent)
|
||||||
: QTcpServer(parent)
|
: QTcpServer(parent)
|
||||||
{
|
{
|
||||||
controller = new TcpController();
|
handler = new TcpRequestHandler();
|
||||||
|
|
||||||
connect(this, &TcpServer::newConnection, this, &TcpServer::onNewConnect);
|
connect(this, &TcpServer::newConnection, this, &TcpServer::onNewConnect);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TcpServer::~TcpServer()
|
||||||
|
{
|
||||||
|
delete handler;
|
||||||
|
if (!clients.isEmpty()) {
|
||||||
|
qDeleteAll(clients);
|
||||||
|
clients.clear();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 监听端口
|
||||||
|
*/
|
||||||
|
void TcpServer::listen()
|
||||||
|
{
|
||||||
|
bool ret = QTcpServer::listen(QHostAddress::Any, 8080);
|
||||||
|
if (!ret) {
|
||||||
|
Log::error(QString("listen port 8080 failed, %1").arg(errorString()).toStdString());
|
||||||
|
return;
|
||||||
|
} else {
|
||||||
|
Log::info("start tcp server, listen port 8080");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 关闭tcp服务器
|
||||||
|
*/
|
||||||
|
void TcpServer::close()
|
||||||
|
{
|
||||||
|
QTcpServer::close();
|
||||||
|
if (!clients.isEmpty()) {
|
||||||
|
qDeleteAll(clients);
|
||||||
|
clients.clear();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief 服务器有新的连接
|
* @brief 服务器有新的连接
|
||||||
*/
|
*/
|
||||||
@ -17,33 +53,13 @@ void TcpServer::onNewConnect()
|
|||||||
if (this->hasPendingConnections()) {
|
if (this->hasPendingConnections()) {
|
||||||
QTcpSocket* socket = this->nextPendingConnection();
|
QTcpSocket* socket = this->nextPendingConnection();
|
||||||
Log::info("new client connected, ip: {}", socket->peerAddress().toString().toStdString());
|
Log::info("new client connected, ip: {}", socket->peerAddress().toString().toStdString());
|
||||||
clients.push_back(socket);
|
TcpConnectionHandler* connection = new TcpConnectionHandler(socket, handler);
|
||||||
connect(socket, &QTcpSocket::readyRead, this, &TcpServer::onReadyRead);
|
clients.push_back(connection);
|
||||||
connect(socket, &QTcpSocket::disconnected, [=] {
|
|
||||||
QTcpSocket* sk = static_cast<QTcpSocket*>(sender());
|
connect(connection, &TcpConnectionHandler::disconnected, [=] {
|
||||||
Log::info(" one client disconnect...");
|
// 从列表中移除该指针
|
||||||
clients.removeOne(sk);
|
TcpConnectionHandler* conn = static_cast<TcpConnectionHandler*>(sender());
|
||||||
|
clients.removeOne(conn);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief 从缓冲区读取数据
|
|
||||||
*/
|
|
||||||
void TcpServer::onReadyRead()
|
|
||||||
{
|
|
||||||
QTcpSocket* socket = static_cast<QTcpSocket*>(sender());
|
|
||||||
// url=xxx
|
|
||||||
QString data = socket->readLine().trimmed();
|
|
||||||
if (data.contains("=")) {
|
|
||||||
QString url = data.split("=")[1];
|
|
||||||
bool contains = controller->getRoutes().contains(url);
|
|
||||||
if (contains) {
|
|
||||||
Log::info("tcp server receive request: {}", url.toStdString());
|
|
||||||
auto handler = controller->getRoutes().value(url);
|
|
||||||
handler(socket);
|
|
||||||
} else {
|
|
||||||
socket->write(QString("url=%1\r\nstatus=error").arg(url).toStdString().data());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
11
TcpServer.h
11
TcpServer.h
@ -1,7 +1,8 @@
|
|||||||
#ifndef TCPSERVER_H
|
#ifndef TCPSERVER_H
|
||||||
#define TCPSERVER_H
|
#define TCPSERVER_H
|
||||||
|
|
||||||
#include "TcpController.h"
|
#include "TcpConnectionHandler.h"
|
||||||
|
#include "TcpRequestHandler.h"
|
||||||
#include <QTcpServer>
|
#include <QTcpServer>
|
||||||
|
|
||||||
class TcpServer : public QTcpServer {
|
class TcpServer : public QTcpServer {
|
||||||
@ -9,14 +10,16 @@ class TcpServer : public QTcpServer {
|
|||||||
|
|
||||||
public:
|
public:
|
||||||
TcpServer(QObject* parent = nullptr);
|
TcpServer(QObject* parent = nullptr);
|
||||||
|
~TcpServer();
|
||||||
|
void listen();
|
||||||
|
void close();
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
void onReadyRead();
|
|
||||||
void onNewConnect();
|
void onNewConnect();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
TcpController* controller;
|
QList<TcpConnectionHandler*> clients;
|
||||||
QList<QTcpSocket*> clients;
|
TcpRequestHandler* handler;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // TCPSERVER_H
|
#endif // TCPSERVER_H
|
||||||
|
1
Tool.cpp
1
Tool.cpp
@ -29,6 +29,7 @@ QStringList Tool::getFileList(QString path)
|
|||||||
nameFilters << "*.mp4";
|
nameFilters << "*.mp4";
|
||||||
dir.setNameFilters(nameFilters);
|
dir.setNameFilters(nameFilters);
|
||||||
fileList = dir.entryList();
|
fileList = dir.entryList();
|
||||||
|
|
||||||
return fileList;
|
return fileList;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
216
Widget.cpp
216
Widget.cpp
@ -3,6 +3,7 @@
|
|||||||
#include "Constant.h"
|
#include "Constant.h"
|
||||||
#include "Json.h"
|
#include "Json.h"
|
||||||
#include "Log.h"
|
#include "Log.h"
|
||||||
|
#include "SerialPortTool.h"
|
||||||
#include "TcpServer.h"
|
#include "TcpServer.h"
|
||||||
#include "Tool.h"
|
#include "Tool.h"
|
||||||
#include "ui_Widget.h"
|
#include "ui_Widget.h"
|
||||||
@ -18,6 +19,7 @@ QString curFilename;
|
|||||||
|
|
||||||
extern QList<Channel*> channelList;
|
extern QList<Channel*> channelList;
|
||||||
extern Constant::PlaybackMode playbackMode;
|
extern Constant::PlaybackMode playbackMode;
|
||||||
|
extern SerialPortTool* serialPortTool;
|
||||||
|
|
||||||
Widget::Widget(QWidget* parent)
|
Widget::Widget(QWidget* parent)
|
||||||
: QWidget(parent)
|
: QWidget(parent)
|
||||||
@ -46,12 +48,6 @@ Widget::Widget(QWidget* parent)
|
|||||||
ui->listWidget->verticalScrollBar()->hide();
|
ui->listWidget->verticalScrollBar()->hide();
|
||||||
ui->listWidget->hide();
|
ui->listWidget->hide();
|
||||||
|
|
||||||
// 初始化串口
|
|
||||||
initSerialPort();
|
|
||||||
|
|
||||||
// 初始化指令列表
|
|
||||||
initCommandMap();
|
|
||||||
|
|
||||||
// 每5秒更新一次进度条
|
// 每5秒更新一次进度条
|
||||||
progressTimer = new QTimer();
|
progressTimer = new QTimer();
|
||||||
progressTimer->setInterval(500);
|
progressTimer->setInterval(500);
|
||||||
@ -60,47 +56,51 @@ Widget::Widget(QWidget* parent)
|
|||||||
for (Channel* chn : channelList) {
|
for (Channel* chn : channelList) {
|
||||||
connect(chn, SIGNAL(playEnd()), this, SLOT(onPlayEnd()));
|
connect(chn, SIGNAL(playEnd()), this, SLOT(onPlayEnd()));
|
||||||
connect(chn, SIGNAL(showRecordState(bool)), this, SLOT(onShowRecordLabel(bool)));
|
connect(chn, SIGNAL(showRecordState(bool)), this, SLOT(onShowRecordLabel(bool)));
|
||||||
|
// 监听输入信号的变化
|
||||||
|
connect(chn->videoInput, &LinkObject::newEvent, [=](QString type, QVariant msg) {
|
||||||
|
if (type == "signal") {
|
||||||
|
QVariantMap data = msg.toMap();
|
||||||
|
bool available = data["avalible"].toBool();
|
||||||
|
if (available) {
|
||||||
|
Log::info("video input {} is available",
|
||||||
|
chn->channelName == Constant::MainChannel ? "HDMI-A" : "HDMI-B");
|
||||||
|
if (chn->channelName == Constant::MainChannel) {
|
||||||
|
serialPortTool->onMainChannelOn();
|
||||||
|
} else {
|
||||||
|
serialPortTool->onSecondaryChannelOn();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
Log::info("video input {} is not available",
|
||||||
|
chn->channelName == Constant::MainChannel ? "HDMI-A" : "HDMI-B");
|
||||||
|
if (chn->channelName == Constant::MainChannel) {
|
||||||
|
serialPortTool->onMainChannelOff();
|
||||||
|
} else {
|
||||||
|
serialPortTool->onSecondaryChannelOff();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
connect(serialPortTool, SIGNAL(btnPlaybackClicked()), this, SLOT(onBtnPlaybackClicked()));
|
||||||
|
connect(serialPortTool, SIGNAL(btnPreviousClicked()), this, SLOT(onBtnPreviousClicked()));
|
||||||
|
connect(serialPortTool, SIGNAL(btnPauseClicked()), this, SLOT(onBtnEnterClicked()));
|
||||||
|
connect(serialPortTool, SIGNAL(btnReturnClicked()), this, SLOT(onBtnReturnClicked()));
|
||||||
|
connect(serialPortTool, SIGNAL(btnBackClicked()), this, SLOT(onBtnBackClicked()));
|
||||||
|
connect(serialPortTool, SIGNAL(btnNextClicked()), this, SLOT(onBtnNextClicked()));
|
||||||
|
connect(serialPortTool, SIGNAL(btnForwardClicked()), this, SLOT(onBtnForwardClicked()));
|
||||||
|
connect(serialPortTool, SIGNAL(btnDoneClicked()), this, SLOT(onBtnEnterClicked()));
|
||||||
}
|
}
|
||||||
|
|
||||||
Widget::~Widget()
|
Widget::~Widget()
|
||||||
{
|
{
|
||||||
serialPort->close();
|
|
||||||
delete ui;
|
delete ui;
|
||||||
delete timer;
|
|
||||||
delete progressTimer;
|
delete progressTimer;
|
||||||
delete menu;
|
delete menu;
|
||||||
delete progressBar;
|
delete progressBar;
|
||||||
delete message;
|
delete message;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief 初始化串口
|
|
||||||
*/
|
|
||||||
void Widget::initSerialPort()
|
|
||||||
{
|
|
||||||
// 用于重连串口的timer
|
|
||||||
timer = new QTimer();
|
|
||||||
timer->setInterval(3000);
|
|
||||||
timer->stop();
|
|
||||||
|
|
||||||
serialPort = new QSerialPort();
|
|
||||||
serialPort->setPortName("ttyAMA2");
|
|
||||||
serialPort->setBaudRate(QSerialPort::Baud115200);
|
|
||||||
serialPort->setDataBits(QSerialPort::Data8);
|
|
||||||
serialPort->setParity(QSerialPort::NoParity);
|
|
||||||
serialPort->setStopBits(QSerialPort::OneStop);
|
|
||||||
serialPort->setFlowControl(QSerialPort::NoFlowControl);
|
|
||||||
if (serialPort->open(QIODevice::ReadWrite)) {
|
|
||||||
Log::info("open serial port: /dev/ttyAMA2 success");
|
|
||||||
} else {
|
|
||||||
Log::error("open serial port: /dev/ttyAMA2 failed, ready to retry...");
|
|
||||||
timer->start();
|
|
||||||
}
|
|
||||||
connect(serialPort, SIGNAL(error(QSerialPort::SerialPortError)), this, SLOT(onSerialError(QSerialPort::SerialPortError)));
|
|
||||||
connect(serialPort, SIGNAL(readyRead()), this, SLOT(onReadyRead()));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief 获取视频文件列表并显示
|
* @brief 获取视频文件列表并显示
|
||||||
*/
|
*/
|
||||||
@ -118,21 +118,6 @@ void Widget::showPlayList()
|
|||||||
ui->listWidget->setCurrentRow(0);
|
ui->listWidget->setCurrentRow(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief 重连串口
|
|
||||||
*/
|
|
||||||
void Widget::onTimeout()
|
|
||||||
{
|
|
||||||
timer->stop();
|
|
||||||
bool ret = serialPort->open(QIODevice::ReadWrite);
|
|
||||||
if (!ret) {
|
|
||||||
Log::info("reopen serial port: /dev/ttyAMA2 success");
|
|
||||||
timer->start();
|
|
||||||
} else {
|
|
||||||
Log::error("reopen serial port: /dev/ttyAMA2 failed, ready to retry...");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief 更新进度条
|
* @brief 更新进度条
|
||||||
*/
|
*/
|
||||||
@ -143,80 +128,10 @@ void Widget::onProgressTimeout()
|
|||||||
progressBar->setCurrent(pos);
|
progressBar->setCurrent(pos);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief 串口错误处理
|
|
||||||
* @param error
|
|
||||||
*/
|
|
||||||
void Widget::onSerialError(QSerialPort::SerialPortError error)
|
|
||||||
{
|
|
||||||
if (error == QSerialPort::ResourceError) {
|
|
||||||
Log::error("serial port break, try to reopen");
|
|
||||||
serialPort->close();
|
|
||||||
timer->start();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief 映射指令列表
|
|
||||||
*/
|
|
||||||
void Widget::initCommandMap()
|
|
||||||
{
|
|
||||||
commandMap.insert("A1", CmdPlayback);
|
|
||||||
commandMap.insert("A2", CmdNext);
|
|
||||||
commandMap.insert("A3", CmdPrevious);
|
|
||||||
commandMap.insert("A4", CmdForward);
|
|
||||||
commandMap.insert("A5", CmdBack);
|
|
||||||
commandMap.insert("A6", CmdPause);
|
|
||||||
commandMap.insert("A7", CmdReturn);
|
|
||||||
commandMap.insert("A8", CmdEnter);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief 从串口缓冲区接收数据
|
|
||||||
*/
|
|
||||||
void Widget::onReadyRead()
|
|
||||||
{
|
|
||||||
serialPort->waitForReadyRead(100);
|
|
||||||
QString data = serialPort->readLine();
|
|
||||||
if (!commandMap.contains(data)) {
|
|
||||||
Log::error("receive unkown command {} from serial port: /dev/ttyAMA2", data.toStdString());
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
Command cmd = commandMap.value(data);
|
|
||||||
switch (cmd) {
|
|
||||||
case CmdPlayback:
|
|
||||||
receivePlayback();
|
|
||||||
break;
|
|
||||||
case CmdPrevious:
|
|
||||||
receivePrevious();
|
|
||||||
break;
|
|
||||||
case CmdNext:
|
|
||||||
receiveNext();
|
|
||||||
break;
|
|
||||||
case CmdForward:
|
|
||||||
seek("forward");
|
|
||||||
break;
|
|
||||||
case CmdBack:
|
|
||||||
seek("next");
|
|
||||||
break;
|
|
||||||
case CmdPause:
|
|
||||||
receivePasue();
|
|
||||||
break;
|
|
||||||
case CmdEnter:
|
|
||||||
receiveEnter();
|
|
||||||
break;
|
|
||||||
case CmdReturn:
|
|
||||||
receiveReturn();
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief 收到回放指令
|
* @brief 收到回放指令
|
||||||
*/
|
*/
|
||||||
void Widget::receivePlayback()
|
void Widget::onBtnPlaybackClicked()
|
||||||
{
|
{
|
||||||
Log::info("receive command playback, playback mode: {}", playbackMode);
|
Log::info("receive command playback, playback mode: {}", playbackMode);
|
||||||
// 如果是一路回放,显示选择菜单
|
// 如果是一路回放,显示选择菜单
|
||||||
@ -234,7 +149,7 @@ void Widget::receivePlayback()
|
|||||||
/**
|
/**
|
||||||
* @brief 收到上段指令
|
* @brief 收到上段指令
|
||||||
*/
|
*/
|
||||||
void Widget::receivePrevious()
|
void Widget::onBtnPreviousClicked()
|
||||||
{
|
{
|
||||||
// 菜单显示则切换菜单选中
|
// 菜单显示则切换菜单选中
|
||||||
if (menu->isVisible()) {
|
if (menu->isVisible()) {
|
||||||
@ -249,14 +164,12 @@ void Widget::receivePrevious()
|
|||||||
ui->listWidget->setCurrentRow(curRow - 1);
|
ui->listWidget->setCurrentRow(curRow - 1);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (isPlayback) {
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief 收到下段指令
|
* @brief 收到下段指令
|
||||||
*/
|
*/
|
||||||
void Widget::receiveNext()
|
void Widget::onBtnNextClicked()
|
||||||
{
|
{
|
||||||
if (menu->isVisible()) {
|
if (menu->isVisible()) {
|
||||||
menu->setCurChannel(Constant::SecondaryChannel);
|
menu->setCurChannel(Constant::SecondaryChannel);
|
||||||
@ -270,14 +183,12 @@ void Widget::receiveNext()
|
|||||||
ui->listWidget->setCurrentRow(curRow + 1);
|
ui->listWidget->setCurrentRow(curRow + 1);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (isPlayback) {
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief 收到暂停指令
|
* @brief 收到暂停指令
|
||||||
*/
|
*/
|
||||||
void Widget::receivePasue()
|
void Widget::onBtnPasueClicked()
|
||||||
{
|
{
|
||||||
if (!isPlayback)
|
if (!isPlayback)
|
||||||
return;
|
return;
|
||||||
@ -288,8 +199,12 @@ void Widget::receivePasue()
|
|||||||
progressBar->showMax();
|
progressBar->showMax();
|
||||||
if (chn->state == Channel::Pause) {
|
if (chn->state == Channel::Pause) {
|
||||||
progressBar->setState(ProgressBar::Pause);
|
progressBar->setState(ProgressBar::Pause);
|
||||||
|
// 打开暂停灯
|
||||||
|
serialPortTool->onPlayPause();
|
||||||
} else {
|
} else {
|
||||||
progressBar->setState(ProgressBar::Play);
|
progressBar->setState(ProgressBar::Play);
|
||||||
|
// 关闭暂停灯
|
||||||
|
serialPortTool->onPlayPause();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -299,7 +214,7 @@ void Widget::receivePasue()
|
|||||||
/**
|
/**
|
||||||
* @brief 收到确定指令
|
* @brief 收到确定指令
|
||||||
*/
|
*/
|
||||||
void Widget::receiveEnter()
|
void Widget::onBtnEnterClicked()
|
||||||
{
|
{
|
||||||
// 菜单显示,则关闭菜单显示列表
|
// 菜单显示,则关闭菜单显示列表
|
||||||
if (menu->isVisible()) {
|
if (menu->isVisible()) {
|
||||||
@ -315,6 +230,7 @@ void Widget::receiveEnter()
|
|||||||
playOneChannel();
|
playOneChannel();
|
||||||
else if (playbackMode == Constant::TwoChannelPlayback)
|
else if (playbackMode == Constant::TwoChannelPlayback)
|
||||||
playTwoChannels();
|
playTwoChannels();
|
||||||
|
serialPortTool->onPlaybackStart();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -323,7 +239,7 @@ void Widget::receiveEnter()
|
|||||||
* @brief 收到返回指令
|
* @brief 收到返回指令
|
||||||
* 处理优先级: 菜单 ==> 列表 ==> 回放
|
* 处理优先级: 菜单 ==> 列表 ==> 回放
|
||||||
*/
|
*/
|
||||||
void Widget::receiveReturn()
|
void Widget::onBtnReturnClicked()
|
||||||
{
|
{
|
||||||
if (menu->isVisible()) {
|
if (menu->isVisible()) {
|
||||||
menu->hide();
|
menu->hide();
|
||||||
@ -336,8 +252,10 @@ void Widget::receiveReturn()
|
|||||||
if (isPlayback) {
|
if (isPlayback) {
|
||||||
// 停止回放
|
// 停止回放
|
||||||
for (Channel* chn : channelList) {
|
for (Channel* chn : channelList) {
|
||||||
if (chn->state != Channel::Stop)
|
if (chn->state != Channel::Stop) {
|
||||||
chn->startPlayLive();
|
chn->startPlayLive();
|
||||||
|
serialPortTool->onPlaybackEnd();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
progressBar->hide();
|
progressBar->hide();
|
||||||
ui->lblA->show();
|
ui->lblA->show();
|
||||||
@ -354,16 +272,36 @@ void Widget::seek(QString type)
|
|||||||
return;
|
return;
|
||||||
for (Channel* chn : channelList) {
|
for (Channel* chn : channelList) {
|
||||||
if (chn->state == Channel::Pause || chn->state == Channel::Playback) {
|
if (chn->state == Channel::Pause || chn->state == Channel::Playback) {
|
||||||
if (type == "forward")
|
if (type == "forward") {
|
||||||
chn->forward();
|
chn->forward();
|
||||||
else
|
serialPortTool->onFoward();
|
||||||
|
} else {
|
||||||
chn->back();
|
chn->back();
|
||||||
|
serialPortTool->onBack();
|
||||||
|
}
|
||||||
|
|
||||||
if (chn->channelName == Constant::MainChannel)
|
if (chn->channelName == Constant::MainChannel)
|
||||||
progressBar->showMax();
|
progressBar->showMax();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 快进
|
||||||
|
*/
|
||||||
|
void Widget::onBtnForwardClicked()
|
||||||
|
{
|
||||||
|
seek("forward");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 快退
|
||||||
|
*/
|
||||||
|
void Widget::onBtnBackClicked()
|
||||||
|
{
|
||||||
|
seek("back");
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief 一路回放,将当前选中播放的视频从HDMI-OUT0口输出
|
* @brief 一路回放,将当前选中播放的视频从HDMI-OUT0口输出
|
||||||
*/
|
*/
|
||||||
@ -478,7 +416,17 @@ void Widget::onPlayEnd()
|
|||||||
QString dirPath = QString("%1/%2").arg(Constant::VideoPath).arg(curPlayChannel);
|
QString dirPath = QString("%1/%2").arg(Constant::VideoPath).arg(curPlayChannel);
|
||||||
fileList = Tool::getFileList(dirPath);
|
fileList = Tool::getFileList(dirPath);
|
||||||
if (index == fileList.length() - 1) {
|
if (index == fileList.length() - 1) {
|
||||||
Log::info("no file to play");
|
Log::info("there is no file to play");
|
||||||
|
// 显示播放完毕的信息
|
||||||
|
if (playbackMode == Constant::OneChannelPlayback) {
|
||||||
|
Channel* chn = findChannelByName(Constant::MainChannel);
|
||||||
|
if (chn)
|
||||||
|
chn->showFinishPromot();
|
||||||
|
} else if (playbackMode == Constant::TwoChannelPlayback) {
|
||||||
|
for (Channel* chn : channelList) {
|
||||||
|
chn->showFinishPromot();
|
||||||
|
}
|
||||||
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
Log::info("refresh current play file list");
|
Log::info("refresh current play file list");
|
||||||
|
41
Widget.h
41
Widget.h
@ -5,11 +5,8 @@
|
|||||||
#include "Menu.h"
|
#include "Menu.h"
|
||||||
#include "Message.h"
|
#include "Message.h"
|
||||||
#include "ProgressBar.h"
|
#include "ProgressBar.h"
|
||||||
#include <QDebug>
|
|
||||||
#include <QDir>
|
#include <QDir>
|
||||||
#include <QMap>
|
#include <QMap>
|
||||||
#include <QSerialPort>
|
|
||||||
#include <QSerialPortInfo>
|
|
||||||
#include <QTimer>
|
#include <QTimer>
|
||||||
#include <QWidget>
|
#include <QWidget>
|
||||||
|
|
||||||
@ -19,17 +16,6 @@ class Widget;
|
|||||||
|
|
||||||
class Widget : public QWidget {
|
class Widget : public QWidget {
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
enum Command {
|
|
||||||
CmdPlayback,
|
|
||||||
CmdNext,
|
|
||||||
CmdPrevious,
|
|
||||||
CmdForward,
|
|
||||||
CmdBack,
|
|
||||||
CmdPause,
|
|
||||||
CmdReturn,
|
|
||||||
CmdEnter
|
|
||||||
};
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit Widget(QWidget* parent = 0);
|
explicit Widget(QWidget* parent = 0);
|
||||||
~Widget();
|
~Widget();
|
||||||
@ -38,21 +24,23 @@ public slots:
|
|||||||
void showPlayList();
|
void showPlayList();
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
void onSerialError(QSerialPort::SerialPortError error);
|
|
||||||
void onTimeout();
|
|
||||||
void onReadyRead();
|
|
||||||
void onProgressTimeout();
|
void onProgressTimeout();
|
||||||
void onPlayEnd();
|
void onPlayEnd();
|
||||||
void onShowRecordLabel(bool show);
|
void onShowRecordLabel(bool show);
|
||||||
|
|
||||||
|
void onBtnPlaybackClicked();
|
||||||
|
void onBtnPreviousClicked();
|
||||||
|
void onBtnNextClicked();
|
||||||
|
void onBtnPasueClicked();
|
||||||
|
void onBtnEnterClicked();
|
||||||
|
void onBtnReturnClicked();
|
||||||
|
void onBtnForwardClicked();
|
||||||
|
void onBtnBackClicked();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Ui::Widget* ui;
|
Ui::Widget* ui;
|
||||||
QStringList fileList;
|
QStringList fileList;
|
||||||
|
|
||||||
QTimer* timer;
|
|
||||||
QSerialPort* serialPort;
|
|
||||||
QMap<QString, Command> commandMap;
|
|
||||||
|
|
||||||
QTimer* progressTimer;
|
QTimer* progressTimer;
|
||||||
bool isPlayback = false;
|
bool isPlayback = false;
|
||||||
QString curPlayChannel;
|
QString curPlayChannel;
|
||||||
@ -64,20 +52,9 @@ private:
|
|||||||
Message* message;
|
Message* message;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void initSerialPort();
|
|
||||||
void initCommandMap();
|
|
||||||
|
|
||||||
void receivePlayback();
|
|
||||||
void receivePrevious();
|
|
||||||
void receiveNext();
|
|
||||||
void seek(QString type);
|
void seek(QString type);
|
||||||
void receivePasue();
|
|
||||||
void receiveEnter();
|
|
||||||
void receiveReturn();
|
|
||||||
|
|
||||||
void playOneChannel();
|
void playOneChannel();
|
||||||
void playTwoChannels();
|
void playTwoChannels();
|
||||||
|
|
||||||
Channel* findChannelByName(QString name);
|
Channel* findChannelByName(QString name);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
36
main.cpp
36
main.cpp
@ -4,13 +4,18 @@
|
|||||||
#include "Json.h"
|
#include "Json.h"
|
||||||
#include "Link.h"
|
#include "Link.h"
|
||||||
#include "Log.h"
|
#include "Log.h"
|
||||||
|
#include "SerialPortTool.h"
|
||||||
#include "TcpServer.h"
|
#include "TcpServer.h"
|
||||||
|
#include "Tool.h"
|
||||||
#include "Widget.h"
|
#include "Widget.h"
|
||||||
#include <QApplication>
|
#include <QApplication>
|
||||||
#include <QDebug>
|
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
|
||||||
|
// Tcp服务器
|
||||||
TcpServer* server;
|
TcpServer* server;
|
||||||
|
// 串口工具
|
||||||
|
SerialPortTool* serialPortTool;
|
||||||
|
// 视频输出通道
|
||||||
LinkObject* vo;
|
LinkObject* vo;
|
||||||
LinkObject* vo1;
|
LinkObject* vo1;
|
||||||
|
|
||||||
@ -60,11 +65,21 @@ bool loadConfiguration(QString path)
|
|||||||
*/
|
*/
|
||||||
void startRecord()
|
void startRecord()
|
||||||
{
|
{
|
||||||
|
// 判断是否挂载了磁盘
|
||||||
|
QString info = Tool::writeCom(QString("df %1").arg(Constant::MountedPath));
|
||||||
|
if (!info.contains(Constant::MountedPath)) {
|
||||||
|
Log::error("there is no disk mounted");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// 一路录制,只录制HDMI-A通道
|
// 一路录制,只录制HDMI-A通道
|
||||||
if (recordMode == Constant::OneChannelRecord) {
|
if (recordMode == Constant::OneChannelRecord) {
|
||||||
for (Channel* chn : channelList) {
|
for (Channel* chn : channelList) {
|
||||||
if (chn->channelName == Constant::MainChannel) {
|
if (chn->channelName == Constant::MainChannel) {
|
||||||
chn->startRecord();
|
chn->startRecord();
|
||||||
|
// 打开录制灯,关闭环路灯
|
||||||
|
serialPortTool->onRecordStart();
|
||||||
|
serialPortTool->onLoopOff();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -72,8 +87,16 @@ void startRecord()
|
|||||||
else if (recordMode == Constant::TwoChannelRecord) {
|
else if (recordMode == Constant::TwoChannelRecord) {
|
||||||
for (Channel* chn : channelList) {
|
for (Channel* chn : channelList) {
|
||||||
chn->startRecord();
|
chn->startRecord();
|
||||||
|
// 打开录制灯,关闭环路灯
|
||||||
|
serialPortTool->onRecordStart();
|
||||||
|
serialPortTool->onLoopOff();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// 无录制
|
||||||
|
else {
|
||||||
|
// 打开环路灯
|
||||||
|
serialPortTool->onLoopOn();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int main(int argc, char* argv[])
|
int main(int argc, char* argv[])
|
||||||
@ -140,6 +163,12 @@ int main(int argc, char* argv[])
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 串口
|
||||||
|
serialPortTool = new SerialPortTool();
|
||||||
|
serialPortTool->open();
|
||||||
|
// 打开电源灯
|
||||||
|
serialPortTool->onPowerOn();
|
||||||
|
|
||||||
// qt界面
|
// qt界面
|
||||||
Widget w;
|
Widget w;
|
||||||
w.show();
|
w.show();
|
||||||
@ -149,12 +178,13 @@ int main(int argc, char* argv[])
|
|||||||
|
|
||||||
// 开启Tcp服务
|
// 开启Tcp服务
|
||||||
server = new TcpServer();
|
server = new TcpServer();
|
||||||
server->listen(QHostAddress::Any, 8080);
|
server->listen();
|
||||||
Log::info("start tcp server, listen port 8080...");
|
|
||||||
|
|
||||||
// 硬盘检测线程,检测硬盘容量
|
// 硬盘检测线程,检测硬盘容量
|
||||||
CheckStorageThread* thread = new CheckStorageThread();
|
CheckStorageThread* thread = new CheckStorageThread();
|
||||||
thread->start();
|
thread->start();
|
||||||
|
QObject::connect(thread, SIGNAL(diskWillFull()), serialPortTool, SLOT(onDiskWillFull()));
|
||||||
|
QObject::connect(thread, SIGNAL(diskNotFull()), serialPortTool, SLOT(onDiskNotFull()));
|
||||||
Log::info("start storage check thread...");
|
Log::info("start storage check thread...");
|
||||||
|
|
||||||
return a.exec();
|
return a.exec();
|
||||||
|
Loading…
Reference in New Issue
Block a user