CSDN博客

img huangtyu

[Tech] 高效屏幕录制

发表于2004/10/26 11:03:00  7892人阅读

分类: 编程

http://blog.joycode.com/jiangsheng/archive/2004/01/01/10410.aspx

高效屏幕录制

屏幕录制有着广泛的用途,主要用于建立演示培训,或者远程屏幕监视和广播。由于屏幕的大小和色深通常很高,而且具有大块背景色、窗口拖动/卷动造成的内容移动和菜单弹出造成的瞬时变化等特性,因此需要在数据采集、压缩和传输/存储上多加考虑。

录制之前

录制之前,应该选择录制方法,压缩方式和录制范围。

有必要尽可能缩小录制的区域以减少数据量。在录制开始之前,可以让用户指定录制的范围,例如全屏幕,指定窗口,指定/自适应坐标等等。小的录制区域意味着更少的原始数据。

尽可能降低录制的色深以减少数据量。通常,用于简单教学的录制只需要256色。

录制之前,应该停用屏幕保护,桌布和活动桌面的一些特性以避免不必要的录制。

录制方法

录制分两种方式,一种是推模式,也就是录制模块不断录制数据,一种是拉模式,录制模块在需要的时候才录制数据。对于低带宽的场合,拉模式可以有效的减少原始数据量。对于需要基本无损回放的场合,推模式在监测到屏幕变化时就录制数据,可以减少视频质量的损失。在推模式下需要选取录制的时机,以避免大量的重复数据。

压缩编码

适当的编码方式可以有效地减少录制时的资源占用。

  • 联合图像专家组(Joint Photographic Experts Group,JPEG)编码
    在有损压缩时,对于静态图像具有比较好的压缩比率。但是有损压缩可能会使得屏幕上的文字变得模糊。
  • 运动图像专家(MPEG)组编码
    适合运动的图像,但是剧烈变化的图像,例如菜单的弹出,可能会暂时使录制的视频质量降低,以及CPU资源占用的升高。
  • 远程帧缓冲(Remote Frame Buffer,RFB)编码
    包括对于窗口拖动/卷动造成的内容移动造成的矩形复制(copy rectangle)和背景色的优化。对于每个矩形,可以有各种不同的编码方式,例如MPEG或者JPEG。
  • 分块比较编码
    将每次录制的屏幕分块和上次录制的屏幕内容比较,如果某块抽样变化了,那么编码整个块。对于每个块,可以有各种不同的编码方式,例如MPEG或者JPEG。

根据录制内容的不同,以及编码设置的不同(例如质量和分块大小设置),以上编码方式可能各有所长。

额外的考虑

  • 扫描线
    隔行扫描而不是逐行扫描屏幕数据可以有效地减少录制的数据量,同时录制的视频质量降低不大。
  • 录制时机
    虚拟显示设备或者适当的系统钩子可以使你在屏幕变化或者即将变化时得到通知,这样可以尽可能地减少录制的次数。参见http://ultravnc.sourceforge.net 以及http://www.realvnc.com 提供的VNC源代码中的VNCHooks。
  • DirectX
    使用DirectX可以进行直接的显存访问,这对提高性能很有好处。但是由于DirectX的特性,某些使用DirectX等技术的程序可能无法录制,例如大多数游戏和媒体播放器。解决的方法是局部或者全局地禁用部分或者全部DirectX加速功能。
  • 机器码
    在录制和编码过程中,使用机器码模块可以有效地加强程序的性能。例如XVID的很多核心模块就是机器码。
  • 分块的大小
    大的分块意味着录制时录制的次数少,但是小的分块可能意味着较少的数据量。对于依赖于背景色的编码方式,分块大小也影响数据量。

 

其他录制内容

鼠标,水印和其他图像

在录制图像的同时,可能同时需要在屏幕内容上叠加其他图像,例如鼠标或者水印。这可以通过在每一次录制的图像上在指定位置上叠加指定的图像来完成。

//Draw the Cursor
if (g_recordcursor==1) {
    ICONINFO iconinfo ;
    BOOL ret;
    ret = GetIconInfo( hcur, &iconinfo );
    if (ret) {
        xPoint.x -= iconinfo.xHotspot;
        xPoint.y -= iconinfo.yHotspot;
        //need to delete the hbmMask and hbmColor bitmaps
        //otherwise the program will crash after a while after running out of resource
        if (iconinfo.hbmMask) DeleteObject(iconinfo.hbmMask);
        if (iconinfo.hbmColor) DeleteObject(iconinfo.hbmColor);
    }
    :: DrawIcon( hMemDC, xPoint.x, xPoint.y, hcur);

}

这里hMemDC包含已经录制的屏幕内容,hcur表示当前缓存的光标(因为光标不是每次录制都变化,所以缓存起来效率较高)。

音频

为了丰富媒体内容,可能有必要在录制屏幕时同时录制音频。屏幕录制占用了大量资源时,有可能造成音频的录制和压缩慢于预计的频率,结果是录制的媒体音调降低,以及可能的同步问题。

加密

如果录制的内容需要保密,那么必须考虑实施加密的性能和可行性。一般来说,为每个会话产生一个不同的密钥来进行初步的加密就可以了。


阅读全文
0 0

相关文章推荐

img
取 消
img