Qt调用FFmpeg命令录屏

19 篇文章 7 订阅

//列出音视频设备
ffmpeg -list_devices true -f dshow -i dummy

//录屏命令

ffmpeg -f gdigrab -i desktop -f dshow -i audio="麦克风 (High Definition Audio 设备)" -pix_fmt yuv420p -vcodec libx264 -acodec aac -s 1440x900 -r 25 -q 10 -ar 44100 -ac 2 -tune zerolatency -preset ultrafast D:/tt.mp4

关闭ffmpeg进程:向QProcess发送q字符

ScreenRecord.h

#pragma once
#include <QWidget>

class QProcess;
class QFile;

class ScreenRecord : public QWidget
{
	Q_OBJECT
public:
	ScreenRecord(QWidget *parent = Q_NULLPTR);

	void Init();

	public slots:
	void Start();
	void Pause();
	void Stop();


private:
	QProcess* m_recordProcess;
	QStringList m_args;
	QString m_audioDeviceName;
	QString m_outPath;
	int m_width;
	int m_height;
	int m_fps;
	QFile* m_tmpText;
	QString m_err;
	QStringList m_errList;
};

ScreenRecord.cpp

#include "ScreenRecord.h"
#include <QApplication>
#include <QDesktopWidget>
#include <QProcess>
#include <QTimer>
#include <QDebug>
#include <QTime>
#include <QDateTime>
#include <QFile>

#include <Windows.h>

ScreenRecord::ScreenRecord(QWidget *parent)
	: QWidget(parent)
	, m_recordProcess(new QProcess(this))
{
	connect(m_recordProcess, static_cast<void(QProcess::*)(int, QProcess::ExitStatus)>(&QProcess::finished),
		[this](int exitCode, QProcess::ExitStatus exitStatus) {
		qDebug() << QStringLiteral("成功录制临时视频");
	});

	Init();
	QTimer::singleShot(1000, this, SLOT(Start()));
	QTimer::singleShot(5000, this, SLOT(Pause()));

	QTimer::singleShot(6000, this, SLOT(Start()));
	QTimer::singleShot(10000, this, SLOT(Stop()));
}

void ScreenRecord::Init()
{
	QProcess *listProcess = new QProcess(this);
	connect(listProcess, &QProcess::readyReadStandardError, [listProcess, this]() {
		//QString tmp = pro->readAllStandardError();
		m_err.append(listProcess->readAllStandardError());
		//qDebug() << tmp;
	});
	connect(listProcess, static_cast<void(QProcess::*)(int, QProcess::ExitStatus)>(&QProcess::finished),
		[this](int exitCode, QProcess::ExitStatus exitStatus) {
		m_errList = m_err.split("\r\n", QString::SkipEmptyParts);
		QStringList filter = m_errList.filter(QString::fromLocal8Bit("麦克风"));
		QString microphone = filter.first();
		QStringList filter2 = microphone.split("\"", QString::SkipEmptyParts);
		QStringList filter3 = filter2.filter(QString::fromLocal8Bit("麦克风"));
		//"麦克风 (High Definition Audio 设备)";
		m_audioDeviceName = "audio=" + filter3.first();

		m_outPath = QString("%1.mp4").arg(QDateTime::currentDateTime().toMSecsSinceEpoch());
		m_width = QApplication::desktop()->screenGeometry().width();
		m_height = QApplication::desktop()->screenGeometry().height();
		m_fps = 25;
		//QString audioName = "audio=" + QString::fromLocal8Bit("麦克风 (High Definition Audio 设备)");
		m_args << "-f" << "gdigrab";
		m_args << "-i" << "desktop";
		m_args << "-f" << "dshow";
		m_args << "-i" << m_audioDeviceName;
		m_args << "-pix_fmt" << "yuv420p";
		m_args << "-vcodec" << "libx264";
		m_args << "-acodec" << "aac";
		m_args << "-s" << QString::number(m_width) + "x" + QString::number(m_height);
		m_args << "-r" << QString::number(m_fps);
		m_args << "-q" << "10";
		m_args << "-ar" << "44100";
		m_args << "-ac" << "2";
		m_args << "-tune" << "zerolatency";
		m_args << "-preset" << "ultrafast";
		m_args << "-f" << "mp4";

		m_tmpText = new QFile(QString("D:\\t%1_tmp").arg(QDateTime::currentDateTime().toMSecsSinceEpoch()));
		if (!m_tmpText->open(QIODevice::ReadWrite | QIODevice::Text))
			qDebug() << "File open error";
	});
	QStringList listCmdArgs;
	listCmdArgs << "-list_devices" << "true" << "-f" << "dshow" << "-i" << "dummy";
	//listProcess->setWorkingDirectory("FFmpeg");
	listProcess->start("ffmpeg", listCmdArgs);
}

void ScreenRecord::Start()
{
	//反斜线对应文本中是绝对路径,斜线对应相对路径
	QString tmpFilePath = QString("v%1_tmp").arg(QDateTime::currentDateTime().toMSecsSinceEpoch());

	QTextStream out(m_tmpText);
	out << "file" << " '" << tmpFilePath << "'\n";

	QStringList args = m_args;
	QString tmpFileAbsolutePath = "D:\\" + tmpFilePath;
	args << tmpFileAbsolutePath;
	//m_recordProcess->setWorkingDirectory("FFmpeg");
	m_recordProcess->start("ffmpeg", args);
}

void ScreenRecord::Pause()
{
	//暂停录制->生成临时视频
	m_recordProcess->write("q");
}

void ScreenRecord::Stop()
{
	//结束录制->合成视频
	connect(m_recordProcess, static_cast<void(QProcess::*)(int, QProcess::ExitStatus)>(&QProcess::finished),
		[this](int exitCode, QProcess::ExitStatus exitStatus) {
		QProcess* mergeProcess = new QProcess(this);
		connect(mergeProcess, static_cast<void(QProcess::*)(int, QProcess::ExitStatus)>(&QProcess::finished),
			[mergeProcess, this](int exitCode, QProcess::ExitStatus exitStatus) {
			qDebug() << QStringLiteral("成功合成视频");
			qDebug() << mergeProcess->readAllStandardError();
		});
		//ffmpeg -f concat -safe 0 -i filelist.txt -c copy output.mkv
		QStringList args;
		args << "-f" << "concat";
		args << "-safe" << "0";
		args << "-i" << m_tmpText->fileName();
		args << "-c" << "copy";
		args << m_outPath;
		//合成视频
		mergeProcess->start("ffmpeg", args);
	});

	m_tmpText->close();
	m_recordProcess->write("q");
}

github

  • 3
    点赞
  • 29
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值