基于FFMpeg的C#录屏全攻略

      最近负责一个录屏的小项目,需要录制Windows窗口内容并压缩保存到指定文件夹,本想使用已有的录屏软件,但是本着学习的态度去探索了FFMpeg,本文主要介绍基于FFMpeg开源项目的C#录屏软件开发。

     在Windows平台下开发录屏相比Linux比较复杂,Windows平台下录屏有gdigrab和dshow两种方法,由于gdigrab可修改属性受限,所以本文采用dshow方法实现录屏的功能,原理是注册录屏dshow滤镜(例如screen-capture-recorder),然后通过dshow获取录屏图像然后编码处理,其中gdigrab可以详见http://www.ffmpeg.org/ffmpeg-devices.html#gdigrab。

    软件开发环境:

    Windows7 32位

    Visual Studio2013

    screen capture recorder(需要Java运行环境Java Runtime Environment)

     1、软件安装完成后,可以在CMD命令行中检测软件安装是否正确,首先进入FFMpeg.exe的根目录文件夹,输入命令:ffmpeg -list_devices true -f dshow -i dummy 命令执行后检查输出的结果是否有[dshow @xxx] "screen-capture-recorder" ,如果有则“screen capture recorder”软件安装正确。

    2、录屏测试:

    在CMD窗口中进入FFMpeg.exe所在的根目录文件夹,输入录屏指令:ffmpeg -f dshow -i video="screen-capture-recorder" -r 15 -vcodec libx264 -preset:v ultrafast -tune:v zerolatency MyDesktop.mkv

      如果上述指令执行后,可以在FFMpeg软件的根目录生成MyDesktop.mkv的视频文件则录屏成功,如果MyDesktop.mkv无法播放,需要注意播放器是否支持H264协议,可以考虑使用VLC media player播放器,或者安装Win7codecs解码包。

3、C#开发

      C#程序中调用FFMpeg.exe程序,并且不显示命令行窗口界面,来完成FFMpeg.exe的录屏功能,在视频录制完成后对视频文件进行压缩,其中主要函数如下所示。注意:在CMD命令行中FFMpeg.exe输出的结果需要在ErrorDataReceived中创建事件才可以显示。

 1 public void RunFFmpeg()
 2 
 3         {
 4 
 5             Process[] KillProcessArray = Process.GetProcessesByName("ffmpeg");
 6 
 7             Debug.WriteLine(KillProcessArray.Length.ToString());
 8 
 9             foreach (var KillProcess in KillProcessArray)
10 
11             {
12 
13                 KillProcess.Kill();
14 
15             }
16 
17             Process p = new Process();//建立外部调用线程
18 
19             p.StartInfo.FileName = @"E:\ffmpeg\ffmpeg.exe";   //ffmpeg.exe的绝对路径
20 
21             p.StartInfo.Arguments = @"-f dshow -i video=""screen-capture-recorder"" -r 15 -vcodec libx264 -preset:v ultrafast -tune:v zerolatency D:\MyDesktop.mkv";  //ffmpeg的参数
22 
23             p.StartInfo.UseShellExecute = false;           //是否使用操作系统shell启动
24 
25             p.StartInfo.RedirectStandardError = true;      //重定向标准错误输出
26 
27             p.StartInfo.CreateNoWindow = true;             //不显示程序窗口
28 
29             p.ErrorDataReceived += new DataReceivedEventHandler(Output);
30 
31             p.Start();
32 
33             myProcessId = p.Id;                            //获取关联进程的唯一标识符
34 
35             p.BeginErrorReadLine();
36 
37         }
38 
39         public void StopFFmpeg()
40 
41         {
42 
43             Process myProcess = Process.GetProcessById(myProcessId);  //通过ID关联进程
44 
45             myProcess.Kill();
46 
47         }
48 
49         private void Output(object sendProcess,DataReceivedEventArgs output)
50 
51         {
52 
53             if (!String.IsNullOrEmpty(output.Data))
54 
55                 Debug.WriteLine(output.Data.ToString());
56 
57         }
58 
59         static void Main(string[] args)
60 
61         {
62 
63             CmdHelper ch = new CmdHelper();
64 
65             ch.RunFFmpeg();
66 
67             Console.WriteLine("Hello");
68 
69             Thread.Sleep(10000);
70 
71             Console.WriteLine("10s passed");
72 
73             ch.StopFFmpeg();
74 
75         } 

参考链接:

http://blog.csdn.net/zhichao2001/article/details/12526095

http://blog.csdn.net/leixiaohua1020/article/details/38284961

http://www.ffmpeg.org/ffmpeg-devices.html#gdigrab

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏lhyt前端之路

pwa+webpack,初探与踩坑0.前言1.webpack2.pwa3.基于webpack的pwa

我们都知道pwa是一个新技术.,依靠缓存,离线了还能正常跑,而且秒开。我把以前原生写的小游戏迁移到react,再迁移到webpack+react,最后再升级到p...

622
来自专栏信安之路

从暴力枚举用户到获取域所有信息

我们在进行内网渗透中,会遇到存在 windows 域环境的情况,当我们获得一个内网主机权限之后,这个主机可能没有加入域,我们无法直接通过在这个主机上获取域中的相...

640
来自专栏信安之路

Linux 闯关游戏之通关秘籍

强盗战争是针对绝对的初学者。它将教授需要能够玩其他战争游戏的基础知识,通过这个游戏能学习到很多 Linux 的基础知识。和大多数其他游戏一样,这个游戏按层次组织...

1526
来自专栏小狼的世界

使Windows Vista 也支持cUrl扩展

我们都知道PHP的扩展在php.ini中只要将extension前的注释去掉就可以,可是我在Vista下使用php_curl.dll时,却怎么都无法正常运行,到...

632
来自专栏web编程技术分享

列举两个前端开发中的“灵异事件”0102

3235
来自专栏向治洪

android打包引用第三方jar出现的错误

今天终于完成了近一个月的App开发工作,对程序进行混淆导出签名apk包时,却出现了如下的错误: Proguard returned with error cod...

1826
来自专栏晨星先生的自留地

漏洞分析| Humax WiFi路由器多个漏洞可获取管理员权限

1533
来自专栏转载gongluck的CSDN博客

打开文件open()函数的使用方法详解

头文件:#include <sys/types.h>    #include <sys/stat.h>    #include <fcntl.h> 定义函数...

2625
来自专栏Lambda

TortoiseSVN文件夹及文件图标不显示解决方法 TortoiseSVN文件夹及文件图标不显示解决方法

TortoiseSVN文件夹及文件图标不显示解决方法           由于自己的电脑是win7(64位)的,系统安装TortoiseSVN之后,其他的功...

2008
来自专栏前端杂货铺

puppeteer实现线上服务器任意区域截图

整个九月份由于业务繁重以及玩心颇重,一直没有机会来写一篇博文。而且笔者于十月一日将会举办人生大事--婚礼,现在家里筹办过程中只能抽出零碎的时间来写这篇文章。

762

扫码关注云+社区