草庐IT

Qt调用ffmpeg录制屏幕

令狐掌门 2023-05-20 原文

使用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源码分析专栏】。

有关Qt调用ffmpeg录制屏幕的更多相关文章

  1. 使用 ACL 调用 upload_file 时出现 Ruby S3 "Access Denied"错误 - 2

    我正在尝试编写一个将文件上传到AWS并公开该文件的Ruby脚本。我做了以下事情:s3=Aws::S3::Resource.new(credentials:Aws::Credentials.new(KEY,SECRET),region:'us-west-2')obj=s3.bucket('stg-db').object('key')obj.upload_file(filename)这似乎工作正常,除了该文件不是公开可用的,而且我无法获得它的公共(public)URL。但是当我登录到S3时,我可以正常查看我的文件。为了使其公开可用,我将最后一行更改为obj.upload_file(file

  2. c# - 如何在 ruby​​ 中调用 C# dll? - 2

    如何在ruby​​中调用C#dll? 最佳答案 我能想到几种可能性:为您的DLL编写(或找人编写)一个COM包装器,如果它还没有,则使用Ruby的WIN32OLE库来调用它;看看RubyCLR,其中一位作者是JohnLam,他继续在Microsoft从事IronRuby方面的工作。(估计不会再维护了,可能不支持.Net2.0以上的版本);正如其他地方已经提到的,看看使用IronRuby,如果这是您的技术选择。有一个主题是here.请注意,最后一篇文章实际上来自JohnLam(看起来像是2009年3月),他似乎很自在地断言RubyCL

  3. java - 从 JRuby 调用 Java 类的问题 - 2

    我正在尝试使用boilerpipe来自JRuby。我看过guide从JRuby调用Java,并成功地将它与另一个Java包一起使用,但无法弄清楚为什么同样的东西不能用于boilerpipe。我正在尝试基本上从JRuby中执行与此Java等效的操作:URLurl=newURL("http://www.example.com/some-location/index.html");Stringtext=ArticleExtractor.INSTANCE.getText(url);在JRuby中试过这个:require'java'url=java.net.URL.new("http://www

  4. ruby - 调用其他方法的 TDD 方法的正确方法 - 2

    我需要一些关于TDD概念的帮助。假设我有以下代码defexecute(command)casecommandwhen"c"create_new_characterwhen"i"display_inventoryendenddefcreate_new_character#dostufftocreatenewcharacterenddefdisplay_inventory#dostufftodisplayinventoryend现在我不确定要为什么编写单元测试。如果我为execute方法编写单元测试,那不是几乎涵盖了我对create_new_character和display_invent

  5. 屏幕录制为什么没声音?检查这2项,轻松解决 - 2

    相信很多人在录制视频的时候都会遇到各种各样的问题,比如录制的视频没有声音。屏幕录制为什么没声音?今天小编就和大家分享一下如何录制音画同步视频的具体操作方法。如果你有录制的视频没有声音,你可以试试这个方法。 一、检查是否打开电脑系统声音相信很多小伙伴在录制视频后会发现录制的视频没有声音,屏幕录制为什么没声音?如果当时没有打开音频录制,则录制好的视频是没有声音的。因此,建议在录制前进行检查。屏幕上没有声音,很可能是因为你的电脑系统的声音被禁止了。您只需打开电脑系统的声音,即可录制音频和图画同步视频。操作方法:步骤1:点击电脑屏幕右下侧的“小喇叭”图案,在上方的选项中,选择“声音”。 步骤2:在“声

  6. 【鸿蒙应用开发系列】- 获取系统设备信息以及版本API兼容调用方式 - 2

    在应用开发中,有时候我们需要获取系统的设备信息,用于数据上报和行为分析。那在鸿蒙系统中,我们应该怎么去获取设备的系统信息呢,比如说获取手机的系统版本号、手机的制造商、手机型号等数据。1、获取方式这里分为两种情况,一种是设备信息的获取,一种是系统信息的获取。1.1、获取设备信息获取设备信息,鸿蒙的SDK包为我们提供了DeviceInfo类,通过该类的一些静态方法,可以获取设备信息,DeviceInfo类的包路径为:ohos.system.DeviceInfo.具体的方法如下:ModifierandTypeMethodDescriptionstatic StringgetAbiList​()Obt

  7. Qt Designer的简单使用 - 2

    在前面两节的例子中,主界面窗口的尺寸和标签控件显示的矩形区域等,都是用C++代码编写的。窗口和控件的尺寸都是预估的,控件如果多起来,那就不好估计每个控件合适的位置和大小了。用C++代码编写图形界面的问题就是不直观,因此Qt项目开发了专门的可视化图形界面编辑器——QtDesigner(Qt设计师)。通过QtDesigner就可以很方便地创建图形界面文件*.ui,然后将ui文件应用到源代码里面,做到“所见即所得”,大大方便了图形界面的设计。本节就演示一下QtDesigner的简单使用,学习拖拽控件和设置控件属性,并将ui文件应用到Qt程序代码里。使用QtDesigner设计界面在开始菜单中找到「Q

  8. C51单片机——实现用独立按键控制LED亮灭(调用函数篇) - 2

    说在前面这部分我本来是合为一篇来写的,因为目的是一样的,都是通过独立按键来控制LED闪灭本质上是起到开关的作用,即调用函数和中断函数。但是写一篇太累了,我还是决定分为两篇写,这篇是调用函数篇。在本篇中你主要看到这些东西!!!1.调用函数的方法(主要讲语法和格式)2.独立按键如何控制LED亮灭3.程序中的一些细节(软件消抖等)1.调用函数的方法思路还是比较清晰地,就是通过按下按键来控制LED闪灭,即每按下一次,LED取反一次。重要的是,把按键与LED联系在一起。我打算用K1来作为开关,看了一下开发板原理图,K1连接的是单片机的P31口,当按下K1时,P31是与GND相连的,也就是说,当我按下去时

  9. python ffmpeg 使用 pyav 转换 一组图像 到 视频 - 2

    2022/8/4更新支持加入水印水印必须包含透明图像,并且水印图像大小要等于原图像的大小pythonconvert_image_to_video.py-f30-mwatermark.pngim_dirout.mkv2022/6/21更新让命令行参数更加易用新的命令行使用方法pythonconvert_image_to_video.py-f30im_dirout.mkvFFMPEG命令行转换一组JPG图像到视频时,是将这组图像视为MJPG流。我需要转换一组PNG图像到视频,FFMPEG就不认了。pyav内置了ffmpeg库,不需要系统带有ffmpeg工具因此我使用ffmpeg的python包装p

  10. ruby - 如何找到调用当前方法的方法 - 2

    如何找到调用此方法的位置?defto_xml(options={})binding.pryoptions=options.to_hifoptions&&options.respond_to?(:to_h)serializable_hash(options).to_xml(options)end 最佳答案 键入caller。这将返回当前调用堆栈。文档:Kernel#caller.例子[0]%rspecspec10/16|===================================================62=====

随机推荐