Qt调用ffmpeg录制屏幕

使用ffmpeg命令行可以进行屏幕录制,命令行如下:

ffmpeg -f gdigrab -i desktop -framerate 60 -offset_x 0 -offset_y 0 -video_size 1600x900  -pix_fmt yuv420p -vcodec libx264 -crf 18 D:/out1.mp4

命令介绍:

  • gdigrab:表明我们是通过gdi抓屏的方式;
  • framerate 30:表示我录制的帧率为30;
  • offset_x :左上偏移量X;
  • offset_y :左上偏移量Y;
  • video_size:需要录制的宽度和高度,这是我是整个屏幕;
  • desktop:告诉ffmpeg我们录的是屏幕,而不是一个窗口
  • crf:该参数来控制转码,这个参数的取值范围为0–51,其中0为无损模式,数值越大,画质越差,生成的文件却越小。从主观上讲,18~28是一个合理的范围。18被认为是视觉无损的(从技术角度上看当然还是有损的),它的输出视频质量和输入视频相当。

代码

界面如下:
在这里插入图片描述
  下面介绍如何使用Qt来调用ffmpeg命令行进行录屏
  Qt调用其它进程需要用到QProcess类,在头文件声明一个QProcess对象

#ifndef WIDGET_H
#define WIDGET_H

#include <QWidget>
#include <QProcess>

QT_BEGIN_NAMESPACE
namespace Ui {
    
     class Widget; }
QT_END_NAMESPACE

class Widget : public QWidget
{
    
    
    Q_OBJECT

public:
    Widget(QWidget *parent = nullptr);
    ~Widget();

private slots:
    void on_btnStart_clicked();
    void on_btnStop_clicked();

private:
    Ui::Widget *ui;

    QProcess m_Process;
};
#endif // WIDGET_H

开始录制与结束录制

void Widget::on_btnStart_clicked()
{
    
    
    m_Process.setProcessChannelMode(QProcess::MergedChannels);
    QString cmd = "ffmpeg -f gdigrab -i desktop -framerate 60 -offset_x 0 -offset_y 0 -video_size 1600x900  -pix_fmt yuv420p -vcodec libx264 -crf 18 D:/out1.mp4";
    m_Process.start(cmd);
}

void Widget::on_btnStop_clicked()
{
    
    
    if (m_Process.isOpen())
    {
    
    
        m_Process.write("q");
    }
}

执行q结束录制。
  由于我是把ffmpeg直接添加到了环境变量,所以可以直接调用,在项目里面使用时,可以把ffmpeg放到exe目录,用绝对路径获取。
  关于ffmpeg的编译可以看这篇博客【vs2019编译ffmpeg】.

ffmpeg录屏的缺陷

(1)使用ffmpeg命令行录制有一些限制,例如无法录制声音,如果想录制声音需要使用screen capture recorder,下载链接: https://sourceforge.net/projects/screencapturer/

(2)声音的录制稍微麻烦一些,分为系统声音和麦克风采集进来的声音,一般笔记本都有内置麦克风,如果使用者插入了外部麦克风,那么得识别出来,此时用ffmpeg就不是很友好了。下面是声音录制的命令行:

# 只录制系统声音
ffmpeg -f dshow -i audio="virtual-audio-capturer" out.mp3

# 同时录制屏幕+系统声音
ffmpeg -f dshow -i audio="virtual-audio-capturer":video="screen-capture-recorder" -pix_fmt yuv420p out.mp4

# 同时录制屏幕+系统声音+麦克风
ffmpeg -f dshow -i audio="麦克风 (Realtek High Definition Audio)" -f dshow -i audio="virtual-audio-capturer" -filter_complex amix=inputs=2:duration=first:dropout_transition=0 -f dshow -i video="screen-capture-recorder" -pix_fmt yuv420p out.mp4

# 显示可用的设备
ffmpeg -list_devices true -f dshow -i dummy

(3)另外由于ffmpeg使用gdi录屏,并没有处理鼠标的重绘,导致鼠标会闪烁,给使用者的体验不太好,如果需要消除鼠标闪烁,则需要在录制时,对每一帧视频数据的鼠标进行重绘,显然这使用命令是做不到的,需要使用代码来实现。

(4)窗口录制,当指定窗口录制时,如果屏幕分辨率不是100%,由于屏幕扩大了,导致窗口录制不完整。

  以上这几条,用ffmpeg命令行基本都是很难解决的。

如何解决ffmpeg录屏缺陷

  obs有完整的录屏方案,可以参考obs的源/码来录制屏幕、声音、制定窗口录制,推流、直播等操作,关于桌面录制的其它内容可以参考我的【obs源码分析专栏】。

猜你喜欢

转载自blog.csdn.net/yao_hou/article/details/125294832