优化录制功能以及网络通信接口
This commit is contained in:
parent
d1d8655645
commit
97f22cf302
60
Channel.cpp
60
Channel.cpp
@ -5,17 +5,22 @@
|
|||||||
#include "Log.h"
|
#include "Log.h"
|
||||||
#include "Tool.h"
|
#include "Tool.h"
|
||||||
#include <QCoreApplication>
|
#include <QCoreApplication>
|
||||||
|
#include <QElapsedTimer>
|
||||||
#include <QFileInfo>
|
#include <QFileInfo>
|
||||||
#include <QProcess>
|
#include <QProcess>
|
||||||
#include <QTime>
|
#include <QTime>
|
||||||
#include <chrono>
|
#include <chrono>
|
||||||
|
|
||||||
#include <QElapsedTimer>
|
|
||||||
|
|
||||||
LinkObject* Channel::lineIn = nullptr;
|
LinkObject* Channel::lineIn = nullptr;
|
||||||
LinkObject* Channel::lineOut = nullptr;
|
LinkObject* Channel::lineOut = nullptr;
|
||||||
LinkObject* Channel::rtspServer = nullptr;
|
LinkObject* Channel::rtspServer = nullptr;
|
||||||
LinkObject* Channel::resample = nullptr;
|
LinkObject* Channel::resample = nullptr;
|
||||||
|
LinkObject* Channel::gain = nullptr;
|
||||||
|
LinkObject* Channel::volume = nullptr;
|
||||||
|
// 这里设置最大12dB增益,最小30dB增益(超过12dB会爆音)
|
||||||
|
int Channel::maxGian = 12;
|
||||||
|
int Channel::minGain = -30;
|
||||||
|
int Channel::curGain = 0;
|
||||||
|
|
||||||
extern LinkObject* vo;
|
extern LinkObject* vo;
|
||||||
extern LinkObject* vo1;
|
extern LinkObject* vo1;
|
||||||
@ -52,15 +57,29 @@ Channel::Channel(QObject* parent)
|
|||||||
if (lineOut == nullptr) {
|
if (lineOut == nullptr) {
|
||||||
lineOut = Link::create("OutputAlsa");
|
lineOut = Link::create("OutputAlsa");
|
||||||
QVariantMap dataOut;
|
QVariantMap dataOut;
|
||||||
dataOut["path"] = "hw:0,0";
|
dataOut["path"] = "hw:0";
|
||||||
lineOut->start(dataOut);
|
lineOut->start(dataOut);
|
||||||
}
|
}
|
||||||
|
if (gain == nullptr) {
|
||||||
|
gain = Link::create("Gain");
|
||||||
|
gain->start();
|
||||||
|
}
|
||||||
|
if (volume == nullptr) {
|
||||||
|
volume = Link::create("Volume");
|
||||||
|
volume->start();
|
||||||
|
gain->linkA(volume);
|
||||||
|
gain->linkA(lineOut);
|
||||||
|
}
|
||||||
if (rtspServer == nullptr) {
|
if (rtspServer == nullptr) {
|
||||||
rtspServer = Link::create("Rtsp");
|
rtspServer = Link::create("Rtsp");
|
||||||
rtspServer->start();
|
rtspServer->start();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Channel::~Channel()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief 初始化
|
* @brief 初始化
|
||||||
*/
|
*/
|
||||||
@ -104,14 +123,6 @@ void Channel::init()
|
|||||||
audioInput->start(dataAi);
|
audioInput->start(dataAi);
|
||||||
audioInput->linkA(audioOutput);
|
audioInput->linkA(audioOutput);
|
||||||
|
|
||||||
// 音量
|
|
||||||
gain = Link::create("Gain");
|
|
||||||
gain->start();
|
|
||||||
volume = Link::create("Volume");
|
|
||||||
volume->start();
|
|
||||||
gain->linkA(volume);
|
|
||||||
lineOut->linkA(gain);
|
|
||||||
|
|
||||||
// 音频编码
|
// 音频编码
|
||||||
audioEncoder = Link::create("EncodeA");
|
audioEncoder = Link::create("EncodeA");
|
||||||
audioEncoder->start(audioEncoderParams);
|
audioEncoder->start(audioEncoderParams);
|
||||||
@ -166,7 +177,7 @@ void Channel::init()
|
|||||||
audioDecoder = Link::create("DecodeA");
|
audioDecoder = Link::create("DecodeA");
|
||||||
audioDecoder->start();
|
audioDecoder->start();
|
||||||
if (channelName == Constant::MainChannel) {
|
if (channelName == Constant::MainChannel) {
|
||||||
inputFile->linkA(audioDecoder)->linkA(lineOut);
|
inputFile->linkA(audioDecoder)->linkA(gain);
|
||||||
} else {
|
} else {
|
||||||
inputFile->linkA(audioDecoder);
|
inputFile->linkA(audioDecoder);
|
||||||
}
|
}
|
||||||
@ -182,8 +193,6 @@ void Channel::init()
|
|||||||
*/
|
*/
|
||||||
void Channel::startRecord()
|
void Channel::startRecord()
|
||||||
{
|
{
|
||||||
QElapsedTimer mstimer;
|
|
||||||
mstimer.start();
|
|
||||||
// 记录本次录制开始时间以及当前视频录制的开始时间
|
// 记录本次录制开始时间以及当前视频录制的开始时间
|
||||||
QString curTime = QDateTime::currentDateTime().toString("yyyyMMddhhmmss");
|
QString curTime = QDateTime::currentDateTime().toString("yyyyMMddhhmmss");
|
||||||
startTime = curTime;
|
startTime = curTime;
|
||||||
@ -198,9 +207,6 @@ void Channel::startRecord()
|
|||||||
|
|
||||||
// 显示录制状态水印
|
// 显示录制状态水印
|
||||||
overlay->setData(recordOverlay);
|
overlay->setData(recordOverlay);
|
||||||
|
|
||||||
float time = (double)mstimer.nsecsElapsed() / (double)1000000;
|
|
||||||
qDebug() << channelName << "startRecord cast time:" << time << "ms";
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -211,7 +217,7 @@ void Channel::startRecord()
|
|||||||
void Channel::onNewEvent(QString msg, QVariant data)
|
void Channel::onNewEvent(QString msg, QVariant data)
|
||||||
{
|
{
|
||||||
if (msg == "newSegment") {
|
if (msg == "newSegment") {
|
||||||
int id = data.toInt();
|
segmentId = data.toInt();
|
||||||
// 将上一次的文件信息存入数据库中
|
// 将上一次的文件信息存入数据库中
|
||||||
DatabaseManager::File file;
|
DatabaseManager::File file;
|
||||||
file.channel = channelName == Constant::MainChannel
|
file.channel = channelName == Constant::MainChannel
|
||||||
@ -223,7 +229,7 @@ void Channel::onNewEvent(QString msg, QVariant data)
|
|||||||
file.day = currentTime.mid(6, 2);
|
file.day = currentTime.mid(6, 2);
|
||||||
file.time = currentTime.mid(8, 6);
|
file.time = currentTime.mid(8, 6);
|
||||||
// 设置当前视频的文件名,格式:本次录制开始时间_第几次分片
|
// 设置当前视频的文件名,格式:本次录制开始时间_第几次分片
|
||||||
file.filename = QString("%1_%2.mp4").arg(startTime).arg(id - 1);
|
file.filename = QString("%1_%2.mp4").arg(startTime).arg(segmentId - 1);
|
||||||
if (db->insert(file)) {
|
if (db->insert(file)) {
|
||||||
Log::info("insert one record into database success, name: {}, channel: {}",
|
Log::info("insert one record into database success, name: {}, channel: {}",
|
||||||
file.filename.toStdString(),
|
file.filename.toStdString(),
|
||||||
@ -235,6 +241,7 @@ void Channel::onNewEvent(QString msg, QVariant data)
|
|||||||
}
|
}
|
||||||
// 更新当前录制录制视频的时间
|
// 更新当前录制录制视频的时间
|
||||||
currentTime = QDateTime::currentDateTime().toString("yyyyMMddhhmmss");
|
currentTime = QDateTime::currentDateTime().toString("yyyyMMddhhmmss");
|
||||||
|
emit appendOneVideo(channelName);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -250,10 +257,11 @@ void Channel::stopRecord()
|
|||||||
file.channel = channelName == Constant::MainChannel
|
file.channel = channelName == Constant::MainChannel
|
||||||
? DatabaseManager::MainChannel
|
? DatabaseManager::MainChannel
|
||||||
: DatabaseManager::SecondaryChannel;
|
: DatabaseManager::SecondaryChannel;
|
||||||
file.year = startTime.mid(0, 4);
|
file.year = currentTime.mid(0, 4);
|
||||||
file.month = startTime.mid(4, 2);
|
file.month = currentTime.mid(4, 2);
|
||||||
file.day = startTime.mid(6, 2);
|
file.day = currentTime.mid(6, 2);
|
||||||
file.time = startTime.mid(8, 6);
|
file.time = currentTime.mid(8, 6);
|
||||||
|
file.filename = QString("%1_%2.mp4").arg(startTime).arg(segmentId);
|
||||||
overlay->setData(norecordOverlay);
|
overlay->setData(norecordOverlay);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -301,7 +309,7 @@ bool Channel::startPlayback(QString path)
|
|||||||
videoDecoder->linkV(videoOutput);
|
videoDecoder->linkV(videoOutput);
|
||||||
// 断开音频信号输出,启动回放输出
|
// 断开音频信号输出,启动回放输出
|
||||||
audioInput->unLinkA(audioOutput);
|
audioInput->unLinkA(audioOutput);
|
||||||
audioDecoder->linkA(lineOut);
|
audioDecoder->linkA(gain);
|
||||||
|
|
||||||
playbackDuration = duration;
|
playbackDuration = duration;
|
||||||
state = Playback;
|
state = Playback;
|
||||||
@ -325,7 +333,7 @@ void Channel::startPlayLive()
|
|||||||
overlay->linkV(videoOutput);
|
overlay->linkV(videoOutput);
|
||||||
audioInput->linkA(audioOutput);
|
audioInput->linkA(audioOutput);
|
||||||
// 关闭外部音频输出
|
// 关闭外部音频输出
|
||||||
audioDecoder->unLinkA(lineOut);
|
audioDecoder->unLinkA(gain);
|
||||||
state = Stop;
|
state = Stop;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -405,6 +413,7 @@ void Channel::volumeUp()
|
|||||||
QVariantMap data;
|
QVariantMap data;
|
||||||
data["gain"] = curGain;
|
data["gain"] = curGain;
|
||||||
gain->setData(data);
|
gain->setData(data);
|
||||||
|
Log::info("current volumn gain: {}dB", curGain);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -417,6 +426,7 @@ void Channel::volumeDown()
|
|||||||
QVariantMap data;
|
QVariantMap data;
|
||||||
data["gain"] = curGain;
|
data["gain"] = curGain;
|
||||||
gain->setData(data);
|
gain->setData(data);
|
||||||
|
Log::info("current volumn gain: {}dB", curGain);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
18
Channel.h
18
Channel.h
@ -17,6 +17,7 @@ public:
|
|||||||
Finish
|
Finish
|
||||||
};
|
};
|
||||||
explicit Channel(QObject* parent = nullptr);
|
explicit Channel(QObject* parent = nullptr);
|
||||||
|
~Channel();
|
||||||
void init();
|
void init();
|
||||||
|
|
||||||
// 录制
|
// 录制
|
||||||
@ -32,9 +33,9 @@ public:
|
|||||||
void showFinishPromot();
|
void showFinishPromot();
|
||||||
|
|
||||||
// 音量
|
// 音量
|
||||||
QVariantMap getVolume();
|
static QVariantMap getVolume();
|
||||||
void volumeUp();
|
static void volumeUp();
|
||||||
void volumeDown();
|
static void volumeDown();
|
||||||
|
|
||||||
public:
|
public:
|
||||||
QString channelName;
|
QString channelName;
|
||||||
@ -47,11 +48,11 @@ public:
|
|||||||
static LinkObject* lineIn; // 外部音频输入
|
static LinkObject* lineIn; // 外部音频输入
|
||||||
static LinkObject* resample; // 重采样
|
static LinkObject* resample; // 重采样
|
||||||
static LinkObject* lineOut; // 外部音频输出
|
static LinkObject* lineOut; // 外部音频输出
|
||||||
LinkObject* gain; // 音量增益
|
static LinkObject* gain; // 音量增益
|
||||||
LinkObject* volume; // 音量
|
static LinkObject* volume; // 音量
|
||||||
int maxGian = 30;
|
static int maxGian; // 最大增益
|
||||||
int minGain = -30;
|
static int minGain; // 最小增益
|
||||||
int curGain = 0;
|
static int curGain; // 当前增益
|
||||||
|
|
||||||
LinkObject* audioInput; // 通道音频输入
|
LinkObject* audioInput; // 通道音频输入
|
||||||
LinkObject* audioOutput; // 通道音频输入
|
LinkObject* audioOutput; // 通道音频输入
|
||||||
@ -85,6 +86,7 @@ private slots:
|
|||||||
signals:
|
signals:
|
||||||
void playEnd();
|
void playEnd();
|
||||||
void showRecordState(bool state);
|
void showRecordState(bool state);
|
||||||
|
void appendOneVideo(QString channelName);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void loadOverlayConfig();
|
void loadOverlayConfig();
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
|
|
||||||
class Constant {
|
class Constant {
|
||||||
public:
|
public:
|
||||||
Constant() {}
|
Constant() { }
|
||||||
enum RecordMode {
|
enum RecordMode {
|
||||||
NoChannelRecord,
|
NoChannelRecord,
|
||||||
OneChannelRecord,
|
OneChannelRecord,
|
||||||
@ -19,6 +19,7 @@ public:
|
|||||||
static constexpr char* ConfigurationPath = "/opt/RecordControlApplication/configuration/config.json";
|
static constexpr char* ConfigurationPath = "/opt/RecordControlApplication/configuration/config.json";
|
||||||
static constexpr char* NetConfigPath = "/opt/RecordControlApplication/configuration/net.json";
|
static constexpr char* NetConfigPath = "/opt/RecordControlApplication/configuration/net.json";
|
||||||
static constexpr char* NetScriptPath = "/opt/RecordControlApplication/scripts/setNetwork.sh";
|
static constexpr char* NetScriptPath = "/opt/RecordControlApplication/scripts/setNetwork.sh";
|
||||||
|
static constexpr char* TimeSciptPath = "/opt/RecordControlApplication/scripts/rtc";
|
||||||
static constexpr char* DatabasePath = "/opt/RecordControlApplication/database/data.db";
|
static constexpr char* DatabasePath = "/opt/RecordControlApplication/database/data.db";
|
||||||
static constexpr char* VideoPath = "/root/usb/videos";
|
static constexpr char* VideoPath = "/root/usb/videos";
|
||||||
static constexpr char* MountedPath = "/root/usb";
|
static constexpr char* MountedPath = "/root/usb";
|
||||||
|
@ -66,12 +66,13 @@ void DatabaseManager::close()
|
|||||||
bool DatabaseManager::insert(File file)
|
bool DatabaseManager::insert(File file)
|
||||||
{
|
{
|
||||||
QSqlQuery query;
|
QSqlQuery query;
|
||||||
query.prepare("insert into file (channel, name, year, month, day) values (?, ?, ?, ?, ?)");
|
query.prepare("insert into file (channel, year, month, day, time, filename) values (?, ?, ?, ?, ?, ?)");
|
||||||
query.bindValue(0, file.channel);
|
query.bindValue(0, file.channel);
|
||||||
query.bindValue(1, file.time);
|
query.bindValue(1, file.year);
|
||||||
query.bindValue(2, file.year);
|
query.bindValue(2, file.month);
|
||||||
query.bindValue(3, file.month);
|
query.bindValue(3, file.day);
|
||||||
query.bindValue(4, file.day);
|
query.bindValue(4, file.time);
|
||||||
|
query.bindValue(5, file.filename);
|
||||||
if (query.exec()) {
|
if (query.exec()) {
|
||||||
return true;
|
return true;
|
||||||
} else {
|
} else {
|
||||||
@ -257,23 +258,55 @@ QStringList DatabaseManager::getAllDays(Channel chn, QString year, QString month
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief 根据通道和文件名删除记录
|
* @brief 根据通道和文件名删除记录,文件名格式yyyyMMddhhmmss
|
||||||
* @param id
|
* @param id
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
bool DatabaseManager::remove(DatabaseManager::Channel chn, QString name)
|
bool DatabaseManager::remove(DatabaseManager::Channel chn, QString name)
|
||||||
{
|
{
|
||||||
|
int id = -1;
|
||||||
|
// 找到对应记录
|
||||||
QSqlQuery query;
|
QSqlQuery query;
|
||||||
query.prepare("delet from file where channel = ? and name = ?");
|
query.prepare("select * from file where channel = ? and filename = ?");
|
||||||
query.bindValue(0, chn);
|
query.bindValue(0, chn);
|
||||||
query.bindValue(1, name);
|
query.bindValue(1, name);
|
||||||
if (query.exec()) {
|
if (query.exec()) {
|
||||||
|
while (query.next()) {
|
||||||
|
id = query.value(0).toInt();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
Log::info("cannot find the record, channel = {}, name = {}",
|
||||||
|
int(chn),
|
||||||
|
name.toStdString());
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
// 未找到
|
||||||
|
if (id == -1) {
|
||||||
|
Log::info("cannot find the record, channel = {}, name = {}",
|
||||||
|
int(chn),
|
||||||
|
name.toStdString());
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
Log::info("find the record, channel = {} , name = {}, and the id = {}",
|
||||||
|
int(chn),
|
||||||
|
name.toStdString(),
|
||||||
|
id);
|
||||||
|
query.clear();
|
||||||
|
// 删除文件
|
||||||
|
query.prepare("delete from file where id = ?");
|
||||||
|
query.bindValue(0, id);
|
||||||
|
if (query.exec()) {
|
||||||
|
Log::info("delete one record from database, id = {}, channel = {}, name = {}",
|
||||||
|
id,
|
||||||
|
int(chn),
|
||||||
|
name.toStdString());
|
||||||
return true;
|
return true;
|
||||||
} else {
|
} else {
|
||||||
Log::error("delete one record from database failed, channel = {}, name = {}, reason: {}",
|
Log::error("delete one record from database failed, channel = {}, name = {}, reason: {}",
|
||||||
(int)chn,
|
(int)chn,
|
||||||
name.toStdString(),
|
name.toStdString(),
|
||||||
query.lastError().databaseText().toStdString());
|
query.lastError().driverText().toStdString() + ", " + query.lastError().databaseText().toStdString());
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
137
Menu.cpp
137
Menu.cpp
@ -32,31 +32,28 @@ Menu::Menu(QWidget* parent)
|
|||||||
ui->cmbMonth->setView(new QListView());
|
ui->cmbMonth->setView(new QListView());
|
||||||
ui->cmbDay->setView(new QListView());
|
ui->cmbDay->setView(new QListView());
|
||||||
|
|
||||||
// 设置ScrollArea为栅格布局
|
// 默认设置当前操作选择主通道
|
||||||
QGridLayout* layout = new QGridLayout(ui->scrollArea);
|
curSelectChannel = DatabaseManager::MainChannel;
|
||||||
ui->scrollAreaWidgetContents->setLayout(layout);
|
curPlayChannel = DatabaseManager::MainChannel;
|
||||||
|
|
||||||
db = DatabaseManager::getInstace();
|
db = DatabaseManager::getInstace();
|
||||||
if (!db->open())
|
if (!db->open())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
// 设置ScrollArea为栅格布局
|
||||||
|
QGridLayout* layout = new QGridLayout(ui->scrollArea);
|
||||||
|
ui->scrollAreaWidgetContents->setLayout(layout);
|
||||||
connect(ui->cmbYear, &QComboBox::currentTextChanged, [=](QString text) {
|
connect(ui->cmbYear, &QComboBox::currentTextChanged, [=](QString text) {
|
||||||
renderComboBoxMonth();
|
renderComboBoxMonth();
|
||||||
});
|
});
|
||||||
connect(ui->cmbMonth, &QComboBox::currentTextChanged, [=](QString text) {
|
connect(ui->cmbMonth, &QComboBox::currentTextChanged, [=](QString text) {
|
||||||
renderComboBoxDay();
|
renderComboBoxDay();
|
||||||
});
|
});
|
||||||
// 默认设置当前操作选择主通道
|
|
||||||
currentChannel = DatabaseManager::MainChannel;
|
|
||||||
QTimer::singleShot(200, [=] {
|
|
||||||
emit curChannelChanged(Constant::MainChannel);
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Menu::~Menu()
|
Menu::~Menu()
|
||||||
{
|
{
|
||||||
delete ui;
|
delete ui;
|
||||||
delete db;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -64,9 +61,9 @@ Menu::~Menu()
|
|||||||
*/
|
*/
|
||||||
void Menu::show()
|
void Menu::show()
|
||||||
{
|
{
|
||||||
|
QWidget::show();
|
||||||
renderComboBoxYear();
|
renderComboBoxYear();
|
||||||
getContents();
|
getContents();
|
||||||
QWidget::show();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -75,6 +72,7 @@ void Menu::show()
|
|||||||
*/
|
*/
|
||||||
void Menu::setChannelSelectVisible(bool visible)
|
void Menu::setChannelSelectVisible(bool visible)
|
||||||
{
|
{
|
||||||
|
channelSelectVisible = visible;
|
||||||
ui->widget_chnSelect->setVisible(visible);
|
ui->widget_chnSelect->setVisible(visible);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -83,7 +81,7 @@ void Menu::setChannelSelectVisible(bool visible)
|
|||||||
*/
|
*/
|
||||||
void Menu::renderComboBoxYear()
|
void Menu::renderComboBoxYear()
|
||||||
{
|
{
|
||||||
QStringList years = db->getAllYears(currentChannel);
|
QStringList years = db->getAllYears(curSelectChannel);
|
||||||
|
|
||||||
ui->cmbYear->clear();
|
ui->cmbYear->clear();
|
||||||
for (auto& str : years) {
|
for (auto& str : years) {
|
||||||
@ -101,7 +99,7 @@ void Menu::renderComboBoxMonth()
|
|||||||
if (year.isEmpty()) {
|
if (year.isEmpty()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
QStringList months = db->getAllMonths(currentChannel, year);
|
QStringList months = db->getAllMonths(curSelectChannel, year);
|
||||||
ui->cmbMonth->clear();
|
ui->cmbMonth->clear();
|
||||||
for (auto& str : months) {
|
for (auto& str : months) {
|
||||||
ui->cmbMonth->addItem(str);
|
ui->cmbMonth->addItem(str);
|
||||||
@ -119,7 +117,7 @@ void Menu::renderComboBoxDay()
|
|||||||
if (year.isEmpty() || year.isEmpty()) {
|
if (year.isEmpty() || year.isEmpty()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
QStringList days = db->getAllDays(currentChannel, year, month);
|
QStringList days = db->getAllDays(curSelectChannel, year, month);
|
||||||
ui->cmbDay->clear();
|
ui->cmbDay->clear();
|
||||||
for (auto& str : days) {
|
for (auto& str : days) {
|
||||||
ui->cmbDay->addItem(str);
|
ui->cmbDay->addItem(str);
|
||||||
@ -133,7 +131,7 @@ void Menu::renderComboBoxDay()
|
|||||||
void Menu::getContents()
|
void Menu::getContents()
|
||||||
{
|
{
|
||||||
QVariantMap params;
|
QVariantMap params;
|
||||||
params["channel"] = currentChannel;
|
params["channel"] = curSelectChannel;
|
||||||
params["year"] = ui->cmbYear->currentText();
|
params["year"] = ui->cmbYear->currentText();
|
||||||
params["month"] = ui->cmbMonth->currentText();
|
params["month"] = ui->cmbMonth->currentText();
|
||||||
params["day"] = ui->cmbDay->currentText();
|
params["day"] = ui->cmbDay->currentText();
|
||||||
@ -155,15 +153,20 @@ void Menu::renderContents()
|
|||||||
}
|
}
|
||||||
// 重新生成若干个按钮
|
// 重新生成若干个按钮
|
||||||
for (int i = 0; i < contentList.length(); i++) {
|
for (int i = 0; i < contentList.length(); i++) {
|
||||||
// 文件名格式: yyyyMMddhhmmss.mp4,只将时分秒显示到界面上
|
// 文件名格式: hhmmss,只将时分秒显示到界面上
|
||||||
DatabaseManager::File file = contentList.at(i);
|
DatabaseManager::File file = contentList.at(i);
|
||||||
QPushButton* btn = new QPushButton(file.time, ui->scrollArea);
|
QString text = QString("%1:%2:%3").arg(file.time.mid(0, 2)).arg(file.time.mid(2, 2)).arg(file.time.mid(4, 2));
|
||||||
|
QPushButton* btn = new QPushButton(text, ui->scrollArea);
|
||||||
btn->setProperty("name", file.filename);
|
btn->setProperty("name", file.filename);
|
||||||
btn->setMinimumHeight(CONTENT_CELL_HEIGHT);
|
btn->setMinimumHeight(CONTENT_CELL_HEIGHT);
|
||||||
btn->setStyleSheet("QPushButton{border-radius: 5px;}");
|
btn->setStyleSheet("QPushButton{border-radius: 5px;}");
|
||||||
btn->setCheckable(true);
|
btn->setCheckable(true);
|
||||||
btn->setAutoExclusive(true);
|
btn->setAutoExclusive(true);
|
||||||
btn->setObjectName(QString("btn_video_%1").arg(i));
|
btn->setObjectName(QString("btn_video_%1").arg(i));
|
||||||
|
if (file.filename == curPlayFilename) {
|
||||||
|
btn->setChecked(true);
|
||||||
|
btn->setFocus();
|
||||||
|
}
|
||||||
int row = i / CONTENT_COLUMN;
|
int row = i / CONTENT_COLUMN;
|
||||||
int column = i % CONTENT_COLUMN;
|
int column = i % CONTENT_COLUMN;
|
||||||
layout->addWidget(btn, row, column);
|
layout->addWidget(btn, row, column);
|
||||||
@ -258,11 +261,9 @@ void Menu::confirm()
|
|||||||
QPushButton* btn = qobject_cast<QPushButton*>(focusWidget);
|
QPushButton* btn = qobject_cast<QPushButton*>(focusWidget);
|
||||||
btn->setChecked(true);
|
btn->setChecked(true);
|
||||||
if (btn == ui->btn_channel_1) {
|
if (btn == ui->btn_channel_1) {
|
||||||
currentChannel = DatabaseManager::MainChannel;
|
curSelectChannel = DatabaseManager::MainChannel;
|
||||||
emit curChannelChanged(Constant::MainChannel);
|
|
||||||
} else {
|
} else {
|
||||||
currentChannel = DatabaseManager::SecondaryChannel;
|
curSelectChannel = DatabaseManager::SecondaryChannel;
|
||||||
emit curChannelChanged(Constant::SecondaryChannel);
|
|
||||||
}
|
}
|
||||||
renderComboBoxYear();
|
renderComboBoxYear();
|
||||||
}
|
}
|
||||||
@ -289,7 +290,9 @@ void Menu::confirm()
|
|||||||
btn->setChecked(true);
|
btn->setChecked(true);
|
||||||
QString filename = btn->property("name").toString();
|
QString filename = btn->property("name").toString();
|
||||||
emit btnVideoClicked(filename);
|
emit btnVideoClicked(filename);
|
||||||
currentFilename = filename;
|
// 记录当前正在回放的通道和文件名
|
||||||
|
curPlayFilename = filename;
|
||||||
|
curPlayChannel = curSelectChannel;
|
||||||
}
|
}
|
||||||
// 确认按钮按下确认
|
// 确认按钮按下确认
|
||||||
else if (focusWidget->objectName() == "btn_done") {
|
else if (focusWidget->objectName() == "btn_done") {
|
||||||
@ -305,45 +308,68 @@ void Menu::confirm()
|
|||||||
/**
|
/**
|
||||||
* @brief 点击查找当前列表中的上一个视频和下一个视频
|
* @brief 点击查找当前列表中的上一个视频和下一个视频
|
||||||
*/
|
*/
|
||||||
void Menu::clickVideo(QString type)
|
void Menu::clickPreOrNext(QString type)
|
||||||
{
|
{
|
||||||
getContents();
|
// 重新获取当前正在回放通道的视频
|
||||||
|
QVariantMap params;
|
||||||
|
params["channel"] = curPlayChannel;
|
||||||
|
params["year"] = ui->cmbYear->currentText();
|
||||||
|
params["month"] = ui->cmbMonth->currentText();
|
||||||
|
params["day"] = ui->cmbDay->currentText();
|
||||||
|
QList<DatabaseManager::File> list = db->get(params);
|
||||||
|
// 搜索当前播放视频的位置
|
||||||
int index = -1;
|
int index = -1;
|
||||||
for (int i = 0; i < contentList.length(); i++) {
|
for (int i = 0; i < list.length(); i++) {
|
||||||
DatabaseManager::File file = contentList[i];
|
DatabaseManager::File file = list[i];
|
||||||
if (file.filename == currentFilename) {
|
if (file.filename == curPlayFilename) {
|
||||||
index = i;
|
index = i;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Log::info("find file filename: {}, index: {}", curPlayFilename.toStdString(), index);
|
||||||
|
// 查找目标文件名
|
||||||
QString filename;
|
QString filename;
|
||||||
// 上一个视频
|
|
||||||
if (type == "previous") {
|
if (type == "previous") {
|
||||||
|
// 已经是第一个视频了
|
||||||
if (index == 0) {
|
if (index == 0) {
|
||||||
emit btnVideoClicked("first");
|
emit btnVideoClicked("first");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
filename = contentList[index - 1].filename;
|
index -= 1;
|
||||||
}
|
} else {
|
||||||
// 下一个视频
|
// 已经是最后一个视频
|
||||||
else {
|
if (index == list.length() - 1) {
|
||||||
if (index == contentList.length() - 1) {
|
|
||||||
emit btnVideoClicked("last");
|
emit btnVideoClicked("last");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
filename = contentList[index + 1].filename;
|
index += 1;
|
||||||
}
|
}
|
||||||
filename = contentList[index + 1].filename;
|
filename = list[index].filename;
|
||||||
|
Log::info("type: {}, index: {}, filename",
|
||||||
|
type.toStdString(),
|
||||||
|
index,
|
||||||
|
filename.toStdString());
|
||||||
emit btnVideoClicked(filename);
|
emit btnVideoClicked(filename);
|
||||||
QString h = filename.mid(8, 2);
|
curPlayFilename = filename;
|
||||||
QString m = filename.mid(10, 2);
|
// 单通道回放
|
||||||
QString s = filename.mid(12, 2);
|
if (channelSelectVisible) {
|
||||||
QString str = QString("%1:%2:%3").arg(h).arg(m).arg(s);
|
// 选中通道和回放通道不是同一个时不处理
|
||||||
|
if (curPlayChannel != curSelectChannel) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// 双通道同时回放
|
||||||
|
else {
|
||||||
|
if (curPlayChannel != DatabaseManager::MainChannel) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
// 选中要播放的按钮
|
// 选中要播放的按钮
|
||||||
QList<QPushButton*> btns = ui->scrollArea->findChildren<QPushButton*>();
|
QList<QPushButton*> btns = ui->scrollArea->findChildren<QPushButton*>();
|
||||||
for (QPushButton* btn : btns) {
|
for (QPushButton* btn : btns) {
|
||||||
if (btn->text() == str) {
|
if (btn->property("name").toString() == filename) {
|
||||||
btn->setChecked(true);
|
btn->setChecked(true);
|
||||||
|
btn->setFocus();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -365,3 +391,36 @@ QList<QWidget*> Menu::getAllFocusabelWidget()
|
|||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 录制完毕一个视频
|
||||||
|
* @param channelName
|
||||||
|
*/
|
||||||
|
void Menu::onAppendOneVideo(QString channelName)
|
||||||
|
{
|
||||||
|
// 单通道
|
||||||
|
if (channelSelectVisible) {
|
||||||
|
// 只有生成新视频的通道和当前选择的通道一致时重新获取文件列表
|
||||||
|
if ((channelName == Constant::MainChannel
|
||||||
|
&& curSelectChannel == DatabaseManager::MainChannel)
|
||||||
|
|| (channelName == Constant::SecondaryChannel
|
||||||
|
&& curSelectChannel == DatabaseManager::SecondaryChannel)) {
|
||||||
|
renderContents();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// 双通道
|
||||||
|
else {
|
||||||
|
if (channelName == Constant::MainChannel) {
|
||||||
|
renderContents();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 获取当前正在回放的通道
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
DatabaseManager::Channel Menu::getCurPlayChannel()
|
||||||
|
{
|
||||||
|
return curSelectChannel;
|
||||||
|
}
|
12
Menu.h
12
Menu.h
@ -18,11 +18,13 @@ public:
|
|||||||
~Menu();
|
~Menu();
|
||||||
void show();
|
void show();
|
||||||
void setChannelSelectVisible(bool visible);
|
void setChannelSelectVisible(bool visible);
|
||||||
|
DatabaseManager::Channel getCurPlayChannel();
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
void move(Direction direction);
|
void move(Direction direction);
|
||||||
void confirm();
|
void confirm();
|
||||||
void clickVideo(QString type);
|
void clickPreOrNext(QString type);
|
||||||
|
void onAppendOneVideo(QString channelName);
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void btnHdmi1Checked();
|
void btnHdmi1Checked();
|
||||||
@ -30,7 +32,6 @@ signals:
|
|||||||
void btnVga1Checked();
|
void btnVga1Checked();
|
||||||
void btnVga2Checked();
|
void btnVga2Checked();
|
||||||
void btnVideoClicked(QString name);
|
void btnVideoClicked(QString name);
|
||||||
void curChannelChanged(QString channel);
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
// 重写父类的方法,以获取当前界面的所有可以获取焦点的控件
|
// 重写父类的方法,以获取当前界面的所有可以获取焦点的控件
|
||||||
@ -41,8 +42,11 @@ private:
|
|||||||
// 视频名数组列表
|
// 视频名数组列表
|
||||||
QList<DatabaseManager::File> contentList;
|
QList<DatabaseManager::File> contentList;
|
||||||
DatabaseManager* db;
|
DatabaseManager* db;
|
||||||
DatabaseManager::Channel currentChannel;
|
QString curPlayFilename; // 当前正在回放的文件名
|
||||||
QString currentFilename;
|
bool channelSelectVisible = false; // 是否显示通道选择,单通道回放显示、双通道不显示
|
||||||
|
|
||||||
|
DatabaseManager::Channel curSelectChannel; // 当前选择的通道
|
||||||
|
DatabaseManager::Channel curPlayChannel; // 当前回放的通道
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void getContents();
|
void getContents();
|
||||||
|
123
Message.cpp
123
Message.cpp
@ -1,123 +0,0 @@
|
|||||||
#include "Message.h"
|
|
||||||
#include <QSpacerItem>
|
|
||||||
#include <QTimer>
|
|
||||||
#include <QVBoxLayout>
|
|
||||||
|
|
||||||
Message::Message(QWidget* parent)
|
|
||||||
: QWidget(parent)
|
|
||||||
{
|
|
||||||
btnStyle = "QPushButton { \
|
|
||||||
background: rgba(0,0,0,0.4); \
|
|
||||||
color: rgba(255,255,255); \
|
|
||||||
border: none; \
|
|
||||||
border-radius: 10px; \
|
|
||||||
min-height: 40px; \
|
|
||||||
}";
|
|
||||||
|
|
||||||
QVBoxLayout* layout = new QVBoxLayout();
|
|
||||||
layout->setContentsMargins(QMargins(10, 10, 10, 10));
|
|
||||||
layout->setSpacing(10);
|
|
||||||
this->setLayout(layout);
|
|
||||||
this->setFixedHeight(260);
|
|
||||||
QFont font;
|
|
||||||
// font.setFamily("Ubuntu Regular");
|
|
||||||
font.setPixelSize(16);
|
|
||||||
this->setFont(font);
|
|
||||||
|
|
||||||
QSpacerItem* verticalSpacer = new QSpacerItem(20, 40, QSizePolicy::Minimum, QSizePolicy::Expanding);
|
|
||||||
layout->addSpacerItem(verticalSpacer);
|
|
||||||
}
|
|
||||||
|
|
||||||
Message::~Message()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
void Message::success(QString content, int duration)
|
|
||||||
{
|
|
||||||
showMessage(content, duration, Success);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Message::info(QString content, int duration)
|
|
||||||
{
|
|
||||||
showMessage(content, duration, Info);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Message::error(QString content, int duration)
|
|
||||||
{
|
|
||||||
showMessage(content, duration, Error);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Message::warning(QString content, int duration)
|
|
||||||
{
|
|
||||||
showMessage(content, duration, Warning);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Message::showMessage(QString content, int duration, Level level)
|
|
||||||
{
|
|
||||||
QVBoxLayout* layout = static_cast<QVBoxLayout*>(this->layout());
|
|
||||||
if (count >= maxCount) {
|
|
||||||
// remove first
|
|
||||||
QPair<QPushButton*, QTimer*> pair = contentList.first();
|
|
||||||
contentList.removeFirst();
|
|
||||||
layout->removeWidget(pair.first);
|
|
||||||
delete pair.first;
|
|
||||||
delete pair.second;
|
|
||||||
count -= 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
// apeend new
|
|
||||||
QPushButton* btn = generateButton(content, level);
|
|
||||||
layout->insertWidget(count, btn);
|
|
||||||
|
|
||||||
QTimer* timer = new QTimer();
|
|
||||||
timer->setInterval(duration);
|
|
||||||
timer->start();
|
|
||||||
QPair<QPushButton*, QTimer*> pair(btn, timer);
|
|
||||||
contentList.append(pair);
|
|
||||||
count += 1;
|
|
||||||
|
|
||||||
connect(timer, &QTimer::timeout, [=] {
|
|
||||||
for (int i = 0; i < contentList.length(); i++) {
|
|
||||||
QPair<QPushButton*, QTimer*> pair = contentList.at(i);
|
|
||||||
if (pair.first == btn) {
|
|
||||||
contentList.removeAt(i);
|
|
||||||
}
|
|
||||||
layout->removeWidget(pair.first);
|
|
||||||
delete pair.first;
|
|
||||||
delete pair.second;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
QPushButton* Message::generateButton(QString content, Level level)
|
|
||||||
{
|
|
||||||
QPushButton* btn = new QPushButton(this);
|
|
||||||
btn->setText(content);
|
|
||||||
QString iconPath;
|
|
||||||
switch (level) {
|
|
||||||
case Info:
|
|
||||||
iconPath = ":/icons/info.png";
|
|
||||||
break;
|
|
||||||
case Success:
|
|
||||||
iconPath = ":/icons/success.png";
|
|
||||||
break;
|
|
||||||
case Error:
|
|
||||||
iconPath = ":/icons/error.png";
|
|
||||||
case Warning:
|
|
||||||
iconPath = ":/icons/waring.png";
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
iconPath = ":/icons/info.png";
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
btn->setIcon(QIcon(iconPath));
|
|
||||||
btn->setIconSize(QSize(16, 16));
|
|
||||||
btn->setStyleSheet(btnStyle);
|
|
||||||
|
|
||||||
QFont font = btn->font();
|
|
||||||
QFontMetrics metrics(font);
|
|
||||||
int width = metrics.boundingRect(content).size().width();
|
|
||||||
btn->setFixedWidth(width);
|
|
||||||
|
|
||||||
return btn;
|
|
||||||
}
|
|
43
Message.h
43
Message.h
@ -1,43 +0,0 @@
|
|||||||
#ifndef MESSAGE_H
|
|
||||||
#define MESSAGE_H
|
|
||||||
|
|
||||||
#include <QLabel>
|
|
||||||
#include <QPair>
|
|
||||||
#include <QPushButton>
|
|
||||||
#include <QTimer>
|
|
||||||
#include <QWidget>
|
|
||||||
|
|
||||||
class Message : public QWidget {
|
|
||||||
Q_OBJECT
|
|
||||||
|
|
||||||
public:
|
|
||||||
enum Level {
|
|
||||||
Success,
|
|
||||||
Error,
|
|
||||||
Info,
|
|
||||||
Warning
|
|
||||||
};
|
|
||||||
explicit Message(QWidget* parent = 0);
|
|
||||||
~Message();
|
|
||||||
|
|
||||||
void success(QString content, int duration);
|
|
||||||
void error(QString content, int duration);
|
|
||||||
void info(QString content, int duration);
|
|
||||||
void warning(QString content, int duration);
|
|
||||||
|
|
||||||
private:
|
|
||||||
Level level = Info;
|
|
||||||
bool isShow = false;
|
|
||||||
|
|
||||||
int count = 0;
|
|
||||||
int maxCount = 5;
|
|
||||||
QList<QPair<QPushButton*, QTimer*>> contentList;
|
|
||||||
|
|
||||||
QString btnStyle;
|
|
||||||
|
|
||||||
private:
|
|
||||||
void showMessage(QString content, int duration, Level level);
|
|
||||||
QPushButton* generateButton(QString content, Level level);
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif // MESSAGE_H
|
|
@ -44,7 +44,6 @@ private:
|
|||||||
inline QString ProgressBar::msecToString(int msc)
|
inline QString ProgressBar::msecToString(int msc)
|
||||||
{
|
{
|
||||||
QString formatStr = QTime(0, 0, 0).addMSecs(msc).toString(QString::fromUtf8("hh:mm:ss"));
|
QString formatStr = QTime(0, 0, 0).addMSecs(msc).toString(QString::fromUtf8("hh:mm:ss"));
|
||||||
qDebug() << msc;
|
|
||||||
return formatStr;
|
return formatStr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -35,7 +35,6 @@ SOURCES += \
|
|||||||
Channel.cpp \
|
Channel.cpp \
|
||||||
Menu.cpp\
|
Menu.cpp\
|
||||||
ProgressBar.cpp \
|
ProgressBar.cpp \
|
||||||
Message.cpp \
|
|
||||||
Tool.cpp \
|
Tool.cpp \
|
||||||
CheckStorageThread.cpp \
|
CheckStorageThread.cpp \
|
||||||
Constant.h \
|
Constant.h \
|
||||||
@ -54,7 +53,6 @@ HEADERS += \
|
|||||||
Channel.h \
|
Channel.h \
|
||||||
Menu.h \
|
Menu.h \
|
||||||
ProgressBar.h \
|
ProgressBar.h \
|
||||||
Message.h \
|
|
||||||
Tool.h \
|
Tool.h \
|
||||||
CheckStorageThread.h \
|
CheckStorageThread.h \
|
||||||
Log.h \
|
Log.h \
|
||||||
|
@ -182,6 +182,12 @@ void SerialPortTool::onReayRead()
|
|||||||
// 返回
|
// 返回
|
||||||
emit btnReturnClicked();
|
emit btnReturnClicked();
|
||||||
break;
|
break;
|
||||||
|
case 8:
|
||||||
|
emit btnVolumnUpClicked();
|
||||||
|
break;
|
||||||
|
case 9:
|
||||||
|
emit btnVolumnDownClicked();
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -240,11 +246,13 @@ void SerialPortTool::onDiskNotFull()
|
|||||||
serialPort->write(cmdMap.value(DiskNotFull));
|
serialPort->write(cmdMap.value(DiskNotFull));
|
||||||
serialPort->flush();
|
serialPort->flush();
|
||||||
}
|
}
|
||||||
|
|
||||||
void SerialPortTool::onPowerOn()
|
void SerialPortTool::onPowerOn()
|
||||||
{
|
{
|
||||||
serialPort->write(cmdMap.value(PowerOn));
|
serialPort->write(cmdMap.value(PowerOn));
|
||||||
serialPort->flush();
|
serialPort->flush();
|
||||||
}
|
}
|
||||||
|
|
||||||
void SerialPortTool::onPowerOff()
|
void SerialPortTool::onPowerOff()
|
||||||
{
|
{
|
||||||
serialPort->write(cmdMap.value(PowerOff));
|
serialPort->write(cmdMap.value(PowerOff));
|
||||||
|
@ -51,6 +51,8 @@ signals:
|
|||||||
void btnRightClicked();
|
void btnRightClicked();
|
||||||
void btnConfirmClicked();
|
void btnConfirmClicked();
|
||||||
void btnReturnClicked();
|
void btnReturnClicked();
|
||||||
|
void btnVolumnUpClicked();
|
||||||
|
void btnVolumnDownClicked();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
enum CommandType {
|
enum CommandType {
|
||||||
|
@ -23,6 +23,7 @@ void TcpConnectionHandler::onReadyRead()
|
|||||||
{
|
{
|
||||||
bool ret = request->readFromSocket(socket);
|
bool ret = request->readFromSocket(socket);
|
||||||
if (!ret) {
|
if (!ret) {
|
||||||
|
response->setUrl("Unkown Url");
|
||||||
response->error(request->getErrorString());
|
response->error(request->getErrorString());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -5,6 +5,7 @@
|
|||||||
#include "Json.h"
|
#include "Json.h"
|
||||||
#include "Log.h"
|
#include "Log.h"
|
||||||
#include "Tool.h"
|
#include "Tool.h"
|
||||||
|
#include <QCoreApplication>
|
||||||
#include <QDir>
|
#include <QDir>
|
||||||
#include <QProcess>
|
#include <QProcess>
|
||||||
|
|
||||||
@ -183,7 +184,7 @@ void TcpRequestHandler::getFileList(TcpRequest* request, TcpResponse* reponse)
|
|||||||
{
|
{
|
||||||
QVariantMap params = request->getBodyParams();
|
QVariantMap params = request->getBodyParams();
|
||||||
QString chn = params.value("interface").toString();
|
QString chn = params.value("interface").toString();
|
||||||
if (chn != Constant::MainChannel || chn != Constant::SecondaryChannel) {
|
if (chn != Constant::MainChannel && chn != Constant::SecondaryChannel) {
|
||||||
Log::error("getFileList params error, error param \"interface\"");
|
Log::error("getFileList params error, error param \"interface\"");
|
||||||
reponse->error("接口参数错误");
|
reponse->error("接口参数错误");
|
||||||
return;
|
return;
|
||||||
@ -192,11 +193,15 @@ void TcpRequestHandler::getFileList(TcpRequest* request, TcpResponse* reponse)
|
|||||||
: DatabaseManager::SecondaryChannel;
|
: DatabaseManager::SecondaryChannel;
|
||||||
QString interface = params.value("interface").toString();
|
QString interface = params.value("interface").toString();
|
||||||
QList<DatabaseManager::File> fileList = db->get(channel);
|
QList<DatabaseManager::File> fileList = db->get(channel);
|
||||||
QStringList result;
|
QVariantList result;
|
||||||
for (const DatabaseManager::File& file : fileList) {
|
for (const DatabaseManager::File& file : fileList) {
|
||||||
result.push_back(file.filename);
|
QString time = file.year + file.month + file.day + file.time;
|
||||||
|
QVariantMap fileInfo;
|
||||||
|
fileInfo["time"] = time;
|
||||||
|
fileInfo["filename"] = file.filename;
|
||||||
|
result.push_back(fileInfo);
|
||||||
}
|
}
|
||||||
reponse->success("获取文件成功", result);
|
reponse->success("获取文件成功", QVariant::fromValue(result));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -208,7 +213,7 @@ void TcpRequestHandler::deleteFile(TcpRequest* request, TcpResponse* reponse)
|
|||||||
QVariantMap params = request->getBodyParams();
|
QVariantMap params = request->getBodyParams();
|
||||||
QString chn = params.value("interface").toString();
|
QString chn = params.value("interface").toString();
|
||||||
QString filename = params.value("filename").toString();
|
QString filename = params.value("filename").toString();
|
||||||
if (chn != Constant::MainChannel || chn != Constant::SecondaryChannel) {
|
if (chn != Constant::MainChannel && chn != Constant::SecondaryChannel) {
|
||||||
Log::error("deleteFile params error, error params \"interface\" or \"filename\"");
|
Log::error("deleteFile params error, error params \"interface\" or \"filename\"");
|
||||||
reponse->error("通道参数错误");
|
reponse->error("通道参数错误");
|
||||||
return;
|
return;
|
||||||
@ -218,18 +223,24 @@ void TcpRequestHandler::deleteFile(TcpRequest* request, TcpResponse* reponse)
|
|||||||
reponse->error("缺少文件名参数");
|
reponse->error("缺少文件名参数");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// 从数据库删除指定记录
|
// 先查找是否存在物理文件,再查找数据库中是否有对应记,然后一一删除
|
||||||
DatabaseManager::Channel channel = chn == Constant::MainChannel
|
// 删除对应的视频文件
|
||||||
? DatabaseManager::MainChannel
|
|
||||||
: DatabaseManager::SecondaryChannel;
|
|
||||||
db->remove(channel, filename);
|
|
||||||
// 删除相对于的视频文件
|
|
||||||
QString filePath = QString("%1/%2/%3").arg(Constant::VideoPath).arg(chn).arg(filename);
|
QString filePath = QString("%1/%2/%3").arg(Constant::VideoPath).arg(chn).arg(filename);
|
||||||
QFile video(filePath);
|
QFile video(filePath);
|
||||||
if (video.exists()) {
|
if (video.exists()) {
|
||||||
video.remove();
|
// 删除数据库记录
|
||||||
Log::info("remove video {}", filePath.toStdString());
|
DatabaseManager::Channel channel = chn == Constant::MainChannel
|
||||||
reponse->success("删除成功");
|
? DatabaseManager::MainChannel
|
||||||
|
: DatabaseManager::SecondaryChannel;
|
||||||
|
bool ret = db->remove(channel, filename);
|
||||||
|
if (!ret) {
|
||||||
|
reponse->error("文件不存在");
|
||||||
|
return;
|
||||||
|
} else {
|
||||||
|
video.remove();
|
||||||
|
Log::info("remove video {}", filePath.toStdString());
|
||||||
|
reponse->success("删除成功");
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
Log::error("error, file: {} dont exist", filePath.toStdString());
|
Log::error("error, file: {} dont exist", filePath.toStdString());
|
||||||
reponse->error("文件不存在");
|
reponse->error("文件不存在");
|
||||||
@ -315,9 +326,7 @@ void TcpRequestHandler::reboot(TcpRequest* request, TcpResponse* reponse)
|
|||||||
chn->stopRecord();
|
chn->stopRecord();
|
||||||
}
|
}
|
||||||
reponse->success("重启成功");
|
reponse->success("重启成功");
|
||||||
|
qApp->quit();
|
||||||
// 退出程序,等待后台运行的shell脚本重启程序
|
|
||||||
exit(0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -334,7 +343,7 @@ void TcpRequestHandler::setCurrentTime(TcpRequest* request, TcpResponse* reponse
|
|||||||
}
|
}
|
||||||
|
|
||||||
QString time = params.value("time").toString();
|
QString time = params.value("time").toString();
|
||||||
QString cmd = QString("/link/bin/rtc -s time %1").arg(time);
|
QString cmd = QString("%1 -s time \"%2\"").arg(Constant::TimeSciptPath).arg(time);
|
||||||
QString result = Tool::writeCom(cmd);
|
QString result = Tool::writeCom(cmd);
|
||||||
// 修改成功会返回类似信息, "Tue Mar 5 15:51:18 CST 2024"
|
// 修改成功会返回类似信息, "Tue Mar 5 15:51:18 CST 2024"
|
||||||
if (result.isEmpty()) {
|
if (result.isEmpty()) {
|
||||||
|
3
Tool.cpp
3
Tool.cpp
@ -1,4 +1,5 @@
|
|||||||
#include "Tool.h"
|
#include "Tool.h"
|
||||||
|
#include "QTimer"
|
||||||
#include <QDebug>
|
#include <QDebug>
|
||||||
#include <QDir>
|
#include <QDir>
|
||||||
#include <QElapsedTimer>
|
#include <QElapsedTimer>
|
||||||
@ -136,4 +137,4 @@ double Tool::getCostTime(std::function<void(void)> callback, const char* callbac
|
|||||||
double time = (double)mstimer.nsecsElapsed() / (double)1000000;
|
double time = (double)mstimer.nsecsElapsed() / (double)1000000;
|
||||||
qDebug() << callbackName << "cast time:" << time << "ms";
|
qDebug() << callbackName << "cast time:" << time << "ms";
|
||||||
return time;
|
return time;
|
||||||
}
|
}
|
49
Widget.cpp
49
Widget.cpp
@ -46,6 +46,7 @@ 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, SIGNAL(appendOneVideo(QString)), menu, SLOT(onAppendOneVideo(QString)));
|
||||||
// 监听输入信号的变化
|
// 监听输入信号的变化
|
||||||
connect(chn->videoInput, &LinkObject::newEvent, [=](QString type, QVariant msg) {
|
connect(chn->videoInput, &LinkObject::newEvent, [=](QString type, QVariant msg) {
|
||||||
if (type == "signal") {
|
if (type == "signal") {
|
||||||
@ -81,10 +82,11 @@ Widget::Widget(QWidget* parent)
|
|||||||
connect(serialPortTool, SIGNAL(btnRightClicked()), this, SLOT(onBtnRightClicked()));
|
connect(serialPortTool, SIGNAL(btnRightClicked()), this, SLOT(onBtnRightClicked()));
|
||||||
connect(serialPortTool, SIGNAL(btnConfirmClicked()), this, SLOT(onBtnConfirmClicked()));
|
connect(serialPortTool, SIGNAL(btnConfirmClicked()), this, SLOT(onBtnConfirmClicked()));
|
||||||
connect(serialPortTool, SIGNAL(btnReturnClicked()), this, SLOT(onBtnReturnClicked()));
|
connect(serialPortTool, SIGNAL(btnReturnClicked()), this, SLOT(onBtnReturnClicked()));
|
||||||
|
connect(serialPortTool, SIGNAL(btnVolumnUpClicked()), this, SLOT(onBtnVolumnUpClicked()));
|
||||||
|
connect(serialPortTool, SIGNAL(btnVolumnDownClicked()), this, SLOT(onBtnVolumnDownClicked()));
|
||||||
|
|
||||||
connect(menu, SIGNAL(curChannelChanged(QString)), this, SLOT(onCurChannelChanged(QString)));
|
|
||||||
connect(menu, SIGNAL(btnVideoClicked(QString)), this, SLOT(onBtnVideoClicked(QString)));
|
connect(menu, SIGNAL(btnVideoClicked(QString)), this, SLOT(onBtnVideoClicked(QString)));
|
||||||
connect(this, SIGNAL(needPlayVideo(QString)), menu, SLOT(clickVideo(QString)));
|
connect(this, SIGNAL(needPlayVideo(QString)), menu, SLOT(clickPreOrNext(QString)));
|
||||||
}
|
}
|
||||||
|
|
||||||
Widget::~Widget()
|
Widget::~Widget()
|
||||||
@ -134,7 +136,6 @@ void Widget::onBtnReturnClicked()
|
|||||||
if (chn->state != Channel::Stop) {
|
if (chn->state != Channel::Stop) {
|
||||||
chn->startPlayLive();
|
chn->startPlayLive();
|
||||||
serialPortTool->onPlaybackEnd();
|
serialPortTool->onPlaybackEnd();
|
||||||
curPlayFilename = "";
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// 隐藏进度条并关闭定时器
|
// 隐藏进度条并关闭定时器
|
||||||
@ -232,12 +233,29 @@ void Widget::onBtnConfirmClicked()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 增大音量
|
||||||
|
*/
|
||||||
|
void Widget::onBtnVolumnUpClicked()
|
||||||
|
{
|
||||||
|
Channel::volumeUp();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 减小音量
|
||||||
|
*/
|
||||||
|
void Widget::onBtnVolumnDownClicked()
|
||||||
|
{
|
||||||
|
Channel::volumeDown();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief 回放视频
|
* @brief 回放视频
|
||||||
*/
|
*/
|
||||||
void Widget::onBtnVideoClicked(QString filename)
|
void Widget::onBtnVideoClicked(QString filename)
|
||||||
{
|
{
|
||||||
if (filename == "first") {
|
if (filename == "first") {
|
||||||
|
qDebug() << "click previous failed, already the first video";
|
||||||
// 显示提示弹窗
|
// 显示提示弹窗
|
||||||
} else if (filename == "last") {
|
} else if (filename == "last") {
|
||||||
if (playbackMode == Constant::OneChannelPlayback) {
|
if (playbackMode == Constant::OneChannelPlayback) {
|
||||||
@ -257,18 +275,16 @@ void Widget::onBtnVideoClicked(QString filename)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Widget::onCurChannelChanged(QString channel)
|
|
||||||
{
|
|
||||||
curSelectChannel = channel;
|
|
||||||
Log::info("channel switch, current channel:", channel.toStdString());
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief 一路回放,将当前选中播放的视频从HDMI-OUT0口输出
|
* @brief 一路回放,将当前选中播放的视频从HDMI-OUT0口输出
|
||||||
*/
|
*/
|
||||||
void Widget::playOneChannel(QString filename)
|
void Widget::playOneChannel(QString filename)
|
||||||
{
|
{
|
||||||
QString path = QString("%1/%2/%3").arg(Constant::VideoPath).arg(curSelectChannel).arg(filename);
|
// 获取当前回放的通道
|
||||||
|
QString curPlayChannel = menu->getCurPlayChannel() == DatabaseManager::MainChannel
|
||||||
|
? Constant::MainChannel
|
||||||
|
: Constant::SecondaryChannel;
|
||||||
|
QString path = QString("%1/%2/%3").arg(Constant::VideoPath).arg(curPlayChannel).arg(filename);
|
||||||
Channel* channel = findChannelByName(Constant::MainChannel);
|
Channel* channel = findChannelByName(Constant::MainChannel);
|
||||||
for (Channel* chn : channelList) {
|
for (Channel* chn : channelList) {
|
||||||
chn->startPlayLive();
|
chn->startPlayLive();
|
||||||
@ -280,10 +296,7 @@ void Widget::playOneChannel(QString filename)
|
|||||||
}
|
}
|
||||||
|
|
||||||
isPlayback = true;
|
isPlayback = true;
|
||||||
curPlayChannel = curSelectChannel;
|
// 全局保存当前播放的视频的文件名
|
||||||
curPlayFilename = filename;
|
|
||||||
|
|
||||||
// 全局保存当前播放的视频
|
|
||||||
mutex.lock();
|
mutex.lock();
|
||||||
curFilename = filename;
|
curFilename = filename;
|
||||||
condition.wakeAll();
|
condition.wakeAll();
|
||||||
@ -334,12 +347,8 @@ void Widget::playTwoChannels(QString filename)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
curPlayFilename = filename;
|
|
||||||
curPlayChannel = Constant::MainChannel;
|
|
||||||
isPlayback = true;
|
isPlayback = true;
|
||||||
|
// 全局保存正在播放的视频的文件名
|
||||||
// 全局保存正在播放的视频
|
|
||||||
mutex.lock();
|
mutex.lock();
|
||||||
curFilename = filename;
|
curFilename = filename;
|
||||||
condition.wakeAll();
|
condition.wakeAll();
|
||||||
@ -374,6 +383,8 @@ void Widget::seek(QString type)
|
|||||||
*/
|
*/
|
||||||
void Widget::onPlayEnd()
|
void Widget::onPlayEnd()
|
||||||
{
|
{
|
||||||
|
// 停下回放计时器
|
||||||
|
progressTimer->stop();
|
||||||
// 当两路回放时,只处理一次槽函数
|
// 当两路回放时,只处理一次槽函数
|
||||||
if (playbackMode == Constant::TwoChannelPlayback) {
|
if (playbackMode == Constant::TwoChannelPlayback) {
|
||||||
LinkObject* file = static_cast<LinkObject*>(sender());
|
LinkObject* file = static_cast<LinkObject*>(sender());
|
||||||
|
8
Widget.h
8
Widget.h
@ -3,7 +3,6 @@
|
|||||||
|
|
||||||
#include "Channel.h"
|
#include "Channel.h"
|
||||||
#include "Menu.h"
|
#include "Menu.h"
|
||||||
#include "Message.h"
|
|
||||||
#include "ProgressBar.h"
|
#include "ProgressBar.h"
|
||||||
#include <QDir>
|
#include <QDir>
|
||||||
#include <QMap>
|
#include <QMap>
|
||||||
@ -36,20 +35,17 @@ private slots:
|
|||||||
void onBtnRightClicked();
|
void onBtnRightClicked();
|
||||||
void onBtnConfirmClicked();
|
void onBtnConfirmClicked();
|
||||||
void onBtnReturnClicked();
|
void onBtnReturnClicked();
|
||||||
|
void onBtnVolumnUpClicked();
|
||||||
|
void onBtnVolumnDownClicked();
|
||||||
|
|
||||||
// 播放视频
|
// 播放视频
|
||||||
void onBtnVideoClicked(QString filename);
|
void onBtnVideoClicked(QString filename);
|
||||||
void onCurChannelChanged(QString channel);
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Ui::Widget* ui;
|
Ui::Widget* ui;
|
||||||
|
|
||||||
QTimer* progressTimer;
|
QTimer* progressTimer;
|
||||||
bool isPlayback = false;
|
bool isPlayback = false;
|
||||||
QString curPlayChannel;
|
|
||||||
QString curSelectChannel;
|
|
||||||
QString curPlayFilename;
|
|
||||||
|
|
||||||
Menu* menu;
|
Menu* menu;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
22
main.cpp
22
main.cpp
@ -15,7 +15,7 @@
|
|||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
|
||||||
// Tcp服务器
|
// Tcp服务器
|
||||||
TcpServer* server;
|
TcpServer* server;
|
||||||
// 串口工具
|
// 串口工具
|
||||||
SerialPortTool* serialPortTool;
|
SerialPortTool* serialPortTool;
|
||||||
// 数据库管理
|
// 数据库管理
|
||||||
@ -23,6 +23,8 @@ DatabaseManager* db;
|
|||||||
// 视频输出通道
|
// 视频输出通道
|
||||||
LinkObject* vo;
|
LinkObject* vo;
|
||||||
LinkObject* vo1;
|
LinkObject* vo1;
|
||||||
|
// 硬盘检测现场
|
||||||
|
CheckStorageThread* thread;
|
||||||
|
|
||||||
// 通道列表
|
// 通道列表
|
||||||
QList<Channel*> channelList;
|
QList<Channel*> channelList;
|
||||||
@ -86,7 +88,7 @@ void startRecord()
|
|||||||
QThread::msleep(100);
|
QThread::msleep(100);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 一路录制,只录制主通道
|
// 一路录制,只录制主通道
|
||||||
if (recordMode == Constant::OneChannelRecord) {
|
if (recordMode == Constant::OneChannelRecord) {
|
||||||
for (Channel* chn : channelList) {
|
for (Channel* chn : channelList) {
|
||||||
@ -135,6 +137,20 @@ void setChannelProtocol()
|
|||||||
|
|
||||||
int main(int argc, char* argv[])
|
int main(int argc, char* argv[])
|
||||||
{
|
{
|
||||||
|
qDebug() << (R"(
|
||||||
|
____ _ _____
|
||||||
|
/ ___|| |__ __ _ _ __ | ___|__ _ __ __ _
|
||||||
|
\___ \| '_ \ / _` | '_ \| |_ / _ \ '_ \ / _` |
|
||||||
|
___) | | | | (_| | | | | _| __/ | | | (_| |
|
||||||
|
|____/|_| |_|\__,_|_| |_|_| \___|_| |_|\__, |
|
||||||
|
|___/ )");
|
||||||
|
qDebug() << (R"(
|
||||||
|
____ _ _ _ __ __ _
|
||||||
|
/ ___|| |_ __ _ _ __| |_ ___ __| | \ \ / /__| | ___ ___ _ __ ___ ___
|
||||||
|
\___ \| __/ _` | '__| __/ _ \/ _` | \ \ /\ / / _ \ |/ __/ _ \| '_ ` _ \ / _ \
|
||||||
|
___) | || (_| | | | || __/ (_| | \ V V / __/ | (_| (_) | | | | | | __/
|
||||||
|
|____/ \__\__,_|_| \__\___|\__,_| \_/\_/ \___|_|\___\___/|_| |_| |_|\___|
|
||||||
|
)");
|
||||||
// std::atexit(resetLight);
|
// std::atexit(resetLight);
|
||||||
// 初始化日志
|
// 初始化日志
|
||||||
Log::init();
|
Log::init();
|
||||||
@ -218,7 +234,7 @@ int main(int argc, char* argv[])
|
|||||||
w.show();
|
w.show();
|
||||||
|
|
||||||
// 硬盘检测线程,检测硬盘容量
|
// 硬盘检测线程,检测硬盘容量
|
||||||
CheckStorageThread* thread = new CheckStorageThread();
|
thread = new CheckStorageThread();
|
||||||
thread->start();
|
thread->start();
|
||||||
QObject::connect(thread, SIGNAL(diskWillFull()), serialPortTool, SLOT(onDiskWillFull()));
|
QObject::connect(thread, SIGNAL(diskWillFull()), serialPortTool, SLOT(onDiskWillFull()));
|
||||||
QObject::connect(thread, SIGNAL(diskNotFull()), serialPortTool, SLOT(onDiskNotFull()));
|
QObject::connect(thread, SIGNAL(diskNotFull()), serialPortTool, SLOT(onDiskNotFull()));
|
||||||
|
Loading…
Reference in New Issue
Block a user