專案實戰:Qt+FFmpeg錄屏應用(支援幀率、清晰度設定)

語言: CN / TW / HK

若該文為原創文章,轉載請註明原文出處 本文章部落格地址:http://blog.csdn.net/qq21497936/article/details/109827936 各位讀者,知識無窮而人力有窮,要麼改需求,要麼找專業人士,要麼自己研究 紅胖子(紅模仿)的博文大全:開發技術集合(包含Qt實用技術、樹莓派、三維、OpenCV、OpenGL、ffmpeg、OSG、微控制器、軟硬結合等等)持續更新中...(點選傳送門)

Qt開發專欄:專案實戰(點選傳送門)

<br>

需求

  實現錄屏功能。

<br>

原理

  使用抓屏模組按照指定範圍和幀率抓屏,同時使用錄影模組按照指定影象大小和幀率錄製。

<br>

Demo

  在這裡插入圖片描述   在這裡插入圖片描述   在這裡插入圖片描述

<br>

體驗下載地址

  CSDN:http://download.csdn.net/download/qq21497936/13126842   QQ群:1047134658(點選“檔案”搜尋“ffmpegRecord”,群內與博文同步更新)

<br>

v1.0.0

在這裡插入圖片描述 在這裡插入圖片描述 在這裡插入圖片描述

#ifndef RECORDWIDGET_H
#define RECORDWIDGET_H

#include <QWidget>
#include <QThread>
#include <QFileDialog>
#include <QDateTime>
#include "GrabWindowManager.h"
#include "FFmpegRecordManager.h"

namespace Ui {
class RecordWidget;
}

class RecordWidget : public QWidget
{
    Q_OBJECT

public:
    explicit RecordWidget(QWidget *parent = 0);
    ~RecordWidget();

protected slots:
    void slot_timeChange(int time);

private slots:
    void on_pushButton_startRecord_clicked();
    void on_pushButton_stopRecord_clicked();
    void on_pushButton_browser_clicked();

private:
    Ui::RecordWidget *ui;

    GrabWindowManager *_pGrabWindowManager;         // 抓屏管理類
    QThread *_pGrabWindowManagerThread;             // 抓屏執行緒

    FFmpegRecordManager *_pFFmpegRecordManager;     // 錄製管理類
    QThread *_pFFmpegRecordManagerThread;           // 錄製執行緒
};

#endif // RECORDWIDGET_H
#include "RecordWidget.h"
#include "ui_RecordWidget.h"
#include <QDateTime>

RecordWidget::RecordWidget(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::RecordWidget),
    _pGrabWindowManager(0),
    _pGrabWindowManagerThread(0)
{
    ui->setupUi(this);

    QString version = "v1.0.0";
    setWindowTitle(QString("錄屏Demo %1(作者:紅胖子(AAA紅模仿) QQ:21497936 微信:yangsir198808 部落格地址:blog.csdn.net/qq21497936)").arg(version));

    // 初始化抓屏執行緒
    _pGrabWindowManagerThread = new QThread();
    _pGrabWindowManager = new GrabWindowManager();
    _pGrabWindowManager->moveToThread(_pGrabWindowManagerThread);
    connect(_pGrabWindowManager, SIGNAL(signal_timeChange(int)),
            this, SLOT(slot_timeChange(int)));
    _pGrabWindowManagerThread->start();
    // 初始化錄製執行緒
    _pFFmpegRecordManagerThread = new QThread();
    _pFFmpegRecordManager = new FFmpegRecordManager();
    _pFFmpegRecordManager->moveToThread(_pFFmpegRecordManagerThread);
    connect(_pFFmpegRecordManagerThread, SIGNAL(started()),
            _pFFmpegRecordManager, SLOT(slot_start()));
    _pFFmpegRecordManagerThread->start();
    // 關聯訊號
    connect(_pGrabWindowManager, SIGNAL(signal_grapWindow(QImage)),
            _pFFmpegRecordManager, SLOT(slot_encoderOneFrame(QImage)));
    // 按鍵狀態初始化
    ui->pushButton_startRecord->setEnabled(true);
    ui->pushButton_stopRecord->setEnabled(false);
    ui->lineEdit_dirPath->setReadOnly(true);
    ui->lineEdit_dirPath->setText(QCoreApplication::applicationDirPath());
    ui->lineEdit_value->setValidator(new QIntValidator(1, 100));
    ui->lineEdit_fps->setValidator(new QIntValidator(5, 50));
}

RecordWidget::~RecordWidget()
{
    delete ui;
}

void RecordWidget::slot_timeChange(int time)
{
    ui->label_time->setText(QString("%1%2:%3%4").arg(time/60/10)
                                                 .arg(time/60%10)
                                                 .arg(time%60/10)
                                                 .arg(time%10));
}

void RecordWidget::on_pushButton_startRecord_clicked()
{
    slot_timeChange(0);

    QScreen *pScreen = QGuiApplication::primaryScreen();
    QRect rect = pScreen->availableGeometry();

    _pFFmpegRecordManager->setFps(ui->lineEdit_fps->text().toInt());
    _pFFmpegRecordManager->setWidthIn(rect.width());
    _pFFmpegRecordManager->setHeightIn(rect.height());
    _pFFmpegRecordManager->setWidthOut(rect.width());
    _pFFmpegRecordManager->setHeightOut(rect.height());
    _pFFmpegRecordManager->setValue(ui->lineEdit_value->text().toInt());
    _pFFmpegRecordManager->slot_startEncoder(QString("%1/%2.mp4")
                                             .arg(ui->lineEdit_dirPath->text())
                                             .arg(QDateTime::currentDateTime().toString("yyyy-MM-dd hh_mm_ss")),
                                             AV_PIX_FMT_BGRA);

    _pGrabWindowManager->slot_startGrabWindow(rect.x(),
                                              rect.y(),
                                              rect.width(),
                                              rect.height(),
                                              ui->lineEdit_fps->text().toInt());

    ui->pushButton_startRecord->setEnabled(false);
    ui->pushButton_stopRecord->setEnabled(true);
    ui->pushButton_browser->setEnabled(false);
    ui->lineEdit_fps->setEnabled(false);
    ui->lineEdit_value->setEnabled(false);
}

void RecordWidget::on_pushButton_stopRecord_clicked()
{
    _pGrabWindowManager->slot_stopGrabWindow();
    _pFFmpegRecordManager->slot_stopEncoder();
    ui->pushButton_startRecord->setEnabled(true);
    ui->pushButton_stopRecord->setEnabled(false);
    ui->pushButton_browser->setEnabled(true);
    ui->lineEdit_fps->setEnabled(true);
    ui->lineEdit_value->setEnabled(true);
}

void RecordWidget::on_pushButton_browser_clicked()
{
    QString dir = QFileDialog::getExistingDirectory(0, "儲存到資料夾", ".");
    if(dir.isEmpty())
    {
        return;
    }
    ui->lineEdit_dirPath->setText(dir);
}

<br>

若該文為原創文章,轉載請註明原文出處 本文章部落格地址:http://blog.csdn.net/qq21497936/article/details/109827936

「其他文章」