diff --git a/Channel.cpp b/Channel.cpp index fd0636b..fd686f8 100755 --- a/Channel.cpp +++ b/Channel.cpp @@ -2,6 +2,7 @@ #include "Constant.h" #include "Log.h" #include "Tool.h" +#include #include #include #include @@ -10,6 +11,7 @@ LinkObject* Channel::audioInput = nullptr; LinkObject* Channel::audioOutput = nullptr; LinkObject* Channel::rtspServer = nullptr; +QString Channel::curRecordFilename = ""; extern LinkObject* vo; extern LinkObject* vo1; @@ -85,11 +87,20 @@ void Channel::init() dataMp4["format"] = "mp4"; dataMp4["segmentDuration"] = duration; dataMp4["lowLatency"] = true; - dataMp4["filecache"] = 20480000; + // dataMp4["filecache"] = 20480000; record->setData(dataMp4); videoInput->linkV(videoEncoder)->linkV(record); audioInput->linkA(audioEncoder)->linkA(record); + connect(record, &LinkObject::newEvent, [=](QString type, QVariant data) { + if (type == "newSegment") { + int id = data.toInt(); + curRecordFilename = QString("%1_%2.mp4") + .arg(curRecordFilename.split("_")[0]) + .arg(id, 2, 10, QLatin1Char('0')); + } + }); + // rstp流 rtsp = Link::create("Mux"); QVariantMap dataRtsp; @@ -128,9 +139,12 @@ void Channel::init() */ void Channel::startRecord() { + // 阻塞到整分钟才开始录制,方便上位机进行回放 while (int secs = QTime::currentTime().second() % 60 != 0) { + QCoreApplication::processEvents(); } QString curTime = QDateTime::currentDateTime().toString("yyyyMMddhhmm"); + curRecordFilename = curTime + "_00.mp4"; QVariantMap dataRecord; QString path = QString("%1/%2/%3.mp4").arg(Constant::VideoPath).arg(channelName).arg(curTime + "_%02d"); dataRecord["path"] = path; diff --git a/Channel.h b/Channel.h index b55376a..2465740 100755 --- a/Channel.h +++ b/Channel.h @@ -31,10 +31,11 @@ public: QVariantMap audioEncoderParams; LinkObject* record; - // 单个视频时长 - int duration = 1 * 60 * 1000; + int duration = 1 * 60 * 1000; // 单个视频时长 bool isRecord = false; + static QString curRecordFilename; // 当前正在录制的文件名 + int playbackDuration = 0; LinkObject* file; LinkObject* image; LinkObject* videoDecoder; @@ -47,15 +48,12 @@ public: void startRecord(); void stopRecord(); - - int playbackDuration = 0; bool startPlayback(QString path); void forward(); void back(); void togglePause(); void startPlayLive(); - void showFinishPromot(); signals: diff --git a/ChannelSetting.cpp b/ChannelSetting.cpp new file mode 100644 index 0000000..030d1f6 --- /dev/null +++ b/ChannelSetting.cpp @@ -0,0 +1,140 @@ +#include "ChannelSetting.h" +#include "Constant.h" +#include "SerialPortTool.h" +#include "ui_ChannelSetting.h" +#include +#include +#include +#include +#include + +extern SerialPortTool* serialPortTool; + +ChannelSetting::ChannelSetting(QWidget* parent) + : QWidget(parent) + , ui(new Ui::ChannelSetting) +{ + ui->setupUi(this); + + QPoint globalPos = parent->mapToGlobal(QPoint(0, 0)); + int x = globalPos.x() + (parent->width() - this->width()) / 2; + int y = globalPos.y() + (parent->height() - this->height()) / 2; + this->move(x, y); +} + +ChannelSetting::~ChannelSetting() +{ + delete ui; +} + +/** + * @brief 重写show方法 + */ +void ChannelSetting::show() +{ + // 默认聚焦确定按钮 + ui->btnDone->setFocus(); + // 获取配置文件中保存的输入源类型(HDMI or VGA) + QVariantMap config = Json::loadFile(Constant::ConfigurationPath).toMap(); + QVariantList list = config["interface"].toList(); + for (int i = 0; i < list.count(); i++) { + QVariantMap cfg = list.at(i).toMap(); + QString channelName = cfg["name"].toString(); + QString protocol = cfg["protocol"].toString(); + if (channelName == Constant::MainChannel) { + protocol1 = protocol; + } else { + protocol2 = protocol; + } + } + if (protocol1 == "HDMI") { + ui->btn_hdmi_1->setChecked(true); + } else { + ui->btn_vga_1->setChecked(true); + } + if (protocol2 == "HDMI") { + ui->btn_hdmi_2->setChecked(true); + } else { + ui->btn_vga_2->setChecked(true); + } + QWidget::show(); +} + +void ChannelSetting::onReceiveNext() +{ + QKeyEvent keyEvent(QEvent::KeyPress, Qt::Key_Down, Qt::NoModifier); + QApplication::sendEvent(focusWidget(), &keyEvent); + + QKeyEvent keyEvent1(QEvent::KeyRelease, Qt::Key_Down, Qt::NoModifier); + QApplication::sendEvent(focusWidget(), &keyEvent1); +} + +void ChannelSetting::onReceivePre() +{ + QKeyEvent keyEvent(QEvent::KeyPress, Qt::Key_Up, Qt::NoModifier); + QApplication::sendEvent(focusWidget(), &keyEvent); + + QKeyEvent keyEvent1(QEvent::KeyRelease, Qt::Key_Up, Qt::NoModifier); + QApplication::sendEvent(focusWidget(), &keyEvent1); +} + +void ChannelSetting::onReceiveEnter() +{ + // 聚焦的控件 + QString objName = focusWidget()->objectName(); + // 通道一 + if (objName.endsWith("1")) { + if (objName == "btn_hdmi_1") { + ui->btn_hdmi_1->setChecked(true); + ui->btn_vga_1->setChecked(false); + protocol1 = "HDMI"; + } else { + ui->btn_hdmi_1->setChecked(false); + ui->btn_vga_1->setChecked(true); + protocol1 = "VGA"; + } + } + // 通道二 + else if (objName.endsWith("2")) { + if (objName == "btn_hdmi_2") { + ui->btn_hdmi_2->setChecked(true); + ui->btn_vga_2->setChecked(false); + protocol2 = "HDMI"; + } else { + ui->btn_hdmi_2->setChecked(false); + ui->btn_vga_2->setChecked(true); + protocol2 = "VGA"; + } + } + // 确认按钮 + else { + // 保存配置 + QVariantMap config = Json::loadFile(Constant::ConfigurationPath).toMap(); + QVariantList list = config["interface"].toList(); + for (int i = 0; i < list.count(); i++) { + QVariantMap cfg = list.at(i).toMap(); + QString channelName = cfg["name"].toString(); + if (channelName == Constant::MainChannel) { + cfg["protocol"] = protocol1; + } else { + cfg["protocol"] = protocol2; + } + list[i] = cfg; + } + config["interface"] = list; + Json::saveFile(config, Constant::ConfigurationPath); + // 发送指令 + if (protocol1 == "HDMI") { + serialPortTool->onMainChannelHDMI(); + } else { + serialPortTool->onMainChannelVGA(); + } + QThread::msleep(100); + if (protocol2 == "HDMI") { + serialPortTool->onSecondaryChannelHDMI(); + } else { + serialPortTool->onSecondaryChannelVGA(); + } + hide(); + } +} \ No newline at end of file diff --git a/ChannelSetting.h b/ChannelSetting.h new file mode 100644 index 0000000..aa5a9be --- /dev/null +++ b/ChannelSetting.h @@ -0,0 +1,29 @@ +#ifndef CHANNELSETTING_H +#define CHANNELSETTING_H + +#include + +namespace Ui { +class ChannelSetting; +} + +class ChannelSetting : public QWidget { + Q_OBJECT + +public: + explicit ChannelSetting(QWidget* parent = 0); + ~ChannelSetting(); + void show(); + +public slots: + void onReceiveEnter(); + void onReceivePre(); + void onReceiveNext(); + +private: + Ui::ChannelSetting* ui; + QString protocol1; // 通道1输入信号类型 + QString protocol2; // 通道2输入信号类型 +}; + +#endif // CHANNELSETTING_H diff --git a/ChannelSetting.ui b/ChannelSetting.ui new file mode 100644 index 0000000..9d1bdce --- /dev/null +++ b/ChannelSetting.ui @@ -0,0 +1,269 @@ + + + ChannelSetting + + + + 0 + 0 + 391 + 307 + + + + Form + + + QPushButton { + outline: none; + border: none; +} + +QPushButton:focus { + border: 5px solid red; +} + +QPushButton:checked { + background: blue; +} + + + + 0 + + + 0 + + + 0 + + + 0 + + + 0 + + + + + QWidget { + color: #ffffff; +} + +QWidget#widget{ + background: rgba(0, 0, 0, 0.8); +} + +QPushButton { + outline: none; + border: none; + background: rgba(100,100,100,0.8); +} + +QPushButton:focus { + border: 5px solid red; +} + +QPushButton:checked { + background: rgba(0,0,255,0.8); +} + + + + + + + 14 + + + + 视频源设置 + + + Qt::AlignCenter + + + + + + + + + + 16777213 + 16777215 + + + + + 12 + + + + 通道1 + + + Qt::AlignCenter + + + + + + + 10 + + + 10 + + + + + + 0 + 0 + + + + + 12 + + + + HDMI + + + true + + + + + + + + 0 + 0 + + + + + 12 + + + + VGA + + + true + + + + + + + + + + + + + + 16777213 + 16777215 + + + + + 12 + + + + 通道2 + + + Qt::AlignCenter + + + + + + + 10 + + + 10 + + + + + + 0 + 0 + + + + + 12 + + + + HDMI + + + true + + + + + + + + 0 + 0 + + + + + 12 + + + + VGA + + + true + + + + + + + + + + + + 0 + 40 + + + + + 12 + + + + background: rgba(0,0,255,0.8); + + + 确定 + + + + + + + + + + + diff --git a/CheckStorageThread.cpp b/CheckStorageThread.cpp index eeaf594..e8c34e2 100755 --- a/CheckStorageThread.cpp +++ b/CheckStorageThread.cpp @@ -46,11 +46,15 @@ void CheckStorageThread::run() bool ret = Tool::removeFile(path); if (!ret) { Log::error("remove file {} failed", path.toStdString()); + } else { + Log::info("remove file {} success", path.toStdString()); } path = QString("%1/%2/%3").arg(Constant::VideoPath).arg(Constant::SecondaryChannel).arg(filename); ret = Tool::removeFile(path); if (!ret) { Log::error("remove file {} failed", path.toStdString()); + } else { + Log::info("remove file {} success", path.toStdString()); } } } else { diff --git a/Constant.h b/Constant.h index 5588998..1b3b626 100755 --- a/Constant.h +++ b/Constant.h @@ -23,8 +23,8 @@ public: static constexpr char* ErrorImagePath = "/opt/RecordControlApplication/images/error.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* SecondaryChannel = "HDMI-B"; + static constexpr char* MainChannel = "HDMI-C"; + static constexpr char* SecondaryChannel = "HDMI-D"; }; #endif // CONSTANT_H diff --git a/Menu.ui b/Menu.ui index 11bd573..4cd7132 100755 --- a/Menu.ui +++ b/Menu.ui @@ -21,12 +21,13 @@ QPushButton { border: none; - background: rgba(0, 0, 0, 0.4); + background: rgba(0, 0, 0, 0.8); color: #ffffff; } QPushButton::checked{ -color: #00AEEC; + /*color: #1668dc;*/ +color:#3c89e8; } diff --git a/RecordControlApplication.pro b/RecordControlApplication.pro index 98a9e7c..9c81698 100755 --- a/RecordControlApplication.pro +++ b/RecordControlApplication.pro @@ -44,7 +44,8 @@ SOURCES += \ TcpConnectionHandler.cpp \ TcpRequestHandler.cpp \ TcpResponse.cpp \ - SerialPortTool.cpp + SerialPortTool.cpp \ + ChannelSetting.cpp HEADERS += \ Widget.h \ @@ -60,12 +61,14 @@ HEADERS += \ TcpConnectionHandler.h \ TcpRequestHandler.h \ TcpResponse.h \ - SerialPortTool.h + SerialPortTool.h \ + ChannelSetting.h FORMS += \ Menu.ui \ ProgressBar.ui \ - Widget.ui + Widget.ui \ + ChannelSetting.ui RESOURCES += \ res.qrc diff --git a/SerialPortTool.cpp b/SerialPortTool.cpp index a7e7100..797e89e 100644 --- a/SerialPortTool.cpp +++ b/SerialPortTool.cpp @@ -14,28 +14,43 @@ SerialPortTool::SerialPortTool(QObject* parent) 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()); + auto makeCommand = [=](int type, QString data, QString enable) { + // 命令类型 + QString t; + if (type == 2) + t = "02"; // 指示灯 + else + t = "03"; // 使能 + return QByteArray::fromHex(QString("A2 B2 08 %1 %2 %3 C2 D2") + .arg(t) + .arg(data) + .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"); + cmdMap[Reset] = makeCommand(2, "00", "00"); + cmdMap[PlaybackStart] = makeCommand(2, "01", "01"); + cmdMap[PlaybackEnd] = makeCommand(2, "01", "00"); + cmdMap[RecordStart] = makeCommand(2, "02", "01"); + cmdMap[RecordEnd] = makeCommand(2, "02", "00"); + cmdMap[PlayPause] = makeCommand(2, "03", "01"); + cmdMap[PlayResume] = makeCommand(2, "03", "00"); + cmdMap[DiskWillFull] = makeCommand(2, "04", "01"); + cmdMap[DiskNotFull] = makeCommand(2, "04", "00"); + cmdMap[PowerOn] = makeCommand(2, "05", "01"); + cmdMap[PowerOff] = makeCommand(2, "05", "00"); + cmdMap[Forward] = makeCommand(2, "08", "01"); + cmdMap[LoopOn] = makeCommand(2, "07", "01"); + cmdMap[LoopOff] = makeCommand(2, "07", "00"); + cmdMap[Back] = makeCommand(2, "06", "01"); + cmdMap[MainChannelOn] = makeCommand(2, "09", "01"); + cmdMap[MainChannelOff] = makeCommand(2, "09", "00"); + cmdMap[SecondaryChannelOn] = makeCommand(2, "0A", "01"); + cmdMap[SecondaryChannelOff] = makeCommand(2, "0A", "00"); + cmdMap[MainChannelHDMI] = makeCommand(3, "03", "00"); + cmdMap[MainChannelVGA] = makeCommand(3, "03", "01"); + cmdMap[SecondaryChannelHDMI] = makeCommand(3, "04", "00"); + cmdMap[SecondaryChanneVGA] = makeCommand(3, "04", "01"); } SerialPortTool::~SerialPortTool() @@ -163,11 +178,20 @@ void SerialPortTool::onReayRead() case 8: emit btnDoneClicked(); break; + case 9: + emit btnChannelSettingClicked(); + break; default: break; } } +void SerialPortTool::onReset() +{ + serialPort->write(cmdMap.value(Reset)); + serialPort->flush(); +} + void SerialPortTool::onPlaybackStart() { serialPort->write(cmdMap.value(PlaybackStart)); @@ -273,3 +297,27 @@ void SerialPortTool::onSecondaryChannelOff() serialPort->write(cmdMap.value(SecondaryChannelOff)); serialPort->flush(); } + +void SerialPortTool::onMainChannelHDMI() +{ + serialPort->write(cmdMap.value(MainChannelHDMI)); + serialPort->flush(); +} + +void SerialPortTool::onMainChannelVGA() +{ + serialPort->write(cmdMap.value(MainChannelVGA)); + serialPort->flush(); +} + +void SerialPortTool::onSecondaryChannelHDMI() +{ + serialPort->write(cmdMap.value(SecondaryChannelHDMI)); + serialPort->flush(); +} + +void SerialPortTool::onSecondaryChannelVGA() +{ + serialPort->write(cmdMap.value(SecondaryChanneVGA)); + serialPort->flush(); +} diff --git a/SerialPortTool.h b/SerialPortTool.h index 9ec5627..870a4af 100644 --- a/SerialPortTool.h +++ b/SerialPortTool.h @@ -14,6 +14,7 @@ public: void open(); void close(); public slots: + void onReset(); void onPlaybackStart(); void onPlaybackEnd(); void onRecordStart(); @@ -32,6 +33,10 @@ public slots: void onMainChannelOff(); void onSecondaryChannelOn(); void onSecondaryChannelOff(); + void onMainChannelHDMI(); + void onMainChannelVGA(); + void onSecondaryChannelHDMI(); + void onSecondaryChannelVGA(); private slots: void onSerialError(QSerialPort::SerialPortError error); @@ -46,9 +51,11 @@ signals: void btnNextClicked(); void btnForwardClicked(); void btnDoneClicked(); + void btnChannelSettingClicked(); private: enum CommandType { + Reset, PlaybackStart, PlaybackEnd, RecordStart, @@ -66,7 +73,11 @@ private: MainChannelOn, MainChannelOff, SecondaryChannelOff, - SecondaryChannelOn + SecondaryChannelOn, + MainChannelHDMI, + MainChannelVGA, + SecondaryChannelHDMI, + SecondaryChanneVGA }; QSerialPort* serialPort; // 串口 diff --git a/TcpRequestHandler.cpp b/TcpRequestHandler.cpp index 4284602..cc3db73 100755 --- a/TcpRequestHandler.cpp +++ b/TcpRequestHandler.cpp @@ -62,7 +62,7 @@ void TcpRequestHandler::setIpaddr(TcpRequest* request, TcpResponse* reponse) netMap["gateway"] = params.value("gateway"); Json::saveFile(netMap, Constant::NetConfigPath); - reponse->success(); + reponse->success("修改ip地址成功,请重新连接"); Tool::writeCom(Constant::NetScriptPath); } @@ -81,7 +81,7 @@ void TcpRequestHandler::setName(TcpRequest* request, TcpResponse* reponse) QVariantMap cfg = Json::loadFile(Constant::ConfigurationPath).toMap(); cfg["name"] = params.value("name"); Json::saveFile(cfg, Constant::ConfigurationPath); - reponse->success(); + reponse->success("设置名称成功"); } /** @@ -92,7 +92,7 @@ void TcpRequestHandler::getName(TcpRequest* request, TcpResponse* reponse) QVariantMap config = Json::loadFile(Constant::ConfigurationPath).toMap(); QString name = config["name"].toString(); QString data = QString("url=get_name\r\nstatus=success\r\nname=%1").arg(name); - reponse->success("", name); + reponse->success("获取盒子名称成功", name); } /** @@ -190,12 +190,10 @@ void TcpRequestHandler::getFileList(TcpRequest* request, TcpResponse* reponse) QString videoPath = QString("%1/%2").arg(Constant::VideoPath).arg(interface); QStringList videoList = Tool::getFileList(videoPath); - - // 复制两份测试用 - QStringList copy = videoList; - QStringList copy1 = videoList; - videoList.append(copy); - videoList.append(copy1); + // 如果最后一个文件名是当前正在录制的文件名,则去除 + if (videoList.last() == Channel::curRecordFilename) { + videoList.pop_back(); + } reponse->success("获取文件成功", videoList); } @@ -284,7 +282,8 @@ void TcpRequestHandler::setPlaybackMode(TcpRequest* request, TcpResponse* repons } QVariantMap cfg = Json::loadFile(Constant::ConfigurationPath).toMap(); - int mode = cfg["playbackMode"].toInt();; + int mode = cfg["playbackMode"].toInt(); + ; if (playbackMode == mode) { Log::info("record mode has not changed, there is nothing need to do"); reponse->success("回放参数无需改变"); diff --git a/Tool.cpp b/Tool.cpp index b8a5302..0ad1e1c 100755 --- a/Tool.cpp +++ b/Tool.cpp @@ -29,7 +29,6 @@ QStringList Tool::getFileList(QString path) nameFilters << "*.mp4"; dir.setNameFilters(nameFilters); fileList = dir.entryList(); - return fileList; } @@ -101,9 +100,9 @@ int64_t Tool::getAvailableStorage(QString mountedPath) continue; index += 1; if (index == 2) - used = s.toInt(); + used = s.toLong(); else if (index == 3) - available = s.toInt(); + available = s.toLong(); } qDebug() << QString("%1: used %2 bytes, available %3 bytes") .arg(mountedPath) diff --git a/Widget.cpp b/Widget.cpp index 814491c..be32b40 100755 --- a/Widget.cpp +++ b/Widget.cpp @@ -35,7 +35,8 @@ Widget::Widget(QWidget* parent) progressBar = new ProgressBar(this); progressBar->hide(); - message = new Message(this); + channelSetting = new ChannelSetting(this); + channelSetting->hide(); // 设置窗体背景透明 QPalette pal = palette(); @@ -63,19 +64,23 @@ Widget::Widget(QWidget* parent) bool available = data["avalible"].toBool(); if (available) { Log::info("video input {} is available", - chn->channelName == Constant::MainChannel ? "HDMI-A" : "HDMI-B"); + chn->channelName == Constant::MainChannel ? "HDMI-C" : "HDMI-D"); if (chn->channelName == Constant::MainChannel) { serialPortTool->onMainChannelOn(); + QThread::msleep(100); } else { serialPortTool->onSecondaryChannelOn(); + QThread::msleep(100); } } else { Log::info("video input {} is not available", - chn->channelName == Constant::MainChannel ? "HDMI-A" : "HDMI-B"); + chn->channelName == Constant::MainChannel ? "HDMI-C" : "HDMI-D"); if (chn->channelName == Constant::MainChannel) { serialPortTool->onMainChannelOff(); + QThread::msleep(100); } else { serialPortTool->onSecondaryChannelOff(); + QThread::msleep(100); } } } @@ -84,12 +89,13 @@ Widget::Widget(QWidget* parent) connect(serialPortTool, SIGNAL(btnPlaybackClicked()), this, SLOT(onBtnPlaybackClicked())); connect(serialPortTool, SIGNAL(btnPreviousClicked()), this, SLOT(onBtnPreviousClicked())); - connect(serialPortTool, SIGNAL(btnPauseClicked()), this, SLOT(onBtnEnterClicked())); + connect(serialPortTool, SIGNAL(btnPauseClicked()), this, SLOT(onBtnPasueClicked())); 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())); + connect(serialPortTool, SIGNAL(btnChannelSettingClicked()), this, SLOT(onBtnChannelSettingClicked())); } Widget::~Widget() @@ -98,7 +104,46 @@ Widget::~Widget() delete progressTimer; delete menu; delete progressBar; - delete message; + delete channelSetting; +} + +void Widget::renderList() +{ + ui->listWidget->clear(); + if (fileList.isEmpty()) { + ui->listWidget->show(); + return; + } + // 如果在录制中应该出去正在录制的文件名 + if (fileList.last() == Channel::curRecordFilename) { + fileList.pop_back(); + } + + QListWidgetItem* curItem = nullptr; + for (QString& file : fileList) { + QListWidgetItem* item = new QListWidgetItem(file); + ui->listWidget->addItem(item); + if (isPlayback) { + // 一路回放 + if (playbackMode == Constant::OneChannelPlayback) { + if (curPlayChannel == curSelectChannel && item->text() == curPlayFilename) { + curItem = item; + } + } + // 两路回放 + else { + if (item->text() == curPlayFilename) { + curItem = item; + } + } + } + } + ui->listWidget->show(); + if (curItem) { + ui->listWidget->setCurrentItem(curItem); + } else { + ui->listWidget->setCurrentRow(0); + } } /** @@ -107,15 +152,8 @@ Widget::~Widget() void Widget::showPlayList() { QString dirPath = QString("%1/%2").arg(Constant::VideoPath).arg(curSelectChannel); - QStringList files = Tool::getFileList(dirPath); - - ui->listWidget->clear(); - for (QString& file : files) { - QListWidgetItem* item = new QListWidgetItem(file); - ui->listWidget->addItem(item); - } - ui->listWidget->show(); - ui->listWidget->setCurrentRow(0); + fileList = Tool::getFileList(dirPath); + renderList(); } /** @@ -133,6 +171,9 @@ void Widget::onProgressTimeout() */ void Widget::onBtnPlaybackClicked() { + // 如果在进行通道设置屏蔽回放操作 + if (channelSetting->isVisible()) + return; Log::info("receive command playback, playback mode: {}", playbackMode); // 如果是一路回放,显示选择菜单 if (playbackMode == Constant::OneChannelPlayback) { @@ -147,10 +188,15 @@ void Widget::onBtnPlaybackClicked() } /** - * @brief 收到上段指令 + * @brief 收到上段指令, 优先级 + * 处理优先级: 通道设置菜单 ==> 通道选择菜单 ==> 列表 */ void Widget::onBtnPreviousClicked() { + if (channelSetting->isVisible()) { + channelSetting->onReceivePre(); + return; + } // 菜单显示则切换菜单选中 if (menu->isVisible()) { menu->setCurChannel(Constant::MainChannel); @@ -168,9 +214,14 @@ void Widget::onBtnPreviousClicked() /** * @brief 收到下段指令 + * 处理优先级: 通道设置菜单 ==> 通道选择菜单 ==> 列表 */ void Widget::onBtnNextClicked() { + if (channelSetting->isVisible()) { + channelSetting->onReceiveNext(); + return; + } if (menu->isVisible()) { menu->setCurChannel(Constant::SecondaryChannel); return; @@ -204,7 +255,7 @@ void Widget::onBtnPasueClicked() } else { progressBar->setState(ProgressBar::Play); // 关闭暂停灯 - serialPortTool->onPlayPause(); + serialPortTool->onPlayResume(); } } } @@ -213,9 +264,14 @@ void Widget::onBtnPasueClicked() /** * @brief 收到确定指令 + * 通道设置菜单 ==> 通道选择菜单 ==> 列表 */ void Widget::onBtnEnterClicked() { + if (channelSetting->isVisible()) { + channelSetting->onReceiveEnter(); + return; + } // 菜单显示,则关闭菜单显示列表 if (menu->isVisible()) { curSelectChannel = menu->getCurChannel(); @@ -237,10 +293,14 @@ void Widget::onBtnEnterClicked() /** * @brief 收到返回指令 - * 处理优先级: 菜单 ==> 列表 ==> 回放 + * 处理优先级: 通道设置菜单 ==> 通道选择菜单 ==> 列表 ==> 回放 */ void Widget::onBtnReturnClicked() { + if (channelSetting->isVisible()) { + channelSetting->hide(); + return; + } if (menu->isVisible()) { menu->hide(); return; @@ -255,6 +315,7 @@ void Widget::onBtnReturnClicked() if (chn->state != Channel::Stop) { chn->startPlayLive(); serialPortTool->onPlaybackEnd(); + curPlayFilename = ""; } } progressBar->hide(); @@ -302,6 +363,20 @@ void Widget::onBtnBackClicked() seek("back"); } +/** + * @brief 打开通道设置HDMI or VGA + */ +void Widget::onBtnChannelSettingClicked() +{ + // 关闭通道选择菜单 + if (menu->isVisible()) + menu->hide(); + // 打开通道设置菜单 + if (channelSetting->isVisible()) + return; + channelSetting->show(); +} + /** * @brief 一路回放,将当前选中播放的视频从HDMI-OUT0口输出 */ @@ -349,7 +424,7 @@ void Widget::playOneChannel() } /** - * @brief 两路回放,以HDMI-A口的视频为主分别从HDMI-OUT0和HDMI-OUT1输出 + * @brief 两路回放,以主通道的视频为主分别从HDMI-OUT0和HDMI-OUT1输出 */ void Widget::playTwoChannels() { @@ -389,7 +464,7 @@ void Widget::playTwoChannels() condition.wakeAll(); mutex.unlock(); - // 将HDMI-A通道的视频列表作为主列表 + // 将主通道的视频列表作为主列表 QString dirPath = QString("%1/%2").arg(Constant::VideoPath).arg(Constant::MainChannel); fileList = Tool::getFileList(dirPath); } @@ -410,11 +485,14 @@ void Widget::onPlayEnd() } } } + bool needRefresh = false; // 计算下一个文件名 int index = fileList.indexOf(curPlayFilename); if (index == fileList.length() - 1) { + // 重新刷新文件列表 QString dirPath = QString("%1/%2").arg(Constant::VideoPath).arg(curPlayChannel); fileList = Tool::getFileList(dirPath); + // 刷新文件列表后还是最后一个文件 if (index == fileList.length() - 1) { Log::info("there is no file to play"); // 显示播放完毕的信息 @@ -429,6 +507,7 @@ void Widget::onPlayEnd() } return; } + needRefresh = true; Log::info("refresh current play file list"); } curPlayFilename = fileList.at(index + 1); @@ -464,6 +543,11 @@ void Widget::onPlayEnd() } } } + if (needRefresh) { + renderList(); + } else { + ui->listWidget->setCurrentRow(ui->listWidget->currentRow() + 1); + } mutex.lock(); curFilename = curPlayFilename; diff --git a/Widget.h b/Widget.h index c2fae94..dee8895 100755 --- a/Widget.h +++ b/Widget.h @@ -2,6 +2,7 @@ #define WIDG_H #include "Channel.h" +#include "ChannelSetting.h" #include "Menu.h" #include "Message.h" #include "ProgressBar.h" @@ -27,7 +28,6 @@ private slots: void onProgressTimeout(); void onPlayEnd(); void onShowRecordLabel(bool show); - void onBtnPlaybackClicked(); void onBtnPreviousClicked(); void onBtnNextClicked(); @@ -36,6 +36,7 @@ private slots: void onBtnReturnClicked(); void onBtnForwardClicked(); void onBtnBackClicked(); + void onBtnChannelSettingClicked(); private: Ui::Widget* ui; @@ -49,13 +50,14 @@ private: Menu* menu; ProgressBar* progressBar; - Message* message; + ChannelSetting* channelSetting; private: void seek(QString type); void playOneChannel(); void playTwoChannels(); Channel* findChannelByName(QString name); + void renderList(); }; #endif // WIDG_H diff --git a/main.cpp b/main.cpp index 923bb8a..29917c6 100755 --- a/main.cpp +++ b/main.cpp @@ -9,6 +9,7 @@ #include "Tool.h" #include "Widget.h" #include +#include #include // Tcp服务器 @@ -41,6 +42,7 @@ bool loadConfiguration(QString path) recordMode = Constant::RecordMode(config["recordMode"].toInt()); playbackMode = Constant::PlaybackMode(config["playbackMode"].toInt()); QVariantList list = config["interface"].toList(); + // 初始化通道 for (int i = 0; i < list.count(); i++) { Channel* chn = new Channel(); QVariantMap cfg = list.at(i).toMap(); @@ -60,6 +62,15 @@ bool loadConfiguration(QString path) return true; } +/** + * @brief 关闭所有灯光 + */ +void resetLight() +{ + printf("reset all lights"); + serialPortTool->onReset(); +} + /** * @brief 开始录制 */ @@ -69,16 +80,19 @@ void startRecord() QString info = Tool::writeCom(QString("df %1").arg(Constant::MountedPath)); if (!info.contains(Constant::MountedPath)) { Log::error("there is no disk mounted"); + serialPortTool->onLoopOn(); + QThread::msleep(100); return; } - // 一路录制,只录制HDMI-A通道 + // 一路录制,只录制主通道 if (recordMode == Constant::OneChannelRecord) { for (Channel* chn : channelList) { if (chn->channelName == Constant::MainChannel) { chn->startRecord(); - // 打开录制灯,关闭环路灯 + QThread::msleep(100); serialPortTool->onRecordStart(); + QThread::msleep(100); serialPortTool->onLoopOff(); } } @@ -87,20 +101,24 @@ void startRecord() else if (recordMode == Constant::TwoChannelRecord) { for (Channel* chn : channelList) { chn->startRecord(); - // 打开录制灯,关闭环路灯 serialPortTool->onRecordStart(); + QThread::msleep(100); serialPortTool->onLoopOff(); + QThread::msleep(100); } } // 无录制 else { + qDebug() << "no record"; // 打开环路灯 serialPortTool->onLoopOn(); + QThread::msleep(100); } } int main(int argc, char* argv[]) { + // std::atexit(resetLight); // 初始化日志 Log::init(); @@ -163,23 +181,21 @@ int main(int argc, char* argv[]) return 0; } - // 串口 + // 打开串口 serialPortTool = new SerialPortTool(); serialPortTool->open(); - // 打开电源灯 - serialPortTool->onPowerOn(); - // qt界面 - Widget w; - w.show(); - - // 开始录制 - startRecord(); + serialPortTool->onPowerOn(); // 打开电源灯 + QThread::msleep(100); // 开启Tcp服务 server = new TcpServer(); server->listen(); + // qt界面 + Widget w; + w.show(); + // 硬盘检测线程,检测硬盘容量 CheckStorageThread* thread = new CheckStorageThread(); thread->start(); @@ -187,5 +203,7 @@ int main(int argc, char* argv[]) QObject::connect(thread, SIGNAL(diskNotFull()), serialPortTool, SLOT(onDiskNotFull())); Log::info("start storage check thread..."); + // 开始录制 + startRecord(); return a.exec(); }