原博客地址:https://www.cnblogs.com/feixiang-energy/p/15528903.html
一.出發點:
tightVNC是一個用在windows上的很好的遠程桌面工具,實現了遠程桌面、文件傳輸等功能。 但是沒有實現遠程桌面錄像保存的功能。
tightVNC使用遠程桌面協議 (RDP) 實現終端服務器和終端服務器客戶端之間的通信。客戶端將服務器端的屏幕拼接成幀圖片進行展示。為了實現屏幕錄制的功能,考慮基於tightVNC的源碼進行修改,在客戶端展示屏幕幀的同時,增加一個線程將已經拼接好的連續的屏幕幀圖片保存為視頻文件。
使用了OpenCV的cv::VideoWriter對象,將連續的圖片保存為視頻文件。經過初步測試,能達到客戶端本地遠程桌面錄像的功能。
現在把實現方式貼出來,希望對有需要的人提供些參考。
二.源碼下載:
tightVNC官網有C++版本的開源代碼可供下載:
https://www.tightvnc.com/download.php

三.實現方式:
使用VS2019打開並編譯源碼。我使用的是tightvnc-2.8.27-gpl版本。
修改viewer-core/RemoteViewerCore類,在里面增加一個record_fun的處理函數實現對遠程桌面屏幕的錄制。
主要代碼如下:
//遠程桌面客戶端屏幕錄制線程 DWORD _stdcall RemoteViewerCore::record_fun(LPVOID lparam) { Sleep(1000); //遠程桌面客戶端連接對象 RemoteViewerCore* lp = (RemoteViewerCore*)lparam; //視頻文件名稱 char file_name[256] = { 0 }; time_t t = time(0); char time_str[64]; strftime(time_str, sizeof(time_str), "%Y%m%d%H%M%S", localtime(&t)); sprintf(file_name, "video/video_%s_%s.mp4", lp->m_host_name, time_str); //獲取遠程桌面屏幕幀的分辨率 Dimension dimension = lp->m_frameBuffer.getDimension(); int weight = dimension.width; int hight = dimension.height; //opencv的視頻保存對象,初始化大小為0.5倍,是為了對分辨率進行裁剪 cv::VideoWriter writer; writer.open(file_name, CV_FOURCC('m', 'p', '4', 'v'), 9, cv::Size(weight * 0.5, hight * 0.5), true); //tightvnc遠程桌面屏幕幀編碼格式為RGBA //初始化一個4倍分辨率的數組用於保存幀二進制數據 int buf_len = weight * hight * 4; char* buf = new char[buf_len]; while (lp->m_record_flag) { int start = clock(); //初始化一個RGB格式的Mat對象 cv::Mat dst = cv::Mat::zeros(hight, weight, 16); memset(buf, 0, buf_len); memcpy(buf, lp->m_frameBuffer.getBuffer(), lp->m_frameBuffer.getBufferSize()); //將視頻幀的數據RGB數據保存到對應的Mat對象中 for (int i = 0; i < hight; i++) { for (int j = 0; j < weight; j++) { dst.at<cv::Vec3b>(i, j)[0] = buf[(i* weight + j) * 4]; dst.at<cv::Vec3b>(i, j)[1] = buf[(i * weight + j) * 4 + 1]; dst.at<cv::Vec3b>(i, j)[2] = buf[(i * weight + j) * 4 + 2]; } } int used = clock() - start; //對Mat對象進行圖片裁剪 cv::Mat dst1; cv::resize(dst, dst1, cv::Size(weight * 0.5, hight * 0.5)); //將圖片寫入到視頻保存對象 writer.write(dst1); //休眠100毫秒。這個時間間隔可以用來控制每秒中保存的視頻圖像幀數,即控制碼率。 Sleep(100); } //釋放掉二進制數組。 delete[]buf; return 0; }
四.實現效果:
每次使用重新編譯過的TightVNCViewer進程遠程桌面連接時,都在本地會保存一個本次操作的遠程桌面錄像文件。