使用的開源的視頻處理組件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(); } } }