RecordControlApplication/Widget.cpp

440 lines
12 KiB
C++
Executable File
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#include "Widget.h"
#include "Channel.h"
#include "Constant.h"
#include "Json.h"
#include "Log.h"
#include "SerialPortTool.h"
#include "TcpServer.h"
#include "Tool.h"
#include "ui_Widget.h"
#include <QDir>
#include <QMutex>
#include <QScrollBar>
#include <QWaitCondition>
// 多线程中使用
QMutex mutex;
QWaitCondition condition;
QString curFilename;
extern QList<Channel*> channelList;
extern Constant::PlaybackMode playbackMode;
extern SerialPortTool* serialPortTool;
Widget::Widget(QWidget* parent)
: QWidget(parent)
, ui(new Ui::Widget)
{
ui->setupUi(this);
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();
menu = new Menu();
menu->hide();
// 设置是否显示通道选择
menu->setChannelSelectVisible(playbackMode == Constant::OneChannelPlayback);
ui->progressBar->hide();
// 每5秒更新一次进度条
progressTimer = new QTimer();
progressTimer->setInterval(200);
connect(progressTimer, SIGNAL(timeout()), this, SLOT(onProgressTimeout()));
for (Channel* chn : channelList) {
connect(chn, SIGNAL(playEnd()), this, SLOT(onPlayEnd()));
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) {
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 {
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);
}
}
}
});
}
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()));
connect(menu, SIGNAL(btnVideoClicked(QString)), this, SLOT(onBtnVideoClicked(QString)));
connect(this, SIGNAL(needPlayVideo(QString)), menu, SLOT(clickPreOrNext(QString)));
}
Widget::~Widget()
{
delete ui;
delete progressTimer;
delete menu;
}
/**
* @brief 更新进度条
*/
void Widget::onProgressTimeout()
{
Channel* chn = findChannelByName(Constant::MainChannel);
if (chn) {
// 获取当前播放位置单位ms
int pos = chn->inputFile->invoke("getPosition").toInt();
ui->progressBar->setCurrent(pos);
}
}
/**
* @brief 按下菜单按键
*/
void Widget::onBtnMenuClicked()
{
if (!menu->isVisible()) {
menu->show();
}
}
/**
* @brief 按下返回按键。优先级:菜单 > 播放
*/
void Widget::onBtnReturnClicked()
{
// 关闭菜单
if (menu->isVisible()) {
menu->hide();
return;
}
// 关闭回放
if (isPlayback) {
// 停止回放
for (Channel* chn : channelList) {
if (chn->state != Channel::Stop) {
chn->startPlayLive();
serialPortTool->onPlaybackEnd();
}
}
// 隐藏进度条并关闭定时器
ui->progressBar->hide();
progressTimer->stop();
// 显示录制状态
// ui->recordWidget->show();
}
}
/**
* @brief 按下上键。优先级: 菜单 > 播放
*/
void Widget::onBtnUpClicked()
{
if (menu->isVisible()) {
menu->move(Menu::Up);
return;
}
if (isPlayback) {
emit needPlayVideo("previous");
}
}
/**
* @brief 按下下键。 优先级: 菜单 > 播放
*/
void Widget::onBtnDownClicked()
{
if (menu->isVisible()) {
menu->move(Menu::Down);
return;
}
if (isPlayback) {
emit needPlayVideo("next");
}
}
/**
* @brief 按下左键。优先级: 菜单 > 播放。
*/
void Widget::onBtnLeftClicked()
{
if (menu->isVisible()) {
menu->move(Menu::Left);
return;
}
if (isPlayback) {
seek("back");
}
}
/**
* @brief 按下左键。优先级: 菜单 > 播放
*/
void Widget::onBtnRightClicked()
{
if (menu->isVisible()) {
menu->move(Menu::Right);
return;
}
if (isPlayback) {
seek("forward");
}
}
/**
* @brief 按下ok键。优先级: 菜单 > 回放
*/
void Widget::onBtnConfirmClicked()
{
if (menu->isVisible()) {
menu->confirm();
return;
}
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();
}
}
}
}
}
}
/**
* @brief 增大音量
*/
void Widget::onBtnVolumnUpClicked()
{
Channel::volumeUp();
}
/**
* @brief 减小音量
*/
void Widget::onBtnVolumnDownClicked()
{
Channel::volumeDown();
}
/**
* @brief 回放视频
*/
void Widget::onBtnVideoClicked(QString filename)
{
if (filename == "first") {
qDebug() << "click previous failed, already the first video";
// 显示提示弹窗
} 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();
}
}
/**
* @brief 一路回放将当前选中播放的视频从HDMI-OUT0口输出
*/
void Widget::playOneChannel(QString 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);
for (Channel* chn : channelList) {
chn->startPlayLive();
}
bool ret = channel->startPlayback(path);
if (!ret) {
Log::info("play back error");
ui->progressBar->hide();
}
isPlayback = true;
// 全局保存当前播放的视频的文件名
mutex.lock();
curFilename = filename;
condition.wakeAll();
mutex.unlock();
int duration = channel->playbackDuration;
ui->progressBar->setDuration(duration);
ui->progressBar->setCurrent(0);
ui->progressBar->show();
ui->progressBar->showMax();
ui->progressBar->setState(ProgressBar::Play);
if (progressTimer->isActive()) {
progressTimer->stop();
progressTimer->start();
} else {
progressTimer->start();
}
ui->recordWidget->hide();
}
/**
* @brief 两路回放以主通道的视频为主分别从HDMI-OUT0和HDMI-OUT1输出
*/
void Widget::playTwoChannels(QString filename)
{
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;
ui->progressBar->setDuration(duration);
ui->progressBar->setCurrent(0);
ui->progressBar->show();
ui->progressBar->showMax();
ui->progressBar->setState(ProgressBar::Play);
if (progressTimer->isActive()) {
progressTimer->stop();
progressTimer->start();
} else {
progressTimer->start();
}
ui->recordWidget->hide();
} else {
ui->progressBar->hide();
ui->recordWidget->hide();
}
}
}
isPlayback = true;
// 全局保存正在播放的视频的文件名
mutex.lock();
curFilename = filename;
condition.wakeAll();
mutex.unlock();
}
/**
* @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();
}
if (chn->channelName == Constant::MainChannel)
ui->progressBar->showMax();
}
}
}
/**
* @brief 当前视频播放完毕
*/
void Widget::onPlayEnd()
{
// 停下回放计时器
progressTimer->stop();
// 当两路回放时,只处理一次槽函数
if (playbackMode == Constant::TwoChannelPlayback) {
LinkObject* file = static_cast<LinkObject*>(sender());
for (Channel* chn : channelList) {
if (chn->inputFile == file) {
if (chn->channelName != Constant::MainChannel) {
return;
}
}
}
}
emit needPlayVideo("next");
}
/**
* @brief 显示录制状态的槽函数
* @param show 是否正在录制
*/
void Widget::onShowRecordLabel(bool show)
{
Channel* chn = static_cast<Channel*>(sender());
QLabel* lblImg;
QLabel* lblTxt;
if (chn->channelName == Constant::MainChannel) {
lblImg = ui->lblImgA;
lblTxt = ui->lblTxtA;
} else {
lblImg = ui->lblImgB;
lblTxt = ui->lblTxtB;
}
if (show) {
lblImg->setPixmap(QPixmap(":/images/record.png"));
lblTxt->setText("录制中");
} else {
lblImg->setPixmap(QPixmap(":/images/no-record.png"));
lblTxt->setText("未录制");
}
}
/**
* @brief 根据名称查找通道
* @param name 通道名称
*/
Channel* Widget::findChannelByName(QString name)
{
for (Channel* chn : channelList) {
if (chn->channelName == name) {
return chn;
}
}
return nullptr;
}