- VNC连接的帧率是多少(以帧/秒为单位)- 或者更确切地说,是客户端还是服务器决定它?
- 有没有其他建议用于桌面屏幕捕捉 - 但要“正确计时”/具有稳定周期的不抖动帧率(具有稳定周期); 并且可以将其作为未压缩(或无损)图像序列获取?
我的策略是:现在使用摄像机记录硬件测试过程(作为“实时”视频)- 同时进行桌面捕捉。摄像机生成29.97(30)FPS MPEG-2 .AVI视频;我想以相同的帧速率将桌面捕捉作为PNG图像序列获取。那么,这个想法就是:如果两个视频的帧速率相同;那么我可以简单地
- 将桌面捕获的开始时间与“实时”视频中的匹配点对齐
- 设置画中画,其中缩小版本的桌面捕获被放置在“实时”视频上方作为覆盖层
- (其中“实时”视频屏幕的一部分用作与“桌面捕获”覆盖层的视觉同步源)
- 导出适合互联网的“最终”组合视频,并进行适当压缩
原则上,我想可以使用像ffmpeg
这样的命令行工具来完成此过程;但是,我更喜欢使用GUI来查找两个视频的对齐起始点。
最终,我想要实现的另一个目标是,在导出“最终”视频时保留最大质量:摄像机外的“实时”视频已经被压缩,这意味着它通过Theora .ogv编解码器时会有额外的降级。这就是为什么我想保留原始视频,并使用类似命令行的东西重新生成“最终”视频,如果需要不同的压缩/分辨率。这也是为什么我喜欢将“桌面捕获”视频作为PNG序列(尽管我想任何未压缩的格式都可以):我采取措施“调整”桌面,因此没有很多渐变,无损编码(即PNG)是适当的。
桌面捕获选项
嗯,在我目前使用的Ubuntu Lucid下,这个过程中有很多问题(你可以在10.04:Ubuntu论坛上使用Theora ogv进行视频叠加/复合编辑中了解一些我的经历)。然而,其中一个关键问题是假设两个输入视频的帧率相等——实际上,通常桌面捕获的帧率较低;更糟糕的是,往往帧不同步。因此,这就需要在视频编辑器前坐着,手动剪切和编辑少于一秒钟的帧级别的剪辑——需要几个小时的工作才能得到最终的5分钟视频。另一方面,如果两个视频(“直播”和“捕获”)确实具有相同的帧率和同步:原则上,您只需要在视频编辑器中找到起始同步点几分钟即可——其余的“合并”视频处理可以通过单个命令行处理。这就是为什么在这篇文章中,我想重点介绍一下桌面捕获部分。
据我所见,在Linux / Ubuntu中,只有很少几个可行的(与5种在Linux桌面上录屏相对)桌面捕获替代方案(请注意,我通常使用笔记本电脑作为桌面捕获的目标)。
- 让目标PC(笔记本电脑)克隆其VGA输出的桌面; 使用VGA到复合视频或VGA到S视频硬件从VGA获取视频信号; 使用不同PC上的视频捕获卡抓取视频。
- 在目标PC上使用recordMyDesktop。
- 在目标PC上设置VNC服务器(Ubuntu上的vino或vncserver)以被捕获; 使用不同PC上的VNC捕获软件(例如vncrec)抓取/记录VNC流(随后可以转换为视频)。
- 使用
ffmpeg
和x11grab
选项。 - *(在目标PC上使用某些工具,直接进行DMA传输,从图形卡帧缓冲存储器到网络适配器存储器的桌面图像帧)
recordMyDesktop
这样的东西,它也会使用相当多的资源,并希望在本地硬盘上进行捕捉 - 我立即遇到严重的内核崩溃(通常没有生成vmcore)。因此,在我的情况下,我通常假设涉及第二台计算机 - 运行“目标”PC桌面的捕获和记录。除此之外,我目前可以看到上述选项的优缺点如下。
(桌面准备)
对于下面讨论的所有方法,我倾向于事先“准备”桌面:
- 删除桌面背景和图标 - 通过System/Preferences/Monitors(
gnome-desktop-properties
)将分辨率降至800x600
- 将颜色深度降至16 bpp(使用xdpyinfo | grep "of root"
检查)为了减少桌面捕获软件的负担,请注意更改Ubuntu上的颜色深度需要更改xorg.conf; 但是,"在/ etc / X11(Ubuntu 10.04)找不到xorg.conf" - 因此您可能需要先运行
sudo Xorg-configure
。为了保持图形资源使用低,我通常也会禁用
compiz
- 或者更确切地说,我将'System / Preferences / Appearance / Visual Effects'设置为“无”。然而,在我尝试通过将'Visual Effects'设置为“Normal”来启用compiz
后(它不会保存 ),我可以注意到LCD屏幕上的窗口重绘速度更快;因此,我保持这样,也适用于桌面捕获。我觉得这有点奇怪:如何增加效果会导致更快的屏幕刷新?看起来并不是由于专有驱动程序(该卡为“Intel Corporation N10 Family Integrated Graphics Controller”,Ubuntu在切换到compiz
时没有提供专有驱动程序选项) - 尽管,可能是所有模糊和效果只是欺骗我的眼睛:))。
克隆VGA
这是最昂贵的选择(因为它需要额外购买两个硬件:VGA转换器和视频捕捉卡),主要适用于笔记本电脑(它们具有屏幕+额外的VGA输出 - 对于台式机,您可能还需要投资于额外的显卡或VGA克隆硬件)。然而,这也是唯一不需要目标PC任何额外软件(因此使用目标CPU的0%处理能力)的选项 - 也是唯一一个可以提供真实、稳定的30 fps帧率的视频的选项(因为它是由独立硬件执行的,尽管假设在各个硬件之间存在的时钟域不对齐可以忽略)。实际上,由于我已经拥有了类似于捕捉卡的东西,我已经投资于VGA转换器 - 希望它最终能够让我只需查找5分钟的对准点和一个单一的命令行即可生成最终的“合并”视频; 但我还没有看到这个过程是否按预期工作。我也想知道是否可能以未压缩的方式捕捉桌面视频@ 800x600,30 fps。recordMyDesktop
如果您运行 recordMyDesktop
而没有任何参数-它首先开始捕获(看起来像)原始图像数据,在类似/ tmp / rMD-session-7247
的文件夹中; 在按Ctrl-C中止后,它将对该原始图像数据进行编码成.ogv。显然,在与我的测试软件(也移动大量数据)相同的硬盘上抓取大量图像数据通常会导致立即崩溃 :)
recordMyDesktop
使用这个网络驱动器(通过gvfs)作为其临时文件位置:recordmydesktop --workdir /home/user/.gvfs/test\ on\ 192.168.1.100/capture/ --no-sound --quick-subsampling --fps 30 --overwrite -o capture.ogv
请注意,虽然此命令将使用网络位置来存储临时文件(从而使
recordMyDesktop
能够与我的软件并行运行),但是一旦按下Ctrl-C,它将开始对目标计算机的本地硬盘进行编码和保存capture.ogv
(尽管在那时,我真的不在意 :))。首先,我对
recordMyDesktop
的抱怨之一是您无法指示它保留临时文件并避免在结束时对其进行编码:您可以使用Ctrl+Alt+p进行暂停,或者在第一个暂停后迅速按下Ctrl-C,以导致它崩溃;这将使临时文件留下(如果第二次没有足够快地按下Ctrl-C,则程序将“清除缓存…”)。然后,您可以运行以下命令:recordmydesktop --rescue /home/user/.gvfs/test\ on\ 192.168.1.100/capture/rMD-session-7247/
为了转换原始临时数据,需要使用
recordMyDesktop
。然而,在进行这种“救援”时,更经常发生的是recordMyDesktop
本身会崩溃。虽然,我想保留临时文件是为了拥有未压缩的源文件,用于画中画蒙太奇。请注意,“--on-the-fly-encoding
”将完全避免使用临时文件——代价是使用更多的CPU处理能力(对我来说,这又是崩溃的原因)。
然后,有帧率——显然,你可以使用“--fps N
”选项设置所需帧率;但是,这并不能保证你实际上会获得那个帧率;例如,我得到的是:
recordmydesktop --fps 25
...
Saved 2983 frames in a total of 6023 requests
...
我希望你能在我的测试软件运行时进行捕获;这意味着实际达到的速率更像是25*2983/6032 = 12.3632 fps!
显然,会有一些帧被丢掉 - 大多数情况下表现为视频回放过快。但是,如果我将请求的fps降低到12,则根据保存/总报告,我可以达到大约11 fps;在这种情况下,视频播放看起来不会“加速”。而且我还没有尝试将这样的捕获与实时视频对齐 - 所以我不知道那些实际上已经保存的帧是否也具有准确的时间戳。
VNC捕获
对我而言,VNC捕获包括在“目标”PC上运行VNC服务器,并在“记录器”PC上运行vncrec
(twibright版)。作为VNC服务器,我使用vino
,它位于“系统/首选项/远程桌面(首选项)”。显然,即使vino配置可能不是最容易管理的东西,vino
作为服务器似乎对“目标”PC的负荷不太大;因为当它与我的测试软件并行运行时,我没有遇到崩溃问题。
另一方面,当vncrec
在记录电脑上进行捕捉时,它也会弹出一个窗口,显示您在“实时”中看到的“目标”桌面;当“目标”上有大型更新(即整个窗口移动)时,可以很明显地看到“记录器”上的更新/刷新率存在问题。但是,对于只有小型更新的情况(即只有光标在静态背景上移动),则似乎没有问题。
这让我想起了这篇文章的一个主要问题 - 是什么设置了VNC连接中的帧率?
我没有找到一个清晰的答案,但从各种信息(见下文参考资料)中搜集到的碎片化信息,我得出以下结论:
- VNC服务器只需尽可能快地发送更改(屏幕更改+点击等),当它们接收到时;受服务器可用的最大网络带宽限制
- VNC客户端通过网络连接延迟和抖动接收这些更改事件,并尝试尽可能快地重建桌面“视频”流
... 这意味着,无法以稳定的、周期性的帧速率(如视频)为基础来确定任何内容。
就客户端而言,vncrec-twibright/README中指出,我通常得到的最终视频被声明为10 fps,尽管帧可能相当错位/抖动(这就需要在视频编辑器中进行剪辑)。请注意:“电影的采样率默认为10,或者通过VNCREC_MOVIE_FRAMERATE环境变量覆盖,默认为10”;然而,手册也指出:“VNCREC_MOVIE_FRAMERATE - 指定输出电影的帧速率。仅在-movie模式下有效。默认值为10。当您的转码器因10而呕吐时,请尝试24。”。如果查看“vncrec / sockets.c
”源代码,可以看到:void print_movie_frames_up_to_time(struct timeval tv)
{
static double framerate;
....
memcpy(out, bufoutptr, buffered);
if (appData.record)
{
writeLogHeader (); /* Writes the timestamp */
fwrite (bufoutptr, 1, buffered, vncLog);
}
...这表明一些时间戳是被写入的——但是这些时间戳是来自“原始”的“目标”PC,还是来自“记录器”PC,我无法确定。
编辑:感谢@kanaka的答案,我再次检查了vncrec/sockets.c,可以看到是writeLogHeader
函数本身调用了gettimeofday
;因此它写入的时间戳是本地的——也就是说,它们来自“记录器”PC(因此,这些时间戳并不能准确地描述帧在“目标”PC上产生的时间)。)
无论如何,对我来说,似乎服务器发送,而vncrec
作为客户端接收——无论何时;只有在从原始捕获编码视频文件的过程中才设置/插值某种形式的帧速率。
我还想声明,在我的“目标”笔记本电脑上,有线网络连接断开了;所以无线是我访问路由器和本地网络的唯一选择——远低于路由器可以处理有线连接的100MB/s速度。然而,如果捕获的帧中的抖动是由于“目标”PC上的负载导致的错误时间戳,那么良好的网络带宽也不会太有帮助。
最后,就VNC而言,还有其他可尝试的替代方案,例如VNCast服务器(有前途,但需要一些时间从源代码构建,并处于“早期实验版本”);或者MultiVNC(虽然它似乎只是一个客户端/查看器,没有录制选项)。
使用x11grab的ffmpeg
我没怎么用过这个,但是我尝试了与netcat
连接; 这样:
# 'target'
ffmpeg -f x11grab -b 8000k -r 30 -s 800x600 -i :0.0 -f rawvideo - | nc 192.168.1.100 5678
# 'recorder'
nc -l 0.0.0.0 5678 > raw.video #
…可以捕获文件,但是ffplay
无法正确读取捕获的文件;而:
# 'target'
ffmpeg -f x11grab -b 500k -r 30 -s 800x600 -i :0.0 -f yuv4mpegpipe -pix_fmt yuv444p - | nc 192.168.1.100 5678
# 'recorder'
nc -l 0.0.0.0 5678 | ffmpeg -i - /path/to/samplimg%03d.png
它确实可以生成.png图像,但会有压缩伪影(我猜是与使用有关的压缩结果)。
因此,目前我并不太喜欢使用+ - 但也许我只是不知道如何为我的需求设置它。
*(图形卡-> DMA->网络)
我承认,我不确定是否存在这样的东西 - 实际上,我敢打赌它不存在 :) 我在这方面也不是专家,但我推测:
如果DMA内存传输可以从图形卡(或其保持当前桌面位图的缓冲区)作为源启动,并且网络适配器作为目标 - 那么原则上应该可以获得正确(和体面)帧速率的未压缩桌面捕获。当然,使用DMA传输的要点是减轻处理器复制桌面图像到网络接口的任务(因此,减少捕获软件对运行在“目标”PC上的进程的影响 - 特别是处理RAM或硬盘的进程)。
这样的建议当然假定:有大量的网络带宽(对于800x600、30fps,至少800*600*3*30 = 43200000 bps = 42 MiB/s,在本地100 MB/s网络中应该可以),另一台PC上有足够的硬盘来进行“记录”,最后,软件可以读取原始数据,并基于它生成图像序列或视频 :)
带宽和硬盘需求我可以接受,只要能保证稳定的帧率和未压缩的数据;这就是为什么我想知道是否已经存在这样的东西。
-- -- -- -- --
好吧,我想那就是全部了 - 尽可能简短 :) 有没有关于工具或流程的建议,可以生成桌面捕获
- 以未压缩的格式(最终可转换为未压缩/无损PNG图像序列),并且
- 带有“正确时间编码”的稳定帧率
..., 最终将有助于'易于', 单个命令行处理生成'画中画'叠加视频 - 将不胜感激!
非常感谢您的任何评论,
干杯!
参考资料
- 在Linux上为CryptoTE制作屏幕录像的经验 - idlebox.net
- VideoLAN论坛•查看主题 - VNC客户端输入支持(如screen://)
- VNCServer限制慢客户端用户输入 - Kyprianou,Mark - com.realvnc.vnc-list - MarkMail
- Linux常见问题解答 - X Windows:如何使用VNC显示和控制远程桌面?
- VNC需要多少带宽?RealVNC-常问问题
- x11vnc:真实X显示器的VNC服务器
- 如何记录VNC(X11会话)- Debian Wiki
- Ubuntu中替代gtk-RecordMyDesktop的工具
- (Ffmpeg-user)如何在ffmpeg中使用管道
- (ffmpeg-devel)(PATCH)修复在不支持XFixes扩展的X服务器上绘制光标时x11grab中的段错误