#include "BoxController.h" #include #include #include 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); }