基于FFmpeg实现屏幕录制

FFmpeg下载

首先需要下载FFmpeg,为了在win7系统上通用和方便,我们采用32位的静态版本,下载页面如下:
软件信息
下载地址:https://ffmpeg.zeranoe.com/builds/

录制屏幕

为了实现对于Window桌面录制,有两种方式进行采集:

  1. DirectShow 设备
  2. gdigrab设备

其基本命令行如下:

//Dshow设备
ffmpeg -f dshow -i video="screen-capture-recorder" output.mkv

//gdigrab设备 采集整个桌面
ffmpeg -f gdigrab -framerate 30 -i desktop output.mkv

这两个命令默认都是采用x264 进行编码,在本地CPU不是足够高的情况下,录制的视频画面根本看不清楚,这是因为编码效率太低导致;

为了提高录制效果,我们可以采用无损编码+提高编码速度方式进行录制,具体命令如下:

ffmpeg -framerate 30 -f gdigrab -i desktop -c:v libx264rgb -crf 0 -preset ultrafast output.mkv
或者
ffmpeg -framerate 30 -f gdigrab -i desktop -c:v libx264rgb -preset:v ultrafast -tune:v zerolatency output.mkv

关于FFmpeg屏幕采集可以参考 https://trac.ffmpeg.org/wiki/Capture/Desktop文章
关于H264编码方面的知识可以参考https://trac.ffmpeg.org/wiki/Encode/H.264文章

录制声音

在上面提到过录制屏幕除了采用gdigrab外,还可以采用dshow方式;它们的区别就是:gdigrab设置仅支持截取屏幕信息,对声音的录制是不支持的,而show方式可以支持录制屏幕和声音

这个dshow软件的下载信息如下:

  1. 编译好的下载地址是:
    http://sourceforge.net/projects/screencapturer/

  2. 源码地址是:
    https://github.com/rdp/screen-capture-recorder-to-video-windows-free

为了使系统能识别出dshow设备,我们首先需要进行注册,为了去掉不必要的文件,我们只提取四个dll:

  • screen-capture-recorder.dll
  • screen-capture-recorder-x64.dll
  • audio_sniffer-x64.dll
  • audio_sniffer.dll

注册命令行如下:

//注册屏幕录制设备(我们采用32位的ffmpeg,可以不用注册带x64的dll)
regsvr32 /s  screen-capture-recorder.dll
//注册虚拟音频设备
regsvr32 /s audio_sniffer.dll

注册成功后,可以采用以下命令进行检查是否注册成功

ffmpeg -list_devices true -f dshow -i dummy  

系统输出大致如下:
在这里插入图片描述
“screen-capture-recorder” 这个就是桌面捕获设备,用于录制屏幕
“virtual-audio-capturer” 这个是音频捕获设备,用于录制声音

-f dshow -i audio="virtual-audio-capturer" 这代表声音从“virtual-audio-capturer”音频设备获取

为了能够同时录制声音和画面,我们可以使用以下命令进行采集:

ffmpeg -framerate 30 -f gdigrab -i desktop -f dshow -i audio="virtual-audio-capturer" -c:v libx264rgb -preset:v ultrafast -tune:v zerolatency output.mp4

用vlc打开录制文件,可以看书画面显示正常以及声音正常被播放处理,截图如下:
在这里插入图片描述

以上就是关于ffmpeg录制window桌面的全部过程了,欢迎大家交流~

参考文章:
https://blog.csdn.net/Fandes_F/article/details/105121581

  • 3
    点赞
  • 22
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
很抱歉,我作为一个语言模型,无法为您提供完整的源代码。不过,我可以提供一些基本的思路和代码片段,帮助您实现基于FFmpeg屏幕录制软件。 首先,您需要安装 FFmpeg 库,并熟悉其基本用法。您还需要安装 Qt 库,用于构建软件界面。 以下是一个简单的 Qt 界面示例,包括一个录制按钮和一个停止按钮: ```cpp #include <QPushButton> #include <QVBoxLayout> #include <QWidget> class MainWindow : public QWidget { public: MainWindow(QWidget* parent = nullptr) : QWidget(parent) { // 创建按钮 record_button_ = new QPushButton("录制", this); stop_button_ = new QPushButton("停止", this); // 添加按钮到布局 QVBoxLayout* layout = new QVBoxLayout(this); layout->addWidget(record_button_); layout->addWidget(stop_button_); // 添加按钮事件处理函数 connect(record_button_, &QPushButton::clicked, this, &MainWindow::StartRecording); connect(stop_button_, &QPushButton::clicked, this, &MainWindow::StopRecording); } private slots: void StartRecording() { // TODO: 开始录制屏幕 } void StopRecording() { // TODO: 停止录制屏幕 } private: QPushButton* record_button_; QPushButton* stop_button_; }; ``` 接下来,您需要实现 FFmpeg屏幕录制功能。以下是一个简单的示例,可以录制整个屏幕: ```cpp #include <iostream> #include <string> #include <unistd.h> #include <X11/Xlib.h> #include <X11/Xutil.h> extern "C" { #include <libavcodec/avcodec.h> #include <libavutil/opt.h> #include <libavutil/imgutils.h> } // 屏幕宽度和高度 const int kScreenWidth = 1280; const int kScreenHeight = 720; // FFmpeg 编码器参数 const AVCodecID kCodecId = AV_CODEC_ID_H264; const int kBitRate = 4000000; const int kFrameRate = 30; void RecordScreen(const std::string& output_file) { // 初始化 X11 显示器 Display* display = XOpenDisplay(nullptr); Window root = DefaultRootWindow(display); // 初始化 FFmpeg 编码器 avcodec_register_all(); AVCodec* codec = avcodec_find_encoder(kCodecId); AVCodecContext* codec_context = avcodec_alloc_context3(codec); codec_context->width = kScreenWidth; codec_context->height = kScreenHeight; codec_context->bit_rate = kBitRate; codec_context->time_base = {1, kFrameRate}; codec_context->framerate = {kFrameRate, 1}; codec_context->gop_size = 10; codec_context->max_b_frames = 0; codec_context->pix_fmt = AV_PIX_FMT_YUV420P; av_opt_set(codec_context->priv_data, "preset", "ultrafast", 0); avcodec_open2(codec_context, codec, nullptr); // 初始化 FFmpeg 编码器输出文件 FILE* file = fopen(output_file.c_str(), "wb"); AVPacket* packet = av_packet_alloc(); AVFrame* frame = av_frame_alloc(); frame->format = codec_context->pix_fmt; frame->width = kScreenWidth; frame->height = kScreenHeight; av_frame_get_buffer(frame, 32); av_frame_make_writable(frame); // 开始录制屏幕 for (;;) { XImage* image = XGetImage(display, root, 0, 0, kScreenWidth, kScreenHeight, AllPlanes, ZPixmap); uint8_t* data[] = {image->data, nullptr, nullptr}; int linesize[] = {static_cast<int>(image->bytes_per_line), 0, 0}; av_image_fill_arrays(frame->data, frame->linesize, data, codec_context->pix_fmt, kScreenWidth, kScreenHeight, 32); int ret = avcodec_send_frame(codec_context, frame); if (ret < 0) { std::cerr << "Error sending a frame for encoding: " << ret << std::endl; break; } while (ret >= 0) { ret = avcodec_receive_packet(codec_context, packet); if (ret == AVERROR(EAGAIN) || ret == AVERROR_EOF) { break; } else if (ret < 0) { std::cerr << "Error during encoding: " << ret << std::endl; break; } fwrite(packet->data, 1, packet->size, file); av_packet_unref(packet); } XDestroyImage(image); } // 停止录制屏幕 avcodec_send_frame(codec_context, nullptr); while (avcodec_receive_packet(codec_context, packet) == 0) { fwrite(packet->data, 1, packet->size, file); av_packet_unref(packet); } fclose(file); avcodec_close(codec_context); avcodec_free_context(&codec_context); } int main() { RecordScreen("output.mp4"); return 0; } ``` 以上示例代码仅供参考,您需要根据自己的需求进行修改和完善。同时,为了保证代码的可读性和可维护性,建议您为代码添加注释。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值