Linux:通过网络的屏幕桌面视频捕获和VNC帧率
对不起,文字墙-TL;博士:Linux:通过网络的屏幕桌面视频捕获和VNC帧率,linux,vnc,screen-capture,frame-rate,Linux,Vnc,Screen Capture,Frame Rate,对不起,文字墙-TL;博士: VNC连接的帧速率是多少(以帧数/秒为单位)-或者更确切地说,是谁决定的:客户机还是服务器 关于桌面屏幕捕获的任何其他建议-但“时间编码正确”/,帧速率不正确(有一个稳定的周期);有可能获得未压缩(或无损)的图像序列吗 简单地说,我面临一个典型的问题:我有时开发硬件,并希望录制一段视频,显示输入PC的命令(“桌面捕获”)和硬件的响应(“实时视频”)。在我谈到具体细节之前,下面是一段介绍。 简介/背景 目前,我的策略是使用摄像机记录硬件测试过程(作为“实时”视
- VNC连接的帧速率是多少(以帧数/秒为单位)-或者更确切地说,是谁决定的:客户机还是服务器李>
- 关于桌面屏幕捕获的任何其他建议-但“时间编码正确”/,帧速率不正确(有一个稳定的周期);有可能获得未压缩(或无损)的图像序列吗
简介/背景 目前,我的策略是使用摄像机记录硬件测试过程(作为“实时”视频),同时进行桌面捕获。摄像机产生29.97(30)FPS的MPEG-2.AVI视频;我想以与视频相同的帧速率将桌面捕获作为PNG的图像序列。这样的想法是:如果两个视频的帧速率相同;那我就可以
- 将桌面捕获的开始时间与“实时”视频中的匹配点对齐
- 设置一个,其中桌面捕获的缩小版本作为覆盖放在“实时”视频的顶部
- (其中“实时”视频屏幕的一部分用作“桌面捕获”覆盖的视觉同步源)
- 导出“最终”组合视频,并适当压缩以用于互联网
ffmpeg
这样的命令行工具来完成这个过程;但是,我更愿意使用GUI来查找两个视频的对齐起点
最后,我还想实现的是,在导出“最终”视频时保持最高质量:“实时”视频在离开摄像机时已经被压缩,这意味着当它通过Theora.ogv编解码器时会进一步降级-这就是我希望保留原始视频的原因,如果需要不同的压缩/分辨率,可以使用类似命令行的方式重新生成“最终”视频。这也是为什么我喜欢将“桌面捕获”视频作为PNG序列(尽管我想任何未压缩的格式都可以):我采取措施“调整”桌面,因此没有太多渐变,无损编码(即PNG)将是合适的。
桌面捕获选项 在我目前使用的UbuntuLucid下,这个过程中有很多麻烦(你可以从中了解我的一些经历)。然而,关键问题之一是假设两个传入视频的帧速率相等——实际上,通常桌面捕获的帧速率较低;更糟糕的是,帧常常不同步 因此,这就需要坐在视频编辑器前,在帧级手动剪切和编辑不到一秒的剪辑,这就需要花费数小时的工作才能完成5分钟的视频。另一方面,如果两个视频(“live”和“capture”)具有相同的帧速率和同步:原则上,在视频编辑器中查找开始同步点不需要超过几分钟,其余的“合并”视频处理可以通过单个命令行处理。这就是为什么在这篇文章中,我想把重点放在桌面捕获部分 就我所见,在Linux/Ubuntu中,只有很少几种可行的(与之相反)桌面捕获替代方案(注意,我通常使用笔记本电脑作为桌面捕获的目标):
ffmpeg
与x11grab
选项一起使用recordMyDesktop
的东西,它也会占用大量资源,并希望在本地硬盘上进行捕获,我马上就会遇到严重的内核崩溃(通常不会生成vmcore)
因此,在我的上下文中,我通常会假设有第二台计算机参与,以运行“目标”PC桌面的捕获和录制。除此之外,到目前为止,我可以看到上述选项的利弊,如下所示
(桌面准备)
对于下面讨论的所有方法,我倾向于提前“准备”桌面:
- 删除桌面背景和图标
- 通过系统/首选项/监视器将分辨率设置为800x600(
)gnome桌面属性
- 低至16 bpp(使用根目录的
xdpyinfo | grep“进行检查)
sudoxorg-configure
为了保持图形资源的低使用率,我也经常使用
recordmydesktop --workdir /home/user/.gvfs/test\ on\ 192.168.1.100/capture/ --no-sound --quick-subsampling --fps 30 --overwrite -o capture.ogv
recordmydesktop --rescue /home/user/.gvfs/test\ on\ 192.168.1.100/capture/rMD-session-7247/
recordmydesktop --fps 25
...
Saved 2983 frames in a total of 6023 requests
...
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);
}
# '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 #
# '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