ICode9

精准搜索请尝试: 精确搜索
首页 > 编程语言> 文章详细

基于TightVNC源码实现远程桌面本地录像功能(OpenCV)

2021-11-09 15:05:14  阅读:367  来源: 互联网

标签:weight int OpenCV 源码 远程桌面 lp buf cv


一.出发点:

  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进程远程桌面连接时,都在本地会保存一个本次操作的远程桌面录像文件。

  

 

   

 

标签:weight,int,OpenCV,源码,远程桌面,lp,buf,cv
来源: https://www.cnblogs.com/feixiang-energy/p/15528903.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有