RecordControlApplication/Widget.cpp

440 lines
12 KiB
C++
Raw Normal View History

2024-01-18 15:41:43 +08:00
#include "Widget.h"
#include "Channel.h"
2024-03-04 16:22:40 +08:00
#include "Constant.h"
#include "Json.h"
#include "Log.h"
#include "SerialPortTool.h"
2024-01-18 15:41:43 +08:00
#include "TcpServer.h"
2024-03-04 16:22:40 +08:00
#include "Tool.h"
2024-01-18 15:41:43 +08:00
#include "ui_Widget.h"
#include <QDir>
2024-03-04 16:22:40 +08:00
#include <QMutex>
2024-01-18 15:41:43 +08:00
#include <QScrollBar>
2024-03-04 16:22:40 +08:00
#include <QWaitCondition>
// 多线程中使用
QMutex mutex;
QWaitCondition condition;
QString curFilename;
2024-01-18 15:41:43 +08:00
extern QList<Channel*> channelList;
2024-03-04 16:22:40 +08:00
extern Constant::PlaybackMode playbackMode;
extern SerialPortTool* serialPortTool;
2024-01-18 15:41:43 +08:00
2024-03-04 16:22:40 +08:00
Widget::Widget(QWidget* parent)
2024-01-18 15:41:43 +08:00
: QWidget(parent)
, ui(new Ui::Widget)
{
ui->setupUi(this);
2024-08-12 11:26:42 +08:00
ui->lblImgA->setPixmap(QPixmap(":/images/no-record.png"));
ui->lblImgB->setPixmap(QPixmap(":/images/no-record.png"));
ui->lblTxtA->setText("未录制");
ui->lblTxtB->setText("未录制");
ui->recordWidget->hide();
2024-01-18 15:41:43 +08:00
2024-08-12 11:26:42 +08:00
menu = new Menu();
2024-01-18 15:41:43 +08:00
menu->hide();
2024-08-12 11:26:42 +08:00
// 设置是否显示通道选择
menu->setChannelSelectVisible(playbackMode == Constant::OneChannelPlayback);
ui->progressBar->hide();
2024-01-18 15:41:43 +08:00
2024-03-04 16:22:40 +08:00
// 每5秒更新一次进度条
progressTimer = new QTimer();
2024-08-12 11:26:42 +08:00
progressTimer->setInterval(200);
connect(progressTimer, SIGNAL(timeout()), this, SLOT(onProgressTimeout()));
for (Channel* chn : channelList) {
connect(chn, SIGNAL(playEnd()), this, SLOT(onPlayEnd()));
2024-03-04 16:22:40 +08:00
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) {
if (type == "signal") {
QVariantMap data = msg.toMap();
bool available = data["avalible"].toBool();
if (available) {
2024-08-12 11:26:42 +08:00
Log::info("video input {} is available", chn->channelName == Constant::MainChannel ? Constant::MainChannel : Constant::SecondaryChannel);
if (chn->channelName == Constant::MainChannel) {
serialPortTool->onMainChannelOn();
QThread::msleep(100);
} else {
serialPortTool->onSecondaryChannelOn();
QThread::msleep(100);
}
} else {
2024-08-12 11:26:42 +08:00
Log::info("video input {} is not available", chn->channelName == Constant::MainChannel ? Constant::MainChannel : Constant::SecondaryChannel);
if (chn->channelName == Constant::MainChannel) {
serialPortTool->onMainChannelOff();
QThread::msleep(100);
} else {
serialPortTool->onSecondaryChannelOff();
QThread::msleep(100);
}
}
}
});
}
2024-08-12 11:26:42 +08:00
connect(serialPortTool, SIGNAL(btnMenuClicked()), this, SLOT(onBtnMenuClicked()));
connect(serialPortTool, SIGNAL(btnUpClicked()), this, SLOT(onBtnUpClicked()));
connect(serialPortTool, SIGNAL(btnDownClicked()), this, SLOT(onBtnDownClicked()));
connect(serialPortTool, SIGNAL(btnLeftClicked()), this, SLOT(onBtnLeftClicked()));
connect(serialPortTool, SIGNAL(btnRightClicked()), this, SLOT(onBtnRightClicked()));
connect(serialPortTool, SIGNAL(btnConfirmClicked()), this, SLOT(onBtnConfirmClicked()));
connect(serialPortTool, SIGNAL(btnReturnClicked()), this, SLOT(onBtnReturnClicked()));
connect(serialPortTool, SIGNAL(btnVolumnUpClicked()), this, SLOT(onBtnVolumnUpClicked()));
connect(serialPortTool, SIGNAL(btnVolumnDownClicked()), this, SLOT(onBtnVolumnDownClicked()));
2024-08-12 11:26:42 +08:00
connect(menu, SIGNAL(btnVideoClicked(QString)), this, SLOT(onBtnVideoClicked(QString)));
connect(this, SIGNAL(needPlayVideo(QString)), menu, SLOT(clickPreOrNext(QString)));
2024-01-18 15:41:43 +08:00
}
Widget::~Widget()
{
delete ui;
2024-03-04 16:22:40 +08:00
delete progressTimer;
delete menu;
2024-01-18 15:41:43 +08:00
}
2024-03-04 16:22:40 +08:00
/**
* @brief
*/
void Widget::onProgressTimeout()
{
2024-03-04 16:22:40 +08:00
Channel* chn = findChannelByName(Constant::MainChannel);
2024-08-12 11:26:42 +08:00
if (chn) {
// 获取当前播放位置单位ms
int pos = chn->inputFile->invoke("getPosition").toInt();
ui->progressBar->setCurrent(pos);
}
}
2024-03-04 16:22:40 +08:00
/**
2024-08-12 11:26:42 +08:00
* @brief
2024-03-04 16:22:40 +08:00
*/
2024-08-12 11:26:42 +08:00
void Widget::onBtnMenuClicked()
2024-03-04 16:22:40 +08:00
{
2024-08-12 11:26:42 +08:00
if (!menu->isVisible()) {
menu->show();
2024-03-04 16:22:40 +08:00
}
}
/**
2024-08-12 11:26:42 +08:00
* @brief >
2024-03-04 16:22:40 +08:00
*/
2024-08-12 11:26:42 +08:00
void Widget::onBtnReturnClicked()
2024-03-04 16:22:40 +08:00
{
2024-08-12 11:26:42 +08:00
// 关闭菜单
2024-03-04 16:22:40 +08:00
if (menu->isVisible()) {
2024-08-12 11:26:42 +08:00
menu->hide();
2024-03-04 16:22:40 +08:00
return;
}
2024-08-12 11:26:42 +08:00
// 关闭回放
if (isPlayback) {
// 停止回放
for (Channel* chn : channelList) {
if (chn->state != Channel::Stop) {
chn->startPlayLive();
serialPortTool->onPlaybackEnd();
}
}
// 隐藏进度条并关闭定时器
ui->progressBar->hide();
progressTimer->stop();
// 显示录制状态
// ui->recordWidget->show();
2024-03-04 16:22:40 +08:00
}
}
/**
2024-08-12 11:26:42 +08:00
* @brief : >
2024-03-04 16:22:40 +08:00
*/
2024-08-12 11:26:42 +08:00
void Widget::onBtnUpClicked()
2024-03-04 16:22:40 +08:00
{
if (menu->isVisible()) {
2024-08-12 11:26:42 +08:00
menu->move(Menu::Up);
2024-03-04 16:22:40 +08:00
return;
}
2024-08-12 11:26:42 +08:00
if (isPlayback) {
emit needPlayVideo("previous");
2024-03-04 16:22:40 +08:00
}
}
/**
2024-08-12 11:26:42 +08:00
* @brief : >
2024-03-04 16:22:40 +08:00
*/
2024-08-12 11:26:42 +08:00
void Widget::onBtnDownClicked()
2024-03-04 16:22:40 +08:00
{
2024-08-12 11:26:42 +08:00
if (menu->isVisible()) {
menu->move(Menu::Down);
2024-03-04 16:22:40 +08:00
return;
2024-08-12 11:26:42 +08:00
}
if (isPlayback) {
emit needPlayVideo("next");
2024-01-18 15:41:43 +08:00
}
2024-03-04 16:22:40 +08:00
}
/**
2024-08-12 11:26:42 +08:00
* @brief : >
2024-03-04 16:22:40 +08:00
*/
2024-08-12 11:26:42 +08:00
void Widget::onBtnLeftClicked()
2024-03-04 16:22:40 +08:00
{
if (menu->isVisible()) {
2024-08-12 11:26:42 +08:00
menu->move(Menu::Left);
2024-03-04 16:22:40 +08:00
return;
}
2024-08-12 11:26:42 +08:00
if (isPlayback) {
seek("back");
2024-03-04 16:22:40 +08:00
}
}
/**
2024-08-12 11:26:42 +08:00
* @brief : >
2024-03-04 16:22:40 +08:00
*/
2024-08-12 11:26:42 +08:00
void Widget::onBtnRightClicked()
2024-03-04 16:22:40 +08:00
{
if (menu->isVisible()) {
2024-08-12 11:26:42 +08:00
menu->move(Menu::Right);
2024-03-04 16:22:40 +08:00
return;
}
if (isPlayback) {
2024-08-12 11:26:42 +08:00
seek("forward");
2024-03-04 16:22:40 +08:00
}
}
/**
2024-08-12 11:26:42 +08:00
* @brief ok键: >
2024-03-04 16:22:40 +08:00
*/
2024-08-12 11:26:42 +08:00
void Widget::onBtnConfirmClicked()
2024-03-04 16:22:40 +08:00
{
2024-08-12 11:26:42 +08:00
if (menu->isVisible()) {
menu->confirm();
2024-03-04 16:22:40 +08:00
return;
2024-08-12 11:26:42 +08:00
}
if (isPlayback) {
// 切换暂停和播放
for (Channel* chn : channelList) {
if (chn->state == Channel::Playback || chn->state == Channel::Pause) {
chn->togglePause();
if (chn->channelName == Constant::MainChannel) {
ui->progressBar->showMax();
if (chn->state == Channel::Pause) {
ui->progressBar->setState(ProgressBar::Pause);
// 打开暂停灯
serialPortTool->onPlayPause();
} else {
ui->progressBar->setState(ProgressBar::Play);
// 关闭暂停灯
serialPortTool->onPlayResume();
}
}
}
2024-01-18 15:41:43 +08:00
}
2024-03-04 16:22:40 +08:00
}
}
/**
* @brief
*/
void Widget::onBtnVolumnUpClicked()
{
Channel::volumeUp();
}
/**
* @brief
*/
void Widget::onBtnVolumnDownClicked()
{
Channel::volumeDown();
}
/**
2024-08-12 11:26:42 +08:00
* @brief
*/
2024-08-12 11:26:42 +08:00
void Widget::onBtnVideoClicked(QString filename)
{
2024-08-12 11:26:42 +08:00
if (filename == "first") {
qDebug() << "click previous failed, already the first video";
2024-08-12 11:26:42 +08:00
// 显示提示弹窗
} else if (filename == "last") {
if (playbackMode == Constant::OneChannelPlayback) {
Channel* chn = findChannelByName(Constant::MainChannel);
chn->showFinishPromot();
} else {
for (Channel* chn : channelList)
chn->showFinishPromot();
}
} else {
if (playbackMode == Constant::OneChannelPlayback) {
playOneChannel(filename);
} else {
playTwoChannels(filename);
}
serialPortTool->onPlaybackStart();
}
}
2024-03-04 16:22:40 +08:00
/**
* @brief HDMI-OUT0口输出
*/
2024-08-12 11:26:42 +08:00
void Widget::playOneChannel(QString filename)
2024-03-04 16:22:40 +08:00
{
// 获取当前回放的通道
QString curPlayChannel = menu->getCurPlayChannel() == DatabaseManager::MainChannel
? Constant::MainChannel
: Constant::SecondaryChannel;
QString path = QString("%1/%2/%3").arg(Constant::VideoPath).arg(curPlayChannel).arg(filename);
2024-03-04 16:22:40 +08:00
Channel* channel = findChannelByName(Constant::MainChannel);
for (Channel* chn : channelList) {
chn->startPlayLive();
}
bool ret = channel->startPlayback(path);
2024-08-12 11:26:42 +08:00
if (!ret) {
Log::info("play back error");
ui->progressBar->hide();
}
2024-03-04 16:22:40 +08:00
isPlayback = true;
// 全局保存当前播放的视频的文件名
2024-03-04 16:22:40 +08:00
mutex.lock();
curFilename = filename;
condition.wakeAll();
mutex.unlock();
int duration = channel->playbackDuration;
2024-08-12 11:26:42 +08:00
ui->progressBar->setDuration(duration);
ui->progressBar->setCurrent(0);
ui->progressBar->show();
ui->progressBar->showMax();
ui->progressBar->setState(ProgressBar::Play);
2024-03-04 16:22:40 +08:00
if (progressTimer->isActive()) {
progressTimer->stop();
progressTimer->start();
} else {
progressTimer->start();
}
2024-08-12 11:26:42 +08:00
ui->recordWidget->hide();
2024-03-04 16:22:40 +08:00
}
/**
* @brief HDMI-OUT0和HDMI-OUT1输出
2024-03-04 16:22:40 +08:00
*/
2024-08-12 11:26:42 +08:00
void Widget::playTwoChannels(QString filename)
2024-03-04 16:22:40 +08:00
{
for (Channel* chn : channelList) {
QString path = QString("%1/%2/%3").arg(Constant::VideoPath).arg(chn->channelName).arg(filename);
int ret = chn->startPlayback(path);
if (chn->channelName == Constant::MainChannel) {
if (ret) {
int duration = chn->playbackDuration;
2024-08-12 11:26:42 +08:00
ui->progressBar->setDuration(duration);
ui->progressBar->setCurrent(0);
ui->progressBar->show();
ui->progressBar->showMax();
ui->progressBar->setState(ProgressBar::Play);
2024-03-04 16:22:40 +08:00
if (progressTimer->isActive()) {
progressTimer->stop();
progressTimer->start();
} else {
progressTimer->start();
2024-01-18 15:41:43 +08:00
}
2024-08-12 11:26:42 +08:00
ui->recordWidget->hide();
2024-03-04 16:22:40 +08:00
} else {
2024-08-12 11:26:42 +08:00
ui->progressBar->hide();
ui->recordWidget->hide();
2024-01-18 15:41:43 +08:00
}
}
}
2024-03-04 16:22:40 +08:00
isPlayback = true;
// 全局保存正在播放的视频的文件名
2024-03-04 16:22:40 +08:00
mutex.lock();
curFilename = filename;
condition.wakeAll();
mutex.unlock();
2024-08-12 11:26:42 +08:00
}
/**
* @brief
*/
void Widget::seek(QString type)
{
if (!isPlayback)
return;
for (Channel* chn : channelList) {
if (chn->state == Channel::Pause || chn->state == Channel::Playback) {
if (type == "forward") {
chn->forward();
serialPortTool->onFoward();
} else {
chn->back();
serialPortTool->onBack();
}
2024-03-04 16:22:40 +08:00
2024-08-12 11:26:42 +08:00
if (chn->channelName == Constant::MainChannel)
ui->progressBar->showMax();
}
}
2024-01-18 15:41:43 +08:00
}
/**
2024-03-04 16:22:40 +08:00
* @brief
*/
void Widget::onPlayEnd()
{
// 停下回放计时器
progressTimer->stop();
2024-03-04 16:22:40 +08:00
// 当两路回放时,只处理一次槽函数
if (playbackMode == Constant::TwoChannelPlayback) {
LinkObject* file = static_cast<LinkObject*>(sender());
for (Channel* chn : channelList) {
2024-08-12 11:26:42 +08:00
if (chn->inputFile == file) {
2024-03-04 16:22:40 +08:00
if (chn->channelName != Constant::MainChannel) {
return;
}
}
}
}
2024-08-12 11:26:42 +08:00
emit needPlayVideo("next");
2024-03-04 16:22:40 +08:00
}
/**
* @brief
* @param show
*/
void Widget::onShowRecordLabel(bool show)
{
Channel* chn = static_cast<Channel*>(sender());
2024-08-12 11:26:42 +08:00
QLabel* lblImg;
QLabel* lblTxt;
2024-03-04 16:22:40 +08:00
if (chn->channelName == Constant::MainChannel) {
2024-08-12 11:26:42 +08:00
lblImg = ui->lblImgA;
lblTxt = ui->lblTxtA;
2024-03-04 16:22:40 +08:00
} else {
2024-08-12 11:26:42 +08:00
lblImg = ui->lblImgB;
lblTxt = ui->lblTxtB;
2024-03-04 16:22:40 +08:00
}
if (show) {
2024-08-12 11:26:42 +08:00
lblImg->setPixmap(QPixmap(":/images/record.png"));
lblTxt->setText("录制中");
} else {
lblImg->setPixmap(QPixmap(":/images/no-record.png"));
lblTxt->setText("未录制");
}
2024-03-04 16:22:40 +08:00
}
/**
* @brief
* @param name
*/
Channel* Widget::findChannelByName(QString name)
{
for (Channel* chn : channelList) {
if (chn->channelName == name) {
return chn;
}
}
return nullptr;
}