C# wpf使用ffmpeg命令行实现录屏的示例代码

目录
  • 前言
  • 一、主要步骤
    • 1、使用 AllowsTransparency实现穿透框
    • 2、获取音频设备名称
    • 3、命令行启动ffmpeg
    • 4、使用JobObject管理子进程
  • 二、完整代码
  • 三、效果预览
    • 1、录制中
    • 2、录制动态流程
  • 总结

前言

上一章我们实现了截屏界面与功能,接下来可以在此基础上实现录屏功能,录屏采用ffmpeg命令行实现会方便一些,效果也是不错的,当然前提是要对Windows子进程的控制比较熟悉,做出来之后完全可以满足项目使用。

一、主要步骤

1、使用 AllowsTransparency实现穿透框

录屏需要使用AllowsTransparency来实现透明背景,因为录屏时框选区域需要能够点击穿透到桌面,使用WindowChome则不行。

2、获取音频设备名称

因为不依赖第三方工具(比如:screen capture recorder),只要我们能够获取音频设备名称就可以使用ffmpeg的dshow录制声音。我们通过调用Com的方式就可以获取到设备名称,在《C# 使用com获取Windows摄像头列表》的基础上添加一个属性获取音频设备列表:

static readonly Guid AudioInputDevice = new Guid(0x33d9a762, 0x90c8, 0x11d0, 0xbd, 0x43, 0x0, 0xa0, 0xc9, 0x11, 0xce, 0x86);
/// <summary>
/// 枚举录音设备
/// </summary>
public static IEnumerable<string> AudioInputDevices
{
    get
    {
        IMoniker[] monikers = new IMoniker[5];
        var devEnum = Activator.CreateInstance(Type.GetTypeFromCLSID(SystemDeviceEnum)) as ICreateDevEnum;
        IEnumMoniker moniker;
        if (devEnum.CreateClassEnumerator(AudioInputDevice, out moniker, 0) == 0)
        {
            while (true)
            {
                int hr = moniker.Next(1, monikers, IntPtr.Zero);
                if (hr != 0 || monikers[0] == null)
                    break;
                yield return GetName(monikers[0]);
                foreach (var i in monikers)
                {
                    if (i != null)
                        Marshal.ReleaseComObject(i);
                }
            }
            Marshal.ReleaseComObject(moniker);
        }
        Marshal.ReleaseComObject(devEnum);
    }
}

获取音频设备名称

string audio = null;
//获取音频采集设备名称
foreach (var i in EnumDevices.AudioInputDevices)
{
    audio = i;
    break;
}

3、命令行启动ffmpeg

得到了音频设备名称之后,我们就可以使用下面的命令行是实现录屏了。
录屏命令行,-i audio=上一步获取的音频设备名称。

ffmpeg -y -f dshow -sample_rate 44100 -sample_size 16 -channels 2 -i audio="麦克风 (Realtek High Definition Audio)" -f gdigrab -offset_x 10 -offset_y 20 -video_size 640x480 -i desktop -preset:v ultrafast -tune:v zerolatency -r 30 screen.mp4 

启动ffmpeg(示例)

var process = new Process();
process.StartInfo.FileName = "ffmpeg";
process.StartInfo.Arguments ="-y -f dshow -sample_rate 44100 -sample_size 16 -channels 2 -i audio=\"麦克风 (Realtek High Definition Audio)\"  -f gdigrab  -offset_x 10 -offset_y 20 -video_size 640x480  -i desktop  -preset:v ultrafast -tune:v zerolatency  -r 30     screen.mp4 "
process.Start()

4、使用JobObject管理子进程

启动ffmpeg作为子进程,需要对其进行一定的管理,要保证主进程任何情况的退出子进程跟随退出,我们可以使用Windows的JobObject实现这一功能。C#需要使用dllimport包装Job Object的WinApi。
下面是部分示例代码:创建了作业对象,并设置为对象销毁后,加入的进程全部退出。

handle = CreateJobObject(IntPtr.Zero, null);
var info = new JOBOBJECT_BASIC_LIMIT_INFORMATION
{
    LimitFlags = 0x2000
};

var extendedInfo = new JOBOBJECT_EXTENDED_LIMIT_INFORMATION
{
    BasicLimitInformation = info
};

int length = Marshal.SizeOf(typeof(JOBOBJECT_EXTENDED_LIMIT_INFORMATION));
IntPtr extendedInfoPtr = Marshal.AllocHGlobal(length);
Marshal.StructureToPtr(extendedInfo, extendedInfoPtr, false);

if (!SetInformationJobObject(handle, JobObjectInfoType.ExtendedLimitInformation, extendedInfoPtr, (uint)length))
    throw new Exception(string.Format("Unable to set information.  Error: {0}", Marshal.GetLastWin32Error()));

二、完整代码

实现了录屏功能,包括画面和声音的录制,只依赖ffmpeg.exe。

之后上传

三、效果预览

1、录制中

2、录制动态流程

总结

以上就是今天要讲的内容了,因为使用了命令行所以录屏逻辑不用自己实现,但是要控制ffmpeg子进程还是有不少细节需要处理的,比如进程自动退出、信息反馈、停止录屏、异常提示等。另外一方面在界面上也有需要处理的东西,比如可控的点击穿透、控制窗口置顶等等。总的来说,实现这一一个功能模块还是需要一定的时间和精力,以及一些相关的知识。

到此这篇关于C# wpf使用ffmpeg命令行实现录屏的示例代码的文章就介绍到这了,更多相关C# wpf ffmpeg命令行录屏内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • C#及WPF获取本机所有字体和颜色的方法

    本文实例讲述了C#及WPF获取本机所有字体和颜色的方法.分享给大家供大家参考.具体如下: WPF 获取所有的字体: System.Drawing.Text.InstalledFontCollection font = new System.Drawing.Text.InstalledFontCollection(); System.Drawing.FontFamily[] array= font.Families; foreach (var v in array) { MessageBox.Sh

  • C# WPF Image控件的绑定方法

    在我们平时的开发中会经常用到Image控件,通过设置Image控件的Source属性,我们可以加载图片,设置Image的source属性时可以使用相对路径也可以使用绝对路径,一般情况下建议使用绝对路径,类似于下面的形式Source="/Demo;Component/Images/Test.jpg"其中Demo表示工程的名称,后面表示具体哪个文件夹下面的哪个图片资源,在程序中,我们甚至可以为Image控件设置X:Name属性,在后台代码中动态去改变Image的Source,但我个人认为这

  • C# WPF ListView控件的实例详解

    C# WPF ListView控件的实例详解 C#的WPF作为现在微软主流的桌面程序开发平台,相比过去的MFC时代,有了非常多的不同.本人刚从MFC平台转过来,以为可以轻松上手,哪知碰到了很多问题,十分不解.不得不乖乖回去看了本书,再继续回到边左边边学的路上.在这边也推荐<深入浅出WPF>这本书,拿来上手还是极好的. 由于WPF以数据驱动UI的设计理念,很多控件用起来都与之前平台的相差很多,ListView控件算是有代表性的,这是进化的成果.关于该控件的应该,很多参考了这篇博文,如觉本人记述不

  • C#中WPF使用多线程调用窗体组件的方法

    本文实例讲述了C#中WPF使用多线程调用窗体组件的方法.分享给大家供大家参考.具体如下: Thread thread=new Thread(new ThreadStart(TestThread)); thread.Start(); private void TestThread() { for (int i = 0; i < 11;i++ ) { Thread.Sleep(2000); this.listBox1.Dispatcher.Invoke(new Action(() => { thi

  • 在C# WPF下自定义滚动条ScrollViewer样式的操作

    一.实现对ScrollViewer样式的自定义主要包括: 1.滚动条宽度设置 2.滚动条颜色 3.滚动条圆角 4.滚动条拉动时的效果mouseover 二.实现效果: 三.实现方法 1.创建资源字典( ResourceDictionary)文件 由于style代码比较多,之间在控件文件中加载style比较混乱,也不利于其它窗口复用,这里单独创建了ScrollViewDictionary.xaml文件代码如下: <ResourceDictionary xmlns="http://schema

  • C#中WPF ListView绑定数据的实例详解

    C#中WPF ListView绑定数据的实例详解 WPF中ListView用来显示数据十分方便, 我们可以将它分成几个列,每一个列用来显示一条数据,但是又是在一方之中. 那么怎样实现这样的效果的呢,这就要用绑定了. 我们先来看一看他的xmal代码 <ListView Name="receiveList" Grid.Row="0"> <ListView.View> <GridView> <GridView.Columns>

  • c# wpf如何使用Blend工具绘制Control样式

    本文通过设计一个RadioButton,分享下使用Blend绘制Path的方法.待绘制的RadioButton样式如下文所示,如有更好的方法实现该样式,欢迎交流. 实现效果 将要实现的RadioButton样式如下图,可以看出按钮的笔尖和笔身的填充色,以及选中时右上方圆形的填充色一致,代表笔的颜色. 实现方式 笔身使用矩形,填充色绑定按钮背景色:笔头部分使用闭合的Path,其中笔尖的颜色同样绑定按钮背景色:右上方的圆形使用Ellipse,填充色同样绑定按钮背景色. 实现步骤 1.打开Blend,

  • C# WPF 通过委托实现多窗口间的传值的方法

    在使用WPF开发的时候就不免会遇到需要两个窗口间进行传值操作,当然多窗口间传值的方法有很多种,本文介绍的是使用委托实现多窗口间的传值. 在上代码之前呢,先简单介绍一下什么是C#中的委托(如果只想了解如何传值可以略过这部分)在网络上有很多对于委托的介绍和讲解,经过我的学习和总结加上了一点我自己的理解,我认为委托是一种类似于C语言的指针,但是它指向的是方法而不是变量.如果把委托看作一个变量,那么这个变量里存着的就是你目标方法的地址,调用委托约等于调用你的目标方法.(个人理解欢迎指正交流) 以下正文:

  • c# wpf使用GMap.NET类库,实现地图轨迹回放

    前言 实现轨迹回放,GMap.NET有对应的类GMapRoute.这个类函数很少,功能有限,只能实现简单的轨迹回放.要实现更复杂的轨迹回放,就需要自己动手了. 本文介绍一种方法,可以实现复杂的轨迹回放.有句话"功夫在诗外",GMap.NET给你提供了基本地图处理功能:但是不要让CMap.NET束缚了手脚.你需要有深刻理解地图实现原理,深入理解WPF动画的原理,才能到达随心所欲.最终的效果如下: GMap.NET 显示原理 地图就是由许多方格"瓦片"组合而来.当你移动

  • C# wpf使用ffmpeg命令行实现录屏的示例代码

    目录 前言 一.主要步骤 1.使用 AllowsTransparency实现穿透框 2.获取音频设备名称 3.命令行启动ffmpeg 4.使用JobObject管理子进程 二.完整代码 三.效果预览 1.录制中 2.录制动态流程 总结 前言 上一章我们实现了截屏界面与功能,接下来可以在此基础上实现录屏功能,录屏采用ffmpeg命令行实现会方便一些,效果也是不错的,当然前提是要对Windows子进程的控制比较熟悉,做出来之后完全可以满足项目使用. 一.主要步骤 1.使用 AllowsTranspa

  • 命令行批量截图Node脚本示例代码

    批量截图任务 作为一个软件工程师,不只是做好自己的本职工作(iOS),而是需要解决项目中的技术问题.这次就是解决自动截图的问题 早期公司的数据工程师利用 phantomjs 来截图,后期不断发现截图效率低,加之开发者团队不再维护,因此决定将截图这部分跟你剥离开来,以后方便开发维护.我就承担了这个工作 puppeteer Puppeteer is a Node library which provides a high-level API to control Chrome or Chromium

  • python调用ffmpeg命令行工具便捷操作视频示例实现过程

    目录 最重要的事 裁剪视频 计算分段 获取视频长度 分段 获取文件 代码集成 总结 参考资料 文 | 李晓飞 来源:Python 技术「ID: pythonall」 最近有了一个新任务,需要将赛事视频,拆分成两分钟以内的小段,用于发布到短视频平台上. 本以为是个一次性的工作,结果赛事视频数据巨大,视频文件长短不一,完全没法手工处理,于是 Python 又一次拯救了我. 还等什么,开始干吧! 最重要的事 无论做什么事情,都要去分析一下最重要的是什么,然后集中精力攻克,再继续找最重要的事. 对我们这

  • 在Linux 命令行终端分屏的两种工具

    下面介绍两种终端分屏工具:screen和tmux 一.使用screen分屏(只能上下分屏,不能左右分屏) (1)安装工具 在ubuntu系统中使用sudo apt-get install screen 安装screen工具 (2)使用工具 1,输入命令screen使用工具 2,上下分屏:ctrl + a  再按shift + s 3,切换屏幕:ctrl + a  再按tab键 4,新建一个终端:ctrl + a  再按c 5,关闭一个终端:ctrl + a  再按x (或直接按exit退出) 二

  • Python脚本开发中的命令行参数及传参示例详解

    目录 sys模块 argparse模块 Python中的正则表达式 正则表达式简介 Re模块 常用的匹配规则 sys模块 在使用python开发脚本的时候,作为一个运维工具,或者是其他工具需要在接受用户参数运行时,这里就可以用到命令行传参的方式,可以给使用者一个比较友好的交互体验. python可以使用 sys 模块中的 sys.argv 命令来获取命令行参数,其中返回的参数是一个列表 在实际开发中,我们一般都使用命令行来执行 python 脚本 使用终端执行python文件的命令:python

  • WPF+ASP.NET SignalR实现后台通知功能的示例代码

    目录 涉及知识点 前提条件 服务端 客户端 运行示例 在实际业务中,当后台数据发生变化,客户端能够实时的收到通知,而不是由用户主动的进行页面刷新才能查看,这将是一个非常人性化的设计.比如数字化大屏,并没有人工的干预,而是自动的刷新数据,那如何才能实现数据的实时刷新呢?本文以一个简单示例,简述如何通过WPF+ASP.NET SignalR实现消息后台通知以及数据的实时刷新,仅供学习分享使用,如有不足之处,还请指正. 通过上一篇文章的学习,了解了如何通过SignalR实现在线聊天功能,在示例中,我们

  • oracle命令行删除与创建用户的代码

    oracle命令行删除用户:  复制代码 代码如下: connect / as sysdba;    shutdown abort;    startup;    drop user user1 cascade;    exit oracle命令行创建用户:     复制代码 代码如下: create user user1     identified by values 'fa091872a2cc669c'     default tablespace user1     temporary 

  • Python编程实现控制cmd命令行显示颜色的方法示例

    本文实例讲述了Python编程实现控制cmd命令行显示颜色的方法.分享给大家供大家参考,具体如下: 基于win7 + python3.4 运行效果: import ctypes import sys '''Windows CMD命令行颜色''' # 句柄号 STD_INPUT_HANDLE = -10 STD_OUTPUT_HANDLE= -11 STD_ERROR_HANDLE = -12 # 前景色 FOREGROUND_BLACK = 0x0 # 黑 FOREGROUND_BLUE = 0

  • 关于Linux命令行下的数学运算示例详解

    前言 有几个有趣的命令可以在 Linux 系统下做数学运算: expr . factor . jot 和 bc 命令. 可以在 Linux 命令行下做数学运算吗?当然可以!事实上,有不少命令可以轻松完成这些操作,其中一些甚至让你大吃一惊.让我们来学习这些有用的数学运算命令或命令语法吧. expr 首先,对于在命令行使用命令进行数学运算,可能最容易想到.最常用的命令就是 expr ( 表达式 expression .它可以完成四则运算,也可以用于比较大小.下面是几个例子: 变量递增 $ count

  • Java简单实现调用命令行并获取执行结果示例

    本文实例讲述了Java简单实现调用命令行并获取执行结果.分享给大家供大家参考,具体如下: import java.io.BufferedReader; import java.io.InputStreamReader; public class Command { public static void exeCmd(String commandStr) { BufferedReader br = null; try { Process p = Runtime.getRuntime().exec(

随机推荐