基於TightVNC源碼實現遠程桌面本地錄像功能(OpenCV)


原博客地址: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進程遠程桌面連接時,都在本地會保存一個本次操作的遠程桌面錄像文件。

  

 

 
 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM