基於FFMpeg的C#錄屏全攻略

      最近負責一個錄屏的小項目,須要錄製Windows窗口內容並壓縮保存到指定文件夾,本想使用已有的錄屏軟件,可是本着學習的態度去探索了FFMpeg,本文主要介紹基於FFMpeg開源項目的C#錄屏軟件開發。html

     在Windows平臺下開發錄屏相比Linux比較複雜,Windows平臺下錄屏有gdigrab和dshow兩種方法,因爲gdigrab可修改屬性受限,因此本文采用dshow方法實現錄屏的功能,原理是註冊錄屏dshow濾鏡(例如screen-capture-recorder),而後經過dshow獲取錄屏圖像而後編碼處理,其中gdigrab能夠詳見http://www.ffmpeg.org/ffmpeg-devices.html#gdigrab。shell

    軟件開發環境:ide

    Windows7 32位函數

    Visual Studio2013學習

    screen capture recorder(須要Java運行環境Java Runtime Environment)測試

     一、軟件安裝完成後,能夠在CMD命令行中檢測軟件安裝是否正確,首先進入FFMpeg.exe的根目錄文件夾,輸入命令:ffmpeg -list_devices true -f dshow -i dummy 命令執行後檢查輸出的結果是否有[dshow @xxx] "screen-capture-recorder" ,若是有則「screen capture recorder」軟件安裝正確。編碼

    二、錄屏測試:spa

    在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解碼包。.net

 

 

三、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

相關文章
相關標籤/搜索