#include "Widget.h" #include "Channel.h" #include "Config.h" #include "TcpServer.h" #include "ui_Widget.h" #include #include #include extern char* VideoPath; extern QList channelList; extern Widget::Widget(QWidget* parent) : QWidget(parent) , ui(new Ui::Widget) { ui->setupUi(this); menu = new Menu(this); menu->hide(); progressBar = new ProgressBar(this); progressBar->hide(); // 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(); // 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))); } } 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(); timer->setInterval(3000); 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" QString dirPath = QString("%1/%2").arg(VideoPath).arg(curSelectChannel); QStringList files = this->getFileList(dirPath); ui->listWidget->clear(); // append fileList to qlistwidget and show for (QString& file : files) { 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..."; } } 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); } } /** * @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) { Channel* chn = Config::findChannelByName(curSelectChannel); chn->forward(); progressBar->showMax(); } break; case Back: if (isPlayback) { Channel* chn = Config::findChannelByName(curSelectChannel); chn->back(); progressBar->showMax(); } break; case Pause: if (isPlayback) { Channel* chn = Config::findChannelByName(curSelectChannel); chn->togglePause(); progressBar->showMax(); if (chn->isPause) { progressBar->setState(ProgressBar::Pause); } else { progressBar->setState(ProgressBar::Play); } } break; case Enter: // if menu show, then hide menu and show play list if (menu->isVisible()) { curSelectChannel = menu->getCurChannel(); menu->hide(); showPlayList(); } else { // if list widget show, then current channel playback and other channel play live if (ui->listWidget->isVisible()) { if (ui->listWidget->count() == 0) return; QString fileName = ui->listWidget->currentItem()->text(); Channel* channel = nullptr; for (int i = 0; i < channelList.count(); i++) { if (channelList.at(i)->channelName == curSelectChannel) { channel = channelList.at(i); } if (channelList.at(i)->isPlayback) { channelList.at(i)->startPlayLive(); } } if (channel) { // play back and output hdmi channel->startPlayback(fileName); isPlayback = true; // 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); } } // ui->listWidget->hide(); } } break; case Return: if (menu->isVisible()) { menu->hide(); } if (isPlayback && !ui->listWidget->isVisible()) { Channel* chn = Config::findChannelByName(curSelectChannel); chn->startPlayLive(); progressBar->hide(); } else { ui->listWidget->hide(); } break; default: break; } } /** * @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); }