2024-01-18 15:41:43 +08:00
|
|
|
#include "Widget.h"
|
|
|
|
#include "Channel.h"
|
|
|
|
#include "Config.h"
|
|
|
|
#include "TcpServer.h"
|
|
|
|
#include "ui_Widget.h"
|
|
|
|
#include <QDebug>
|
|
|
|
#include <QDir>
|
|
|
|
#include <QScrollBar>
|
|
|
|
|
|
|
|
extern char* VideoPath;
|
|
|
|
extern QList<Channel*> channelList;
|
|
|
|
|
|
|
|
extern Widget::Widget(QWidget* parent)
|
|
|
|
: QWidget(parent)
|
|
|
|
, ui(new Ui::Widget)
|
|
|
|
{
|
|
|
|
ui->setupUi(this);
|
|
|
|
|
|
|
|
menu = new Menu(this);
|
|
|
|
menu->hide();
|
|
|
|
|
2024-01-25 09:57:08 +08:00
|
|
|
progressBar = new ProgressBar(this);
|
|
|
|
progressBar->hide();
|
|
|
|
|
2024-01-18 15:41:43 +08:00
|
|
|
// set window background transparent
|
|
|
|
QPalette pal = palette();
|
|
|
|
pal.setBrush(QPalette::Base, Qt::transparent);
|
|
|
|
setPalette(pal);
|
|
|
|
setAttribute(Qt::WA_TranslucentBackground, true);
|
|
|
|
|
|
|
|
// set list no scroll bar
|
|
|
|
ui->listWidget->horizontalScrollBar()->hide();
|
|
|
|
ui->listWidget->verticalScrollBar()->hide();
|
|
|
|
ui->listWidget->hide();
|
|
|
|
|
|
|
|
// serial port
|
|
|
|
initSerialPort();
|
|
|
|
|
|
|
|
// init command map
|
|
|
|
initCommandMap();
|
2024-01-25 09:57:08 +08:00
|
|
|
|
|
|
|
// get playback position each 0.5s
|
|
|
|
progressTimer = new QTimer();
|
|
|
|
progressTimer->setInterval(500);
|
|
|
|
connect(progressTimer, SIGNAL(timeout()), this, SLOT(onProgressTimeout()));
|
|
|
|
|
|
|
|
for (Channel* chn : channelList) {
|
|
|
|
connect(chn, SIGNAL(playEnd()), this, SLOT(onPlayEnd()));
|
|
|
|
connect(chn, SIGNAL(signalInputed(QString, int, int)), this, SLOT(onSignalInputed(QString, int, int)));
|
|
|
|
}
|
2024-01-18 15:41:43 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
Widget::~Widget()
|
|
|
|
{
|
|
|
|
serialPort->close();
|
|
|
|
delete ui;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief open serial port and link the signals and slots
|
|
|
|
*/
|
|
|
|
void Widget::initSerialPort()
|
|
|
|
{
|
|
|
|
// timer used to reopen serial port
|
|
|
|
timer = new QTimer();
|
2024-01-25 09:57:08 +08:00
|
|
|
timer->setInterval(3000);
|
2024-01-18 15:41:43 +08:00
|
|
|
timer->stop();
|
|
|
|
|
|
|
|
// serialport
|
|
|
|
serialPort = new QSerialPort();
|
|
|
|
serialPort->setPortName("ttyAMA2");
|
|
|
|
serialPort->setBaudRate(QSerialPort::Baud115200);
|
|
|
|
serialPort->setDataBits(QSerialPort::Data8);
|
|
|
|
serialPort->setParity(QSerialPort::NoParity);
|
|
|
|
serialPort->setStopBits(QSerialPort::OneStop);
|
|
|
|
serialPort->setFlowControl(QSerialPort::NoFlowControl);
|
|
|
|
if (serialPort->open(QIODevice::ReadWrite)) {
|
|
|
|
qDebug() << "open serial port: /dev/ttyAMA2 success";
|
|
|
|
} else {
|
|
|
|
qDebug() << "open serial port: /dev/ttyAMA2 failed, ready to retry...";
|
|
|
|
timer->start();
|
|
|
|
}
|
|
|
|
connect(serialPort, SIGNAL(error(QSerialPort::SerialPortError)), this, SLOT(onSerialError(QSerialPort::SerialPortError)));
|
|
|
|
connect(serialPort, SIGNAL(readyRead()), this, SLOT(onReadyRead()));
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief get the video list of current channel, and show
|
|
|
|
*/
|
|
|
|
void Widget::showPlayList()
|
|
|
|
{
|
|
|
|
// find the videos in dictionary "/root/usb/video"
|
2024-01-25 09:57:08 +08:00
|
|
|
QString dirPath = QString("%1/%2").arg(VideoPath).arg(curSelectChannel);
|
|
|
|
QStringList files = this->getFileList(dirPath);
|
2024-01-18 15:41:43 +08:00
|
|
|
|
|
|
|
ui->listWidget->clear();
|
|
|
|
// append fileList to qlistwidget and show
|
2024-01-25 09:57:08 +08:00
|
|
|
for (QString& file : files) {
|
2024-01-18 15:41:43 +08:00
|
|
|
QListWidgetItem* item = new QListWidgetItem(file);
|
|
|
|
ui->listWidget->addItem(item);
|
|
|
|
}
|
|
|
|
ui->listWidget->show();
|
|
|
|
ui->listWidget->setCurrentRow(0);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief try to reopen serial port
|
|
|
|
*/
|
|
|
|
void Widget::onTimeout()
|
|
|
|
{
|
|
|
|
timer->stop();
|
|
|
|
bool ret = serialPort->open(QIODevice::ReadWrite);
|
|
|
|
// if open failed, then start timer and reopen
|
|
|
|
if (!ret) {
|
|
|
|
qDebug() << "reopen serial port: /dev/ttyAMA2 success";
|
|
|
|
timer->start();
|
|
|
|
} else {
|
|
|
|
qDebug() << "reopen serial port: /dev/ttyAMA2 failed, ready to retry...";
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2024-01-25 09:57:08 +08:00
|
|
|
void Widget::onProgressTimeout()
|
|
|
|
{
|
|
|
|
Channel* chn = Config::findChannelByName(curSelectChannel);
|
|
|
|
int pos = chn->file->invoke("getPosition").toInt() / 1000;
|
|
|
|
progressBar->setCurrent(pos);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief call it when input hdmi signal
|
|
|
|
* @param name
|
|
|
|
* @param width
|
|
|
|
* @param height
|
|
|
|
*/
|
|
|
|
void Widget::onSignalInputed(QString name, int width, int height)
|
|
|
|
{
|
|
|
|
if (name == "HDMI-A") {
|
|
|
|
this->setFixedSize(QSize(width, height));
|
|
|
|
qDebug() << QString("set windows size: %1x%2").arg(width).arg(height);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2024-01-18 15:41:43 +08:00
|
|
|
/**
|
|
|
|
* @brief handling error
|
|
|
|
* @param error
|
|
|
|
*/
|
|
|
|
void Widget::onSerialError(QSerialPort::SerialPortError error)
|
|
|
|
{
|
|
|
|
if (error == QSerialPort::ResourceError) {
|
|
|
|
qDebug() << "serial port break, try to reopen";
|
|
|
|
serialPort->close();
|
|
|
|
timer->start();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief map command from string to int
|
|
|
|
*/
|
|
|
|
void Widget::initCommandMap()
|
|
|
|
{
|
|
|
|
commandMap.insert("A1", Playback);
|
|
|
|
commandMap.insert("A2", Next);
|
|
|
|
commandMap.insert("A3", Previous);
|
|
|
|
commandMap.insert("A4", Forward);
|
|
|
|
commandMap.insert("A5", Back);
|
|
|
|
commandMap.insert("A6", Pause);
|
|
|
|
commandMap.insert("A7", Return);
|
|
|
|
commandMap.insert("A8", Enter);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief receive data from serial port, and handle it
|
|
|
|
*/
|
|
|
|
void Widget::onReadyRead()
|
|
|
|
{
|
|
|
|
serialPort->waitForReadyRead(100);
|
|
|
|
QString data = serialPort->readLine();
|
|
|
|
if (!commandMap.contains(data)) {
|
|
|
|
qDebug() << QString("receive unkown command %1 from serial port: /dev/ttyAMA2").arg(data);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
Command cmd = commandMap.value(data);
|
|
|
|
switch (cmd) {
|
|
|
|
case Playback: {
|
|
|
|
if (menu->isVisible())
|
|
|
|
return;
|
|
|
|
menu->show();
|
|
|
|
}
|
|
|
|
case Previous: {
|
|
|
|
// if show menu, then switch menu select
|
|
|
|
if (menu->isVisible()) {
|
|
|
|
menu->setCurChannel("HDMI-A");
|
|
|
|
}
|
|
|
|
// if menu hide, then select previous of listwidget
|
|
|
|
else {
|
|
|
|
int curRow = ui->listWidget->currentRow();
|
|
|
|
if (curRow == 0)
|
|
|
|
curRow = ui->listWidget->count();
|
|
|
|
ui->listWidget->setCurrentRow(curRow - 1);
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case Next: {
|
|
|
|
if (menu->isVisible()) {
|
|
|
|
menu->setCurChannel("HDMI-B");
|
|
|
|
} else {
|
|
|
|
int curRow = ui->listWidget->currentRow();
|
|
|
|
if (curRow == ui->listWidget->count() - 1) {
|
|
|
|
curRow = -1;
|
|
|
|
}
|
|
|
|
ui->listWidget->setCurrentRow(curRow + 1);
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case Forward:
|
|
|
|
if (isPlayback) {
|
2024-01-25 09:57:08 +08:00
|
|
|
Channel* chn = Config::findChannelByName(curSelectChannel);
|
2024-01-18 15:41:43 +08:00
|
|
|
chn->forward();
|
2024-01-25 09:57:08 +08:00
|
|
|
progressBar->showMax();
|
2024-01-18 15:41:43 +08:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
case Back:
|
|
|
|
if (isPlayback) {
|
2024-01-25 09:57:08 +08:00
|
|
|
Channel* chn = Config::findChannelByName(curSelectChannel);
|
2024-01-18 15:41:43 +08:00
|
|
|
chn->back();
|
2024-01-25 09:57:08 +08:00
|
|
|
progressBar->showMax();
|
2024-01-18 15:41:43 +08:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
case Pause:
|
|
|
|
if (isPlayback) {
|
2024-01-25 09:57:08 +08:00
|
|
|
Channel* chn = Config::findChannelByName(curSelectChannel);
|
2024-01-18 15:41:43 +08:00
|
|
|
chn->togglePause();
|
2024-01-25 09:57:08 +08:00
|
|
|
progressBar->showMax();
|
|
|
|
if (chn->isPause) {
|
|
|
|
progressBar->setState(ProgressBar::Pause);
|
|
|
|
} else {
|
|
|
|
progressBar->setState(ProgressBar::Play);
|
|
|
|
}
|
2024-01-18 15:41:43 +08:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
case Enter:
|
|
|
|
// if menu show, then hide menu and show play list
|
|
|
|
if (menu->isVisible()) {
|
2024-01-25 09:57:08 +08:00
|
|
|
curSelectChannel = menu->getCurChannel();
|
2024-01-18 15:41:43 +08:00
|
|
|
menu->hide();
|
|
|
|
showPlayList();
|
2024-01-19 09:04:21 +08:00
|
|
|
} else {
|
|
|
|
// if list widget show, then current channel playback and other channel play live
|
|
|
|
if (ui->listWidget->isVisible()) {
|
2024-01-25 09:57:08 +08:00
|
|
|
if (ui->listWidget->count() == 0)
|
|
|
|
return;
|
2024-01-19 09:04:21 +08:00
|
|
|
QString fileName = ui->listWidget->currentItem()->text();
|
|
|
|
Channel* channel = nullptr;
|
|
|
|
for (int i = 0; i < channelList.count(); i++) {
|
2024-01-25 09:57:08 +08:00
|
|
|
if (channelList.at(i)->channelName == curSelectChannel) {
|
2024-01-19 09:04:21 +08:00
|
|
|
channel = channelList.at(i);
|
|
|
|
}
|
|
|
|
if (channelList.at(i)->isPlayback) {
|
|
|
|
channelList.at(i)->startPlayLive();
|
|
|
|
}
|
2024-01-18 15:41:43 +08:00
|
|
|
}
|
2024-01-19 09:04:21 +08:00
|
|
|
if (channel) {
|
2024-01-25 09:57:08 +08:00
|
|
|
// play back and output hdmi
|
2024-01-19 09:04:21 +08:00
|
|
|
channel->startPlayback(fileName);
|
|
|
|
isPlayback = true;
|
2024-01-25 09:57:08 +08:00
|
|
|
|
|
|
|
// only show progressbar in HDMI-A(HDMI-OUT0)
|
|
|
|
if (channel->channelName == "HDMI-A") {
|
|
|
|
// show progress bar maximize
|
|
|
|
int duration = channel->getDuration(fileName) / 1000;
|
|
|
|
progressBar->setDuration(duration);
|
|
|
|
progressBar->setCurrent(0);
|
|
|
|
progressBar->show();
|
|
|
|
progressBar->showMax();
|
|
|
|
progressBar->setState(ProgressBar::Play);
|
|
|
|
// if timer is active, then restart timer
|
|
|
|
if (progressTimer->isActive()) {
|
|
|
|
progressTimer->stop();
|
|
|
|
progressTimer->start();
|
|
|
|
} else {
|
|
|
|
progressTimer->start();
|
|
|
|
}
|
|
|
|
curPlayChannel = curSelectChannel;
|
|
|
|
curFileName = fileName;
|
|
|
|
QString dirPath = QString("%1/%2").arg(VideoPath).arg(curPlayChannel);
|
|
|
|
fileList = this->getFileList(dirPath);
|
|
|
|
}
|
2024-01-18 15:41:43 +08:00
|
|
|
}
|
2024-01-25 09:57:08 +08:00
|
|
|
// ui->listWidget->hide();
|
2024-01-18 15:41:43 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case Return:
|
|
|
|
if (menu->isVisible()) {
|
|
|
|
menu->hide();
|
|
|
|
}
|
2024-01-25 09:57:08 +08:00
|
|
|
if (isPlayback && !ui->listWidget->isVisible()) {
|
|
|
|
Channel* chn = Config::findChannelByName(curSelectChannel);
|
2024-01-18 15:41:43 +08:00
|
|
|
chn->startPlayLive();
|
2024-01-25 09:57:08 +08:00
|
|
|
progressBar->hide();
|
|
|
|
} else {
|
|
|
|
ui->listWidget->hide();
|
2024-01-18 15:41:43 +08:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
2024-01-25 09:57:08 +08:00
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief current play end and then play next video
|
|
|
|
*/
|
|
|
|
void Widget::onPlayEnd()
|
|
|
|
{
|
|
|
|
int index = fileList.indexOf(curFileName);
|
|
|
|
// cur video is last one of list, then refresh list
|
|
|
|
if (index == fileList.length() - 1) {
|
|
|
|
QString dirPath = QString("%1/%2").arg(VideoPath).arg(curPlayChannel);
|
|
|
|
this->getFileList(dirPath);
|
|
|
|
if (index == fileList.length() - 1) {
|
|
|
|
qDebug() << "no file to play";
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
qDebug() << "refresh current play file list";
|
|
|
|
}
|
|
|
|
|
|
|
|
curFileName = fileList.at(index + 1);
|
|
|
|
Channel* chn = Config::findChannelByName(curPlayChannel);
|
|
|
|
if (chn)
|
|
|
|
chn->startPlayback(curFileName);
|
|
|
|
}
|