整体框架:
屏幕录制、声音录制、音视频合成分别在不同的子线程中运行,由主程序控制录制的开始和结束。控制流程如下图所示:
主线程:点击开始按钮à打开音频设备、视频设备、输出文件、启动子线程à发送开始录制信号;
子线程:收到开始信号à开始录制;
主线程:点击结束按钮à发送结束信号;
子线程:接收到结束信号à发送结束信号;
主线程:已经接收到了所有子线程发来的结束信号à处理结束事项并清理资源。
主要代码:
主线程:screenrecord.h
/**
* 录屏主控类
*/
#ifndef SCREENRECORD_H
#define SCREENRECORD_H
/**QT header**/
#include <QFont>
#include <QLabel>
#include <QMutex>
#include <QDebug>
#include <QWidget>
#include <QThread>
#include <QLineEdit>
#include <QFileInfo>
#include <QPaintEvent>
#include <QPushButton>
#include <QCameraInfo>
#include <QMessageBox>
#include <QStandardPaths>
#include <QAudioDeviceInfo>
#include "myglobals.h"
#include "muxerprocess.h"
#include "screencaptureprocess.h"
#include "audiocaptureprocess.h"
class ScreenRecord : public QWidget
{
Q_OBJECT
public:
explicit ScreenRecord(QWidget *parent = nullptr);
~ScreenRecord();
public:
QMutex mutex;
/*状态*/
bool screenCapturing;
bool audioCapturing;
bool muxing;
/*合并音视频的线程及程序*/
QThread muxerThread;
MuxerProcess *muxerProcess;
/*抓取屏幕的线程及程序*/
QThread screenCaptureThread;
ScreenCaptureProcess *screenCaptureProcess;
/*录制声音的线程及程序*/
QThread audioCaptureThread;
AudioCaptureProcess *audioCaptureProcess;
/*开始及结束录屏的按钮*/
QPushButton *startButton;
/*转换后的视频帧尺寸(由用户设置,宽度必须是4的整数倍)*/
int outputWidth;
int outputHeight;
/*视频输出路径/文件名称/文件类型*/
QString outputDirectory;
QString outputFilename;
QString outputFileType;
/*********控件***********/
//视频输出路径
QLabel *outputDirLabel;
QLineEdit *outputDirEdit;
QPushButton *outputDirButton;
/*********控件***********/
public slots:
void replyButtonPressed();
void replyScreenCapturingFinished();
void replyAudioCapturingFinished();
void replyMuxingFinished();
signals:
void startRecord(); //开始录屏信号
void stopRecord(); //结束录屏信号
public:
/**
* @brief 打开屏幕抓取设备(gdigrab)
* @return
* 0 -- success,else error code
*
*/
int openScreenCaptureDevice();
/**
* @brief 打开声音抓取设备(dshow)
* @return
* 0 -- success,else error code
*
*/
int openAudioCaptureDevice();
/*打开输出视频文件*/
int openOutput();
/*获取电脑内置的声音设备*/
QString getSpeakerDeviceName();
/*释放全局资源*/
void releaseGlobals();
/*结束所有子线程*/
void stopChildThreads();
/*开始所有的子线程*/
void startChildThreads();
protected:
void paintEvent(QPaintEvent *event);
};
#endif // SCREENRECORD_H
主线程:screenrecord.cpp
#include "screenc