RecordControlApplication/BoxController.cpp

278 lines
6.6 KiB
C++
Raw Normal View History

2024-01-18 15:41:43 +08:00
#include "BoxController.h"
#include <QProcess>
#include <QThread>
#include <QTime>
const char* path = "/root/usb";
BoxController::BoxController(QObject* parent)
: QObject(parent)
{
// init output in constructor;
videoOutput = Link::create("OutputVo");
QVariantMap dataVo;
dataVo["type"] = "hdmi";
dataVo["interface"] = "HDMI-OUT0";
videoOutput->setData(dataVo);
videoOutput->start();
// init video duration
videoDuration = 1 * 60 * 1000;
recordTimer = new QTimer();
recordTimer->setInterval(videoDuration);
recordTimer->stop();
connect(recordTimer, SIGNAL(timeout()), this, SLOT(onTimeout()));
// init record params
videoEncodeParams["codec"] = "h264";
videoEncodeParams["width"] = 1920;
videoEncodeParams["height"] = 1080;
videoEncodeParams["bitrate"] = 4000;
videoEncodeParams["framerate"] = 30;
audioEncodeParams["codec"] = "aac";
audioEncodeParams["samplerate"] = 48000;
audioEncodeParams["bitrate"] = 128000;
audioEncodeParams["channels"] = 1;
}
/**
* @brief initialize "Link" components
*/
void BoxController::init()
{
// audio input by external microphone
audioInput = Link::create("InputAlsa");
QVariantMap dataAi;
dataAi["path"] = "hw:0,0";
dataAi["channels"] = 2;
audioInput->start(dataAi);
// audio output by external speaker
audioOutput = Link::create("OutputAlsa");
QVariantMap dataAo;
dataAo["path"] = "hw:0,0";
audioOutput->start(dataAo);
videoInputA = Link::create("InputVi");
QVariantMap dataVi;
dataVi["interface"] = "HDMI-A";
videoInputA->start(dataVi);
// capture picture from video
snap = Link::create("EncodeV");
QVariantMap dataSnap;
dataSnap["codec"] = "jpeg";
dataSnap["snap"] = true;
dataSnap["width"] = videoEncodeParams.value("width");
dataSnap["height"] = videoEncodeParams.value("height");
snap->start(dataSnap);
videoInputA->linkV(snap);
// sleep 1s, if didnt sleep , function snap would return flase and capture failed
QThread::sleep(1);
videoInputA->linkV(videoOutput);
// video encode
videoEncoder = Link::create("EncodeV");
videoEncoder->start(videoEncodeParams);
// audio encode
audioEncoder = Link::create("EncodeA");
audioEncoder->start(audioEncodeParams);
// record
record = Link::create("Mux");
QVariantMap dataMp4;
dataMp4["format"] = "mp4";
dataMp4["mute"] = true;
record->setData(dataMp4);
videoInputA->linkV(videoEncoder)->linkV(record);
audioInput->linkA(audioEncoder)->linkA(record);
// rtmp server
rtmpServer = Link::create("Mux");
QVariantMap dataRtmp;
dataRtmp["path"] = "rtmp://127.0.0.1/live/stream";
dataRtmp["mute"] = true;
rtmpServer->setData(dataRtmp);
videoInputA->linkV(videoEncoder)->linkV(rtmpServer);
audioInput->linkA(audioEncoder)->linkA(rtmpServer);
// init file and decoder
file = Link::create("InputFile");
file->start();
videoDecoder = Link::create("DecodeV");
videoDecoder->start();
audioDecoder = Link::create("DecodeA");
audioDecoder->start();
file->linkV(videoDecoder)->linkV(videoOutput);
file->linkA(audioDecoder)->linkA(audioOutput);
connect(file, &LinkObject::newEvent, [=](QString type, QVariant) {
if (type == "EOF") {
qDebug() << "one video playback end";
}
});
}
/**
* @brief start record
*/
void BoxController::startRecord()
{
if (!isMountDisk()) {
return;
}
QString curTime = QDateTime::currentDateTime().toString("yyyy-MM-dd_hh:mm:ss");
QVariantMap dataRecord;
dataRecord["path"] = QString("%1/videos/%2.mp4").arg(path).arg(curTime);
record->setData(dataRecord);
record->start();
isRecord = true;
recordTimer->start();
snap->invoke("snapSync", QString("%1/snap/%2.jpg").arg(path).arg(curTime));
}
/**
* @brief stop record
*/
void BoxController::stopRecord()
{
record->stop(true);
isRecord = false;
recordTimer->stop();
}
/**
* @brief BoxController::onTimeout
*/
void BoxController::onTimeout()
{
if (!isMountDisk()) {
return;
}
record->stop(true);
recordTimer->stop();
QString curTime = QDateTime::currentDateTime().toString("yyyy-MM-dd_hh:mm:ss");
QVariantMap dataRecord;
dataRecord["path"] = QString("%1/videos/%2.mp4").arg(path).arg(curTime);
record->setData(dataRecord);
record->start();
recordTimer->start();
snap->invoke("snapSync", QString("%1/snap/%2.jpg").arg(path).arg(curTime));
}
void BoxController::startRtmpServer()
{
if (rtmpServer->getState() != "started") {
rtmpServer->start();
qDebug() << "start rtmp server...";
}
}
/**
* @brief open console process, and use it by command
* @param com
* @return
*/
QString BoxController::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 BoxController::isMountDisk()
{
QString mount = writeCom(QString("df %1").arg(path));
if (!mount.contains(path))
return false;
return true;
}
/**
* @brief start playback and output hdmi signals
* @param fileName
*/
void BoxController::startPlayback(QString fileName)
{
QString path = "/root/usb/videos/" + fileName;
videoInputA->unLinkV(videoOutput);
QVariantMap dataFile;
dataFile["path"] = path;
file->start(dataFile);
emit playListNeedHide();
}
/**
* @brief play live
*/
void BoxController::startPlayLive()
{
videoInputA->linkV(videoOutput);
file->stop(true);
emit playListNeedHide();
}
/**
* @brief playback -10s
*/
void BoxController::back()
{
qDebug() << "back";
int curPos = file->invoke("getPosition").toInt();
curPos -= 10 * 100;
file->invoke("seek", curPos);
}
/**
* @brief playback +10s
*/
void BoxController::forward()
{
qDebug() << "forward";
int curPos = file->invoke("getPosition").toInt();
curPos += 10 * 100;
file->invoke("seek", curPos);
}
/**
* @brief playback pause
*/
void BoxController::pause()
{
QString state = file->getState();
if (state != "started") {
return;
}
file->invoke("pause", true);
}
/**
* @brief playback resume
*/
void BoxController::resume()
{
QString state = file->getState();
if (state != "started") {
return;
}
file->invoke("pause", false);
}