修改视频录制的文件名以及录制起点
This commit is contained in:
parent
a1771c5404
commit
b6215897df
50
Channel.cpp
50
Channel.cpp
@ -26,8 +26,6 @@ Channel::Channel(QObject* parent)
|
|||||||
audioEncoder = nullptr;
|
audioEncoder = nullptr;
|
||||||
record = nullptr;
|
record = nullptr;
|
||||||
rtsp = nullptr;
|
rtsp = nullptr;
|
||||||
snap = Link::create("EncodeV");
|
|
||||||
overlay = Link::create("Overlay");
|
|
||||||
file = nullptr;
|
file = nullptr;
|
||||||
videoDecoder = nullptr;
|
videoDecoder = nullptr;
|
||||||
audioDecoder = nullptr;
|
audioDecoder = nullptr;
|
||||||
@ -76,37 +74,7 @@ void Channel::init()
|
|||||||
dataVi["width"] = 1920;
|
dataVi["width"] = 1920;
|
||||||
dataVi["height"] = 1080;
|
dataVi["height"] = 1080;
|
||||||
videoInput->start(dataVi);
|
videoInput->start(dataVi);
|
||||||
|
videoInput->linkV(videoOutput);
|
||||||
// 测试水印
|
|
||||||
QVariantMap dataOver;
|
|
||||||
QVariantList lays;
|
|
||||||
QVariantMap lay;
|
|
||||||
lay["type"] = "time";
|
|
||||||
lay["enable"] = true;
|
|
||||||
lay["font"] = "/link/res/font.ttf";
|
|
||||||
lay["content"] = "yyyy年MM月dd日 hh:mm:ss";
|
|
||||||
lay["x"] = 0.1;
|
|
||||||
lay["y"] = 0.5;
|
|
||||||
lay["scale"] = 2;
|
|
||||||
lay["color"] = "#ffffff";
|
|
||||||
lay["alpha"] = 1;
|
|
||||||
lays << lay;
|
|
||||||
dataOver["lays"] = lays;
|
|
||||||
overlay->start(dataOver);
|
|
||||||
videoInput->linkV(overlay)->linkV(videoOutput);
|
|
||||||
|
|
||||||
// videoInput->linkV(videoOutput);
|
|
||||||
|
|
||||||
// 截图
|
|
||||||
QVariantMap dataSnap;
|
|
||||||
dataSnap["codec"] = "jpeg";
|
|
||||||
dataSnap["snap"] = true;
|
|
||||||
dataSnap["width"] = 1920;
|
|
||||||
dataSnap["height"] = 1080;
|
|
||||||
snap->start(dataSnap);
|
|
||||||
videoInput->linkV(snap);
|
|
||||||
// 等待1秒,防止截图失败
|
|
||||||
QThread::sleep(1);
|
|
||||||
|
|
||||||
// 视频编码
|
// 视频编码
|
||||||
videoEncoder = Link::create("EncodeV");
|
videoEncoder = Link::create("EncodeV");
|
||||||
@ -120,7 +88,8 @@ void Channel::init()
|
|||||||
record = Link::create("Mux");
|
record = Link::create("Mux");
|
||||||
QVariantMap dataMp4;
|
QVariantMap dataMp4;
|
||||||
dataMp4["format"] = "mp4";
|
dataMp4["format"] = "mp4";
|
||||||
dataMp4["lowLatency"] = true;
|
// dataMp4["lowLatency"] = true;
|
||||||
|
// dataMp4["filecache"] = 20480000;
|
||||||
record->setData(dataMp4);
|
record->setData(dataMp4);
|
||||||
videoInput->linkV(videoEncoder)->linkV(record);
|
videoInput->linkV(videoEncoder)->linkV(record);
|
||||||
audioInput->linkA(audioEncoder)->linkA(record);
|
audioInput->linkA(audioEncoder)->linkA(record);
|
||||||
@ -163,13 +132,12 @@ void Channel::init()
|
|||||||
*/
|
*/
|
||||||
void Channel::onTimeout()
|
void Channel::onTimeout()
|
||||||
{
|
{
|
||||||
QString curTime = QDateTime::currentDateTime().toString("yyyy-MM-dd_hh:mm:ss");
|
while (int secs = QTime::currentTime().second() % 60 != 0) {
|
||||||
|
}
|
||||||
|
QString curTime = QDateTime::currentDateTime().toString("yyyyMMddhhmm");
|
||||||
QString path = QString("%1/%2/%3.mp4").arg(Constant::VideoPath).arg(channelName).arg(curTime);
|
QString path = QString("%1/%2/%3.mp4").arg(Constant::VideoPath).arg(channelName).arg(curTime);
|
||||||
// 重新分片
|
// 重新分片
|
||||||
record->invoke("segment", path);
|
record->invoke("segment", path);
|
||||||
|
|
||||||
// path = QString("%1/%2/%3.jpg").arg(Constant::SnapPath).arg(channelName).arg(curTime);
|
|
||||||
// snap->invoke("snapSync", path);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -181,8 +149,10 @@ void Channel::startRecord()
|
|||||||
Log::error("there are no disk mounted");
|
Log::error("there are no disk mounted");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
while (int secs = QTime::currentTime().second() % 60 != 0) {
|
||||||
|
}
|
||||||
|
|
||||||
QString curTime = QDateTime::currentDateTime().toString("yyyy-MM-dd_hh:mm:ss");
|
QString curTime = QDateTime::currentDateTime().toString("yyyyMMddhhmm");
|
||||||
QVariantMap dataRecord;
|
QVariantMap dataRecord;
|
||||||
QString path = QString("%1/%2/%3.mp4").arg(Constant::VideoPath).arg(channelName).arg(curTime);
|
QString path = QString("%1/%2/%3.mp4").arg(Constant::VideoPath).arg(channelName).arg(curTime);
|
||||||
dataRecord["path"] = path;
|
dataRecord["path"] = path;
|
||||||
@ -191,8 +161,6 @@ void Channel::startRecord()
|
|||||||
Log::info("{} start recording...", channelName.toStdString());
|
Log::info("{} start recording...", channelName.toStdString());
|
||||||
|
|
||||||
timer->start();
|
timer->start();
|
||||||
// path = QString("%1/%2/%3.jpg").arg(Constant::SnapPath).arg(channelName).arg(curTime);
|
|
||||||
// snap->invoke("snapSync", path);
|
|
||||||
emit showRecordState(true);
|
emit showRecordState(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -29,12 +29,9 @@ public:
|
|||||||
LinkObject* audioEncoder;
|
LinkObject* audioEncoder;
|
||||||
QVariantMap audioEncoderParams;
|
QVariantMap audioEncoderParams;
|
||||||
|
|
||||||
LinkObject* overlay;
|
|
||||||
|
|
||||||
LinkObject* record;
|
LinkObject* record;
|
||||||
LinkObject* snap;
|
|
||||||
// 单个视频时长
|
// 单个视频时长
|
||||||
int duration = 1 * 60 * 1000;
|
int duration = 10 * 60 * 1000;
|
||||||
bool isRecord = false;
|
bool isRecord = false;
|
||||||
|
|
||||||
LinkObject* file;
|
LinkObject* file;
|
||||||
|
@ -20,7 +20,7 @@ CheckStorageThread::CheckStorageThread()
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief check available storage each 10 min
|
* @brief 10分钟检查一次外接硬盘的可用空间
|
||||||
*/
|
*/
|
||||||
void CheckStorageThread::run()
|
void CheckStorageThread::run()
|
||||||
{
|
{
|
||||||
@ -28,12 +28,11 @@ void CheckStorageThread::run()
|
|||||||
int64_t available = Tool::getAvailableStorage(Constant::MountedPath);
|
int64_t available = Tool::getAvailableStorage(Constant::MountedPath);
|
||||||
if (available < THRESHOLD) {
|
if (available < THRESHOLD) {
|
||||||
Log::info("there are not enough storage, then remove some files...");
|
Log::info("there are not enough storage, then remove some files...");
|
||||||
// get the file list
|
// 获取文件列表
|
||||||
QStringList fileList = Tool::getFileList(QString("%1/%2").arg(Constant::VideoPath).arg(Constant::MainChannel));
|
QStringList fileList = Tool::getFileList(QString("%1/%2").arg(Constant::VideoPath).arg(Constant::MainChannel));
|
||||||
if (!fileList.isEmpty()) {
|
if (!fileList.isEmpty()) {
|
||||||
// remove the first video file
|
|
||||||
QString filename = fileList.first();
|
QString filename = fileList.first();
|
||||||
// wait until file is not playing
|
// 判断文件是否再回放,如果在回放就阻塞等待
|
||||||
mutex.lock();
|
mutex.lock();
|
||||||
if (filename == curFilename) {
|
if (filename == curFilename) {
|
||||||
Log::info("{} is playing, wait for play end and remove the files...", filename.toStdString());
|
Log::info("{} is playing, wait for play end and remove the files...", filename.toStdString());
|
||||||
@ -41,7 +40,7 @@ void CheckStorageThread::run()
|
|||||||
Log::info("check thread end wait...");
|
Log::info("check thread end wait...");
|
||||||
}
|
}
|
||||||
mutex.unlock();
|
mutex.unlock();
|
||||||
// start remove file
|
// 删除文件
|
||||||
QString path = QString("%1/%2/%3").arg(Constant::VideoPath).arg(Constant::MainChannel).arg(filename);
|
QString path = QString("%1/%2/%3").arg(Constant::VideoPath).arg(Constant::MainChannel).arg(filename);
|
||||||
bool ret = Tool::removeFile(path);
|
bool ret = Tool::removeFile(path);
|
||||||
if (!ret) {
|
if (!ret) {
|
||||||
|
@ -19,7 +19,6 @@ public:
|
|||||||
static constexpr char* NetConfigPath = "/opt/RecordControlApplication/configuration/net.json";
|
static constexpr char* NetConfigPath = "/opt/RecordControlApplication/configuration/net.json";
|
||||||
static constexpr char* NetScriptPath = "/opt/RecordControlApplication/scripts/setNetwork.sh";
|
static constexpr char* NetScriptPath = "/opt/RecordControlApplication/scripts/setNetwork.sh";
|
||||||
static constexpr char* VideoPath = "/root/usb/videos";
|
static constexpr char* VideoPath = "/root/usb/videos";
|
||||||
static constexpr char* SnapPath = "/root/usb/snap";
|
|
||||||
static constexpr char* MountedPath = "/root/usb";
|
static constexpr char* MountedPath = "/root/usb";
|
||||||
static constexpr char* ErrorImagePath = "/opt/RecordControlApplication/images/error.jpeg";
|
static constexpr char* ErrorImagePath = "/opt/RecordControlApplication/images/error.jpeg";
|
||||||
static constexpr char* EmptyImagePath = "/opt/RecordControlApplication/images/empty.jpeg";
|
static constexpr char* EmptyImagePath = "/opt/RecordControlApplication/images/empty.jpeg";
|
||||||
|
@ -22,6 +22,7 @@ TcpController::TcpController(QObject* parent)
|
|||||||
routes.insert("get_name", std::bind(&TcpController::getName, this, std::placeholders::_1));
|
routes.insert("get_name", std::bind(&TcpController::getName, this, std::placeholders::_1));
|
||||||
routes.insert("set_record_mode", std::bind(&TcpController::setRecordMode, this, std::placeholders::_1));
|
routes.insert("set_record_mode", std::bind(&TcpController::setRecordMode, this, std::placeholders::_1));
|
||||||
routes.insert("set_playback_mode", std::bind(&TcpController::setPlaybackMode, this, std::placeholders::_1));
|
routes.insert("set_playback_mode", std::bind(&TcpController::setPlaybackMode, this, std::placeholders::_1));
|
||||||
|
routes.insert("reoot", std::bind(&TcpController::reboot, this, std::placeholders::_1));
|
||||||
}
|
}
|
||||||
|
|
||||||
Routes TcpController::getRoutes()
|
Routes TcpController::getRoutes()
|
||||||
@ -214,16 +215,10 @@ void TcpController::deleteFile(QTcpSocket* socket)
|
|||||||
QString snapName = fileName.split(".")[0] + ".jpg";
|
QString snapName = fileName.split(".")[0] + ".jpg";
|
||||||
|
|
||||||
QString filePath = QString("%1/%2/%3").arg(Constant::VideoPath).arg(interface).arg(fileName);
|
QString filePath = QString("%1/%2/%3").arg(Constant::VideoPath).arg(interface).arg(fileName);
|
||||||
QString snapPath = QString("%1/%2/%3").arg(Constant::SnapPath).arg(interface).arg(fileName);
|
|
||||||
QFile video(filePath);
|
QFile video(filePath);
|
||||||
if (video.exists()) {
|
if (video.exists()) {
|
||||||
video.remove();
|
video.remove();
|
||||||
Log::info("remove video {}", filePath.toStdString());
|
Log::info("remove video {}", filePath.toStdString());
|
||||||
QFile image(snapPath);
|
|
||||||
if (image.exists()) {
|
|
||||||
image.remove();
|
|
||||||
Log::info("remove image: {}", snapPath.toStdString());
|
|
||||||
}
|
|
||||||
socket->write("url=delete_file\r\nstatus=success");
|
socket->write("url=delete_file\r\nstatus=success");
|
||||||
} else {
|
} else {
|
||||||
Log::error("error, file: {} dont exist", filePath.toStdString());
|
Log::error("error, file: {} dont exist", filePath.toStdString());
|
||||||
@ -288,3 +283,20 @@ void TcpController::setPlaybackMode(QTcpSocket* socket)
|
|||||||
Json::saveFile(cfg, Constant::ConfigurationPath);
|
Json::saveFile(cfg, Constant::ConfigurationPath);
|
||||||
socket->write("url=set_playback_mode\r\nstatus=success");
|
socket->write("url=set_playback_mode\r\nstatus=success");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 重启程序
|
||||||
|
* @param socket
|
||||||
|
*/
|
||||||
|
void TcpController::reboot(QTcpSocket* socket)
|
||||||
|
{
|
||||||
|
// 先停止所有的录制
|
||||||
|
for (Channel* chn : channelList) {
|
||||||
|
chn->stopRecord();
|
||||||
|
}
|
||||||
|
socket->write("url=reboot\r\nstatus=success");
|
||||||
|
socket->flush();
|
||||||
|
|
||||||
|
// 退出程序,等待后台运行的shell脚本重启程序
|
||||||
|
exit(0);
|
||||||
|
}
|
@ -31,6 +31,8 @@ private:
|
|||||||
void setRecordMode(QTcpSocket* socket);
|
void setRecordMode(QTcpSocket* socket);
|
||||||
void setPlaybackMode(QTcpSocket* socket);
|
void setPlaybackMode(QTcpSocket* socket);
|
||||||
|
|
||||||
|
void reboot(QTcpSocket* socket);
|
||||||
|
|
||||||
inline QVariantMap parseParams(QTcpSocket* socket);
|
inline QVariantMap parseParams(QTcpSocket* socket);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
18
Tool.cpp
18
Tool.cpp
@ -13,7 +13,7 @@ Tool::Tool()
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief get file list of
|
* @brief 获取文件列表
|
||||||
*/
|
*/
|
||||||
QStringList Tool::getFileList(QString path)
|
QStringList Tool::getFileList(QString path)
|
||||||
{
|
{
|
||||||
@ -33,7 +33,7 @@ QStringList Tool::getFileList(QString path)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief remove file or dir
|
* @brief 删除文件或文件夹
|
||||||
*/
|
*/
|
||||||
bool Tool::removeFile(QString path)
|
bool Tool::removeFile(QString path)
|
||||||
{
|
{
|
||||||
@ -58,7 +58,8 @@ bool Tool::removeFile(QString path)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief call linux shell tool
|
* @brief 另外开启一个进程,使用linux命令行工具
|
||||||
|
* @param path 命令
|
||||||
*/
|
*/
|
||||||
#ifdef Q_OS_UNIX
|
#ifdef Q_OS_UNIX
|
||||||
QString Tool::writeCom(QString path)
|
QString Tool::writeCom(QString path)
|
||||||
@ -67,10 +68,10 @@ QString Tool::writeCom(QString path)
|
|||||||
QStringList argList;
|
QStringList argList;
|
||||||
argList << "-c" << path;
|
argList << "-c" << path;
|
||||||
proc.start("/bin/sh", argList);
|
proc.start("/bin/sh", argList);
|
||||||
// wait process start
|
// 等待进程启动
|
||||||
proc.waitForFinished();
|
proc.waitForFinished();
|
||||||
proc.waitForReadyRead();
|
proc.waitForReadyRead();
|
||||||
// read data from console
|
// 从控制台读取数据
|
||||||
QByteArray procOutput = proc.readAll();
|
QByteArray procOutput = proc.readAll();
|
||||||
proc.close();
|
proc.close();
|
||||||
return QString(procOutput);
|
return QString(procOutput);
|
||||||
@ -78,14 +79,15 @@ QString Tool::writeCom(QString path)
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* get available storage of disk
|
* @brief 获取磁盘的可用空间
|
||||||
|
* @param mountedPath 磁盘挂载位置
|
||||||
*/
|
*/
|
||||||
int64_t Tool::getAvailableStorage(QString mountedPath)
|
int64_t Tool::getAvailableStorage(QString mountedPath)
|
||||||
{
|
{
|
||||||
#ifdef Q_OS_UNIX
|
#ifdef Q_OS_UNIX
|
||||||
// get the available size of disk
|
// 使用linux命令获取磁盘挂载信息
|
||||||
QString mountInfo = writeCom(QString("df %1").arg(mountedPath));
|
QString mountInfo = writeCom(QString("df %1").arg(mountedPath));
|
||||||
// parse the string like
|
// 解析挂载信息获取可用磁盘大侠
|
||||||
// "Filesystem 1K-blocks Used Available Use% Mounted on\n/dev/sda 487110880 45112 462630056 0% /root/usb\n"
|
// "Filesystem 1K-blocks Used Available Use% Mounted on\n/dev/sda 487110880 45112 462630056 0% /root/usb\n"
|
||||||
QString diskInfo = mountInfo.split("\n")[1];
|
QString diskInfo = mountInfo.split("\n")[1];
|
||||||
QStringList list = diskInfo.split(" ");
|
QStringList list = diskInfo.split(" ");
|
||||||
|
3
main.cpp
3
main.cpp
@ -154,7 +154,8 @@ int main(int argc, char* argv[])
|
|||||||
|
|
||||||
// 硬盘检测线程,检测硬盘容量
|
// 硬盘检测线程,检测硬盘容量
|
||||||
CheckStorageThread* thread = new CheckStorageThread();
|
CheckStorageThread* thread = new CheckStorageThread();
|
||||||
// thread->start();
|
thread->start();
|
||||||
|
Log::info("start storage check thread...");
|
||||||
|
|
||||||
return a.exec();
|
return a.exec();
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user