1. 程式人生 > >在Windows下通過directshow錄製螢幕的教程

在Windows下通過directshow錄製螢幕的教程

轉載自A站,原文連結

這裡介紹的是Windows下的螢幕錄影方式.對於linux和mac黨,請自行搜尋關鍵字"ffmpeg X11",以上.

一句話介紹:註冊錄屏dshow濾鏡(例如screen-capture-recorder或者uscreen capture),然後通過dshow獲取錄屏影象來壓制,例如ffmpeg可以從dshow的對應濾鏡獲取錄屏資訊然後壓制存在硬碟或者送給rtmp伺服器,或者graphedit載入濾鏡然後使用avs的dshowsource載入grf檔案,送給壓制程式壓制.

如果上句話你能看懂或者通過google看懂,那麼你就可以ctrl+W了.如果看不懂,那麼請把這句話忘掉,然後把全文看完.

目前基佬們錄屏所使用的主要工具就是Fraps或者Xspilt.但是這些工具經常容易出現rp問題,往往只能重來.而且Fraps只能錄製出無損avi,對硬碟的體積和讀寫都是很大的傷害,Xspilt則只能錄屏後接著送到rtmp伺服器:這些工具都無法自己設定壓制設定,無法獲得更好的壓縮比.

當然有的童鞋會提到vfw.問題是一來就算是vfw,有的程式也不一定支援vfw輸出.二來MPEG B幀和AVI相容性很差(http://forum.doom9.org/showthread.php?p=215654#post215654).vfw並不能作為最完美的解決方案.

而這裡介紹的是通過DirectShow來自己完成螢幕的錄製.

首先介紹一下DirectShow.DirectShow是DirectX的元件的一部分,是Windows提供的對於媒體檔案的各種操作的一個通用介面,是VfW的"被"升級版.例如,我們可以直接通過DirectShow API來獲取某個視訊的解碼流,從而送到播放器中供使用者觀看——目前絕大多數基於Windows的播放器預設的播放方式都是如此.作為對比我們來看一下跨平臺的開源播放器mplayer,其解碼方式是自行呼叫libav庫,獲得解碼資料流和其它必需的資訊之後顯示給螢幕觀看,解碼過程中沒有DirectShow介面的參與.

DirectShow基於模組化的方式進行設計.每一個元件都被稱為一個Filter.例如,眾所周知FFMpeg的庫可以進行視訊音訊的分離解碼前處理等工作,而於是我們就可以將其修改程式碼製作成一個FIlter.這樣,當DirectShow介面獲取要解碼一個視訊檔案的請求的時候,DirectShow便可以呼叫這個Filter,獲取需要的資訊從而返回給發起請求的應用程式.順便說下這個Filter就是著名的ffdshow專案.

而更重要的是,我們可以註冊一個DirectShow Filter,獲取其它的視訊源資訊,依舊可以通過DirectShow介面返回給需要的程式.比如,如果有一個DirectShow介面能夠獲得當前計算機螢幕上的動態影象資訊並且作為視訊流返回給DirectShow介面,那麼只要我們有程式能夠獲得這段視訊流,我們就能實現在Windows下的螢幕錄製.

這是絕大多是基於WIndows的螢幕錄製程式的原理,也是我們這裡要使用的原理.

總結起來我們的螢幕錄製方法基本原理如下:

註冊用於螢幕錄影的DirectShow濾鏡,然後執行DirectShow濾鏡獲取螢幕動態影象,將獲取到的動態影象流通過視訊轉換程式轉換成需要的視訊格式.

下面來介紹具體的方法.當然具體方法肯定不止一個也不止兩個,喜歡玩的童鞋可以自己配置啦~

我們需要如下工具:

screen capture recorder

專案地址:https://github.com/rdp/screen-capture-recorder-to-video-windows-free

安裝程式下載地址:https://sourceforge.net/projects/screencapturer/files

ffmpeg

專案地址:http://www.ffmpeg.org/

可執行程式下載地址:http://ffmpeg.zeranoe.com/builds/

第一步,安裝screen capture recorder

安裝過程十分簡單,根據提示安裝即可.如果安裝失敗,請去下載安裝Java Runtime Environment

第二步是配置screen capture recorder.除去開始選單中所自帶的配置選項外,screen capture recorder的配置選項也可以在登錄檔的HKEY_CURRENT_USER/SOftware/screen-capture-recorder中找到.可以配置錄製視窗大小,錄製幀率等選項.


第二步下載ffmpeg.當然如果你之前就有ffmpeg並且你認為能夠使用的話也可以跳過這步.

安裝完畢後的screen capture recorder本身就自帶有錄屏功能,不過我們這裡可以自己使用ffmpeg,自行配置一些選項.

下面是我所使用的ffmpeg命令:

ffmpeg -f dshow -i video="screen-capture-recorder" -f dshow -i audio="virtual-audio-capturer" -pix_fmt yuv420p -ar 48000 -vcodec libx264 -crf 23 -preset veryslow -x264opts b-adapt=2:bframes=0:aq-strength=1:psy-rd=0.8,0 -vsync vfr -acodec libvo_aacenc -f mpegts - | ffmpeg -f mpegts -i - -c copy -bsf:a aac_adtstoasc -f flv temp.flv

其中,"-f dshow -i video="screen-capture-recorder" -f dshow -i audio="virtual-audio-capturer""是指定ffmpeg從dshow介面的兩個濾鏡中獲得輸入."-pix_fmt yuv420p"則是指定輸出的顏色空間.錄屏得到的視訊顏色空間都是RGB的,而壓制視訊時需要將其轉成YUV顏色空間.當然有的童鞋可能會開噴說rgb24轉成yuv420根本沒法看,但問題是請注意flash player只支援解碼yuv420的視訊,所以這是沒有辦法的事情撒~

這裡我們選用了libx264和libvo_aacenc作為編碼器.實際的壓制引數我們可以根據實際的視訊情況調整,這裡列舉的只是一個例子.像Fraps或者螢幕錄影專家就無法自行選擇編碼器和壓制引數,這就是使用dshow+ffmpeg自行錄屏的優勢所在.

最後第一個ffmpeg壓制出來的資料流將會封裝為mpeg TS格式然後傳遞給第二個ffmpeg.第二個ffmpeg接收此TS然後重新封裝為flv.這樣的處理方法在screen capture recorder自帶的錄屏選項中有,其主要目的是為了避免錄下的視訊出現過度的卡頓現象.

這樣執行此命令後,ffmpeg會不斷錄製生成flv檔案.當要結束錄屏的時候,在命令列介面中按一下q,錄屏就會停止,最終留下一個flv檔案.

此外,由於ffmpeg支援librtmp,因此如果我們把最終輸出的檔案地址設定成rtmp伺服器的地址的話,就可以將最終輸出的flv資料流直接傳送到rtmp伺服器上,這樣我們不需要Xspilt,就能變成生主啦~~~

這樣screen capture recorder+ffmpeg的方法介紹完了.當然具體的方法肯定不止這一種.比如,dshow源濾鏡就不止screen capture recorder這一種,uscreencapture也是可選的一種濾鏡.此外,從dshow獲取視訊流的方法也不止ffmpeg這一種,GraphEdit+AVS的組合技也是可以的.