C#基于FFmpeg实现录屏功能
⼀、前⾔
上⼀篇⽂章已经知道了FFmpeg的录屏命令格式,那么,如何⾃⼰开发c#程序,实现录屏功能呢?其实单纯利⽤c#开发录屏软件,⽅法有
很多:
可以基于Accord(AForge)⾃⾏开发,思路就是以⼀定时间间隔捕获屏幕,再利⽤Accord实现⾼效的视频编码等,但是这样做⼀是稍微复杂了⼀点,⼆是不知道怎么利⽤GPU加速,毕竟占CPU太⾼的话,影响使⽤。⼤神可以⾃⾏研究⼀下。
可以基于FFmpeg.AutoGen开发,这个可以看做是FFmpeg的C#版吧,但是这个东西对.Net Framework4.5以上兼容性不好啊,原作者貌似现在也没解决这个问题,总之就是没研究明⽩,还浪费了不少时间,先放弃了。
可以基于OpencvSharp,原理与Accord类似,⾃⼰实现录屏的捕获桌⾯、编码等全过程,没试过,不知道效率怎么样,不过以
opencv的尿性,应该值得信赖吧。
可以基于ScnLib,这是⼀家公司开发的录屏SDK,有各种语⾔实现的版本,能试⽤(有⽔印),东西好是真的好,但是也真贵啊,本着程序员⾃给⾃⾜的精神,花钱买它真是羞耻。(⼟豪忽略)
可以基于,c#程序后台调⽤这个进程,实现录屏,实际上就是借⽤来实现录屏,这个⽅法简单,⽽且⼈家
FFmpeg做的那么好,⼲嘛不⽤呢,节约时间,开⼲吧。
⼆、⽅法
通过调⽤系统API加载,向其模拟输⼊命令的的⽅式进⾏录屏录⾳,然后模拟输⼊q⽤于暂停录制。具体实现⽅式如下,直接上
代码:
public class ScreenRecordHelper
{
#region 模拟控制台信号需要使⽤的API
[DllImport("kernel32.dll")]
static extern bool GenerateConsoleCtrlEvent(int dwCtrlEvent, int dwProcessGroupId);
[DllImport("kernel32.dll")]
static extern bool SetConsoleCtrlHandler(IntPtr handlerRoutine, bool add);writeline方法的作用
[DllImport("kernel32.dll")]
static extern bool AttachConsole(int dwProcessId);
[DllImport("kernel32.dll")]
static extern bool FreeConsole();
#endregion
//ffmpeg进程
static Process ffmpegProcess = new Process();
/
/实体⽂件路径,建议把及其配套放在⾃⼰的Debug⽬录下
static string ffmpegPath = AppDomain.CurrentDomain.BaseDirectory + "bin\\";
//static string ffmpegPath = @"C:\Users\awang\Desktop\ScreenRecord\ffmpeg-N-101429-g54e5d21aca-win64-gpl-shared-vulkan\";
/// <summary>
/// 开始录制
/// </summary>
/// <param name="outFilePath">录屏⽂件保存路径</param>
public static void Start(string outFilePath)
{
if (File.Exists(outFilePath))
{
File.Delete(outFilePath);
}
string arguments = "-f gdigrab -framerate 15 -r 15 -i desktop -pix_fmt yuv420p -f dshow -i audio=" + "\"virtual-audio-capturer\"" + " -vcodec" + " h264_qsv"
/*转码,
* 视频录制设备:gdigrab;
* 录制对象:整个桌⾯desktop;
* ⾳频录制⽅式:dshow;
* ⾳频输⼊:virtual-audio-capturer;
* 视频编码格式:h.264;
* 视频帧率:15;
* 硬件加速:若N卡加速:h264_nvenc;若集显加速:h264_qsv;若软件编码:libx264;
*/
ProcessStartInfo startInfo = new ProcessStartInfo(ffmpegPath);
startInfo.WindowStyle = ProcessWindowStyle.Normal;
startInfo.Arguments = arguments;
startInfo.UseShellExecute = false;//不使⽤操作系统外壳程序启动
startInfo.RedirectStandardError = true;//重定向标准错误流
startInfo.CreateNoWindow = true;//默认不显⽰窗⼝
startInfo.RedirectStandardInput = true;//启⽤模拟该进程控制台输⼊的开关
//startInfo.RedirectStandardOutput = true;
ffmpegProcess.ErrorDataReceived += new DataReceivedEventHandler(Output);//把FFmpeg的输出写到StandardError流中            ffmpegProcess.StartInfo = startInfo;
ffmpegProcess.Start();//启动
ffmpegProcess.BeginErrorReadLine();//开始异步读取输出
}
/// <summary>
/// 停⽌录制
/// </summary>
public static void Stop()
{
ffmpegProcess.StandardInput.WriteLine("q");//在这个进程的控制台中模拟输⼊q,⽤于停⽌录制
ffmpegProcess.Close();
ffmpegProcess.Dispose();
}
/
// <summary>
/// 控制台输出信息
/// </summary>
private static void Output(object sender, DataReceivedEventArgs e)
{
if (!String.IsNullOrEmpty(e.Data))
{
Console.WriteLine(e.Data.ToString());
}
}
}
搞定 舒服了

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。