RecordControlApplication/Channel.cpp

284 lines
6.7 KiB
C++
Raw Normal View History

2024-01-18 15:41:43 +08:00
#include "Channel.h"
#include <QProcess>
#include <QTime>
LinkObject* Channel::audioInput = nullptr;
LinkObject* Channel::audioOutput = nullptr;
LinkObject* Channel::rtspServer = nullptr;
LinkObject* Channel::file = nullptr;
LinkObject* Channel::audioDecoder = nullptr;
LinkObject* Channel::videoDecoder = nullptr;
extern LinkObject* vo;
extern LinkObject* vo1;
const char* VideoPath = "/root/usb/videos";
const char* SnapPath = "/root/usb/snap";
Channel::Channel(QObject* parent)
: QObject(parent)
{
timer = new QTimer();
timer->setInterval(duration);
timer->stop();
videoInput = nullptr;
videoOutput = nullptr;
2024-01-19 09:04:21 +08:00
videoEncoder = nullptr;
2024-01-18 15:41:43 +08:00
audioEncoder = nullptr;
record = nullptr;
rtsp = nullptr;
snap = Link::create("EncodeV");
overLay = Link::create("Overlay");
if (audioInput == nullptr) {
audioInput = Link::create("InputAlsa");
QVariantMap dataIn;
dataIn["path"] = "hw:0,0";
2024-01-19 09:04:21 +08:00
2024-01-18 15:41:43 +08:00
audioInput->start(dataIn);
}
if (audioOutput == nullptr) {
audioOutput = Link::create("OutputAlsa");
QVariantMap dataOut;
dataOut["path"] = "hw:0,0";
audioOutput->start(dataOut);
}
if (rtspServer == nullptr) {
rtspServer = Link::create("Rtsp");
rtspServer->start();
}
if (file == nullptr) {
file = Link::create("InputFile");
// one video playback end
connect(file, &LinkObject::newEvent, [=](QString type, QVariant) {
if (type == "EOF") {
qDebug() << "one video playback end";
}
});
}
if (audioDecoder == nullptr) {
audioDecoder = Link::create("DecodeA");
audioDecoder->start();
file->linkA(audioDecoder)->linkA(audioOutput);
}
if (videoDecoder == nullptr) {
videoDecoder = Link::create("DecodeV");
videoDecoder->start();
file->linkV(videoDecoder);
}
connect(timer, SIGNAL(timeout()), this, SLOT(onTimeout()));
}
/**
* @brief load configuration and init components
*/
void Channel::init()
{
if (channelName.isEmpty()) {
qDebug() << "channel name is empty!";
return;
}
if (channelName == "HDMI-A") {
videoOutput = vo;
} else {
videoOutput = vo1;
}
// init video input by channel name
videoInput = Link::create("InputVi");
QVariantMap dataVi;
dataVi["interface"] = channelName;
videoInput->start(dataVi);
// start water mask
2024-01-19 09:04:21 +08:00
// overLay->start();
2024-01-18 15:41:43 +08:00
// link video input and output, and add water mask
2024-01-19 09:04:21 +08:00
videoInput->linkV(videoOutput);
2024-01-18 15:41:43 +08:00
// capture picture from video
QVariantMap dataSnap;
dataSnap["codec"] = "jpeg";
dataSnap["snap"] = true;
dataSnap["width"] = 1920;
dataSnap["height"] = 1080;
snap->start(dataSnap);
videoInput->linkV(snap);
// sleep 1s, if didnt sleep , function snap would return flase and capture failed
QThread::sleep(1);
// video encode
videoEncoder = Link::create("EncodeV");
videoEncoder->start(videoEncoderParams);
// audio encode
audioEncoder = Link::create("EncodeA");
audioEncoder->start(audioEncoderParams);
// record
record = Link::create("Mux");
QVariantMap dataMp4;
dataMp4["format"] = "mp4";
record->setData(dataMp4);
videoInput->linkV(videoEncoder)->linkV(record);
audioInput->linkA(audioEncoder)->linkA(record);
// rtsp
rtsp = Link::create("Mux");
QVariantMap dataRtsp;
dataRtsp["path"] = QString("mem://%1").arg(pushCode);
dataRtsp["format"] = "rtsp";
rtsp->start(dataRtsp);
videoInput->linkV(videoEncoder)->linkV(rtsp)->linkV(rtspServer);
audioInput->linkA(audioEncoder)->linkA(rtsp)->linkA(rtspServer);
}
/**
* @brief end previous record and start new record
*/
void Channel::onTimeout()
{
record->stop(true);
timer->stop();
if (!isMountDisk()) {
return;
}
QString curTime = QDateTime::currentDateTime().toString("yyyy-MM-dd_hh:mm:ss");
QVariantMap dataRecord;
dataRecord["path"] = QString("%1/%2/%3.mp4").arg(VideoPath).arg(channelName).arg(curTime);
record->setData(dataRecord);
record->start();
timer->start();
snap->invoke("snapSync", QString("%1/%2/%3.jpg").arg(SnapPath).arg(channelName).arg(curTime));
}
/**
* @brief start record
*/
void Channel::startRecord()
{
if (!isMountDisk()) {
return;
}
QString curTime = QDateTime::currentDateTime().toString("yyyy-MM-dd_hh:mm:ss");
QVariantMap dataRecord;
// /usb/root/videos/HDMI-A/2024-1-1_10:00:00
dataRecord["path"] = QString("%1/%2/%3.mp4").arg(VideoPath).arg(channelName).arg(curTime);
record->setData(dataRecord);
record->start();
2024-01-19 09:04:21 +08:00
// setOverlay("Record");
2024-01-18 15:41:43 +08:00
timer->start();
snap->invoke("snapSync", QString("%1/%2/%3.jpg").arg(SnapPath).arg(channelName).arg(curTime));
}
/**
* @brief stop record
*/
void Channel::stopRecord()
{
record->stop(true);
2024-01-19 09:04:21 +08:00
// setOverlay("No Record");
2024-01-18 15:41:43 +08:00
timer->stop();
}
/**
* @brief start playback and output hdmi signals
* @param fileName
*/
void Channel::startPlayback(QString fileName)
{
QString path = QString("%1/%2/%3").arg(VideoPath).arg(channelName).arg(fileName);
// break video input and output
videoInput->unLinkV(videoOutput);
2024-01-19 09:04:21 +08:00
videoDecoder->linkV(videoOutput);
2024-01-18 15:41:43 +08:00
QVariantMap dataFile;
dataFile["path"] = path;
2024-01-19 09:04:21 +08:00
file->start(dataFile);
2024-01-18 15:41:43 +08:00
isPlayback = true;
}
2024-01-19 09:04:21 +08:00
/**
* @brief play live
*/
void Channel::startPlayLive()
{
videoDecoder->unLinkV(videoOutput);
file->stop(true);
videoInput->linkV(videoOutput);
isPlayback = false;
}
2024-01-18 15:41:43 +08:00
/**
* @brief playback -10s
*/
void Channel::back()
{
qDebug() << "back 10s";
int curPos = file->invoke("getPosition").toInt();
curPos -= 10 * 100;
file->invoke("seek", curPos);
}
/**
* @brief playback +10s
*/
void Channel::forward()
{
qDebug() << "forward 10s";
int curPos = file->invoke("getPosition").toInt();
curPos += 10 * 100;
file->invoke("seek", curPos);
}
/**
* @brief Channel::togglePause
*/
void Channel::togglePause()
{
isPause = !isPause;
file->invoke("pause", isPause);
}
/**
* @brief open console process, and use it by command
* @param com
* @return
*/
QString Channel::writeCom(const QString& com)
{
QProcess proc;
QStringList argList;
argList << "-c" << com;
proc.start("/bin/sh", argList);
// wait process start
proc.waitForFinished();
proc.waitForReadyRead();
// read data from console
QByteArray procOutput = proc.readAll();
proc.close();
return QString(procOutput);
}
/**
* @brief judge the disk whether mounted
* @return
*/
bool Channel::isMountDisk()
{
QString mount = writeCom("df /root/usb");
if (!mount.contains("/root/usb"))
return false;
return true;
}