C# wpf使用ffmpeg命令行實現(xiàn)錄屏的示例代碼
前言
上一章我們實現(xiàn)了截屏界面與功能,接下來可以在此基礎上實現(xiàn)錄屏功能,錄屏采用ffmpeg命令行實現(xiàn)會方便一些,效果也是不錯的,當然前提是要對Windows子進程的控制比較熟悉,做出來之后完全可以滿足項目使用。
一、主要步驟
1、使用 AllowsTransparency實現(xiàn)穿透框
錄屏需要使用AllowsTransparency來實現(xiàn)透明背景,因為錄屏時框選區(qū)域需要能夠點擊穿透到桌面,使用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
得到了音頻設備名稱之后,我們就可以使用下面的命令行是實現(xiàn)錄屏了。
錄屏命令行,-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實現(xiàn)這一功能。C#需要使用dllimport包裝Job Object的WinApi。
下面是部分示例代碼:創(chuàng)建了作業(yè)對象,并設置為對象銷毀后,加入的進程全部退出。
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()));
二、完整代碼
實現(xiàn)了錄屏功能,包括畫面和聲音的錄制,只依賴ffmpeg.exe。
之后上傳
三、效果預覽
1、錄制中
2、錄制動態(tài)流程
總結
以上就是今天要講的內容了,因為使用了命令行所以錄屏邏輯不用自己實現(xiàn),但是要控制ffmpeg子進程還是有不少細節(jié)需要處理的,比如進程自動退出、信息反饋、停止錄屏、異常提示等。另外一方面在界面上也有需要處理的東西,比如可控的點擊穿透、控制窗口置頂?shù)鹊???偟膩碚f,實現(xiàn)這一一個功能模塊還是需要一定的時間和精力,以及一些相關的知識。
到此這篇關于C# wpf使用ffmpeg命令行實現(xiàn)錄屏的示例代碼的文章就介紹到這了,更多相關C# wpf ffmpeg命令行錄屏內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
相關文章
C#更新SQLServer中TimeStamp字段(時間戳)的方法
這篇文章主要介紹了C#更新SQLServer中TimeStamp字段(時間戳)的方法,涉及C#操作數(shù)據(jù)庫字段的相關技巧,需要的朋友可以參考下2015-05-05深入理解C#索引器(一種支持參數(shù)的屬性)與屬性的對比
本篇文章是對C#索引器(一種支持參數(shù)的屬性)與屬性的對比進行了詳細的分析介紹,需要的朋友參考下2013-06-06