当前位置: 首页 > news >正文

如何使用ffmpeg命令行进行录屏

录屏软件,我们去网上下载,发现有很多软件都是要收费的!但是录屏功能很难做吗?为啥都需要收费呢?

于是我整了个小demo,用于实现基础的屏幕录制功能。

思路很简单,考虑到 FFMpeg.exe是一个非常成熟的音视频处理软件,而且是开源的。我们完全可以基于 FFMpeg.exe来实现我们的要求。

使用 FFMpeg录屏通常有两种方式:

  1. 基于 gdigrab (使用CPU录制)

  2. 基于 DirectShow (使用显卡录制)

考虑到 gdigrab方式实现更简单,更轻量,兼容性也更好,所以我们采用 gdigrab方案。DirectShow方案需要额外下载 screen-capture-recorder!

基于该方法,主要核心就是 ffmpeg的命令编写,具体命令如下:

ffmpeg -f gdigrab -framerate 30 -offset_x 0 -offset_y 0 -video_size 1920x1080 -i desktop -r 30 -vcodec libx264 -pix_fmt yuv420p -y "output.mp4"

命令说明:


//注意:ffmpeg 的命令输入,也需要考虑输入顺序的。先指定输入参数,再指定输出参数。// -f 表示指定文件格式或采集数据的设备,如果是 DirectShow 方案,就需要指定为 screen-capture-recorder。    //对于输入,如果不指定-f, ffmpeg 会根据输入数据,来判断数据的封装格式.    //对于输出,如果不指定-f, ffmpeg 也可以通过输出文件名进行推导.    
//ffmpeg -formats 可以列出所有的formats
// -framerate 指定录制的视频帧率
// -offset_x -offset_y 指定录制的区域左上角坐标
// -video_size 指定录制的视频尺寸
// -i 指定从哪儿采集数据,它是一个文件索引号。这里是指定输入的视频源。(i 表示input,不一定是表示视频文件,表示输入。如也可以是音频文件输入等)
// -r 指定帧率
// -vcodec 指定编码格式。libx264 这种格式录制出来的视频,清晰度更清晰,占用的文件大小更小,推荐使用。
// -pix_fmt 像素格式,常规使用yuv420p
// -y 表示强制覆盖,如果输出文件已经存在,就覆盖
// 输出文件路径。这里需要注意下:输出文件路径带上 双引号 ,防止不合法路径将命令拆分了。

 为了更方便代码实现相关编码,下面贴上核心代码(附加音视频合并的示例代码):

/// <summary>/// 视频录制命令构建类/// </summary>public class FFMpegScreenRecordArgs : FFMpegArgs{public int Framerate { get; set; }public int Rate { get; set; }public Rect Region { get; set; }public VideoCodec Codec { get; set; }public PixelFormat PixelFormat { get; set; }public string SavePath { get; set; }public override string ToArgs(){ArgsBuilder.SetRecordDevice();ArgsBuilder.SetFramerate(Framerate);ArgsBuilder.SetRecordRect((int)Region.Left, (int)Region.Top);ArgsBuilder.SetVideoSize((int)Region.Width, (int)Region.Height);ArgsBuilder.SetInput();ArgsBuilder.SetRate(Rate);ArgsBuilder.SetCodec(Codec);ArgsBuilder.SetPixFarmat(PixelFormat);return $"{ArgsBuilder.GetArgs()} -y {SavePath}\"";}}/// <summary>/// 音视频合成构建类/// </summary>public class FFMpegAVSynthesisArgs : FFMpegArgs{public string InputAudioPath { get; set; }public string InputVideoPath { get; set; }public string OutputVideoPath { get; set; }public override string ToArgs(){this.ArgsBuilder.SetInput(InputAudioPath);this.ArgsBuilder.SetInput(InputVideoPath);this.ArgsBuilder.SetCodec(AudioCodec.copy);this.ArgsBuilder.SetCodec(VideoCodec.copy);return $"{ArgsBuilder.GetArgs()} \"{OutputVideoPath}\"";}}//基础命名构建类public class FFmpegArgsBuilder{protected readonly List<string> Args = new List<string>();public FFmpegArgsBuilder AddArg<T>(string Key, T Value){Args.Add($"-{Key} {Value}");return this;}public virtual string GetArgs(){return string.Join(" ", Args);}public void Reset(){Args.Clear();}#region argspublic FFmpegArgsBuilder SetRecordRect(int x, int y){AddArg("offset_x", x);AddArg("offset_y", y);return this;}public FFmpegArgsBuilder SetVideoSize(int width, int height){AddArg("video_size", $"{width}x{height}");return this;}public FFmpegArgsBuilder SetInput(string input = "desktop"){AddArg("i", input);return this;}public FFmpegArgsBuilder SetFramerate(int framerate){AddArg("framerate", framerate);return this;}public FFmpegArgsBuilder SetRate(int rate){AddArg("r", rate);return this;}public FFmpegArgsBuilder SetRecordDevice(string device = "gdigrab"){AddArg("f", device);return this;}public FFmpegArgsBuilder SetCodec(VideoCodec codec){            AddArg("vcodec", codec);return this;}public FFmpegArgsBuilder SetCodec(AudioCodec audioCodec){AddArg("acodec", audioCodec);return this;}public FFmpegArgsBuilder SetPixFarmat(PixelFormat x){AddArg("pix_fmt", x);return this;}#endregion}//像素格式public enum PixelFormat{///<summary>/// yuv420p///</summary>yuv420p,//……省略……}//编码格式public enum VideoCodec{///<summary>///      libx264///</summary>libx264,///<summary>///      copy///</summary>copy,//……省略……}/// <summary>///     Audio codec ("ffmpeg -codecs")/// </summary>public enum AudioCodec{///<summary>///      copy///</summary>copy,}

http://www.lryc.cn/news/483636.html

相关文章:

  • ODOO学习笔记(8):模块化架构的优势
  • 数字IC后端实现之Innovus specifyCellEdgeSpacing和ICC2 set_placement_spacing_rule的应用
  • 每日小练:Day2
  • ubuntu 安装kafka-eagle
  • 深入理解指针
  • 自动驾驶合集(更新中)
  • Chapter 14 scoped样式以及data函数
  • Golang | Leetcode Golang题解之第557题反转字符串中的单词III
  • 区块链技术在电子政务中的应用
  • Simulink中Matlab function使用全局变量
  • WPF-控件的属性值的类型转化
  • 海思Hi3516DV300上播放G711U音频文件
  • Linux源码阅读笔记-V4L2框架基础介绍
  • 列表(list)
  • 使用Python抓取数据的实战指南
  • GIC寄存器介绍
  • c++实现B树(下)
  • 外星人入侵
  • 【数据仓库】hbase的安装与简单操作
  • 为什么RNN(循环神经网络)存在梯度消失和梯度爆炸?
  • 【数据库】数据库迁移的注意事项有哪些?
  • MQTT协议解析 : 物联网领域的最佳选择
  • pycharm中from[本地包]import文件/模块出现问题(最最最全方法!)
  • MongoDB在现代Web开发中的应用
  • Python Bokeh 数据可视化教程
  • (一)<江科大STM32>——软件环境搭建+新建工程步骤
  • 内存大小的单位转换
  • 如何在 Spring MVC 中使用 `@PostMapping`? 如何在 Spring MVC 中使用 `@PutMapping`?
  • AIGC Agent(智能体)应用开发高级工程师实战培训 —— 线上8周系统教学课程学习路线图
  • GDSC、CTRP数据库学习