1、ffmpeg.exe只是一個外圍程序,其核心邏輯在libavcodec.dll和libavformat.dll,libavdevice.dll等
之所以是外圍,相當於一個GUI,也就是說基於這些dll,你可以寫自己的外圍程序,比如做成特別的功能齊全的錄屏軟件或windows GUI的轉碼軟件
2、libavcodec超過30mb,要想變小必須自己編譯ffmpeg,放棄大量對你無用的encoder和decoder,這樣可以降到2MB以內
3、ffmpeg錄屏
如果使用gdigrab只能支持錄製20fps以內的,以上將導致cpu佔比超過30%,而且如果同時錄音的話,則會產生巨大的幀延遲
ffmpeg.exe -y -rtbufsize 100M -f gdigrab -framerate 15 -offset_x 0 -offset_y 0 -video_size 1920x1080 -draw_mouse 1 -i desktop -f dshow -i audio="麥克風 (Realtek High Definition Au" -c:v libx264 -r 15 -preset ultrafast -tune zerolatency -crf 25 -pix_fmt yuv420p -c:a libmp3lame -qscale:a 4 "output-grab15.mp4"
如果使用creen-capture-recorder雖然可以達到30fps,但是cpu佔比高達50%以上
4、ffmpeg -h encoder=libx264可以查看支持什麼pixformat
我嘗試過通過c++程序直接把rgba數據格式AV_PIX_FMT_BGRA(ARGB)直接avcodec_encode_video2到x264格式的mp4文件,會提示[libx264 @ 004b1e60] Specified pixel format bgra is invalid or not supported,通過上述命令可以查到:
Encoder libx264 [libx264 H.264 / AVC / MPEG-4 AVC / MPEG-4 part 10]:
General capabilities: delay threads
Threading capabilities: auto
Supported pixel formats: yuv420p yuvj420p yuv422p yuvj422p yuv444p yuvj444p nv12 nv16 nv21
可以說mp4只支持yuv系列的數據格式,這些格式中以yuv420p爲主,是ffmpeg的默認編碼輸入的格式。
5、關於yuv420p格式:
yuv420p格式,如果不經過準確處理,會導致嚴重的失真,原因是yuv格式並不是無損格式,只是損失比較小,但是其大小確實比rgb24格式節省了一半的存儲空間。
如rgb經過變換yuv格式,再變換回rgb格式後,絕對值的和(absSum(r,g,b))要比原來有2-30的誤差,導致顏色有一些細微變化。
在我的轉換中,雖然清晰度很高,但是某些細微的地方總是出現顏色變化,特別是亮度明顯比原來變暗。
但是swscale內部的變換代碼卻能比較好的處理這種格式,覺察不出有顏色變化,如果有人能從ffmpeg裏面提取一個rgb2yuv420p的函數,請告知一下。
而yuv420p2rgb的函數在https://github.com/FFmpeg/FFmpeg/blob/master/libswscale/yuv2rgb.c或http://www.fourcc.org/fccyvrgb.php 找到,或者使用swscale內部的函數:
SwsContext *img_convert_ctx= sws_getContext(w,h,AV_PIX_FMT_BGRA, w,h,AV_PIX_FMT_YUV420P, SWS_BICUBIC, NULL, NULL, NULL);
int op=sws_scale(img_convert_ctx, (const unsigned char* const*)srcFrame->data, (const int*)srcFrame->linesize, 0,h, dstFrame->data, dstFrame->linesize);
記得linesize都是一個二維數組,必須對srcFrame進行初始化才能成功,或則會提示數據沒有對齊的錯誤
對於rgba數據,必須這樣初始化:
AVFrame *srcFrame = av_frame_alloc();
srcFrame ->data[0]=in_frame_data;//rgba的數據
srcFrame ->linesize[0]=in_linesize;//像素個數x4
這樣轉換的yuv420p數據就會轉換到srcFrame->data裏面
6、其他關於錄屏的方案
1、先錄製yuv420p的文件、pts時間文件和音頻文件再後期通過ffmpeg轉成mp4
這個方案可以支持的fps應該是最高的,25fps的錄製,cpu佔有率不會高於20%
風險:視頻和音頻對不上,而且所需的磁盤文件極爲極大,1920x1080的25fps視頻60分鐘需要超過1T的存儲空間。
正方意見:專業電影錄製的時候也是音頻和視頻分開錄製的
反方意見:錄個屏幕,你有多少時間和精力做後期的處理?又有多少個高速硬盤可以用來錄屏?
所以,該方案對於非專業級的需求,是很不經濟的。
2、用ffmpeg.exe命令行錄製音頻和視頻,對於一般要求,這個基本可以解決問題,但是可控度不高
比如不能暫停,出錯不能及時得到通知,不能分文件保存。有點就是無需任何開發工作。這點優勢也是高到天花板上去了。
3、就是利用libavxxx.dll這些共享dll,開發自己的程序,以實現暫停、及時反饋、分文件
這個就需要開發了,雖然開發工作不算多,但是爲了穩定運行,對ffmpeg的api要有比較詳細的認知。否則性能和穩定性還不如ffmpeg本身。
以上僅爲備忘。