使用的开源的视频处理组件AForge,当然它所包含的功能远不止于此,想了解更多到官网上去看吧。一下代码主要是录制桌面屏幕,每20秒存入一个视频文件,可以为有类似需要的同学提供一点帮助。
注:在指定时间启动录制那个功能下面代码没有做,有需要的可以自己改一下代码。
/// <summary> /// 比特率 /// </summary> public enum BitRate : int { _50kbit = 5000, _100kbit = 10000, _500kbit = 50000, _1000kbit = 1000000, _2000kbit = 2000000, _3000kbit = 3000000 }
/// <summary> /// 屏幕录制模板 /// </summary> public class ScreenRecorderTemplate { /// <summary> /// 模板名称 /// </summary> public string TmpName { get; set; } /// <summary> /// 录屏开始时间 /// </summary> public DateTime? StartDateTime { get; set; } /// <summary> /// 录屏结束时间 /// </summary> public DateTime? StopDateTime { get; set; } /// <summary> /// 是否为开机启动 /// </summary> public bool IsStartUp { get; set; } }
using System; using System.Collections.Generic; using System.Diagnostics; using System.Drawing; using System.Linq; using System.Text; using System.Windows.Forms; using AForge.Video; using AForge.Video.FFMPEG; namespace ConsoleRecoderTest { /// <summary> /// 屏幕录制工具类 /// </summary> public class ScreenRecorderTool { #region Fields private int screenWidth; private int screenHight; private int bitRate = (int)BitRate._500kbit; private int frameRate = 5;//默认帧率为5 private bool isRecording; private string saveFolderPath; private string fileName; private Stopwatch stopWatch; private Rectangle screenArea; private VideoFileWriter videoWriter; private ScreenCaptureStream videoStreamer; private VideoCodec videoCodec = VideoCodec.MSMPEG4v2; private ScreenRecorderTemplate recorderTmp; private static object key = new object(); #endregion /// <summary> /// 是否正在录制 /// </summary> private bool IsRecording { get { lock (key) { return isRecording; } } set { lock (key) { isRecording = value; } } } public ScreenRecorderTool(ScreenRecorderTemplate recorderTmp) { this.recorderTmp = recorderTmp; this.screenWidth = SystemInformation.VirtualScreen.Width; this.screenHight = SystemInformation.VirtualScreen.Height; this.IsRecording = false; this.SaveFolderPath = AppDomain.CurrentDomain.BaseDirectory; this.stopWatch = new Stopwatch(); this.screenArea = Rectangle.Empty; SetScreenArea(); } /// <summary> /// 视频保存位置 /// </summary> private string SaveFolderPath { get { return this.saveFolderPath; } set { if (string.IsNullOrEmpty(value)) { throw new ArgumentNullException("saveFolderpath", "保存路径不能为空"); } this.saveFolderPath = value; } } /// <summary> /// 视频文件名称 /// </summary> private string FileName { get { return this.fileName; } set { if (string.IsNullOrEmpty(value)) { throw new ArgumentNullException("fileName", "File name can not be empty or null"); } this.fileName = value; } } /// <summary> /// 完成一帧录制的事件 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void video_NewFrame(object sender, NewFrameEventArgs e) { if (this.IsRecording) { if (videoWriter != null) { this.videoWriter.WriteVideoFrame(e.Frame); } if (this.stopWatch.Elapsed.Seconds >= 20) { Console.WriteLine("超过指定时间,写入文件"); StopRecording(); } } else { videoStreamer.SignalToStop(); videoWriter.Close(); videoWriter.Dispose(); //GC.Collect(); Console.WriteLine("停止录制"); if (recorderTmp.IsStartUp)//开机录制 { StartRecording(); } else { if (DateTime.Now <= recorderTmp.StopDateTime.Value) { Console.WriteLine("记录重启录制"); StartRecording(); } else { Console.WriteLine("时间到不再录制"); } } } } /// <summary> /// 设置必要参数打开视频写入工具 /// </summary> private void InitializeRecordingParameters() { if (!this.IsRecording) { this.IsRecording = true; CreateCatalog(); this.FileName = saveFolderPath + string.Format (@"{0}-{1}.avi", "MSR", DateTime.Now.ToString("yyyy-MM-dd-HH-mm-ss")); this.videoWriter.Open(this.FileName, this.screenWidth, this.screenHight, this.frameRate, this.videoCodec, this.bitRate); } } /// <summary> /// 创建目录 /// </summary> private void CreateCatalog() { if (saveFolderPath == AppDomain.CurrentDomain.BaseDirectory) { var catalog = SaveFolderPath + DateTime.Now.ToString("yyyy-MM-dd") + "\"; if (!System.IO.Directory.Exists(catalog)) { System.IO.Directory.CreateDirectory(catalog); } SaveFolderPath = catalog; } } /// <summary> /// 设置屏幕录制区域为全屏 /// </summary> private void SetScreenArea() { foreach (Screen screen in Screen.AllScreens) { this.screenArea = Rectangle.Union(this.screenArea, screen.Bounds); } if (this.screenArea == Rectangle.Empty) { //logger.Error("没有获取到屏幕信息"); throw new InvalidOperationException("Screan area can not be set"); } } /// <summary> /// 旧文件清理(避免文件大小超标) /// </summary> private void ClearOldVideo() { } #region public method /// <summary> /// 打开视频流开始录制 /// </summary> public void StartRecording() { if (recorderTmp == null) { Console.WriteLine("模板不能为空"); return; } if (!recorderTmp.IsStartUp) { if (!recorderTmp.StartDateTime.HasValue || !recorderTmp.StopDateTime.HasValue || recorderTmp.StartDateTime.Value > recorderTmp.StopDateTime.Value) { Console.WriteLine("模板不正确"); return; } } this.videoWriter = new VideoFileWriter(); InitializeRecordingParameters(); this.videoStreamer = new ScreenCaptureStream(this.screenArea); this.videoStreamer.NewFrame += new NewFrameEventHandler(video_NewFrame); this.videoStreamer.Start(); this.stopWatch.Start(); this.IsRecording = true; Console.WriteLine("开始录制..."); } /// <summary> /// 停止录制 /// </summary> public void StopRecording() { this.stopWatch.Reset(); this.IsRecording = false; } #endregion } }
示例调用:
using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace ConsoleRecoderTest { class Program { static void Main(string[] args) { ScreenRecorderTemplate tmp = new ScreenRecorderTemplate() { IsStartUp = false, StartDateTime = DateTime.Now, StopDateTime = DateTime.Now.AddMinutes(2) }; new ScreenRecorderTool(tmp).StartRecording(); Console.WriteLine("complete"); Console.Read(); } } }