單一視窗畫面擷取
前陣子有一名客戶希望能將大尺寸的螢幕平放,然後在兩個長邊的地方各坐兩個人,很像是一張桌子坐了四個人,兩兩相望。
不過由於客戶的程式只有單一視窗,也不能修改這隻程式讓它直接輸出就可以分四格畫面,且電腦主機只有一個 HDMI 輸出。
仔細想想,應該是要再另外寫一隻程式,不斷的去捕捉客戶的程式畫面,並複製成四宮格 (上面的那兩格要 180 度旋轉),蓋在整個畫面的上方。
一開始想到的是用 ffmpeg 針對客戶的程式去錄影並做成串流伺服器,我只要寫個程式去播放這個串流就好了。
不過可惜的是,Windows 似乎沒有 ffserver?所以還要弄成 ffmpeg + vlc 之類的… 有點複雜。我後來沒有採用這種方式,但,ffmpeg 能針對單一的視窗去錄影嗎?可以的,用 gdigrab
。
$ ffmpeg -re -f gdigrab -framerate 20 -draw_mouse 0 -i title=window_name \
-vcodec libx264 -preset ultrafast \
-tune zerolatency -f mpegts udp://127.0.0.1:1234
-i title=window_name
的 window_name
是你要錄影的視窗 title。-i desktop
則可以抓取整個桌面。gdigrab 的參數可以
參考這裡。
然後再搭配 vlc 作串流播出,這裡有影片教學。我測試的時候,效果不太好,會有點 lag,可能參數那邊要再調整。
後來我想到用 Qt 來試試看,找了一下資料,發現是有可能針對特定視窗去錄製畫面的。關鍵在 QScreen::grabWindow()
,大概的用法是:
#include <Windows.h>
Qscreen *screen = QGuiApplication::primaryScreen();
QPixmap picOrig = screen->grabWindow((WId) FindWindow(NULL, L"視窗名稱"));
// 旋轉
QTransform trans;
trans = trans.rotate(180);
QPixmap picTrans = picOrig.transformed(trans);
// 現在 picOrig 是正常的畫面,picTrans 是旋轉過的畫面
FindWindow() 是 Windows 的 API,所以要 #include <Windows.h>
。
再來就只要不斷的去抓取這個畫面就行了。
後來我發現是我誤會客戶的意思,所以… 就當作是一次寶貴的經驗吧。😦