基本的原理就是通过截屏,然后opencv合成avi视频
screenthread.h
线程
#pragma once
#include <QThread>
#include "recordscreen/recordscreen.h"
class ScreenThread :public QThread {
public:
void ScreenThread::run()
{
RecordScreen* record = new RecordScreen;
record->screenStart();
exec();
}
ScreenThread::~ScreenThread()
{
if (record)
{
delete record;
record = NULL;
}
}
private:
RecordScreen* record =NULL;
};
mainwindow主函数调用,可以通过按钮等
/**
*录屏
*/
void MainWindow::recordScreen()
{
if (!record)
{
record = new ScreenThread;
}
record->start();
statusBar()->showMessage(QStringLiteral("开始录屏"));
}
/**
* 结束录屏实际做转换视频操作
*/
void MainWindow::endRecordScreen()
{
if (record)
{
record->quit();
//delete record;
record = NULL;
}
QDesktopWidget *desktop = QApplication::desktop();
int width = desktop->width();
int height = desktop->height();
QString path = QDir::currentPath();//当前工作路径
QString videopath = path + "/images/screenVideo/";
QDir dir(videopath);
String cou = std::to_string(dir.count() - 1);
String videoNamePath = "images/screenVideo/Videotest" + cou + ".avi";
VideoWriter video(videoNamePath, CV_FOURCC('X', 'V', 'I', 'D'), 5.0/*27.0*/, Size(width, height));
String img_path = "D:\\photoscreen\\";
vector<String> img;
if (!dir.exists()) {
bool ok = dir.mkdir(videopath);//只创建一级子目录,即必须保证上级目录存在
//return ;
}
dir.setFilter(QDir::Files);
QString photopath =path+ "/images/photoscreen/";
QDir *pdir = new QDir(photopath);
QStringList filter2;
filter2 << "*.png";
pdir->setNameFilters(filter2); //过滤文件类型
QList<QFileInfo> *fileInfo = new QList<QFileInfo>(pdir->entryInfoList(filter2));
int count = fileInfo->count(); //文件个数
//glob(img_path, img, false);
//size_t count = img.size();
//size_t count = 80;
for (size_t i = 0; i < count; i++)
{
stringstream str;
str << i << ".png";
string tem = photopath.toStdString() + str.str();
Mat image = imread(photopath.toStdString() + str.str());
if (!image.empty())
{
cv::resize(image, image, Size(width, height));
video << image;
cout << "正在处理第" << i << "帧" << endl;
}
}
statusBar()->showMessage(QStringLiteral("录屏结束"));
}
/**
*回放
*/
void MainWindow::playback()
{
QDesktopWidget *desktop = QApplication::desktop();
QString path = QDir::currentPath();//当前工作路径
QString videopath = path + "/images/screenVideo/";
QDir dir(videopath);
QString cou = QString::number(dir.count() - 2);
QString videoNamePath = videopath + "Videotest" + cou + ".avi";
QMediaPlayer* mediaPlayer = new QMediaPlayer;
QRect desktopRect = QApplication::desktop()->availableGeometry();
mediaPlayer->setMedia(QUrl(videoNamePath));
QVideoWidget* videoWidget = new QVideoWidget;
mediaPlayer->setVideoOutput(videoWidget);
videoWidget->resize(desktop->width() - 10, desktop->height() - 80);
videoWidget->move((desktop->width() - videoWidget->width() - 10) / 2, (desktop->height() - videoWidget->height() - 70) / 2);
videoWidget->show();
mediaPlayer->play();
}
recordscreen.cpp
#include "recordscreen/recordscreen.h"
#include <QObject>
#include <QDesktopWidget>
#include <QtWidgets/QApplication>
RecordScreen::RecordScreen()
{
count = 0;
}
/**
* 开始录屏
*/
void RecordScreen::screenStart()
{
QString path = QDir::currentPath();//当前工作路径
path += "/images/photoscreen/";
QDir dir(path);
if (!dir.exists()) {
bool ok = dir.mkdir(path);//只创建一级子目录,即必须保证上级目录存在
//return ;
}
QStringList filter; //过滤器
filter.append("*");
QDirIterator it(path, filter, QDir::Files, QDirIterator::Subdirectories);
while (it.hasNext()) { //若容器中还有成员,继续执行删除操作
dir.remove(it.next());
}
time = new QTimer();
//time->setInterval(1);
connect(time,SIGNAL(timeout()),this,SLOT(shotScreen()));
//connect(time, &QTimer::timeout, this, [=] {
// shotScreen();
//});
time->start(10);
}
void RecordScreen::screenEnd()
{
time->stop();
}
**recordscreen.cpp**
/**
* 录屏保存为图片
*/
void RecordScreen::shotScreen()
{
int width = QApplication::desktop()->width();
int height = QApplication::desktop()->height();
QPixmap pix = QPixmap::grabWindow(QApplication::desktop()->winId(),0,0,width,height);
QString path = QDir::currentPath();//当前工作路径
path += "/images/photoscreen/";
count++;
QString fileName = QString::number(count);
QString format = ".png";
fileName = path + fileName + format;
bool ok = pix.save(fileName);
if (ok)
{
qDebug() << "save photo success";
}
else
{
qCritical() << "save photo unsuccess";
}
}
RecordScreen::~RecordScreen()
{
}
recordscreen.h
#ifndef RECORD_SCREEN_H
#define RECORD_SCREEN_H
#include <QtGui>
#include <QTime>
#include <QWidget>
class RecordScreen:public QObject {
Q_OBJECT
public:
RecordScreen();
~RecordScreen();
void screenStart();
void screenEnd();
public slots:
void shotScreen();
private:
int count;
QTimer* time;
};
#endif // !RECORD_SCREEN_H